ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/SheepShaver/src/name_registry.cpp
Revision: 1.12
Committed: 2004-07-03T10:39:04Z (20 years, 4 months ago) by gbeauche
Branch: MAIN
Changes since 1.11: +1 -1 lines
Log Message:
Introducce TimebaseSpeed which represents exact timebase-frequency instead
of supposing it to be (BusClockSpeed/4), which is no longer true on G5 et al.

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