|
|
1.1 ! root 1: // Support for building memory maps suitable for int 15 e820 calls. ! 2: // ! 3: // Copyright (C) 2008,2009 Kevin O'Connor <[email protected]> ! 4: // ! 5: // This file may be distributed under the terms of the GNU LGPLv3 license. ! 6: ! 7: #include "memmap.h" // struct e820entry ! 8: #include "util.h" // dprintf.h ! 9: #include "biosvar.h" // SET_EBDA ! 10: ! 11: ! 12: /**************************************************************** ! 13: * e820 memory map ! 14: ****************************************************************/ ! 15: ! 16: // Remove an entry from the e820_list. ! 17: static void ! 18: remove_e820(int i) ! 19: { ! 20: e820_count--; ! 21: memmove(&e820_list[i], &e820_list[i+1] ! 22: , sizeof(e820_list[0]) * (e820_count - i)); ! 23: } ! 24: ! 25: // Insert an entry in the e820_list at the given position. ! 26: static void ! 27: insert_e820(int i, u64 start, u64 size, u32 type) ! 28: { ! 29: if (e820_count >= CONFIG_MAX_E820) { ! 30: dprintf(1, "Overflowed e820 list!\n"); ! 31: return; ! 32: } ! 33: ! 34: memmove(&e820_list[i+1], &e820_list[i] ! 35: , sizeof(e820_list[0]) * (e820_count - i)); ! 36: e820_count++; ! 37: struct e820entry *e = &e820_list[i]; ! 38: e->start = start; ! 39: e->size = size; ! 40: e->type = type; ! 41: } ! 42: ! 43: // Show the current e820_list. ! 44: static void ! 45: dump_map() ! 46: { ! 47: dprintf(1, "e820 map has %d items:\n", e820_count); ! 48: int i; ! 49: for (i=0; i<e820_count; i++) { ! 50: struct e820entry *e = &e820_list[i]; ! 51: u64 e_end = e->start + e->size; ! 52: dprintf(1, " %d: %08x%08x - %08x%08x = %d\n", i ! 53: , (u32)(e->start >> 32), (u32)e->start ! 54: , (u32)(e_end >> 32), (u32)e_end ! 55: , e->type); ! 56: } ! 57: } ! 58: ! 59: // Add a new entry to the list. This scans for overlaps and keeps the ! 60: // list sorted. ! 61: void ! 62: add_e820(u64 start, u64 size, u32 type) ! 63: { ! 64: dprintf(8, "Add to e820 map: %08x %08x %d\n", (u32)start, (u32)size, type); ! 65: ! 66: if (! size) ! 67: // Huh? Nothing to do. ! 68: return; ! 69: ! 70: // Find position of new item (splitting existing item if needed). ! 71: u64 end = start + size; ! 72: int i; ! 73: for (i=0; i<e820_count; i++) { ! 74: struct e820entry *e = &e820_list[i]; ! 75: u64 e_end = e->start + e->size; ! 76: if (start > e_end) ! 77: continue; ! 78: // Found position - check if an existing item needs to be split. ! 79: if (start > e->start) { ! 80: if (type == e->type) { ! 81: // Same type - merge them. ! 82: size += start - e->start; ! 83: start = e->start; ! 84: } else { ! 85: // Split existing item. ! 86: e->size = start - e->start; ! 87: i++; ! 88: if (e_end > end) ! 89: insert_e820(i, end, e_end - end, e->type); ! 90: } ! 91: } ! 92: break; ! 93: } ! 94: // Remove/adjust existing items that are overlapping. ! 95: while (i<e820_count) { ! 96: struct e820entry *e = &e820_list[i]; ! 97: if (end < e->start) ! 98: // No overlap - done. ! 99: break; ! 100: u64 e_end = e->start + e->size; ! 101: if (end >= e_end) { ! 102: // Existing item completely overlapped - remove it. ! 103: remove_e820(i); ! 104: continue; ! 105: } ! 106: // Not completely overlapped - adjust its start. ! 107: e->start = end; ! 108: e->size = e_end - end; ! 109: if (type == e->type) { ! 110: // Same type - merge them. ! 111: size += e->size; ! 112: remove_e820(i); ! 113: } ! 114: break; ! 115: } ! 116: // Insert new item. ! 117: if (type != E820_HOLE) ! 118: insert_e820(i, start, size, type); ! 119: //dump_map(); ! 120: } ! 121: ! 122: // Find highest area of 32bit memory that can hold the given size. ! 123: struct e820entry * ! 124: find_high_area(u32 size) ! 125: { ! 126: int i; ! 127: for (i=e820_count-1; i>=0; i--) { ! 128: struct e820entry *e = &e820_list[i]; ! 129: u64 end = e->start + e->size; ! 130: if (e->type != E820_RAM || end > 0xffffffff || e->size < size) ! 131: continue; ! 132: if (end < 1024*1024 + size) ! 133: break; ! 134: return e; ! 135: } ! 136: return NULL; ! 137: } ! 138: ! 139: // Prep for memmap stuff - init bios table locations. ! 140: void ! 141: memmap_setup() ! 142: { ! 143: e820_count = 0; ! 144: } ! 145: ! 146: // Report on final memory locations. ! 147: void ! 148: memmap_finalize() ! 149: { ! 150: dump_map(); ! 151: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.