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);