* 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:
@@ -15,6 +15,13 @@
|
|||||||
extern int gChosen;
|
extern int gChosen;
|
||||||
|
|
||||||
|
|
||||||
|
template<typename addressSize>
|
||||||
|
struct of_region
|
||||||
|
{
|
||||||
|
addressSize base;
|
||||||
|
uint32 size;
|
||||||
|
};
|
||||||
|
|
||||||
struct of_arguments {
|
struct of_arguments {
|
||||||
const char *name;
|
const char *name;
|
||||||
int num_args;
|
int num_args;
|
||||||
@@ -27,11 +34,6 @@ struct of_arguments {
|
|||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
struct of_region {
|
|
||||||
void *base;
|
|
||||||
uint32 size;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ KernelMergeObject boot_platform_openfirmware.o :
|
|||||||
network.cpp
|
network.cpp
|
||||||
real_time_clock.cpp
|
real_time_clock.cpp
|
||||||
start.cpp
|
start.cpp
|
||||||
support.cpp
|
of_support.cpp
|
||||||
video.cpp
|
video.cpp
|
||||||
|
|
||||||
openfirmware.cpp
|
openfirmware.cpp
|
||||||
|
|||||||
@@ -17,6 +17,7 @@
|
|||||||
#include <arch_mmu.h>
|
#include <arch_mmu.h>
|
||||||
#include <kernel.h>
|
#include <kernel.h>
|
||||||
|
|
||||||
|
#include "of_support.h"
|
||||||
|
|
||||||
// set protection to WIMGNPP: -----PP
|
// set protection to WIMGNPP: -----PP
|
||||||
// PP: 00 - no access
|
// PP: 00 - no access
|
||||||
@@ -69,30 +70,81 @@ remove_virtual_range_to_keep(void *start, uint32 size)
|
|||||||
static status_t
|
static status_t
|
||||||
find_physical_memory_ranges(size_t &total)
|
find_physical_memory_ranges(size_t &total)
|
||||||
{
|
{
|
||||||
int memory, package;
|
int memory;
|
||||||
dprintf("checking for memory...\n");
|
dprintf("checking for memory...\n");
|
||||||
if (of_getprop(gChosen, "memory", &memory, sizeof(int)) == OF_FAILED)
|
if (of_getprop(gChosen, "memory", &memory, sizeof(int)) == OF_FAILED)
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
package = of_instance_to_package(memory);
|
int package = of_instance_to_package(memory);
|
||||||
|
|
||||||
total = 0;
|
total = 0;
|
||||||
|
|
||||||
struct of_region regions[64];
|
/* Memory base addresses are provided in 32 or 64 bit flavors
|
||||||
int count;
|
#address-cells and #size-cells matches the number of 32-bit 'cells'
|
||||||
count = of_getprop(package, "reg", regions, sizeof(regions));
|
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)
|
if (count == OF_FAILED)
|
||||||
count = of_getprop(memory, "reg", regions, sizeof(regions));
|
count = of_getprop(memory, "reg", regions, sizeof(regions));
|
||||||
if (count == OF_FAILED)
|
if (count == OF_FAILED)
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
count /= sizeof(of_region);
|
count /= sizeof(regions[0]);
|
||||||
|
|
||||||
for (int32 i = 0; i < count; i++) {
|
for (int32 i = 0; i < count; i++) {
|
||||||
if (regions[i].size <= 0) {
|
if (regions[i].size <= 0) {
|
||||||
dprintf("%ld: empty region\n", i);
|
dprintf("%ld: empty region\n", i);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
dprintf("%" B_PRIu32 ": base = %p, size = %" B_PRIu32 "\n", i,
|
dprintf("%" B_PRIu32 ": base = %" B_PRIu32 ","
|
||||||
regions[i].base, regions[i].size);
|
"size = %" B_PRIu32 "\n", i, regions[i].base, regions[i].size);
|
||||||
|
|
||||||
total += regions[i].size;
|
total += regions[i].size;
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,48 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2005, Ingo Weinhold <[email protected]>.
|
||||||
|
* Copyright 2006-2011, Haiku, Inc. All Rights Reserved.
|
||||||
|
* All rights reserved. Distributed under the terms of the MIT License.
|
||||||
|
*
|
||||||
|
* Authors:
|
||||||
|
* Ingo Weinhold, [email protected]
|
||||||
|
* Alexander von Gluck, [email protected]
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2006-2011, Haiku, Inc. All Rights Reserved.
|
||||||
|
* Distributed under the terms of the MIT License.
|
||||||
|
*
|
||||||
|
* Authors:
|
||||||
|
* Alexander von Gluck, [email protected]
|
||||||
|
*/
|
||||||
|
#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 <[email protected]>.
|
|
||||||
* 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);
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user