sparc: fix bootloader build

- Add various missing jamfiles
- Add required implementation stubs
- Update openfirmware jamfiles for multiboot support
- Update linker rules for sparc loader

Change-Id: I2d06c7a4d33827f58d82946687003f9a0dcb1b7d
Reviewed-on: https://review.haiku-os.org/c/1329
Reviewed-by: waddlesplash <waddlesplash@gmail.com>
This commit is contained in:
PulkoMandy 2019-03-28 08:07:33 +01:00 committed by waddlesplash
parent 834a613e53
commit e8f58ba4be
16 changed files with 825 additions and 42 deletions

View File

@ -0,0 +1,15 @@
/*
** Copyright 2019, Adrien Destugues, pulkomandy@pulkomandy.tk
** Distributed under the terms of the MIT License.
*/
#ifndef _KERNEL_ARCH_SPARC_MMU_H
#define _KERNEL_ARCH_SPARC_MMU_H
#include <SupportDefs.h>
#include <string.h>
#include <arch_cpu.h>
#endif /* _KERNEL_ARCH_SPARC_MMU_H */

View File

@ -0,0 +1,11 @@
SubDir HAIKU_TOP src add-ons kernel bus_managers config_manager arch $(TARGET_ARCH) ;
SubDirHdrs [ FDirName $(SUBDIR) $(DOTDOT) $(DOTDOT) ] ;
UsePrivateHeaders kernel [ FDirName kernel arch $(TARGET_ARCH) ] ;
KernelStaticLibrary config_manager_arch :
config_manager_arch.c
;

View File

@ -0,0 +1,18 @@
/*
* Copyright 2009 Haiku, Inc.
* Distributed under the terms of the MIT License.
*
* arch-specific config manager
*
* Authors (in chronological order):
* François Revol (revol@free.fr)
*/
#include <OS.h>
#include <config_manager.h>
int config_manager_scan_hardcoded(struct device_info **info, int32 *count)
{
return B_OK;
}

View File

@ -0,0 +1,16 @@
SubDir HAIKU_TOP src add-ons kernel bus_managers pci arch sparc ;
SubDirHdrs [ FDirName $(SUBDIR) $(DOTDOT) $(DOTDOT) ] ;
UsePrivateHeaders kernel [ FDirName kernel arch $(TARGET_ARCH) ]
[ FDirName kernel boot platform $(HAIKU_BOOT_PLATFORM) ] ;
SEARCH_SOURCE += [ FDirName $(SUBDIR) openfirmware ] ;
KernelStaticLibrary pci_arch_bus_manager :
pci_controller.cpp
pci_io.c
# openfirmware
# TODO
;

View File

@ -1,33 +1,29 @@
SubDir HAIKU_TOP src system boot arch sparc ;
{
local defines = _BOOT_MODE ;
defines = [ FDefines $(defines) ] ;
SubDirCcFlags $(defines) ;
SubDirC++Flags $(defines) -fno-rtti ;
}
local kernelLibArchObjects =
<src!system!kernel!lib!arch!$(TARGET_ARCH)>byteorder.o
<src!system!kernel!lib!arch!$(TARGET_ARCH)>memcpy.o
<src!system!kernel!lib!arch!$(TARGET_ARCH)>memset.o
;
BootMergeObject boot_arch_$(TARGET_KERNEL_ARCH).o :
debug_uart_8250.cpp
#arch_uart_8250.cpp
arch_elf.cpp
: # additional flags
:
$(kernelArchObjects)
$(kernelLibArchObjects)
;
local platform ;
for platform in [ MultiBootSubDirSetup openfirmware ] {
on $(platform) {
DEFINES += _BOOT_MODE ;
SEARCH on [ FGristFiles arch_elf.cpp arch_uart_8250.cpp ]
= [ FDirName $(HAIKU_TOP) src system kernel arch $(TARGET_KERNEL_ARCH) ] ;
BootMergeObject [ FGristFiles boot_arch_$(TARGET_KERNEL_ARCH).o ] :
debug_uart_8250.cpp
#arch_uart_8250.cpp
arch_elf.cpp
: # additional flags
:
$(kernelArchObjects)
$(kernelLibArchObjects)
;
SEARCH on [ FGristFiles debug_uart_8250.cpp ]
= [ FDirName $(HAIKU_TOP) src system kernel arch generic ] ;
SEARCH on [ FGristFiles arch_elf.cpp arch_uart_8250.cpp ]
= [ FDirName $(HAIKU_TOP) src system kernel arch $(TARGET_KERNEL_ARCH) ] ;
SEARCH on [ FGristFiles debug_uart_8250.cpp ]
= [ FDirName $(HAIKU_TOP) src system kernel arch generic ] ;
}
}

View File

@ -4,9 +4,14 @@ SubDirC++Flags -D_BOOT_MODE -fno-rtti ;
UsePrivateHeaders [ FDirName graphics common ] ;
SEARCH_SOURCE += [ FDirName $(HAIKU_TOP) src add-ons accelerants common ] ;
{
local defines = _BOOT_MODE _BOOT_PLATFORM_OPENFIRMWARE ;
defines = [ FDefines $(defines) ] ;
SubDirCcFlags $(defines) ;
SubDirC++Flags $(defines) -fno-rtti ;
}
BootMergeObject boot_platform_openfirmware.o :
local platform_src =
console.cpp
debug.cpp
devices.cpp
@ -19,23 +24,41 @@ BootMergeObject boot_platform_openfirmware.o :
start.cpp
support.cpp
video.cpp
;
local kernel_src =
openfirmware.cpp
openfirmware_devices.cpp
;
local vesa_src =
# VESA/DDC EDID
decode_edid.c
dump_edid.c
:
:
boot_platform_generic.a
boot_platform_openfirmware_$(TARGET_ARCH).a
;
SEARCH on [ FGristFiles $(genericPlatformSources) ]
= [ FDirName $(HAIKU_TOP) src system boot platform generic ] ;
SEARCH on [ FGristFiles openfirmware.cpp openfirmware_devices.cpp ]
= [ FDirName $(HAIKU_TOP) src system kernel platform openfirmware ] ;
local platform ;
for platform in [ MultiBootSubDirSetup openfirmware ] {
on $(platform) {
BootMergeObject boot_platform_openfirmware.o :
$(platform_src)
$(kernel_src)
$(vesa_src)
:
:
boot_platform_generic_openfirmware.a
boot_platform_openfirmware_$(TARGET_ARCH).a
;
# SEARCH on [ FGristFiles $(genericPlatformSources) ]
# = [ FDirName $(HAIKU_TOP) src system boot platform generic ] ;
SEARCH on [ FGristFiles $(kernel_src) ]
= [ FDirName $(HAIKU_TOP) src system kernel platform openfirmware ] ;
SEARCH on [ FGristFiles $(vesa_src) ]
= [ FDirName $(HAIKU_TOP) src add-ons accelerants common ] ;
}
}
SubInclude HAIKU_TOP src system boot platform openfirmware arch ;

View File

@ -1,6 +1,6 @@
SubDir HAIKU_TOP src system boot platform openfirmware arch sparc ;
SubDirHdrs $(HAIKU_TOP) src system boot platform $(TARGET_BOOT_PLATFORM) ;
SubDirHdrs $(HAIKU_TOP) src system boot platform $(HAIKU_BOOT_PLATFORM) ;
UsePrivateSystemHeaders ;
UsePrivateHeaders kernel [ FDirName kernel arch $(TARGET_KERNEL_ARCH) ]
[ FDirName kernel boot platform $(HAIKU_KERNEL_PLATFORM) ]
@ -9,6 +9,9 @@ UsePrivateHeaders kernel [ FDirName kernel arch $(TARGET_KERNEL_ARCH) ]
SubDirC++Flags -fno-rtti ;
BootStaticLibrary boot_platform_openfirmware_sparc :
arch_start_kernel.S
cpu.cpp
mmu.cpp
;
SEARCH on [ FGristFiles arch_cpu_asm.S arch_mmu.cpp ]

View File

@ -0,0 +1,16 @@
/*
* Copyright 2005, Ingo Weinhold <bonefish@cs.tu-berlin.de>.
* All rights reserved. Distributed under the terms of the MIT License.
*/
#define FUNCTION(x) .global x; .type x,@function; x
/* status_t arch_start_kernel(struct kernel_args *kernelArgs,
addr_t kernelEntry, addr_t kernelStackTop);
r3 - kernelArgs
r4 - kernelEntry
r5 - kernelStackTop
*/
FUNCTION(arch_start_kernel):
return

View File

@ -0,0 +1,125 @@
/*
* Copyright 2005, Ingo Weinhold <bonefish@cs.tu-berlin.de>.
* All rights reserved. Distributed under the terms of the MIT License.
*/
#include <boot/platform/openfirmware/platform_arch.h>
#include <stdio.h>
#include <KernelExport.h>
#include <boot/kernel_args.h>
#include <boot/stage2.h>
#include <kernel.h>
#include <platform/openfirmware/devices.h>
#include <platform/openfirmware/openfirmware.h>
#define TRACE_CPU
#ifdef TRACE_CPU
# define TRACE(x) dprintf x
#else
# define TRACE(x) ;
#endif
status_t
boot_arch_cpu_init(void)
{
int32 busFrequency = 0;
int root = of_finddevice("/");
if (root == OF_FAILED) {
printf("boot_arch_cpu_init(): Failed to open \"/\"!\n");
return B_ERROR;
}
of_getprop(root, "clock-frequency", &busFrequency, 4);
// we might find it in /cpus instead
// iterate through the "/cpus" node to find all CPUs
int cpus = of_finddevice("/cpus");
if (cpus == OF_FAILED) {
printf("boot_arch_cpu_init(): Failed to open \"/cpus\"!\n");
return B_ERROR;
}
char cpuPath[256];
int cookie = 0;
int cpuCount = 0;
while (of_get_next_device(&cookie, cpus, "cpu", cpuPath,
sizeof(cpuPath)) == B_OK) {
TRACE(("found CPU: %s\n", cpuPath));
// For the first CPU get the frequencies of CPU, bus, and time base.
// We assume they are the same for all CPUs.
if (cpuCount == 0) {
int cpu = of_finddevice(cpuPath);
if (cpu == OF_FAILED) {
printf("boot_arch_cpu_init: Failed get CPU device node!\n");
return B_ERROR;
}
// TODO: Does encode-int really encode quadlet (32 bit numbers)
// only?
int32 clockFrequency;
if (of_getprop(cpu, "clock-frequency", &clockFrequency, 4)
== OF_FAILED) {
printf("boot_arch_cpu_init: Failed to get CPU clock "
"frequency!\n");
return B_ERROR;
}
if (busFrequency == 0
&& of_getprop(cpu, "bus-frequency", &busFrequency, 4)
== OF_FAILED) {
printf("boot_arch_cpu_init: Failed to get bus clock "
"frequency!\n");
return B_ERROR;
}
int32 timeBaseFrequency;
if (of_getprop(cpu, "timebase-frequency", &timeBaseFrequency, 4)
== OF_FAILED) {
printf("boot_arch_cpu_init: Failed to get time base "
"frequency!\n");
return B_ERROR;
}
gKernelArgs.arch_args.cpu_frequency = clockFrequency;
gKernelArgs.arch_args.bus_frequency = busFrequency;
gKernelArgs.arch_args.time_base_frequency = timeBaseFrequency;
TRACE((" CPU clock frequency: %d\n", clockFrequency));
TRACE((" bus clock frequency: %d\n", busFrequency));
TRACE((" time base frequency: %d\n", timeBaseFrequency));
}
cpuCount++;
}
if (cpuCount == 0) {
printf("boot_arch_cpu_init(): Found no CPUs!\n");
return B_ERROR;
}
gKernelArgs.num_cpus = cpuCount;
// allocate the kernel stacks (the memory stuff is already initialized
// at this point)
addr_t stack = (addr_t)arch_mmu_allocate((void*)0x80000000,
cpuCount * (KERNEL_STACK_SIZE + KERNEL_STACK_GUARD_PAGES * B_PAGE_SIZE),
B_READ_AREA | B_WRITE_AREA, false);
if (!stack) {
printf("boot_arch_cpu_init(): Failed to allocate kernel stack(s)!\n");
return B_NO_MEMORY;
}
for (int i = 0; i < cpuCount; i++) {
gKernelArgs.cpu_kstack[i].start = stack;
gKernelArgs.cpu_kstack[i].size = KERNEL_STACK_SIZE
+ KERNEL_STACK_GUARD_PAGES * B_PAGE_SIZE;
stack += KERNEL_STACK_SIZE + KERNEL_STACK_GUARD_PAGES * B_PAGE_SIZE;
}
return B_OK;
}

View File

@ -0,0 +1,457 @@
/*
* Copyright 2003-2009, Axel Dörfler, axeld@pinc-software.de.
* Copyright 2010-2011, Haiku, Inc. All Rights Reserved.
* All rights reserved. Distributed under the terms of the MIT License.
*
* Authors:
* Axel Dörfler, axeld@pinc-software.de.
* Alexander von Gluck, kallisti5@unixzen.com
*/
#include <OS.h>
#include <platform_arch.h>
#include <boot/addr_range.h>
#include <boot/kernel_args.h>
#include <boot/platform.h>
#include <boot/stage2.h>
#include <boot/stdio.h>
#include <platform/openfirmware/openfirmware.h>
#include <arch_cpu.h>
#include <arch_mmu.h>
#include <kernel.h>
#include "support.h"
// set protection to WIMGNPP: -----PP
// PP: 00 - no access
// 01 - read only
// 10 - read/write
// 11 - read only
#define PAGE_READ_ONLY 0x01
#define PAGE_READ_WRITE 0x02
// NULL is actually a possible physical address...
//#define PHYSINVAL ((void *)-1)
#define PHYSINVAL NULL
//#define TRACE_MMU
#ifdef TRACE_MMU
# define TRACE(x...) dprintf(x)
#else
# define TRACE(x...) ;
#endif
uint32 sPageTableHashMask;
// begin and end of the boot loader
extern "C" uint8 __text_begin;
extern "C" uint8 _end;
static status_t
find_physical_memory_ranges(size_t &total)
{
int memory;
dprintf("checking for memory...\n");
if (of_getprop(gChosen, "memory", &memory, sizeof(int)) == OF_FAILED)
return B_ERROR;
int package = of_instance_to_package(memory);
total = 0;
// Memory base addresses are provided in 32 or 64 bit flavors
// #address-cells and #size-cells matches the number of 32-bit 'cells'
// representing the length of the base address and size fields
int root = of_finddevice("/");
int32 regAddressCells = of_address_cells(root);
int32 regSizeCells = of_size_cells(root);
if (regAddressCells == OF_FAILED || regSizeCells == OF_FAILED) {
dprintf("finding base/size length counts failed, assume 32-bit.\n");
regAddressCells = 1;
regSizeCells = 1;
}
// NOTE : Size Cells of 2 is possible in theory... but I haven't seen it yet.
if (regAddressCells > 2 || regSizeCells > 1) {
panic("%s: Unsupported OpenFirmware cell count detected.\n"
"Address Cells: %" B_PRId32 "; Size Cells: %" B_PRId32
" (CPU > 64bit?).\n", __func__, regAddressCells, regSizeCells);
return B_ERROR;
}
// On 64-bit PowerPC systems (G5), our mem base range address is larger
if (regAddressCells == 2) {
struct of_region<uint64> regions[64];
int count = of_getprop(package, "reg", regions, sizeof(regions));
if (count == OF_FAILED)
count = of_getprop(memory, "reg", regions, sizeof(regions));
if (count == OF_FAILED)
return B_ERROR;
count /= sizeof(regions[0]);
for (int32 i = 0; i < count; i++) {
if (regions[i].size <= 0) {
dprintf("%d: empty region\n", i);
continue;
}
dprintf("%" B_PRIu32 ": base = %" B_PRIu64 ","
"size = %" B_PRIu32 "\n", i, regions[i].base, regions[i].size);
total += regions[i].size;
if (insert_physical_memory_range((addr_t)regions[i].base,
regions[i].size) != B_OK) {
dprintf("cannot map physical memory range "
"(num ranges = %" B_PRIu32 ")!\n",
gKernelArgs.num_physical_memory_ranges);
return B_ERROR;
}
}
return B_OK;
}
// Otherwise, normal 32-bit PowerPC G3 or G4 have a smaller 32-bit one
struct of_region<uint32> regions[64];
int count = of_getprop(package, "reg", regions, sizeof(regions));
if (count == OF_FAILED)
count = of_getprop(memory, "reg", regions, sizeof(regions));
if (count == OF_FAILED)
return B_ERROR;
count /= sizeof(regions[0]);
for (int32 i = 0; i < count; i++) {
if (regions[i].size <= 0) {
dprintf("%d: empty region\n", i);
continue;
}
dprintf("%" B_PRIu32 ": base = %" B_PRIu32 ","
"size = %" B_PRIu32 "\n", i, regions[i].base, regions[i].size);
total += regions[i].size;
if (insert_physical_memory_range((addr_t)regions[i].base,
regions[i].size) != B_OK) {
dprintf("cannot map physical memory range "
"(num ranges = %" B_PRIu32 ")!\n",
gKernelArgs.num_physical_memory_ranges);
return B_ERROR;
}
}
return B_OK;
}
static bool
is_virtual_allocated(void *address, size_t size)
{
uint64 foundBase;
return !get_free_address_range(gKernelArgs.virtual_allocated_range,
gKernelArgs.num_virtual_allocated_ranges, (addr_t)address, size,
&foundBase) || foundBase != (addr_t)address;
}
static bool
is_physical_allocated(void *address, size_t size)
{
uint64 foundBase;
return !get_free_address_range(gKernelArgs.physical_allocated_range,
gKernelArgs.num_physical_allocated_ranges, (addr_t)address, size,
&foundBase) || foundBase != (addr_t)address;
}
static bool
is_physical_memory(void *address, size_t size)
{
return is_address_range_covered(gKernelArgs.physical_memory_range,
gKernelArgs.num_physical_memory_ranges, (addr_t)address, size);
}
static bool
is_physical_memory(void *address)
{
return is_physical_memory(address, 1);
}
static void
map_page(void *virtualAddress, void *physicalAddress, uint8 mode)
{
panic("%s: out of page table entries!\n", __func__);
}
static void
map_range(void *virtualAddress, void *physicalAddress, size_t size, uint8 mode)
{
for (uint32 offset = 0; offset < size; offset += B_PAGE_SIZE) {
map_page((void *)(intptr_t(virtualAddress) + offset),
(void *)(intptr_t(physicalAddress) + offset), mode);
}
}
static void *
find_physical_memory_range(size_t size)
{
for (uint32 i = 0; i < gKernelArgs.num_physical_memory_ranges; i++) {
if (gKernelArgs.physical_memory_range[i].size > size)
return (void *)(addr_t)gKernelArgs.physical_memory_range[i].start;
}
return PHYSINVAL;
}
static void *
find_free_physical_range(size_t size)
{
// just do a simple linear search at the end of the allocated
// ranges (dumb memory allocation)
if (gKernelArgs.num_physical_allocated_ranges == 0) {
if (gKernelArgs.num_physical_memory_ranges == 0)
return PHYSINVAL;
return find_physical_memory_range(size);
}
for (uint32 i = 0; i < gKernelArgs.num_physical_allocated_ranges; i++) {
void *address
= (void *)(addr_t)(gKernelArgs.physical_allocated_range[i].start
+ gKernelArgs.physical_allocated_range[i].size);
if (!is_physical_allocated(address, size)
&& is_physical_memory(address, size))
return address;
}
return PHYSINVAL;
}
static void *
find_free_virtual_range(void *base, size_t size)
{
if (base && !is_virtual_allocated(base, size))
return base;
void *firstFound = NULL;
void *firstBaseFound = NULL;
for (uint32 i = 0; i < gKernelArgs.num_virtual_allocated_ranges; i++) {
void *address
= (void *)(addr_t)(gKernelArgs.virtual_allocated_range[i].start
+ gKernelArgs.virtual_allocated_range[i].size);
if (!is_virtual_allocated(address, size)) {
if (!base)
return address;
if (firstFound == NULL)
firstFound = address;
if (address >= base
&& (firstBaseFound == NULL || address < firstBaseFound)) {
firstBaseFound = address;
}
}
}
return (firstBaseFound ? firstBaseFound : firstFound);
}
extern "C" void *
arch_mmu_allocate(void *_virtualAddress, size_t size, uint8 _protection,
bool exactAddress)
{
// we only know page sizes
size = ROUNDUP(size, B_PAGE_SIZE);
uint8 protection = 0;
if (_protection & B_WRITE_AREA)
protection = PAGE_READ_WRITE;
else
protection = PAGE_READ_ONLY;
// If no address is given, use the KERNEL_BASE as base address, since
// that avoids trouble in the kernel, when we decide to keep the region.
void *virtualAddress = _virtualAddress;
if (!virtualAddress)
virtualAddress = (void*)KERNEL_BASE;
// find free address large enough to hold "size"
virtualAddress = find_free_virtual_range(virtualAddress, size);
if (virtualAddress == NULL)
return NULL;
// fail if the exact address was requested, but is not free
if (exactAddress && _virtualAddress && virtualAddress != _virtualAddress) {
dprintf("arch_mmu_allocate(): exact address requested, but virtual "
"range (base: %p, size: %" B_PRIuSIZE ") is not free.\n",
_virtualAddress, size);
return NULL;
}
// we have a free virtual range for the allocation, now
// have a look for free physical memory as well (we assume
// that a) there is enough memory, and b) failing is fatal
// so that we don't have to optimize for these cases :)
void *physicalAddress = find_free_physical_range(size);
if (physicalAddress == PHYSINVAL) {
dprintf("arch_mmu_allocate(base: %p, size: %" B_PRIuSIZE ") "
"no free physical address\n", virtualAddress, size);
return NULL;
}
// everything went fine, so lets mark the space as used.
dprintf("mmu_alloc: va %p, pa %p, size %" B_PRIuSIZE "\n", virtualAddress,
physicalAddress, size);
insert_virtual_allocated_range((addr_t)virtualAddress, size);
insert_physical_allocated_range((addr_t)physicalAddress, size);
map_range(virtualAddress, physicalAddress, size, protection);
return virtualAddress;
}
extern "C" status_t
arch_mmu_free(void *address, size_t size)
{
// TODO: implement freeing a region!
return B_OK;
}
// #pragma mark - OpenFirmware callbacks and public API
static int
map_callback(struct of_arguments *args)
{
void *physicalAddress = (void *)args->Argument(0);
void *virtualAddress = (void *)args->Argument(1);
int length = args->Argument(2);
int mode = args->Argument(3);
intptr_t &error = args->ReturnValue(0);
// insert range in physical allocated if needed
if (is_physical_memory(physicalAddress)
&& insert_physical_allocated_range((addr_t)physicalAddress, length)
!= B_OK) {
error = -1;
return OF_FAILED;
}
// insert range in virtual allocated
if (insert_virtual_allocated_range((addr_t)virtualAddress, length)
!= B_OK) {
error = -2;
return OF_FAILED;
}
// map range into the page table
map_range(virtualAddress, physicalAddress, length, mode);
return B_OK;
}
static int
unmap_callback(struct of_arguments *args)
{
/* void *address = (void *)args->Argument(0);
int length = args->Argument(1);
int &error = args->ReturnValue(0);
*/
// TODO: to be implemented
return OF_FAILED;
}
static int
translate_callback(struct of_arguments *args)
{
// could not find the translation
return OF_FAILED;
}
static int
alloc_real_mem_callback(struct of_arguments *args)
{
/* addr_t minAddress = (addr_t)args->Argument(0);
addr_t maxAddress = (addr_t)args->Argument(1);
int length = args->Argument(2);
int mode = args->Argument(3);
int &error = args->ReturnValue(0);
int &physicalAddress = args->ReturnValue(1);
*/
// ToDo: to be implemented
return OF_FAILED;
}
/** Dispatches the callback to the responsible function */
static int
callback(struct of_arguments *args)
{
const char *name = args->name;
TRACE("OF CALLBACK: %s\n", name);
if (!strcmp(name, "map"))
return map_callback(args);
else if (!strcmp(name, "unmap"))
return unmap_callback(args);
else if (!strcmp(name, "translate"))
return translate_callback(args);
else if (!strcmp(name, "alloc-real-mem"))
return alloc_real_mem_callback(args);
return OF_FAILED;
}
extern "C" status_t
arch_set_callback(void)
{
// set OpenFirmware callbacks - it will ask us for memory after that
// instead of maintaining it itself
void *oldCallback = NULL;
if (of_call_client_function("set-callback", 1, 1, &callback, &oldCallback)
== OF_FAILED) {
dprintf("Error: OpenFirmware set-callback failed\n");
return B_ERROR;
}
TRACE("old callback = %p; new callback = %p\n", oldCallback, callback);
return B_OK;
}
extern "C" status_t
arch_mmu_init(void)
{
// get map of physical memory (fill in kernel_args structure)
size_t total;
if (find_physical_memory_ranges(total) != B_OK) {
dprintf("Error: could not find physical memory ranges!\n");
return B_ERROR;
}
dprintf("total physical memory = %luMB\n", total / (1024 * 1024));
return B_OK;
}

View File

@ -0,0 +1,45 @@
OUTPUT_FORMAT("elf64-sparc")
OUTPUT_ARCH(sparc:v9)
ENTRY(_start)
SECTIONS
{
. = 0x202000 + SIZEOF_HEADERS;
__text_begin = .;
/* text/read-only data */
.text : { *(.text .text.* .gnu.linkonce.t.*)
*(.rodata .rodata.* .gnu.linkonce.r.*)
*(.sdata2) }
/* writable data */
/* align to the same offset in the next page (for performance reasons
(not that it really matters in the boot loader)) */
. = ALIGN(0x1000) + 0x1000 + (. & (0x1000 - 1));
.data : {
__ctor_list = .;
*(.ctors)
__ctor_end = .;
__data_start = .;
*(.data .gnu.linkonce.d.*)
*(.data.rel.ro.local .data.rel.ro*)
*(.got .got2)
*(.sdata .sdata.* .gnu.linkonce.s.* .fixup) }
/* uninitialized data (in same segment as writable data) */
__bss_start = .;
.bss : { *(.sbss .sbss.* .gnu.linkonce.sb.*)
*(.bss .bss.* .gnu.linkonce.b.*)
. = ALIGN(0x1000);
}
_end = . ;
/* Strip unnecessary stuff */
/DISCARD/ : { *(.comment .note .eh_frame .dtors .debug_* .gnu.attributes) }
}

View File

@ -1,10 +1,17 @@
SubDir HAIKU_TOP src system libroot posix string arch sparc ;
UsePrivateSystemHeaders ;
local architectureObject ;
for architectureObject in [ MultiArchSubDirSetup sparc ] {
on $(architectureObject) {
local architecture = $(TARGET_PACKAGING_ARCH) ;
SEARCH_SOURCE += [ FDirName $(SUBDIR) $(DOTDOT) generic ] ;
UsePrivateSystemHeaders ;
MergeObject <$(TARGET_ARCH)>posix_string_arch_$(TARGET_ARCH).o :
memcpy.c
memset.c
;
SEARCH_SOURCE += [ FDirName $(SUBDIR) $(DOTDOT) generic ] ;
MergeObject <$(TARGET_ARCH)>posix_string_arch_$(TARGET_ARCH).o :
memcpy.c
memset.c
;
}
}

View File

@ -7,7 +7,7 @@ if $(TARGET_ARCH) = x86_64
}
local architectureObject ;
for architectureObject in [ MultiArchSubDirSetup ] {
for architectureObject in [ MultiArchSubDirSetup sparc ] {
on $(architectureObject) {
local architecture = $(TARGET_PACKAGING_ARCH) ;

View File

@ -0,0 +1,21 @@
SubDir HAIKU_TOP src system runtime_loader arch sparc ;
local architectureObject ;
for architectureObject in [ MultiArchSubDirSetup sparc ] {
on $(architectureObject) {
local architecture = $(TARGET_PACKAGING_ARCH) ;
UsePrivateHeaders runtime_loader ;
UsePrivateSystemHeaders ;
SubDirHdrs [ FDirName $(SUBDIR) $(DOTDOT) $(DOTDOT) ] ;
StaticLibrary <$(architecture)>libruntime_loader_$(TARGET_ARCH).a :
arch_relocate.cpp
:
<src!system!libroot!os!arch!$(TARGET_ARCH)!$(architecture)>thread.o
<src!system!libroot!posix!string!arch!$(TARGET_ARCH)!$(architecture)>memset.o
;
}
}

View File

@ -0,0 +1,30 @@
/*
* Copyright 2012-2018, Haiku, Inc. All rights reserved.
* Distributed under the terms of the MIT License.
*
* Authors:
* Ithamar R. Adema <ithamar@upgrade-android.com>
*/
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include "runtime_loader_private.h"
#include <runtime_loader.h>
//#define TRACE_RLD
#ifdef TRACE_RLD
# define TRACE(x) dprintf x
#else
# define TRACE(x) ;
#endif
status_t
arch_relocate_image(image_t *rootImage, image_t *image,
SymbolLookupCache* cache)
{
debugger("arch_relocate_image: Not Yet Implemented!");
return B_OK;
}