ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/SheepShaver/src/main.cpp
Revision: 1.8
Committed: 2009-08-26T00:06:29Z (14 years, 8 months ago) by asvitkine
Branch: MAIN
CVS Tags: HEAD
Changes since 1.7: +1 -0 lines
Log Message:
[Michael Schmitt]
Attached is a patch to SheepShaver, to fix a SIGSEGV crash that occurs when booting a new machine with OS 7.5.

One of the bytes in the xPRAM portion of the NVRAM controls which version of the system memory manager is used by OS 7.5: the legacy 680x0 memory manager or the PPC memory manager (aka the "Modern Memory Manager"). OS 7.5 is supposed to be able to use either one, but for some reason SheepShaver crashes on boot if the 680x0 version is used.

Later Mac OS versions don't have this problem. They don't support the 680x0 version, so they force the PPC version to be used.

The fix is to have SheepShaver initialize the NVRAM to use the PPC memory manager. Note: This is supposed to be the default in OS 7.5.

This affects when a new NVRAM file is used, or when it is initialized after doing zapping the PRAM.

File Contents

# Content
1 /*
2 * main.cpp - ROM patches
3 *
4 * SheepShaver (C) 1997-2008 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
23 #include "main.h"
24 #include "version.h"
25 #include "prefs.h"
26 #include "prefs_editor.h"
27 #include "cpu_emulation.h"
28 #include "emul_op.h"
29 #include "xlowmem.h"
30 #include "xpram.h"
31 #include "timer.h"
32 #include "adb.h"
33 #include "sony.h"
34 #include "disk.h"
35 #include "cdrom.h"
36 #include "scsi.h"
37 #include "video.h"
38 #include "audio.h"
39 #include "ether.h"
40 #include "serial.h"
41 #include "clip.h"
42 #include "extfs.h"
43 #include "sys.h"
44 #include "macos_util.h"
45 #include "rom_patches.h"
46 #include "user_strings.h"
47 #include "vm_alloc.h"
48 #include "sigsegv.h"
49 #include "thunks.h"
50
51 #define DEBUG 0
52 #include "debug.h"
53
54 #ifdef ENABLE_MON
55 #include "mon.h"
56
57 static uint32 sheepshaver_read_byte(uintptr adr)
58 {
59 return ReadMacInt8(adr);
60 }
61
62 static void sheepshaver_write_byte(uintptr adr, uint32 b)
63 {
64 WriteMacInt8(adr, b);
65 }
66 #endif
67
68
69 /*
70 * Initialize everything, returns false on error
71 */
72
73 bool InitAll(const char *vmdir)
74 {
75 // Load NVRAM
76 XPRAMInit(vmdir);
77
78 // Load XPRAM default values if signature not found
79 if (XPRAM[0x130c] != 0x4e || XPRAM[0x130d] != 0x75
80 || XPRAM[0x130e] != 0x4d || XPRAM[0x130f] != 0x63) {
81 D(bug("Loading XPRAM default values\n"));
82 memset(XPRAM + 0x1300, 0, 0x100);
83 XPRAM[0x130c] = 0x4e; // "NuMc" signature
84 XPRAM[0x130d] = 0x75;
85 XPRAM[0x130e] = 0x4d;
86 XPRAM[0x130f] = 0x63;
87 XPRAM[0x1301] = 0x80; // InternalWaitFlags = DynWait (don't wait for SCSI devices upon bootup)
88 XPRAM[0x1310] = 0xa8; // Standard PRAM values
89 XPRAM[0x1311] = 0x00;
90 XPRAM[0x1312] = 0x00;
91 XPRAM[0x1313] = 0x22;
92 XPRAM[0x1314] = 0xcc;
93 XPRAM[0x1315] = 0x0a;
94 XPRAM[0x1316] = 0xcc;
95 XPRAM[0x1317] = 0x0a;
96 XPRAM[0x131c] = 0x00;
97 XPRAM[0x131d] = 0x02;
98 XPRAM[0x131e] = 0x63;
99 XPRAM[0x131f] = 0x00;
100 XPRAM[0x1308] = 0x13;
101 XPRAM[0x1309] = 0x88;
102 XPRAM[0x130a] = 0x00;
103 XPRAM[0x130b] = 0xcc;
104 XPRAM[0x1376] = 0x00; // OSDefault = MacOS
105 XPRAM[0x1377] = 0x01;
106 XPRAM[0x138a] = 0x25; // Use PPC memory manager ("Modern Memory Manager")
107 }
108
109 // Set boot volume
110 int16 i16 = PrefsFindInt32("bootdrive");
111 XPRAM[0x1378] = i16 >> 8;
112 XPRAM[0x1379] = i16 & 0xff;
113 i16 = PrefsFindInt32("bootdriver");
114 XPRAM[0x137a] = i16 >> 8;
115 XPRAM[0x137b] = i16 & 0xff;
116
117 // Create BootGlobs at top of Mac memory
118 memset(RAMBaseHost + RAMSize - 4096, 0, 4096);
119 BootGlobsAddr = RAMBase + RAMSize - 0x1c;
120 WriteMacInt32(BootGlobsAddr - 5 * 4, RAMBase + RAMSize); // MemTop
121 WriteMacInt32(BootGlobsAddr + 0 * 4, RAMBase); // First RAM bank
122 WriteMacInt32(BootGlobsAddr + 1 * 4, RAMSize);
123 WriteMacInt32(BootGlobsAddr + 2 * 4, (uint32)-1); // End of bank table
124
125 // Init thunks
126 if (!ThunksInit())
127 return false;
128
129 // Init drivers
130 SonyInit();
131 DiskInit();
132 CDROMInit();
133 SCSIInit();
134
135 // Init external file system
136 ExtFSInit();
137
138 // Init ADB
139 ADBInit();
140
141 // Init audio
142 AudioInit();
143
144 // Init network
145 EtherInit();
146
147 // Init serial ports
148 SerialInit();
149
150 // Init Time Manager
151 TimerInit();
152
153 // Init clipboard
154 ClipInit();
155
156 // Init video
157 if (!VideoInit())
158 return false;
159
160 // Install ROM patches
161 if (!PatchROM()) {
162 ErrorAlert(GetString(STR_UNSUPPORTED_ROM_TYPE_ERR));
163 return false;
164 }
165
166 // Initialize Kernel Data
167 KernelData *kernel_data = (KernelData *)Mac2HostAddr(KERNEL_DATA_BASE);
168 memset(kernel_data, 0, sizeof(KernelData));
169 if (ROMType == ROMTYPE_NEWWORLD) {
170 uint32 of_dev_tree = SheepMem::Reserve(4 * sizeof(uint32));
171 Mac_memset(of_dev_tree, 0, 4 * sizeof(uint32));
172 uint32 vector_lookup_tbl = SheepMem::Reserve(128);
173 uint32 vector_mask_tbl = SheepMem::Reserve(64);
174 memset((uint8 *)kernel_data + 0xb80, 0x3d, 0x80);
175 Mac_memset(vector_lookup_tbl, 0, 128);
176 Mac_memset(vector_mask_tbl, 0, 64);
177 kernel_data->v[0xb80 >> 2] = htonl(ROMBase);
178 kernel_data->v[0xb84 >> 2] = htonl(of_dev_tree); // OF device tree base
179 kernel_data->v[0xb90 >> 2] = htonl(vector_lookup_tbl);
180 kernel_data->v[0xb94 >> 2] = htonl(vector_mask_tbl);
181 kernel_data->v[0xb98 >> 2] = htonl(ROMBase); // OpenPIC base
182 kernel_data->v[0xbb0 >> 2] = htonl(0); // ADB base
183 kernel_data->v[0xc20 >> 2] = htonl(RAMSize);
184 kernel_data->v[0xc24 >> 2] = htonl(RAMSize);
185 kernel_data->v[0xc30 >> 2] = htonl(RAMSize);
186 kernel_data->v[0xc34 >> 2] = htonl(RAMSize);
187 kernel_data->v[0xc38 >> 2] = htonl(0x00010020);
188 kernel_data->v[0xc3c >> 2] = htonl(0x00200001);
189 kernel_data->v[0xc40 >> 2] = htonl(0x00010000);
190 kernel_data->v[0xc50 >> 2] = htonl(RAMBase);
191 kernel_data->v[0xc54 >> 2] = htonl(RAMSize);
192 kernel_data->v[0xf60 >> 2] = htonl(PVR);
193 kernel_data->v[0xf64 >> 2] = htonl(CPUClockSpeed); // clock-frequency
194 kernel_data->v[0xf68 >> 2] = htonl(BusClockSpeed); // bus-frequency
195 kernel_data->v[0xf6c >> 2] = htonl(TimebaseSpeed); // timebase-frequency
196 } else if (ROMType == ROMTYPE_GOSSAMER) {
197 kernel_data->v[0xc80 >> 2] = htonl(RAMSize);
198 kernel_data->v[0xc84 >> 2] = htonl(RAMSize);
199 kernel_data->v[0xc90 >> 2] = htonl(RAMSize);
200 kernel_data->v[0xc94 >> 2] = htonl(RAMSize);
201 kernel_data->v[0xc98 >> 2] = htonl(0x00010020);
202 kernel_data->v[0xc9c >> 2] = htonl(0x00200001);
203 kernel_data->v[0xca0 >> 2] = htonl(0x00010000);
204 kernel_data->v[0xcb0 >> 2] = htonl(RAMBase);
205 kernel_data->v[0xcb4 >> 2] = htonl(RAMSize);
206 kernel_data->v[0xf60 >> 2] = htonl(PVR);
207 kernel_data->v[0xf64 >> 2] = htonl(CPUClockSpeed); // clock-frequency
208 kernel_data->v[0xf68 >> 2] = htonl(BusClockSpeed); // bus-frequency
209 kernel_data->v[0xf6c >> 2] = htonl(TimebaseSpeed); // timebase-frequency
210 } else {
211 kernel_data->v[0xc80 >> 2] = htonl(RAMSize);
212 kernel_data->v[0xc84 >> 2] = htonl(RAMSize);
213 kernel_data->v[0xc90 >> 2] = htonl(RAMSize);
214 kernel_data->v[0xc94 >> 2] = htonl(RAMSize);
215 kernel_data->v[0xc98 >> 2] = htonl(0x00010020);
216 kernel_data->v[0xc9c >> 2] = htonl(0x00200001);
217 kernel_data->v[0xca0 >> 2] = htonl(0x00010000);
218 kernel_data->v[0xcb0 >> 2] = htonl(RAMBase);
219 kernel_data->v[0xcb4 >> 2] = htonl(RAMSize);
220 kernel_data->v[0xf80 >> 2] = htonl(PVR);
221 kernel_data->v[0xf84 >> 2] = htonl(CPUClockSpeed); // clock-frequency
222 kernel_data->v[0xf88 >> 2] = htonl(BusClockSpeed); // bus-frequency
223 kernel_data->v[0xf8c >> 2] = htonl(TimebaseSpeed); // timebase-frequency
224 }
225
226 // Initialize extra low memory
227 D(bug("Initializing Low Memory...\n"));
228 Mac_memset(0, 0, 0x3000);
229 WriteMacInt32(XLM_SIGNATURE, FOURCC('B','a','a','h')); // Signature to detect SheepShaver
230 WriteMacInt32(XLM_KERNEL_DATA, KernelDataAddr); // For trap replacement routines
231 WriteMacInt32(XLM_PVR, PVR); // Theoretical PVR
232 WriteMacInt32(XLM_BUS_CLOCK, BusClockSpeed); // For DriverServicesLib patch
233 WriteMacInt16(XLM_EXEC_RETURN_OPCODE, M68K_EXEC_RETURN); // For Execute68k() (RTS from the executed 68k code will jump here and end 68k mode)
234 WriteMacInt32(XLM_ZERO_PAGE, SheepMem::ZeroPage()); // Pointer to read-only page with all bits set to 0
235 #if !EMULATED_PPC
236 #ifdef SYSTEM_CLOBBERS_R2
237 WriteMacInt32(XLM_TOC, (uint32)TOC); // TOC pointer of emulator
238 #endif
239 #ifdef SYSTEM_CLOBBERS_R13
240 WriteMacInt32(XLM_R13, (uint32)R13); // TLS register
241 #endif
242 #endif
243
244 WriteMacInt32(XLM_ETHER_AO_GET_HWADDR, NativeFunction(NATIVE_ETHER_AO_GET_HWADDR)); // Low level ethernet driver functions
245 WriteMacInt32(XLM_ETHER_AO_ADD_MULTI, NativeFunction(NATIVE_ETHER_AO_ADD_MULTI));
246 WriteMacInt32(XLM_ETHER_AO_DEL_MULTI, NativeFunction(NATIVE_ETHER_AO_DEL_MULTI));
247 WriteMacInt32(XLM_ETHER_AO_SEND_PACKET, NativeFunction(NATIVE_ETHER_AO_SEND_PACKET));
248
249 WriteMacInt32(XLM_ETHER_INIT, NativeFunction(NATIVE_ETHER_INIT)); // DLPI ethernet driver functions
250 WriteMacInt32(XLM_ETHER_TERM, NativeFunction(NATIVE_ETHER_TERM));
251 WriteMacInt32(XLM_ETHER_OPEN, NativeFunction(NATIVE_ETHER_OPEN));
252 WriteMacInt32(XLM_ETHER_CLOSE, NativeFunction(NATIVE_ETHER_CLOSE));
253 WriteMacInt32(XLM_ETHER_WPUT, NativeFunction(NATIVE_ETHER_WPUT));
254 WriteMacInt32(XLM_ETHER_RSRV, NativeFunction(NATIVE_ETHER_RSRV));
255 WriteMacInt32(XLM_VIDEO_DOIO, NativeFunction(NATIVE_VIDEO_DO_DRIVER_IO));
256 D(bug("Low Memory initialized\n"));
257
258 #if ENABLE_MON
259 // Initialize mon
260 mon_init();
261 mon_read_byte = sheepshaver_read_byte;
262 mon_write_byte = sheepshaver_write_byte;
263 #endif
264
265 return true;
266 }
267
268
269 /*
270 * Deinitialize everything
271 */
272
273 void ExitAll(void)
274 {
275 #if ENABLE_MON
276 // Deinitialize mon
277 mon_exit();
278 #endif
279
280 // Save NVRAM
281 XPRAMExit();
282
283 // Exit clipboard
284 ClipExit();
285
286 // Exit Time Manager
287 TimerExit();
288
289 // Exit serial
290 SerialExit();
291
292 // Exit network
293 EtherExit();
294
295 // Exit audio
296 AudioExit();
297
298 // Exit ADB
299 ADBExit();
300
301 // Exit video
302 VideoExit();
303
304 // Exit external file system
305 ExtFSExit();
306
307 // Exit drivers
308 SCSIExit();
309 CDROMExit();
310 DiskExit();
311 SonyExit();
312
313 // Delete thunks
314 ThunksExit();
315 }
316
317
318 /*
319 * Patch things after system startup (gets called by disk driver accRun routine)
320 */
321
322 void PatchAfterStartup(void)
323 {
324 ExecuteNative(NATIVE_VIDEO_INSTALL_ACCEL);
325 InstallExtFS();
326 }