]> git.ipfire.org Git - thirdparty/grub.git/commitdiff
2007-02-12 Hollis Blanchard <hollis@penguinppc.org>
authorhollisb <hollisb@localhost>
Tue, 13 Feb 2007 03:20:16 +0000 (03:20 +0000)
committerhollisb <hollisb@localhost>
Tue, 13 Feb 2007 03:20:16 +0000 (03:20 +0000)
* include/grub/ieee1275/ieee1275.h (grub_available_iterate): New
prototype.
* kern/powerpc/ieee1275/init.c (grub_heap_start): Removed.
(grub_heap_len): Likewise.
(HEAP_SIZE): New macro.
(grub_claim_heap): New function.
(grub_machine_init): Don't claim heap directly.  Call
`grub_claim_heap'.
* kern/powerpc/ieee1275/openfw.c: Include alloca.h.
(grub_available_iterate): New function.

ChangeLog
include/grub/ieee1275/ieee1275.h
kern/powerpc/ieee1275/init.c
kern/powerpc/ieee1275/openfw.c

index a6dd60a80cc67ebe790c5be281b94b7ebb4c2c34..9c0aeb2f0244d1b5e72f7faa74207e4fd924f2f6 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,16 @@
+2007-02-12  Hollis Blanchard  <hollis@penguinppc.org>
+
+       * include/grub/ieee1275/ieee1275.h (grub_available_iterate): New
+       prototype.
+       * kern/powerpc/ieee1275/init.c (grub_heap_start): Removed.
+       (grub_heap_len): Likewise.
+       (HEAP_SIZE): New macro.
+       (grub_claim_heap): New function.
+       (grub_machine_init): Don't claim heap directly.  Call
+       `grub_claim_heap'.
+       * kern/powerpc/ieee1275/openfw.c: Include alloca.h.
+       (grub_available_iterate): New function.
+
 2007-02-03  Thomas Schwinge  <tschwinge@gnu.org>
 
        * aclocal.m4 (grub_CHECK_STACK_PROTECTOR): New definition.
index 9da492923ecdff4303600dc6de8f5816909d5b53..d6cccf529a10738120c1d0a46b53575c13d36943 100644 (file)
@@ -145,6 +145,8 @@ grub_err_t EXPORT_FUNC(grub_devalias_iterate)
      (int (*hook) (struct grub_ieee1275_devalias *alias));
 grub_err_t EXPORT_FUNC(grub_children_iterate) (char *devpath,
      int (*hook) (struct grub_ieee1275_devalias *alias));
+grub_err_t EXPORT_FUNC(grub_available_iterate)
+     (int (*hook) (grub_uint64_t, grub_uint64_t));
 int EXPORT_FUNC(grub_claimmap) (grub_addr_t addr, grub_size_t size);
 
 char *EXPORT_FUNC(grub_ieee1275_encode_devname) (const char *path);
index 0c9766e0c3e15ec4934b8b92d7dfa1d168121509..f28f5192fc856d0cce9dc8e78d1c2418f87e0c1e 100644 (file)
@@ -34,9 +34,7 @@
 #include <grub/ieee1275/ofdisk.h>
 #include <grub/ieee1275/ieee1275.h>
 
-/* Apple OF 1.0.5 reserves 0x0 to 0x4000 for the exception handlers.  */
-static const grub_addr_t grub_heap_start = 0x4000;
-static grub_addr_t grub_heap_len;
+#define HEAP_SIZE (8<<20) /* 8 MiB */
 
 void
 grub_exit (void)
@@ -112,27 +110,44 @@ grub_machine_set_prefix (void)
   grub_free (prefix);
 }
 
+/* Claim some available memory in the first /memory node. */
+static void grub_claim_heap (unsigned long heapsize)
+{
+  unsigned long total = 0;
+
+  auto int heap_init (grub_uint64_t addr, grub_uint64_t len);
+  int heap_init (grub_uint64_t addr, grub_uint64_t len)
+  {
+    len -= 1; /* Required for some firmware.  */
+
+    /* Limit heap to `heapsize'.  */
+    if (total + len > heapsize)
+      len = heapsize - total;
+
+    /* Claim and use it.  */
+    if (grub_claimmap (addr, len) < 0)
+      return grub_error (GRUB_ERR_OUT_OF_MEMORY,
+                        "Failed to claim heap at 0x%llx, len 0x%llx\n",
+                        addr, len);
+    grub_mm_init_region ((void *) (grub_addr_t) addr, len);
+
+    total += len;
+    if (total >= heapsize)
+      return 1;
+    return 0;
+  }
+
+  grub_available_iterate (heap_init);
+}
+
 void
 grub_machine_init (void)
 {
   char args[256];
   int actual;
-  extern char _start;
 
   grub_console_init ();
-
-  /* Apple OF 3.1.1 reserves an extra 0x1000 bytes below the load address
-     of an ELF file.  */
-  grub_heap_len = (grub_addr_t) &_start - 0x1000 - grub_heap_start;
-
-  if (grub_ieee1275_claim (grub_heap_start, grub_heap_len, 0, 0))
-    {
-      grub_printf ("Failed to claim heap at 0x%x, len 0x%x\n", grub_heap_start,
-                  grub_heap_len);
-      grub_abort ();
-    }
-  grub_mm_init_region ((void *) grub_heap_start, grub_heap_len);
-
+  grub_claim_heap (HEAP_SIZE);
   grub_ofdisk_init ();
 
   /* Process commandline.  */
index 4e4f4248c267227b310fb7c324b9b14b6ddb2fd8..30b4428cb87d8dca06bc5b91002380902433cddd 100644 (file)
@@ -18,6 +18,8 @@
  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
+#include <alloca.h>
+#include <grub/types.h>
 #include <grub/err.h>
 #include <grub/misc.h>
 #include <grub/mm.h>
@@ -135,6 +137,53 @@ nextprop:
   return 0;
 }
 
+grub_err_t grub_available_iterate (int (*hook) (grub_uint64_t, grub_uint64_t))
+{
+  grub_ieee1275_phandle_t root;
+  grub_ieee1275_phandle_t memory;
+  grub_uint32_t available[32];
+  int address_cells = 1;
+  int size_cells = 1;
+  unsigned int i;
+
+  /* Determine the format of each entry in `available'.  */
+  grub_ieee1275_finddevice ("/", &root);
+  grub_ieee1275_get_property (root, "#address-cells", &address_cells,
+       sizeof address_cells, 0);
+  grub_ieee1275_get_property (root, "#size-cells", &size_cells,
+       sizeof size_cells, 0);
+
+  /* Load `/memory/available'.  */
+  if (grub_ieee1275_finddevice ("/memory", &memory))
+    return grub_error (GRUB_ERR_UNKNOWN_DEVICE,
+                      "Couldn't find /memory node");
+  if (grub_ieee1275_get_property (memory, "available", available,
+                                 sizeof available, 0))
+    return grub_error (GRUB_ERR_UNKNOWN_DEVICE,
+                      "Couldn't examine /memory/available propery");
+
+  /* Decode each entry and call `hook'.  */
+  i = 0;
+  while (i < sizeof (*available))
+    {
+      grub_uint64_t address;
+      grub_uint64_t size;
+
+      address = available[i++];
+      if (address_cells == 2)
+       address = (address << 32) | available[i++];
+
+      size = available[i++];
+      if (size_cells == 2)
+       size = (size << 32) | available[i++];
+
+      if (hook (address, size))
+       break;
+    }
+
+  return grub_errno;
+}
+
 /* Call the "map" method of /chosen/mmu.  */
 static int
 grub_map (grub_addr_t phys, grub_addr_t virt, grub_uint32_t size,