ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/SheepShaver/src/name_registry.cpp
Revision: 1.14
Committed: 2004-11-22T22:16:09Z (20 years ago) by gbeauche
Branch: MAIN
Changes since 1.13: +15 -5 lines
Log Message:
Avoid use of Host2MacAddr() with static data as it may need to force
a 32-bit address truncation on 64-bit platforms with DIRECT_ADDRESSING
or with platforms with particular Direct Addressing modes (a.g. Cygwin)

File Contents

# Content
1 /*
2 * name_registry.cpp - Name Registry handling
3 *
4 * SheepShaver (C) 1997-2004 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 <string.h>
22
23 #include "sysdeps.h"
24 #include "name_registry.h"
25 #include "main.h"
26 #include "macos_util.h"
27 #include "user_strings.h"
28 #include "emul_op.h"
29 #include "thunks.h"
30
31 #define DEBUG 0
32 #include "debug.h"
33
34
35 // Function pointers
36 typedef int16 (*rcec_ptr)(const RegEntryID *, const char *, RegEntryID *);
37 static uint32 rcec_tvect = 0;
38 static inline int16 RegistryCStrEntryCreate(uintptr arg1, const char *arg2, uint32 arg3)
39 {
40 SheepString arg2str(arg2);
41 return (int16)CallMacOS3(rcec_ptr, rcec_tvect, (const RegEntryID *)arg1, arg2str.addr(), arg3);
42 }
43 typedef int16 (*rpc_ptr)(const RegEntryID *, const char *, const void *, uint32);
44 static uint32 rpc_tvect = 0;
45 static inline int16 RegistryPropertyCreate(uintptr arg1, const char *arg2, uintptr arg3, uint32 arg4)
46 {
47 SheepString arg2str(arg2);
48 return (int16)CallMacOS4(rpc_ptr, rpc_tvect, (const RegEntryID *)arg1, arg2str.addr(), (const void *)arg3, arg4);
49 }
50 static inline int16 RegistryPropertyCreateStr(uintptr arg1, const char *arg2, const char *arg3)
51 {
52 SheepString arg3str(arg3);
53 return RegistryPropertyCreate(arg1, arg2, arg3str.addr(), strlen(arg3) + 1);
54 }
55
56 // Video driver stub
57 static const uint8 video_driver[] = {
58 #include "VideoDriverStub.i"
59 };
60
61 // Ethernet driver stub
62 static const uint8 ethernet_driver[] = {
63 #include "EthernetDriverStub.i"
64 };
65
66 // Helper for RegEntryID
67 typedef SheepArray<sizeof(RegEntryID)> SheepRegEntryID;
68
69 // Helper for a <uint32, uint32> pair
70 struct SheepPair : public SheepArray<8> {
71 SheepPair(uint32 base, uint32 size) : SheepArray<8>()
72 { WriteMacInt32(addr(), base); WriteMacInt32(addr() + 4, size); }
73 };
74
75
76 /*
77 * Patch Name Registry during startup
78 */
79
80 void DoPatchNameRegistry(void)
81 {
82 SheepVar32 u32;
83 D(bug("Patching Name Registry..."));
84
85 // Create "device-tree"
86 SheepRegEntryID device_tree;
87 if (!RegistryCStrEntryCreate(0, "Devices:device-tree", device_tree.addr())) {
88 u32.set_value(BusClockSpeed);
89 RegistryPropertyCreate(device_tree.addr(), "clock-frequency", u32.addr(), 4);
90 RegistryPropertyCreateStr(device_tree.addr(), "model", "Power Macintosh");
91
92 // Create "AAPL,ROM"
93 SheepRegEntryID aapl_rom;
94 if (!RegistryCStrEntryCreate(device_tree.addr(), "AAPL,ROM", aapl_rom.addr())) {
95 RegistryPropertyCreateStr(aapl_rom.addr(), "device_type", "rom");
96 SheepPair reg(ROM_BASE, ROM_SIZE);
97 RegistryPropertyCreate(aapl_rom.addr(), "reg", reg.addr(), 8);
98 }
99
100 // Create "PowerPC,60x"
101 SheepRegEntryID power_pc;
102 char *str;
103 switch (PVR >> 16) {
104 case 1: // 601
105 str = "PowerPC,601";
106 break;
107 case 3: // 603
108 str = "PowerPC,603";
109 break;
110 case 4: // 604
111 str = "PowerPC,604";
112 break;
113 case 6: // 603e
114 str = "PowerPC,603e";
115 break;
116 case 7: // 603ev
117 str = "PowerPC,603ev";
118 break;
119 case 8: // 750
120 str = "PowerPC,750";
121 break;
122 case 9: // 604e
123 str = "PowerPC,604e";
124 break;
125 case 10: // 604ev5
126 str = "PowerPC,604ev";
127 break;
128 case 50: // 821
129 str = "PowerPC,821";
130 break;
131 case 80: // 860
132 str = "PowerPC,860";
133 break;
134 default:
135 str = "PowerPC,???";
136 break;
137 }
138 if (!RegistryCStrEntryCreate(device_tree.addr(), str, power_pc.addr())) {
139 u32.set_value(CPUClockSpeed);
140 RegistryPropertyCreate(power_pc.addr(), "clock-frequency", u32.addr(), 4);
141 u32.set_value(BusClockSpeed);
142 RegistryPropertyCreate(power_pc.addr(), "bus-frequency", u32.addr(), 4);
143 u32.set_value(TimebaseSpeed);
144 RegistryPropertyCreate(power_pc.addr(), "timebase-frequency", u32.addr(), 4);
145 u32.set_value(PVR);
146 RegistryPropertyCreate(power_pc.addr(), "cpu-version", u32.addr(), 4);
147 RegistryPropertyCreateStr(power_pc.addr(), "device_type", "cpu");
148 switch (PVR >> 16) {
149 case 1: // 601
150 u32.set_value(64);
151 RegistryPropertyCreate(power_pc.addr(), "d-cache-block-size", u32.addr(), 4);
152 u32.set_value(128);
153 RegistryPropertyCreate(power_pc.addr(), "d-cache-sets", u32.addr(), 4);
154 u32.set_value(0x8000);
155 RegistryPropertyCreate(power_pc.addr(), "d-cache-size", u32.addr(), 4);
156 u32.set_value(64);
157 RegistryPropertyCreate(power_pc.addr(), "i-cache-block-size", u32.addr(), 4);
158 u32.set_value(128);
159 RegistryPropertyCreate(power_pc.addr(), "i-cache-sets", u32.addr(), 4);
160 u32.set_value(0x8000);
161 RegistryPropertyCreate(power_pc.addr(), "i-cache-size", u32.addr(), 4);
162 u32.set_value(128);
163 RegistryPropertyCreate(power_pc.addr(), "tlb-sets", u32.addr(), 4);
164 u32.set_value(256);
165 RegistryPropertyCreate(power_pc.addr(), "tlb-size", u32.addr(), 4);
166 break;
167 case 3: // 603
168 u32.set_value(32);
169 RegistryPropertyCreate(power_pc.addr(), "d-cache-block-size", u32.addr(), 4);
170 u32.set_value(64);
171 RegistryPropertyCreate(power_pc.addr(), "d-cache-sets", u32.addr(), 4);
172 u32.set_value(0x2000);
173 RegistryPropertyCreate(power_pc.addr(), "d-cache-size", u32.addr(), 4);
174 u32.set_value(32);
175 RegistryPropertyCreate(power_pc.addr(), "i-cache-block-size", u32.addr(), 4);
176 u32.set_value(64);
177 RegistryPropertyCreate(power_pc.addr(), "i-cache-sets", u32.addr(), 4);
178 u32.set_value(0x2000);
179 RegistryPropertyCreate(power_pc.addr(), "i-cache-size", u32.addr(), 4);
180 u32.set_value(32);
181 RegistryPropertyCreate(power_pc.addr(), "tlb-sets", u32.addr(), 4);
182 u32.set_value(64);
183 RegistryPropertyCreate(power_pc.addr(), "tlb-size", u32.addr(), 4);
184 break;
185 case 4: // 604
186 u32.set_value(32);
187 RegistryPropertyCreate(power_pc.addr(), "d-cache-block-size", u32.addr(), 4);
188 u32.set_value(128);
189 RegistryPropertyCreate(power_pc.addr(), "d-cache-sets", u32.addr(), 4);
190 u32.set_value(0x4000);
191 RegistryPropertyCreate(power_pc.addr(), "d-cache-size", u32.addr(), 4);
192 u32.set_value(32);
193 RegistryPropertyCreate(power_pc.addr(), "i-cache-block-size", u32.addr(), 4);
194 u32.set_value(128);
195 RegistryPropertyCreate(power_pc.addr(), "i-cache-sets", u32.addr(), 4);
196 u32.set_value(0x4000);
197 RegistryPropertyCreate(power_pc.addr(), "i-cache-size", u32.addr(), 4);
198 u32.set_value(64);
199 RegistryPropertyCreate(power_pc.addr(), "tlb-sets", u32.addr(), 4);
200 u32.set_value(128);
201 RegistryPropertyCreate(power_pc.addr(), "tlb-size", u32.addr(), 4);
202 break;
203 case 6: // 603e
204 case 7: // 603ev
205 u32.set_value(32);
206 RegistryPropertyCreate(power_pc.addr(), "d-cache-block-size", u32.addr(), 4);
207 u32.set_value(128);
208 RegistryPropertyCreate(power_pc.addr(), "d-cache-sets", u32.addr(), 4);
209 u32.set_value(0x4000);
210 RegistryPropertyCreate(power_pc.addr(), "d-cache-size", u32.addr(), 4);
211 u32.set_value(32);
212 RegistryPropertyCreate(power_pc.addr(), "i-cache-block-size", u32.addr(), 4);
213 u32.set_value(128);
214 RegistryPropertyCreate(power_pc.addr(), "i-cache-sets", u32.addr(), 4);
215 u32.set_value(0x4000);
216 RegistryPropertyCreate(power_pc.addr(), "i-cache-size", u32.addr(), 4);
217 u32.set_value(32);
218 RegistryPropertyCreate(power_pc.addr(), "tlb-sets", u32.addr(), 4);
219 u32.set_value(64);
220 RegistryPropertyCreate(power_pc.addr(), "tlb-size", u32.addr(), 4);
221 break;
222 case 8: // 750, 750FX
223 case 0x7000:
224 u32.set_value(32);
225 RegistryPropertyCreate(power_pc.addr(), "d-cache-block-size", u32.addr(), 4);
226 u32.set_value(256);
227 RegistryPropertyCreate(power_pc.addr(), "d-cache-sets", u32.addr(), 4);
228 u32.set_value(0x8000);
229 RegistryPropertyCreate(power_pc.addr(), "d-cache-size", u32.addr(), 4);
230 u32.set_value(32);
231 RegistryPropertyCreate(power_pc.addr(), "i-cache-block-size", u32.addr(), 4);
232 u32.set_value(256);
233 RegistryPropertyCreate(power_pc.addr(), "i-cache-sets", u32.addr(), 4);
234 u32.set_value(0x8000);
235 RegistryPropertyCreate(power_pc.addr(), "i-cache-size", u32.addr(), 4);
236 u32.set_value(64);
237 RegistryPropertyCreate(power_pc.addr(), "tlb-sets", u32.addr(), 4);
238 u32.set_value(128);
239 RegistryPropertyCreate(power_pc.addr(), "tlb-size", u32.addr(), 4);
240 break;
241 case 9: // 604e
242 case 10: // 604ev5
243 u32.set_value(32);
244 RegistryPropertyCreate(power_pc.addr(), "d-cache-block-size", u32.addr(), 4);
245 u32.set_value(256);
246 RegistryPropertyCreate(power_pc.addr(), "d-cache-sets", u32.addr(), 4);
247 u32.set_value(0x8000);
248 RegistryPropertyCreate(power_pc.addr(), "d-cache-size", u32.addr(), 4);
249 u32.set_value(32);
250 RegistryPropertyCreate(power_pc.addr(), "i-cache-block-size", u32.addr(), 4);
251 u32.set_value(256);
252 RegistryPropertyCreate(power_pc.addr(), "i-cache-sets", u32.addr(), 4);
253 u32.set_value(0x8000);
254 RegistryPropertyCreate(power_pc.addr(), "i-cache-size", u32.addr(), 4);
255 u32.set_value(64);
256 RegistryPropertyCreate(power_pc.addr(), "tlb-sets", u32.addr(), 4);
257 u32.set_value(128);
258 RegistryPropertyCreate(power_pc.addr(), "tlb-size", u32.addr(), 4);
259 break;
260 case 12: // 7400, 7410, 7450, 7455, 7457
261 case 0x800c:
262 case 0x8000:
263 case 0x8001:
264 case 0x8002:
265 u32.set_value(32);
266 RegistryPropertyCreate(power_pc.addr(), "d-cache-block-size", u32.addr(), 4);
267 u32.set_value(128);
268 RegistryPropertyCreate(power_pc.addr(), "d-cache-sets", u32.addr(), 4);
269 u32.set_value(0x8000);
270 RegistryPropertyCreate(power_pc.addr(), "d-cache-size", u32.addr(), 4);
271 u32.set_value(32);
272 RegistryPropertyCreate(power_pc.addr(), "i-cache-block-size", u32.addr(), 4);
273 u32.set_value(128);
274 RegistryPropertyCreate(power_pc.addr(), "i-cache-sets", u32.addr(), 4);
275 u32.set_value(0x8000);
276 RegistryPropertyCreate(power_pc.addr(), "i-cache-size", u32.addr(), 4);
277 u32.set_value(64);
278 RegistryPropertyCreate(power_pc.addr(), "tlb-sets", u32.addr(), 4);
279 u32.set_value(128);
280 RegistryPropertyCreate(power_pc.addr(), "tlb-size", u32.addr(), 4);
281 break;
282 case 0x39: // 970
283 u32.set_value(128);
284 RegistryPropertyCreate(power_pc.addr(), "d-cache-block-size", u32.addr(), 4);
285 u32.set_value(128);
286 RegistryPropertyCreate(power_pc.addr(), "d-cache-sets", u32.addr(), 4);
287 u32.set_value(0x8000);
288 RegistryPropertyCreate(power_pc.addr(), "d-cache-size", u32.addr(), 4);
289 u32.set_value(128);
290 RegistryPropertyCreate(power_pc.addr(), "i-cache-block-size", u32.addr(), 4);
291 u32.set_value(512);
292 RegistryPropertyCreate(power_pc.addr(), "i-cache-sets", u32.addr(), 4);
293 u32.set_value(0x10000);
294 RegistryPropertyCreate(power_pc.addr(), "i-cache-size", u32.addr(), 4);
295 u32.set_value(256);
296 RegistryPropertyCreate(power_pc.addr(), "tlb-sets", u32.addr(), 4);
297 u32.set_value(0x1000);
298 RegistryPropertyCreate(power_pc.addr(), "tlb-size", u32.addr(), 4);
299 break;
300 default:
301 break;
302 }
303 u32.set_value(32);
304 RegistryPropertyCreate(power_pc.addr(), "reservation-granularity", u32.addr(), 4);
305 SheepPair reg(0, 0);
306 RegistryPropertyCreate(power_pc.addr(), "reg", reg.addr(), 8);
307 }
308
309 // Create "memory"
310 SheepRegEntryID memory;
311 if (!RegistryCStrEntryCreate(device_tree.addr(), "memory", memory.addr())) {
312 SheepPair reg(RAMBase, RAMSize);
313 RegistryPropertyCreateStr(memory.addr(), "device_type", "memory");
314 RegistryPropertyCreate(memory.addr(), "reg", reg.addr(), 8);
315 }
316
317 // Create "video"
318 SheepRegEntryID video;
319 if (!RegistryCStrEntryCreate(device_tree.addr(), "video", video.addr())) {
320 RegistryPropertyCreateStr(video.addr(), "AAPL,connector", "monitor");
321 RegistryPropertyCreateStr(video.addr(), "device_type", "display");
322 SheepArray<sizeof(video_driver)> the_video_driver;
323 Host2Mac_memcpy(the_video_driver.addr(), video_driver, sizeof(video_driver));
324 RegistryPropertyCreate(video.addr(), "driver,AAPL,MacOS,PowerPC", the_video_driver.addr(), sizeof(video_driver));
325 RegistryPropertyCreateStr(video.addr(), "model", "SheepShaver Video");
326 }
327
328 // Create "ethernet"
329 SheepRegEntryID ethernet;
330 if (!RegistryCStrEntryCreate(device_tree.addr(), "ethernet", ethernet.addr())) {
331 RegistryPropertyCreateStr(ethernet.addr(), "AAPL,connector", "ethernet");
332 RegistryPropertyCreateStr(ethernet.addr(), "device_type", "network");
333 SheepArray<sizeof(ethernet_driver)> the_ethernet_driver;
334 Host2Mac_memcpy(the_ethernet_driver.addr(), ethernet_driver, sizeof(ethernet_driver));
335 RegistryPropertyCreate(ethernet.addr(), "driver,AAPL,MacOS,PowerPC", the_ethernet_driver.addr(), sizeof(ethernet_driver));
336 // local-mac-address
337 // max-frame-size 2048
338 }
339 }
340 D(bug("done.\n"));
341 }
342
343 void PatchNameRegistry(void)
344 {
345 // Find RegistryCStrEntryCreate() and RegistryPropertyCreate() TVECTs
346 rcec_tvect = (uint32)FindLibSymbol("\017NameRegistryLib", "\027RegistryCStrEntryCreate");
347 D(bug("RegistryCStrEntryCreate TVECT at %08x\n", rcec_tvect));
348 rpc_tvect = (uint32)FindLibSymbol("\017NameRegistryLib", "\026RegistryPropertyCreate");
349 D(bug("RegistryPropertyCreate TVECT at %08x\n", rpc_tvect));
350 if (rcec_tvect == 0 || rpc_tvect == 0) {
351 ErrorAlert(GetString(STR_NO_NAME_REGISTRY_ERR));
352 QuitEmulator();
353 }
354
355 // Main routine must be executed in PPC mode
356 ExecuteNative(NATIVE_PATCH_NAME_REGISTRY);
357 }