diff options
-rw-r--r-- | src/acpi.c | 5 | ||||
-rw-r--r-- | src/acpi.h | 1 | ||||
-rw-r--r-- | src/apm.c | 5 | ||||
-rw-r--r-- | src/pciinit.c | 3 |
4 files changed, 14 insertions, 0 deletions
@@ -18,6 +18,8 @@ #include "acpi-dsdt.hex" +u32 acpi_pm1a_cnt VARFSEG; + static void build_header(struct acpi_table_header *h, u32 sig, int len, u8 rev) { @@ -730,9 +732,12 @@ find_acpi_features(void) 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, 3579); + 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 @@ -36,6 +36,7 @@ struct rsdp_descriptor { /* Root System Descriptor Pointer */ }; extern struct rsdp_descriptor *RsdpAddr; +extern u32 acpi_pm1a_cnt; /* Table structure from Linux kernel (the ACPI tables are under the BSD license) */ @@ -12,6 +12,7 @@ #include "config.h" // CONFIG_* #include "biosvar.h" // GET_GLOBAL #include "paravirt.h" // runningOnQEMU +#include "acpi.h" // acpi_pm_ctl static void out_str(const char *str_cs) @@ -108,7 +109,11 @@ handle_155306(struct bregs *regs) void apm_shutdown(void) { + u16 pm1a_cnt = GET_GLOBAL(acpi_pm1a_cnt); + irq_disable(); + if (pm1a_cnt) + outw(0x2000, pm1a_cnt); out_str("Shutdown"); for (;;) hlt(); diff --git a/src/pciinit.c b/src/pciinit.c index 8370b96..0c6b0cb 100644 --- a/src/pciinit.c +++ b/src/pciinit.c @@ -15,6 +15,7 @@ #include "paravirt.h" // RamSize #include "dev-q35.h" // Q35_HOST_BRIDGE_PCIEXBAR_ADDR #include "list.h" // struct hlist_node +#include "acpi.h" // acpi_pm1a_cnt /* PM Timer ticks per second (HZ) */ #define PM_TIMER_FREQUENCY 3579545 @@ -194,6 +195,7 @@ void mch_isa_bridge_setup(struct pci_device *dev, void *arg) /* acpi enable, SCI: IRQ9 000b = irq9*/ pci_config_writeb(bdf, ICH9_LPC_ACPI_CTRL, ICH9_LPC_ACPI_CTRL_ACPI_EN); + acpi_pm1a_cnt = PORT_ACPI_PM_BASE + 0x04; pmtimer_setup(PORT_ACPI_PM_BASE + 0x08, PM_TIMER_FREQUENCY / 1000); } @@ -238,6 +240,7 @@ static void piix4_pm_setup(struct pci_device *pci, void *arg) pci_config_writel(bdf, 0x90, PORT_SMB_BASE | 1); pci_config_writeb(bdf, 0xd2, 0x09); /* enable SMBus io space */ + acpi_pm1a_cnt = PORT_ACPI_PM_BASE + 0x04; pmtimer_setup(PORT_ACPI_PM_BASE + 0x08, PM_TIMER_FREQUENCY / 1000); } |