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 <[email protected]>
This commit is contained in:
PulkoMandy
2019-05-25 18:16:35 +00:00
committed by waddlesplash
parent 906c14da63
commit cdbda49e88
7 changed files with 140 additions and 79 deletions
@@ -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) ]
@@ -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 ]
@@ -0,0 +1,81 @@
/*
* Copyright 2003-2010, Axel Dörfler, [email protected].
* Copyright 2011, Alexander von Gluck, [email protected]
* Copyright 2019, Adrien Destugues, [email protected]
* 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);
}
@@ -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 ]
@@ -0,0 +1,35 @@
/*
* Copyright 2003-2010, Axel Dörfler, [email protected].
* Copyright 2011, Alexander von Gluck, [email protected]
* Copyright 2019, Adrien Destugues, [email protected]
* 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);
}
@@ -1,10 +1,13 @@
/*
* Copyright 2003-2010, Axel Dörfler, [email protected].
* Copyright 2011, Alexander von Gluck, [email protected]
* Copyright 2019, Adrien Destugues, [email protected]
* Distributed under the terms of the MIT License.
*/
#include "start.h"
#include <string.h>
#include <OS.h>
@@ -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
@@ -0,0 +1,12 @@
/*
* Copyright 2003-2010, Axel Dörfler, [email protected].
* Copyright 2011, Alexander von Gluck, [email protected]
* Copyright 2019, Adrien Destugues, [email protected]
* Distributed under the terms of the MIT License.
*/
extern "C" void start(void *openFirmwareEntry);
void determine_machine(void);
void call_ctors(void);