summaryrefslogtreecommitdiff
path: root/hw/i386/acpi-build.c
diff options
context:
space:
mode:
authorPhil Dennis-Jordan <phil@philjordan.eu>2017-03-15 19:20:26 +1300
committerPaolo Bonzini <pbonzini@redhat.com>2017-05-03 12:29:40 +0200
commit77af8a2b95b79699de650965d5228772743efe84 (patch)
tree99f42e47728226f4743aa91b234451343d63cebc /hw/i386/acpi-build.c
parente619b14746e5d8c0e53061661fd0e1da01fd4d60 (diff)
hw/i386: Use Rev3 FADT (ACPI 2.0) instead of Rev1 to improve guest OS support.
This updates the FADT generated for x86/64 machine types from Revision 1 to 3. (Based on ACPI standard 2.0 instead of 1.0) The intention is to expose the reset register information to guest operating systems which require it, specifically OS X/macOS. Revision 1 FADTs do not contain the fields relating to the reset register. The new layout and contents remains backwards-compatible with operating systems which only support ACPI 1.0, as the existing fields are not modified by this change, as the 64-bit and 32-bit variants are allowed to co-exist according to the ACPI 2.0 standard. No regressions became apparent in tests with a range of Windows (XP-10) and Linux versions. The BIOS tables test suite's FADT checksum test has also been updated to reflect the new FADT layout and content. Signed-off-by: Phil Dennis-Jordan <phil@philjordan.eu> Message-Id: <1489558827-28971-2-git-send-email-phil@philjordan.eu> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Diffstat (limited to 'hw/i386/acpi-build.c')
-rw-r--r--hw/i386/acpi-build.c32
1 files changed, 29 insertions, 3 deletions
diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
index 2073108577..7997f06823 100644
--- a/hw/i386/acpi-build.c
+++ b/hw/i386/acpi-build.c
@@ -272,7 +272,7 @@ build_facs(GArray *table_data, BIOSLinker *linker)
}
/* Load chipset information in FADT */
-static void fadt_setup(AcpiFadtDescriptorRev1 *fadt, AcpiPmInfo *pm)
+static void fadt_setup(AcpiFadtDescriptorRev3 *fadt, AcpiPmInfo *pm)
{
fadt->model = 1;
fadt->reserved1 = 0;
@@ -304,6 +304,28 @@ static void fadt_setup(AcpiFadtDescriptorRev1 *fadt, AcpiPmInfo *pm)
fadt->flags |= cpu_to_le32(1 << ACPI_FADT_F_FORCE_APIC_CLUSTER_MODEL);
}
fadt->century = RTC_CENTURY;
+
+ fadt->flags |= cpu_to_le32(1 << ACPI_FADT_F_RESET_REG_SUP);
+ fadt->reset_value = 0xf;
+ fadt->reset_register.space_id = AML_SYSTEM_IO;
+ fadt->reset_register.bit_width = 8;
+ fadt->reset_register.address = cpu_to_le64(ICH9_RST_CNT_IOPORT);
+
+ fadt->xpm1a_event_block.space_id = AML_SYSTEM_IO;
+ fadt->xpm1a_event_block.bit_width = fadt->pm1_evt_len * 8;
+ fadt->xpm1a_event_block.address = cpu_to_le64(pm->io_base);
+
+ fadt->xpm1a_control_block.space_id = AML_SYSTEM_IO;
+ fadt->xpm1a_control_block.bit_width = fadt->pm1_cnt_len * 8;
+ fadt->xpm1a_control_block.address = cpu_to_le64(pm->io_base + 0x4);
+
+ fadt->xpm_timer_block.space_id = AML_SYSTEM_IO;
+ fadt->xpm_timer_block.bit_width = fadt->pm_tmr_len * 8;
+ fadt->xpm_timer_block.address = cpu_to_le64(pm->io_base + 0x8);
+
+ fadt->xgpe0_block.space_id = AML_SYSTEM_IO;
+ fadt->xgpe0_block.bit_width = pm->gpe0_blk_len * 8;
+ fadt->xgpe0_block.address = cpu_to_le64(pm->gpe0_blk);
}
@@ -313,9 +335,10 @@ build_fadt(GArray *table_data, BIOSLinker *linker, AcpiPmInfo *pm,
unsigned facs_tbl_offset, unsigned dsdt_tbl_offset,
const char *oem_id, const char *oem_table_id)
{
- AcpiFadtDescriptorRev1 *fadt = acpi_data_push(table_data, sizeof(*fadt));
+ AcpiFadtDescriptorRev3 *fadt = acpi_data_push(table_data, sizeof(*fadt));
unsigned fw_ctrl_offset = (char *)&fadt->firmware_ctrl - table_data->data;
unsigned dsdt_entry_offset = (char *)&fadt->dsdt - table_data->data;
+ unsigned xdsdt_entry_offset = (char *)&fadt->Xdsdt - table_data->data;
/* FACS address to be filled by Guest linker */
bios_linker_loader_add_pointer(linker,
@@ -327,9 +350,12 @@ build_fadt(GArray *table_data, BIOSLinker *linker, AcpiPmInfo *pm,
bios_linker_loader_add_pointer(linker,
ACPI_BUILD_TABLE_FILE, dsdt_entry_offset, sizeof(fadt->dsdt),
ACPI_BUILD_TABLE_FILE, dsdt_tbl_offset);
+ bios_linker_loader_add_pointer(linker,
+ ACPI_BUILD_TABLE_FILE, xdsdt_entry_offset, sizeof(fadt->Xdsdt),
+ ACPI_BUILD_TABLE_FILE, dsdt_tbl_offset);
build_header(linker, table_data,
- (void *)fadt, "FACP", sizeof(*fadt), 1, oem_id, oem_table_id);
+ (void *)fadt, "FACP", sizeof(*fadt), 3, oem_id, oem_table_id);
}
void pc_madt_cpu_entry(AcpiDeviceIf *adev, int uid,