Enhance e820 memory map generation.
authorKevin O'Connor <kevin@koconnor.net>
Mon, 9 Jun 2008 03:08:12 +0000 (23:08 -0400)
committerKevin O'Connor <kevin@koconnor.net>
Mon, 9 Jun 2008 03:08:12 +0000 (23:08 -0400)
Build e820 maps at post time; just copy the pre-built ones at runtime.
Add support for populating memory and map info from coreboot.

Makefile
TODO
src/biosvar.h
src/post.c
src/rombios32.c
src/system.c
src/util.c
src/util.h

index 7e5fa6b51715b87726532408a05fd214f0f1dcdd..ccf038580e98d80b1620ea501e25506143a00ff1 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -10,7 +10,7 @@ OUT=out/
 # Source files
 SRCBOTH=output.c util.c floppy.c ata.c kbd.c pci.c boot.c serial.c clock.c
 SRC16=$(SRCBOTH) disk.c system.c mouse.c cdrom.c apm.c pcibios.c
-SRC32=$(SRCBOTH) post.c shadow.c rombios32.c post_menu.c
+SRC32=$(SRCBOTH) post.c shadow.c rombios32.c post_menu.c memmap.c coreboot.c
 TABLESRC=font.c cbt.c floppy_dbt.c
 
 cc-option = $(shell if test -z "`$(1) $(2) -S -o /dev/null -xc \
diff --git a/TODO b/TODO
index 05cfa2e22f7658d1ce830ca184173102f3e44e2c..2fd001aaa35983c2b48ce8bde58b5edc6215fac0 100644 (file)
--- a/TODO
+++ b/TODO
@@ -5,12 +5,16 @@ Support parsing of linuxbios/coreboot table.
 Do a pci scan for ide controllers - don't just assume ISA ports are
 available.
 
+The keyboard driver should detect ctrl+alt+del and reboot the
+machine.
+
 Review changes committed to coreboot, virtualbox, qemu, kvm, and bochs
 cvs tip.
   * bochs cvs (1.209)         -- all changes synched
   * coreboot (r3348): 1.163   -- no noteworthy enhancements
   * qemu (r4675): 1.207       -- supports >4Gig memory
-  * kvm (45a442c): 1.182      -- >4gig, e820 vmx pages, enable cache?
+  * kvm (45a442c): 1.182      -- >4gig, e820 vmx pages, enable cache?,
+    wrmsr in smp_start and rombios32, acpi insrcovr table
   * virtualbox (r9404): 1.176 -- f11/f12 kbd, lots of mouse changes,
     logo, set text mode?, int 1589, floppy data rate?,
     dummy_isr_function, int19 calls post
@@ -42,6 +46,3 @@ location.
 Look at integrating the lgpl vgabios into tree.
 
 Try generating bios tables at compile time.
-
-Move e820 map generation to post time (just have e820 code copy pre
-made tables back to user).
index 9668f31617283ac5ae0f8298c10e18492dae8132..177656e666eeb13fcc7a7e61b24db08cad495fed 100644 (file)
@@ -48,11 +48,11 @@ struct bios_data_area_s {
     u8 floppy_motor_counter;
     u8 floppy_last_status;
     u8 floppy_return_status[7];
-    u8 other1[0x7];
+    u8 other_49[0x7];
     // 40:50
-    u8 other2[0x10];
+    u8 other_50[0x10];
     // 40:60
-    u8 other3[0x7];
+    u8 other_60[0x7];
     u32 jump_cs_ip;
     u8 dummy;
     u32 timer_counter;
@@ -69,7 +69,7 @@ struct bios_data_area_s {
     // 40:80
     u16 kbd_buf_start_offset;
     u16 kbd_buf_end_offset;
-    u8 other5[7];
+    u8 other_84[7];
     u8 floppy_last_data_rate;
     u8 disk_status_controller;
     u8 disk_error_controller;
@@ -260,6 +260,8 @@ struct extended_bios_data_area_s {
 
     // Physical memory available.
     u32 ram_size;
+    u16 e820_count;
+    u32 e820_loc;
 
     // ATA Driver data
     struct ata_s   ata;
index 718cc2a22470a78074785ab4d901078891557f0d..4593b69c1e90b58dc08ec6c3c522c026d95666d7 100644 (file)
@@ -14,6 +14,7 @@
 #include "ata.h" // hard_drive_setup
 #include "kbd.h" // kbd_setup
 #include "disk.h" // floppy_drive_setup
+#include "memmap.h" // add_e820
 
 #define bda ((struct bios_data_area_s *)MAKE_FARPTR(SEG_BDA, 0))
 #define ebda ((struct extended_bios_data_area_s *)MAKE_FARPTR(SEG_EBDA, 0))
@@ -82,24 +83,30 @@ static void
 ram_probe(void)
 {
     dprintf(3, "Find memory size\n");
-    u32 rs;
     if (CONFIG_COREBOOT) {
-        // XXX - just hardcode for now.
-        rs = 128*1024*1024;
+        coreboot_fill_map();
     } else {
         // On emulators, get memory size from nvram.
-        rs = (inb_cmos(CMOS_MEM_EXTMEM2_LOW)
-              | (inb_cmos(CMOS_MEM_EXTMEM2_HIGH) << 8)) * 65536;
+        u32 rs = (inb_cmos(CMOS_MEM_EXTMEM2_LOW)
+                  | (inb_cmos(CMOS_MEM_EXTMEM2_HIGH) << 8)) * 65536;
         if (rs)
             rs += 16 * 1024 * 1024;
         else
             rs = ((inb_cmos(CMOS_MEM_EXTMEM_LOW)
                    | (inb_cmos(CMOS_MEM_EXTMEM_HIGH) << 8)) * 1024
                   + 1 * 1024 * 1024);
+        SET_EBDA(ram_size, rs);
+        add_e820(0, rs, E820_RAM);
+
+        /* reserve 256KB BIOS area at the end of 4 GB */
+        add_e820(0xfffc0000, 256*1024, E820_RESERVED);
     }
 
-    SET_EBDA(ram_size, rs);
-    dprintf(1, "ram_size=0x%08x\n", rs);
+    // Mark known areas as reserved.
+    add_e820((u32)MAKE_FARPTR(SEG_EBDA, 0), EBDA_SIZE * 1024, E820_RESERVED);
+    add_e820((u32)MAKE_FARPTR(SEG_BIOS, 0), 0x10000, E820_RESERVED);
+
+    dprintf(1, "ram_size=0x%08x\n", GET_EBDA(ram_size));
 }
 
 static void
@@ -231,6 +238,8 @@ post()
     serial_setup();
     pic_setup();
 
+    memmap_setup();
+
     ram_probe();
 
     dprintf(1, "Scan for VGA option rom\n");
@@ -240,6 +249,8 @@ post()
 
     rombios32_init();
 
+    memmap_finalize();
+
     floppy_drive_setup();
     hard_drive_setup();
 
index 74c456346d61eb60a19ebe242d6e24528034f899..1bf554af79fb5b09a66491f94b854bb3f71da572 100644 (file)
@@ -21,6 +21,7 @@
 #include "pci.h" // PCIDevice
 #include "types.h" // u32
 #include "config.h" // CONFIG_*
+#include "memmap.h" // bios_table_cur_addr
 
 // Memory addresses used by this code.  (Note global variables (bss)
 // are at 0x40000).
@@ -89,8 +90,6 @@ unsigned long ebda_cur_addr;
 int acpi_enabled;
 u32 pm_io_base, smb_io_base;
 int pm_sci_int;
-unsigned long bios_table_cur_addr;
-unsigned long bios_table_end_addr;
 
 void uuid_probe(void)
 {
@@ -986,6 +985,7 @@ void acpi_bios_init(void)
 #endif
 
     addr = base_addr = GET_EBDA(ram_size) - CONFIG_ACPI_DATA_SIZE;
+    add_e820(addr, CONFIG_ACPI_DATA_SIZE, E820_ACPI);
     rsdt_addr = addr;
     rsdt = (void *)(addr);
     addr += sizeof(*rsdt);
@@ -1617,11 +1617,6 @@ void rombios32_init(void)
     dprintf(1, "ebda_cur_addr: 0x%08lx\n", ebda_cur_addr);
 #endif
 
-    bios_table_cur_addr = 0xf0000 | OFFSET_freespace2_start;
-    bios_table_end_addr = 0xf0000 | OFFSET_freespace2_end;
-    dprintf(1, "bios_table_addr: 0x%08lx end=0x%08lx\n",
-            bios_table_cur_addr, bios_table_end_addr);
-
     cpu_probe();
 
     smp_probe();
@@ -1639,7 +1634,7 @@ void rombios32_init(void)
         if (acpi_enabled)
             acpi_bios_init();
 
-        dprintf(1, "bios_table_cur_addr: 0x%08lx\n", bios_table_cur_addr);
+        dprintf(1, "bios_table_cur_addr: 0x%08x\n", bios_table_cur_addr);
         if (bios_table_cur_addr > bios_table_end_addr)
             BX_PANIC("bios_table_end_addr overflow!\n");
     }
index 26da94138da06ef6eb416cc83ce8269c2abd0ab8..f3909c166654f49bad9d6f45925815221335ef9f 100644 (file)
@@ -8,12 +8,7 @@
 #include "util.h" // irq_restore
 #include "biosvar.h" // BIOS_CONFIG_TABLE
 #include "ioport.h" // inb
-
-#define E820_RAM          1
-#define E820_RESERVED     2
-#define E820_ACPI         3
-#define E820_NVS          4
-#define E820_UNUSABLE     5
+#include "memmap.h" // E820_RAM
 
 // Use PS2 System Control port A to set A20 enable
 static inline u8
@@ -270,67 +265,25 @@ handle_15e801(struct bregs *regs)
 }
 
 static void
-set_e820_range(struct bregs *regs, u32 start, u32 end, u16 type, int last)
+handle_15e820(struct bregs *regs)
 {
-    u32 size = end - start;
-    SET_FARVAR(regs->es, *(u64*)(regs->di+0), start);
-    SET_FARVAR(regs->es, *(u64*)(regs->di+8), size);
-    SET_FARVAR(regs->es, *(u16*)(regs->di+16), type);
-    SET_FARVAR(regs->es, *(u16*)(regs->di+18), 0x0);
+    int count = GET_EBDA(e820_count);
+    if (regs->edx != 0x534D4150 || regs->bx >= count) {
+        set_code_fail(regs, RET_EUNSUPPORTED);
+        return;
+    }
 
-    if (last)
+    struct e820entry *e = &((struct e820entry *)GET_EBDA(e820_loc))[regs->bx];
+    memcpy(MAKE_FARPTR(regs->es, regs->di), e, sizeof(*e));
+    if (regs->bx == count-1)
         regs->ebx = 0;
     else
         regs->ebx++;
     regs->eax = 0x534D4150;
-    regs->ecx = 0x14;
+    regs->ecx = sizeof(*e);
     set_success(regs);
 }
 
-// XXX - should create e820 memory map in post and just copy it here.
-static void
-handle_15e820(struct bregs *regs)
-{
-    if (regs->edx != 0x534D4150) {
-        set_code_fail(regs, RET_EUNSUPPORTED);
-        return;
-    }
-
-    u32 extended_memory_size = GET_EBDA(ram_size);
-    // greater than EFF00000???
-    if (extended_memory_size > 0xf0000000)
-        // everything after this is reserved memory until we get to 0x100000000
-        extended_memory_size = 0xf0000000;
-
-    switch (regs->bx) {
-    case 0:
-        set_e820_range(regs, 0x0000000L, 0x0009fc00L, E820_RAM, 0);
-        break;
-    case 1:
-        set_e820_range(regs, 0x0009fc00L, 0x000a0000L, E820_RESERVED, 0);
-        break;
-    case 2:
-        set_e820_range(regs, 0x000e8000L, 0x00100000L, E820_RESERVED, 0);
-        break;
-    case 3:
-        set_e820_range(regs, 0x00100000L
-                       , extended_memory_size - CONFIG_ACPI_DATA_SIZE
-                       , E820_RAM, 0);
-        break;
-    case 4:
-        set_e820_range(regs,
-                       extended_memory_size - CONFIG_ACPI_DATA_SIZE,
-                       extended_memory_size, E820_ACPI, 0);
-        break;
-    case 5:
-        /* 256KB BIOS area at the end of 4 GB */
-        set_e820_range(regs, 0xfffc0000L, 0x00000000L, E820_RESERVED, 1);
-        break;
-    default:  /* AX=E820, DX=534D4150, BX unrecognized */
-        set_code_fail(regs, RET_EUNSUPPORTED);
-    }
-}
-
 static void
 handle_15e8XX(struct bregs *regs)
 {
index 581c7d8c27650f11790b589e0f0f0e6685cfc6fe..6b2d9dba44f536b1dc9f70e13af1938482503af6 100644 (file)
@@ -34,6 +34,23 @@ memcpy(void *far_d1, const void *far_s1, size_t len)
     return far_d1;
 }
 
+void *
+memmove(void *d, const void *s, size_t len)
+{
+    if (s >= d)
+        return memcpy(d, s, len);
+
+    d += len-1;
+    s += len-1;
+    while (len--) {
+        *(char*)d = *(char*)s;
+        d--;
+        s--;
+    }
+
+    return d;
+}
+
 void
 __set_fail(const char *fname, struct bregs *regs)
 {
index 5c3710048f8c25f599b8a95b8b8be479ee48d434..fa30e08e58cb4f1c412f54e97106d8ca04a25ab3 100644 (file)
@@ -54,6 +54,7 @@ static inline void wbinvd(void)
 
 void *memset(void *s, int c, size_t n);
 void *memcpy(void *d1, const void *s1, size_t len);
+void *memmove(void *d, const void *s, size_t len);
 
 static inline void
 eoi_master_pic()
@@ -197,4 +198,7 @@ void printf_bootdev(u16 bootdev);
 // post_menu.c
 void interactive_bootmenu();
 
+// coreboot.c
+void coreboot_fill_map();
+
 #endif // util.h