diff --git a/SheepShaver/src/Unix/main_unix.cpp b/SheepShaver/src/Unix/main_unix.cpp index 7ff5e2bf..38f6af29 100644 --- a/SheepShaver/src/Unix/main_unix.cpp +++ b/SheepShaver/src/Unix/main_unix.cpp @@ -987,10 +987,12 @@ void Dump68kRegs(M68kRegisters *r) void MakeExecutable(int dummy, void *start, uint32 length) { -#if !EMULATED_PPC - if (((uint32)start >= ROM_BASE) && ((uint32)start < (ROM_BASE + ROM_SIZE))) + if (((uintptr)start >= ROM_BASE) && ((uintptr)start < (ROM_BASE + ROM_SIZE))) return; - flush_icache_range(start, (void *)((uint32)start + length)); +#if EMULATED_PPC + FlushCodeCache((uintptr)start, (uintptr)start + length); +#else + flush_icache_range(start, (void *)((uintptr)start + length)); #endif } diff --git a/SheepShaver/src/Unix/sysdeps.h b/SheepShaver/src/Unix/sysdeps.h index 927bfe12..40577f71 100644 --- a/SheepShaver/src/Unix/sysdeps.h +++ b/SheepShaver/src/Unix/sysdeps.h @@ -79,6 +79,7 @@ #endif // Configure PowerPC emulator #define PPC_NO_LAZY_PC_UPDATE 1 +#define PPC_NO_DECODE_CACHE 1 #define PPC_FLIGHT_RECORDER 1 #else // Mac ROM is write protected diff --git a/SheepShaver/src/emul_op.cpp b/SheepShaver/src/emul_op.cpp index a6c815ec..38a5e09a 100644 --- a/SheepShaver/src/emul_op.cpp +++ b/SheepShaver/src/emul_op.cpp @@ -257,10 +257,12 @@ void EmulOp(M68kRegisters *r, uint32 pc, int selector) // Install drivers InstallDrivers(); -#if !EMULATED_PPC // Patch MakeExecutable() MakeExecutableTvec = (uint32 *)FindLibSymbol("\023PrivateInterfaceLib", "\016MakeExecutable"); D(bug("MakeExecutable TVECT at %p\n", MakeExecutableTvec)); +#if EMULATED_PPC + MakeExecutableTvec[0] = POWERPC_NATIVE_OP_FUNC(NATIVE_MAKE_EXECUTABLE); +#else #ifdef __BEOS__ MakeExecutableTvec[0] = ((uint32 *)MakeExecutable)[0]; #else diff --git a/SheepShaver/src/include/cpu_emulation.h b/SheepShaver/src/include/cpu_emulation.h index ce9a4939..bfa54cd8 100644 --- a/SheepShaver/src/include/cpu_emulation.h +++ b/SheepShaver/src/include/cpu_emulation.h @@ -91,6 +91,7 @@ struct M68kRegisters; extern void Execute68k(uint32, M68kRegisters *r); // Execute 68k subroutine from EMUL_OP routine, must be ended with RTS extern void Execute68kTrap(uint16 trap, M68kRegisters *r); // Execute 68k A-Trap from EMUL_OP routine #if EMULATED_PPC +extern void FlushCodeCache(uintptr start, uintptr end); // Invalidate emulator caches extern void ExecuteNative(int selector); // Execute native code from EMUL_OP routine (real mode switch) #else extern void ExecutePPC(void (*func)(void)); // Execute PPC code from EMUL_OP routine (real mode switch) diff --git a/SheepShaver/src/include/emul_op.h b/SheepShaver/src/include/emul_op.h index 5f08b5c2..4348c440 100644 --- a/SheepShaver/src/include/emul_op.h +++ b/SheepShaver/src/include/emul_op.h @@ -54,6 +54,7 @@ enum { // Selectors for NATIVE_EXEC callbacks (only used with PPC emulation) NATIVE_R_GET_RESOURCE, NATIVE_DISABLE_INTERRUPT, NATIVE_ENABLE_INTERRUPT, + NATIVE_MAKE_EXECUTABLE, NATIVE_OP_MAX }; #define POWERPC_NATIVE_OP(SELECTOR) NativeOpTable[SELECTOR] diff --git a/SheepShaver/src/kpx_cpu/sheepshaver_glue.cpp b/SheepShaver/src/kpx_cpu/sheepshaver_glue.cpp index b1bbbd6a..dd9c76fd 100644 --- a/SheepShaver/src/kpx_cpu/sheepshaver_glue.cpp +++ b/SheepShaver/src/kpx_cpu/sheepshaver_glue.cpp @@ -144,7 +144,7 @@ void sheepshaver_cpu::init_decoder() { "sheep", (execute_fn)&sheepshaver_cpu::execute_sheep, NULL, - D_form, 6, 0, CFLOW_TRAP + D_form, 6, 0, CFLOW_JUMP | CFLOW_TRAP } }; @@ -492,6 +492,15 @@ static sheepshaver_cpu *main_cpu = NULL; // CPU emulator to handle usual contro static sheepshaver_cpu *interrupt_cpu = NULL; // CPU emulator to handle interrupts static sheepshaver_cpu *current_cpu = NULL; // Current CPU emulator context +void FlushCodeCache(uintptr start, uintptr end) +{ + D(bug("FlushCodeCache(%08x, %08x)\n", start, end)); + main_cpu->invalidate_cache_range(start, end); +#if MULTICORE_CPU + interrupt_cpu->invalidate_cache_range(start, end); +#endif +} + static inline void cpu_push(sheepshaver_cpu *new_cpu) { #if MULTICORE_CPU @@ -723,6 +732,7 @@ const uint32 NativeOpTable[NATIVE_OP_MAX] = { POWERPC_NATIVE_OP_INIT(1, NATIVE_R_GET_RESOURCE), POWERPC_NATIVE_OP_INIT(0, NATIVE_DISABLE_INTERRUPT), POWERPC_NATIVE_OP_INIT(0, NATIVE_ENABLE_INTERRUPT), + POWERPC_NATIVE_OP_INIT(1, NATIVE_MAKE_EXECUTABLE), }; static void get_resource(void); @@ -790,6 +800,9 @@ static void NativeOp(int selector) case NATIVE_ENABLE_INTERRUPT: EnableInterrupt(); break; + case NATIVE_MAKE_EXECUTABLE: + MakeExecutable(0, (void *)GPR(4), GPR(5)); + break; default: printf("FATAL: NATIVE_OP called with bogus selector %d\n", selector); QuitEmulator(); diff --git a/SheepShaver/src/kpx_cpu/src/cpu/ppc/ppc-cpu.hpp b/SheepShaver/src/kpx_cpu/src/cpu/ppc/ppc-cpu.hpp index c387f81f..7d6cec52 100644 --- a/SheepShaver/src/kpx_cpu/src/cpu/ppc/ppc-cpu.hpp +++ b/SheepShaver/src/kpx_cpu/src/cpu/ppc/ppc-cpu.hpp @@ -364,16 +364,15 @@ inline void powerpc_cpu::do_execute() uint32 dpc = pc() - 4; do { uint32 opcode = vm_read_memory_4(dpc += 4); - ii = decode(opcode); - di->opcode = opcode; - di->execute = ii->execute; #if PPC_FLIGHT_RECORDER if (is_logging()) { - di++; di->opcode = opcode; di->execute = &powerpc_cpu::record_step; + di++; } #endif + di->opcode = opcode; + di->execute = ii->execute; if (++di >= decode_cache_end_p) { // Invalidate cache and move current code to start invalidate_cache();