diff --git a/SheepShaver/src/BeOS/main_beos.cpp b/SheepShaver/src/BeOS/main_beos.cpp index 88663447..286a1ce8 100644 --- a/SheepShaver/src/BeOS/main_beos.cpp +++ b/SheepShaver/src/BeOS/main_beos.cpp @@ -220,6 +220,7 @@ system_info SysInfo; // System information static void *sig_stack = NULL; // Stack for signal handlers static void *extra_stack = NULL; // Stack for SIGSEGV inside interrupt handler +uint32 SheepMem::page_size; // Size of a native page uintptr SheepMem::zero_page = 0; // Address of ro page filled in with zeros uintptr SheepMem::base; // Address of SheepShaver data uintptr SheepMem::top; // Top of SheepShaver data (stack like storage) @@ -726,6 +727,9 @@ void SheepShaver::Quit(void) void SheepShaver::init_rom(void) { + // Size of a native page + page_size = B_PAGE_SIZE; + // Create area for ROM void *rom_addr = (void *)ROM_BASE; rom_area = create_area(ROM_AREA_NAME, &rom_addr, B_EXACT_ADDRESS, ROM_AREA_SIZE, B_NO_LOCK, B_READ_AREA | B_WRITE_AREA); diff --git a/SheepShaver/src/Unix/main_unix.cpp b/SheepShaver/src/Unix/main_unix.cpp index 6f7ae945..9aef379b 100644 --- a/SheepShaver/src/Unix/main_unix.cpp +++ b/SheepShaver/src/Unix/main_unix.cpp @@ -273,6 +273,7 @@ static sigregs sigsegv_regs; // Register dump when crashed static const char *crash_reason = NULL; // Reason of the crash (SIGSEGV, SIGBUS, SIGILL) #endif +uint32 SheepMem::page_size; // Size of a native page uintptr SheepMem::zero_page = 0; // Address of ro page filled in with zeros uintptr SheepMem::base = 0x60000000; // Address of SheepShaver data uintptr SheepMem::top = 0; // Top of SheepShaver data (stack like storage) @@ -1659,8 +1660,10 @@ static void sigsegv_handler(int sig, siginfo_t *sip, void *scp) #endif } - // Ignore ROM writes - if (transfer_type == TYPE_STORE && addr >= ROM_BASE && addr < ROM_BASE + ROM_SIZE) { + // Ignore ROM writes (including to the zero page, which is read-only) + if (transfer_type == TYPE_STORE && + ((addr >= ROM_BASE && addr < ROM_BASE + ROM_SIZE) || + (addr >= SheepMem::ZeroPage() && addr < SheepMem::ZeroPage() + SheepMem::PageSize()))) { // D(bug("WARNING: %s write access to ROM at %08lx, pc %08lx\n", transfer_size == SIZE_BYTE ? "Byte" : transfer_size == SIZE_HALFWORD ? "Halfword" : "Word", addr, r->pc())); if (addr_mode == MODE_U || addr_mode == MODE_UX) r->gpr(ra) = addr; @@ -1904,7 +1907,8 @@ rti:; bool SheepMem::Init(void) { - const int page_size = getpagesize(); + // Size of a native page + page_size = getpagesize(); // Allocate SheepShaver globals if (vm_acquire_fixed((char *)base, size) < 0) @@ -1932,8 +1936,6 @@ bool SheepMem::Init(void) void SheepMem::Exit(void) { if (top) { - const int page_size = getpagesize(); - // Delete SheepShaver globals vm_release((void *)base, size); diff --git a/SheepShaver/src/include/thunks.h b/SheepShaver/src/include/thunks.h index 4479261d..0495b68d 100644 --- a/SheepShaver/src/include/thunks.h +++ b/SheepShaver/src/include/thunks.h @@ -86,6 +86,7 @@ extern uint32 NativeRoutineDescriptor(int selector); class SheepMem { static uint32 align(uint32 size); protected: + static uint32 page_size; static uintptr zero_page; static uintptr base; static uintptr top; @@ -93,6 +94,7 @@ protected: public: static bool Init(void); static void Exit(void); + static uint32 PageSize(); static uintptr ZeroPage(); static uintptr Reserve(uint32 size); static void Release(uint32 size); @@ -105,6 +107,11 @@ inline uint32 SheepMem::align(uint32 size) return (size + 3) & -4; } +inline uint32 SheepMem::PageSize() +{ + return page_size; +} + inline uintptr SheepMem::ZeroPage() { return zero_page; diff --git a/SheepShaver/src/kpx_cpu/sheepshaver_glue.cpp b/SheepShaver/src/kpx_cpu/sheepshaver_glue.cpp index 37dcfd14..400228f7 100644 --- a/SheepShaver/src/kpx_cpu/sheepshaver_glue.cpp +++ b/SheepShaver/src/kpx_cpu/sheepshaver_glue.cpp @@ -715,6 +715,10 @@ static sigsegv_return_t sigsegv_handler(sigsegv_address_t fault_address, sigsegv else if (pc == ROM_BASE + 0x4a10a0 && (cpu->gpr(20) == 0xf3012002 || cpu->gpr(20) == 0xf3012000)) return SIGSEGV_RETURN_SKIP_INSTRUCTION; + // Ignore writes to the zero page + else if ((uint32)(addr - SheepMem::ZeroPage()) < (uint32)SheepMem::PageSize()) + return SIGSEGV_RETURN_SKIP_INSTRUCTION; + // Ignore all other faults, if requested if (PrefsFindBool("ignoresegv")) return SIGSEGV_RETURN_SKIP_INSTRUCTION; diff --git a/SheepShaver/src/rom_patches.cpp b/SheepShaver/src/rom_patches.cpp index e80b54c1..470d9f42 100644 --- a/SheepShaver/src/rom_patches.cpp +++ b/SheepShaver/src/rom_patches.cpp @@ -2305,7 +2305,7 @@ void InstallDrivers(void) WriteMacInt16(dce + dCtlFlags, SonyDriverFlags); } -#if DISABLE_SCSI && 0 +#if DISABLE_SCSI && HAVE_SIGSEGV_SKIP_INSTRUCTION // Fake SCSIGlobals WriteMacInt32(0xc0c, SheepMem::ZeroPage()); #endif