Signed-off-by: David Woodhouse David.Woodhouse@intel.com ---
Nothing actually sets it yet. We'll do that from the ACPI table parser for CSM and Xen, and we can put it in our own tables for the native case.
diff --git a/src/acpi.c b/src/acpi.c index f7a2e55..97ade3f 100644 --- a/src/acpi.c +++ b/src/acpi.c @@ -150,17 +150,6 @@ struct madt_local_nmi {
/* - * ACPI 2.0 Generic Address Space definition. - */ -struct acpi_20_generic_address { - u8 address_space_id; - u8 register_bit_width; - u8 register_bit_offset; - u8 reserved; - u64 address; -} PACKED; - -/* * HPET Description Table */ struct acpi_20_hpet { @@ -936,3 +925,38 @@ find_pmtimer(void)
pmtimer_setup(pm_tmr, 3579); } + +static struct acpi_20_generic_address acpi_reset_reg; +static u8 acpi_reset_val; + +void +acpi_reboot(void) +{ + // Must be a single byte; + if (acpi_reset_reg.register_bit_width != 8) + return; + + switch (acpi_reset_reg.address_space_id) { + case 0: // System Memory + writeb((void *)(u32)acpi_reset_reg.address, acpi_reset_val); + break; + case 1: // System I/O + outb(acpi_reset_val, acpi_reset_reg.address); + break; + case 2: // PCI config space + pci_config_writeb(acpi_ga_to_bdf(acpi_reset_reg.address), + acpi_reset_reg.address & 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/acpi.h b/src/acpi.h index e52470e..3f85814 100644 --- a/src/acpi.h +++ b/src/acpi.h @@ -3,9 +3,23 @@
#include "types.h" // u32
+/* + * ACPI 2.0 Generic Address Space definition. + */ +struct acpi_20_generic_address { + u8 address_space_id; + u8 register_bit_width; + u8 register_bit_offset; + u8 reserved; + u64 address; +} PACKED; +#define acpi_ga_to_bdf(addr) pci_to_bdf(0, (addr >> 32) & 0xffff, (addr >> 16) & 0xffff) + void acpi_setup(void); u32 find_resume_vector(void); void find_pmtimer(void); +void acpi_set_reset_reg(struct acpi_20_generic_address *reg, u8 val); +void acpi_reboot(void);
#define RSDP_SIGNATURE 0x2052545020445352LL // "RSD PTR "
diff --git a/src/resume.c b/src/resume.c index adc3594..6b9ad9a 100644 --- a/src/resume.c +++ b/src/resume.c @@ -132,6 +132,9 @@ tryReboot(void) // Setup for reset on qemu. qemu_prep_reset();
+ // Reboot using ACPI RESET_REG + acpi_reboot(); + // Try keyboard controller reboot. i8042_reboot();