From a900d88e1af013362bb9243530af1bb80935389b Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sun, 12 Nov 2023 13:55:09 -0700 Subject: efi: Collect the ACPI tables in the app Locate these so that they can be displayed using the 'acpi' command. Signed-off-by: Simon Glass Reviewed-by: Heinrich Schuchardt --- lib/efi/efi_app.c | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) (limited to 'lib') diff --git a/lib/efi/efi_app.c b/lib/efi/efi_app.c index 2209410f35b..c5eb816655e 100644 --- a/lib/efi/efi_app.c +++ b/lib/efi/efi_app.c @@ -12,18 +12,21 @@ #include #include #include +#include +#include #include #include #include +#include +#include #include #include #include -#include -#include -#include +#include #include #include #include +#include DECLARE_GLOBAL_DATA_PTR; @@ -320,6 +323,19 @@ int dm_scan_other(bool pre_reloc_only) return 0; } +static void scan_tables(struct efi_system_table *sys_table) +{ + efi_guid_t acpi = EFI_ACPI_TABLE_GUID; + uint i; + + for (i = 0; i < sys_table->nr_tables; i++) { + struct efi_configuration_table *tab = &sys_table->tables[i]; + + if (!memcmp(&tab->guid, &acpi, sizeof(efi_guid_t))) + gd_set_acpi_start(map_to_sysmem(tab->table)); + } +} + /** * efi_main() - Start an EFI image * @@ -354,6 +370,8 @@ efi_status_t EFIAPI efi_main(efi_handle_t image, return ret; } + scan_tables(priv->sys_table); + /* * We could store the EFI memory map here, but it changes all the time, * so this is only useful for debugging. -- cgit v1.3.1 From 1be415b21b2da2f7979bdbccf7cf01103883b5de Mon Sep 17 00:00:00 2001 From: Heinrich Schuchardt Date: Thu, 16 Nov 2023 10:29:28 +0100 Subject: efi_loader: create memory reservations in ACPI case ACPI tables cannot convey memory reservations for ARM and RISC-V. x86 uses the BIOS E820 table for this purpose. We cannot simply ignore the device-tree when booting via ACPI. We have to assign EfiReservedMemory according to the prior stage device-tree ($fdtaddr) or as fallback the control device-tree ($fdtcontroladdr). Signed-off-by: Heinrich Schuchardt Reviewed-by: Simon Glass --- cmd/bootefi.c | 25 ++++++++++--------------- lib/efi_loader/Makefile | 2 -- 2 files changed, 10 insertions(+), 17 deletions(-) (limited to 'lib') diff --git a/cmd/bootefi.c b/cmd/bootefi.c index 20e5c94a33a..395b0629de2 100644 --- a/cmd/bootefi.c +++ b/cmd/bootefi.c @@ -162,8 +162,6 @@ static efi_status_t efi_env_set_load_options(efi_handle_t handle, return ret; } -#if !CONFIG_IS_ENABLED(GENERATE_ACPI_TABLE) - /** * copy_fdt() - Copy the device tree to a new location available to EFI * @@ -237,8 +235,6 @@ static void *get_config_table(const efi_guid_t *guid) return NULL; } -#endif /* !CONFIG_IS_ENABLED(GENERATE_ACPI_TABLE) */ - /** * efi_install_fdt() - install device tree * @@ -258,18 +254,15 @@ static void *get_config_table(const efi_guid_t *guid) */ efi_status_t efi_install_fdt(void *fdt) { + struct bootm_headers img = { 0 }; + efi_status_t ret; + /* * The EBBR spec requires that we have either an FDT or an ACPI table * but not both. */ -#if CONFIG_IS_ENABLED(GENERATE_ACPI_TABLE) - if (fdt) { + if (CONFIG_IS_ENABLED(GENERATE_ACPI_TABLE) && fdt) log_warning("WARNING: Can't have ACPI table and device tree - ignoring DT.\n"); - return EFI_SUCCESS; - } -#else - struct bootm_headers img = { 0 }; - efi_status_t ret; if (fdt == EFI_FDT_USE_INTERNAL) { const char *fdt_opt; @@ -302,6 +295,12 @@ efi_status_t efi_install_fdt(void *fdt) return EFI_LOAD_ERROR; } + /* Create memory reservations as indicated by the device tree */ + efi_carve_out_dt_rsv(fdt); + + if (CONFIG_IS_ENABLED(GENERATE_ACPI_TABLE)) + return EFI_SUCCESS; + /* Prepare device tree for payload */ ret = copy_fdt(&fdt); if (ret) { @@ -314,9 +313,6 @@ efi_status_t efi_install_fdt(void *fdt) return EFI_LOAD_ERROR; } - /* Create memory reservations as indicated by the device tree */ - efi_carve_out_dt_rsv(fdt); - efi_try_purge_kaslr_seed(fdt); if (CONFIG_IS_ENABLED(EFI_TCG2_PROTOCOL_MEASURE_DTB)) { @@ -333,7 +329,6 @@ efi_status_t efi_install_fdt(void *fdt) log_err("ERROR: failed to install device tree\n"); return ret; } -#endif /* GENERATE_ACPI_TABLE */ return EFI_SUCCESS; } diff --git a/lib/efi_loader/Makefile b/lib/efi_loader/Makefile index 8d31fc61c60..d476df112b8 100644 --- a/lib/efi_loader/Makefile +++ b/lib/efi_loader/Makefile @@ -51,9 +51,7 @@ obj-y += efi_console.o obj-y += efi_device_path.o obj-$(CONFIG_EFI_DEVICE_PATH_TO_TEXT) += efi_device_path_to_text.o obj-$(CONFIG_EFI_DEVICE_PATH_UTIL) += efi_device_path_utilities.o -ifeq ($(CONFIG_GENERATE_ACPI_TABLE),) obj-y += efi_dt_fixup.o -endif obj-y += efi_file.o obj-$(CONFIG_EFI_LOADER_HII) += efi_hii.o obj-y += efi_image_loader.o -- cgit v1.3.1 From 6805b4dbad72a6e9180426c50f6db6e2681430c0 Mon Sep 17 00:00:00 2001 From: Ilias Apalodimas Date: Tue, 28 Nov 2023 21:10:31 +0200 Subject: efi_loader: Make DisconnectController follow the EFI spec commit 239d59a65e20 ("efi_loader: reconnect drivers on failure") tried to fix the UninstallProtocol interface which must reconnect any controllers it disconnected by calling ConnectController() in case of failure. However, the reconnect functionality was wired in efi_disconnect_all_drivers() instead of efi_uninstall_protocol(). As a result some SCT tests started failing. Specifically, BBTestOpenProtocolInterfaceTest333CheckPoint3() test - Calls ConnectController for DriverImageHandle1 - Calls DisconnectController for DriverImageHandle1 which will disconnect everything apart from TestProtocol4. That will remain open on purpose. - Calls ConnectController for DriverImageHandle2. TestProtocol4 which was explicitly preserved was installed wth BY_DRIVER attributes. The new protocol will call DisconnectController since its attributes are BY_DRIVER|EXCLUSIVE, but TestProtocol4 will not be removed. The test expects EFI_ACCESS_DENIED which works fine. The problem is that DisconnectController, will eventually call EFI_DRIVER_BINDING_PROTOCOL.Stop(). But on the aforementioned test this will call CloseProtocol -- the binding protocol is defined in 'DBindingDriver3.c' and the .Stop function uses CloseProtocol. If that close protocol call fails with EFI_NOT_FOUND, the current code will try to mistakenly reconnect all drivers and the subsequent tests that rely on the device being disconnected will fail. Move the reconnection in efi_uninstall_protocol() were it belongs. Fixes: commit 239d59a65e20 ("efi_loader: reconnect drivers on failure") Signed-off-by: Ilias Apalodimas Reviewed-by: Heinrich Schuchardt --- lib/efi_loader/efi_boottime.c | 27 ++++++++++----------------- 1 file changed, 10 insertions(+), 17 deletions(-) (limited to 'lib') diff --git a/lib/efi_loader/efi_boottime.c b/lib/efi_loader/efi_boottime.c index 0b7579cb5af..fad0476a881 100644 --- a/lib/efi_loader/efi_boottime.c +++ b/lib/efi_loader/efi_boottime.c @@ -1339,7 +1339,7 @@ static efi_status_t efi_disconnect_all_drivers const efi_guid_t *protocol, efi_handle_t child_handle) { - efi_uintn_t number_of_drivers, tmp; + efi_uintn_t number_of_drivers; efi_handle_t *driver_handle_buffer; efi_status_t r, ret; @@ -1350,27 +1350,13 @@ static efi_status_t efi_disconnect_all_drivers if (!number_of_drivers) return EFI_SUCCESS; - tmp = number_of_drivers; while (number_of_drivers) { - ret = EFI_CALL(efi_disconnect_controller( + r = EFI_CALL(efi_disconnect_controller( handle, driver_handle_buffer[--number_of_drivers], child_handle)); - if (ret != EFI_SUCCESS) - goto reconnect; - } - - free(driver_handle_buffer); - return ret; - -reconnect: - /* Reconnect all disconnected drivers */ - for (; number_of_drivers < tmp; number_of_drivers++) { - r = EFI_CALL(efi_connect_controller(handle, - &driver_handle_buffer[number_of_drivers], - NULL, true)); if (r != EFI_SUCCESS) - EFI_PRINT("Failed to reconnect controller\n"); + ret = r; } free(driver_handle_buffer); @@ -1409,6 +1395,13 @@ static efi_status_t efi_uninstall_protocol r = efi_disconnect_all_drivers(handle, protocol, NULL); if (r != EFI_SUCCESS) { r = EFI_ACCESS_DENIED; + /* + * This will reconnect all controllers of the handle, even ones + * that were not connected before. This can be done better + * but we are following the EDKII implementation on this for + * now + */ + EFI_CALL(efi_connect_controller(handle, NULL, NULL, true)); goto out; } /* Close protocol */ -- cgit v1.3.1 From 253f939aa11cecde2aef632b528d550ca94630b4 Mon Sep 17 00:00:00 2001 From: Tom Rini Date: Mon, 20 Nov 2023 15:17:23 -0500 Subject: lib/Kconfig: Correct typo about SYSINFO_SMBIOS in help message The correct symbol to enable to have SMBIOS populate fields based on the device tree is SYSINFO_SMBIOS and not SMBIOS_SYSINFO. Signed-off-by: Tom Rini Reviewed-by: Simon Glass --- lib/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/Kconfig b/lib/Kconfig index 19649517a39..d47df6bb1cf 100644 --- a/lib/Kconfig +++ b/lib/Kconfig @@ -995,7 +995,7 @@ config GENERATE_SMBIOS_TABLE Check http://www.dmtf.org/standards/smbios for details. - See also SMBIOS_SYSINFO which allows SMBIOS values to be provided in + See also SYSINFO_SMBIOS which allows SMBIOS values to be provided in the devicetree. endmenu -- cgit v1.3.1