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.3 by gbeauche, 2003-09-29T07:05:15Z vs.
Revision 1.8 by gbeauche, 2003-10-19T21:37:43Z

# Line 71 | Line 71 | static void enter_mon(void)
71   // Interrupts in native mode?
72   #define INTERRUPTS_IN_NATIVE_MODE 1
73  
74 // 68k Emulator Data
75 struct EmulatorData {
76        uint32  v[0x400];      
77 };
78
79 // Kernel Data
80 struct KernelData {
81        uint32  v[0x400];
82        EmulatorData ed;
83 };
84
74   // Pointer to Kernel Data
75 < static KernelData * const kernel_data = (KernelData *)0x68ffe000;
75 > static KernelData * const kernel_data = (KernelData *)KERNEL_DATA_BASE;
76  
77  
78   /**
# Line 124 | Line 113 | public:
113          void get_resource(uint32 old_get_resource);
114  
115          // Handle MacOS interrupt
116 <        void interrupt(uint32 entry, sheepshaver_cpu *cpu);
116 >        void interrupt(uint32 entry);
117  
118          // spcflags for interrupts handling
119          static uint32 spcflags;
# Line 155 | Line 144 | void sheepshaver_cpu::init_decoder()
144                  { "sheep",
145                    (execute_fn)&sheepshaver_cpu::execute_sheep,
146                    NULL,
147 <                  D_form, 6, 0, CFLOW_TRAP
147 >                  D_form, 6, 0, CFLOW_JUMP | CFLOW_TRAP
148                  }
149          };
150  
# Line 192 | Line 181 | void sheepshaver_cpu::execute_sheep(uint
181          case 0:         // EMUL_RETURN
182                  QuitEmulator();
183                  break;
184 <                
184 >
185          case 1:         // EXEC_RETURN
186                  throw sheepshaver_exec_return();
187                  break;
# Line 232 | Line 221 | struct execute_nothing {
221          static inline void execute(powerpc_cpu *) { }
222   };
223  
235 static void HandleInterrupt(void);
236
224   struct execute_spcflags_check {
225          static inline void execute(powerpc_cpu *cpu) {
226 + #if !ASYNC_IRQ
227                  if (SPCFLAGS_TEST(SPCFLAG_ALL_BUT_EXEC_RETURN)) {
228                          if (SPCFLAGS_TEST( SPCFLAG_ENTER_MON )) {
229                                  SPCFLAGS_CLEAR( SPCFLAG_ENTER_MON );
# Line 250 | Line 238 | struct execute_spcflags_check {
238                                  SPCFLAGS_SET( SPCFLAG_DOINT );
239                          }
240                  }
241 + #endif
242          }
243   };
244  
# Line 270 | Line 259 | void sheepshaver_cpu::execute(uint32 ent
259   }
260  
261   // Handle MacOS interrupt
262 < void sheepshaver_cpu::interrupt(uint32 entry, sheepshaver_cpu *cpu)
262 > void sheepshaver_cpu::interrupt(uint32 entry)
263   {
264 < #if MULTICORE_CPU
276 <        // Initialize stack pointer from previous CPU running
277 <        gpr(1) = cpu->gpr(1);
278 < #else
264 > #if !MULTICORE_CPU
265          // Save program counters and branch registers
266          uint32 saved_pc = pc();
267          uint32 saved_lr = lr();
268          uint32 saved_ctr= ctr();
269 +        uint32 saved_sp = gpr(1);
270   #endif
271  
272 <        // Create stack frame
273 <        gpr(1) -= 64;
272 >        // Initialize stack pointer to SheepShaver alternate stack base
273 >        gpr(1) = SheepStack1Base - 64;
274  
275          // Build trampoline to return from interrupt
276 <        uint32 trampoline[] = { POWERPC_EMUL_OP | 1 };
276 >        uint32 trampoline[] = { htonl(POWERPC_EMUL_OP | 1) };
277  
278          // Prepare registers for nanokernel interrupt routine
279 <        kernel_data->v[0x004 >> 2] = gpr(1);
280 <        kernel_data->v[0x018 >> 2] = gpr(6);
279 >        kernel_data->v[0x004 >> 2] = htonl(gpr(1));
280 >        kernel_data->v[0x018 >> 2] = htonl(gpr(6));
281  
282 <        gpr(6) = kernel_data->v[0x65c >> 2];
282 >        gpr(6) = ntohl(kernel_data->v[0x65c >> 2]);
283          assert(gpr(6) != 0);
284          WriteMacInt32(gpr(6) + 0x13c, gpr(7));
285          WriteMacInt32(gpr(6) + 0x144, gpr(8));
# Line 303 | Line 290 | void sheepshaver_cpu::interrupt(uint32 e
290          WriteMacInt32(gpr(6) + 0x16c, gpr(13));
291  
292          gpr(1)  = KernelDataAddr;
293 <        gpr(7)  = kernel_data->v[0x660 >> 2];
293 >        gpr(7)  = ntohl(kernel_data->v[0x660 >> 2]);
294          gpr(8)  = 0;
295          gpr(10) = (uint32)trampoline;
296          gpr(12) = (uint32)trampoline;
297 <        gpr(13) = cr().get();
297 >        gpr(13) = get_cr();
298  
299          // rlwimi. r7,r7,8,0,0
300          uint32 result = op_ppc_rlwimi::apply(gpr(7), 8, 0x80000000, gpr(7));
# Line 315 | Line 302 | void sheepshaver_cpu::interrupt(uint32 e
302          gpr(7) = result;
303  
304          gpr(11) = 0xf072; // MSR (SRR1)
305 <        cr().set((gpr(11) & 0x0fff0000) | (cr().get() & ~0x0fff0000));
305 >        cr().set((gpr(11) & 0x0fff0000) | (get_cr() & ~0x0fff0000));
306  
307          // Enter nanokernel
308          execute(entry);
309  
323        // Cleanup stack
324        gpr(1) += 64;
325
310   #if !MULTICORE_CPU
311          // Restore program counters and branch registers
312          pc() = saved_pc;
313          lr() = saved_lr;
314          ctr()= saved_ctr;
315 +        gpr(1) = saved_sp;
316   #endif
317   }
318  
# Line 343 | Line 328 | void sheepshaver_cpu::execute_68k(uint32
328          uint32 saved_pc = pc();
329          uint32 saved_lr = lr();
330          uint32 saved_ctr= ctr();
331 +        uint32 saved_cr = get_cr();
332  
333          // Create MacOS stack frame
334 +        // FIXME: make sure MacOS doesn't expect PPC registers to live on top
335          uint32 sp = gpr(1);
336 <        gpr(1) -= 56 + 19*4 + 18*8;
336 >        gpr(1) -= 56;
337          WriteMacInt32(gpr(1), sp);
338  
339          // Save PowerPC registers
340 <        memcpy(Mac2HostAddr(gpr(1)+56), &gpr(13), sizeof(uint32)*(32-13));
340 >        uint32 saved_GPRs[19];
341 >        memcpy(&saved_GPRs[0], &gpr(13), sizeof(uint32)*(32-13));
342   #if SAVE_FP_EXEC_68K
343 <        memcpy(Mac2HostAddr(gpr(1)+56+19*4), &fpr(14), sizeof(double)*(32-14));
343 >        double saved_FPRs[18];
344 >        memcpy(&saved_FPRs[0], &fpr(14), sizeof(double)*(32-14));
345   #endif
346  
347          // Setup registers for 68k emulator
# Line 366 | Line 355 | void sheepshaver_cpu::execute_68k(uint32
355          gpr(25) = ReadMacInt32(XLM_68K_R25);            // MSB of SR
356          gpr(26) = 0;
357          gpr(28) = 0;                                                            // VBR
358 <        gpr(29) = kernel_data->ed.v[0x74 >> 2];         // Pointer to opcode table
359 <        gpr(30) = kernel_data->ed.v[0x78 >> 2];         // Address of emulator
358 >        gpr(29) = ntohl(kernel_data->ed.v[0x74 >> 2]);          // Pointer to opcode table
359 >        gpr(30) = ntohl(kernel_data->ed.v[0x78 >> 2]);          // Address of emulator
360          gpr(31) = KernelDataAddr + 0x1000;
361  
362          // Push return address (points to EXEC_RETURN opcode) on stack
# Line 399 | Line 388 | void sheepshaver_cpu::execute_68k(uint32
388            r->a[i] = gpr(16 + i);
389  
390          // Restore PowerPC registers
391 <        memcpy(&gpr(13), Mac2HostAddr(gpr(1)+56), sizeof(uint32)*(32-13));
391 >        memcpy(&gpr(13), &saved_GPRs[0], sizeof(uint32)*(32-13));
392   #if SAVE_FP_EXEC_68K
393 <        memcpy(&fpr(14), Mac2HostAddr(gpr(1)+56+19*4), sizeof(double)*(32-14));
393 >        memcpy(&fpr(14), &saved_FPRs[0], sizeof(double)*(32-14));
394   #endif
395  
396          // Cleanup stack
397 <        gpr(1) += 56 + 19*4 + 18*8;
397 >        gpr(1) += 56;
398  
399          // Restore program counters and branch registers
400          pc() = saved_pc;
401          lr() = saved_lr;
402          ctr()= saved_ctr;
403 +        set_cr(saved_cr);
404   }
405  
406   // Call MacOS PPC code
# Line 422 | Line 412 | uint32 sheepshaver_cpu::execute_macos_co
412          uint32 saved_ctr= ctr();
413  
414          // Build trampoline with EXEC_RETURN
415 <        uint32 trampoline[] = { POWERPC_EMUL_OP | 1 };
415 >        uint32 trampoline[] = { htonl(POWERPC_EMUL_OP | 1) };
416          lr() = (uint32)trampoline;
417  
418          gpr(1) -= 64;                                                           // Create stack frame
# Line 462 | Line 452 | inline void sheepshaver_cpu::execute_ppc
452   {
453          // Save branch registers
454          uint32 saved_lr = lr();
465        uint32 saved_ctr= ctr();
466
467        const uint32 trampoline[] = { POWERPC_EMUL_OP | 1 };
455  
456 +        const uint32 trampoline[] = { htonl(POWERPC_EMUL_OP | 1) };
457          lr() = (uint32)trampoline;
458 <        ctr()= entry;
458 >
459          execute(entry);
460  
461          // Restore branch registers
462          lr() = saved_lr;
475        ctr()= saved_ctr;
463   }
464  
465   // Resource Manager thunk
466 < extern "C" void check_load_invoc(uint32 type, int16 id, uint16 **h);
466 > extern "C" void check_load_invoc(uint32 type, int16 id, uint32 h);
467  
468   inline void sheepshaver_cpu::get_resource(uint32 old_get_resource)
469   {
# Line 488 | Line 475 | inline void sheepshaver_cpu::get_resourc
475  
476          // Call old routine
477          execute_ppc(old_get_resource);
491        uint16 **handle = (uint16 **)gpr(3);
478  
479          // Call CheckLoad()
480 +        uint32 handle = gpr(3);
481          check_load_invoc(type, id, handle);
482 <        gpr(3) = (uint32)handle;
482 >        gpr(3) = handle;
483  
484          // Cleanup stack
485          gpr(1) += 56;
# Line 507 | Line 494 | static sheepshaver_cpu *main_cpu = NULL;
494   static sheepshaver_cpu *interrupt_cpu = NULL;   // CPU emulator to handle interrupts
495   static sheepshaver_cpu *current_cpu = NULL;             // Current CPU emulator context
496  
497 + void FlushCodeCache(uintptr start, uintptr end)
498 + {
499 +        D(bug("FlushCodeCache(%08x, %08x)\n", start, end));
500 +        main_cpu->invalidate_cache_range(start, end);
501 + #if MULTICORE_CPU
502 +        interrupt_cpu->invalidate_cache_range(start, end);
503 + #endif
504 + }
505 +
506   static inline void cpu_push(sheepshaver_cpu *new_cpu)
507   {
508   #if MULTICORE_CPU
# Line 585 | Line 581 | void init_emul_ppc(void)
581  
582          // Install the handler for SIGSEGV
583          sigsegv_install_handler(sigsegv_handler);
584 <        
584 >
585   #if ENABLE_MON
586          // Install "regs" command in cxmon
587          mon_add_command("regs", dump_registers, "regs                     Dump PowerPC registers\n");
# Line 613 | Line 609 | extern int atomic_add(int *var, int v);
609   extern int atomic_and(int *var, int v);
610   extern int atomic_or(int *var, int v);
611  
612 + #if !ASYNC_IRQ
613   void TriggerInterrupt(void)
614   {
615   #if 0
# Line 621 | Line 618 | void TriggerInterrupt(void)
618    SPCFLAGS_SET( SPCFLAG_INT );
619   #endif
620   }
621 + #endif
622  
623 < static void HandleInterrupt(void)
623 > void HandleInterrupt(void)
624   {
625          // Do nothing if interrupts are disabled
626          if (int32(ReadMacInt32(XLM_IRQ_NEST)) > 0)
# Line 659 | Line 657 | static void HandleInterrupt(void)
657                          DisableInterrupt();
658                          cpu_push(interrupt_cpu);
659                          if (ROMType == ROMTYPE_NEWWORLD)
660 <                                current_cpu->interrupt(ROM_BASE + 0x312b1c, main_cpu);
660 >                                current_cpu->interrupt(ROM_BASE + 0x312b1c);
661                          else
662 <                                current_cpu->interrupt(ROM_BASE + 0x312a3c, main_cpu);
662 >                                current_cpu->interrupt(ROM_BASE + 0x312a3c);
663                          cpu_pop();
664                  }
665                  break;
# Line 736 | Line 734 | const uint32 NativeOpTable[NATIVE_OP_MAX
734          POWERPC_NATIVE_OP_INIT(1, NATIVE_R_GET_RESOURCE),
735          POWERPC_NATIVE_OP_INIT(0, NATIVE_DISABLE_INTERRUPT),
736          POWERPC_NATIVE_OP_INIT(0, NATIVE_ENABLE_INTERRUPT),
737 +        POWERPC_NATIVE_OP_INIT(1, NATIVE_MAKE_EXECUTABLE),
738   };
739  
740   static void get_resource(void);
# Line 803 | Line 802 | static void NativeOp(int selector)
802          case NATIVE_ENABLE_INTERRUPT:
803                  EnableInterrupt();
804                  break;
805 +        case NATIVE_MAKE_EXECUTABLE:
806 +                MakeExecutable(0, (void *)GPR(4), GPR(5));
807 +                break;
808          default:
809                  printf("FATAL: NATIVE_OP called with bogus selector %d\n", selector);
810                  QuitEmulator();
# Line 842 | Line 844 | void Execute68k(uint32 pc, M68kRegisters
844  
845   void Execute68kTrap(uint16 trap, M68kRegisters *r)
846   {
847 <        uint16 proc[2] = {trap, M68K_RTS};
847 >        uint16 proc[2];
848 >        proc[0] = htons(trap);
849 >        proc[1] = htons(M68K_RTS);
850          Execute68k((uint32)proc, r);
851   }
852  

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines