]> xenbits.xensource.com Git - seabios.git/commitdiff
Fix coreboot bios table copying by delaying to after memory scan.
authorKevin O'Connor <kevin@koconnor.net>
Wed, 29 Jul 2009 00:46:03 +0000 (20:46 -0400)
committerKevin O'Connor <kevin@koconnor.net>
Wed, 29 Jul 2009 00:46:03 +0000 (20:46 -0400)
Delay coreboot bios table scan after memory scan and malloc setup is
    complete.
Also, fix sign underflow in malloc memory available check.
Add check to ensure high bios area is big enough for zone.
Add more debug info to malloc setup/finalize.

src/coreboot.c
src/memmap.c
src/post.c
src/util.h

index f99146e4aff31b50f58c786577b44e7798dd4b80..4ab2a7a8f6f331080eb69efcb64415ea4cdb8511 100644 (file)
 #include "memmap.h" // malloc_fseg
 
 
-/****************************************************************
- * BIOS table copying
- ****************************************************************/
-
-static void
-copy_pir(void *pos)
-{
-    struct pir_header *p = pos;
-    if (p->signature != PIR_SIGNATURE)
-        return;
-    if (PirOffset)
-        return;
-    if (p->size < sizeof(*p))
-        return;
-    if (checksum(pos, p->size) != 0)
-        return;
-    void *newpos = malloc_fseg(p->size);
-    if (!newpos) {
-        dprintf(1, "No room to copy PIR table!\n");
-        return;
-    }
-    dprintf(1, "Copying PIR from %p to %p\n", pos, newpos);
-    memcpy(newpos, pos, p->size);
-    PirOffset = (u32)newpos - BUILD_BIOS_ADDR;
-}
-
-static void
-copy_mptable(void *pos)
-{
-    struct mptable_floating_s *p = pos;
-    if (p->signature != MPTABLE_SIGNATURE)
-        return;
-    if (!p->physaddr)
-        return;
-    if (checksum(pos, sizeof(*p)) != 0)
-        return;
-    u32 length = p->length * 16;
-    u16 mpclength = ((struct mptable_config_s *)p->physaddr)->length;
-    struct mptable_floating_s *newpos = malloc_fseg(length + mpclength);
-    if (!newpos) {
-        dprintf(1, "No room to copy MPTABLE!\n");
-        return;
-    }
-    dprintf(1, "Copying MPTABLE from %p/%x to %p\n", pos, p->physaddr, newpos);
-    memcpy(newpos, pos, length);
-    newpos->physaddr = (u32)newpos + length;
-    newpos->checksum -= checksum(newpos, sizeof(*newpos));
-    memcpy((void*)newpos + length, (void*)p->physaddr, mpclength);
-}
-
-static void
-copy_acpi_rsdp(void *pos)
-{
-    if (RsdpAddr)
-        return;
-    struct rsdp_descriptor *p = pos;
-    if (p->signature != RSDP_SIGNATURE)
-        return;
-    u32 length = 20;
-    if (checksum(pos, length) != 0)
-        return;
-    if (p->revision > 1) {
-        length = p->length;
-        if (checksum(pos, length) != 0)
-            return;
-    }
-    void *newpos = malloc_fseg(length);
-    if (!newpos) {
-        dprintf(1, "No room to copy ACPI RSDP table!\n");
-        return;
-    }
-    dprintf(1, "Copying ACPI RSDP from %p to %p\n", pos, newpos);
-    memcpy(newpos, pos, length);
-    RsdpAddr = newpos;
-}
-
-// Attempt to find (and relocate) any standard bios tables found in a
-// given address range.
-static void
-scan_tables(u32 start, u32 size)
-{
-    void *p = (void*)ALIGN(start, 16);
-    void *end = (void*)start + size;
-    for (; p<end; p += 16) {
-        copy_pir(p);
-        copy_mptable(p);
-        copy_acpi_rsdp(p);
-    }
-}
-
-
 /****************************************************************
  * Memory map
  ****************************************************************/
@@ -209,15 +118,15 @@ find_cb_subtable(struct cb_header *cbh, u32 tag)
     return NULL;
 }
 
+static struct cb_memory *CBMemTable;
+
 // Populate max ram and e820 map info by scanning for a coreboot table.
 static void
 coreboot_fill_map()
 {
     dprintf(3, "Attempting to find coreboot table\n");
 
-    // Init variables set in coreboot table memory scan.
-    PirOffset = 0;
-    RsdpAddr = 0;
+    CBMemTable = NULL;
 
     // Find coreboot table.
     struct cb_header *cbh = find_cb_header(0, 0x1000);
@@ -231,7 +140,7 @@ coreboot_fill_map()
             goto fail;
     }
     dprintf(3, "Now attempting to find coreboot memory map\n");
-    struct cb_memory *cbm = find_cb_subtable(cbh, CB_TAG_MEMORY);
+    struct cb_memory *cbm = CBMemTable = find_cb_subtable(cbh, CB_TAG_MEMORY);
     if (!cbm)
         goto fail;
 
@@ -242,7 +151,6 @@ coreboot_fill_map()
         u32 type = m->type;
         if (type == CB_MEM_TABLE) {
             type = E820_RESERVED;
-            scan_tables(m->start, m->size);
         } else if (type == E820_ACPI || type == E820_RAM) {
             u64 end = m->start + m->size;
             if (end > 0x100000000ull) {
@@ -262,10 +170,6 @@ coreboot_fill_map()
     // confuses grub.  So, override it.
     add_e820(0, 16*1024, E820_RAM);
 
-    // XXX - just create dummy smbios table for now - should detect if
-    // smbios/dmi table is found from coreboot and use that instead.
-    smbios_init();
-
     struct cb_mainboard *cbmb = find_cb_subtable(cbh, CB_TAG_MAINBOARD);
     if (cbmb) {
         const char *vendor = &cbmb->strings[cbmb->vendor_idx];
@@ -287,6 +191,123 @@ fail:
 }
 
 
+/****************************************************************
+ * BIOS table copying
+ ****************************************************************/
+
+static void
+copy_pir(void *pos)
+{
+    struct pir_header *p = pos;
+    if (p->signature != PIR_SIGNATURE)
+        return;
+    if (PirOffset)
+        return;
+    if (p->size < sizeof(*p))
+        return;
+    if (checksum(pos, p->size) != 0)
+        return;
+    void *newpos = malloc_fseg(p->size);
+    if (!newpos) {
+        dprintf(1, "No room to copy PIR table!\n");
+        return;
+    }
+    dprintf(1, "Copying PIR from %p to %p\n", pos, newpos);
+    memcpy(newpos, pos, p->size);
+    PirOffset = (u32)newpos - BUILD_BIOS_ADDR;
+}
+
+static void
+copy_mptable(void *pos)
+{
+    struct mptable_floating_s *p = pos;
+    if (p->signature != MPTABLE_SIGNATURE)
+        return;
+    if (!p->physaddr)
+        return;
+    if (checksum(pos, sizeof(*p)) != 0)
+        return;
+    u32 length = p->length * 16;
+    u16 mpclength = ((struct mptable_config_s *)p->physaddr)->length;
+    struct mptable_floating_s *newpos = malloc_fseg(length + mpclength);
+    if (!newpos) {
+        dprintf(1, "No room to copy MPTABLE!\n");
+        return;
+    }
+    dprintf(1, "Copying MPTABLE from %p/%x to %p\n", pos, p->physaddr, newpos);
+    memcpy(newpos, pos, length);
+    newpos->physaddr = (u32)newpos + length;
+    newpos->checksum -= checksum(newpos, sizeof(*newpos));
+    memcpy((void*)newpos + length, (void*)p->physaddr, mpclength);
+}
+
+static void
+copy_acpi_rsdp(void *pos)
+{
+    if (RsdpAddr)
+        return;
+    struct rsdp_descriptor *p = pos;
+    if (p->signature != RSDP_SIGNATURE)
+        return;
+    u32 length = 20;
+    if (checksum(pos, length) != 0)
+        return;
+    if (p->revision > 1) {
+        length = p->length;
+        if (checksum(pos, length) != 0)
+            return;
+    }
+    void *newpos = malloc_fseg(length);
+    if (!newpos) {
+        dprintf(1, "No room to copy ACPI RSDP table!\n");
+        return;
+    }
+    dprintf(1, "Copying ACPI RSDP from %p to %p\n", pos, newpos);
+    memcpy(newpos, pos, length);
+    RsdpAddr = newpos;
+}
+
+// Attempt to find (and relocate) any standard bios tables found in a
+// given address range.
+static void
+scan_tables(u32 start, u32 size)
+{
+    void *p = (void*)ALIGN(start, 16);
+    void *end = (void*)start + size;
+    for (; p<end; p += 16) {
+        copy_pir(p);
+        copy_mptable(p);
+        copy_acpi_rsdp(p);
+    }
+}
+
+void
+coreboot_copy_biostable()
+{
+    struct cb_memory *cbm = CBMemTable;
+    if (! CONFIG_COREBOOT || !cbm)
+        return;
+
+    dprintf(3, "Relocating coreboot bios tables\n");
+
+    // Init variables set in coreboot table memory scan.
+    PirOffset = 0;
+    RsdpAddr = 0;
+
+    // Scan CB_MEM_TABLE areas for bios tables.
+    int i, count = MEM_RANGE_COUNT(cbm);
+    for (i=0; i<count; i++) {
+        struct cb_memory_range *m = &cbm->map[i];
+        if (m->type == CB_MEM_TABLE)
+            scan_tables(m->start, m->size);
+    }
+
+    // XXX - just create dummy smbios table for now - should detect if
+    // smbios/dmi table is found from coreboot and use that instead.
+    smbios_init();
+}
+
+
 /****************************************************************
  * ulzma
  ****************************************************************/
index 2524e8a8b6ebd6a7970020ef34bbc22ef7f04fdf..9fc3626fcdb7108364a10670b753c333b9538b71 100644 (file)
@@ -150,7 +150,7 @@ static void *
 __malloc(struct zone_s *zone, u32 size)
 {
     u32 newpos = (zone->cur - size) / MINALIGN * MINALIGN;
-    if (newpos < zone->bottom)
+    if ((s32)(newpos - zone->bottom) < 0)
         // No space
         return NULL;
     zone->cur = newpos;
@@ -174,6 +174,8 @@ malloc_fseg(u32 size)
 void
 malloc_setup()
 {
+    dprintf(3, "malloc setup\n");
+
     // Memory in 0xf0000 area.
     memset(BiosTableSpace, 0, CONFIG_MAX_BIOSTABLE);
     ZoneFSeg.bottom = (u32)BiosTableSpace;
@@ -185,7 +187,8 @@ malloc_setup()
     for (i=e820_count-1; i>=0; i--) {
         struct e820entry *e = &e820_list[i];
         u64 end = e->start + e->size;
-        if (e->type != E820_RAM || end > 0xffffffff)
+        if (e->type != E820_RAM || end > 0xffffffff
+            || e->size < CONFIG_MAX_HIGHTABLE)
             continue;
         top = end;
         break;
@@ -203,6 +206,8 @@ malloc_setup()
 void
 malloc_finalize()
 {
+    dprintf(3, "malloc finalize\n");
+
     // Give back unused high ram.
     u32 giveback = (ZoneHigh.cur - ZoneHigh.bottom) / 4096 * 4096;
     add_e820(ZoneHigh.bottom, giveback, E820_RAM);
index 9568ca488680cb83e4989ed7cd9c862086822f48..abbd2dd614864590b6b5dd04297eaeb31bf44a0d 100644 (file)
@@ -137,9 +137,10 @@ ram_probe(void)
 static void
 init_bios_tables(void)
 {
-    if (CONFIG_COREBOOT)
-        // XXX - not supported on coreboot yet.
+    if (CONFIG_COREBOOT) {
+        coreboot_copy_biostable();
         return;
+    }
 
     create_pirtable();
 
index 8a43914c88304f0ab2f6d8132b7bb44e6ded2759..22b58bcc9dcdfefcce6726c66ffcf33a746f07e4 100644 (file)
@@ -208,6 +208,7 @@ void cbfs_run_payload(const char *filename);
 struct cbfs_file;
 struct cbfs_file *cbfs_copyfile_prefix(void *dst, u32 maxlen, const char *prefix
                                        , struct cbfs_file *last);
+void coreboot_copy_biostable();
 void coreboot_setup();
 
 // vgahooks.c