From 57939730b7765dc5df87ff16d27d3c31367b4227 Mon Sep 17 00:00:00 2001 From: Victor Sun Date: Tue, 24 Dec 2019 09:18:08 +0800 Subject: [PATCH] HV: search rsdp from e820 acpi reclaim region Per ACPI 6.2 spec, chapter 5.2.5.2 "Finding the RSDP on UEFI Enabled Systems": In Unified Extensible Firmware Interface (UEFI) enabled systems, a pointer to the RSDP structure exists within the EFI System Table. The OS loader is provided a pointer to the EFI System Table at invocation. The OS loader must retrieve the pointer to the RSDP structure from the EFI System Table and convey the pointer to OSPM, using an OS dependent data structure, as part of the hand off of control from the OS loader to the OS. So when ACRN boot from direct mode on a UEFI enabled system, hypervisor might be failed to get rsdp by seaching rsdp in legacy EBDA or 0xe0000~0xfffff region, but it still have chance to get rsdp by seaching it in e820 ACPI reclaimable region with some edk2 based BIOS. The patch will search rsdp from e820 ACPI reclaim region When failed to get rsdp from legacy region. Tracked-On: #4301 Signed-off-by: Victor Sun Reviewed-by: Fei Li Acked-by: Eddie Dong --- hypervisor/boot/acpi_base.c | 27 ++++++++++++++++++++++----- 1 file changed, 22 insertions(+), 5 deletions(-) diff --git a/hypervisor/boot/acpi_base.c b/hypervisor/boot/acpi_base.c index 7084c7733..e1b8377e9 100644 --- a/hypervisor/boot/acpi_base.c +++ b/hypervisor/boot/acpi_base.c @@ -35,16 +35,17 @@ #include #include #include +#include static struct acpi_table_rsdp *acpi_rsdp; -static struct acpi_table_rsdp *found_rsdp(char *base, int32_t length) +static struct acpi_table_rsdp *found_rsdp(char *base, uint64_t length) { struct acpi_table_rsdp *rsdp, *ret = NULL; - int32_t ofs; + uint64_t ofs; /* search on 16-byte boundaries */ - for (ofs = 0; ofs < length; ofs += 16) { + for (ofs = 0UL; ofs < length; ofs += 16UL) { rsdp = (struct acpi_table_rsdp *)(base + ofs); /* compare signature, validate checksum */ @@ -76,11 +77,27 @@ static struct acpi_table_rsdp *get_rsdp(void) /* EBDA is addressed by the 16 bit pointer at 0x40E */ addr = (uint16_t *)hpa2hva(0x40eUL); - rsdp = found_rsdp((char *)hpa2hva((uint64_t)(*addr) << 4U), 0x400); + rsdp = found_rsdp((char *)hpa2hva((uint64_t)(*addr) << 4U), 0x400UL); } if (rsdp == NULL) { /* Check the upper memory BIOS space, 0xe0000 - 0xfffff. */ - rsdp = found_rsdp((char *)hpa2hva(0xe0000UL), 0x20000); + rsdp = found_rsdp((char *)hpa2hva(0xe0000UL), 0x20000UL); + } + + if (rsdp == NULL) { + /* Check ACPI RECLAIM region, there might be multiple ACPI reclaimable regions. */ + uint32_t i; + const struct e820_entry *entry = get_e820_entry(); + uint32_t entries_count = get_e820_entries_count(); + + for (i = 0U; i < entries_count; i++) { + if (entry[i].type == E820_TYPE_ACPI_RECLAIM) { + rsdp = found_rsdp((char *)hpa2hva(entry[i].baseaddr), entry[i].length); + if (rsdp != NULL) { + break; + } + } + } } if (rsdp == NULL) {