+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.
(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);
#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)
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. */
* 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>
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,