From a6ac50cad59825087510a1e5db41551cc91d5529 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sun, 19 Nov 2023 08:18:07 -0700 Subject: [PATCH 1/8] sandbox: Fix VPL instructions Fix the devicetree used with sandbox. This is needed because the default (full) devicetree must be used by all phases of boot, with sandbox. Signed-off-by: Simon Glass Reviewed-by: Heinrich Schuchardt --- doc/arch/sandbox/sandbox.rst | 50 +++++++++++++++++++++++++++++++++--- 1 file changed, 47 insertions(+), 3 deletions(-) diff --git a/doc/arch/sandbox/sandbox.rst b/doc/arch/sandbox/sandbox.rst index 23902dee89e..5f8db126657 100644 --- a/doc/arch/sandbox/sandbox.rst +++ b/doc/arch/sandbox/sandbox.rst @@ -424,15 +424,59 @@ space. See existing code for examples. VPL (Verifying Program Loader) ------------------------------ -Sandbox provides an example build of vpl called `sandbox_vpl`. This can be run -using:: +Sandbox provides an example build of vpl called `sandbox_vpl`. To build it: - /path/to/sandbox_vpl/tpl/u-boot-tpl -D +.. code-block:: bash + + make sandbox_vpl_defconfig all + +This can be run using: + +.. code-block:: bash + + ./tpl/u-boot-tpl -d u-boot.dtb It starts up TPL (first-stage init), then VPL, then runs SPL and finally U-Boot proper, following the normal flow for a verified boot. At present, no verification is actually implemented. +Here is an example trace:: + + U-Boot TPL 2024.01-rc2-00129 (Nov 19 2023 - 08:10:12 -0700) + Trying to boot from sandbox_image + Trying to boot from sandbox_file + + U-Boot VPL 2024.01-rc2-00129 (Nov 19 2023 - 08:10:12 -0700) + Trying to boot from vbe_simple + Trying to boot from sandbox_image + Trying to boot from sandbox_file + + U-Boot SPL 2024.01-rc2-00129 (Nov 19 2023 - 08:10:12 -0700) + Trying to boot from vbe_simple + Trying to boot from sandbox_image + Trying to boot from sandbox_file + + + U-Boot 2024.01-rc2-00129 (Nov 19 2023 - 08:10:12 -0700) + + Reset Status: COLD + Model: sandbox + DRAM: 256 MiB + using memory 0x1b576000-0x1f578000 for malloc() + + Warning: host_lo MAC addresses don't match: + Address in ROM is 96:cd:ef:82:78:51 + Address in environment is 02:00:11:22:33:44 + Core: 103 devices, 51 uclasses, devicetree: board + MMC: + Loading Environment from nowhere... OK + In: serial,cros-ec-keyb,usbkbd + Out: serial,vidconsole + Err: serial,vidconsole + Model: sandbox + Net: eth0: host_lo, eth1: host_enp14s0, eth2: host_eth6, eth3: host_wlp15s0, eth4: host_virbr0, eth5: host_docker0, eth6: eth@10002000 + Hit any key to stop autoboot: 1 + Debugging the init sequence --------------------------- From 463e341348738151df6fadcae0cd459ea431bbce Mon Sep 17 00:00:00 2001 From: Tom Rini Date: Tue, 21 Nov 2023 10:41:07 -0500 Subject: [PATCH 2/8] doc: clang: Update and correct support notes At this point, clang can be used on both 32bit and 64bit targets without issue. Make note of logic we have that will inform clang of the architecture to build for. Signed-off-by: Tom Rini Reviewed-by: Heinrich Schuchardt --- doc/build/clang.rst | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/doc/build/clang.rst b/doc/build/clang.rst index cc265506c2f..09bb988e923 100644 --- a/doc/build/clang.rst +++ b/doc/build/clang.rst @@ -11,14 +11,6 @@ The ARM backend can be instructed not to use the r9 and x18 registers using supported inline assembly is needed to get and set the r9 or x18 value. This leads to larger code then strictly necessary, but at least works. -**NOTE:** target compilation only work for _some_ ARM boards at the moment. -Also AArch64 is not supported currently due to a lack of private libgcc -support. Boards which reassign gd in c will also fail to compile, but there is -in no strict reason to do so in the ARM world, since crt0.S takes care of this. -These assignments can be avoided by changing the init calls but this is not in -mainline yet. - - Debian based ------------ @@ -28,14 +20,20 @@ Required packages can be installed via apt, e.g. sudo apt-get install clang -Note that we still use binutils for some tools so we must continue to set -CROSS_COMPILE. To compile U-Boot with Clang on Linux without IAS use e.g. +We make use of the CROSS_COMPILE variable to derive the build target which is +passed as the --target parameter to clang. + +The CROSS_COMPILE variable further determines the paths to other build +tools. As assembler we use the binary pointed to by '$(CROSS_COMPILE)as' +instead of the LLVM integrated assembler (IAS). + +Here is an example demonstrating building U-Boot for the Raspberry Pi 2 +using clang: .. code-block:: bash make HOSTCC=clang rpi_2_defconfig - make HOSTCC=clang CROSS_COMPILE=arm-linux-gnueabi- \ - CC="clang -target arm-linux-gnueabi" -j8 + make HOSTCC=clang CROSS_COMPILE=arm-linux-gnueabi- CC=clang -j8 It can also be used to compile sandbox: From 1e8a8f3232ba1f7d08b9760204f0a7425ea710c5 Mon Sep 17 00:00:00 2001 From: Mattijs Korpershoek Date: Tue, 21 Nov 2023 17:27:38 +0100 Subject: [PATCH 3/8] doc: sending_patches.rst: s/Superseeded/Superseded This is a common typo listed in scripts/spelling.txt. Fix it to match the patchwork status, which is superseded. Signed-off-by: Mattijs Korpershoek Reviewed-by: Heinrich Schuchardt Signed-off-by: Heinrich Schuchardt --- doc/develop/sending_patches.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/develop/sending_patches.rst b/doc/develop/sending_patches.rst index ba73d0d11b4..5a6962f1021 100644 --- a/doc/develop/sending_patches.rst +++ b/doc/develop/sending_patches.rst @@ -363,7 +363,7 @@ A Custodian has additional privileges and can: * Awaiting Upstream - * Superseeded + * Superseded * Deferred @@ -399,7 +399,7 @@ today. Not all states are used by all custodians. and has not merged yet to master, or has queued the patch up to be submitted to be merged, but has not yet. -* Superseeded: Patches are marked as 'superseeded' when the poster submits a +* Superseded: Patches are marked as 'superseded' when the poster submits a new version of these patches. * Deferred: Deferred usually means the patch depends on something else that From f32fee03595684ebf362832fb56ad01e97b01925 Mon Sep 17 00:00:00 2001 From: Masahisa Kojima Date: Fri, 27 Oct 2023 16:43:26 +0900 Subject: [PATCH 4/8] scripts/Makefile.lib: print error when no public key is specified The current build system embeds the EFI Signature List(ESL) into the dtb to be used in the EFI capsule authentication. This ESL file is specified through the CONFIG_EFI_CAPSULE_ESL_FILE Kconfig option. If CONFIG_EFI_CAPSULE_ESL_FILE is not specified, U-boot build ends up with failure but the cause of failure is not easily understandable. Current error message is as follows. FATAL ERROR: Error reading file into data: Is a directoryCheck /home/ubuntu/src/ledge/u-boot/arch/arm/dts/.synquacer-sc2a11-developerbox.dtb.pre.tmp for errors make[2]: *** [scripts/Makefile.lib:355: arch/arm/dts/synquacer-sc2a11-developerbox.dtb] Error 1 make[1]: *** [dts/Makefile:44: arch-dtbs] Error 2 make: *** [Makefile:1165: dts/dt.dtb] Error 2 make: *** Waiting for unfinished jobs.... This commit shows the error message that CONFIG_EFI_CAPSULE_ESL_FILE must be specified when the EFI capsule authentication is enabled, then terminate the build with error. Signed-off-by: Masahisa Kojima Reviewed-by: Weizhao Ouyang --- scripts/Makefile.lib | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib index 8dc6ec82cd5..16bbc277a9f 100644 --- a/scripts/Makefile.lib +++ b/scripts/Makefile.lib @@ -339,7 +339,12 @@ cmd_capsule_esl_gen = \ $(shell sed "s:ESL_BIN_FILE:$(capsule_esl_path):" $(capsule_esl_input_file) > $@) $(obj)/.capsule_esl.dtsi: FORCE +ifeq ($(CONFIG_EFI_CAPSULE_ESL_FILE),"") + $(error "CONFIG_EFI_CAPSULE_ESL_FILE is empty, EFI capsule authentication \ + public key must be specified when CONFIG_EFI_CAPSULE_AUTHENTICATE is enabled") +else $(call cmd_capsule_esl_gen) +endif capsule_esl_input_file=$(srctree)/lib/efi_loader/capsule_esl.dtsi.in capsule_esl_dtsi = .capsule_esl.dtsi From a900d88e1af013362bb9243530af1bb80935389b Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sun, 12 Nov 2023 13:55:09 -0700 Subject: [PATCH 5/8] 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(-) 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. From 8c06b27eec8c3e5c7316a0525b596f26e001b0f3 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sun, 12 Nov 2023 13:55:10 -0700 Subject: [PATCH 6/8] efi: Correct display of table GUIDs The printf() %pU option decodes GUIDs so it is not necessary to do this first. Drop the incorrect code. Signed-off-by: Simon Glass Reviewed-by: Ilias Apalodimas Reviewed-by: Heinrich Schuchardt --- cmd/efi_common.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/cmd/efi_common.c b/cmd/efi_common.c index f4056096cd3..1aa2351fcdf 100644 --- a/cmd/efi_common.c +++ b/cmd/efi_common.c @@ -17,10 +17,8 @@ void efi_show_tables(struct efi_system_table *systab) for (i = 0; i < systab->nr_tables; i++) { struct efi_configuration_table *tab = &systab->tables[i]; - char guid_str[37]; - uuid_bin_to_str(tab->guid.b, guid_str, 1); - printf("%p %pUl %s\n", tab->table, guid_str, + printf("%p %pUl %s\n", tab->table, tab->guid.b, uuid_guid_get_str(tab->guid.b) ?: "(unknown)"); } } From 1be415b21b2da2f7979bdbccf7cf01103883b5de Mon Sep 17 00:00:00 2001 From: Heinrich Schuchardt Date: Thu, 16 Nov 2023 10:29:28 +0100 Subject: [PATCH 7/8] 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(-) 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 From 6805b4dbad72a6e9180426c50f6db6e2681430c0 Mon Sep 17 00:00:00 2001 From: Ilias Apalodimas Date: Tue, 28 Nov 2023 21:10:31 +0200 Subject: [PATCH 8/8] 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(-) 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 */