[Linux] [PowerPC] Cannot launch SheepShaver

About SheepShaver, a PPC Mac emulator for Windows, MacOS X, and Linux that can run System 7.5.3 to MacOS 9.0.4.

Moderators: Cat_7, Ronald P. Regensburg, ClockWise

Post Reply
powerpsaw
Student Driver
Posts: 12
Joined: Sat Jan 15, 2011 12:41 pm
Location: PowerPlanet

[Linux] [PowerPC] Cannot launch SheepShaver

Post by powerpsaw »

That's what I've got:

Code: Select all

# SheepShaver 
SheepShaver V2.3 by Christian Bauer and Mar"c" Hellwig
WARNING: Unknown CPU type 'PPC970MP', assuming 604
WARNING: Unknown CPU type 'PPC970MP', assuming 604
Paranoia checks...
[emul_thread] waiting for tick thread to initialize
[emul_thread] filling in registers and waiting for interrupt
[tick_thread] waiting for emul thread to initialize
[tick_thread] trigger interrupt
SIGUSR2 caught
...passed
ERROR: Cannot map usable RAM area. Try to decrease the MacOS RAM size.
X Error of failed request:  BadValue (integer parameter out of range for operation)
  Major opcode of failed request:  105 (X_ChangePointerControl)
  Value in failed request:  0x0
  Serial number of failed request:  9
  Current serial number in output stream:  9

Code: Select all

# SheepShaver --help | grep -A1 ramsize
  --ramsize NUMBER
    size of Mac RAM in bytes [default=0]
Changing ramsize doesn't help:

Code: Select all

# SheepShaver --ramsize 67108864
SheepShaver V2.3 by Christian Bauer and Mar"c" Hellwig
WARNING: Unknown CPU type 'PPC970MP', assuming 604
WARNING: Unknown CPU type 'PPC970MP', assuming 604
Paranoia checks...
[emul_thread] waiting for tick thread to initialize
[emul_thread] filling in registers and waiting for interrupt
[tick_thread] waiting for emul thread to initialize
[tick_thread] trigger interrupt
SIGUSR2 caught
...passed
ERROR: Cannot map usable RAM area. Try to decrease the MacOS RAM size.
X Error of failed request:  BadValue (integer parameter out of range for operation)
  Major opcode of failed request:  105 (X_ChangePointerControl)
  Value in failed request:  0x0
  Serial number of failed request:  9
  Current serial number in output stream:  9
powerpsaw
Student Driver
Posts: 12
Joined: Sat Jan 15, 2011 12:41 pm
Location: PowerPlanet

Re: [Linux] [PowerPC] Cannot launch SheepShaver

Post by powerpsaw »

Fixed!

Here's what I have developed. The source of a problem is STR_RAM_AREA_TOO_HIGH_ERR, which is triggered inside main_unix.cpp:

Code: Select all

if (RAMBase > KernelDataAddr) {
        ErrorAlert(GetString(STR_RAM_AREA_TOO_HIGH_ERR));
        goto quit;
}
Turning on debug printout, I got:

Code: Select all

Kernel Data at 0x68ffe000 (68ffe000)
RAM area at 0xeeab5000 (eeab5000)
Due to it's very distant from nanokernel's 0x68ffe000, there's no problem to remove such check from main_unix.cpp:

Code: Select all

# if you are facing STR_RAM_AREA_TOO_HIGH_ERR ("Cannot map usable RAM area. Try to decrease the MacOS RAM size.")
# errors on launch on 64-bit systems, use the following workaround
sed -i 's/if (RAMBase > KernelDataAddr)/if (0)/' ./main_unix.cpp
And yes, there's no "direct" addressing when running on real (non-emulated) PowerPC, only "real".

As for 970MP type of CPUs to be correctly recognized at least as having AltiVec. Looking at main_unix.cpp file, I found that there are specs for PPC970 and PPC970FX, but not for PPC970MP. Here's what I've found:
http://lists.ozlabs.org/pipermail/linux ... 04688.html

Code: Select all

+	{	/* PPC970MP */
+		.pvr_mask		= 0xffff0000,
+		.pvr_value		= 0x00440000,
+		.cpu_name		= "PPC970MP",
So I added the following to SheepShaver's main_unix.cpp:

Code: Select all

# add recognition for 970MP processors
sed -i 's/{ 0xffff0000, 0x003c0000, "PPC970FX" }/{ 0xffff0000, 0x003c0000, "PPC970FX" },\
                        { 0xffff0000, 0x00440000, "PPC970MP" }/' ./main_unix.cpp
sed -i 's;.*case 0x003c:.*;        case 0x003c:                            //  970FX\
        case 0x0044:                            //  970MP;' ./main_unix.cpp
After that, I got very well working SheepShaver for GNU/Linux@PowerPC 64-bit (970MP type of CPU).
User avatar
Cat_7
Expert User
Posts: 5016
Joined: Fri Feb 13, 2004 8:59 am
Location: Sittard, The Netherlands

Re: [Linux] [PowerPC] Cannot launch SheepShaver

Post by Cat_7 »

Hi,

Great to see you solved this error. Would you mind sending this as possible patch to the mailing list? https://lists.sourceforge.net/lists/lis ... lisk-devel )This is no error, the Basilisk mailing list is also used for SheepShaver.)

Best,
Cat_7
powerpsaw
Student Driver
Posts: 12
Joined: Sat Jan 15, 2011 12:41 pm
Location: PowerPlanet

Re: [Linux] [PowerPC] Cannot launch SheepShaver

Post by powerpsaw »

Would you mind sending this as possible patch to the mailing list?
Thanks. Just did it. But only CPU recognition part. As a see in a long run, just disabling a check for RAMBase < KernelBase doesn't work well. If RAMBase begin to start with $f..... (may look like negative addrs or even DMA area), mapping refuses to work. It would be probably better to develop a full support for 64-bit addressing for 64-bit host machine, even in the case of SSINE ("sheepshaver is not emulator"). I'll try to work on this.
Myrd
Granny Smith
Posts: 109
Joined: Mon Dec 25, 2006 4:09 am

Re: [Linux] [PowerPC] Cannot launch SheepShaver

Post by Myrd »

So you're saying REAL_ADDRESSING is on, in your config?

So that would mean RAMBase gets allocated via this path in main_unix.cpp:

Code: Select all

		RAMBaseHost = vm_mac_acquire(RAMSize + ROM_AREA_SIZE + ROM_ALIGNMENT);
		if (RAMBaseHost == VM_MAP_FAILED) {
			sprintf(str, GetString(STR_RAM_ROM_MMAP_ERR), strerror(errno));
			ErrorAlert(str);
			goto quit;
		}
		RAMBase = Host2MacAddr(RAMBaseHost);
If we look at vm_acquire() in vm_alloc.cpp, I assume it takes the HAVE_MMAP_VM path on your system?

That path tries to map memory at 'next_address'. Which starts at 0 and should keep incrementing up as it allocates things. So I wonder how it gets allocated all the way at 0xeeab5000 for you?

Or perhaps HAVE_MMAP_VM isn't set for you, in which case it just gets allocated via calloc(), which would explain why it doesn't work. If that's the case, the solution is to make mmap() work on your system.

One suspicion I have is that since mmap() code does not try to to use a different 'next_address' if it fails, it might be just failing initially. If this happens during ./configure detection, then HAVE_MMAP_VM may not be getting set, and thus you're getting the calloc() path. In which case, we can probably just make the mmap() failure case retry some number of times, while incrementing 'next_address'.

Let me know what you find.
powerpsaw
Student Driver
Posts: 12
Joined: Sat Jan 15, 2011 12:41 pm
Location: PowerPlanet

Re: [Linux] [PowerPC] Cannot launch SheepShaver

Post by powerpsaw »

> So that would mean RAMBase gets allocated via this path in main_unix.cpp

That's right.

> I assume it takes the HAVE_MMAP_VM path on your system?

Yep. Not calloc. This is how pre-processed vm_acquire looks:

Code: Select all

void * vm_acquire(size_t size, int options)
{
 void * addr;

 (*__errno_location ()) = 0;


 if (options & 0x04)
  return ((void *)-1);


 if (options & 0x10)
  return ((void *)-1);
# 229 "vm_alloc.cpp"
 int fd = -1;
 int the_map_flags = translate_map_flags(options) | (0x020 | (0));

 if ((addr = mmap((caddr_t)next_address, size, (0x1 | 0x2), the_map_flags, fd, 0)) == (void *)((void *) -1))
  return ((void *)-1);


 if (sizeof(void *) == 8 && (options & 0x08) && !((char *)addr <= (char *)0xffffffff))
  return ((void *)-1);

 next_address = (char *)addr + size;
# 260 "vm_alloc.cpp"
 if (vm_protect(addr, size, (0x1 | 0x2)) != 0)
  return ((void *)-1);

 return addr;
}
Usually, I'm getting "RAM area at 0xf2ea0000 (f2ea0000)" and such.

From mmap(2) man page:
> If addr is NULL, then the kernel chooses the address at which to create the mapping. If addr is not NULL, then the kernel takes it as a hint about where to place the mapping; on Linux, the mapping will be created at a nearby page boundary.

And it is initially nil (as specified in vm_alloc.cpp):

Code: Select all

static char * next_address = (char *)0x00000000;
because MAP_BASE is nil for non-x86 linux w/o "linker script":

Code: Select all

#define MAP_BASE        0x00000000
With (notice the change from nil to 0x01000000):

Code: Select all

#if (defined(__linux__) && defined(__i386__)) || HAVE_LINKER_SCRIPT
/* Force a reasonnable address below 0x80000000 on x86 so that we
   don't get addresses above when the program is run on AMD64.
   NOTE: this is empirically determined on Linux/x86.  */
#define MAP_BASE	0x10000000
#else
#define MAP_BASE	0x01000000
#endif
I have:

Code: Select all

Kernel Data at 0x68ffe000 (68ffe000)
Emulator Data at 0x68fff000 (68fff000)
DR Cache at 0x69000000
RAM area at 0x1000000 (01000000)
ROM area at 0x5000000 (05000000)
UPD: Almost forgot. With MAP_BASE set to 0x10000000 (not 0x01000000), I'm getting allocation at the same 0xe... and 0xf... addresses as for when MAP_BASE is set to NULL: RAM area at 0xf2afc000 (f2afc000).
Myrd
Granny Smith
Posts: 109
Joined: Mon Dec 25, 2006 4:09 am

Re: [Linux] [PowerPC] Cannot launch SheepShaver

Post by Myrd »

What if you change the code in main_unix.cpp to:

Code: Select all

static inline uint8 *vm_mac_acquire(uint32 size)
{
	return (uint8 *)vm_acquire(size, VM_MAP_PRIVATE | VM_MAP_32BIT);
}
(While reverting your other changes.)

This should force the allocations to be within the first 2 GB boundary, and thus wouldn't result in such high addresses as you're seeing.
powerpsaw
Student Driver
Posts: 12
Joined: Sat Jan 15, 2011 12:41 pm
Location: PowerPlanet

Re: [Linux] [PowerPC] Cannot launch SheepShaver

Post by powerpsaw »

Doesn't work.

With the following patch applied to fresh CVS checkout:

Code: Select all

--- main_unix.cpp.old	2012-01-01 13:38:25.015955849 -0500
+++ main_unix.cpp	2012-01-01 13:38:49.611894553 -0500
@@ -342,7 +342,7 @@
 
 static inline uint8 *vm_mac_acquire(uint32 size)
 {
-	return (uint8 *)vm_acquire(size);
+	return (uint8 *)vm_acquire(size, VM_MAP_PRIVATE | VM_MAP_32BIT);
 }
 
 static inline int vm_mac_acquire_fixed(uint32 addr, uint32 size)
I have:

Code: Select all

Kernel Data at 0x68ffe000 (68ffe000)
Emulator Data at 0x68fff000 (68fff000)
DR Cache at 0x69000000
RAM area at 0xeabfa000 (eabfa000)
ERROR: Cannot map usable RAM area. Try to decrease the MacOS RAM size.
By the way: what's wrong with specifying 0x01000000 for allocation base and not NULL? (NULL means "kernel chooses where to allocate, and it can be anywhere".)
Myrd
Granny Smith
Posts: 109
Joined: Mon Dec 25, 2006 4:09 am

Re: [Linux] [PowerPC] Cannot launch SheepShaver

Post by Myrd »

powerpsaw wrote: By the way: what's wrong with specifying 0x01000000 for allocation base and not NULL? (NULL means "kernel chooses where to allocate, and it can be anywhere".)
My main concern is that it's fragile. If a shared library was loaded there or memory was malloc'd out of there, then the call would fail - and there isn't really a way to ensure things don't go there before we try to map things there. I guess the solution to this would be to make the code loop trying different addresses on failure.

The other issue is that the address we pass to mmap() is only a hint, unless we specify the VM_MAP_FIXED flag, so in that case, the code should be using vm_acquire_fixed().
Post Reply