aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/fw/acpi.c129
-rw-r--r--src/fw/biostables.c146
-rw-r--r--src/fw/paravirt.c22
-rw-r--r--src/util.h12
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;