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:
@@ -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);
|
||||
Reference in New Issue
Block a user