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.14 by gbeauche, 2005-07-03T22:02:01Z

# 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 <                +------------+--------------------------+--+----------+------------+
41 <                |      6     |                          |FN|    OP    |      2     |
42 <                +------------+--------------------------+--+----------+------------+
43 <                 0         5 |6                       19 20 21      25 26        31
40 >                +------------+-------------------------+--+-----------+------------+
41 >                |      6     |                         |FN|    OP     |      2     |
42 >                +------------+-------------------------+--+-----------+------------+
43 >                 0         5 |6                      18 19 20      25 26        31
44   */
45  
46 < #define POWERPC_NATIVE_OP(LR, OP) \
47 <                (POWERPC_EMUL_OP | ((LR) << 11) | (((uint32)OP) << 6) | 2)
46 > #define POWERPC_NATIVE_OP(FN, OP) \
47 >                (POWERPC_EMUL_OP | ((FN) << 12) | (((uint32)OP) << 6) | 2)
48  
49   /*
50   *  Return the fake PowerPC opcode to handle specified native code
# Line 51 | Line 55 | uint32 NativeOpcode(int selector)
55   {
56          uint32 opcode;
57          switch (selector) {
58 <        case NATIVE_DISABLE_INTERRUPT:
55 <        case NATIVE_ENABLE_INTERRUPT:
58 >        case NATIVE_CHECK_LOAD_INVOC:
59                  opcode = POWERPC_NATIVE_OP(0, selector);
60                  break;
61          case NATIVE_PATCH_NAME_REGISTRY:
62          case NATIVE_VIDEO_INSTALL_ACCEL:
63          case NATIVE_VIDEO_VBL:
64          case NATIVE_VIDEO_DO_DRIVER_IO:
65 +        case NATIVE_ETHER_AO_GET_HWADDR:
66 +        case NATIVE_ETHER_AO_ADD_MULTI:
67 +        case NATIVE_ETHER_AO_DEL_MULTI:
68 +        case NATIVE_ETHER_AO_SEND_PACKET:
69          case NATIVE_ETHER_IRQ:
70          case NATIVE_ETHER_INIT:
71          case NATIVE_ETHER_TERM:
# Line 79 | Line 86 | uint32 NativeOpcode(int selector)
86          case NATIVE_GET_1_IND_RESOURCE:
87          case NATIVE_R_GET_RESOURCE:
88          case NATIVE_MAKE_EXECUTABLE:
89 +        case NATIVE_SYNC_HOOK:
90 +        case NATIVE_BITBLT_HOOK:
91 +        case NATIVE_FILLRECT_HOOK:
92 +        case NATIVE_BITBLT:
93 +        case NATIVE_INVRECT:
94 +        case NATIVE_FILLRECT:
95                  opcode = POWERPC_NATIVE_OP(1, selector);
96                  break;
97          default:
# Line 90 | Line 103 | uint32 NativeOpcode(int selector)
103  
104  
105   /*
106 + *  Generate PowerPC thunks for GetResource() replacements
107 + */
108 +
109 + #if EMULATED_PPC
110 + static uint32 get_resource_func;
111 + static uint32 get_1_resource_func;
112 + static uint32 get_ind_resource_func;
113 + static uint32 get_1_ind_resource_func;
114 + static uint32 r_get_resource_func;
115 +
116 + static void generate_powerpc_thunks(void)
117 + {
118 +        static uint32 get_resource_template[] = {
119 +                PL(0x7c0802a6),         // mflr    r0
120 +                PL(0x90010008),         // stw     r0,8(r1)
121 +                PL(0x9421ffbc),         // stwu    r1,-68(r1)
122 +                PL(0x90610038),         // stw     r3,56(r1)
123 +                PL(0x9081003c),         // stw     r4,60(r1)
124 +                PL(0x00000000),         // lwz     r0,XLM_GET_RESOURCE(r0)
125 +                PL(0x80402834),         // lwz     r2,XLM_RES_LIB_TOC(r0)
126 +                PL(0x7c0903a6),         // mtctr   r0
127 +                PL(0x4e800421),         // bctrl
128 +                PL(0x90610040),         // stw     r3,64(r1)
129 +                PL(0x80610038),         // lwz     r3,56(r1)
130 +                PL(0xa881003e),         // lha     r4,62(r1)
131 +                PL(0x80a10040),         // lwz     r5,64(r1)
132 +                PL(0x00000001),         // <check_load_invoc>
133 +                PL(0x80610040),         // lwz     r3,64(r1)
134 +                PL(0x8001004c),         // lwz     r0,76(r1)
135 +                PL(0x7c0803a6),         // mtlr    r0
136 +                PL(0x38210044),         // addi    r1,r1,68
137 +                PL(0x4e800020)          // blr
138 +        };
139 +        const uint32 get_resource_template_size = sizeof(get_resource_template);
140 +
141 +        int xlm_index = -1, check_load_invoc_index = -1;
142 +        for (int i = 0; i < get_resource_template_size/4; i++) {
143 +                uint32 opcode = ntohl(get_resource_template[i]);
144 +                switch (opcode) {
145 +                case 0x00000000:
146 +                        xlm_index = i;
147 +                        break;
148 +                case 0x00000001:
149 +                        check_load_invoc_index = i;
150 +                        break;
151 +                }
152 +        }
153 +        assert(xlm_index != -1 && check_load_invoc_index != -1);
154 +
155 +        uint32 check_load_invoc_opcode = NativeOpcode(NATIVE_CHECK_LOAD_INVOC);
156 +        uint32 base;
157 +
158 +        // GetResource()
159 +        get_resource_func = base = SheepMem::Reserve(get_resource_template_size);
160 +        Host2Mac_memcpy(base, get_resource_template, get_resource_template_size);
161 +        WriteMacInt32(base + xlm_index * 4, 0x80000000 | XLM_GET_RESOURCE);
162 +        WriteMacInt32(base + check_load_invoc_index * 4, check_load_invoc_opcode);
163 +
164 +        // Get1Resource()
165 +        get_1_resource_func = base = SheepMem::Reserve(get_resource_template_size);
166 +        Host2Mac_memcpy(base, get_resource_template, get_resource_template_size);
167 +        WriteMacInt32(base + xlm_index * 4, 0x80000000 | XLM_GET_1_RESOURCE);
168 +        WriteMacInt32(base + check_load_invoc_index * 4, check_load_invoc_opcode);
169 +
170 +        // GetIndResource()
171 +        get_ind_resource_func = base = SheepMem::Reserve(get_resource_template_size);
172 +        Host2Mac_memcpy(base, get_resource_template, get_resource_template_size);
173 +        WriteMacInt32(base + xlm_index * 4, 0x80000000 | XLM_GET_IND_RESOURCE);
174 +        WriteMacInt32(base + check_load_invoc_index * 4, check_load_invoc_opcode);
175 +
176 +        // Get1IndResource()
177 +        get_1_ind_resource_func = base = SheepMem::Reserve(get_resource_template_size);
178 +        Host2Mac_memcpy(base, get_resource_template, get_resource_template_size);
179 +        WriteMacInt32(base + xlm_index * 4, 0x80000000 | XLM_GET_1_IND_RESOURCE);
180 +        WriteMacInt32(base + check_load_invoc_index * 4, check_load_invoc_opcode);
181 +
182 +        // RGetResource()
183 +        r_get_resource_func = base = SheepMem::Reserve(get_resource_template_size);
184 +        Host2Mac_memcpy(base, get_resource_template, get_resource_template_size);
185 +        WriteMacInt32(base + xlm_index * 4, 0x80000000 | XLM_R_GET_RESOURCE);
186 +        WriteMacInt32(base + check_load_invoc_index * 4, check_load_invoc_opcode);
187 + }
188 + #endif
189 +
190 +
191 + /*
192   *  Initialize the thunks system
193   */
194  
195   struct native_op_t {
196          uint32 tvect;
197          uint32 func;
198 +        SheepRoutineDescriptor *desc;
199   };
200   static native_op_t native_op[NATIVE_OP_MAX];
201  
# Line 110 | Line 210 | bool ThunksInit(void)
210                  native_op[i].tvect = base;
211                  native_op[i].func  = base + 8;
212          }
213 + #if POWERPC_GET_RESOURCE_THUNKS
214 +        generate_powerpc_thunks();
215 +        native_op[NATIVE_GET_RESOURCE].func = get_resource_func;
216 +        native_op[NATIVE_GET_1_RESOURCE].func = get_1_resource_func;
217 +        native_op[NATIVE_GET_IND_RESOURCE].func = get_ind_resource_func;
218 +        native_op[NATIVE_GET_1_IND_RESOURCE].func = get_1_ind_resource_func;
219 +        native_op[NATIVE_R_GET_RESOURCE].func = r_get_resource_func;
220 + #endif
221   #else
222 < #if defined(__linux__)
222 > #if defined(__linux__) || defined(__NetBSD__) || (defined(__APPLE__) && defined(__MACH__))
223   #define DEFINE_NATIVE_OP(ID, FUNC) do {                         \
224                  uintptr base = SheepMem::Reserve(8);            \
225                  WriteMacInt32(base + 0, (uint32)FUNC);          \
226 <                WriteMacInt32(base + 4, 0); /*Fake TVECT*/      \
226 >                WriteMacInt32(base + 4, (uint32)TOC);           \
227                  native_op[ID].tvect = base;                                     \
228                  native_op[ID].func  = (uint32)FUNC;                     \
229          } while (0)
# Line 127 | Line 235 | bool ThunksInit(void)
235   #else
236   #error "FIXME: define NativeOp for your platform"
237   #endif
238 +        // FIXME: add GetResource() and friends for completeness
239          DEFINE_NATIVE_OP(NATIVE_PATCH_NAME_REGISTRY, DoPatchNameRegistry);
240          DEFINE_NATIVE_OP(NATIVE_VIDEO_INSTALL_ACCEL, VideoInstallAccel);
241          DEFINE_NATIVE_OP(NATIVE_VIDEO_VBL, VideoVBL);
242          DEFINE_NATIVE_OP(NATIVE_VIDEO_DO_DRIVER_IO, VideoDoDriverIO);
243 +        DEFINE_NATIVE_OP(NATIVE_ETHER_AO_GET_HWADDR, AO_get_ethernet_address);
244 +        DEFINE_NATIVE_OP(NATIVE_ETHER_AO_ADD_MULTI, AO_enable_multicast);
245 +        DEFINE_NATIVE_OP(NATIVE_ETHER_AO_DEL_MULTI, AO_disable_multicast);
246 +        DEFINE_NATIVE_OP(NATIVE_ETHER_AO_SENDPACKET, AO_transmit_packet);
247          DEFINE_NATIVE_OP(NATIVE_ETHER_IRQ, EtherIRQ);
248          DEFINE_NATIVE_OP(NATIVE_ETHER_INIT, InitStreamModule);
249          DEFINE_NATIVE_OP(NATIVE_ETHER_TERM, TerminateStreamModule);
# Line 146 | Line 259 | bool ThunksInit(void)
259          DEFINE_NATIVE_OP(NATIVE_SERIAL_STATUS, SerialStatus);
260          DEFINE_NATIVE_OP(NATIVE_SERIAL_CLOSE, SerialClose);
261          DEFINE_NATIVE_OP(NATIVE_MAKE_EXECUTABLE, MakeExecutable);
262 +        DEFINE_NATIVE_OP(NATIVE_SYNC_HOOK, NQD_sync_hook);
263 +        DEFINE_NATIVE_OP(NATIVE_BITBLT_HOOK, NQD_bitblt_hook);
264 +        DEFINE_NATIVE_OP(NATIVE_FILLRECT_HOOK, NQD_fillrect_hook);
265 +        DEFINE_NATIVE_OP(NATIVE_BITBLT, NQD_bitblt);
266 +        DEFINE_NATIVE_OP(NATIVE_INVRECT, NQD_invrect);
267 +        DEFINE_NATIVE_OP(NATIVE_FILLRECT, NQD_fillrect);
268   #undef DEFINE_NATIVE_OP
269   #endif
270 +
271 +        // Initialize routine descriptors (if TVECT exists)
272 +        for (int i = 0; i < NATIVE_OP_MAX; i++) {
273 +                uint32 tvect = native_op[i].tvect;
274 +                if (tvect)
275 +                        native_op[i].desc = new SheepRoutineDescriptor(0, tvect);
276 +        }
277 +
278          return true;
279   }
280  
281  
282   /*
283 + *  Delete generated thunks
284 + */
285 +
286 + void ThunksExit(void)
287 + {
288 +        for (int i = 0; i < NATIVE_OP_MAX; i++) {
289 +                SheepRoutineDescriptor *desc = native_op[i].desc;
290 +                if (desc)
291 +                        delete desc;
292 +        }
293 + }
294 +
295 +
296 + /*
297   *  Return the native function descriptor (TVECT)
298   */
299  
# Line 179 | Line 320 | uint32 NativeFunction(int selector)
320  
321  
322   /*
323 + *  Return the routine descriptor address of the native function
324 + */
325 +
326 + uint32 NativeRoutineDescriptor(int selector)
327 + {
328 +        assert(selector < NATIVE_OP_MAX);
329 +        SheepRoutineDescriptor * const desc = native_op[selector].desc;
330 +        assert(desc != 0);
331 +        return desc->addr();
332 + }
333 +
334 +
335 + /*
336   *  Execute native code from EMUL_OP routine (real mode switch)
337   */
338  
339   void ExecuteNative(int selector)
340   {
187        SheepRoutineDescriptor desc(0, NativeTVECT(selector));
341          M68kRegisters r;
342 <        Execute68k(desc.addr(), &r);
342 >        Execute68k(NativeRoutineDescriptor(selector), &r);
343   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines