File grub-efi-large-memory-map.patch of Package grub
From: Mike Travis <travis@sgi.com>
Subject: [PATCH] Convert EFI memory map to E820 map for the operating system
Date: Thu, 19 Aug 2010 14:08:00 -0400
IT#1003573
Convert EFI memory map to E820 map for the operating system
This code is based on a Linux kernel patch submitted by Edgar Hucek
diff --exclude='*.rej' --exclude='*.orig' --exclude='*~' -Naurp grub.a/efi/efimm.c grub.b/efi/efimm.c
--- grub.a/efi/efimm.c 2010-08-17 11:04:54.000000000 -0400
+++ grub.b/efi/efimm.c 2010-08-17 11:09:07.176704838 -0400
@@ -265,6 +265,9 @@ grub_efi_get_memory_map (grub_efi_uintn_
/*
* Add a memory region to the kernel e820 map.
+ *
+ * Convert EFI memory map to E820 map for the operating system
+ * This code is based on a Linux kernel patch submitted by Edgar Hucek
*/
static void
add_memory_region (struct e820_entry *e820_map,
@@ -274,25 +277,49 @@ add_memory_region (struct e820_entry *e8
unsigned int type)
{
int x = *e820_nr_map;
+ static unsigned long long estart = 0ULL;
+ static unsigned long esize = 0L;
+ static unsigned int etype = -1;
+ static int merge = 0;
- if (x == E820_MAX)
- {
- grub_printf ("Too many entries in the memory map!\n");
- return;
- }
-
- if (e820_map[x-1].addr + e820_map[x-1].size == start
+ /* merge adjacent regions of same type */
+ if ((x > 0) && e820_map[x-1].addr + e820_map[x-1].size == start
&& e820_map[x-1].type == type)
{
e820_map[x-1].size += size;
+ estart = e820_map[x-1].addr;
+ esize = e820_map[x-1].size;
+ etype = e820_map[x-1].type;
+ merge++;
+ return;
}
- else
+
+ /* fill up to E820_MAX */
+ if ( x < E820_MAX )
{
e820_map[x].addr = start;
e820_map[x].size = size;
e820_map[x].type = type;
(*e820_nr_map)++;
+ merge=0;
+ return;
+ }
+
+ /* different type means another region didn't fit */
+ /* or same type, but there's a hole */
+ if (etype != type || (estart + esize) != start)
+ {
+ merge = 0;
+ estart = start;
+ esize = size;
+ etype = type;
+ return;
}
+
+ /* same type and no hole, merge it */
+ estart += esize;
+ esize += size;
+ merge++;
}
/*