--- SheepShaver/src/kpx_cpu/sheepshaver_glue.cpp 2004/12/18 18:40:04 1.55 +++ SheepShaver/src/kpx_cpu/sheepshaver_glue.cpp 2005/03/05 18:33:30 1.59 @@ -1,7 +1,7 @@ /* * sheepshaver_glue.cpp - Glue Kheperix CPU to SheepShaver CPU engine interface * - * SheepShaver (C) 1997-2004 Christian Bauer and Marc Hellwig + * SheepShaver (C) 1997-2005 Christian Bauer and Marc Hellwig * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -93,9 +93,6 @@ extern "C" void check_load_invoc(uint32 // PowerPC EmulOp to exit from emulation looop const uint32 POWERPC_EXEC_RETURN = POWERPC_EMUL_OP | 1; -// Enable interrupt routine safety checks? -#define SAFE_INTERRUPT_PPC 1 - // Enable Execute68k() safety checks? #define SAFE_EXEC_68K 1 @@ -142,21 +139,6 @@ class sheepshaver_cpu void init_decoder(); void execute_sheep(uint32 opcode); - // CPU context to preserve on interrupt - class interrupt_context { - uint32 gpr[32]; - uint32 pc; - uint32 lr; - uint32 ctr; - uint32 cr; - uint32 xer; - sheepshaver_cpu *cpu; - const char *where; - public: - interrupt_context(sheepshaver_cpu *_cpu, const char *_where); - ~interrupt_context(); - }; - public: // Constructor @@ -192,7 +174,6 @@ public: // Handle MacOS interrupt void interrupt(uint32 entry); - void handle_interrupt(); // Make sure the SIGSEGV handler can access CPU registers friend sigsegv_return_t sigsegv_handler(sigsegv_address_t, sigsegv_address_t); @@ -477,46 +458,6 @@ int sheepshaver_cpu::compile1(codegen_co } #endif -// CPU context to preserve on interrupt -sheepshaver_cpu::interrupt_context::interrupt_context(sheepshaver_cpu *_cpu, const char *_where) -{ -#if SAFE_INTERRUPT_PPC >= 2 - cpu = _cpu; - where = _where; - - // Save interrupt context - memcpy(&gpr[0], &cpu->gpr(0), sizeof(gpr)); - pc = cpu->pc(); - lr = cpu->lr(); - ctr = cpu->ctr(); - cr = cpu->get_cr(); - xer = cpu->get_xer(); -#endif -} - -sheepshaver_cpu::interrupt_context::~interrupt_context() -{ -#if SAFE_INTERRUPT_PPC >= 2 - // Check whether CPU context was preserved by interrupt - if (memcmp(&gpr[0], &cpu->gpr(0), sizeof(gpr)) != 0) { - printf("FATAL: %s: interrupt clobbers registers\n", where); - for (int i = 0; i < 32; i++) - if (gpr[i] != cpu->gpr(i)) - printf(" r%d: %08x -> %08x\n", i, gpr[i], cpu->gpr(i)); - } - if (pc != cpu->pc()) - printf("FATAL: %s: interrupt clobbers PC\n", where); - if (lr != cpu->lr()) - printf("FATAL: %s: interrupt clobbers LR\n", where); - if (ctr != cpu->ctr()) - printf("FATAL: %s: interrupt clobbers CTR\n", where); - if (cr != cpu->get_cr()) - printf("FATAL: %s: interrupt clobbers CR\n", where); - if (xer != cpu->get_xer()) - printf("FATAL: %s: interrupt clobbers XER\n", where); -#endif -} - // Handle MacOS interrupt void sheepshaver_cpu::interrupt(uint32 entry) { @@ -525,13 +466,6 @@ void sheepshaver_cpu::interrupt(uint32 e const clock_t interrupt_start = clock(); #endif -#if SAFE_INTERRUPT_PPC - static int depth = 0; - if (depth != 0) - printf("FATAL: sheepshaver_cpu::interrupt() called more than once: %d\n", depth); - depth++; -#endif - // Save program counters and branch registers uint32 saved_pc = pc(); uint32 saved_lr = lr(); @@ -585,10 +519,6 @@ void sheepshaver_cpu::interrupt(uint32 e #if EMUL_TIME_STATS interrupt_time += (clock() - interrupt_start); #endif - -#if SAFE_INTERRUPT_PPC - depth--; -#endif } // Execute 68k routine @@ -988,7 +918,7 @@ void TriggerInterrupt(void) #endif } -void sheepshaver_cpu::handle_interrupt(void) +void HandleInterrupt(powerpc_registers *r) { #ifdef USE_SDL_VIDEO // We must fill in the events queue in the same thread that did call SDL_SetVideoMode() @@ -999,6 +929,10 @@ void sheepshaver_cpu::handle_interrupt(v 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; @@ -1006,22 +940,18 @@ void sheepshaver_cpu::handle_interrupt(v interrupt_count++; #endif - // Disable MacOS stack sniffer - WriteMacInt32(0x110, 0); - // Interrupt action depends on current run mode switch (ReadMacInt32(XLM_RUN_MODE)) { case MODE_68K: // 68k emulator active, trigger 68k interrupt level 1 WriteMacInt16(tswap32(kernel_data->v[0x67c >> 2]), 1); - set_cr(get_cr() | tswap32(kernel_data->v[0x674 >> 2])); + r->cr.set(r->cr.get() | tswap32(kernel_data->v[0x674 >> 2])); break; #if INTERRUPTS_IN_NATIVE_MODE case MODE_NATIVE: // 68k emulator inactive, in nanokernel? - if (gpr(1) != KernelDataAddr && interrupt_depth == 1) { - interrupt_context ctx(this, "PowerPC mode"); + if (r->gpr[1] != KernelDataAddr && interrupt_depth == 1) { // Prepare for 68k interrupt level 1 WriteMacInt16(tswap32(kernel_data->v[0x67c >> 2]), 1); @@ -1043,7 +973,6 @@ void sheepshaver_cpu::handle_interrupt(v case MODE_EMUL_OP: // 68k emulator active, within EMUL_OP routine, execute 68k interrupt routine directly when interrupt level is 0 if ((ReadMacInt32(XLM_68K_R25) & 7) == 0) { - interrupt_context ctx(this, "68k mode"); #if EMUL_TIME_STATS const clock_t interrupt_start = clock(); #endif