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

Comparing SheepShaver/src/thunks.cpp (file contents):
Revision 1.2 by gbeauche, 2003-12-04T23:37:35Z vs.
Revision 1.6 by gbeauche, 2004-01-24T11:28:04Z

# Line 22 | Line 22
22   #include "thunks.h"
23   #include "emul_op.h"
24   #include "cpu_emulation.h"
25 + #include "xlowmem.h"
26  
27   // Native function declarations
28   #include "main.h"
# Line 31 | Line 32
32   #include "ether.h"
33   #include "macos_util.h"
34  
35 + // Generate PowerPC thunks for GetResource() replacements?
36 + #define POWERPC_GET_RESOURCE_THUNKS 1
37 +
38  
39   /*              NativeOp instruction format:
40                  +------------+--------------------------+--+----------+------------+
# Line 53 | Line 57 | uint32 NativeOpcode(int selector)
57          switch (selector) {
58          case NATIVE_DISABLE_INTERRUPT:
59          case NATIVE_ENABLE_INTERRUPT:
60 +        case NATIVE_CHECK_LOAD_INVOC:
61                  opcode = POWERPC_NATIVE_OP(0, selector);
62                  break;
63          case NATIVE_PATCH_NAME_REGISTRY:
# Line 90 | Line 95 | uint32 NativeOpcode(int selector)
95  
96  
97   /*
98 + *  Generate PowerPC thunks for GetResource() replacements
99 + */
100 +
101 + #if EMULATED_PPC
102 + static uint32 get_resource_func;
103 + static uint32 get_1_resource_func;
104 + static uint32 get_ind_resource_func;
105 + static uint32 get_1_ind_resource_func;
106 + static uint32 r_get_resource_func;
107 +
108 + static void generate_powerpc_thunks(void)
109 + {
110 +        static uint32 get_resource_template[] = {
111 +                PL(0x7c0802a6),         // mflr    r0
112 +                PL(0x90010008),         // stw     r0,8(r1)
113 +                PL(0x9421ffbc),         // stwu    r1,-68(r1)
114 +                PL(0x90610038),         // stw     r3,56(r1)
115 +                PL(0x9081003c),         // stw     r4,60(r1)
116 +                PL(0x00000000),         // lwz     r0,XLM_GET_RESOURCE(r0)
117 +                PL(0x80402834),         // lwz     r2,XLM_RES_LIB_TOC(r0)
118 +                PL(0x7c0903a6),         // mtctr   r0
119 +                PL(0x4e800421),         // bctrl
120 +                PL(0x90610040),         // stw     r3,64(r1)
121 +                PL(0x80610038),         // lwz     r3,56(r1)
122 +                PL(0xa881003e),         // lha     r4,62(r1)
123 +                PL(0x80a10040),         // lwz     r5,64(r1)
124 +                PL(0x00000001),         // <check_load_invoc>
125 +                PL(0x80610040),         // lwz     r3,64(r1)
126 +                PL(0x8001004c),         // lwz     r0,76(r1)
127 +                PL(0x7c0803a6),         // mtlr    r0
128 +                PL(0x38210044),         // addi    r1,r1,68
129 +                PL(0x4e800020)          // blr
130 +        };
131 +        const uint32 get_resource_template_size = sizeof(get_resource_template);
132 +
133 +        int xlm_index = -1, check_load_invoc_index = -1;
134 +        for (int i = 0; i < get_resource_template_size/4; i++) {
135 +                uint32 opcode = ntohl(get_resource_template[i]);
136 +                switch (opcode) {
137 +                case 0x00000000:
138 +                        xlm_index = i;
139 +                        break;
140 +                case 0x00000001:
141 +                        check_load_invoc_index = i;
142 +                        break;
143 +                }
144 +        }
145 +        assert(xlm_index != -1 && check_load_invoc_index != -1);
146 +
147 +        uint32 check_load_invoc_opcode = NativeOpcode(NATIVE_CHECK_LOAD_INVOC);
148 +        uintptr base;
149 +
150 +        // GetResource()
151 +        get_resource_func = base = SheepMem::Reserve(get_resource_template_size);
152 +        Host2Mac_memcpy(base, get_resource_template, get_resource_template_size);
153 +        WriteMacInt32(base + xlm_index * 4, 0x80000000 | XLM_GET_RESOURCE);
154 +        WriteMacInt32(base + check_load_invoc_index * 4, check_load_invoc_opcode);
155 +
156 +        // Get1Resource()
157 +        get_1_resource_func = base = SheepMem::Reserve(get_resource_template_size);
158 +        Host2Mac_memcpy(base, get_resource_template, get_resource_template_size);
159 +        WriteMacInt32(base + xlm_index * 4, 0x80000000 | XLM_GET_1_RESOURCE);
160 +        WriteMacInt32(base + check_load_invoc_index * 4, check_load_invoc_opcode);
161 +
162 +        // GetIndResource()
163 +        get_ind_resource_func = base = SheepMem::Reserve(get_resource_template_size);
164 +        Host2Mac_memcpy(base, get_resource_template, get_resource_template_size);
165 +        WriteMacInt32(base + xlm_index * 4, 0x80000000 | XLM_GET_IND_RESOURCE);
166 +        WriteMacInt32(base + check_load_invoc_index * 4, check_load_invoc_opcode);
167 +
168 +        // Get1IndResource()
169 +        get_1_ind_resource_func = base = SheepMem::Reserve(get_resource_template_size);
170 +        Host2Mac_memcpy(base, get_resource_template, get_resource_template_size);
171 +        WriteMacInt32(base + xlm_index * 4, 0x80000000 | XLM_GET_1_IND_RESOURCE);
172 +        WriteMacInt32(base + check_load_invoc_index * 4, check_load_invoc_opcode);
173 +
174 +        // RGetResource()
175 +        r_get_resource_func = base = SheepMem::Reserve(get_resource_template_size);
176 +        Host2Mac_memcpy(base, get_resource_template, get_resource_template_size);
177 +        WriteMacInt32(base + xlm_index * 4, 0x80000000 | XLM_R_GET_RESOURCE);
178 +        WriteMacInt32(base + check_load_invoc_index * 4, check_load_invoc_opcode);
179 + }
180 + #endif
181 +
182 +
183 + /*
184   *  Initialize the thunks system
185   */
186  
187   struct native_op_t {
188          uint32 tvect;
189          uint32 func;
190 +        SheepRoutineDescriptor *desc;
191   };
192   static native_op_t native_op[NATIVE_OP_MAX];
193  
# Line 110 | Line 202 | bool ThunksInit(void)
202                  native_op[i].tvect = base;
203                  native_op[i].func  = base + 8;
204          }
205 + #if POWERPC_GET_RESOURCE_THUNKS
206 +        generate_powerpc_thunks();
207 +        native_op[NATIVE_GET_RESOURCE].func = get_resource_func;
208 +        native_op[NATIVE_GET_1_RESOURCE].func = get_1_resource_func;
209 +        native_op[NATIVE_GET_IND_RESOURCE].func = get_ind_resource_func;
210 +        native_op[NATIVE_GET_1_IND_RESOURCE].func = get_1_ind_resource_func;
211 +        native_op[NATIVE_R_GET_RESOURCE].func = r_get_resource_func;
212 + #endif
213   #else
214 < #if defined(__linux__)
214 > #if defined(__linux__) || (defined(__APPLE__) && defined(__MACH__))
215   #define DEFINE_NATIVE_OP(ID, FUNC) do {                         \
216                  uintptr base = SheepMem::Reserve(8);            \
217                  WriteMacInt32(base + 0, (uint32)FUNC);          \
# Line 127 | Line 227 | bool ThunksInit(void)
227   #else
228   #error "FIXME: define NativeOp for your platform"
229   #endif
230 +        // FIXME: add GetResource() and friends for completeness
231          DEFINE_NATIVE_OP(NATIVE_PATCH_NAME_REGISTRY, DoPatchNameRegistry);
232          DEFINE_NATIVE_OP(NATIVE_VIDEO_INSTALL_ACCEL, VideoInstallAccel);
233          DEFINE_NATIVE_OP(NATIVE_VIDEO_VBL, VideoVBL);
# Line 148 | Line 249 | bool ThunksInit(void)
249          DEFINE_NATIVE_OP(NATIVE_MAKE_EXECUTABLE, MakeExecutable);
250   #undef DEFINE_NATIVE_OP
251   #endif
252 +
253 +        // Initialize routine descriptors (if TVECT exists)
254 +        for (int i = 0; i < NATIVE_OP_MAX; i++) {
255 +                uint32 tvect = native_op[i].tvect;
256 +                if (tvect)
257 +                        native_op[i].desc = new SheepRoutineDescriptor(0, tvect);
258 +        }
259 +
260          return true;
261   }
262  
263  
264   /*
265 + *  Delete generated thunks
266 + */
267 +
268 + void ThunksExit(void)
269 + {
270 +        for (int i = 0; i < NATIVE_OP_MAX; i++) {
271 +                SheepRoutineDescriptor *desc = native_op[i].desc;
272 +                if (desc)
273 +                        delete desc;
274 +        }
275 + }
276 +
277 +
278 + /*
279   *  Return the native function descriptor (TVECT)
280   */
281  
# Line 179 | Line 302 | uint32 NativeFunction(int selector)
302  
303  
304   /*
305 + *  Return the routine descriptor address of the native function
306 + */
307 +
308 + uint32 NativeRoutineDescriptor(int selector)
309 + {
310 +        assert(selector < NATIVE_OP_MAX);
311 +        SheepRoutineDescriptor * const desc = native_op[selector].desc;
312 +        assert(desc != 0);
313 +        return desc->addr();
314 + }
315 +
316 +
317 + /*
318   *  Execute native code from EMUL_OP routine (real mode switch)
319   */
320  
321   void ExecuteNative(int selector)
322   {
187        SheepRoutineDescriptor desc(0, NativeTVECT(selector));
323          M68kRegisters r;
324 <        Execute68k(desc.addr(), &r);
324 >        Execute68k(NativeRoutineDescriptor(selector), &r);
325   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines