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.39 by gbeauche, 2004-05-20T11:05:30Z

# 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 1070 | Line 1117 | void sheepshaver_cpu::handle_interrupt(v
1117                  // 68k emulator inactive, in nanokernel?
1118                  assert(current_cpu == main_cpu);
1119                  if (gpr(1) != KernelDataAddr) {
1120 +                        interrupt_context ctx(this, "PowerPC mode");
1121 +
1122                          // Prepare for 68k interrupt level 1
1123                          WriteMacInt16(tswap32(kernel_data->v[0x67c >> 2]), 1);
1124                          WriteMacInt32(tswap32(kernel_data->v[0x658 >> 2]) + 0xdc,
# Line 1092 | Line 1141 | void sheepshaver_cpu::handle_interrupt(v
1141          case MODE_EMUL_OP:
1142                  // 68k emulator active, within EMUL_OP routine, execute 68k interrupt routine directly when interrupt level is 0
1143                  if ((ReadMacInt32(XLM_68K_R25) & 7) == 0) {
1144 +                        interrupt_context ctx(this, "68k mode");
1145   #if 1
1146                          // Execute full 68k interrupt routine
1147                          M68kRegisters r;

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines