Update e820 map in place instead of copying it.
authorKevin O'Connor <kevin@koconnor.net>
Sat, 8 Nov 2008 18:05:27 +0000 (13:05 -0500)
committerKevin O'Connor <kevin@koconnor.net>
Sat, 8 Nov 2008 18:05:27 +0000 (13:05 -0500)
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
src/config.h
src/memmap.c
src/memmap.h
src/system.c

index 7ea038ff2ce3cedb0ec60723f39f0e6db6508091..6dfcbc71518e51e0a2380cc60964d89aad89b00f 100644 (file)
@@ -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
index fa7ae9ed250804ec6b8f6fb98c2b1cfa40f4c06e..39a796d74bf6bc700a7fd287ea03193225af7cfd 100644 (file)
@@ -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
index e02745f91f87c0b7d829aa5cd5c2197c701edc5f..f74f4f2672480d9b19e6a48202066e953ed4584a 100644 (file)
@@ -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)
index b5e1d0d19e7771a732d9dc07030523f7cfb02036..8a6bd799515dafb09eead220f66fa93845ce5de2 100644 (file)
@@ -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;
 
index 04cd6acb75e624a1e9deedafbe30360c20f17365..f4e42635a89774fc3566a8afce863ecfa5693426 100644 (file)
@@ -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);
 }