From 2ff4dca8c4b54d85fa0ea77dbcc264373b79bd4a Mon Sep 17 00:00:00 2001 From: Mark Date: Tue, 1 Sep 2020 23:46:18 +0300 Subject: [PATCH] acpi: add a way to early define RSDP location --- arch/amd64/acpi_osl_table.c | 6 ++-- arch/amd64/hw/acpi.c | 56 +++++++++++++++++++++++++----------- include/arch/amd64/hw/acpi.h | 3 ++ 3 files changed, 44 insertions(+), 21 deletions(-) diff --git a/arch/amd64/acpi_osl_table.c b/arch/amd64/acpi_osl_table.c index d82c60c..9696256 100644 --- a/arch/amd64/acpi_osl_table.c +++ b/arch/amd64/acpi_osl_table.c @@ -1,3 +1,4 @@ +#include "arch/amd64/hw/acpi.h" #include "acpi.h" ACPI_STATUS AcpiOsPredefinedOverride(const ACPI_PREDEFINED_NAMES *InitVal, ACPI_STRING *NewVal) { @@ -16,8 +17,5 @@ ACPI_STATUS AcpiOsPhysicalTableOverride(ACPI_TABLE_HEADER *ExistingTable, ACPI_P } ACPI_PHYSICAL_ADDRESS AcpiOsGetRootPointer(void) { - ACPI_PHYSICAL_ADDRESS Ret; - Ret = 0; - AcpiFindRootPointer(&Ret); - return Ret; + return (ACPI_PHYSICAL_ADDRESS) acpi_rsdp - 0xFFFFFF0000000000; } diff --git a/arch/amd64/hw/acpi.c b/arch/amd64/hw/acpi.c index 25993ed..c57d620 100644 --- a/arch/amd64/hw/acpi.c +++ b/arch/amd64/hw/acpi.c @@ -11,6 +11,9 @@ #include "sys/dev.h" #include "acpi.h" +static uintptr_t early_rsdp, early_rsdp_v2; + +struct acpi_rsdp_ext *acpi_rsdp = NULL; struct acpi_madt *acpi_madt = NULL; struct acpi_fadt *acpi_fadt = NULL; struct acpi_mcfg *acpi_mcfg = NULL; @@ -51,12 +54,12 @@ static ACPI_STATUS acpica_init(void) { args.Pointer = &arg1; if (ACPI_FAILURE(ret = AcpiInitializeSubsystem())) { - kerror("ACPI INIT failure %s\n", AcpiFormatException(ret)); + kerror("AcpiInitializeSubsystem: %s\n", AcpiFormatException(ret)); return ret; } if (ACPI_FAILURE(ret = AcpiInitializeTables(NULL, 0, FALSE))) { - kerror("ACPI INIT failure %s\n", AcpiFormatException(ret)); + kerror("AcpiInitializeTables: %s\n", AcpiFormatException(ret)); return ret; } @@ -93,32 +96,51 @@ static ACPI_STATUS acpica_init(void) { return AE_OK; } -void amd64_acpi_init(void) { - struct acpi_rsdp_ext *rsdp = NULL; - struct acpi_rsdt *rsdt; - acpi_madt = NULL; +void amd64_acpi_set_rsdp(uintptr_t addr) { + early_rsdp = addr; +} - for (size_t i = 0xFFFFFF0000000000 + 0x000E0000; i < 0xFFFFFF0000000000 + 0x000FFFFF - 8; ++i) { - if (!strncmp((const char *) i, "RSD PTR ", 8)) { - rsdp = (struct acpi_rsdp_ext *) i; - break; +void amd64_acpi_set_rsdp2(uintptr_t addr) { + early_rsdp_v2 = addr; +} + +static uintptr_t locate_rsdp(void) { + // TODO: support rsdpv2 + if (early_rsdp) { + if (checksum((void *) early_rsdp, sizeof(struct acpi_rsdp)) != 0) { + kwarn("Provided RSDP has invalid checksum, falling back to scan method\n"); + } else { + return early_rsdp; } } - if (!rsdp) { - kdebug("Failed to find rsdp\n"); - while (1); + for (size_t i = 0xFFFFFF0000000000 + 0x000E0000; i < 0xFFFFFF0000000000 + 0x000FFFFF - 8; ++i) { + if (!strncmp((const char *) i, "RSD PTR ", 8)) { + return i; + } } - kdebug("Found RSDP: %p\n", rsdp); + return 0; +} - if (checksum(rsdp, sizeof(struct acpi_rsdp)) != 0) { +void amd64_acpi_init(void) { + struct acpi_rsdt *rsdt; + acpi_madt = NULL; + + acpi_rsdp = (struct acpi_rsdp_ext *) locate_rsdp(); + + if (!acpi_rsdp) { + panic("Failed to find RSDP\n"); + } + + kdebug("Found RSDP: %p\n", acpi_rsdp); + if (checksum(acpi_rsdp, sizeof(struct acpi_rsdp)) != 0) { kdebug("RSDP is invalid\n"); while (1); } - kdebug("RSDP revision %d\n", rsdp->rsdp.rev); - rsdt = (struct acpi_rsdt *) (0xFFFFFF0000000000 + rsdp->rsdp.rsdt_address); + kdebug("RSDP revision %d\n", acpi_rsdp->rsdp.rev); + rsdt = (struct acpi_rsdt *) (0xFFFFFF0000000000 + acpi_rsdp->rsdp.rsdt_address); kdebug("RSDT: %p\n", rsdt); if (checksum(rsdt, rsdt->hdr.length) != 0) { diff --git a/include/arch/amd64/hw/acpi.h b/include/arch/amd64/hw/acpi.h index c34b2ff..e506409 100644 --- a/include/arch/amd64/hw/acpi.h +++ b/include/arch/amd64/hw/acpi.h @@ -100,7 +100,10 @@ struct acpi_fadt { //... } __attribute__((packed)); +extern struct acpi_rsdp_ext *acpi_rsdp; extern struct acpi_madt *acpi_madt; extern struct acpi_mcfg *acpi_mcfg; +void amd64_acpi_set_rsdp(uintptr_t addr); +void amd64_acpi_set_rsdp2(uintptr_t addr); void amd64_acpi_init(void);