* Move platform support.cpp into less generic of_support.cpp
* Add header file to support of_support.cpp * Add support functions to obtain address and size cell lengths * Small style cleanups * Add support for G5 PowerPC cpus... * Refactor memory region code to be aware of 64-bit OF addresses. As-is the boot loader wouldn't start on G5 systems because OpenFirmware memory base addresses are stored as two 32-bit unsigned int 'cells' vs one 32-bit unsigned int 'cell' on G3/G4. I removed the static struct and replaced it with a template and pass uint32 or uint64 depending on the address cell size. Thanks for the idea DeadYak! git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@42486 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
0bb924af97
commit
d24ddec4e4
@ -15,6 +15,13 @@
|
||||
extern int gChosen;
|
||||
|
||||
|
||||
template<typename addressSize>
|
||||
struct of_region
|
||||
{
|
||||
addressSize base;
|
||||
uint32 size;
|
||||
};
|
||||
|
||||
struct of_arguments {
|
||||
const char *name;
|
||||
int num_args;
|
||||
@ -27,11 +34,6 @@ struct of_arguments {
|
||||
#endif
|
||||
};
|
||||
|
||||
struct of_region {
|
||||
void *base;
|
||||
uint32 size;
|
||||
};
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
|
@ -17,7 +17,7 @@ KernelMergeObject boot_platform_openfirmware.o :
|
||||
network.cpp
|
||||
real_time_clock.cpp
|
||||
start.cpp
|
||||
support.cpp
|
||||
of_support.cpp
|
||||
video.cpp
|
||||
|
||||
openfirmware.cpp
|
||||
|
@ -17,6 +17,7 @@
|
||||
#include <arch_mmu.h>
|
||||
#include <kernel.h>
|
||||
|
||||
#include "of_support.h"
|
||||
|
||||
// set protection to WIMGNPP: -----PP
|
||||
// PP: 00 - no access
|
||||
@ -69,30 +70,81 @@ remove_virtual_range_to_keep(void *start, uint32 size)
|
||||
static status_t
|
||||
find_physical_memory_ranges(size_t &total)
|
||||
{
|
||||
int memory, package;
|
||||
int memory;
|
||||
dprintf("checking for memory...\n");
|
||||
if (of_getprop(gChosen, "memory", &memory, sizeof(int)) == OF_FAILED)
|
||||
return B_ERROR;
|
||||
package = of_instance_to_package(memory);
|
||||
int package = of_instance_to_package(memory);
|
||||
|
||||
total = 0;
|
||||
|
||||
struct of_region regions[64];
|
||||
int count;
|
||||
count = of_getprop(package, "reg", regions, sizeof(regions));
|
||||
/* 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("/");
|
||||
int regAddressCount = of_address_cells(root);
|
||||
int regSizeCount = of_size_cells(root);
|
||||
if (regAddressCount == OF_FAILED || regSizeCount == OF_FAILED) {
|
||||
dprintf("finding base/size length counts failed, assume 32-bit.\n");
|
||||
regAddressCount = 1;
|
||||
regSizeCount = 1;
|
||||
}
|
||||
dprintf("memory range address cells: %d; size cells: %d;\n",
|
||||
regAddressCount, regSizeCount);
|
||||
|
||||
if (regAddressCount > 2 || regSizeCount > 1) {
|
||||
dprintf("Unsupported cell size detected. (machine is > 64bit?).\n");
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
// On 64-bit PowerPC systems (G5), our mem base range address is larger
|
||||
if (regAddressCount == 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("%ld: 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(of_region);
|
||||
count /= sizeof(regions[0]);
|
||||
|
||||
for (int32 i = 0; i < count; i++) {
|
||||
if (regions[i].size <= 0) {
|
||||
dprintf("%ld: empty region\n", i);
|
||||
continue;
|
||||
}
|
||||
dprintf("%" B_PRIu32 ": base = %p, size = %" B_PRIu32 "\n", i,
|
||||
regions[i].base, regions[i].size);
|
||||
dprintf("%" B_PRIu32 ": base = %" B_PRIu32 ","
|
||||
"size = %" B_PRIu32 "\n", i, regions[i].base, regions[i].size);
|
||||
|
||||
total += regions[i].size;
|
||||
|
||||
|
48
src/system/boot/platform/openfirmware/of_support.cpp
Normal file
48
src/system/boot/platform/openfirmware/of_support.cpp
Normal file
@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Copyright 2005, Ingo Weinhold <bonefish@cs.tu-berlin.de>.
|
||||
* Copyright 2006-2011, Haiku, Inc. All Rights Reserved.
|
||||
* All rights reserved. Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Ingo Weinhold, bonefish@cs.tu-berlin.de
|
||||
* Alexander von Gluck, kallisti5@unixzen.com
|
||||
*/
|
||||
|
||||
|
||||
#include "of_support.h"
|
||||
#include <platform/openfirmware/openfirmware.h>
|
||||
|
||||
|
||||
bigtime_t
|
||||
system_time(void)
|
||||
{
|
||||
int result = of_milliseconds();
|
||||
return (result == OF_FAILED ? 0 : bigtime_t(result) * 1000);
|
||||
}
|
||||
|
||||
|
||||
/** given the package provided, get the number of cells
|
||||
+ in the reg property
|
||||
+ */
|
||||
|
||||
uint32
|
||||
of_address_cells(int package) {
|
||||
uint32 address_cells;
|
||||
if (of_getprop(package, "#address-cells",
|
||||
&address_cells, sizeof(address_cells)) == OF_FAILED)
|
||||
return OF_FAILED;
|
||||
|
||||
return address_cells;
|
||||
}
|
||||
|
||||
|
||||
uint32
|
||||
of_size_cells(int package) {
|
||||
uint32 size_cells;
|
||||
if (of_getprop(package, "#size-cells",
|
||||
&size_cells, sizeof(size_cells)) == OF_FAILED)
|
||||
return OF_FAILED;
|
||||
return size_cells;
|
||||
}
|
||||
|
||||
|
19
src/system/boot/platform/openfirmware/of_support.h
Normal file
19
src/system/boot/platform/openfirmware/of_support.h
Normal file
@ -0,0 +1,19 @@
|
||||
/*
|
||||
* Copyright 2006-2011, Haiku, Inc. All Rights Reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Alexander von Gluck, kallisti5@unixzen.com
|
||||
*/
|
||||
#ifndef OF_SUPPORT_H
|
||||
#define OF_SUPPORT_H
|
||||
|
||||
|
||||
#include <OS.h>
|
||||
|
||||
|
||||
bigtime_t system_time(void);
|
||||
uint32 of_address_cells(int package);
|
||||
uint32 of_size_cells(int package);
|
||||
|
||||
#endif
|
@ -1,17 +0,0 @@
|
||||
/*
|
||||
* Copyright 2005, Ingo Weinhold <bonefish@cs.tu-berlin.de>.
|
||||
* All rights reserved. Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
|
||||
#include <OS.h>
|
||||
|
||||
#include <platform/openfirmware/openfirmware.h>
|
||||
|
||||
|
||||
bigtime_t
|
||||
system_time(void)
|
||||
{
|
||||
int result = of_milliseconds();
|
||||
return (result == OF_FAILED ? 0 : bigtime_t(result) * 1000);
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user