X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=src%2Fmemmap.c;h=20ccae0d4909fe291e87634b32231d1e1d89d5a6;hb=refs%2Fheads%2Fcoreboot;hp=e02745f91f87c0b7d829aa5cd5c2197c701edc5f;hpb=15b3165711bc3c94b4941e17bc9036cd151f997e;p=seabios.git diff --git a/src/memmap.c b/src/memmap.c index e02745f..20ccae0 100644 --- a/src/memmap.c +++ b/src/memmap.c @@ -1,16 +1,17 @@ // Support for building memory maps suitable for int 15 e820 calls. // -// Copyright (C) 2008 Kevin O'Connor +// Copyright (C) 2008,2009 Kevin O'Connor // -// This file may be distributed under the terms of the GNU GPLv3 license. +// This file may be distributed under the terms of the GNU LGPLv3 license. #include "memmap.h" // struct e820entry #include "util.h" // dprintf.h #include "biosvar.h" // SET_EBDA -// Temporary storage used during map building. -static struct e820entry e820_list[64]; -static int e820_count; + +/**************************************************************** + * e820 memory map + ****************************************************************/ // Remove an entry from the e820_list. static void @@ -25,8 +26,8 @@ remove_e820(int i) static void insert_e820(int i, u64 start, u64 size, u32 type) { - if (e820_count >= ARRAY_SIZE(e820_list)) { - dprintf(1, "Overflowed e820 list!\n"); + if (e820_count >= CONFIG_MAX_E820) { + warn_noalloc(); return; } @@ -39,19 +40,33 @@ insert_e820(int i, u64 start, u64 size, u32 type) e->type = type; } +static const char * +e820_type_name(u32 type) +{ + switch (type) { + case E820_RAM: return "RAM"; + case E820_RESERVED: return "RESERVED"; + case E820_ACPI: return "ACPI"; + case E820_NVS: return "NVS"; + case E820_UNUSABLE: return "UNUSABLE"; + case E820_HOLE: return "HOLE"; + default: return "UNKNOWN"; + } +} + // Show the current e820_list. static void -dump_map() +dump_map(void) { dprintf(1, "e820 map has %d items:\n", e820_count); int i; for (i=0; istart + e->size; - dprintf(1, " %d: %x%x - %x%x = %d\n", i + dprintf(1, " %d: %08x%08x - %08x%08x = %d %s\n", i , (u32)(e->start >> 32), (u32)e->start , (u32)(e_end >> 32), (u32)e_end - , e->type); + , e->type, e820_type_name(e->type)); } } @@ -60,107 +75,67 @@ dump_map() void add_e820(u64 start, u64 size, u32 type) { - dprintf(8, "Add to e820 map: %x %x %d\n", (u32)start, (u32)size, type); + dprintf(8, "Add to e820 map: %08x %08x %d\n", (u32)start, (u32)size, type); if (! size) // Huh? Nothing to do. return; + // Find position of new item (splitting existing item if needed). u64 end = start + size; int i; for (i=0; istart) - // Simple insertion point. - break; u64 e_end = e->start + e->size; if (start > e_end) - // No overlap. continue; - // New item overlaps (or borders) an existing one. + // Found position - check if an existing item needs to be split. if (start > e->start) { - e->size = start - e->start; - i++; - if (end < e_end) - // Need to split existing item - insert_e820(i, end, e_end - end, e->type); if (type == e->type) { // Same type - merge them. size += start - e->start; start = e->start; - i--; - remove_e820(i); + } else { + // Split existing item. + e->size = start - e->start; + i++; + if (e_end > end) + insert_e820(i, end, e_end - end, e->type); } } - if (type != E820_HOLE) { - insert_e820(i, start, size, type); - i++; - } - // Remove all existing items that are completely overlapped. - while (istart) - // No overlap - done. - break; - e_end = e->start + e->size; - if (end >= e_end) { - // Existing item completely overlapped - remove it. - remove_e820(i); - continue; - } - // Not completely overlapped - adjust its start. - e->start = end; - e->size = e_end - e->start; - if (type == e->type) { - // Same type - merge them. - (e-1)->size += e->size; - remove_e820(i); - } + break; + } + // Remove/adjust existing items that are overlapping. + while (istart) + // No overlap - done. break; + u64 e_end = e->start + e->size; + if (end >= e_end) { + // Existing item completely overlapped - remove it. + remove_e820(i); + continue; } - //dump_map(); - return; + // Not completely overlapped - adjust its start. + e->start = end; + e->size = e_end - end; + if (type == e->type) { + // Same type - merge them. + size += e->size; + remove_e820(i); + } + break; } - // Just insert item. - insert_e820(i, start, size, type); + // Insert new item. + if (type != E820_HOLE) + insert_e820(i, start, size, type); //dump_map(); } -// Symbols defined in romlayout.S -extern char freespace2_start, freespace2_end; - -u32 bios_table_cur_addr, bios_table_end_addr; - -// Prep for memmap stuff - init bios table locations. -void -memmap_setup() -{ - bios_table_cur_addr = (u32)&freespace2_start; - bios_table_end_addr = (u32)&freespace2_end; - dprintf(1, "bios_table_addr: 0x%08x end=0x%08x\n", - bios_table_cur_addr, bios_table_end_addr); -} - -// Copy the temporary e820 map info to its permanent location. +// Report on final memory locations. void -memmap_finalize() +memmap_finalize(void) { dump_map(); - - u32 msize = e820_count * sizeof(e820_list[0]); - if (bios_table_cur_addr + msize > bios_table_end_addr) { - dprintf(1, "No room for e820 map!\n"); - return; - } - memcpy((void*)bios_table_cur_addr, e820_list, msize); - SET_EBDA(e820_loc, bios_table_cur_addr); - SET_EBDA(e820_count, e820_count); - bios_table_cur_addr += msize; - - dprintf(1, "final bios_table_addr: 0x%08x (used %d%%)\n" - , bios_table_cur_addr - , (100 * (bios_table_cur_addr - (u32)&freespace2_start) - / ((u32)&freespace2_end - (u32)&freespace2_start))); - if (bios_table_cur_addr > bios_table_end_addr) - BX_PANIC("bios_table_end_addr overflow!\n"); }