From 5f46c6eba59bc3bd29f0641628891c443930e477 Mon Sep 17 00:00:00 2001 From: Heinrich Schuchardt Date: Sat, 3 Sep 2022 12:21:09 +0000 Subject: cmd: fix tftpput command Calling tftpput with less than 2 arguments must lead to a failure. If tftpput is called with two arguments, these are the address and the size of the file to be transferred. Signed-off-by: Heinrich Schuchardt Reviewed-by: Simon Glass --- cmd/net.c | 90 ++++++++++++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 66 insertions(+), 24 deletions(-) diff --git a/cmd/net.c b/cmd/net.c index 3619c843d83..527ac84553a 100644 --- a/cmd/net.c +++ b/cmd/net.c @@ -189,30 +189,49 @@ static void netboot_update_env(void) #endif } -static int netboot_common(enum proto_t proto, struct cmd_tbl *cmdtp, int argc, - char *const argv[]) +/** + * parse_addr_size() - parse address and size arguments for tftpput + * + * @argv: command line arguments + * Return: 0 on success + */ +static int parse_addr_size(char * const argv[]) { - char *s; - char *end; - int rcode = 0; - int size; - ulong addr; - - net_boot_file_name_explicit = false; + if (strict_strtoul(argv[1], 16, &image_save_addr) < 0 || + strict_strtoul(argv[2], 16, &image_save_size) < 0) { + printf("Invalid address/size\n"); + return CMD_RET_USAGE; + } + return 0; +} - /* pre-set image_load_addr */ - s = env_get("loadaddr"); - if (s != NULL) - image_load_addr = hextoul(s, NULL); +/** + * parse_args() - parse command line arguments + * + * @proto: command prototype + * @argc: number of arguments + * @argv: command line arguments + * Return: 0 on success + */ +static int parse_args(enum proto_t proto, int argc, char *const argv[]) +{ + ulong addr; + char *end; switch (argc) { case 1: + if (CONFIG_IS_ENABLED(CMD_TFTPPUT) && proto == TFTPPUT) + return 1; + /* refresh bootfile name from env */ copy_filename(net_boot_file_name, env_get("bootfile"), sizeof(net_boot_file_name)); break; - case 2: /* + case 2: + if (CONFIG_IS_ENABLED(CMD_TFTPPUT) && proto == TFTPPUT) + return 1; + /* * Only one arg - accept two forms: * Just load address, or just boot file name. The latter * form must be written in a format which can not be @@ -232,29 +251,52 @@ static int netboot_common(enum proto_t proto, struct cmd_tbl *cmdtp, int argc, break; case 3: - image_load_addr = hextoul(argv[1], NULL); - net_boot_file_name_explicit = true; - copy_filename(net_boot_file_name, argv[2], - sizeof(net_boot_file_name)); - + if (CONFIG_IS_ENABLED(CMD_TFTPPUT) && proto == TFTPPUT) { + if (parse_addr_size(argv)) + return 1; + } else { + image_load_addr = hextoul(argv[1], NULL); + net_boot_file_name_explicit = true; + copy_filename(net_boot_file_name, argv[2], + sizeof(net_boot_file_name)); + } break; #ifdef CONFIG_CMD_TFTPPUT case 4: - if (strict_strtoul(argv[1], 16, &image_save_addr) < 0 || - strict_strtoul(argv[2], 16, &image_save_size) < 0) { - printf("Invalid address/size\n"); - return CMD_RET_USAGE; - } + if (parse_addr_size(argv)) + return 1; net_boot_file_name_explicit = true; copy_filename(net_boot_file_name, argv[3], sizeof(net_boot_file_name)); break; #endif default: + return 1; + } + return 0; +} + +static int netboot_common(enum proto_t proto, struct cmd_tbl *cmdtp, int argc, + char *const argv[]) +{ + char *s; + int rcode = 0; + int size; + + net_boot_file_name_explicit = false; + *net_boot_file_name = '\0'; + + /* pre-set image_load_addr */ + s = env_get("loadaddr"); + if (s != NULL) + image_load_addr = hextoul(s, NULL); + + if (parse_args(proto, argc, argv)) { bootstage_error(BOOTSTAGE_ID_NET_START); return CMD_RET_USAGE; } + bootstage_mark(BOOTSTAGE_ID_NET_START); size = net_loop(proto); -- cgit From 651031ef7c47f2efb2cec11c18eb9aa2020e0815 Mon Sep 17 00:00:00 2001 From: Heinrich Schuchardt Date: Sun, 4 Sep 2022 09:08:11 +0200 Subject: cmd: correct short text for tftpboot The command's name is a misnomer. The command loads a file but does not run (boot) it. Signed-off-by: Heinrich Schuchardt Reviewed-by: Simon Glass --- cmd/Kconfig | 2 +- cmd/net.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/cmd/Kconfig b/cmd/Kconfig index 8ea064b8d2f..0e0be94f41f 100644 --- a/cmd/Kconfig +++ b/cmd/Kconfig @@ -1719,7 +1719,7 @@ config CMD_TFTPBOOT bool "tftpboot" default y help - tftpboot - boot image via network using TFTP protocol + tftpboot - load file via network using TFTP protocol config CMD_TFTPPUT bool "tftp put" diff --git a/cmd/net.c b/cmd/net.c index 527ac84553a..46f8c87b692 100644 --- a/cmd/net.c +++ b/cmd/net.c @@ -46,7 +46,7 @@ int do_tftpb(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) U_BOOT_CMD( tftpboot, 3, 1, do_tftpb, - "boot image via network using TFTP protocol", + "load file via network using TFTP protocol", "[loadAddress] [[hostIPaddr:]bootfilename]" ); #endif -- cgit From afb70d1ef48850c3e40ca57926a20cef79804fe2 Mon Sep 17 00:00:00 2001 From: Heinrich Schuchardt Date: Sat, 3 Sep 2022 13:31:04 +0200 Subject: doc: man-page for tftpput Provide a man-page for the tftpput command. Signed-off-by: Heinrich Schuchardt Reviewed-by: Simon Glass --- doc/usage/cmd/tftpput.rst | 87 +++++++++++++++++++++++++++++++++++++++++++++++ doc/usage/index.rst | 1 + 2 files changed, 88 insertions(+) create mode 100644 doc/usage/cmd/tftpput.rst diff --git a/doc/usage/cmd/tftpput.rst b/doc/usage/cmd/tftpput.rst new file mode 100644 index 00000000000..aabac7f763d --- /dev/null +++ b/doc/usage/cmd/tftpput.rst @@ -0,0 +1,87 @@ +.. SPDX-License-Identifier: GPL-2.0+: + +tftpput command +=============== + +Synopsis +-------- + +:: + + tftpput address size [[hostIPaddr:]filename] + +Decription +---------- + +The tftpput command is used to transfer a file to a TFTP server. + +By default the destination port is 69 and the source port is pseudo-random. +If CONFIG_TFTP_PORT=y, the environment variable *tftpsrcp* can be used to set +the source port and the environment variable *tftpdstp* can be used to set +the destination port. + +address + memory address where the data starts + +size + number of bytes to be transferred + +hostIPaddr + IP address of the TFTP server, defaults to the value of environment + variable *serverip* + +filename + path of the file to be written. If not provided, the client's IP address is + used to construct a default file name, e.g. C0.A8.00.28.img for IP address + 192.168.0.40. + +Example +------- + +In the example the following steps are executed: + +* setup client network address +* load a file from the SD-card +* send the file via TFTP to a server + +:: + + => setenv autoload no + => dhcp + BOOTP broadcast 1 + DHCP client bound to address 192.168.1.40 (7 ms) + => load mmc 0:1 $loadaddr test.txt + 260096 bytes read in 13 ms (19.1 MiB/s) + => tftpput $loadaddr $filesize 192.168.1.3:upload/test.txt + Using ethernet@1c30000 device + TFTP to server 192.168.1.3; our IP address is 192.168.1.40 + Filename 'upload/test.txt'. + Save address: 0x42000000 + Save size: 0x3f800 + Saving: ################# + 4.4 MiB/s + done + Bytes transferred = 260096 (3f800 hex) + => + +Configuration +------------- + +The command is only available if CONFIG_CMD_TFTPPUT=y. + +CONFIG_TFTP_BLOCKSIZE defines the size of the TFTP blocks sent. It defaults +to 1468 matching an ethernet MTU of 1500. + +If CONFIG_TFTP_PORT=y, the environment variables *tftpsrcp* and *tftpdstp* can +be used to set the source and the destination ports. + +CONFIG_TFTP_WINDOWSIZE can be used to set the TFTP window size of transmits +after which an ACK response is required. The window size defaults to 1. + +If CONFIG_TFTP_TSIZE=y, the progress bar is limited to 50 '#' characters. +Otherwise an '#' is written per UDP package which may decrease performance. + +Return value +------------ + +The return value $? is 0 (true) on success and 1 (false) otherwise. diff --git a/doc/usage/index.rst b/doc/usage/index.rst index 28f9683a3e6..f1beeec59c9 100644 --- a/doc/usage/index.rst +++ b/doc/usage/index.rst @@ -63,6 +63,7 @@ Shell commands cmd/scp03 cmd/setexpr cmd/size + cmd/tftpput cmd/true cmd/ums cmd/wdt -- cgit From b33f246c0b6affe16c5df1459fe6d35c15a3c672 Mon Sep 17 00:00:00 2001 From: Heinrich Schuchardt Date: Sat, 3 Sep 2022 15:56:51 +0200 Subject: efi_selftest: export efi_st_get_config_table() We can use efi_st_get_config_table() in multiple unit tests. Export the function. Export system-table and boot-services. Signed-off-by: Heinrich Schuchardt --- include/efi_selftest.h | 11 +++++++++++ lib/efi_selftest/efi_selftest.c | 38 ++++++++++++++++++------------------ lib/efi_selftest/efi_selftest_fdt.c | 17 ---------------- lib/efi_selftest/efi_selftest_util.c | 11 +++++++++++ 4 files changed, 41 insertions(+), 36 deletions(-) diff --git a/include/efi_selftest.h b/include/efi_selftest.h index 5340cefbb6f..e900cb85a96 100644 --- a/include/efi_selftest.h +++ b/include/efi_selftest.h @@ -18,6 +18,9 @@ #define EFI_ST_FAILURE 1 #define EFI_ST_SUCCESS_STR u"SUCCESS" +extern const struct efi_system_table *st_systable; +extern const struct efi_boot_services *st_boottime; + /** * efi_st_printf() - print a message * @@ -130,6 +133,14 @@ u16 *efi_st_translate_code(u16 code); */ int efi_st_strcmp_16_8(const u16 *buf1, const char *buf2); +/** + * efi_st_get_config_table() - get configuration table + * + * @guid: GUID of the configuration table + * Return: pointer to configuration table or NULL + */ +void *efi_st_get_config_table(const efi_guid_t *guid); + /** * efi_st_get_key() - reads an Unicode character from the input device * diff --git a/lib/efi_selftest/efi_selftest.c b/lib/efi_selftest/efi_selftest.c index 8e427b9e511..191da7fc451 100644 --- a/lib/efi_selftest/efi_selftest.c +++ b/lib/efi_selftest/efi_selftest.c @@ -14,8 +14,8 @@ #define EFI_ST_EXECUTE 2 #define EFI_ST_TEARDOWN 4 -static const struct efi_system_table *systable; -static const struct efi_boot_services *boottime; +const struct efi_system_table *st_systable; +const struct efi_boot_services *st_boottime; static const struct efi_runtime_services *runtime; static efi_handle_t handle; static u16 reset_message[] = u"Selftest completed"; @@ -41,7 +41,7 @@ void efi_st_exit_boot_services(void) /* Do not detach devices in ExitBootServices. We need the console. */ efi_st_keep_devices = true; - ret = boottime->get_memory_map(&map_size, NULL, &map_key, &desc_size, + ret = st_boottime->get_memory_map(&map_size, NULL, &map_key, &desc_size, &desc_version); if (ret != EFI_BUFFER_TOO_SMALL) { efi_st_error( @@ -50,19 +50,19 @@ void efi_st_exit_boot_services(void) } /* Allocate extra space for newly allocated memory */ map_size += sizeof(struct efi_mem_desc); - ret = boottime->allocate_pool(EFI_BOOT_SERVICES_DATA, map_size, + ret = st_boottime->allocate_pool(EFI_BOOT_SERVICES_DATA, map_size, (void **)&memory_map); if (ret != EFI_SUCCESS) { efi_st_error("AllocatePool did not return EFI_SUCCESS\n"); return; } - ret = boottime->get_memory_map(&map_size, memory_map, &map_key, + ret = st_boottime->get_memory_map(&map_size, memory_map, &map_key, &desc_size, &desc_version); if (ret != EFI_SUCCESS) { efi_st_error("GetMemoryMap did not return EFI_SUCCESS\n"); return; } - ret = boottime->exit_boot_services(handle, map_key); + ret = st_boottime->exit_boot_services(handle, map_key); if (ret != EFI_SUCCESS) { efi_st_error("ExitBootServices did not return EFI_SUCCESS\n"); return; @@ -84,7 +84,7 @@ static int setup(struct efi_unit_test *test, unsigned int *failures) if (!test->setup) return EFI_ST_SUCCESS; efi_st_printc(EFI_LIGHTBLUE, "\nSetting up '%s'\n", test->name); - ret = test->setup(handle, systable); + ret = test->setup(handle, st_systable); if (ret != EFI_ST_SUCCESS) { efi_st_error("Setting up '%s' failed\n", test->name); ++*failures; @@ -240,8 +240,8 @@ void efi_st_do_tests(const u16 *testname, unsigned int phase, * All tests use a driver model and are run in three phases: * setup, execute, teardown. * - * A test may be setup and executed at boottime, - * it may be setup at boottime and executed at runtime, + * A test may be setup and executed at st_boottime, + * it may be setup at st_boottime and executed at runtime, * or it may be setup and executed at runtime. * * After executing all tests the system is reset. @@ -257,14 +257,14 @@ efi_status_t EFIAPI efi_selftest(efi_handle_t image_handle, struct efi_loaded_image *loaded_image; efi_status_t ret; - systable = systab; - boottime = systable->boottime; - runtime = systable->runtime; + st_systable = systab; + st_boottime = st_systable->boottime; + runtime = st_systable->runtime; handle = image_handle; - con_out = systable->con_out; - con_in = systable->con_in; + con_out = st_systable->con_out; + con_in = st_systable->con_in; - ret = boottime->handle_protocol(image_handle, &efi_guid_loaded_image, + ret = st_boottime->handle_protocol(image_handle, &efi_guid_loaded_image, (void **)&loaded_image); if (ret != EFI_SUCCESS) { efi_st_error("Cannot open loaded image protocol\n"); @@ -280,9 +280,9 @@ efi_status_t EFIAPI efi_selftest(efi_handle_t image_handle, list_all_tests(); /* * TODO: - * Once the Exit boottime service is correctly + * Once the Exit st_boottime service is correctly * implemented we should call - * boottime->exit(image_handle, EFI_SUCCESS, 0, NULL); + * st_boottime->exit(image_handle, EFI_SUCCESS, 0, NULL); * here, cf. * https://lists.denx.de/pipermail/u-boot/2017-October/308720.html */ @@ -300,7 +300,7 @@ efi_status_t EFIAPI efi_selftest(efi_handle_t image_handle, efi_unit_test)); /* Allocate buffer for setup results */ - ret = boottime->allocate_pool(EFI_RUNTIME_SERVICES_DATA, sizeof(int) * + ret = st_boottime->allocate_pool(EFI_RUNTIME_SERVICES_DATA, sizeof(int) * ll_entry_count(struct efi_unit_test, efi_unit_test), (void **)&setup_status); @@ -309,7 +309,7 @@ efi_status_t EFIAPI efi_selftest(efi_handle_t image_handle, return ret; } - /* Execute boottime tests */ + /* Execute st_boottime tests */ efi_st_do_tests(testname, EFI_EXECUTE_BEFORE_BOOTTIME_EXIT, EFI_ST_SETUP | EFI_ST_EXECUTE | EFI_ST_TEARDOWN, &failures); diff --git a/lib/efi_selftest/efi_selftest_fdt.c b/lib/efi_selftest/efi_selftest_fdt.c index 114ac58bf5c..aa3b13ae3ab 100644 --- a/lib/efi_selftest/efi_selftest_fdt.c +++ b/lib/efi_selftest/efi_selftest_fdt.c @@ -144,23 +144,6 @@ static char *get_property(const u16 *property, const u16 *node) return NULL; } -/** - * efi_st_get_config_table() - get configuration table - * - * @guid: GUID of the configuration table - * Return: pointer to configuration table or NULL - */ -static void *efi_st_get_config_table(const efi_guid_t *guid) -{ - size_t i; - - for (i = 0; i < systab.nr_tables; i++) { - if (!guidcmp(guid, &systemtab->tables[i].guid)) - return systemtab->tables[i].table; - } - return NULL; -} - /* * Setup unit test. * diff --git a/lib/efi_selftest/efi_selftest_util.c b/lib/efi_selftest/efi_selftest_util.c index dba02d6b567..7e03e0c9392 100644 --- a/lib/efi_selftest/efi_selftest_util.c +++ b/lib/efi_selftest/efi_selftest_util.c @@ -110,3 +110,14 @@ int efi_st_strcmp_16_8(const u16 *buf1, const char *buf2) } return 0; } + +void *efi_st_get_config_table(const efi_guid_t *guid) +{ + size_t i; + + for (i = 0; i < st_systable->nr_tables; i++) { + if (!guidcmp(guid, &st_systable->tables[i].guid)) + return st_systable->tables[i].table; + } + return NULL; +} -- cgit From 1e30e377a62fad6e22cdfabf9847662695f68ba8 Mon Sep 17 00:00:00 2001 From: Heinrich Schuchardt Date: Sat, 3 Sep 2022 15:58:19 +0200 Subject: efi_selftest: unit test for EFI Conformance Profile Table Add a new unit test to test the integrity of the EFI Conformance Profile Table. Signed-off-by: Heinrich Schuchardt Reviewed-by: Ilias Apalodimas --- lib/efi_selftest/Makefile | 1 + lib/efi_selftest/efi_selftest_ecpt.c | 76 ++++++++++++++++++++++++++++++++++++ 2 files changed, 77 insertions(+) create mode 100644 lib/efi_selftest/efi_selftest_ecpt.c diff --git a/lib/efi_selftest/Makefile b/lib/efi_selftest/Makefile index 33536c9ec02..daac6c39682 100644 --- a/lib/efi_selftest/Makefile +++ b/lib/efi_selftest/Makefile @@ -49,6 +49,7 @@ efi_selftest_variables.o \ efi_selftest_variables_runtime.o \ efi_selftest_watchdog.o +obj-$(CONFIG_EFI_ECPT) += efi_selftest_ecpt.o obj-$(CONFIG_NET) += efi_selftest_snp.o obj-$(CONFIG_EFI_DEVICE_PATH_TO_TEXT) += efi_selftest_devicepath.o diff --git a/lib/efi_selftest/efi_selftest_ecpt.c b/lib/efi_selftest/efi_selftest_ecpt.c new file mode 100644 index 00000000000..e8cc13545db --- /dev/null +++ b/lib/efi_selftest/efi_selftest_ecpt.c @@ -0,0 +1,76 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * efi_selftest_fdt + * + * Copyright (c) 2022 Heinrich Schuchardt + * + * Check the EFI_CONFORMANCE_PROFILE_TABLE + */ + +#include + +static const efi_guid_t guid_ecpt = EFI_CONFORMANCE_PROFILES_TABLE_GUID; +static const efi_guid_t guid_ebbr_2_0 = EFI_CONFORMANCE_PROFILE_EBBR_2_0_GUID; + +/* + * ecpt_find_guid() - find GUID in EFI Conformance Profile Table + * + * @ecpt: EFI Conformance Profile Table + * @guid: GUID to find + * Return: EFI_ST_SUCCESS for success + */ +static int ecpt_find_guid(struct efi_conformance_profiles_table *ecpt, + const efi_guid_t *guid) { + int i; + + for (i = 0; i < ecpt->number_of_profiles; ++i) { + if (!memcmp(&ecpt->conformance_profiles[i], guid, 16)) + return EFI_ST_SUCCESS; + } + efi_st_error("GUID %pU not found\n", guid); + return EFI_ST_FAILURE; +} + +/* + * Execute unit test. + * + * Return: EFI_ST_SUCCESS for success + */ +static int execute(void) +{ + struct efi_conformance_profiles_table *ecpt; + int expected_entries = 0; + + ecpt = efi_st_get_config_table(&guid_ecpt); + + if (!ecpt) { + efi_st_error("Missing EFI Conformance Profile Table\n"); + return EFI_ST_FAILURE; + } + + if (ecpt->version != EFI_CONFORMANCE_PROFILES_TABLE_VERSION) { + efi_st_error("Wrong table version\n"); + return EFI_ST_FAILURE; + } + + if (CONFIG_IS_ENABLED(EFI_EBBR_2_0_CONFORMANCE)) { + ++expected_entries; + if (ecpt_find_guid(ecpt, &guid_ebbr_2_0)) + return EFI_ST_FAILURE; + } + + if (ecpt->number_of_profiles != expected_entries) { + efi_st_error("Expected %d entries, found %d\n", + expected_entries, ecpt->number_of_profiles); + return EFI_ST_FAILURE; + } + + return EFI_ST_SUCCESS; +} + + +EFI_UNIT_TEST(ecpt) = { + .name = "conformance profile table", + .phase = EFI_EXECUTE_BEFORE_BOOTTIME_EXIT, + .execute = execute, +}; -- cgit From 793254893954dc96437b5b5541aab84485bf78b1 Mon Sep 17 00:00:00 2001 From: Etienne Carriere Date: Wed, 7 Sep 2022 10:20:13 +0200 Subject: lib: efi_loader: don't delete invalid handles Change efi_delete_handle() to not free EFI handles twice. This change tries to resolved an issue seen since U-Boot v2022.07 in which ExitBootService() attempts to release some EFI handles twice. The issue was seen booting a EFI shell that invokes 'connect -r' and then boots a Linux kernel. Execution of connect command makes EFI subsystem to bind a block device for each root block devices EFI handles. However these EFI device handles are already bound to a driver and we can have 2 registered devices relating to the same EFI handler. On ExitBootService(), the loop removing the devices makes these EFI handles to be released twice which corrupts memory. This patch prevents the memory release operation caused by the issue but but does not resolve the underlying problem. Signed-off-by: Etienne Carriere Add log message. Reviewed-by: Heinrich Schuchardt Reviewed-by: Ilias Apalodimas --- lib/efi_loader/efi_boottime.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/lib/efi_loader/efi_boottime.c b/lib/efi_loader/efi_boottime.c index 4da64b5d296..6f7333638ae 100644 --- a/lib/efi_loader/efi_boottime.c +++ b/lib/efi_loader/efi_boottime.c @@ -619,9 +619,14 @@ efi_status_t efi_remove_all_protocols(const efi_handle_t handle) */ void efi_delete_handle(efi_handle_t handle) { - if (!handle) + efi_status_t ret; + + ret = efi_remove_all_protocols(handle); + if (ret == EFI_INVALID_PARAMETER) { + log_err("Can't remove invalid handle %p\n", handle); return; - efi_remove_all_protocols(handle); + } + list_del(&handle->link); free(handle); } -- cgit From 8cf8ad353345cc4a92288b5136e7d714d2bdde4a Mon Sep 17 00:00:00 2001 From: Heinrich Schuchardt Date: Fri, 9 Sep 2022 06:57:58 +0000 Subject: efi_driver: don't bind internal block devices UEFI block devices can either mirror U-Boot's internal devices or be provided by an EFI application like iPXE. When ConnectController() is invoked for the EFI_BLOCK_IO_PROTOCOL interface for such an application provided device we create a virtual U-Boot block device of type "efi_blk". Currently we do not call ConnectController() when handles for U-Boot's internal block devices are created. If an EFI application calls ConnectController() for a handle relating to an internal block device, we erroneously create an extra "efi_blk" block device. E.g. the UEFI shell has a command 'connect -r' which calls ConnectController() for all handles with device path protocol. In the Supported() method of our EFI_DRIVER_BINDING_PROTOCOL return EFI_UNSUPPORTED when dealing with an U-Boot internal device. Reported-by: Etienne Carriere Fixes: commit 05ef48a2484b ("efi_driver: EFI block driver") Signed-off-by: Heinrich Schuchardt Reviewed-by: Etienne Carriere Tested-by: Etienne Carriere Reviewed-by: Ilias Apalodimas --- lib/efi_driver/efi_uclass.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/lib/efi_driver/efi_uclass.c b/lib/efi_driver/efi_uclass.c index b01ce89c84e..74dd0032437 100644 --- a/lib/efi_driver/efi_uclass.c +++ b/lib/efi_driver/efi_uclass.c @@ -71,6 +71,15 @@ static efi_status_t EFIAPI efi_uc_supported( EFI_ENTRY("%p, %p, %ls", this, controller_handle, efi_dp_str(remaining_device_path)); + /* + * U-Boot internal devices install protocols interfaces without calling + * ConnectController(). Hence we should not bind an extra driver. + */ + if (controller_handle->dev) { + ret = EFI_UNSUPPORTED; + goto out; + } + ret = EFI_CALL(systab.boottime->open_protocol( controller_handle, bp->ops->protocol, &interface, this->driver_binding_handle, -- cgit