summaryrefslogtreecommitdiffstats
path: root/sys/boot/ofw
diff options
context:
space:
mode:
authornwhitehorn <nwhitehorn@FreeBSD.org>2010-10-28 23:46:05 +0000
committernwhitehorn <nwhitehorn@FreeBSD.org>2010-10-28 23:46:05 +0000
commit4da7d606a25ece6c60dd8f08f085da60d3ac3a5f (patch)
tree964a3f93b40db7ae9565c875ac2858a732dc15f9 /sys/boot/ofw
parent6f54496b1660e6b4fd963cbd53a65890e2eaa8d4 (diff)
downloadFreeBSD-src-4da7d606a25ece6c60dd8f08f085da60d3ac3a5f.zip
FreeBSD-src-4da7d606a25ece6c60dd8f08f085da60d3ac3a5f.tar.gz
Fix some memory management issues discovered when trying to boot the PPC
OF loader on systems where address cells and size cells are both 2 (the Mambo simulator) and fix an error where cons_probe() was called before init_heap() but used malloc() to set environment variables. MFC after: 1 month
Diffstat (limited to 'sys/boot/ofw')
-rw-r--r--sys/boot/ofw/common/main.c40
-rw-r--r--sys/boot/ofw/libofw/ofw_memory.c14
-rw-r--r--sys/boot/ofw/libofw/openfirm.c9
3 files changed, 35 insertions, 28 deletions
diff --git a/sys/boot/ofw/common/main.c b/sys/boot/ofw/common/main.c
index 1a03e9b..00fe9ca 100644
--- a/sys/boot/ofw/common/main.c
+++ b/sys/boot/ofw/common/main.c
@@ -41,7 +41,7 @@ extern char bootprog_rev[];
extern char bootprog_date[];
extern char bootprog_maker[];
-u_int32_t acells;
+u_int32_t acells, scells;
static char bootargs[128];
@@ -64,25 +64,20 @@ uint64_t
memsize(void)
{
phandle_t memoryp;
- struct ofw_reg reg[4];
- struct ofw_reg2 reg2[8];
- int i;
- u_int64_t sz, memsz;
+ cell_t reg[24];
+ int i, sz;
+ u_int64_t memsz;
+ memsz = 0;
memoryp = OF_instance_to_package(memory);
- if (acells == 1) {
- sz = OF_getprop(memoryp, "reg", &reg, sizeof(reg));
- sz /= sizeof(struct ofw_reg);
-
- for (i = 0, memsz = 0; i < sz; i++)
- memsz += reg[i].size;
- } else if (acells == 2) {
- sz = OF_getprop(memoryp, "reg", &reg2, sizeof(reg2));
- sz /= sizeof(struct ofw_reg2);
+ sz = OF_getprop(memoryp, "reg", &reg, sizeof(reg));
+ sz /= sizeof(reg[0]);
- for (i = 0, memsz = 0; i < sz; i++)
- memsz += reg2[i].size;
+ for (i = 0; i < sz; i += (acells + scells)) {
+ if (scells > 1)
+ memsz += (uint64_t)reg[i + acells] << 32;
+ memsz += reg[i + acells + scells - 1];
}
return (memsz);
@@ -105,13 +100,9 @@ main(int (*openfirm)(void *))
root = OF_finddevice("/");
- acells = 1;
+ scells = acells = 1;
OF_getprop(root, "#address-cells", &acells, sizeof(acells));
-
- /*
- * Set up console.
- */
- cons_probe();
+ OF_getprop(root, "#size-cells", &scells, sizeof(scells));
/*
* Initialise the heap as early as possible. Once this is done,
@@ -121,6 +112,11 @@ main(int (*openfirm)(void *))
init_heap();
/*
+ * Set up console.
+ */
+ cons_probe();
+
+ /*
* March through the device switch probing for things.
*/
for (i = 0; devsw[i] != NULL; i++)
diff --git a/sys/boot/ofw/libofw/ofw_memory.c b/sys/boot/ofw/libofw/ofw_memory.c
index ebf01af..60cc904 100644
--- a/sys/boot/ofw/libofw/ofw_memory.c
+++ b/sys/boot/ofw/libofw/ofw_memory.c
@@ -118,13 +118,19 @@ ofw_memmap(int acells)
void *
ofw_alloc_heap(unsigned int size)
{
- phandle_t memoryp;
- struct ofw_reg available;
+ phandle_t memoryp, root;
+ cell_t available[4];
+ cell_t acells;
+
+ root = OF_finddevice("/");
+ acells = 1;
+ OF_getprop(root, "#address-cells", &acells, sizeof(acells));
memoryp = OF_instance_to_package(memory);
- OF_getprop(memoryp, "available", &available, sizeof(available));
+ OF_getprop(memoryp, "available", available, sizeof(available));
- heap_base = OF_claim((void *)available.base, size, sizeof(register_t));
+ heap_base = OF_claim((void *)available[acells-1], size,
+ sizeof(register_t));
if (heap_base != (void *)-1) {
heap_size = size;
diff --git a/sys/boot/ofw/libofw/openfirm.c b/sys/boot/ofw/libofw/openfirm.c
index 8786d5d..4b84fa1 100644
--- a/sys/boot/ofw/libofw/openfirm.c
+++ b/sys/boot/ofw/libofw/openfirm.c
@@ -80,8 +80,13 @@ OF_init(int (*openfirm)(void *))
if ((chosen = OF_finddevice("/chosen")) == -1)
OF_exit();
- if (OF_getprop(chosen, "memory", &memory, sizeof(memory)) == -1)
- OF_exit();
+ if (OF_getprop(chosen, "memory", &memory, sizeof(memory)) == -1) {
+ memory = OF_open("/memory");
+ if (memory == -1)
+ memory = OF_open("/memory@0");
+ if (memory == -1)
+ OF_exit();
+ }
if (OF_getprop(chosen, "mmu", &mmu, sizeof(mmu)) == -1)
OF_exit();
}
OpenPOWER on IntegriCloud