[coreboot] r937 - coreboot-v3/arch/x86
svn at coreboot.org
svn at coreboot.org
Sat Oct 18 00:49:50 CEST 2008
Author: jcrouse
Date: 2008-10-18 00:49:50 +0200 (Sat, 18 Oct 2008)
New Revision: 937
Modified:
coreboot-v3/arch/x86/multiboot.c
Log:
I noticed that free regions provided by search_global_resources() don't have
the reserved regions substracted from them. This patch introduces a check
to weed them out, splitting when necessary
Signed-off-by: Robert Millan <rmh at aybabtu.com>
Acked-by: Jordan Crouse <jordan.crouse at amd.com>
Modified: coreboot-v3/arch/x86/multiboot.c
===================================================================
--- coreboot-v3/arch/x86/multiboot.c 2008-10-17 22:49:43 UTC (rev 936)
+++ coreboot-v3/arch/x86/multiboot.c 2008-10-17 22:49:50 UTC (rev 937)
@@ -25,42 +25,83 @@
static struct multiboot_mmap_entry *mb_mem;
-static void build_mb_mem_range(void *gp, struct device *dev, struct resource *res)
+static struct {
+ u64 addr;
+ u64 len;
+} reserved_mem[2];
+
+static void build_mb_mem_range_nooverlap(u64 addr, u64 len)
{
- mb_mem->addr = res->base;
- mb_mem->len = res->size;
+ int i;
+ for (i = 0; i < sizeof(reserved_mem) / sizeof(reserved_mem[0]); i++) {
+ /* free region fully contained in reserved region, abort */
+ if (addr >= reserved_mem[i].addr && addr + len <= reserved_mem[i].addr + reserved_mem[i].len)
+ return;
+ /* reserved region splits free region */
+ if (addr < reserved_mem[i].addr && addr + len > reserved_mem[i].addr + reserved_mem[i].len) {
+ build_mb_mem_range_nooverlap(addr, reserved_mem[i].addr - addr);
+ build_mb_mem_range_nooverlap(reserved_mem[i].addr + reserved_mem[i].len, (addr + len) - (reserved_mem[i].addr + reserved_mem[i].len));
+ return;
+ }
+ /* left overlap */
+ if (addr < reserved_mem[i].addr + reserved_mem[i].len && addr + len > reserved_mem[i].addr + reserved_mem[i].len) {
+ len += addr;
+ addr = reserved_mem[i].addr + reserved_mem[i].len;
+ len -= addr;
+ /* len += addr - old_addr */
+ continue;
+ }
+ /* right overlap */
+ if (addr < reserved_mem[i].addr && addr + len > reserved_mem[i].addr) {
+ len = reserved_mem[i].addr - addr;
+ continue;
+ }
+ /* none of the above, just add it */
+ }
+
+ mb_mem->addr = addr;
+ mb_mem->len = len;
mb_mem->type = 1;
mb_mem->size = sizeof(*mb_mem) - sizeof(mb_mem->size);
mb_mem++;
}
+static void build_mb_mem_range(void *gp, struct device *dev, struct resource *res)
+{
+ build_mb_mem_range_nooverlap(res->base, res->size);
+}
+
unsigned long write_multiboot_info(
unsigned long low_table_start, unsigned long low_table_end,
unsigned long rom_table_start, unsigned long rom_table_end)
{
- struct multiboot_info *mbi = rom_table_end;
+ struct multiboot_info *mbi;
+ int i;
+
+ mbi = rom_table_end;
memset(mbi, 0, sizeof(*mbi));
rom_table_end += sizeof(*mbi);
mbi->mmap_addr = (u32) rom_table_end;
mb_mem = rom_table_end;
+ /* reserved regions */
+ reserved_mem[0].addr = low_table_start;
+ reserved_mem[0].len = low_table_end - low_table_start;
+ reserved_mem[1].addr = rom_table_start;
+ reserved_mem[1].len = rom_table_end - rom_table_start;
+ for (i = 0; i < sizeof(reserved_mem) / sizeof(reserved_mem[0]); i++) {
+ mb_mem->addr = reserved_mem[i].addr;
+ mb_mem->len = reserved_mem[i].len;
+ mb_mem->type = 2;
+ mb_mem->size = sizeof(*mb_mem) - sizeof(mb_mem->size);
+ mb_mem++;
+ }
+
/* free regions */
search_global_resources( IORESOURCE_MEM | IORESOURCE_CACHEABLE,
IORESOURCE_MEM | IORESOURCE_CACHEABLE, build_mb_mem_range, NULL);
- /* reserved regions */
- mb_mem->addr = low_table_start;
- mb_mem->len = low_table_end - low_table_start;
- mb_mem->type = 2;
- mb_mem->size = sizeof(*mb_mem) - sizeof(mb_mem->size);
- mb_mem++;
- mb_mem->addr = rom_table_start;
- mb_mem->len = rom_table_end - rom_table_start;
- mb_mem->type = 2;
- mb_mem->size = sizeof(*mb_mem) - sizeof(mb_mem->size);
- mb_mem++;
-
mbi->mmap_length = ((u32) mb_mem) - mbi->mmap_addr;
mbi->flags |= MB_INFO_MEM_MAP;
More information about the coreboot
mailing list