This patch series isolates acpi.c to the code that generates acpi tables and isolates smbios.c to the code that generates smbios tables. The code not specific to table generation (eg, parsing logic) is moved to biostables.c. Finally the bios table generation code is marked so that developers are warned against trying to add enhancements.
I've also added a patch here to refactor the way the bios tables are copied to their final locations when seabios does generate them. The code will now use the same mechanism that coreboot/csm would use when copying tables.
-Kevin
Kevin O'Connor (5): acpi: Move acpi parsing logic from acpi.c to biostables.c / paravirt.c. smbios: Move smbios parsing logic from smbios.c to biostables.c. Move PirAddr definition from pirtable.c to biostables.c. Use biostables.c for copying bios tables even when generating them. Document no new changes to pirtable.c, mptable.c, acpi.c, and smbios.c.
src/fw/acpi.c | 149 +++------------------------------- src/fw/biostables.c | 228 ++++++++++++++++++++++++++++++++++++++++++++++++---- src/fw/mptable.c | 34 +++----- src/fw/paravirt.c | 22 +++++ src/fw/pirtable.c | 11 +-- src/fw/smbios.c | 108 ++++--------------------- src/util.h | 21 ++--- 7 files changed, 284 insertions(+), 289 deletions(-)
After this change, src/fw/acpi.c only contains the legacy code for generating ACPI tables. This change only contains code movement - no logic is changed.
Signed-off-by: Kevin O'Connor kevin@koconnor.net --- src/fw/acpi.c | 129 +--------------------------------------------- src/fw/biostables.c | 146 +++++++++++++++++++++++++++++++++++++++++++++++----- src/fw/paravirt.c | 22 ++++++++ src/util.h | 12 ++--- 4 files changed, 160 insertions(+), 149 deletions(-)
diff --git a/src/fw/acpi.c b/src/fw/acpi.c index 042d571..340ea9d 100644 --- a/src/fw/acpi.c +++ b/src/fw/acpi.c @@ -19,12 +19,9 @@ #include "string.h" // memset #include "util.h" // MaxCountCPUs #include "x86.h" // readl -#include "romfile_loader.h" // romfile_loader_execute
#include "src/fw/acpi-dsdt.hex"
-u32 acpi_pm1a_cnt VARFSEG; - static void build_header(struct acpi_table_header *h, u32 sig, int len, u8 rev) { @@ -73,7 +70,7 @@ static void piix4_fadt_setup(struct pci_device *pci, void *arg) }
/* PCI_VENDOR_ID_INTEL && PCI_DEVICE_ID_INTEL_ICH9_LPC */ -void ich9_lpc_fadt_setup(struct pci_device *dev, void *arg) +static void ich9_lpc_fadt_setup(struct pci_device *dev, void *arg) { struct fadt_descriptor_rev1 *fadt = arg;
@@ -592,32 +589,10 @@ static const struct pci_device_id acpi_find_tbl[] = { PCI_DEVICE_END, };
-struct rsdp_descriptor *RsdpAddr; - #define MAX_ACPI_TABLES 20 void acpi_setup(void) { - if (CONFIG_FW_ROMFILE_LOAD) { - int loader_err; - - dprintf(3, "load ACPI tables\n"); - - loader_err = romfile_loader_execute("etc/table-loader"); - - RsdpAddr = find_acpi_rsdp(); - - if (RsdpAddr) - return; - - /* If present, loader should have installed an RSDP. - * Not installed? We might still be able to continue - * using the builtin RSDP. - */ - if (!loader_err) - warn_internalerror(); - } - if (! CONFIG_ACPI) return;
@@ -714,105 +689,3 @@ acpi_setup(void) RsdpAddr = rsdp; dprintf(1, "ACPI tables: RSDP=%p RSDT=%p\n", rsdp, rsdt); } - -static struct fadt_descriptor_rev1 * -find_fadt(void) -{ - dprintf(4, "rsdp=%p\n", RsdpAddr); - if (!RsdpAddr || RsdpAddr->signature != RSDP_SIGNATURE) - return NULL; - struct rsdt_descriptor_rev1 *rsdt = (void*)RsdpAddr->rsdt_physical_address; - dprintf(4, "rsdt=%p\n", rsdt); - if (!rsdt || rsdt->signature != RSDT_SIGNATURE) - return NULL; - void *end = (void*)rsdt + rsdt->length; - int i; - for (i=0; (void*)&rsdt->table_offset_entry[i] < end; i++) { - struct fadt_descriptor_rev1 *fadt = (void*)rsdt->table_offset_entry[i]; - if (!fadt || fadt->signature != FACP_SIGNATURE) - continue; - dprintf(4, "fadt=%p\n", fadt); - return fadt; - } - dprintf(4, "no fadt found\n"); - return NULL; -} - -u32 -find_resume_vector(void) -{ - struct fadt_descriptor_rev1 *fadt = find_fadt(); - if (!fadt) - return 0; - struct facs_descriptor_rev1 *facs = (void*)fadt->firmware_ctrl; - dprintf(4, "facs=%p\n", facs); - if (! facs || facs->signature != FACS_SIGNATURE) - return 0; - // Found it. - dprintf(4, "resume addr=%d\n", facs->firmware_waking_vector); - return facs->firmware_waking_vector; -} - -void -find_acpi_features(void) -{ - struct fadt_descriptor_rev1 *fadt = find_fadt(); - if (!fadt) - return; - u32 pm_tmr = le32_to_cpu(fadt->pm_tmr_blk); - u32 pm1a_cnt = le32_to_cpu(fadt->pm1a_cnt_blk); - dprintf(4, "pm_tmr_blk=%x\n", pm_tmr); - if (pm_tmr) - pmtimer_setup(pm_tmr); - if (pm1a_cnt) - acpi_pm1a_cnt = pm1a_cnt; - - // Theoretically we should check the 'reset_reg_sup' flag, but Windows - // doesn't and thus nobody seems to *set* it. If the table is large enough - // to include it, let the sanity checks in acpi_set_reset_reg() suffice. - if (fadt->length >= 129) { - void *p = fadt; - acpi_set_reset_reg(p + 116, *(u8 *)(p + 128)); - } -} - -static struct acpi_20_generic_address acpi_reset_reg; -static u8 acpi_reset_val; - -#define acpi_ga_to_bdf(addr) pci_to_bdf(0, (addr >> 32) & 0xffff, (addr >> 16) & 0xffff) - -void -acpi_reboot(void) -{ - // Check it passed the sanity checks in acpi_set_reset_reg() and was set - if (acpi_reset_reg.register_bit_width != 8) - return; - - u64 addr = le64_to_cpu(acpi_reset_reg.address); - - dprintf(1, "ACPI hard reset %d:%llx (%x)\n", - acpi_reset_reg.address_space_id, addr, acpi_reset_val); - - switch (acpi_reset_reg.address_space_id) { - case 0: // System Memory - writeb((void *)(u32)addr, acpi_reset_val); - break; - case 1: // System I/O - outb(acpi_reset_val, addr); - break; - case 2: // PCI config space - pci_config_writeb(acpi_ga_to_bdf(addr), addr & 0xffff, acpi_reset_val); - break; - } -} - -void -acpi_set_reset_reg(struct acpi_20_generic_address *reg, u8 val) -{ - if (!reg || reg->address_space_id > 2 || - reg->register_bit_width != 8 || reg->register_bit_offset) - return; - - acpi_reset_reg = *reg; - acpi_reset_val = val; -} diff --git a/src/fw/biostables.c b/src/fw/biostables.c index 070143d..b2a7231 100644 --- a/src/fw/biostables.c +++ b/src/fw/biostables.c @@ -4,15 +4,18 @@ // // This file may be distributed under the terms of the GNU LGPLv3 license.
+#include "byteorder.h" // le32_to_cpu #include "config.h" // CONFIG_* #include "malloc.h" // malloc_fseg #include "output.h" // dprintf +#include "hw/pci.h" // pci_config_writeb #include "std/acpi.h" // struct rsdp_descriptor #include "std/mptable.h" // MPTABLE_SIGNATURE #include "std/pirtable.h" // struct pir_header #include "std/smbios.h" // struct smbios_entry_point #include "string.h" // memcpy #include "util.h" // copy_table +#include "x86.h" // outb
static void copy_pir(void *pos) @@ -60,6 +63,11 @@ copy_mptable(void *pos) memcpy((void*)newpos + length, (void*)p->physaddr, mpclength); }
+ +/**************************************************************** + * ACPI + ****************************************************************/ + static int get_acpi_rsdp_length(void *pos, unsigned size) { @@ -81,6 +89,8 @@ get_acpi_rsdp_length(void *pos, unsigned size) return length; }
+struct rsdp_descriptor *RsdpAddr; + static void copy_acpi_rsdp(void *pos) { @@ -99,6 +109,128 @@ copy_acpi_rsdp(void *pos) RsdpAddr = newpos; }
+void *find_acpi_rsdp(void) +{ + extern u8 zonefseg_start[], zonefseg_end[]; + unsigned long start = (unsigned long)zonefseg_start; + unsigned long end = (unsigned long)zonefseg_end; + unsigned long pos; + + for (pos = ALIGN(start, 0x10); pos <= ALIGN_DOWN(end, 0x10); pos += 0x10) + if (get_acpi_rsdp_length((void *)pos, end - pos) >= 0) + return (void *)pos; + + return NULL; +} + +static struct fadt_descriptor_rev1 * +find_fadt(void) +{ + dprintf(4, "rsdp=%p\n", RsdpAddr); + if (!RsdpAddr || RsdpAddr->signature != RSDP_SIGNATURE) + return NULL; + struct rsdt_descriptor_rev1 *rsdt = (void*)RsdpAddr->rsdt_physical_address; + dprintf(4, "rsdt=%p\n", rsdt); + if (!rsdt || rsdt->signature != RSDT_SIGNATURE) + return NULL; + void *end = (void*)rsdt + rsdt->length; + int i; + for (i=0; (void*)&rsdt->table_offset_entry[i] < end; i++) { + struct fadt_descriptor_rev1 *fadt = (void*)rsdt->table_offset_entry[i]; + if (!fadt || fadt->signature != FACP_SIGNATURE) + continue; + dprintf(4, "fadt=%p\n", fadt); + return fadt; + } + dprintf(4, "no fadt found\n"); + return NULL; +} + +u32 +find_resume_vector(void) +{ + struct fadt_descriptor_rev1 *fadt = find_fadt(); + if (!fadt) + return 0; + struct facs_descriptor_rev1 *facs = (void*)fadt->firmware_ctrl; + dprintf(4, "facs=%p\n", facs); + if (! facs || facs->signature != FACS_SIGNATURE) + return 0; + // Found it. + dprintf(4, "resume addr=%d\n", facs->firmware_waking_vector); + return facs->firmware_waking_vector; +} + +static struct acpi_20_generic_address acpi_reset_reg; +static u8 acpi_reset_val; +u32 acpi_pm1a_cnt VARFSEG; + +#define acpi_ga_to_bdf(addr) pci_to_bdf(0, (addr >> 32) & 0xffff, (addr >> 16) & 0xffff) + +void +acpi_reboot(void) +{ + // Check it passed the sanity checks in acpi_set_reset_reg() and was set + if (acpi_reset_reg.register_bit_width != 8) + return; + + u64 addr = le64_to_cpu(acpi_reset_reg.address); + + dprintf(1, "ACPI hard reset %d:%llx (%x)\n", + acpi_reset_reg.address_space_id, addr, acpi_reset_val); + + switch (acpi_reset_reg.address_space_id) { + case 0: // System Memory + writeb((void *)(u32)addr, acpi_reset_val); + break; + case 1: // System I/O + outb(acpi_reset_val, addr); + break; + case 2: // PCI config space + pci_config_writeb(acpi_ga_to_bdf(addr), addr & 0xffff, acpi_reset_val); + break; + } +} + +static void +acpi_set_reset_reg(struct acpi_20_generic_address *reg, u8 val) +{ + if (!reg || reg->address_space_id > 2 || + reg->register_bit_width != 8 || reg->register_bit_offset) + return; + + acpi_reset_reg = *reg; + acpi_reset_val = val; +} + +void +find_acpi_features(void) +{ + struct fadt_descriptor_rev1 *fadt = find_fadt(); + if (!fadt) + return; + u32 pm_tmr = le32_to_cpu(fadt->pm_tmr_blk); + u32 pm1a_cnt = le32_to_cpu(fadt->pm1a_cnt_blk); + dprintf(4, "pm_tmr_blk=%x\n", pm_tmr); + if (pm_tmr) + pmtimer_setup(pm_tmr); + if (pm1a_cnt) + acpi_pm1a_cnt = pm1a_cnt; + + // Theoretically we should check the 'reset_reg_sup' flag, but Windows + // doesn't and thus nobody seems to *set* it. If the table is large enough + // to include it, let the sanity checks in acpi_set_reset_reg() suffice. + if (fadt->length >= 129) { + void *p = fadt; + acpi_set_reset_reg(p + 116, *(u8 *)(p + 128)); + } +} + + +/**************************************************************** + * SMBIOS + ****************************************************************/ + void copy_smbios(void *pos) { @@ -131,17 +263,3 @@ copy_table(void *pos) copy_acpi_rsdp(pos); copy_smbios(pos); } - -void *find_acpi_rsdp(void) -{ - extern u8 zonefseg_start[], zonefseg_end[]; - unsigned long start = (unsigned long)zonefseg_start; - unsigned long end = (unsigned long)zonefseg_end; - unsigned long pos; - - for (pos = ALIGN(start, 0x10); pos <= ALIGN_DOWN(end, 0x10); pos += 0x10) - if (get_acpi_rsdp_length((void *)pos, end - pos) >= 0) - return (void *)pos; - - return NULL; -} diff --git a/src/fw/paravirt.c b/src/fw/paravirt.c index 00e327d..569fd25 100644 --- a/src/fw/paravirt.c +++ b/src/fw/paravirt.c @@ -18,6 +18,7 @@ #include "output.h" // dprintf #include "paravirt.h" // qemu_cfg_preinit #include "romfile.h" // romfile_loadint +#include "romfile_loader.h" // romfile_loader_execute #include "string.h" // memset #include "util.h" // pci_setup #include "x86.h" // cpuid @@ -147,6 +148,27 @@ qemu_platform_setup(void) pirtable_setup(); mptable_setup(); smbios_setup(); + + if (CONFIG_FW_ROMFILE_LOAD) { + int loader_err; + + dprintf(3, "load ACPI tables\n"); + + loader_err = romfile_loader_execute("etc/table-loader"); + + RsdpAddr = find_acpi_rsdp(); + + if (RsdpAddr) + return; + + /* If present, loader should have installed an RSDP. + * Not installed? We might still be able to continue + * using the builtin RSDP. + */ + if (!loader_err) + warn_internalerror(); + } + acpi_setup(); }
diff --git a/src/util.h b/src/util.h index b8acbfa..2201da2 100644 --- a/src/util.h +++ b/src/util.h @@ -61,19 +61,17 @@ int irqtimer_check(u32 end); void handle_1586(struct bregs *regs);
// fw/acpi.c +void acpi_setup(void); + +// fw/biostable.c extern struct rsdp_descriptor *RsdpAddr; extern u32 acpi_pm1a_cnt; -void acpi_setup(void); +void *find_acpi_rsdp(void); u32 find_resume_vector(void); -void find_acpi_features(void); -struct acpi_20_generic_address; -void acpi_set_reset_reg(struct acpi_20_generic_address *reg, u8 val); void acpi_reboot(void); - -// fw/biostable.c +void find_acpi_features(void); void copy_smbios(void *pos); void copy_table(void *pos); -void *find_acpi_rsdp(void);
// fw/coreboot.c extern const char *CBvendor, *CBpart;
After this change, src/fw/smbios.c only contains the legacy code for generating SMBIOS tables. This change only contains code movement - no logic is changed.
Signed-off-by: Kevin O'Connor kevin@koconnor.net --- src/fw/biostables.c | 71 +++++++++++++++++++++++++++++++++++++++++++++++++++++ src/fw/smbios.c | 70 ---------------------------------------------------- src/util.h | 4 +-- 3 files changed, 73 insertions(+), 72 deletions(-)
diff --git a/src/fw/biostables.c b/src/fw/biostables.c index b2a7231..48325a4 100644 --- a/src/fw/biostables.c +++ b/src/fw/biostables.c @@ -231,6 +231,8 @@ find_acpi_features(void) * SMBIOS ****************************************************************/
+struct smbios_entry_point *SMBiosAddr; + void copy_smbios(void *pos) { @@ -256,6 +258,75 @@ copy_smbios(void *pos) }
void +display_uuid(void) +{ + u32 addr, end; + u8 *uuid; + u8 empty_uuid[16] = { 0 }; + + if (SMBiosAddr == NULL) + return; + + addr = SMBiosAddr->structure_table_address; + end = addr + SMBiosAddr->structure_table_length; + + /* the following takes care of any initial wraparound too */ + while (addr < end) { + const struct smbios_structure_header *hdr; + + /* partial structure header */ + if (end - addr < sizeof(struct smbios_structure_header)) + return; + + hdr = (struct smbios_structure_header *)addr; + + /* partial structure */ + if (end - addr < hdr->length) + return; + + /* any Type 1 structure version will do that has the UUID */ + if (hdr->type == 1 && + hdr->length >= offsetof(struct smbios_type_1, uuid) + 16) + break; + + /* done with formatted area, skip string-set */ + addr += hdr->length; + + while (end - addr >= 2 && + (*(u8 *)addr != '\0' || + *(u8 *)(addr+1) != '\0')) + ++addr; + + /* structure terminator not found */ + if (end - addr < 2) + return; + + addr += 2; + } + + /* parsing finished or skipped entirely, UUID not found */ + if (addr >= end) + return; + + uuid = (u8 *)(addr + offsetof(struct smbios_type_1, uuid)); + if (memcmp(uuid, empty_uuid, sizeof empty_uuid) == 0) + return; + + printf("Machine UUID" + " %02x%02x%02x%02x" + "-%02x%02x" + "-%02x%02x" + "-%02x%02x" + "-%02x%02x%02x%02x%02x%02x\n" + , uuid[ 0], uuid[ 1], uuid[ 2], uuid[ 3] + , uuid[ 4], uuid[ 5] + , uuid[ 6], uuid[ 7] + , uuid[ 8], uuid[ 9] + , uuid[10], uuid[11], uuid[12], uuid[13], uuid[14], uuid[15]); +} + + +void copy_table(void *pos) { copy_pir(pos); diff --git a/src/fw/smbios.c b/src/fw/smbios.c index 0c6a5b2..902e8ab 100644 --- a/src/fw/smbios.c +++ b/src/fw/smbios.c @@ -15,8 +15,6 @@ #include "util.h" // MaxCountCPUs #include "x86.h" // cpuid
-struct smbios_entry_point *SMBiosAddr; - static void smbios_entry_point_setup(u16 max_structure_size, u16 structure_table_length, @@ -589,71 +587,3 @@ smbios_setup(void) smbios_entry_point_setup(max_struct_size, p - start, start, nr_structs); free(start); } - -void -display_uuid(void) -{ - u32 addr, end; - u8 *uuid; - u8 empty_uuid[16] = { 0 }; - - if (SMBiosAddr == NULL) - return; - - addr = SMBiosAddr->structure_table_address; - end = addr + SMBiosAddr->structure_table_length; - - /* the following takes care of any initial wraparound too */ - while (addr < end) { - const struct smbios_structure_header *hdr; - - /* partial structure header */ - if (end - addr < sizeof(struct smbios_structure_header)) - return; - - hdr = (struct smbios_structure_header *)addr; - - /* partial structure */ - if (end - addr < hdr->length) - return; - - /* any Type 1 structure version will do that has the UUID */ - if (hdr->type == 1 && - hdr->length >= offsetof(struct smbios_type_1, uuid) + 16) - break; - - /* done with formatted area, skip string-set */ - addr += hdr->length; - - while (end - addr >= 2 && - (*(u8 *)addr != '\0' || - *(u8 *)(addr+1) != '\0')) - ++addr; - - /* structure terminator not found */ - if (end - addr < 2) - return; - - addr += 2; - } - - /* parsing finished or skipped entirely, UUID not found */ - if (addr >= end) - return; - - uuid = (u8 *)(addr + offsetof(struct smbios_type_1, uuid)); - if (memcmp(uuid, empty_uuid, sizeof empty_uuid) == 0) - return; - - printf("Machine UUID" - " %02x%02x%02x%02x" - "-%02x%02x" - "-%02x%02x" - "-%02x%02x" - "-%02x%02x%02x%02x%02x%02x\n" - , uuid[ 0], uuid[ 1], uuid[ 2], uuid[ 3] - , uuid[ 4], uuid[ 5] - , uuid[ 6], uuid[ 7] - , uuid[ 8], uuid[ 9] - , uuid[10], uuid[11], uuid[12], uuid[13], uuid[14], uuid[15]); -} diff --git a/src/util.h b/src/util.h index 2201da2..088437b 100644 --- a/src/util.h +++ b/src/util.h @@ -70,7 +70,9 @@ void *find_acpi_rsdp(void); u32 find_resume_vector(void); void acpi_reboot(void); void find_acpi_features(void); +extern struct smbios_entry_point *SMBiosAddr; void copy_smbios(void *pos); +void display_uuid(void); void copy_table(void *pos);
// fw/coreboot.c @@ -109,9 +111,7 @@ void make_bios_readonly(void); void qemu_prep_reset(void);
// fw/smbios.c -extern struct smbios_entry_point *SMBiosAddr; void smbios_setup(void); -void display_uuid(void);
// fw/smm.c void smm_device_setup(void);
Signed-off-by: Kevin O'Connor kevin@koconnor.net --- src/fw/biostables.c | 2 ++ src/fw/pirtable.c | 3 +-- src/util.h | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-)
diff --git a/src/fw/biostables.c b/src/fw/biostables.c index 48325a4..b132734 100644 --- a/src/fw/biostables.c +++ b/src/fw/biostables.c @@ -17,6 +17,8 @@ #include "util.h" // copy_table #include "x86.h" // outb
+struct pir_header *PirAddr VARFSEG; + static void copy_pir(void *pos) { diff --git a/src/fw/pirtable.c b/src/fw/pirtable.c index ee2659d..ded9143 100644 --- a/src/fw/pirtable.c +++ b/src/fw/pirtable.c @@ -9,8 +9,7 @@ #include "output.h" // dprintf #include "std/pirtable.h" // struct pir_header #include "string.h" // checksum - -struct pir_header *PirAddr VARFSEG; +#include "util.h" // PirAddr
struct pir_table { struct pir_header pir; diff --git a/src/util.h b/src/util.h index 088437b..223d5c0 100644 --- a/src/util.h +++ b/src/util.h @@ -64,6 +64,7 @@ void handle_1586(struct bregs *regs); void acpi_setup(void);
// fw/biostable.c +extern struct pir_header *PirAddr; extern struct rsdp_descriptor *RsdpAddr; extern u32 acpi_pm1a_cnt; void *find_acpi_rsdp(void); @@ -102,7 +103,6 @@ void pci_setup(void); void pci_resume(void);
// fw/pirtable.c -extern struct pir_header *PirAddr; void pirtable_setup(void);
// fw/shadow.c
Use the biostables.c copy_pir(), copy_smbios(), copy_acpi_rsdp(), and copy_mptable() code even when using the legacy bios table generation code. This unifies the final bios table deployment code between qemu, coreboot, and csm.
Signed-off-by: Kevin O'Connor kevin@koconnor.net --- src/fw/acpi.c | 19 +++++++------------ src/fw/biostables.c | 9 ++++++--- src/fw/mptable.c | 33 +++++++++------------------------ src/fw/pirtable.c | 7 ++----- src/fw/smbios.c | 37 ++++++++++++++++--------------------- src/util.h | 3 +++ 6 files changed, 43 insertions(+), 65 deletions(-)
diff --git a/src/fw/acpi.c b/src/fw/acpi.c index 340ea9d..70284ab 100644 --- a/src/fw/acpi.c +++ b/src/fw/acpi.c @@ -676,16 +676,11 @@ acpi_setup(void) build_header((void*)rsdt, RSDT_SIGNATURE, rsdt_len, 1);
// Build rsdp pointer table - struct rsdp_descriptor *rsdp = malloc_fseg(sizeof(*rsdp)); - if (!rsdp) { - warn_noalloc(); - return; - } - memset(rsdp, 0, sizeof(*rsdp)); - rsdp->signature = cpu_to_le64(RSDP_SIGNATURE); - memcpy(rsdp->oem_id, BUILD_APPNAME6, 6); - rsdp->rsdt_physical_address = cpu_to_le32((u32)rsdt); - rsdp->checksum -= checksum(rsdp, 20); - RsdpAddr = rsdp; - dprintf(1, "ACPI tables: RSDP=%p RSDT=%p\n", rsdp, rsdt); + struct rsdp_descriptor rsdp; + memset(&rsdp, 0, sizeof(rsdp)); + rsdp.signature = cpu_to_le64(RSDP_SIGNATURE); + memcpy(rsdp.oem_id, BUILD_APPNAME6, 6); + rsdp.rsdt_physical_address = cpu_to_le32((u32)rsdt); + rsdp.checksum -= checksum(&rsdp, 20); + copy_acpi_rsdp(&rsdp); } diff --git a/src/fw/biostables.c b/src/fw/biostables.c index b132734..19fcbf9 100644 --- a/src/fw/biostables.c +++ b/src/fw/biostables.c @@ -19,7 +19,7 @@
struct pir_header *PirAddr VARFSEG;
-static void +void copy_pir(void *pos) { struct pir_header *p = pos; @@ -41,7 +41,7 @@ copy_pir(void *pos) PirAddr = newpos; }
-static void +void copy_mptable(void *pos) { struct mptable_floating_s *p = pos; @@ -53,6 +53,9 @@ copy_mptable(void *pos) return; u32 length = p->length * 16; u16 mpclength = ((struct mptable_config_s *)p->physaddr)->length; + // Allocate final memory location. (In theory the config + // structure can go in high memory, but Linux kernels before + // v2.6.30 crash with that.) struct mptable_floating_s *newpos = malloc_fseg(length + mpclength); if (!newpos) { warn_noalloc(); @@ -93,7 +96,7 @@ get_acpi_rsdp_length(void *pos, unsigned size)
struct rsdp_descriptor *RsdpAddr;
-static void +void copy_acpi_rsdp(void *pos) { if (RsdpAddr) diff --git a/src/fw/mptable.c b/src/fw/mptable.c index b453469..59c2a3e 100644 --- a/src/fw/mptable.c +++ b/src/fw/mptable.c @@ -182,29 +182,14 @@ mptable_setup(void) config->length = length; config->checksum -= checksum(config, length);
- // Allocate final memory locations. (In theory the config - // structure can go in high memory, but Linux kernels before - // v2.6.30 crash with that.) - struct mptable_config_s *finalconfig = malloc_fseg(length); - struct mptable_floating_s *floating = malloc_fseg(sizeof(*floating)); - if (!finalconfig || !floating) { - warn_noalloc(); - free(config); - free(finalconfig); - free(floating); - return; - } - memcpy(finalconfig, config, length); + // floating pointer structure + struct mptable_floating_s floating; + memset(&floating, 0, sizeof(floating)); + floating.signature = MPTABLE_SIGNATURE; + floating.physaddr = (u32)config; + floating.length = 1; + floating.spec_rev = 4; + floating.checksum -= checksum(&floating, sizeof(floating)); + copy_mptable(&floating); free(config); - - /* floating pointer structure */ - memset(floating, 0, sizeof(*floating)); - floating->signature = MPTABLE_SIGNATURE; - floating->physaddr = (u32)finalconfig; - floating->length = 1; - floating->spec_rev = 4; - floating->checksum -= checksum(floating, sizeof(*floating)); - - dprintf(1, "MP table addr=%p MPC table addr=%p size=%d\n", - floating, finalconfig, length); } diff --git a/src/fw/pirtable.c b/src/fw/pirtable.c index ded9143..44fc71b 100644 --- a/src/fw/pirtable.c +++ b/src/fw/pirtable.c @@ -16,9 +16,7 @@ struct pir_table { struct pir_slot slots[6]; } PACKED;
-extern struct pir_table PIR_TABLE; -#if CONFIG_PIRTABLE -struct pir_table PIR_TABLE __aligned(16) VARFSEG = { +static struct pir_table PIR_TABLE = { .pir = { .version = 0x0100, .size = sizeof(struct pir_table), @@ -89,7 +87,6 @@ struct pir_table PIR_TABLE __aligned(16) VARFSEG = { }, } }; -#endif // CONFIG_PIRTABLE
void pirtable_setup(void) @@ -101,5 +98,5 @@ pirtable_setup(void)
PIR_TABLE.pir.signature = PIR_SIGNATURE; PIR_TABLE.pir.checksum -= checksum(&PIR_TABLE, sizeof(PIR_TABLE)); - PirAddr = &PIR_TABLE.pir; + copy_pir(&PIR_TABLE); } diff --git a/src/fw/smbios.c b/src/fw/smbios.c index 902e8ab..6d580c2 100644 --- a/src/fw/smbios.c +++ b/src/fw/smbios.c @@ -21,7 +21,6 @@ smbios_entry_point_setup(u16 max_structure_size, void *structure_table_address, u16 number_of_structures) { - struct smbios_entry_point *ep = malloc_fseg(sizeof(*ep)); void *finaltable; if (structure_table_length <= BUILD_MAX_SMBIOS_FSEG) // Table is small enough for f-seg - allocate there. This @@ -29,35 +28,31 @@ smbios_entry_point_setup(u16 max_structure_size, finaltable = malloc_fseg(structure_table_length); else finaltable = malloc_high(structure_table_length); - if (!ep || !finaltable) { + if (!finaltable) { warn_noalloc(); - free(ep); - free(finaltable); return; } memcpy(finaltable, structure_table_address, structure_table_length);
- memcpy(ep->anchor_string, "_SM_", 4); - ep->length = 0x1f; - ep->smbios_major_version = 2; - ep->smbios_minor_version = 4; - ep->max_structure_size = max_structure_size; - ep->entry_point_revision = 0; - memset(ep->formatted_area, 0, 5); - memcpy(ep->intermediate_anchor_string, "_DMI_", 5); + struct smbios_entry_point ep; + memset(&ep, 0, sizeof(ep)); + memcpy(ep.anchor_string, "_SM_", 4); + ep.length = 0x1f; + ep.smbios_major_version = 2; + ep.smbios_minor_version = 4; + ep.max_structure_size = max_structure_size; + memcpy(ep.intermediate_anchor_string, "_DMI_", 5);
- ep->structure_table_length = structure_table_length; - ep->structure_table_address = (u32)finaltable; - ep->number_of_structures = number_of_structures; - ep->smbios_bcd_revision = 0x24; + ep.structure_table_length = structure_table_length; + ep.structure_table_address = (u32)finaltable; + ep.number_of_structures = number_of_structures; + ep.smbios_bcd_revision = 0x24;
- ep->checksum -= checksum(ep, 0x10); + ep.checksum -= checksum(&ep, 0x10);
- ep->intermediate_checksum -= checksum((void*)ep + 0x10, ep->length - 0x10); + ep.intermediate_checksum -= checksum((void*)&ep + 0x10, ep.length - 0x10);
- SMBiosAddr = ep; - dprintf(1, "SMBIOS ptr=%p table=%p size=%d\n" - , ep, finaltable, structure_table_length); + copy_smbios(&ep); }
static int diff --git a/src/util.h b/src/util.h index 223d5c0..dd0ec6a 100644 --- a/src/util.h +++ b/src/util.h @@ -64,7 +64,10 @@ void handle_1586(struct bregs *regs); void acpi_setup(void);
// fw/biostable.c +void copy_pir(void *pos); +void copy_mptable(void *pos); extern struct pir_header *PirAddr; +void copy_acpi_rsdp(void *pos); extern struct rsdp_descriptor *RsdpAddr; extern u32 acpi_pm1a_cnt; void *find_acpi_rsdp(void);
Add a note to the code that generates the pir, mptable, smbios, and smbios tables that no new changes are expected. Going forward, it is expected that if any changes are needed to these bios tables that SeaBIOS will get the tables passed in from upstream.
Signed-off-by: Kevin O'Connor kevin@koconnor.net --- src/fw/acpi.c | 1 + src/fw/mptable.c | 1 + src/fw/pirtable.c | 1 + src/fw/smbios.c | 1 + 4 files changed, 4 insertions(+)
diff --git a/src/fw/acpi.c b/src/fw/acpi.c index 70284ab..5ad2eec 100644 --- a/src/fw/acpi.c +++ b/src/fw/acpi.c @@ -1,4 +1,5 @@ // Support for generating ACPI tables (on emulators) +// DO NOT ADD NEW FEATURES HERE. (See paravirt.c / biostables.c instead.) // // Copyright (C) 2008-2010 Kevin O'Connor kevin@koconnor.net // Copyright (C) 2006 Fabrice Bellard diff --git a/src/fw/mptable.c b/src/fw/mptable.c index 59c2a3e..8e01e00 100644 --- a/src/fw/mptable.c +++ b/src/fw/mptable.c @@ -1,4 +1,5 @@ // MPTable generation (on emulators) +// DO NOT ADD NEW FEATURES HERE. (See paravirt.c / biostables.c instead.) // // Copyright (C) 2008-2010 Kevin O'Connor kevin@koconnor.net // Copyright (C) 2006 Fabrice Bellard diff --git a/src/fw/pirtable.c b/src/fw/pirtable.c index 44fc71b..a494408 100644 --- a/src/fw/pirtable.c +++ b/src/fw/pirtable.c @@ -1,4 +1,5 @@ // PIR table generation (for emulators) +// DO NOT ADD NEW FEATURES HERE. (See paravirt.c / biostables.c instead.) // // Copyright (C) 2008 Kevin O'Connor kevin@koconnor.net // Copyright (C) 2002 MandrakeSoft S.A. diff --git a/src/fw/smbios.c b/src/fw/smbios.c index 6d580c2..0ac9ff5 100644 --- a/src/fw/smbios.c +++ b/src/fw/smbios.c @@ -1,4 +1,5 @@ // smbios table generation (on emulators) +// DO NOT ADD NEW FEATURES HERE. (See paravirt.c / biostables.c instead.) // // Copyright (C) 2008,2009 Kevin O'Connor kevin@koconnor.net // Copyright (C) 2006 Fabrice Bellard
On Mon, Apr 07, 2014 at 04:48:43PM -0400, Kevin O'Connor wrote:
This patch series isolates acpi.c to the code that generates acpi tables and isolates smbios.c to the code that generates smbios tables. The code not specific to table generation (eg, parsing logic) is moved to biostables.c. Finally the bios table generation code is marked so that developers are warned against trying to add enhancements.
I've also added a patch here to refactor the way the bios tables are copied to their final locations when seabios does generate them. The code will now use the same mechanism that coreboot/csm would use when copying tables.
FYI, I have pushed this patch series to seabios master.
-Kevin