ACPI uses 32-bit addresses for RSDP revision < 2: use RSDT table in this case instead of XSDT. Tested on SIMATIC IPC847e.
Signed-off-by: Cedric Hombourger <[email protected]> --- drivers/watchdog/wdat.c | 53 ++++++++++++++++++++++++++++++++++------- 1 file changed, 45 insertions(+), 8 deletions(-) diff --git a/drivers/watchdog/wdat.c b/drivers/watchdog/wdat.c index df708cf..5157955 100644 --- a/drivers/watchdog/wdat.c +++ b/drivers/watchdog/wdat.c @@ -29,6 +29,7 @@ #define EFI_ACPI_ROOT_SDP_REVISION 0x02 #define ACPI_SIG_RSDP (CHAR8 *)"RSD PTR " +#define ACPI_SIG_RSDT (CHAR8 *)"RSDT" #define ACPI_SIG_XSDT (CHAR8 *)"XSDT" #define ACPI_SIG_WDAT (CHAR8 *)"WDAT" @@ -140,18 +141,32 @@ typedef struct { */ static EFI_STATUS -parse_rsdp(EFI_ACPI_ROOT_SDP_HEADER *rsdp, ACPI_TABLE_WDAT **wdat_table_ptr) { - EFI_ACPI_SDT_HEADER *xsdt; - UINT64 *entry_ptr; - UINT64 n, count; +parse_rsdt(EFI_ACPI_SDT_HEADER *rsdt, ACPI_TABLE_WDAT **wdat_table_ptr) { + UINT32 *entry_ptr; + UINT32 n, count; - *wdat_table_ptr = NULL; + if (strncmpa(ACPI_SIG_RSDT, (CHAR8 *)(VOID *)(rsdt->signature), 4)) { + return EFI_INCOMPATIBLE_VERSION; + } - if (rsdp->revision < EFI_ACPI_ROOT_SDP_REVISION) { - return EFI_NOT_FOUND; + entry_ptr = (UINT32 *)(rsdt + 1); + count = (rsdt->length - sizeof (EFI_ACPI_SDT_HEADER)) / sizeof(UINT32); + for (n = 0; n < count; n++, entry_ptr++) { + EFI_ACPI_SDT_HEADER *entry = + (EFI_ACPI_SDT_HEADER *)((UINTN)(*entry_ptr)); + if (!strncmpa(ACPI_SIG_WDAT, entry->signature, 4)) { + *wdat_table_ptr = (ACPI_TABLE_WDAT *)entry; + return EFI_SUCCESS; + } } + return EFI_NOT_FOUND; +} + +static EFI_STATUS +parse_xsdt(EFI_ACPI_SDT_HEADER *xsdt, ACPI_TABLE_WDAT **wdat_table_ptr) { + UINT64 *entry_ptr; + UINT64 n, count; - xsdt = (EFI_ACPI_SDT_HEADER *)(UINTN)(rsdp->xsdt_address); if (strncmpa(ACPI_SIG_XSDT, (CHAR8 *)(VOID *)(xsdt->signature), 4)) { return EFI_INCOMPATIBLE_VERSION; } @@ -169,6 +184,28 @@ parse_rsdp(EFI_ACPI_ROOT_SDP_HEADER *rsdp, ACPI_TABLE_WDAT **wdat_table_ptr) { return EFI_NOT_FOUND; } +static EFI_STATUS +parse_rsdp(EFI_ACPI_ROOT_SDP_HEADER *rsdp, ACPI_TABLE_WDAT **wdat_table_ptr) { + EFI_ACPI_SDT_HEADER *sdt; + + *wdat_table_ptr = NULL; + + if (rsdp->revision > EFI_ACPI_ROOT_SDP_REVISION) { + ERROR(L"SDP revision not supported (%d)\n", rsdp->revision); + return EFI_INCOMPATIBLE_VERSION; + } + + if (rsdp->revision == EFI_ACPI_ROOT_SDP_REVISION) { + sdt = (EFI_ACPI_SDT_HEADER *)(UINTN)(rsdp->xsdt_address); + return parse_xsdt(sdt, wdat_table_ptr); + } + else { + /* Promote 32-bit address to 64-bit... */ + sdt = (EFI_ACPI_SDT_HEADER *)(UINTN)(rsdp->rsdt_address); + return parse_rsdt(sdt, wdat_table_ptr); + } +} + static EFI_STATUS locate_and_parse_rsdp(ACPI_TABLE_WDAT **wdat_table_ptr) { EFI_CONFIGURATION_TABLE *ect = ST->ConfigurationTable; -- 2.30.2 -- You received this message because you are subscribed to the Google Groups "EFI Boot Guard" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. To view this discussion on the web visit https://groups.google.com/d/msgid/efibootguard-dev/20211014122438.815-1-Cedric_Hombourger%40mentor.com.
