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

# User Rev Content
1 gbeauche 1.1 /*
2     * main.cpp - ROM patches
3     *
4 gbeauche 1.5 * SheepShaver (C) 1997-2008 Christian Bauer and Marc Hellwig
5 gbeauche 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 "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 asvitkine 1.6 bool InitAll(const char *vmdir)
74 gbeauche 1.1 {
75     // Load NVRAM
76 asvitkine 1.6 XPRAMInit(vmdir);
77 gbeauche 1.1
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 asvitkine 1.8 XPRAM[0x138a] = 0x25; // Use PPC memory manager ("Modern Memory Manager")
107 gbeauche 1.1 }
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 asvitkine 1.7 kernel_data->v[0xb80 >> 2] = htonl(ROMBase);
178 gbeauche 1.1 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 asvitkine 1.7 kernel_data->v[0xb98 >> 2] = htonl(ROMBase); // OpenPIC base
182 gbeauche 1.1 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 gbeauche 1.3 #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 gbeauche 1.1 #endif
243 gbeauche 1.4
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 gbeauche 1.1 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     }