From df5a5fddf694a2fce40d57427c3c105b307622f7 Mon Sep 17 00:00:00 2001 From: Kevin O'Connor Date: Tue, 28 Jul 2009 20:46:03 -0400 Subject: [PATCH] Fix coreboot bios table copying by delaying to after memory scan. 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 | 221 +++++++++++++++++++++++++++---------------------- src/memmap.c | 9 +- src/post.c | 5 +- src/util.h | 1 + 4 files changed, 132 insertions(+), 104 deletions(-) diff --git a/src/coreboot.c b/src/coreboot.c index f99146e..4ab2a7a 100644 --- a/src/coreboot.c +++ b/src/coreboot.c @@ -14,97 +14,6 @@ #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 (; ptype; 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 (; pmap[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 ****************************************************************/ diff --git a/src/memmap.c b/src/memmap.c index 2524e8a..9fc3626 100644 --- a/src/memmap.c +++ b/src/memmap.c @@ -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); diff --git a/src/post.c b/src/post.c index 9568ca4..abbd2dd 100644 --- a/src/post.c +++ b/src/post.c @@ -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(); diff --git a/src/util.h b/src/util.h index 8a43914..22b58bc 100644 --- a/src/util.h +++ b/src/util.h @@ -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 -- 2.39.5