}
void uae_ppc_spinlock_reset(void)
{
- spinlock_cnt = 1;
- uae_ppc_spinlock_release();
+ spinlock_cnt = 0;
+ uae_ppc_spinlock_get();
}
volatile int ppc_state;
-
static volatile bool ppc_thread_running;
-static smp_comm_pipe ppcrequests, ppcreturn;
-static smp_comm_pipe ppcquery, ppcreply;
int ppc_cycle_count;
static volatile bool ppc_access;
static volatile int ppc_cpu_lock_state;
static bool ppc_io_pipe;
static bool ppc_use_spinlock;
static bool ppc_init_done;
+static bool ppc_cpu_init_done;
static int ppc_implementation;
#define CSPPC_PVR 0x00090204
{
TRACE(_T("uae_ppc_cpu_reset\n"));
initialize();
- if (!ppc_init_done) {
+ if (!ppc_cpu_init_done) {
write_log(_T("PPC: Hard reset\n"));
g_ppc_cpu_init(currprefs.cpuboard_type == BOARD_BLIZZARDPPC ? BLIZZPPC_PVR : CSPPC_PVR);
map_banks();
- ppc_init_done = true;
+ ppc_cpu_init_done = true;
}
write_log(_T("PPC: Init\n"));
g_ppc_cpu_set_pc(0, 0xfff00100);
static void *ppc_thread(void *v)
{
- for (;;) {
- uae_u32 v = read_comm_pipe_u32_blocking(&ppcrequests);
- if (v == 0xffffffff)
- break;
- uae_ppc_spinlock_reset();
- ppc_io_pipe = true;
- ppc_use_spinlock = false;
- uae_ppc_cpu_reset();
- g_ppc_cpu_run_continuous();
- if (ppc_state == PPC_STATE_ACTIVE || ppc_state == PPC_STATE_SLEEP)
- ppc_state = PPC_STATE_STOP;
- write_log(_T("ppc_cpu_run() exited.\n"));
- write_comm_pipe_u32(&ppcreturn, 0, 0);
- }
-
+ uae_ppc_cpu_reset();
+ g_ppc_cpu_run_continuous();
+ if (ppc_state == PPC_STATE_ACTIVE || ppc_state == PPC_STATE_SLEEP)
+ ppc_state = PPC_STATE_STOP;
+ write_log(_T("ppc_cpu_run() exited.\n"));
ppc_thread_running = false;
return NULL;
}
-bool uae_ppc_to_main_thread(void)
-{
- TRACE(_T("uae_ppc_to_main_thread\n"));
-
- // QEMU: keep using thread
- if (ppc_implementation == PPC_IMPLEMENTATION_QEMU) {
- // already done?
- if (ppc_io_pipe == false)
- return true;
- // make sure no new messages added to queue
- ppc_cpu_lock_state = 1;
- ppc_use_spinlock = true;
- // empty queue
- while (comm_pipe_has_data(&ppcquery))
- uae_ppc_poll_queue();
- ppc_io_pipe = false;
- ppc_cpu_lock_state = 0;
- return true;
- }
-
- if (ppc_thread_running) {
- write_log(_T("PPC: transferring PPC emulation to main thread.\n"));
- uae_ppc_cpu_stop();
- write_comm_pipe_u32(&ppcrequests, 0xffffffff, 1);
- while (ppc_thread_running)
- sleep_millis(2);
- while (comm_pipe_has_data(&ppcquery))
- uae_ppc_poll_queue();
- write_log(_T("PPC: transfer complete.\n"));
- }
- ppc_state = PPC_STATE_ACTIVE;
- ppc_main_thread = true;
- ppc_io_pipe = false;
- return true;
-}
-
void uae_ppc_execute_quick(int linetype)
{
if (linetype == 0) {
g_ppc_cpu_run_single(10);
}
-bool uae_ppc_poll_queue(void)
-{
- if (!ppc_io_pipe)
- return true;
- // ppc locked?
- if (ppc_cpu_lock_state < 0)
- return false;
-
- if (comm_pipe_has_data(&ppcquery)) {
- ppc_access = true;
- uae_u32 addr = read_comm_pipe_u32_blocking(&ppcquery);
- uae_u32 size = read_comm_pipe_u32_blocking(&ppcquery);
- uae_u32 data = 0, data2 = 0;
- if (size & 0x80) {
- if (size & 0x08)
- data2 = read_comm_pipe_u32_blocking(&ppcquery);
- data = read_comm_pipe_u32_blocking(&ppcquery);
- switch (size & 127)
- {
- case 8:
- put_long(addr + 0, data2);
- put_long(addr + 4, data);
- break;
- case 4:
- put_long(addr, data);
- break;
- case 2:
- put_word(addr, data);
- break;
- case 1:
- put_byte(addr, data);
- break;
- }
-#if PPC_SYNC_WRITE
- write_comm_pipe_u32(&ppcreply, 0, 1);
-#else
- read_comm_pipe_u32_blocking(&ppcquery);
-#endif
- } else {
- switch (size & 127)
- {
- case 8:
- data2 = get_long(addr + 0);
- data = get_long(addr + 4);
- break;
- case 4:
- data = get_long(addr);
- break;
- case 2:
- data = get_word(addr);
- break;
- case 1:
- data = get_byte(addr);
- break;
- }
- if (size & 0x08)
- write_comm_pipe_u32(&ppcreply, data2, 0);
- write_comm_pipe_u32(&ppcreply, data, 1);
- }
- ppc_access = false;
- }
- if (ppc_cpu_lock_state > 0)
- return true;
- return false;
-}
-
-void uae_ppc_sync (void)
-{
- while (ppc_thread_running && comm_pipe_has_data(&ppcquery));
-}
-
bool uae_ppc_direct_physical_memory_handle(uint32_t addr, uint8_t *&ptr)
{
- if (valid_address(addr, 0x1000)) {
- ptr = get_real_address(addr);
- return true;
- }
- return false;
+ ptr = get_real_address(addr);
+ if (!ptr)
+ gui_message(_T("Executing PPC code at IO address %08x!"), addr);
+ return true;
}
STATIC_INLINE bool spinlock_pre(uaecptr addr)
bool UAECALL uae_ppc_io_mem_write(uint32_t addr, uint32_t data, int size)
{
bool locked = false;
+
while (ppc_thread_running && ppc_cpu_lock_state < 0 && ppc_state);
- if (ppc_io_pipe && !valid_address(addr, size)) {
- write_comm_pipe_u32(&ppcquery, addr, 0);
- write_comm_pipe_u32(&ppcquery, size | 0x80, 0);
- write_comm_pipe_u32(&ppcquery, data, 1);
-#if PPC_SYNC_WRITE
- read_comm_pipe_u32_blocking(&ppcreply);
-#else
- write_comm_pipe_u32(&ppcquery, data, 0);
-#endif
-#if PPC_ACCESS_LOG > 0
- write_log(_T("PPC io write %08x = %08x %d\n"), addr, data, size);
-#endif
- return true;
- }
#if PPC_ACCESS_LOG > 0
if (!ppc_io_pipe && !valid_address(addr, size)) {
if (addr >= PPC_DEBUG_ADDR_FROM && addr < PPC_DEBUG_ADDR_TO)
write_log(_T("PPC io write %08x = %08x %d\n"), addr, data, size);
}
#endif
+
locked = spinlock_pre(addr);
switch (size)
{
}
spinlock_post(locked);
}
+
#if PPC_ACCESS_LOG > 2
write_log(_T("PPC mem write %08x = %08x %d\n"), addr, data, size);
#endif
+
return true;
}
while (ppc_thread_running && ppc_cpu_lock_state < 0 && ppc_state);
- if (ppc_io_pipe && !valid_address(addr, size)) {
- write_comm_pipe_u32(&ppcquery, addr, 0);
- write_comm_pipe_u32(&ppcquery, size, 1);
- v = read_comm_pipe_u32_blocking(&ppcreply);
-#if PPC_ACCESS_LOG > 0
- if (addr != 0xbfe001)
- write_log(_T("PPC io read %08x=%08x %d\n"), addr, v, size);
-#endif
- *data = v;
- return true;
+ if (addr >= 0xdff000 && addr < 0xe00000) {
+ // shortcuts for common registers
+ if (addr == 0xdff01c) { // INTENAR
+ *data = intena;
+ return true;
+ }
+ if (addr == 0xdff01e) { // INTREQR
+ *data = intreq;
+ return true;
+ }
}
locked = spinlock_pre(addr);
bool locked = false;
while (ppc_thread_running && ppc_cpu_lock_state < 0 && ppc_state);
- if (ppc_io_pipe && !valid_address(addr, 8)) {
-#if PPC_ACCESS_LOG > 0
- write_log(_T("PPC io write64 %08x = %08llx\n"), addr, (unsigned long long) data);
-#endif
- write_comm_pipe_u32(&ppcquery, addr, 0);
- write_comm_pipe_u32(&ppcquery, 8 | 0x80, 0);
- write_comm_pipe_u32(&ppcquery, data >> 32, 0);
- write_comm_pipe_u32(&ppcquery, data & 0xffffffff, 1);
-#if PPC_SYNC_WRITE
- read_comm_pipe_u32_blocking(&ppcreply);
-#else
- write_comm_pipe_u32(&ppcquery, data, 0);
-#endif
- return true;
- }
locked = spinlock_pre(addr);
put_long(addr + 0, data >> 32);
put_long(addr + 4, data & 0xffffffff);
spinlock_post(locked);
+
#if PPC_ACCESS_LOG > 2
write_log(_T("PPC mem write64 %08x = %08llx\n"), addr, data);
#endif
+
return true;
}
while (ppc_thread_running && ppc_cpu_lock_state < 0 && ppc_state);
- if (ppc_io_pipe && !valid_address(addr, 8)) {
- write_comm_pipe_u32(&ppcquery, addr, 0);
- write_comm_pipe_u32(&ppcquery, 8, 0);
- v1 = read_comm_pipe_u32_blocking(&ppcreply);
- v2 = read_comm_pipe_u32_blocking(&ppcreply);
- *data = ((uint64_t)v1 << 32) | v2;
-#if PPC_ACCESS_LOG > 0
- write_log(_T("PPC io read64 %08x = %08llx\n"), addr, (unsigned long long) *data);
-#endif
- return true;
- }
locked = spinlock_pre(addr);
v1 = get_long(addr + 0);
v2 = get_long(addr + 4);
*data = ((uint64_t)v1 << 32) | v2;
spinlock_post(locked);
+
#if PPC_ACCESS_LOG > 2
write_log(_T("PPC mem read64 %08x = %08llx\n"), addr, *data);
#endif
+
return true;
}
g_ppc_cpu_stop();
while (ppc_state != PPC_STATE_STOP && ppc_state != PPC_STATE_CRASH) {
uae_ppc_wakeup();
- uae_ppc_poll_queue();
if (ppc_use_spinlock) {
uae_ppc_spinlock_release();
uae_ppc_spinlock_get();
}
}
- read_comm_pipe_u32_blocking(&ppcreturn);
ppc_state = PPC_STATE_STOP;
write_log(_T("PPC stopped.\n"));
}
void uae_ppc_cpu_reboot(void)
{
TRACE(_T("uae_ppc_cpu_reboot\n"));
+
+ uae_ppc_spinlock_reset();
+ ppc_io_pipe = false;
+ ppc_use_spinlock = true;
+
if (ppc_main_thread) {
uae_ppc_cpu_reset();
} else {
if (!ppc_thread_running) {
ppc_thread_running = true;
ppc_main_thread = false;
- init_comm_pipe(&ppcrequests, 10, 1);
- init_comm_pipe(&ppcreturn, 10, 1);
- init_comm_pipe(&ppcreply, 100, 1);
- init_comm_pipe(&ppcquery, 100, 1);
uae_start_thread(_T("ppc"), ppc_thread, NULL, NULL);
}
- write_comm_pipe_u32(&ppcrequests, 1, 1);
}
}