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.7 by gbeauche, 2003-10-12T05:44:15Z vs.
Revision 1.14 by gbeauche, 2003-11-03T21:28:29Z

# Line 28 | Line 28
28   #include "macos_util.h"
29   #include "block-alloc.hpp"
30   #include "sigsegv.h"
31 #include "spcflags.h"
31   #include "cpu/ppc/ppc-cpu.hpp"
32   #include "cpu/ppc/ppc-operations.hpp"
33  
# Line 44 | Line 43
43   #include "mon_disass.h"
44   #endif
45  
46 < #define DEBUG 1
46 > #define DEBUG 0
47   #include "debug.h"
48  
49   static void enter_mon(void)
# Line 57 | Line 56 | static void enter_mon(void)
56   }
57  
58   // Enable multicore (main/interrupts) cpu emulation?
59 < #define MULTICORE_CPU 0
59 > #define MULTICORE_CPU (ASYNC_IRQ ? 1 : 0)
60  
61   // Enable Execute68k() safety checks?
62   #define SAFE_EXEC_68K 1
# Line 79 | Line 78 | static KernelData * const kernel_data =
78   *              PowerPC emulator glue with special 'sheep' opcodes
79   **/
80  
82 struct sheepshaver_exec_return { };
83
81   class sheepshaver_cpu
82          : public powerpc_cpu
83   {
# Line 89 | Line 86 | class sheepshaver_cpu
86  
87   public:
88  
89 <        sheepshaver_cpu()
90 <                : powerpc_cpu()
94 <                { init_decoder(); }
89 >        // Constructor
90 >        sheepshaver_cpu();
91  
92          // Condition Register accessors
93          uint32 get_cr() const           { return cr().get(); }
94          void set_cr(uint32 v)           { cr().set(v); }
95  
96          // Execution loop
97 <        void execute(uint32 pc);
97 >        void execute(uint32 entry, bool enable_cache = false);
98  
99          // Execute 68k routine
100          void execute_68k(uint32 entry, M68kRegisters *r);
# Line 114 | Line 110 | public:
110  
111          // Handle MacOS interrupt
112          void interrupt(uint32 entry);
113 <
118 <        // spcflags for interrupts handling
119 <        static uint32 spcflags;
113 >        void handle_interrupt();
114  
115          // Lazy memory allocator (one item at a time)
116          void *operator new(size_t size)
# Line 128 | Line 122 | public:
122          void operator delete[](void *p);
123   };
124  
131 uint32 sheepshaver_cpu::spcflags = 0;
125   lazy_allocator< sheepshaver_cpu > allocator_helper< sheepshaver_cpu, lazy_allocator >::allocator;
126  
127 + sheepshaver_cpu::sheepshaver_cpu()
128 +        : powerpc_cpu()
129 + {
130 +        init_decoder();
131 + }
132 +
133   void sheepshaver_cpu::init_decoder()
134   {
135   #ifndef PPC_NO_STATIC_II_INDEX_TABLE
# Line 142 | Line 141 | void sheepshaver_cpu::init_decoder()
141  
142          static const instr_info_t sheep_ii_table[] = {
143                  { "sheep",
144 <                  (execute_fn)&sheepshaver_cpu::execute_sheep,
144 >                  (execute_pmf)&sheepshaver_cpu::execute_sheep,
145                    NULL,
146                    D_form, 6, 0, CFLOW_JUMP | CFLOW_TRAP
147                  }
# Line 181 | Line 180 | void sheepshaver_cpu::execute_sheep(uint
180          case 0:         // EMUL_RETURN
181                  QuitEmulator();
182                  break;
183 <                
183 >
184          case 1:         // EXEC_RETURN
185 <                throw sheepshaver_exec_return();
185 >                spcflags().set(SPCFLAG_CPU_EXEC_RETURN);
186                  break;
187  
188          case 2:         // EXEC_NATIVE
# Line 216 | Line 215 | void sheepshaver_cpu::execute_sheep(uint
215          }
216   }
217  
219 // Checks for pending interrupts
220 struct execute_nothing {
221        static inline void execute(powerpc_cpu *) { }
222 };
223
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 );
230                                enter_mon();
231                        }
232                        if (SPCFLAGS_TEST( SPCFLAG_DOINT )) {
233                                SPCFLAGS_CLEAR( SPCFLAG_DOINT );
234                                HandleInterrupt();
235                        }
236                        if (SPCFLAGS_TEST( SPCFLAG_INT )) {
237                                SPCFLAGS_CLEAR( SPCFLAG_INT );
238                                SPCFLAGS_SET( SPCFLAG_DOINT );
239                        }
240                }
241 #endif
242        }
243 };
244
218   // Execution loop
219 < void sheepshaver_cpu::execute(uint32 entry)
219 > void sheepshaver_cpu::execute(uint32 entry, bool enable_cache)
220   {
221 <        try {
249 <                pc() = entry;
250 <                powerpc_cpu::do_execute<execute_nothing, execute_spcflags_check>();
251 <        }
252 <        catch (sheepshaver_exec_return const &) {
253 <                // Nothing, simply return
254 <        }
255 <        catch (...) {
256 <                printf("ERROR: execute() received an unknown exception!\n");
257 <                QuitEmulator();
258 <        }
221 >        powerpc_cpu::execute(entry, enable_cache);
222   }
223  
224   // Handle MacOS interrupt
# Line 294 | Line 257 | void sheepshaver_cpu::interrupt(uint32 e
257          gpr(8)  = 0;
258          gpr(10) = (uint32)trampoline;
259          gpr(12) = (uint32)trampoline;
260 <        gpr(13) = cr().get();
260 >        gpr(13) = get_cr();
261  
262          // rlwimi. r7,r7,8,0,0
263          uint32 result = op_ppc_rlwimi::apply(gpr(7), 8, 0x80000000, gpr(7));
# Line 302 | Line 265 | void sheepshaver_cpu::interrupt(uint32 e
265          gpr(7) = result;
266  
267          gpr(11) = 0xf072; // MSR (SRR1)
268 <        cr().set((gpr(11) & 0x0fff0000) | (cr().get() & ~0x0fff0000));
268 >        cr().set((gpr(11) & 0x0fff0000) | (get_cr() & ~0x0fff0000));
269  
270          // Enter nanokernel
271          execute(entry);
# Line 328 | Line 291 | void sheepshaver_cpu::execute_68k(uint32
291          uint32 saved_pc = pc();
292          uint32 saved_lr = lr();
293          uint32 saved_ctr= ctr();
294 +        uint32 saved_cr = get_cr();
295  
296          // Create MacOS stack frame
297          // FIXME: make sure MacOS doesn't expect PPC registers to live on top
# Line 399 | Line 363 | void sheepshaver_cpu::execute_68k(uint32
363          pc() = saved_pc;
364          lr() = saved_lr;
365          ctr()= saved_ctr;
366 +        set_cr(saved_cr);
367   }
368  
369   // Call MacOS PPC code
# Line 588 | Line 553 | void init_emul_ppc(void)
553   }
554  
555   /*
556 + *  Deinitialize emulation
557 + */
558 +
559 + void exit_emul_ppc(void)
560 + {
561 +        delete main_cpu;
562 + #if MULTICORE_CPU
563 +        delete interrupt_cpu;
564 + #endif
565 + }
566 +
567 + /*
568   *  Emulation loop
569   */
570  
571   void emul_ppc(uint32 entry)
572   {
573          current_cpu = main_cpu;
574 + #if DEBUG
575          current_cpu->start_log();
576 <        current_cpu->execute(entry);
576 > #endif
577 >        // start emulation loop and enable code translation or caching
578 >        current_cpu->execute(entry, true);
579   }
580  
581   /*
582   *  Handle PowerPC interrupt
583   */
584  
585 < // Atomic operations
586 < extern int atomic_add(int *var, int v);
587 < extern int atomic_and(int *var, int v);
588 < extern int atomic_or(int *var, int v);
589 <
590 < #if !ASYNC_IRQ
585 > #if ASYNC_IRQ
586 > void HandleInterrupt(void)
587 > {
588 >        main_cpu->handle_interrupt();
589 > }
590 > #else
591   void TriggerInterrupt(void)
592   {
593   #if 0
594    WriteMacInt32(0x16a, ReadMacInt32(0x16a) + 1);
595   #else
596 <  SPCFLAGS_SET( SPCFLAG_INT );
596 >  // Trigger interrupt to main cpu only
597 >  if (main_cpu)
598 >          main_cpu->trigger_interrupt();
599   #endif
600   }
601   #endif
602  
603 < void HandleInterrupt(void)
603 > void sheepshaver_cpu::handle_interrupt(void)
604   {
605          // Do nothing if interrupts are disabled
606          if (int32(ReadMacInt32(XLM_IRQ_NEST)) > 0)
# Line 637 | Line 619 | void HandleInterrupt(void)
619                  // 68k emulator active, trigger 68k interrupt level 1
620                  assert(current_cpu == main_cpu);
621                  WriteMacInt16(tswap32(kernel_data->v[0x67c >> 2]), 1);
622 <                main_cpu->set_cr(main_cpu->get_cr() | tswap32(kernel_data->v[0x674 >> 2]));
622 >                set_cr(get_cr() | tswap32(kernel_data->v[0x674 >> 2]));
623                  break;
624      
625   #if INTERRUPTS_IN_NATIVE_MODE
626          case MODE_NATIVE:
627                  // 68k emulator inactive, in nanokernel?
628                  assert(current_cpu == main_cpu);
629 <                if (main_cpu->gpr(1) != KernelDataAddr) {
629 >                if (gpr(1) != KernelDataAddr) {
630                          // Prepare for 68k interrupt level 1
631                          WriteMacInt16(tswap32(kernel_data->v[0x67c >> 2]), 1);
632                          WriteMacInt32(tswap32(kernel_data->v[0x658 >> 2]) + 0xdc,
# Line 900 | Line 882 | uint32 call_macos7(uint32 tvect, uint32
882   }
883  
884   /*
903 *  Atomic operations
904 */
905
906 int atomic_add(int *var, int v)
907 {
908        int ret = *var;
909        *var += v;
910        return ret;
911 }
912
913 int atomic_and(int *var, int v)
914 {
915        int ret = *var;
916        *var &= v;
917        return ret;
918 }
919
920 int atomic_or(int *var, int v)
921 {
922        int ret = *var;
923        *var |= v;
924        return ret;
925 }
926
927 /*
885   *  Resource Manager thunks
886   */
887  

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines