From cdbda49e8857ec6958c91a500cbc322304bd487f Mon Sep 17 00:00:00 2001 From: PulkoMandy Date: Mon, 20 May 2019 23:08:19 +0200 Subject: [PATCH] sparc: fix openfirmware entry point. According to the IEEE standard documentation, the OpenFirmware entry point should be in %o3. But that doesn't work, and both FreeBSD and NetBSD expect it in %o4 (5th argument of the function). I suspect this was changed for 64bit sparc, but neither the sparc nor 64bit openfirmware specs mention it. Move the sparc and powerpc specific parts out of the generic start.cpp for openfirmware as they each have some specificities. More specifically: - sparc already clears bss for us - entry point arguments are different - determine_machine is of course platform specific Change-Id: Icaa05087e88ea4d29198e3565223459aed75cdf9 Reviewed-on: https://review.haiku-os.org/c/1470 Reviewed-by: waddlesplash --- src/system/boot/platform/openfirmware/Jamfile | 2 +- .../platform/openfirmware/arch/ppc/Jamfile | 3 +- .../platform/openfirmware/arch/ppc/start.cpp | 81 +++++++++++++++++++ .../platform/openfirmware/arch/sparc/Jamfile | 5 +- .../openfirmware/arch/sparc/start.cpp | 35 ++++++++ .../boot/platform/openfirmware/start.cpp | 81 ++----------------- src/system/boot/platform/openfirmware/start.h | 12 +++ 7 files changed, 140 insertions(+), 79 deletions(-) create mode 100644 src/system/boot/platform/openfirmware/arch/ppc/start.cpp create mode 100644 src/system/boot/platform/openfirmware/arch/sparc/start.cpp create mode 100644 src/system/boot/platform/openfirmware/start.h diff --git a/src/system/boot/platform/openfirmware/Jamfile b/src/system/boot/platform/openfirmware/Jamfile index 736258595b..fa03216547 100644 --- a/src/system/boot/platform/openfirmware/Jamfile +++ b/src/system/boot/platform/openfirmware/Jamfile @@ -48,7 +48,7 @@ for platform in [ MultiBootSubDirSetup openfirmware ] { : : boot_platform_generic_openfirmware.a - boot_platform_openfirmware_$(TARGET_ARCH).a + boot_platform_openfirmware_$(TARGET_ARCH).o ; # SEARCH on [ FGristFiles $(genericPlatformSources) ] diff --git a/src/system/boot/platform/openfirmware/arch/ppc/Jamfile b/src/system/boot/platform/openfirmware/arch/ppc/Jamfile index 09471a95b8..f7c3d95efc 100644 --- a/src/system/boot/platform/openfirmware/arch/ppc/Jamfile +++ b/src/system/boot/platform/openfirmware/arch/ppc/Jamfile @@ -8,12 +8,13 @@ UsePrivateHeaders kernel [ FDirName kernel arch $(TARGET_KERNEL_ARCH) ] SubDirC++Flags -fno-rtti ; -BootStaticLibrary boot_platform_openfirmware_ppc : +BootStaticLibrary boot_platform_openfirmware_ppc.o : arch_mmu.cpp arch_cpu_asm.S arch_start_kernel.S cpu.cpp mmu.cpp + start.cpp ; SEARCH on [ FGristFiles arch_cpu_asm.S arch_mmu.cpp ] diff --git a/src/system/boot/platform/openfirmware/arch/ppc/start.cpp b/src/system/boot/platform/openfirmware/arch/ppc/start.cpp new file mode 100644 index 0000000000..604e726c51 --- /dev/null +++ b/src/system/boot/platform/openfirmware/arch/ppc/start.cpp @@ -0,0 +1,81 @@ +/* + * Copyright 2003-2010, Axel Dörfler, axeld@pinc-software.de. + * Copyright 2011, Alexander von Gluck, kallisti5@unixzen.com + * Copyright 2019, Adrien Destugues, pulkomandy@pulkomandy.tk + * Distributed under the terms of the MIT License. + */ + + +#include "start.h" + +#include "machine.h" + + +extern "C" void _start(uint32 _unused1, uint32 _unused2, + void *openFirmwareEntry); + +// XCOFF "entry-point" is actually a pointer to the real code +extern "C" void *_coff_start; +void *_coff_start = (void *)&_start; + +// GCC defined globals +extern uint8 __bss_start; +extern uint8 _end; + + +static void +clear_bss(void) +{ + memset(&__bss_start, 0, &_end - &__bss_start); +} + + +void +determine_machine(void) +{ + gMachine = MACHINE_UNKNOWN; + + intptr_t root = of_finddevice("/"); + char buffer[64]; + int length; + + // TODO : Probe other OpenFirmware platforms and set gMachine as needed + + if ((length = of_getprop(root, "device_type", buffer, sizeof(buffer) - 1)) + != OF_FAILED) { + buffer[length] = '\0'; + if (!strcasecmp("chrp", buffer)) + gMachine = MACHINE_CHRP; + else if (!strcasecmp("bootrom", buffer)) + gMachine = MACHINE_MAC; + } else + gMachine = MACHINE_MAC; + + if ((length = of_getprop(root, "model", buffer, sizeof(buffer) - 1)) + != OF_FAILED) { + buffer[length] = '\0'; + if (!strcasecmp("pegasos", buffer)) + gMachine |= MACHINE_PEGASOS; + } + + if ((length = of_getprop(root, "name", buffer, sizeof(buffer) - 1)) + != OF_FAILED) { + buffer[length] = '\0'; + if (!strcasecmp("openbiosteam,openbios", buffer)) + gMachine |= MACHINE_QEMU; + } +} + + +extern "C" void __attribute__((section(".text.start"))) +_start(uint32 _unused1, uint32 _unused3, void *openFirmwareEntry) +{ + // According to the PowerPC bindings, OpenFirmware should have created + // a stack of 32kB or higher for us at this point + + clear_bss(); + call_ctors(); + // call C++ constructors before doing anything else + + start(openFirmwareEntry); +} diff --git a/src/system/boot/platform/openfirmware/arch/sparc/Jamfile b/src/system/boot/platform/openfirmware/arch/sparc/Jamfile index 4871b0cb49..1990ac2577 100644 --- a/src/system/boot/platform/openfirmware/arch/sparc/Jamfile +++ b/src/system/boot/platform/openfirmware/arch/sparc/Jamfile @@ -1,6 +1,6 @@ SubDir HAIKU_TOP src system boot platform openfirmware arch sparc ; -SubDirHdrs $(HAIKU_TOP) src system boot platform $(HAIKU_BOOT_PLATFORM) ; +SubDirHdrs $(HAIKU_TOP) src system boot platform openfirmware ; UsePrivateSystemHeaders ; UsePrivateHeaders kernel [ FDirName kernel arch $(TARGET_KERNEL_ARCH) ] [ FDirName kernel boot platform $(HAIKU_KERNEL_PLATFORM) ] @@ -8,10 +8,11 @@ UsePrivateHeaders kernel [ FDirName kernel arch $(TARGET_KERNEL_ARCH) ] SubDirC++Flags -fno-rtti ; -BootStaticLibrary boot_platform_openfirmware_sparc : +BootMergeObject boot_platform_openfirmware_sparc.o : arch_start_kernel.S cpu.cpp mmu.cpp + start.cpp ; SEARCH on [ FGristFiles arch_cpu_asm.S arch_mmu.cpp ] diff --git a/src/system/boot/platform/openfirmware/arch/sparc/start.cpp b/src/system/boot/platform/openfirmware/arch/sparc/start.cpp new file mode 100644 index 0000000000..cd2c857b26 --- /dev/null +++ b/src/system/boot/platform/openfirmware/arch/sparc/start.cpp @@ -0,0 +1,35 @@ +/* + * Copyright 2003-2010, Axel Dörfler, axeld@pinc-software.de. + * Copyright 2011, Alexander von Gluck, kallisti5@unixzen.com + * Copyright 2019, Adrien Destugues, pulkomandy@pulkomandy.tk + * Distributed under the terms of the MIT License. + */ + + +#include "start.h" + +#include "machine.h" + + +void +determine_machine(void) +{ + gMachine = MACHINE_UNKNOWN; +} + + +extern "C" void __attribute__((section(".text.start"))) +_start(int _reserved, int _argstr, int _arglen, int _unknown, + void *openFirmwareEntry) +{ + // According to the sparc bindings, OpenFirmware should have created + // a stack of 8kB or higher for us at this point, and window traps are + // operational so it's possible to call the openFirmwareEntry safely. + // The bss segment is already cleared by the firmware as well. + + call_ctors(); + // call C++ constructors before doing anything else + + start(openFirmwareEntry); +} + diff --git a/src/system/boot/platform/openfirmware/start.cpp b/src/system/boot/platform/openfirmware/start.cpp index a2777e4177..a034441dcb 100644 --- a/src/system/boot/platform/openfirmware/start.cpp +++ b/src/system/boot/platform/openfirmware/start.cpp @@ -1,10 +1,13 @@ /* * Copyright 2003-2010, Axel Dörfler, axeld@pinc-software.de. * Copyright 2011, Alexander von Gluck, kallisti5@unixzen.com + * Copyright 2019, Adrien Destugues, pulkomandy@pulkomandy.tk * Distributed under the terms of the MIT License. */ +#include "start.h" + #include #include @@ -23,27 +26,15 @@ #define HEAP_SIZE 65536 -extern "C" void _start(uint32 _unused1, uint32 _unused2, - void *openFirmwareEntry); -extern "C" void start(void *openFirmwareEntry); - -#ifdef __powerpc__ -// XCOFF "entry-point" is actually a pointer to the real code -extern "C" void *_coff_start; -void *_coff_start = (void *)&_start; -#endif - // GCC defined globals extern void (*__ctor_list)(void); extern void (*__ctor_end)(void); -extern uint8 __bss_start; -extern uint8 _end; uint32 gMachine; static uint32 sBootOptions; -static void +void call_ctors(void) { void (**f)(void); @@ -54,52 +45,6 @@ call_ctors(void) } -#ifdef __powerpc__ -static void -clear_bss(void) -{ - memset(&__bss_start, 0, &_end - &__bss_start); -} -#endif - - -static void -determine_machine(void) -{ - gMachine = MACHINE_UNKNOWN; - - int root = of_finddevice("/"); - char buffer[64]; - int length; - - // TODO : Probe other OpenFirmware platforms and set gMachine as needed - - if ((length = of_getprop(root, "device_type", buffer, sizeof(buffer) - 1)) - != OF_FAILED) { - buffer[length] = '\0'; - if (!strcasecmp("chrp", buffer)) - gMachine = MACHINE_CHRP; - else if (!strcasecmp("bootrom", buffer)) - gMachine = MACHINE_MAC; - } else - gMachine = MACHINE_MAC; - - if ((length = of_getprop(root, "model", buffer, sizeof(buffer) - 1)) - != OF_FAILED) { - buffer[length] = '\0'; - if (!strcasecmp("pegasos", buffer)) - gMachine |= MACHINE_PEGASOS; - } - - if ((length = of_getprop(root, "name", buffer, sizeof(buffer) - 1)) - != OF_FAILED) { - buffer[length] = '\0'; - if (!strcasecmp("openbiosteam,openbios", buffer)) - gMachine |= MACHINE_QEMU; - } -} - - extern "C" void platform_start_kernel(void) { @@ -138,22 +83,6 @@ platform_boot_options(void) } -extern "C" void __attribute__((section(".text.start"))) -_start(uint32 _unused1, uint32 _unused3, void *openFirmwareEntry) -{ - // According to the PowerPC bindings, OpenFirmware should have created - // a stack of 32kB or higher for us at this point - -#ifndef __sparc__ - clear_bss(); -#endif - call_ctors(); - // call C++ constructors before doing anything else - - start(openFirmwareEntry); -} - - extern "C" void start(void *openFirmwareEntry) { @@ -178,12 +107,14 @@ start(void *openFirmwareEntry) determine_machine(); console_init(); +#ifdef __powerpc__ if ((gMachine & MACHINE_QEMU) != 0) dprintf("OpenBIOS (QEMU?) OpenFirmware machine detected\n"); else if ((gMachine & MACHINE_PEGASOS) != 0) dprintf("Pegasos PowerPC machine detected\n"); else dprintf("Apple PowerPC machine assumed\n"); +#endif // Initialize and take over MMU and set the OpenFirmware callbacks - it // will ask us for memory after that instead of maintaining it itself diff --git a/src/system/boot/platform/openfirmware/start.h b/src/system/boot/platform/openfirmware/start.h new file mode 100644 index 0000000000..9e31d8cb95 --- /dev/null +++ b/src/system/boot/platform/openfirmware/start.h @@ -0,0 +1,12 @@ +/* + * Copyright 2003-2010, Axel Dörfler, axeld@pinc-software.de. + * Copyright 2011, Alexander von Gluck, kallisti5@unixzen.com + * Copyright 2019, Adrien Destugues, pulkomandy@pulkomandy.tk + * Distributed under the terms of the MIT License. + */ + + +extern "C" void start(void *openFirmwareEntry); + +void determine_machine(void); +void call_ctors(void);