From d995b3df0189f931325f1630a6e9d17e8e5319db Mon Sep 17 00:00:00 2001 From: Kevin O'Connor Date: Sat, 8 Nov 2008 13:05:27 -0500 Subject: [PATCH] Update e820 map in place instead of copying it. Allocate the e820 map space in the 0xf0000 segment and do all updates in place. This reduces the need to access external memory during post. Also, move e820 pointer and count from ebda to variables in 0xf0000. --- src/biosvar.h | 2 -- src/config.h | 2 ++ src/memmap.c | 25 ++++++++++--------------- src/memmap.h | 4 ++++ src/system.c | 14 ++++++++++---- 5 files changed, 26 insertions(+), 21 deletions(-) diff --git a/src/biosvar.h b/src/biosvar.h index 7ea038f..6dfcbc7 100644 --- a/src/biosvar.h +++ b/src/biosvar.h @@ -275,8 +275,6 @@ struct extended_bios_data_area_s { // Physical memory available. u32 ram_size; // Amount of continuous ram under 4Gig u64 ram_size_over4G; // Amount of continuous ram >4Gig - u16 e820_count; - u32 e820_loc; u32 pir_loc; // ATA Driver data diff --git a/src/config.h b/src/config.h index fa7ae9e..39a796d 100644 --- a/src/config.h +++ b/src/config.h @@ -64,6 +64,8 @@ #define CONFIG_ACPI 1 // Support bios callbacks specific to via vgabios. #define CONFIG_VGAHOOKS 1 +// Maximum number of map entries in the e820 map +#define CONFIG_MAX_E820 32 /* define it if the (emulated) hardware supports SMM mode */ #define CONFIG_USE_SMM 1 diff --git a/src/memmap.c b/src/memmap.c index e02745f..f74f4f2 100644 --- a/src/memmap.c +++ b/src/memmap.c @@ -8,10 +8,6 @@ #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; - // Remove an entry from the e820_list. static void remove_e820(int i) @@ -25,7 +21,7 @@ remove_e820(int i) static void insert_e820(int i, u64 start, u64 size, u32 type) { - if (e820_count >= ARRAY_SIZE(e820_list)) { + if (e820_count >= CONFIG_MAX_E820) { dprintf(1, "Overflowed e820 list!\n"); return; } @@ -139,6 +135,15 @@ memmap_setup() 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); + + bios_table_cur_addr = ALIGN(bios_table_cur_addr, 4); + u32 msize = CONFIG_MAX_E820 * sizeof(e820_list[0]); + if (bios_table_cur_addr + msize > bios_table_end_addr) { + dprintf(1, "No room for e820 map!\n"); + return; + } + e820_list = (void*)bios_table_cur_addr; + bios_table_cur_addr += msize; } // Copy the temporary e820 map info to its permanent location. @@ -147,16 +152,6 @@ memmap_finalize() { 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) diff --git a/src/memmap.h b/src/memmap.h index b5e1d0d..8a6bd79 100644 --- a/src/memmap.h +++ b/src/memmap.h @@ -20,6 +20,10 @@ void add_e820(u64 start, u64 size, u32 type); void memmap_setup(); void memmap_finalize(); +// e820 map storage (defined in system.c) +extern struct e820entry *e820_list; +extern int e820_count; + // Space for exported bios tables. extern u32 bios_table_cur_addr, bios_table_end_addr; diff --git a/src/system.c b/src/system.c index 04cd6ac..f4e4263 100644 --- a/src/system.c +++ b/src/system.c @@ -266,23 +266,29 @@ handle_15e801(struct bregs *regs) set_success(regs); } +#if MODE16 +// Info on e820 map location and size. +struct e820entry *e820_list VISIBLE16; +int e820_count VISIBLE16; +#endif + static void handle_15e820(struct bregs *regs) { - int count = GET_EBDA(e820_count); + int count = GET_VAR(CS, e820_count); if (regs->edx != 0x534D4150 || regs->bx >= count) { set_code_fail(regs, RET_EUNSUPPORTED); return; } - struct e820entry *e = &((struct e820entry *)GET_EBDA(e820_loc))[regs->bx]; - memcpy_far(MAKE_FARPTR(regs->es, regs->di), e, sizeof(*e)); + struct e820entry *l = GET_VAR(CS, e820_list); + memcpy_far(MAKE_FARPTR(regs->es, regs->di), &l[regs->bx], sizeof(l[0])); if (regs->bx == count-1) regs->ebx = 0; else regs->ebx++; regs->eax = 0x534D4150; - regs->ecx = sizeof(*e); + regs->ecx = sizeof(l[0]); set_success(regs); } -- 2.39.5