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;