ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/SheepShaver/src/kpx_cpu/sheepshaver_glue.cpp
(Generate patch)

Comparing SheepShaver/src/kpx_cpu/sheepshaver_glue.cpp (file contents):
Revision 1.38 by gbeauche, 2004-05-19T21:23:16Z vs.
Revision 1.40 by gbeauche, 2004-05-20T11:47:27Z

# Line 147 | Line 147 | class sheepshaver_cpu
147          void execute_emul_op_idle_time_1();
148          void execute_emul_op_idle_time_2();
149  
150 +        // CPU context to preserve on interrupt
151 +        class interrupt_context {
152 +                uint32 gpr[32];
153 +                uint32 pc;
154 +                uint32 lr;
155 +                uint32 ctr;
156 +                uint32 cr;
157 +                uint32 xer;
158 +                sheepshaver_cpu *cpu;
159 +                const char *where;
160 +        public:
161 +                interrupt_context(sheepshaver_cpu *_cpu, const char *_where);
162 +                ~interrupt_context();
163 +        };
164 +
165   public:
166  
167          // Constructor
# Line 533 | Line 548 | int sheepshaver_cpu::compile1(codegen_co
548          return COMPILE_FAILURE;
549   }
550  
551 + // CPU context to preserve on interrupt
552 + sheepshaver_cpu::interrupt_context::interrupt_context(sheepshaver_cpu *_cpu, const char *_where)
553 + {
554 + #if SAFE_INTERRUPT_PPC >= 2
555 +        cpu = _cpu;
556 +        where = _where;
557 +
558 +        // Save interrupt context
559 +        memcpy(&gpr[0], &cpu->gpr(0), sizeof(gpr));
560 +        pc = cpu->pc();
561 +        lr = cpu->lr();
562 +        ctr = cpu->ctr();
563 +        cr = cpu->get_cr();
564 +        xer = cpu->get_xer();
565 + #endif
566 + }
567 +
568 + sheepshaver_cpu::interrupt_context::~interrupt_context()
569 + {
570 + #if SAFE_INTERRUPT_PPC >= 2
571 +        // Check whether CPU context was preserved by interrupt
572 +        if (memcmp(&gpr[0], &cpu->gpr(0), sizeof(gpr)) != 0) {
573 +                printf("FATAL: %s: interrupt clobbers registers\n", where);
574 +                for (int i = 0; i < 32; i++)
575 +                        if (gpr[i] != cpu->gpr(i))
576 +                                printf(" r%d: %08x -> %08x\n", i, gpr[i], cpu->gpr(i));
577 +        }
578 +        if (pc != cpu->pc())
579 +                printf("FATAL: %s: interrupt clobbers PC\n", where);
580 +        if (lr != cpu->lr())
581 +                printf("FATAL: %s: interrupt clobbers LR\n", where);
582 +        if (ctr != cpu->ctr())
583 +                printf("FATAL: %s: interrupt clobbers CTR\n", where);
584 +        if (cr != cpu->get_cr())
585 +                printf("FATAL: %s: interrupt clobbers CR\n", where);
586 +        if (xer != cpu->get_xer())
587 +                printf("FATAL: %s: interrupt clobbers XER\n", where);
588 + #endif
589 + }
590 +
591   // Handle MacOS interrupt
592   void sheepshaver_cpu::interrupt(uint32 entry)
593   {
# Line 547 | Line 602 | void sheepshaver_cpu::interrupt(uint32 e
602                  printf("FATAL: sheepshaver_cpu::interrupt() called more than once: %d\n", depth);
603          depth++;
604   #endif
550 #if SAFE_INTERRUPT_PPC >= 2
551        uint32 saved_regs[32];
552        memcpy(&saved_regs[0], &gpr(0), sizeof(saved_regs));
553 #endif
605  
606   #if !MULTICORE_CPU
607          // Save program counters and branch registers
# Line 610 | Line 661 | void sheepshaver_cpu::interrupt(uint32 e
661          interrupt_time += (clock() - interrupt_start);
662   #endif
663  
613 #if SAFE_INTERRUPT_PPC >= 2
614        if (memcmp(&saved_regs[0], &gpr(0), sizeof(saved_regs)) != 0)
615                printf("FATAL: dirty PowerPC registers\n");
616 #endif
664   #if SAFE_INTERRUPT_PPC
665          depth--;
666   #endif
# Line 1053 | Line 1100 | void sheepshaver_cpu::handle_interrupt(v
1100          if (InterruptFlags == 0)
1101                  return;
1102  
1103 +        // Current interrupt nest level
1104 +        static int interrupt_depth = 0;
1105 +        ++interrupt_depth;
1106 +
1107          // Disable MacOS stack sniffer
1108          WriteMacInt32(0x110, 0);
1109  
# Line 1069 | Line 1120 | void sheepshaver_cpu::handle_interrupt(v
1120          case MODE_NATIVE:
1121                  // 68k emulator inactive, in nanokernel?
1122                  assert(current_cpu == main_cpu);
1123 <                if (gpr(1) != KernelDataAddr) {
1123 >                if (gpr(1) != KernelDataAddr && interrupt_depth == 1) {
1124 >                        interrupt_context ctx(this, "PowerPC mode");
1125 >
1126                          // Prepare for 68k interrupt level 1
1127                          WriteMacInt16(tswap32(kernel_data->v[0x67c >> 2]), 1);
1128                          WriteMacInt32(tswap32(kernel_data->v[0x658 >> 2]) + 0xdc,
# Line 1092 | Line 1145 | void sheepshaver_cpu::handle_interrupt(v
1145          case MODE_EMUL_OP:
1146                  // 68k emulator active, within EMUL_OP routine, execute 68k interrupt routine directly when interrupt level is 0
1147                  if ((ReadMacInt32(XLM_68K_R25) & 7) == 0) {
1148 +                        interrupt_context ctx(this, "68k mode");
1149   #if 1
1150                          // Execute full 68k interrupt routine
1151                          M68kRegisters r;
# Line 1121 | Line 1175 | void sheepshaver_cpu::handle_interrupt(v
1175                  break;
1176   #endif
1177          }
1178 +
1179 +        // We are done with this interrupt
1180 +        --interrupt_depth;
1181   }
1182  
1183   static void get_resource(void);

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines