Author: nwhitehorn
Date: Thu Oct 28 23:46:05 2010
New Revision: 214493
URL: http://svn.freebsd.org/changeset/base/214493

Log:
  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

Modified:
  head/sys/boot/ofw/common/main.c
  head/sys/boot/ofw/libofw/ofw_memory.c
  head/sys/boot/ofw/libofw/openfirm.c

Modified: head/sys/boot/ofw/common/main.c
==============================================================================
--- head/sys/boot/ofw/common/main.c     Thu Oct 28 22:34:49 2010        
(r214492)
+++ head/sys/boot/ofw/common/main.c     Thu Oct 28 23:46:05 2010        
(r214493)
@@ -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++)

Modified: head/sys/boot/ofw/libofw/ofw_memory.c
==============================================================================
--- head/sys/boot/ofw/libofw/ofw_memory.c       Thu Oct 28 22:34:49 2010        
(r214492)
+++ head/sys/boot/ofw/libofw/ofw_memory.c       Thu Oct 28 23:46:05 2010        
(r214493)
@@ -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;

Modified: head/sys/boot/ofw/libofw/openfirm.c
==============================================================================
--- head/sys/boot/ofw/libofw/openfirm.c Thu Oct 28 22:34:49 2010        
(r214492)
+++ head/sys/boot/ofw/libofw/openfirm.c Thu Oct 28 23:46:05 2010        
(r214493)
@@ -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("/mem...@0");
+               if (memory == -1)
+                       OF_exit();
+       }
        if (OF_getprop(chosen, "mmu", &mmu, sizeof(mmu)) == -1)
                OF_exit();
 }
_______________________________________________
svn-src-head@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to