ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/SheepShaver/src/thunks.cpp
Revision: 1.4
Committed: 2004-01-15T23:28:59Z (20 years, 4 months ago) by gbeauche
Branch: MAIN
Changes since 1.3: +7 -3 lines
Log Message:
Fix native mode, a better solution would be to also add GetResource()
patches into the native_op[] table in native mode too.

File Contents

# Content
1 /*
2 * thunks.cpp - Thunks to share data and code with MacOS
3 *
4 * SheepShaver (C) 1997-2002 Christian Bauer and Marc Hellwig
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20
21 #include "sysdeps.h"
22 #include "thunks.h"
23 #include "emul_op.h"
24 #include "cpu_emulation.h"
25
26 // Native function declarations
27 #include "main.h"
28 #include "video.h"
29 #include "name_registry.h"
30 #include "serial.h"
31 #include "ether.h"
32 #include "macos_util.h"
33
34
35 /* NativeOp instruction format:
36 +------------+--------------------------+--+----------+------------+
37 | 6 | |FN| OP | 2 |
38 +------------+--------------------------+--+----------+------------+
39 0 5 |6 19 20 21 25 26 31
40 */
41
42 #define POWERPC_NATIVE_OP(LR, OP) \
43 (POWERPC_EMUL_OP | ((LR) << 11) | (((uint32)OP) << 6) | 2)
44
45 /*
46 * Return the fake PowerPC opcode to handle specified native code
47 */
48
49 #if EMULATED_PPC
50 uint32 NativeOpcode(int selector)
51 {
52 uint32 opcode;
53 switch (selector) {
54 case NATIVE_DISABLE_INTERRUPT:
55 case NATIVE_ENABLE_INTERRUPT:
56 opcode = POWERPC_NATIVE_OP(0, selector);
57 break;
58 case NATIVE_PATCH_NAME_REGISTRY:
59 case NATIVE_VIDEO_INSTALL_ACCEL:
60 case NATIVE_VIDEO_VBL:
61 case NATIVE_VIDEO_DO_DRIVER_IO:
62 case NATIVE_ETHER_IRQ:
63 case NATIVE_ETHER_INIT:
64 case NATIVE_ETHER_TERM:
65 case NATIVE_ETHER_OPEN:
66 case NATIVE_ETHER_CLOSE:
67 case NATIVE_ETHER_WPUT:
68 case NATIVE_ETHER_RSRV:
69 case NATIVE_SERIAL_NOTHING:
70 case NATIVE_SERIAL_OPEN:
71 case NATIVE_SERIAL_PRIME_IN:
72 case NATIVE_SERIAL_PRIME_OUT:
73 case NATIVE_SERIAL_CONTROL:
74 case NATIVE_SERIAL_STATUS:
75 case NATIVE_SERIAL_CLOSE:
76 case NATIVE_GET_RESOURCE:
77 case NATIVE_GET_1_RESOURCE:
78 case NATIVE_GET_IND_RESOURCE:
79 case NATIVE_GET_1_IND_RESOURCE:
80 case NATIVE_R_GET_RESOURCE:
81 case NATIVE_MAKE_EXECUTABLE:
82 opcode = POWERPC_NATIVE_OP(1, selector);
83 break;
84 default:
85 abort();
86 }
87 return opcode;
88 }
89 #endif
90
91
92 /*
93 * Initialize the thunks system
94 */
95
96 struct native_op_t {
97 uint32 tvect;
98 uint32 func;
99 SheepRoutineDescriptor *desc;
100 };
101 static native_op_t native_op[NATIVE_OP_MAX];
102
103 bool ThunksInit(void)
104 {
105 #if EMULATED_PPC
106 for (int i = 0; i < NATIVE_OP_MAX; i++) {
107 uintptr base = SheepMem::Reserve(12);
108 WriteMacInt32(base + 0, base + 8);
109 WriteMacInt32(base + 4, 0); // Fake TVECT
110 WriteMacInt32(base + 8, NativeOpcode(i));
111 native_op[i].tvect = base;
112 native_op[i].func = base + 8;
113 }
114 #else
115 #if defined(__linux__)
116 #define DEFINE_NATIVE_OP(ID, FUNC) do { \
117 uintptr base = SheepMem::Reserve(8); \
118 WriteMacInt32(base + 0, (uint32)FUNC); \
119 WriteMacInt32(base + 4, 0); /*Fake TVECT*/ \
120 native_op[ID].tvect = base; \
121 native_op[ID].func = (uint32)FUNC; \
122 } while (0)
123 #elif defined(__BEOS__)
124 #define DEFINE_NATIVE_OP(ID, FUNC) do { \
125 native_op[ID].tvect = FUNC; \
126 native_op[ID].func = ((uint32 *)FUNC)[0]; \
127 } while (0)
128 #else
129 #error "FIXME: define NativeOp for your platform"
130 #endif
131 // FIXME: add GetResource() and friends for completeness
132 DEFINE_NATIVE_OP(NATIVE_PATCH_NAME_REGISTRY, DoPatchNameRegistry);
133 DEFINE_NATIVE_OP(NATIVE_VIDEO_INSTALL_ACCEL, VideoInstallAccel);
134 DEFINE_NATIVE_OP(NATIVE_VIDEO_VBL, VideoVBL);
135 DEFINE_NATIVE_OP(NATIVE_VIDEO_DO_DRIVER_IO, VideoDoDriverIO);
136 DEFINE_NATIVE_OP(NATIVE_ETHER_IRQ, EtherIRQ);
137 DEFINE_NATIVE_OP(NATIVE_ETHER_INIT, InitStreamModule);
138 DEFINE_NATIVE_OP(NATIVE_ETHER_TERM, TerminateStreamModule);
139 DEFINE_NATIVE_OP(NATIVE_ETHER_OPEN, ether_open);
140 DEFINE_NATIVE_OP(NATIVE_ETHER_CLOSE, ether_close);
141 DEFINE_NATIVE_OP(NATIVE_ETHER_WPUT, ether_wput);
142 DEFINE_NATIVE_OP(NATIVE_ETHER_RSRV, ether_rsrv);
143 DEFINE_NATIVE_OP(NATIVE_SERIAL_NOTHING, SerialNothing);
144 DEFINE_NATIVE_OP(NATIVE_SERIAL_OPEN, SerialOpen);
145 DEFINE_NATIVE_OP(NATIVE_SERIAL_PRIME_IN, SerialPrimeIn);
146 DEFINE_NATIVE_OP(NATIVE_SERIAL_PRIME_OUT, SerialPrimeOut);
147 DEFINE_NATIVE_OP(NATIVE_SERIAL_CONTROL, SerialControl);
148 DEFINE_NATIVE_OP(NATIVE_SERIAL_STATUS, SerialStatus);
149 DEFINE_NATIVE_OP(NATIVE_SERIAL_CLOSE, SerialClose);
150 DEFINE_NATIVE_OP(NATIVE_MAKE_EXECUTABLE, MakeExecutable);
151 #undef DEFINE_NATIVE_OP
152 #endif
153
154 // Initialize routine descriptors (if TVECT exists)
155 for (int i = 0; i < NATIVE_OP_MAX; i++) {
156 uint32 tvect = native_op[i].tvect;
157 if (tvect)
158 native_op[i].desc = new SheepRoutineDescriptor(0, tvect);
159 }
160
161 return true;
162 }
163
164
165 /*
166 * Delete generated thunks
167 */
168
169 void ThunksExit(void)
170 {
171 for (int i = 0; i < NATIVE_OP_MAX; i++) {
172 SheepRoutineDescriptor *desc = native_op[i].desc;
173 if (desc)
174 delete desc;
175 }
176 }
177
178
179 /*
180 * Return the native function descriptor (TVECT)
181 */
182
183 uint32 NativeTVECT(int selector)
184 {
185 assert(selector < NATIVE_OP_MAX);
186 const uint32 tvect = native_op[selector].tvect;
187 assert(tvect != 0);
188 return tvect;
189 }
190
191
192 /*
193 * Return the native function address
194 */
195
196 uint32 NativeFunction(int selector)
197 {
198 assert(selector < NATIVE_OP_MAX);
199 const uint32 func = native_op[selector].func;
200 assert(func != 0);
201 return func;
202 }
203
204
205 /*
206 * Return the routine descriptor address of the native function
207 */
208
209 uint32 NativeRoutineDescriptor(int selector)
210 {
211 assert(selector < NATIVE_OP_MAX);
212 SheepRoutineDescriptor * const desc = native_op[selector].desc;
213 assert(desc != 0);
214 return desc->addr();
215 }
216
217
218 /*
219 * Execute native code from EMUL_OP routine (real mode switch)
220 */
221
222 void ExecuteNative(int selector)
223 {
224 M68kRegisters r;
225 Execute68k(NativeRoutineDescriptor(selector), &r);
226 }