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, 10 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

# User Rev Content
1 gbeauche 1.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 gbeauche 1.2 #include "macos_util.h"
33 gbeauche 1.1
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 gbeauche 1.2 /*
46     * Return the fake PowerPC opcode to handle specified native code
47     */
48    
49 gbeauche 1.1 #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 gbeauche 1.2
92     /*
93     * Initialize the thunks system
94     */
95    
96 gbeauche 1.1 struct native_op_t {
97     uint32 tvect;
98     uint32 func;
99 gbeauche 1.3 SheepRoutineDescriptor *desc;
100 gbeauche 1.1 };
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 gbeauche 1.4 // FIXME: add GetResource() and friends for completeness
132 gbeauche 1.2 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 gbeauche 1.1 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 gbeauche 1.3
154 gbeauche 1.4 // 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 gbeauche 1.3
161 gbeauche 1.1 return true;
162     }
163    
164 gbeauche 1.2
165     /*
166 gbeauche 1.3 * 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 gbeauche 1.2 * Return the native function descriptor (TVECT)
181     */
182    
183 gbeauche 1.1 uint32 NativeTVECT(int selector)
184     {
185     assert(selector < NATIVE_OP_MAX);
186     const uint32 tvect = native_op[selector].tvect;
187     assert(tvect != 0);
188 gbeauche 1.2 return tvect;
189 gbeauche 1.1 }
190    
191 gbeauche 1.2
192     /*
193     * Return the native function address
194     */
195    
196 gbeauche 1.1 uint32 NativeFunction(int selector)
197     {
198     assert(selector < NATIVE_OP_MAX);
199     const uint32 func = native_op[selector].func;
200     assert(func != 0);
201 gbeauche 1.2 return func;
202     }
203    
204    
205     /*
206 gbeauche 1.3 * 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 gbeauche 1.2 * Execute native code from EMUL_OP routine (real mode switch)
220     */
221    
222     void ExecuteNative(int selector)
223     {
224     M68kRegisters r;
225 gbeauche 1.3 Execute68k(NativeRoutineDescriptor(selector), &r);
226 gbeauche 1.1 }