--- SheepShaver/src/kpx_cpu/sheepshaver_glue.cpp 2005/06/30 07:34:17 1.62 +++ SheepShaver/src/kpx_cpu/sheepshaver_glue.cpp 2007/12/30 09:18:40 1.74 @@ -89,6 +89,7 @@ extern uintptr SignalStackBase(); // From rsrc_patches.cpp extern "C" void check_load_invoc(uint32 type, int16 id, uint32 h); +extern "C" void named_check_load_invoc(uint32 type, uint32 name, uint32 h); // PowerPC EmulOp to exit from emulation looop const uint32 POWERPC_EXEC_RETURN = POWERPC_EMUL_OP | 1; @@ -117,12 +118,6 @@ static uint8 *emul_op_trampoline; static uint8 *native_op_trampoline; #endif -// JIT Compiler enabled? -static inline bool enable_jit_p() -{ - return PrefsFindBool("jit"); -} - /** * PowerPC emulator glue with special 'sheep' opcodes @@ -176,55 +171,17 @@ public: void interrupt(uint32 entry); // Make sure the SIGSEGV handler can access CPU registers - friend sigsegv_return_t sigsegv_handler(sigsegv_address_t, sigsegv_address_t); - - // Memory allocator returning areas aligned on 16-byte boundaries - void *operator new(size_t size); - void operator delete(void *p); + friend sigsegv_return_t sigsegv_handler(sigsegv_info_t *sip); }; -// Memory allocator returning sheepshaver_cpu objects aligned on 16-byte boundaries -// FORMAT: [ alignment ] magic identifier, offset to malloc'ed data, sheepshaver_cpu data -void *sheepshaver_cpu::operator new(size_t size) -{ - const int ALIGN = 16; - - // Allocate enough space for sheepshaver_cpu data + signature + align pad - uint8 *ptr = (uint8 *)malloc(size + ALIGN * 2); - if (ptr == NULL) - throw std::bad_alloc(); - - // Align memory - int ofs = 0; - while ((((uintptr)ptr) % ALIGN) != 0) - ofs++, ptr++; - - // Insert signature and offset - struct aligned_block_t { - uint32 pad[(ALIGN - 8) / 4]; - uint32 signature; - uint32 offset; - uint8 data[sizeof(sheepshaver_cpu)]; - }; - aligned_block_t *blk = (aligned_block_t *)ptr; - blk->signature = FOURCC('S','C','P','U'); - blk->offset = ofs + (&blk->data[0] - (uint8 *)blk); - assert((((uintptr)&blk->data) % ALIGN) == 0); - return &blk->data[0]; -} - -void sheepshaver_cpu::operator delete(void *p) -{ - uint32 *blk = (uint32 *)p; - assert(blk[-2] == FOURCC('S','C','P','U')); - void *ptr = (void *)(((uintptr)p) - blk[-1]); - free(ptr); -} - sheepshaver_cpu::sheepshaver_cpu() - : powerpc_cpu(enable_jit_p()) { init_decoder(); + +#if PPC_ENABLE_JIT + if (PrefsFindBool("jit")) + enable_jit(); +#endif } void sheepshaver_cpu::init_decoder() @@ -232,7 +189,6 @@ void sheepshaver_cpu::init_decoder() static const instr_info_t sheep_ii_table[] = { { "sheep", (execute_pmf)&sheepshaver_cpu::execute_sheep, - NULL, PPC_I(SHEEP), D_form, 6, 0, CFLOW_JUMP | CFLOW_TRAP } @@ -377,6 +333,7 @@ int sheepshaver_cpu::compile1(codegen_co status = COMPILE_CODE_OK; break; } +#endif case NATIVE_CHECK_LOAD_INVOC: dg.gen_load_T0_GPR(3); dg.gen_load_T1_GPR(4); @@ -385,18 +342,48 @@ int sheepshaver_cpu::compile1(codegen_co dg.gen_invoke_T0_T1_T2((void (*)(uint32, uint32, uint32))check_load_invoc); status = COMPILE_CODE_OK; break; -#endif - case NATIVE_BITBLT: + case NATIVE_NAMED_CHECK_LOAD_INVOC: + dg.gen_load_T0_GPR(3); + dg.gen_load_T1_GPR(4); + dg.gen_load_T2_GPR(5); + dg.gen_invoke_T0_T1_T2((void (*)(uint32, uint32, uint32))named_check_load_invoc); + status = COMPILE_CODE_OK; + break; + case NATIVE_NQD_SYNC_HOOK: + dg.gen_load_T0_GPR(3); + dg.gen_invoke_T0_ret_T0((uint32 (*)(uint32))NQD_sync_hook); + dg.gen_store_T0_GPR(3); + status = COMPILE_CODE_OK; + break; + case NATIVE_NQD_BITBLT_HOOK: + dg.gen_load_T0_GPR(3); + dg.gen_invoke_T0_ret_T0((uint32 (*)(uint32))NQD_bitblt_hook); + dg.gen_store_T0_GPR(3); + status = COMPILE_CODE_OK; + break; + case NATIVE_NQD_FILLRECT_HOOK: + dg.gen_load_T0_GPR(3); + dg.gen_invoke_T0_ret_T0((uint32 (*)(uint32))NQD_fillrect_hook); + dg.gen_store_T0_GPR(3); + status = COMPILE_CODE_OK; + break; + case NATIVE_NQD_UNKNOWN_HOOK: + dg.gen_load_T0_GPR(3); + dg.gen_invoke_T0_ret_T0((uint32 (*)(uint32))NQD_unknown_hook); + dg.gen_store_T0_GPR(3); + status = COMPILE_CODE_OK; + break; + case NATIVE_NQD_BITBLT: dg.gen_load_T0_GPR(3); dg.gen_invoke_T0((void (*)(uint32))NQD_bitblt); status = COMPILE_CODE_OK; break; - case NATIVE_INVRECT: + case NATIVE_NQD_INVRECT: dg.gen_load_T0_GPR(3); dg.gen_invoke_T0((void (*)(uint32))NQD_invrect); status = COMPILE_CODE_OK; break; - case NATIVE_FILLRECT: + case NATIVE_NQD_FILLRECT: dg.gen_load_T0_GPR(3); dg.gen_invoke_T0((void (*)(uint32))NQD_fillrect); status = COMPILE_CODE_OK; @@ -407,8 +394,8 @@ int sheepshaver_cpu::compile1(codegen_co if (!FN_field::test(opcode)) cg_context.done_compile = false; else { - dg.gen_load_A0_LR(); - dg.gen_set_PC_A0(); + dg.gen_load_T0_LR_aligned(); + dg.gen_set_PC_T0(); cg_context.done_compile = true; } break; @@ -418,8 +405,8 @@ int sheepshaver_cpu::compile1(codegen_co if (!FN_field::test(opcode)) dg.gen_set_PC_im(cg_context.pc + 4); else { - dg.gen_load_A0_LR(); - dg.gen_set_PC_A0(); + dg.gen_load_T0_LR_aligned(); + dg.gen_set_PC_T0(); } dg.gen_mov_32_T0_im(selector); dg.gen_jmp(native_op_trampoline); @@ -743,16 +730,16 @@ static void dump_log(void) * Initialize CPU emulation */ -sigsegv_return_t sigsegv_handler(sigsegv_address_t fault_address, sigsegv_address_t fault_instruction) +sigsegv_return_t sigsegv_handler(sigsegv_info_t *sip) { #if ENABLE_VOSF // Handle screen fault - extern bool Screen_fault_handler(sigsegv_address_t, sigsegv_address_t); - if (Screen_fault_handler(fault_address, fault_instruction)) + extern bool Screen_fault_handler(sigsegv_info_t *sip); + if (Screen_fault_handler(sip)) return SIGSEGV_RETURN_SUCCESS; #endif - const uintptr addr = (uintptr)fault_address; + const uintptr addr = (uintptr)sigsegv_get_fault_address(sip); #if HAVE_SIGSEGV_SKIP_INSTRUCTION // Ignore writes to ROM if ((addr - (uintptr)ROMBaseHost) < ROM_SIZE) @@ -803,8 +790,8 @@ sigsegv_return_t sigsegv_handler(sigsegv #endif fprintf(stderr, "SIGSEGV\n"); - fprintf(stderr, " pc %p\n", fault_instruction); - fprintf(stderr, " ea %p\n", fault_address); + fprintf(stderr, " pc %p\n", sigsegv_get_fault_instruction_address(sip)); + fprintf(stderr, " ea %p\n", sigsegv_get_fault_address(sip)); dump_registers(); ppc_cpu->dump_log(); enter_mon(); @@ -868,6 +855,7 @@ void exit_emul_ppc(void) #endif delete ppc_cpu; + ppc_cpu = NULL; } #if PPC_ENABLE_JIT && PPC_REENTRANT_JIT @@ -915,6 +903,7 @@ void emul_ppc(uint32 entry) void TriggerInterrupt(void) { + idle_resume(); #if 0 WriteMacInt32(0x16a, ReadMacInt32(0x16a) + 1); #else @@ -935,13 +924,7 @@ void HandleInterrupt(powerpc_registers * if (int32(ReadMacInt32(XLM_IRQ_NEST)) > 0) return; - // Do nothing if there is no pending interrupt - if (InterruptFlags == 0) - return; - - // Current interrupt nest level - static int interrupt_depth = 0; - ++interrupt_depth; + // Update interrupt count #if EMUL_TIME_STATS interrupt_count++; #endif @@ -957,7 +940,7 @@ void HandleInterrupt(powerpc_registers * #if INTERRUPTS_IN_NATIVE_MODE case MODE_NATIVE: // 68k emulator inactive, in nanokernel? - if (r->gpr[1] != KernelDataAddr && interrupt_depth == 1) { + if (r->gpr[1] != KernelDataAddr) { // Prepare for 68k interrupt level 1 WriteMacInt16(tswap32(kernel_data->v[0x67c >> 2]), 1); @@ -1015,17 +998,8 @@ void HandleInterrupt(powerpc_registers * break; #endif } - - // We are done with this interrupt - --interrupt_depth; } -static void get_resource(void); -static void get_1_resource(void); -static void get_ind_resource(void); -static void get_1_ind_resource(void); -static void r_get_resource(void); - // Execute NATIVE_OP routine void sheepshaver_cpu::execute_native_op(uint32 selector) { @@ -1047,6 +1021,18 @@ void sheepshaver_cpu::execute_native_op( case NATIVE_VIDEO_DO_DRIVER_IO: gpr(3) = (int32)(int16)VideoDoDriverIO(gpr(3), gpr(4), gpr(5), gpr(6), gpr(7)); break; + case NATIVE_ETHER_AO_GET_HWADDR: + AO_get_ethernet_address(gpr(3)); + break; + case NATIVE_ETHER_AO_ADD_MULTI: + AO_enable_multicast(gpr(3)); + break; + case NATIVE_ETHER_AO_DEL_MULTI: + AO_disable_multicast(gpr(3)); + break; + case NATIVE_ETHER_AO_SEND_PACKET: + AO_transmit_packet(gpr(3)); + break; case NATIVE_ETHER_IRQ: EtherIRQ(); break; @@ -1068,22 +1054,25 @@ void sheepshaver_cpu::execute_native_op( case NATIVE_ETHER_RSRV: gpr(3) = ether_rsrv((queue_t *)gpr(3)); break; - case NATIVE_SYNC_HOOK: + case NATIVE_NQD_SYNC_HOOK: gpr(3) = NQD_sync_hook(gpr(3)); break; - case NATIVE_BITBLT_HOOK: + case NATIVE_NQD_UNKNOWN_HOOK: + gpr(3) = NQD_unknown_hook(gpr(3)); + break; + case NATIVE_NQD_BITBLT_HOOK: gpr(3) = NQD_bitblt_hook(gpr(3)); break; - case NATIVE_BITBLT: + case NATIVE_NQD_BITBLT: NQD_bitblt(gpr(3)); break; - case NATIVE_FILLRECT_HOOK: + case NATIVE_NQD_FILLRECT_HOOK: gpr(3) = NQD_fillrect_hook(gpr(3)); break; - case NATIVE_INVRECT: + case NATIVE_NQD_INVRECT: NQD_invrect(gpr(3)); break; - case NATIVE_FILLRECT: + case NATIVE_NQD_FILLRECT: NQD_fillrect(gpr(3)); break; case NATIVE_SERIAL_NOTHING: @@ -1107,27 +1096,29 @@ void sheepshaver_cpu::execute_native_op( break; } case NATIVE_GET_RESOURCE: + get_resource(ReadMacInt32(XLM_GET_RESOURCE)); + break; case NATIVE_GET_1_RESOURCE: + get_resource(ReadMacInt32(XLM_GET_1_RESOURCE)); + break; case NATIVE_GET_IND_RESOURCE: + get_resource(ReadMacInt32(XLM_GET_IND_RESOURCE)); + break; case NATIVE_GET_1_IND_RESOURCE: - case NATIVE_R_GET_RESOURCE: { - typedef void (*GetResourceCallback)(void); - static const GetResourceCallback get_resource_callbacks[] = { - ::get_resource, - ::get_1_resource, - ::get_ind_resource, - ::get_1_ind_resource, - ::r_get_resource - }; - get_resource_callbacks[selector - NATIVE_GET_RESOURCE](); + get_resource(ReadMacInt32(XLM_GET_1_IND_RESOURCE)); + break; + case NATIVE_R_GET_RESOURCE: + get_resource(ReadMacInt32(XLM_R_GET_RESOURCE)); break; - } case NATIVE_MAKE_EXECUTABLE: MakeExecutable(0, gpr(4), gpr(5)); break; case NATIVE_CHECK_LOAD_INVOC: check_load_invoc(gpr(3), gpr(4), gpr(5)); break; + case NATIVE_NAMED_CHECK_LOAD_INVOC: + named_check_load_invoc(gpr(3), gpr(4), gpr(5)); + break; default: printf("FATAL: NATIVE_OP called with bogus selector %d\n", selector); QuitEmulator(); @@ -1214,32 +1205,3 @@ uint32 call_macos7(uint32 tvect, uint32 const uint32 args[] = { arg1, arg2, arg3, arg4, arg5, arg6, arg7 }; return ppc_cpu->execute_macos_code(tvect, sizeof(args)/sizeof(args[0]), args); } - -/* - * Resource Manager thunks - */ - -void get_resource(void) -{ - ppc_cpu->get_resource(ReadMacInt32(XLM_GET_RESOURCE)); -} - -void get_1_resource(void) -{ - ppc_cpu->get_resource(ReadMacInt32(XLM_GET_1_RESOURCE)); -} - -void get_ind_resource(void) -{ - ppc_cpu->get_resource(ReadMacInt32(XLM_GET_IND_RESOURCE)); -} - -void get_1_ind_resource(void) -{ - ppc_cpu->get_resource(ReadMacInt32(XLM_GET_1_IND_RESOURCE)); -} - -void r_get_resource(void) -{ - ppc_cpu->get_resource(ReadMacInt32(XLM_R_GET_RESOURCE)); -}