Skip to content

Commit 2dd054b

Browse files
jacobly0adriweb
authored andcommitted
Moar threads! \o/
1 parent 4f551c9 commit 2dd054b

File tree

13 files changed

+515
-276
lines changed

13 files changed

+515
-276
lines changed

core/arm/armcpu.c

Lines changed: 231 additions & 230 deletions
Large diffs are not rendered by default.

core/arm/armcpu.h

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,6 @@
44
#include <stdbool.h>
55
#include <stdint.h>
66

7-
#ifdef __cplusplus
8-
extern "C" {
9-
#endif
10-
117
typedef enum arm_exception_number {
128
ARM_Exception_Reset = 1,
139
ARM_Exception_NMI = 2,
@@ -17,19 +13,23 @@ typedef enum arm_exception_number {
1713
ARM_Exception_SysTick = 15,
1814
} arm_exception_number_t;
1915

20-
typedef union arm_cpu_state {
16+
typedef union arm_cpu {
2117
uint32_t r[32];
2218
struct {
2319
uint32_t r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, sp, lr, pc, altsp;
24-
uint8_t excNum : 6;
20+
arm_exception_number_t excNum : 6;
2521
bool v, c, z, n, pm, spsel, mode;
2622
};
27-
} arm_cpu_state_t;
23+
} arm_cpu_t;
2824

29-
extern arm_cpu_state_t arm_cpu;
25+
typedef struct arm_state arm_state_t;
26+
27+
#ifdef __cplusplus
28+
extern "C" {
29+
#endif
3030

31-
void arm_cpu_reset(void);
32-
void arm_execute(void);
31+
void arm_cpu_reset(arm_state_t *state);
32+
void arm_execute(arm_state_t *state);
3333

3434
#ifdef __cplusplus
3535
}

core/arm/armmem.c

Lines changed: 49 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,54 +1,82 @@
11
#include "armmem.h"
22

3+
#include "armstate.h"
4+
35
#include <assert.h>
46
#include <stdlib.h>
7+
#include <string.h>
58

6-
arm_mem_state_t arm_mem;
9+
#define ARM_FLASH_WORDS 0x10000
10+
#define ARM_RAM_WORDS 0x2000
711

8-
void arm_mem_reset(void) {
9-
free(arm_mem.flash);
10-
free(arm_mem.ram);
11-
arm_mem.flash = calloc(0x10000, sizeof(uint32_t));
12-
arm_mem.ram = calloc(0x2000, sizeof(uint32_t));
12+
bool arm_mem_init(arm_state_t *state) {
13+
state->flash = calloc(ARM_FLASH_WORDS, sizeof(uint32_t));
14+
if (state->flash) {
15+
state->ram = calloc(ARM_RAM_WORDS, sizeof(uint32_t));
16+
if (state->ram) {
17+
return true;
18+
free(state->ram);
19+
}
20+
free(state->flash);
21+
}
22+
return false;
23+
}
24+
25+
void arm_mem_destroy(arm_state_t *state) {
26+
free(state->flash);
27+
free(state->ram);
28+
}
29+
30+
void arm_mem_reset(arm_state_t *state) {
31+
memset(state->ram, 0, ARM_RAM_WORDS * sizeof(uint32_t));
32+
}
33+
34+
bool arm_mem_load_rom(arm_state_t *state, FILE *file) {
35+
size_t read = fread(state->flash, 1, ARM_FLASH_WORDS * sizeof(uint32_t), file);
36+
if (!read) {
37+
return false;
38+
}
39+
memset(state->flash + read, ~0, ARM_FLASH_WORDS * sizeof(uint32_t) - read);
40+
return true;
1341
}
1442

15-
uint8_t arm_mem_load_byte(uint32_t addr) {
16-
return arm_mem_load_word(addr & ~UINT32_C(3)) >> ((addr & UINT32_C(3)) << UINT32_C(3));
43+
uint8_t arm_mem_load_byte(arm_state_t *state, uint32_t addr) {
44+
return arm_mem_load_word(state, addr & ~UINT32_C(3)) >> ((addr & UINT32_C(3)) << UINT32_C(3));
1745
}
1846

19-
uint16_t arm_mem_load_half(uint32_t addr) {
20-
return arm_mem_load_word(addr & ~UINT32_C(2)) >> ((addr & UINT32_C(2)) << UINT32_C(3));
47+
uint16_t arm_mem_load_half(arm_state_t *state, uint32_t addr) {
48+
return arm_mem_load_word(state, addr & ~UINT32_C(2)) >> ((addr & UINT32_C(2)) << UINT32_C(3));
2149
}
2250

23-
uint32_t arm_mem_load_word(uint32_t addr) {
51+
uint32_t arm_mem_load_word(arm_state_t *state, uint32_t addr) {
2452
assert(!(addr & UINT32_C(3)));
2553
if (addr - UINT32_C(0) < UINT32_C(0x40000)) {
26-
return arm_mem.flash[(addr - UINT32_C(0)) >> 2];
54+
return state->flash[(addr - UINT32_C(0)) >> 2];
2755
}
2856
if (addr - UINT32_C(0x20000000) < UINT32_C(0x8000)) {
29-
return arm_mem.ram[(addr - UINT32_C(0x20000000)) >> 2];
57+
return state->ram[(addr - UINT32_C(0x20000000)) >> 2];
3058
}
3159
return 0;
3260
}
3361

34-
static void arm_mem_store(uint32_t val, uint32_t mask, uint32_t addr) {
62+
static void arm_mem_store(arm_state_t *state, uint32_t val, uint32_t mask, uint32_t addr) {
3563
assert(!(addr & UINT32_C(3)) && !(val & ~mask));
3664
if (addr - UINT32_C(0x20000000) < UINT32_C(0x8000)) {
37-
uint32_t *ptr = &arm_mem.ram[(addr - UINT32_C(0x20000000)) >> UINT32_C(2)];
65+
uint32_t *ptr = &state->ram[(addr - UINT32_C(0x20000000)) >> UINT32_C(2)];
3866
*ptr = (*ptr & ~mask) | val;
3967
}
4068
}
4169

42-
void arm_mem_store_byte(uint8_t val, uint32_t addr) {
70+
void arm_mem_store_byte(arm_state_t *state, uint8_t val, uint32_t addr) {
4371
uint32_t shift = (addr & UINT32_C(3)) << UINT32_C(3);
44-
arm_mem_store(val << shift, UINT32_C(0xFF) << shift, addr & ~UINT32_C(3));
72+
arm_mem_store(state, val << shift, UINT32_C(0xFF) << shift, addr & ~UINT32_C(3));
4573
}
4674

47-
void arm_mem_store_half(uint16_t val, uint32_t addr) {
75+
void arm_mem_store_half(arm_state_t *state, uint16_t val, uint32_t addr) {
4876
uint32_t shift = (addr & UINT32_C(2)) << UINT32_C(3);
49-
arm_mem_store(val << shift, UINT32_C(0xFFFF) << shift, addr & ~UINT32_C(2));
77+
arm_mem_store(state, val << shift, UINT32_C(0xFFFF) << shift, addr & ~UINT32_C(2));
5078
}
5179

52-
void arm_mem_store_word(uint32_t val, uint32_t addr) {
53-
arm_mem_store(val, UINT32_C(0xFFFFFFFF), addr);
80+
void arm_mem_store_word(arm_state_t *state, uint32_t val, uint32_t addr) {
81+
arm_mem_store(state, val, UINT32_C(0xFFFFFFFF), addr);
5482
}

core/arm/armmem.h

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,26 @@
11
#ifndef ARMMEM_H
22
#define ARMMEM_H
33

4+
#include <stdbool.h>
45
#include <stdint.h>
6+
#include <stdio.h>
7+
8+
typedef struct arm_state arm_state_t;
59

610
#ifdef __cplusplus
711
extern "C" {
812
#endif
913

10-
typedef struct arm_mem_state {
11-
uint32_t *flash, *ram;
12-
} arm_mem_state_t;
13-
14-
extern arm_mem_state_t arm_mem;
15-
16-
void arm_mem_reset(void);
17-
uint8_t arm_mem_load_byte(uint32_t addr);
18-
uint16_t arm_mem_load_half(uint32_t addr);
19-
uint32_t arm_mem_load_word(uint32_t addr);
20-
void arm_mem_store_byte(uint8_t val, uint32_t addr);
21-
void arm_mem_store_half(uint16_t val, uint32_t addr);
22-
void arm_mem_store_word(uint32_t val, uint32_t addr);
14+
bool arm_mem_init(arm_state_t *state);
15+
void arm_mem_destroy(arm_state_t *state);
16+
void arm_mem_reset(arm_state_t *state);
17+
bool arm_mem_load_rom(arm_state_t *state, FILE *file);
18+
uint8_t arm_mem_load_byte(arm_state_t *state, uint32_t addr);
19+
uint16_t arm_mem_load_half(arm_state_t *state, uint32_t addr);
20+
uint32_t arm_mem_load_word(arm_state_t *state, uint32_t addr);
21+
void arm_mem_store_byte(arm_state_t *state, uint8_t val, uint32_t addr);
22+
void arm_mem_store_half(arm_state_t *state, uint16_t val, uint32_t addr);
23+
void arm_mem_store_word(arm_state_t *state, uint32_t val, uint32_t addr);
2324

2425
#ifdef __cplusplus
2526
}

core/arm/armstate.c

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
#include "armstate.h"
2+
3+
#include "armcpu.h"
4+
#include "armmem.h"
5+
6+
bool arm_state_init(arm_state_t *state) {
7+
return arm_mem_init(state);
8+
}
9+
10+
void arm_state_destroy(arm_state_t *state) {
11+
arm_mem_destroy(state);
12+
}
13+
14+
void arm_state_reset(arm_state_t *state) {
15+
arm_mem_reset(state);
16+
arm_cpu_reset(state);
17+
}
18+
19+
void arm_state_load(arm_state_t *state, FILE *file) {
20+
arm_mem_load_rom(state, file);
21+
}

core/arm/armstate.h

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
#ifndef ARMSTATE_H
2+
#define ARMSTATE_H
3+
4+
#include "armcpu.h"
5+
6+
#include <stdbool.h>
7+
#include <stdint.h>
8+
#include <stdio.h>
9+
10+
typedef struct arm_state {
11+
arm_cpu_t cpu;
12+
uint32_t *flash, *ram;
13+
} arm_state_t;
14+
15+
#ifdef __cplusplus
16+
extern "C" {
17+
#endif
18+
19+
bool arm_state_init(arm_state_t *state);
20+
void arm_state_destroy(arm_state_t *state);
21+
void arm_state_reset(arm_state_t *state);
22+
void arm_state_load(arm_state_t *state, FILE *file);
23+
24+
#ifdef __cplusplus
25+
}
26+
#endif
27+
28+
#endif

core/arm/sync.c

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
#include "sync.h"
2+
3+
#include "../defines.h"
4+
5+
#include <stdlib.h>
6+
7+
bool sync_init(sync_t *sync) {
8+
if (likely(mtx_init(&sync->mtx, mtx_plain) == thrd_success)) {
9+
if (likely(cnd_init(&sync->cnd[0]) == thrd_success)) {
10+
if (likely(cnd_init(&sync->cnd[1]) == thrd_success)) {
11+
atomic_init(&sync->cnt, 0u);
12+
sync->run = true;
13+
sync->rdy = false;
14+
return true;
15+
cnd_destroy(&sync->cnd[1]);
16+
}
17+
cnd_destroy(&sync->cnd[0]);
18+
}
19+
mtx_destroy(&sync->mtx);
20+
}
21+
return false;
22+
}
23+
24+
void sync_destroy(sync_t *sync) {
25+
cnd_destroy(&sync->cnd[1]);
26+
cnd_destroy(&sync->cnd[0]);
27+
mtx_destroy(&sync->mtx);
28+
}
29+
30+
bool sync_check(sync_t *sync) {
31+
if (likely(!atomic_load_explicit(&sync->cnt, memory_order_relaxed))) {
32+
return true;
33+
}
34+
if (unlikely(mtx_lock(&sync->mtx) != thrd_success)) {
35+
abort();
36+
}
37+
sync->rdy = true;
38+
do {
39+
if (cnd_signal(&sync->cnd[0]) != thrd_success ||
40+
cnd_wait(&sync->cnd[1], &sync->mtx) != thrd_success) {
41+
abort();
42+
}
43+
} while (unlikely(atomic_load_explicit(&sync->cnt, memory_order_relaxed)));
44+
bool run = sync->run;
45+
sync->rdy = false;
46+
if (unlikely(mtx_unlock(&sync->mtx) != thrd_success)) {
47+
abort();
48+
}
49+
if (likely(run)) {
50+
return true;
51+
}
52+
sync_destroy(sync);
53+
return false;
54+
}
55+
56+
void sync_enter(sync_t *sync) {
57+
if (unlikely(mtx_lock(&sync->mtx) != thrd_success)) {
58+
abort();
59+
}
60+
(void)atomic_fetch_add_explicit(&sync->cnt, 1, memory_order_relaxed);
61+
while (unlikely(!sync->rdy)) {
62+
if (unlikely(cnd_wait(&sync->cnd[0], &sync->mtx) != thrd_success)) {
63+
abort();
64+
}
65+
}
66+
}
67+
68+
void sync_leave(sync_t *sync) {
69+
bool done = atomic_fetch_sub_explicit(&sync->cnt, 1, memory_order_relaxed) == 1;
70+
if (unlikely(mtx_unlock(&sync->mtx) != thrd_success ||
71+
cnd_signal(&sync->cnd[done]) != thrd_success)) {
72+
abort();
73+
}
74+
}

core/arm/sync.h

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
#ifndef SYNC_H
2+
#define SYNC_H
3+
4+
#include <stdatomic.h>
5+
#include <stdbool.h>
6+
#include <threads.h>
7+
8+
#ifdef __cplusplus
9+
extern "C" {
10+
#endif
11+
12+
typedef struct sync {
13+
mtx_t mtx;
14+
cnd_t cnd[2];
15+
bool run, rdy;
16+
atomic_uint cnt;
17+
} sync_t;
18+
19+
bool sync_init(sync_t *sync);
20+
void sync_destroy(sync_t *sync);
21+
22+
/* Target thread only */
23+
bool sync_check(sync_t *sync);
24+
25+
/* Thread-safe, not target thread */
26+
void sync_enter(sync_t *sync);
27+
void sync_leave(sync_t *sync);
28+
29+
#ifdef __cplusplus
30+
}
31+
#endif
32+
33+
#endif

core/asic.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
#include "asic.h"
2-
#include "arm/armcpu.h"
3-
#include "arm/armmem.h"
42
#include "cpu.h"
3+
#include "coproc.h"
54
#include "misc.h"
65
#include "mem.h"
76
#include "lcd.h"
@@ -88,6 +87,7 @@ static void plug_devices(void) {
8887
add_reset_proc(uart_reset);
8988
add_reset_proc(arm_mem_reset);
9089
add_reset_proc(arm_cpu_reset);
90+
add_reset_proc(coproc_reset);
9191

9292
gui_console_printf("[CEmu] Initialized Advanced Peripheral Bus...\n");
9393
}

core/coproc.c

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
#include "coproc.h"
2+
3+
coproc_state_t coproc;
4+
5+
void coproc_init(void) {
6+
}
7+
8+
void coproc_reset(void) {
9+
arm_destroy(coproc.arm);
10+
coproc.arm = arm_create();
11+
}
12+
13+
bool coproc_load(const char *path) {
14+
return arm_load(coproc.arm, path);
15+
}

0 commit comments

Comments
 (0)