[haiku-development] State of ppc

  • From: Andreas Färber <andreas.faerber@xxxxxx>
  • To: haiku-development@xxxxxxxxxxxxx
  • Date: Thu, 31 Dec 2009 17:17:10 +0100

Hello everyone,

I've been playing with the PowerPC target, trying to identify what's going wrong in qemu-system-ppc.

(i) Currently, i.e. with today's QEMU git master and OpenBIOS SVN r654, I get:

$ qemu-system-ppc -localtime -boot d -cdrom haiku-boot-cd-ppc.iso -hda haiku.image -nographic

>> =============================================================
>> OpenBIOS 1.0 [Dec 29 2009 21:30]
>> Configuration device id QEMU version 1 machine id 2
>> CPUs: 1
>> Memory: 128M
>> UUID: 00000000-0000-0000-0000-000000000000
>> CPU type PowerPC,750
Welcome to OpenBIOS v1.0 built on Dec 29 2009 21:30


checking for memory...
0: base = 0x00000000, size = 134217728
1: empty region
total physical memory = 128 MB
suggested page table size = 1048576
need new page table, size = 1048576!
new table at: 0x07f00000
invalid/unsupported opcode: 00 - 00 - 00 (00000000) fff0245c 1
invalid/unsupported opcode: 00 - 00 - 00 (00000000) 00008754 0

QEMU's invalid opcode errors are apparently triggered (given this 128 MB RAM configuration) by a memset in the boot loader as follows:

diff --git a/src/system/boot/platform/openfirmware/arch/ppc/mmu.cpp b/ src/system/boot/platform/openfirmware/arch/ppc/mmu.cpp
index 262e2c1..7af7247 100644
--- a/src/system/boot/platform/openfirmware/arch/ppc/mmu.cpp
+++ b/src/system/boot/platform/openfirmware/arch/ppc/mmu.cpp
@@ -909,7 +909,8 @@ arch_mmu_init(void)

        sPageTableHashMask = tableSize / sizeof(page_table_entry_group) - 1;
        if (sPageTable != oldTable)
-               memset(sPageTable, 0, tableSize);
+               //memset(sPageTable, 0, 9308 /*tableSize*/);
+               memset((void*)0x7F0245c, 0, 1);

        // turn off address translation via the page table/segment mechanism,
        // identity map the first 256 MB (where our code/data reside)

The previous 9308 (0x245C) bytes appear to do no harm.


(ii) On a real PowerMac G5, I get a panic "out of page table entries!",
cf. http://dev.haiku-os.org/ticket/5164

(iii) On a real PowerMac G3, I get to the boot menu, can select a volume, and whatever options I choose either hang at:

kernel entry at 0x80081de4
kernel stack top: 0x80004000

or return to the OpenFirmware prompt:

kernel entry at 0x80089a00
kernel stack top: 0x80004000

DEFAULT CATCH!, code=900 at  %SRR0: ff818d70  %SRR1: 0000b030
ok
0 >

This appears to match Alexander's picture in #1048.

So I'm wondering whether Haiku is correct as far as it works or whether there's an issue causing different troubles on different systems. I'd tend to assume the first, given that the QEMU+OpenBIOS combination is still quite new...


Debugging further on real hardware, I noticed that the ".init" and ".text" sections are supposedly aligned to 0x60000000 in ppc/ kernel.ld, yet above the kernel entry appears to be beyond 0x80000000. Could someone explain that please?
http://dev.haiku-os.org/browser/haiku/trunk/src/system/ldscripts/ppc/kernel.ld?rev=33670
Also, is it intentional that the're no line for the ".plt" section as on x86 but a "*(.got.plt)"? If I do add a rule .plt { *(.plt) }, loading the kernel fails, saying an rw ELF section was already loaded (or similar).

I've noticed a TODO mentioning mmu_init_for_kernel:
http://dev.haiku-os.org/browser/haiku/trunk/src/system/boot/platform/openfirmware/start.c?rev=33670#L92

I've stubbed such a function, dumping the memory setup (since that's where x86 puts it together) for a 512 MB configuration on real hardware:

phys memory ranges:
    base 0x00000000, length 0x20000000
allocated phys memory ranges:
    base 0x00000000, length 0x00101000
    base 0x00102000, length 0x0002c000
    base 0x0012f000, length 0x00714000
    base 0x1fe00000, length 0x00200000
allocated virt memory ranges:
    base 0x00000000, length 0x00003000
    base 0x00102000, length 0x0002c000
    base 0x0012f000, length 0x0000c000
    base 0x00400000, length 0x00400000
    base 0x80800000, length 0x00081000
    base 0x80900000, length 0x00010000
    base 0x90000000, length 0x10000000
    base 0xfe000000, length 0x00010000
    base 0xfec00000, length 0x00001000
    base 0xfee00000, length 0x00200000
    base 0xff800000, length 0x00200000
    base 0x80000000, length 0x00406000

(debug code taken from bios_ia32)

So this part of gKernelArgs appears to be set up in a sane way already, so that it doesn't need to be done in mmu_init_for_kernel. x86 also sets up "the final and kernel accessible GDT and IDT tables" - is this or an equivalent needed on ppc?

The G3 being a single-core system, I assume I can safely skip the other remaining TODO "smp_boot_other_cpus();" for now since on x86 it instantly returns if gKernelArgs.num_cpus < 2.


Finally a more practical question: How do I tell the boot loader which volume to boot from? I tried 'setenv /chosen/bootargs foo bar baz', but the boot loader still outputs:
adding args: ´´

Thanks in advance for any hints, and a Happy New Year,

Andreas

Other related posts: