The new unit tests checks if ACPI tables are available. If yes, it checks if the RSDT correctly points to the RSDT or XSDT.
Signed-off-by: Heinrich Schuchardt <[email protected]> --- lib/efi_selftest/Makefile | 1 + lib/efi_selftest/efi_selftest_acpi.c | 75 ++++++++++++++++++++++++++++ 2 files changed, 76 insertions(+) create mode 100644 lib/efi_selftest/efi_selftest_acpi.c diff --git a/lib/efi_selftest/Makefile b/lib/efi_selftest/Makefile index 67102648703..c6cc2430bbf 100644 --- a/lib/efi_selftest/Makefile +++ b/lib/efi_selftest/Makefile @@ -17,6 +17,7 @@ CFLAGS_REMOVE_efi_selftest_miniapp_return.o := $(CFLAGS_NON_EFI) obj-y += \ efi_selftest.o \ +efi_selftest_acpi.o \ efi_selftest_bitblt.o \ efi_selftest_config_table.o \ efi_selftest_controllers.o \ diff --git a/lib/efi_selftest/efi_selftest_acpi.c b/lib/efi_selftest/efi_selftest_acpi.c new file mode 100644 index 00000000000..ee91c1fd120 --- /dev/null +++ b/lib/efi_selftest/efi_selftest_acpi.c @@ -0,0 +1,75 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * efi_selftest_acpi + * + * Copyright 2026, Heinrich Schuchardt <[email protected]> + * + * Check ACPI configuration table availability and root table presence. + */ + +#include <efi_selftest.h> +#include <acpi/acpi_table.h> + +static const efi_guid_t acpi2_guid = EFI_ACPI_TABLE_GUID; +static const efi_guid_t acpi1_guid = EFI_GUID_EFI_ACPI1; + +/** + * efi_st_acpi_execute() - execute ACPI selftest + * + * Return: status code + */ +static int efi_st_acpi_execute(void) +{ + struct acpi_rsdp *rsdp; + struct acpi_table_header *table; + u32 rsdt_addr32; + u64 xsdt_addr64; + uintptr_t rsdt_addr; + uintptr_t xsdt_addr; + + rsdp = efi_st_get_config_table(&acpi2_guid); + if (!rsdp) + rsdp = efi_st_get_config_table(&acpi1_guid); + if (!rsdp) + return EFI_ST_SUCCESS; + + if (memcmp(rsdp->signature, RSDP_SIG, sizeof(rsdp->signature))) { + efi_st_error("Wrong RSDP signature\n"); + return EFI_ST_FAILURE; + } + + memcpy(&rsdt_addr32, &rsdp->rsdt_address, sizeof(rsdt_addr32)); + rsdt_addr = rsdt_addr32; + + xsdt_addr64 = 0; + if (rsdp->revision >= ACPI_RSDP_REV_ACPI_2_0) + memcpy(&xsdt_addr64, &rsdp->xsdt_address, sizeof(xsdt_addr64)); + xsdt_addr = xsdt_addr64; + + if (!rsdt_addr && !xsdt_addr) { + efi_st_error("Neither RSDT nor XSDT address is set\n"); + return EFI_ST_FAILURE; + } + + if (xsdt_addr) { + table = (struct acpi_table_header *)xsdt_addr; + if (!memcmp(table->signature, "XSDT", 4)) + return EFI_ST_SUCCESS; + efi_st_error("XSDT address does not point to XSDT\n"); + } + + if (rsdt_addr) { + table = (struct acpi_table_header *)rsdt_addr; + if (!memcmp(table->signature, "RSDT", 4)) + return EFI_ST_SUCCESS; + efi_st_error("RSDT address does not point to RSDT\n"); + } + + return EFI_ST_FAILURE; +} + +EFI_UNIT_TEST(acpi) = { + .name = "acpi", + .phase = EFI_EXECUTE_BEFORE_BOOTTIME_EXIT, + .execute = efi_st_acpi_execute, +}; -- 2.53.0

