ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/SheepShaver/src/name_registry.cpp
Revision: 1.21
Committed: 2009-08-18T18:26:10Z (14 years, 8 months ago) by asvitkine
Branch: MAIN
Changes since 1.20: +1 -1 lines
Log Message:
[Michael Schmitt]
Attached is a patch to SheepShaver to fix memory allocation problems when OS X 10.5 is the host. It also relaxes the 512 MB RAM limit on OS X hosts.


Problem
-------
Some users have been unable to run SheepShaver on OS X 10.5 (Leopard) hosts. The symptom is error "ERROR: Cannot map RAM: File already exists".

SheepShaver allocates RAM at fixed addresses. If it is running in "Real" addressing mode, and can't allocate at address 0, then it was hard-coded to allocate the RAM area at 0x20000000. The ROM area as allocated at 0x40800000.

The normal configuration is for SheepShaver to run under SDL, which is a Cocoa wrapper. By the time SheepShaver does its memory allocations, the Cocoa application has already started. The result is the SheepShaver memory address space already contains libraries, fonts, Input Managers, and IOKit areas.

On Leopard hosts these areas can land on the same addresses SheepShaver needs, so SheepShaver's memory allocation fails.


Solution
--------
The approach is to change SheepShaver (on Unix & OS X hosts) to allocate the RAM area anywhere it can find the space, rather than at a fixed address.

This could result in the RAM allocated higher than the ROM area, which causes a crash. To prevent this from occurring, the RAM and ROM areas are allocated contiguously.

Previously the ROM starting address was a constant ROM_BASE, which was used throughout the source files. The ROM start address is now a variable ROMBase. ROMBase is allocated and set by main_*.cpp just like RAMBase.

A side-effect of this change is that it lifts the 512 MB RAM limit for OS X hosts. The limit was because the fixed RAM and ROM addresses were such that the RAM could only be 512 MB before it overlapped the ROM area.


Impact
------
The change to make ROMBase a variable is throughout all hosts & addressing modes.

The RAM and ROM areas will only shift when run on Unix & OS X hosts, otherwise the same fixed allocation address is used as before.

This change is limited to "Real" addressing mode. Unlike Basilisk II, SheepShaver *pre-calculates* the offset for "Direct" addressing mode; the offset is compiled into the program. If the RAM address were allowed to shift, it could result in the RAM area wrapping around address 0.


Changes to main_unix.cpp
------------------------
1. Real addressing mode no longer defines a RAM_BASE constant.

2. The base address of the Mac ROM (ROMBase) is defined and exported by this program.

3. Memory management helper vm_mac_acquire is renamed to vm_mac_acquire_fixed. Added a new memory management helper vm_mac_acquire, which allocates memory at any address.

4. Changed and rearranged the allocation of RAM and ROM areas.

Before it worked like this:

  - Allocate ROM area
  - If can, attempt to allocate RAM at address zero
  - If RAM not allocated at 0, allocate at fixed address

We still want to try allocating the RAM at zero, and if using DIRECT addressing we're still going to use the fixed addresses. So we don't know where the ROM should be until after we do the RAM. The new logic is:

  - If can, attempt to allocate RAM at address zero
  - If RAM not allocated at 0
      if REAL addressing
         allocate RAM and ROM together. The ROM address is aligned to a 1 MB boundary
      else (direct addressing)
         allocate RAM at fixed address
  - If ROM hasn't been allocated yet, allocate at fixed address

5. Calculate ROMBase and ROMBaseHost based on where the ROM was loaded.

6. There is a crash if the RAM is allocated too high. To try and catch this, check if it was allocated higher than the kernel data address.

7. Change subsequent code from using constant ROM_BASE to variable ROMBase.


Changes to Other Programs
-------------------------
emul_op.cpp, main.cpp, name_registery.cpp, rom_patches.cpp, rsrc_patches.cpp, emul_ppc.cpp, sheepshaver_glue.cpp, ppc-translate-cpp:
Change from constant ROM_BASE to variable ROMBase.

ppc_asm.S: It was setting register to a hard-coded literal address: 0x40b0d000. Changed to set it to ROMBase + 0x30d000.

ppc_asm.tmpl: It defined a macro ASM_LO16 but it assumed that the macro would always be used with operands that included a register specification. This is not true. Moved the register specification from the macro to the macro invocations.

main_beos.cpp, main_windows.cpp: Since the subprograms are all expecting a variable ROMBase, all the main_*.cpp pgrams have to define and export it. The ROM_BASE constant is moved here for consistency. The mains for beos and windows just allocate the ROM at the same fixed address as before, set ROMBaseHost and ROMBase to that address, and then use ROMBase for the subsequent code.

cpu_emulation.h: removed ROM_BASE constant. This value is moved to the main_*.cpp modules, to be consistent with RAM_BASE.

user_strings_unix.cpp, user_strings_unix.h: Added new error messages related to errors that occur when the RAM and ROM are allocated anywhere.

File Contents

# User Rev Content
1 cebix 1.1 /*
2     * name_registry.cpp - Name Registry handling
3     *
4 gbeauche 1.20 * SheepShaver (C) 1997-2008 Christian Bauer and Marc Hellwig
5 cebix 1.1 *
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 gbeauche 1.2 #include "emul_op.h"
29 gbeauche 1.4 #include "thunks.h"
30 cebix 1.1
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 gbeauche 1.13 static inline int16 RegistryCStrEntryCreate(uintptr arg1, const char *arg2, uint32 arg3)
39 cebix 1.1 {
40 gbeauche 1.14 SheepString arg2str(arg2);
41     return (int16)CallMacOS3(rcec_ptr, rcec_tvect, (const RegEntryID *)arg1, arg2str.addr(), arg3);
42 cebix 1.1 }
43     typedef int16 (*rpc_ptr)(const RegEntryID *, const char *, const void *, uint32);
44     static uint32 rpc_tvect = 0;
45 gbeauche 1.13 static inline int16 RegistryPropertyCreate(uintptr arg1, const char *arg2, uintptr arg3, uint32 arg4)
46 cebix 1.1 {
47 gbeauche 1.14 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 cebix 1.1 }
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 gbeauche 1.19 #ifdef USE_ETHER_FULL_DRIVER
64     #include "EthernetDriverFull.i"
65     #else
66 cebix 1.1 #include "EthernetDriverStub.i"
67 gbeauche 1.19 #endif
68 cebix 1.1 };
69    
70 gbeauche 1.4 // Helper for RegEntryID
71 gbeauche 1.13 typedef SheepArray<sizeof(RegEntryID)> SheepRegEntryID;
72 gbeauche 1.4
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 cebix 1.1
80     /*
81     * Patch Name Registry during startup
82     */
83    
84 gbeauche 1.2 void DoPatchNameRegistry(void)
85 cebix 1.1 {
86 gbeauche 1.4 SheepVar32 u32;
87 cebix 1.1 D(bug("Patching Name Registry..."));
88    
89     // Create "device-tree"
90 gbeauche 1.4 SheepRegEntryID device_tree;
91 gbeauche 1.13 if (!RegistryCStrEntryCreate(0, "Devices:device-tree", device_tree.addr())) {
92 gbeauche 1.4 u32.set_value(BusClockSpeed);
93 gbeauche 1.13 RegistryPropertyCreate(device_tree.addr(), "clock-frequency", u32.addr(), 4);
94     RegistryPropertyCreateStr(device_tree.addr(), "model", "Power Macintosh");
95 cebix 1.1
96     // Create "AAPL,ROM"
97 gbeauche 1.4 SheepRegEntryID aapl_rom;
98 gbeauche 1.13 if (!RegistryCStrEntryCreate(device_tree.addr(), "AAPL,ROM", aapl_rom.addr())) {
99     RegistryPropertyCreateStr(aapl_rom.addr(), "device_type", "rom");
100 asvitkine 1.21 SheepPair reg(ROMBase, ROM_SIZE);
101 gbeauche 1.13 RegistryPropertyCreate(aapl_rom.addr(), "reg", reg.addr(), 8);
102 cebix 1.1 }
103    
104     // Create "PowerPC,60x"
105 gbeauche 1.4 SheepRegEntryID power_pc;
106 cebix 1.1 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 gbeauche 1.16 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 cebix 1.1 default:
146     str = "PowerPC,???";
147     break;
148     }
149 gbeauche 1.13 if (!RegistryCStrEntryCreate(device_tree.addr(), str, power_pc.addr())) {
150 gbeauche 1.4 u32.set_value(CPUClockSpeed);
151 gbeauche 1.13 RegistryPropertyCreate(power_pc.addr(), "clock-frequency", u32.addr(), 4);
152 gbeauche 1.9 u32.set_value(BusClockSpeed);
153 gbeauche 1.13 RegistryPropertyCreate(power_pc.addr(), "bus-frequency", u32.addr(), 4);
154 gbeauche 1.12 u32.set_value(TimebaseSpeed);
155 gbeauche 1.13 RegistryPropertyCreate(power_pc.addr(), "timebase-frequency", u32.addr(), 4);
156 gbeauche 1.4 u32.set_value(PVR);
157 gbeauche 1.13 RegistryPropertyCreate(power_pc.addr(), "cpu-version", u32.addr(), 4);
158     RegistryPropertyCreateStr(power_pc.addr(), "device_type", "cpu");
159 cebix 1.1 switch (PVR >> 16) {
160     case 1: // 601
161 gbeauche 1.4 u32.set_value(64);
162 gbeauche 1.13 RegistryPropertyCreate(power_pc.addr(), "d-cache-block-size", u32.addr(), 4);
163 gbeauche 1.4 u32.set_value(128);
164 gbeauche 1.13 RegistryPropertyCreate(power_pc.addr(), "d-cache-sets", u32.addr(), 4);
165 gbeauche 1.4 u32.set_value(0x8000);
166 gbeauche 1.13 RegistryPropertyCreate(power_pc.addr(), "d-cache-size", u32.addr(), 4);
167 gbeauche 1.4 u32.set_value(64);
168 gbeauche 1.13 RegistryPropertyCreate(power_pc.addr(), "i-cache-block-size", u32.addr(), 4);
169 gbeauche 1.4 u32.set_value(128);
170 gbeauche 1.13 RegistryPropertyCreate(power_pc.addr(), "i-cache-sets", u32.addr(), 4);
171 gbeauche 1.4 u32.set_value(0x8000);
172 gbeauche 1.13 RegistryPropertyCreate(power_pc.addr(), "i-cache-size", u32.addr(), 4);
173 gbeauche 1.4 u32.set_value(128);
174 gbeauche 1.13 RegistryPropertyCreate(power_pc.addr(), "tlb-sets", u32.addr(), 4);
175 gbeauche 1.4 u32.set_value(256);
176 gbeauche 1.13 RegistryPropertyCreate(power_pc.addr(), "tlb-size", u32.addr(), 4);
177 cebix 1.1 break;
178     case 3: // 603
179 gbeauche 1.4 u32.set_value(32);
180 gbeauche 1.13 RegistryPropertyCreate(power_pc.addr(), "d-cache-block-size", u32.addr(), 4);
181 gbeauche 1.4 u32.set_value(64);
182 gbeauche 1.13 RegistryPropertyCreate(power_pc.addr(), "d-cache-sets", u32.addr(), 4);
183 gbeauche 1.4 u32.set_value(0x2000);
184 gbeauche 1.13 RegistryPropertyCreate(power_pc.addr(), "d-cache-size", u32.addr(), 4);
185 gbeauche 1.4 u32.set_value(32);
186 gbeauche 1.13 RegistryPropertyCreate(power_pc.addr(), "i-cache-block-size", u32.addr(), 4);
187 gbeauche 1.4 u32.set_value(64);
188 gbeauche 1.13 RegistryPropertyCreate(power_pc.addr(), "i-cache-sets", u32.addr(), 4);
189 gbeauche 1.4 u32.set_value(0x2000);
190 gbeauche 1.13 RegistryPropertyCreate(power_pc.addr(), "i-cache-size", u32.addr(), 4);
191 gbeauche 1.4 u32.set_value(32);
192 gbeauche 1.13 RegistryPropertyCreate(power_pc.addr(), "tlb-sets", u32.addr(), 4);
193 gbeauche 1.4 u32.set_value(64);
194 gbeauche 1.13 RegistryPropertyCreate(power_pc.addr(), "tlb-size", u32.addr(), 4);
195 cebix 1.1 break;
196     case 4: // 604
197 gbeauche 1.4 u32.set_value(32);
198 gbeauche 1.13 RegistryPropertyCreate(power_pc.addr(), "d-cache-block-size", u32.addr(), 4);
199 gbeauche 1.4 u32.set_value(128);
200 gbeauche 1.13 RegistryPropertyCreate(power_pc.addr(), "d-cache-sets", u32.addr(), 4);
201 gbeauche 1.4 u32.set_value(0x4000);
202 gbeauche 1.13 RegistryPropertyCreate(power_pc.addr(), "d-cache-size", u32.addr(), 4);
203 gbeauche 1.4 u32.set_value(32);
204 gbeauche 1.13 RegistryPropertyCreate(power_pc.addr(), "i-cache-block-size", u32.addr(), 4);
205 gbeauche 1.4 u32.set_value(128);
206 gbeauche 1.13 RegistryPropertyCreate(power_pc.addr(), "i-cache-sets", u32.addr(), 4);
207 gbeauche 1.4 u32.set_value(0x4000);
208 gbeauche 1.13 RegistryPropertyCreate(power_pc.addr(), "i-cache-size", u32.addr(), 4);
209 gbeauche 1.4 u32.set_value(64);
210 gbeauche 1.13 RegistryPropertyCreate(power_pc.addr(), "tlb-sets", u32.addr(), 4);
211 gbeauche 1.4 u32.set_value(128);
212 gbeauche 1.13 RegistryPropertyCreate(power_pc.addr(), "tlb-size", u32.addr(), 4);
213 cebix 1.1 break;
214     case 6: // 603e
215     case 7: // 603ev
216 gbeauche 1.4 u32.set_value(32);
217 gbeauche 1.13 RegistryPropertyCreate(power_pc.addr(), "d-cache-block-size", u32.addr(), 4);
218 gbeauche 1.4 u32.set_value(128);
219 gbeauche 1.13 RegistryPropertyCreate(power_pc.addr(), "d-cache-sets", u32.addr(), 4);
220 gbeauche 1.4 u32.set_value(0x4000);
221 gbeauche 1.13 RegistryPropertyCreate(power_pc.addr(), "d-cache-size", u32.addr(), 4);
222 gbeauche 1.4 u32.set_value(32);
223 gbeauche 1.13 RegistryPropertyCreate(power_pc.addr(), "i-cache-block-size", u32.addr(), 4);
224 gbeauche 1.4 u32.set_value(128);
225 gbeauche 1.13 RegistryPropertyCreate(power_pc.addr(), "i-cache-sets", u32.addr(), 4);
226 gbeauche 1.4 u32.set_value(0x4000);
227 gbeauche 1.13 RegistryPropertyCreate(power_pc.addr(), "i-cache-size", u32.addr(), 4);
228 gbeauche 1.4 u32.set_value(32);
229 gbeauche 1.13 RegistryPropertyCreate(power_pc.addr(), "tlb-sets", u32.addr(), 4);
230 gbeauche 1.4 u32.set_value(64);
231 gbeauche 1.13 RegistryPropertyCreate(power_pc.addr(), "tlb-size", u32.addr(), 4);
232 cebix 1.1 break;
233 gbeauche 1.10 case 8: // 750, 750FX
234     case 0x7000:
235 gbeauche 1.4 u32.set_value(32);
236 gbeauche 1.13 RegistryPropertyCreate(power_pc.addr(), "d-cache-block-size", u32.addr(), 4);
237 gbeauche 1.4 u32.set_value(256);
238 gbeauche 1.13 RegistryPropertyCreate(power_pc.addr(), "d-cache-sets", u32.addr(), 4);
239 gbeauche 1.4 u32.set_value(0x8000);
240 gbeauche 1.13 RegistryPropertyCreate(power_pc.addr(), "d-cache-size", u32.addr(), 4);
241 gbeauche 1.4 u32.set_value(32);
242 gbeauche 1.13 RegistryPropertyCreate(power_pc.addr(), "i-cache-block-size", u32.addr(), 4);
243 gbeauche 1.4 u32.set_value(256);
244 gbeauche 1.13 RegistryPropertyCreate(power_pc.addr(), "i-cache-sets", u32.addr(), 4);
245 gbeauche 1.4 u32.set_value(0x8000);
246 gbeauche 1.13 RegistryPropertyCreate(power_pc.addr(), "i-cache-size", u32.addr(), 4);
247 gbeauche 1.4 u32.set_value(64);
248 gbeauche 1.13 RegistryPropertyCreate(power_pc.addr(), "tlb-sets", u32.addr(), 4);
249 gbeauche 1.4 u32.set_value(128);
250 gbeauche 1.13 RegistryPropertyCreate(power_pc.addr(), "tlb-size", u32.addr(), 4);
251 cebix 1.1 break;
252     case 9: // 604e
253     case 10: // 604ev5
254 gbeauche 1.4 u32.set_value(32);
255 gbeauche 1.13 RegistryPropertyCreate(power_pc.addr(), "d-cache-block-size", u32.addr(), 4);
256 gbeauche 1.4 u32.set_value(256);
257 gbeauche 1.13 RegistryPropertyCreate(power_pc.addr(), "d-cache-sets", u32.addr(), 4);
258 gbeauche 1.4 u32.set_value(0x8000);
259 gbeauche 1.13 RegistryPropertyCreate(power_pc.addr(), "d-cache-size", u32.addr(), 4);
260 gbeauche 1.4 u32.set_value(32);
261 gbeauche 1.13 RegistryPropertyCreate(power_pc.addr(), "i-cache-block-size", u32.addr(), 4);
262 gbeauche 1.4 u32.set_value(256);
263 gbeauche 1.13 RegistryPropertyCreate(power_pc.addr(), "i-cache-sets", u32.addr(), 4);
264 gbeauche 1.4 u32.set_value(0x8000);
265 gbeauche 1.13 RegistryPropertyCreate(power_pc.addr(), "i-cache-size", u32.addr(), 4);
266 gbeauche 1.4 u32.set_value(64);
267 gbeauche 1.13 RegistryPropertyCreate(power_pc.addr(), "tlb-sets", u32.addr(), 4);
268 gbeauche 1.4 u32.set_value(128);
269 gbeauche 1.13 RegistryPropertyCreate(power_pc.addr(), "tlb-size", u32.addr(), 4);
270 cebix 1.1 break;
271 gbeauche 1.10 case 12: // 7400, 7410, 7450, 7455, 7457
272 gbeauche 1.8 case 0x800c:
273 gbeauche 1.10 case 0x8000:
274     case 0x8001:
275     case 0x8002:
276 gbeauche 1.7 u32.set_value(32);
277 gbeauche 1.13 RegistryPropertyCreate(power_pc.addr(), "d-cache-block-size", u32.addr(), 4);
278 gbeauche 1.7 u32.set_value(128);
279 gbeauche 1.13 RegistryPropertyCreate(power_pc.addr(), "d-cache-sets", u32.addr(), 4);
280 gbeauche 1.7 u32.set_value(0x8000);
281 gbeauche 1.13 RegistryPropertyCreate(power_pc.addr(), "d-cache-size", u32.addr(), 4);
282 gbeauche 1.7 u32.set_value(32);
283 gbeauche 1.13 RegistryPropertyCreate(power_pc.addr(), "i-cache-block-size", u32.addr(), 4);
284 gbeauche 1.7 u32.set_value(128);
285 gbeauche 1.13 RegistryPropertyCreate(power_pc.addr(), "i-cache-sets", u32.addr(), 4);
286 gbeauche 1.7 u32.set_value(0x8000);
287 gbeauche 1.13 RegistryPropertyCreate(power_pc.addr(), "i-cache-size", u32.addr(), 4);
288 gbeauche 1.7 u32.set_value(64);
289 gbeauche 1.13 RegistryPropertyCreate(power_pc.addr(), "tlb-sets", u32.addr(), 4);
290 gbeauche 1.7 u32.set_value(128);
291 gbeauche 1.13 RegistryPropertyCreate(power_pc.addr(), "tlb-size", u32.addr(), 4);
292 gbeauche 1.7 break;
293 gbeauche 1.11 case 0x39: // 970
294     u32.set_value(128);
295 gbeauche 1.13 RegistryPropertyCreate(power_pc.addr(), "d-cache-block-size", u32.addr(), 4);
296 gbeauche 1.11 u32.set_value(128);
297 gbeauche 1.13 RegistryPropertyCreate(power_pc.addr(), "d-cache-sets", u32.addr(), 4);
298 gbeauche 1.11 u32.set_value(0x8000);
299 gbeauche 1.13 RegistryPropertyCreate(power_pc.addr(), "d-cache-size", u32.addr(), 4);
300 gbeauche 1.11 u32.set_value(128);
301 gbeauche 1.13 RegistryPropertyCreate(power_pc.addr(), "i-cache-block-size", u32.addr(), 4);
302 gbeauche 1.11 u32.set_value(512);
303 gbeauche 1.13 RegistryPropertyCreate(power_pc.addr(), "i-cache-sets", u32.addr(), 4);
304 gbeauche 1.11 u32.set_value(0x10000);
305 gbeauche 1.13 RegistryPropertyCreate(power_pc.addr(), "i-cache-size", u32.addr(), 4);
306 gbeauche 1.11 u32.set_value(256);
307 gbeauche 1.13 RegistryPropertyCreate(power_pc.addr(), "tlb-sets", u32.addr(), 4);
308 gbeauche 1.11 u32.set_value(0x1000);
309 gbeauche 1.13 RegistryPropertyCreate(power_pc.addr(), "tlb-size", u32.addr(), 4);
310 gbeauche 1.11 break;
311 cebix 1.1 default:
312     break;
313     }
314 gbeauche 1.4 u32.set_value(32);
315 gbeauche 1.13 RegistryPropertyCreate(power_pc.addr(), "reservation-granularity", u32.addr(), 4);
316 gbeauche 1.4 SheepPair reg(0, 0);
317 gbeauche 1.13 RegistryPropertyCreate(power_pc.addr(), "reg", reg.addr(), 8);
318 cebix 1.1 }
319    
320     // Create "memory"
321 gbeauche 1.4 SheepRegEntryID memory;
322 gbeauche 1.13 if (!RegistryCStrEntryCreate(device_tree.addr(), "memory", memory.addr())) {
323 gbeauche 1.4 SheepPair reg(RAMBase, RAMSize);
324 gbeauche 1.13 RegistryPropertyCreateStr(memory.addr(), "device_type", "memory");
325     RegistryPropertyCreate(memory.addr(), "reg", reg.addr(), 8);
326 cebix 1.1 }
327    
328     // Create "video"
329 gbeauche 1.4 SheepRegEntryID video;
330 gbeauche 1.13 if (!RegistryCStrEntryCreate(device_tree.addr(), "video", video.addr())) {
331     RegistryPropertyCreateStr(video.addr(), "AAPL,connector", "monitor");
332     RegistryPropertyCreateStr(video.addr(), "device_type", "display");
333 gbeauche 1.14 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 gbeauche 1.13 RegistryPropertyCreateStr(video.addr(), "model", "SheepShaver Video");
337 cebix 1.1 }
338    
339     // Create "ethernet"
340 gbeauche 1.4 SheepRegEntryID ethernet;
341 gbeauche 1.13 if (!RegistryCStrEntryCreate(device_tree.addr(), "ethernet", ethernet.addr())) {
342     RegistryPropertyCreateStr(ethernet.addr(), "AAPL,connector", "ethernet");
343     RegistryPropertyCreateStr(ethernet.addr(), "device_type", "network");
344 gbeauche 1.14 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 cebix 1.1 // 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 gbeauche 1.15 rcec_tvect = FindLibSymbol("\017NameRegistryLib", "\027RegistryCStrEntryCreate");
358 cebix 1.1 D(bug("RegistryCStrEntryCreate TVECT at %08x\n", rcec_tvect));
359 gbeauche 1.15 rpc_tvect = FindLibSymbol("\017NameRegistryLib", "\026RegistryPropertyCreate");
360 cebix 1.1 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 gbeauche 1.2 ExecuteNative(NATIVE_PATCH_NAME_REGISTRY);
368 cebix 1.1 }