From 86df34d42b05f574854f19c96142d8e5d30f5d8d Mon Sep 17 00:00:00 2001 From: Bin Meng Date: Wed, 27 Jun 2018 20:38:03 -0700 Subject: [PATCH] efi_loader: Install ACPI configuration tables ACPI tables can be passed via EFI configuration table to an EFI application. This is only supported on x86 so far. Signed-off-by: Bin Meng Reviewed-by: Simon Glass --- cmd/bootefi.c | 5 +++++ include/efi_api.h | 4 ++++ include/efi_loader.h | 8 ++++++++ lib/efi_loader/Makefile | 1 + lib/efi_loader/efi_acpi.c | 42 ++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 60 insertions(+) create mode 100644 lib/efi_loader/efi_acpi.c diff --git a/cmd/bootefi.c b/cmd/bootefi.c index f55a40d..cd755b6 100644 --- a/cmd/bootefi.c +++ b/cmd/bootefi.c @@ -61,6 +61,11 @@ efi_status_t efi_init_obj_list(void) if (ret != EFI_SUCCESS) goto out; #endif +#ifdef CONFIG_GENERATE_ACPI_TABLE + ret = efi_acpi_register(); + if (ret != EFI_SUCCESS) + goto out; +#endif #ifdef CONFIG_GENERATE_SMBIOS_TABLE ret = efi_smbios_register(); if (ret != EFI_SUCCESS) diff --git a/include/efi_api.h b/include/efi_api.h index 094be6e..0c3dd3c 100644 --- a/include/efi_api.h +++ b/include/efi_api.h @@ -282,6 +282,10 @@ struct efi_runtime_services { EFI_GUID(0xb1b621d5, 0xf19c, 0x41a5, \ 0x83, 0x0b, 0xd9, 0x15, 0x2c, 0x69, 0xaa, 0xe0) +#define EFI_ACPI_TABLE_GUID \ + EFI_GUID(0x8868e871, 0xe4f1, 0x11d3, \ + 0xbc, 0x22, 0x00, 0x80, 0xc7, 0x3c, 0x88, 0x81) + #define SMBIOS_TABLE_GUID \ EFI_GUID(0xeb9d2d31, 0x2d88, 0x11d3, \ 0x9a, 0x16, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d) diff --git a/include/efi_loader.h b/include/efi_loader.h index c66252a..d837e7b 100644 --- a/include/efi_loader.h +++ b/include/efi_loader.h @@ -215,6 +215,14 @@ efi_status_t efi_net_register(void); efi_status_t efi_watchdog_register(void); /* Called by bootefi to make SMBIOS tables available */ /** + * efi_acpi_register() - write out ACPI tables + * + * Called by bootefi to make ACPI tables available + * + * @return 0 if OK, -ENOMEM if no memory is available for the tables + */ +efi_status_t efi_acpi_register(void); +/** * efi_smbios_register() - write out SMBIOS tables * * Called by bootefi to make SMBIOS tables available diff --git a/lib/efi_loader/Makefile b/lib/efi_loader/Makefile index c6046e3..d6402c4 100644 --- a/lib/efi_loader/Makefile +++ b/lib/efi_loader/Makefile @@ -22,4 +22,5 @@ obj-$(CONFIG_LCD) += efi_gop.o obj-$(CONFIG_DM_VIDEO) += efi_gop.o obj-$(CONFIG_PARTITIONS) += efi_disk.o obj-$(CONFIG_NET) += efi_net.o +obj-$(CONFIG_GENERATE_ACPI_TABLE) += efi_acpi.o obj-$(CONFIG_GENERATE_SMBIOS_TABLE) += efi_smbios.o diff --git a/lib/efi_loader/efi_acpi.c b/lib/efi_loader/efi_acpi.c new file mode 100644 index 0000000..a4e5e53 --- /dev/null +++ b/lib/efi_loader/efi_acpi.c @@ -0,0 +1,42 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * EFI application ACPI tables support + * + * Copyright (C) 2018, Bin Meng + */ + +#include +#include +#include + +static const efi_guid_t acpi_guid = EFI_ACPI_TABLE_GUID; + +/* + * Install the ACPI table as a configuration table. + * + * @return status code + */ +efi_status_t efi_acpi_register(void) +{ + /* Map within the low 32 bits, to allow for 32bit ACPI tables */ + u64 acpi = U32_MAX; + efi_status_t ret; + + /* Reserve 64kiB page for ACPI */ + ret = efi_allocate_pages(EFI_ALLOCATE_MAX_ADDRESS, + EFI_RUNTIME_SERVICES_DATA, 16, &acpi); + if (ret != EFI_SUCCESS) + return ret; + + /* + * Generate ACPI tables - we know that efi_allocate_pages() returns + * a 4k-aligned address, so it is safe to assume that + * write_acpi_tables() will write the table at that address. + */ + assert(!(acpi & 0xf)); + write_acpi_tables(acpi); + + /* And expose them to our EFI payload */ + return efi_install_configuration_table(&acpi_guid, + (void *)(uintptr_t)acpi); +}