ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/SheepShaver/src/name_registry.cpp
Revision: 1.22
Committed: 2010-02-21T09:59:14Z (14 years, 9 months ago) by cebix
Branch: MAIN
CVS Tags: HEAD
Changes since 1.21: +2 -2 lines
Log Message:
fixed const-ness

File Contents

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