macemu/SheepShaver/src/Unix/ppc_asm.tmpl
asvitkine b3b5db5456 [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.
2009-08-18 18:26:11 +00:00

157 lines
3.2 KiB
Cheetah

/* Define usage of "reserved" registers */
#if defined(__linux__)
#define SYSTEM_CLOBBERS_R2 1 /* Pointer to Thread Local Storage */
#define SYSTEM_CLOBBERS_R13 1 /* Pointer to .sdata section */
#endif
#ifdef __ASSEMBLY__
/* Helper macros */
#ifdef SYSTEM_CLOBBERS_R2
#define RESTORE_SYSTEM_R2 lwz r2,XLM_TOC(0)
#define SAVE_SYSTEM_R2 stw r2,XLM_TOC(0)
#else
#define RESTORE_SYSTEM_R2
#define SAVE_SYSTEM_R2
#endif
#ifdef SYSTEM_CLOBBERS_R13
#define RESTORE_SYSTEM_R13 lwz r13,XLM_R13(0)
#define SAVE_SYSTEM_R13 stw r13,XLM_R13(0)
#else
#define RESTORE_SYSTEM_R13
#define SAVE_SYSTEM_R13
#endif
/* Helper macros */
#define xglue(x, y) x ## y
#define glue(x, y) xglue(x, y)
/* Apple assembler perticularities */
#if (defined(__APPLE__) && defined(__MACH__))
#define C_SYMBOL_NAME(NAME) glue(_, NAME)
#define ASM_TYPE(NAME, TYPE) /* nothing */
#define ASM_ALIGN_2(EXP) EXP
#define ASM_HA16(VAR) ha16(VAR)
#define ASM_LO16(VAR) lo16(VAR)
#define ASM_MACRO_END .endmacro
#define ASM_MACRO_ARG_SEP ,
#define ASM_MACRO_ARG0_DEF /* nothing! */
#define ASM_MACRO_ARG0 $0
#define ASM_MACRO_ARG1_DEF /* nothing! */
#define ASM_MACRO_ARG1 $1
#define ASM_MACRO_ARG2_DEF /* nothing! */
#define ASM_MACRO_ARG2 $2
#define ASM_MACRO_ARG3_DEF /* nothing! */
#define ASM_MACRO_ARG3 $3
#endif
/* Defaults for GNU assembler */
#ifndef ASM_TYPE
#define ASM_TYPE(NAME, TYPE) .type NAME, TYPE
#endif
#ifndef ASM_ALIGN_2
#define ASM_ALIGN_2(EXP) (1 << (EXP))
#endif
#ifndef ASM_HA16
#define ASM_HA16(VAR) VAR@ha
#endif
#ifndef ASM_LO16
#define ASM_LO16(VAR) VAR@l
#endif
#ifndef ASM_MACRO_START
#define ASM_MACRO_START .macro
#endif
#ifndef ASM_MACRO_END
#define ASM_MACRO_END .endm
#endif
#ifndef ASM_MACRO_ARG_SEP
#define ASM_MACRO_ARG_SEP
#endif
#ifndef ASM_MACRO_ARG0_DEF
#define ASM_MACRO_ARG0_DEF __asm_macro_arg0
#define ASM_MACRO_ARG0 \__asm_macro_arg0
#define ASM_MACRO_ARG1_DEF , __asm_macro_arg1
#define ASM_MACRO_ARG1 \__asm_macro_arg1
#define ASM_MACRO_ARG2_DEF , __asm_macro_arg2
#define ASM_MACRO_ARG2 \__asm_macro_arg2
#define ASM_MACRO_ARG3_DEF , __asm_macro_arg3
#define ASM_MACRO_ARG3 \__asm_macro_arg3
#endif
#ifndef C_SYMBOL_NAME
#define C_SYMBOL_NAME(NAME) NAME
#endif
#ifndef ASM_GLOBAL_DIRECTIVE
#define ASM_GLOBAL_DIRECTIVE .globl
#endif
/* Register names */
#if defined(__linux__) || defined(__NetBSD__)
#define r0 0
#define r1 1
#define r2 2
#define r3 3
#define r4 4
#define r5 5
#define r6 6
#define r7 7
#define r8 8
#define r9 9
#define r10 10
#define r11 11
#define r12 12
#define r13 13
#define r14 14
#define r15 15
#define r16 16
#define r17 17
#define r18 18
#define r19 19
#define r20 20
#define r21 21
#define r22 22
#define r23 23
#define r24 24
#define r25 25
#define r26 26
#define r27 27
#define r28 28
#define r29 29
#define r30 30
#define r31 31
#endif
#if defined(__linux__) || defined(__NetBSD__)
#define f0 0
#define f1 1
#define f2 2
#define f3 3
#define f4 4
#define f5 5
#define f6 6
#define f7 7
#define f8 8
#define f9 9
#define f10 10
#define f11 11
#define f12 12
#define f13 13
#define f14 14
#define f15 15
#define f16 16
#define f17 17
#define f18 18
#define f19 19
#define f20 20
#define f21 21
#define f22 22
#define f23 23
#define f24 24
#define f25 25
#define f26 26
#define f27 27
#define f28 28
#define f29 29
#define f30 30
#define f31 31
#endif
#endif