From 8ec7d5d35531f9a321181e60b088980da8c68d1c Mon Sep 17 00:00:00 2001 From: Heinrich Schuchardt Date: Sun, 7 Apr 2019 23:53:53 +0200 Subject: efi_loader: assign HII protocols to root node We should not install the HII protocols on every loaded image. It is sufficient to install them once on the root node. Signed-off-by: Heinrich Schuchardt --- lib/efi_loader/efi_boottime.c | 20 -------------------- lib/efi_loader/efi_root_node.c | 20 ++++++++++++++++++++ 2 files changed, 20 insertions(+), 20 deletions(-) diff --git a/lib/efi_loader/efi_boottime.c b/lib/efi_loader/efi_boottime.c index b215bd7723..31d11b8678 100644 --- a/lib/efi_loader/efi_boottime.c +++ b/lib/efi_loader/efi_boottime.c @@ -1569,26 +1569,6 @@ efi_status_t efi_setup_loaded_image(struct efi_device_path *device_path, if (ret != EFI_SUCCESS) goto failure; -#if CONFIG_IS_ENABLED(EFI_LOADER_HII) - ret = efi_add_protocol(&obj->header, - &efi_guid_hii_string_protocol, - (void *)&efi_hii_string); - if (ret != EFI_SUCCESS) - goto failure; - - ret = efi_add_protocol(&obj->header, - &efi_guid_hii_database_protocol, - (void *)&efi_hii_database); - if (ret != EFI_SUCCESS) - goto failure; - - ret = efi_add_protocol(&obj->header, - &efi_guid_hii_config_routing_protocol, - (void *)&efi_hii_config_routing); - if (ret != EFI_SUCCESS) - goto failure; -#endif - *info_ptr = info; *handle_ptr = obj; diff --git a/lib/efi_loader/efi_root_node.c b/lib/efi_loader/efi_root_node.c index b056ba3ee8..b58d9d8c96 100644 --- a/lib/efi_loader/efi_root_node.c +++ b/lib/efi_loader/efi_root_node.c @@ -74,6 +74,26 @@ efi_status_t efi_root_node_register(void) if (ret != EFI_SUCCESS) goto failure; +#if CONFIG_IS_ENABLED(EFI_LOADER_HII) + /* Install HII string protocol */ + ret = efi_add_protocol(root, &efi_guid_hii_string_protocol, + (void *)&efi_hii_string); + if (ret != EFI_SUCCESS) + goto failure; + + /* Install HII database protocol */ + ret = efi_add_protocol(root, &efi_guid_hii_database_protocol, + (void *)&efi_hii_database); + if (ret != EFI_SUCCESS) + goto failure; + + /* Install HII configuration routing protocol */ + ret = efi_add_protocol(root, &efi_guid_hii_config_routing_protocol, + (void *)&efi_hii_config_routing); + if (ret != EFI_SUCCESS) + goto failure; +#endif + failure: return ret; } -- cgit v1.2.1 From 084f09330131656c3073ed51084b50cbc85a05e4 Mon Sep 17 00:00:00 2001 From: Heinrich Schuchardt Date: Sun, 7 Apr 2019 23:58:50 +0200 Subject: efi_loader: enable HII protocols by default As the UEFI shell requires the HII protocols let's enable them by default. Signed-off-by: Heinrich Schuchardt --- lib/efi_loader/Kconfig | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/lib/efi_loader/Kconfig b/lib/efi_loader/Kconfig index 23487b8130..a6489ca534 100644 --- a/lib/efi_loader/Kconfig +++ b/lib/efi_loader/Kconfig @@ -38,14 +38,11 @@ config EFI_LOADER_BOUNCE_BUFFER config EFI_LOADER_HII bool "Expose HII protocols to EFI applications" depends on EFI_LOADER - default n + default y help The Human Interface Infrastructure is a complicated framework that allows UEFI applications to draw fancy menus and hook strings using a translation framework. U-Boot implements enough of its features to be able to run the UEFI - Shell, but not more than that. The code is experimental still, so - beware that your system might break with HII enabled. - - If unsure, say n. + Shell, but not more than that. -- cgit v1.2.1 From 2337741fb4379754340149f2d4fdaf8071274826 Mon Sep 17 00:00:00 2001 From: Heinrich Schuchardt Date: Tue, 9 Apr 2019 23:22:13 +0200 Subject: efi_loader: remove stray #define LOG_CATEGORY LOGL_ERR The statement '#define LOG_CATEGORY LOGL_ERR' makes not sense. LOGL_ERR is not a LOG_CATEGORY. Remove the statement. Signed-off-by: Heinrich Schuchardt --- lib/efi_loader/efi_device_path.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/lib/efi_loader/efi_device_path.c b/lib/efi_loader/efi_device_path.c index 53b40c8c3c..1b08ca8f62 100644 --- a/lib/efi_loader/efi_device_path.c +++ b/lib/efi_loader/efi_device_path.c @@ -5,8 +5,6 @@ * (C) Copyright 2017 Rob Clark */ -#define LOG_CATEGORY LOGL_ERR - #include #include #include -- cgit v1.2.1 From e7ac009b0063b8e9bafa5c39cacab4948ae8238d Mon Sep 17 00:00:00 2001 From: Heinrich Schuchardt Date: Wed, 10 Apr 2019 00:32:07 +0200 Subject: efi_loader: move efi_save_gd() call to board_r.c The first functions of the UEFI sub-system are invoked before reaching the U-Boot shell, e.g. efi_set_bootdev(), efi_dp_from_name(), efi_dp_from_file(). We should be able to print out device paths for debugging purposes here. When printing device paths via printf("%pD\n", dp) this invokes functions defined as EFIAPI. So efi_save_gd() must be called beforehand. So let's move the efi_save_gd() call to function initr_reloc_global_data(() in board_r.c. Signed-off-by: Heinrich Schuchardt --- common/board_r.c | 7 +++++++ lib/efi_driver/efi_uclass.c | 3 --- lib/efi_loader/efi_setup.c | 7 ------- 3 files changed, 7 insertions(+), 10 deletions(-) diff --git a/common/board_r.c b/common/board_r.c index 472987d5d5..1ad44bbe3f 100644 --- a/common/board_r.c +++ b/common/board_r.c @@ -154,6 +154,13 @@ static int initr_reloc_global_data(void) gd->fdt_blob += gd->reloc_off; #endif #ifdef CONFIG_EFI_LOADER + /* + * On the ARM architecture gd is mapped to a fixed register (r9 or x18). + * As this register may be overwritten by an EFI payload we save it here + * and restore it on every callback entered. + */ + efi_save_gd(); + efi_runtime_relocate(gd->relocaddr, NULL); #endif diff --git a/lib/efi_driver/efi_uclass.c b/lib/efi_driver/efi_uclass.c index 7cdf81f40c..b14746e6b1 100644 --- a/lib/efi_driver/efi_uclass.c +++ b/lib/efi_driver/efi_uclass.c @@ -300,9 +300,6 @@ efi_status_t efi_driver_init(void) struct driver *drv; efi_status_t ret = EFI_SUCCESS; - /* Save 'gd' pointer */ - efi_save_gd(); - debug("EFI: Initializing EFI driver framework\n"); for (drv = ll_entry_start(struct driver, driver); drv < ll_entry_end(struct driver, driver); ++drv) { diff --git a/lib/efi_loader/efi_setup.c b/lib/efi_loader/efi_setup.c index a908843d87..6e9d5fe5b7 100644 --- a/lib/efi_loader/efi_setup.c +++ b/lib/efi_loader/efi_setup.c @@ -20,13 +20,6 @@ efi_status_t efi_init_obj_list(void) { efi_status_t ret = EFI_SUCCESS; - /* - * On the ARM architecture gd is mapped to a fixed register (r9 or x18). - * As this register may be overwritten by an EFI payload we save it here - * and restore it on every callback entered. - */ - efi_save_gd(); - /* * Variable PlatformLang defines the language that the machine has been * configured for. -- cgit v1.2.1 From bba816569075be9bcede1ef5626336ee5d014de8 Mon Sep 17 00:00:00 2001 From: Heinrich Schuchardt Date: Thu, 4 Apr 2019 22:06:25 +0200 Subject: arm: print information about loaded UEFI images If an exception occurs in a UEFI loaded image we need the start address of the image to determine the relocation offset. This patch adds the necessary lines after the registers in the crash dump for armv8. A possible output would be: UEFI image [0x00000000bffe6000:0x00000000bffe631f] pc=0x138 '/\snp.efi' With the offset 0x138 we can now find the relevant instruction in the disassembled 'snp.efi' binary. Signed-off-by: Heinrich Schuchardt --- arch/arm/lib/interrupts_64.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/arch/arm/lib/interrupts_64.c b/arch/arm/lib/interrupts_64.c index 458319ab48..0bfdb8d93d 100644 --- a/arch/arm/lib/interrupts_64.c +++ b/arch/arm/lib/interrupts_64.c @@ -25,6 +25,11 @@ int disable_interrupts(void) return 0; } +static void show_efi_loaded_images(struct pt_regs *regs) +{ + efi_print_image_infos((void *)regs->elr); +} + void show_regs(struct pt_regs *regs) { int i; @@ -49,6 +54,7 @@ void do_bad_sync(struct pt_regs *pt_regs, unsigned int esr) efi_restore_gd(); printf("Bad mode in \"Synchronous Abort\" handler, esr 0x%08x\n", esr); show_regs(pt_regs); + show_efi_loaded_images(pt_regs); panic("Resetting CPU ...\n"); } @@ -60,6 +66,7 @@ void do_bad_irq(struct pt_regs *pt_regs, unsigned int esr) efi_restore_gd(); printf("Bad mode in \"Irq\" handler, esr 0x%08x\n", esr); show_regs(pt_regs); + show_efi_loaded_images(pt_regs); panic("Resetting CPU ...\n"); } @@ -71,6 +78,7 @@ void do_bad_fiq(struct pt_regs *pt_regs, unsigned int esr) efi_restore_gd(); printf("Bad mode in \"Fiq\" handler, esr 0x%08x\n", esr); show_regs(pt_regs); + show_efi_loaded_images(pt_regs); panic("Resetting CPU ...\n"); } @@ -82,6 +90,7 @@ void do_bad_error(struct pt_regs *pt_regs, unsigned int esr) efi_restore_gd(); printf("Bad mode in \"Error\" handler, esr 0x%08x\n", esr); show_regs(pt_regs); + show_efi_loaded_images(pt_regs); panic("Resetting CPU ...\n"); } @@ -93,6 +102,7 @@ void do_sync(struct pt_regs *pt_regs, unsigned int esr) efi_restore_gd(); printf("\"Synchronous Abort\" handler, esr 0x%08x\n", esr); show_regs(pt_regs); + show_efi_loaded_images(pt_regs); panic("Resetting CPU ...\n"); } @@ -104,6 +114,7 @@ void do_irq(struct pt_regs *pt_regs, unsigned int esr) efi_restore_gd(); printf("\"Irq\" handler, esr 0x%08x\n", esr); show_regs(pt_regs); + show_efi_loaded_images(pt_regs); panic("Resetting CPU ...\n"); } @@ -115,6 +126,7 @@ void do_fiq(struct pt_regs *pt_regs, unsigned int esr) efi_restore_gd(); printf("\"Fiq\" handler, esr 0x%08x\n", esr); show_regs(pt_regs); + show_efi_loaded_images(pt_regs); panic("Resetting CPU ...\n"); } @@ -129,5 +141,6 @@ void __weak do_error(struct pt_regs *pt_regs, unsigned int esr) efi_restore_gd(); printf("\"Error\" handler, esr 0x%08x\n", esr); show_regs(pt_regs); + show_efi_loaded_images(pt_regs); panic("Resetting CPU ...\n"); } -- cgit v1.2.1 From 60fd8844af5c47f606680f287db4585d783c1964 Mon Sep 17 00:00:00 2001 From: Patrick Wildt Date: Tue, 9 Apr 2019 22:58:30 +0200 Subject: efi: fix memory calculation overflow on 32-bit systems There are Cubox-i machines out there with nearly 4 GiB of RAM. The RAM starts at 0x10000000 with a size of 0xf0000000. Thus the end of RAM is at 0x100000000. This overflows a 32-bit integer, which should be fine since in the EFI memory code the variables used are all 64-bit with a fixed size. Unfortunately EFI_PAGE_MASK, which is used in the EFI memory code to remove the lower bits, is based on the EFI_PAGE_SIZE macro which, uses 1UL with a shift. This means the resulting mask is UL, which is only 32-bit on ARMv7. Use ULL to make sure that even on 32-bit platforms we use a 64-bit long mask. Without this there will be no memory available in the EFI memory map and bootefi will fail allocating pages. Signed-off-by: Patrick Wildt Reviewed-by: Heinrich Schuchardt Reviewed-by: Patrick Delaunay --- include/efi.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/efi.h b/include/efi.h index d98441ab19..3c9d20f8c0 100644 --- a/include/efi.h +++ b/include/efi.h @@ -190,7 +190,7 @@ enum efi_mem_type { #define EFI_MEM_DESC_VERSION 1 #define EFI_PAGE_SHIFT 12 -#define EFI_PAGE_SIZE (1UL << EFI_PAGE_SHIFT) +#define EFI_PAGE_SIZE (1ULL << EFI_PAGE_SHIFT) #define EFI_PAGE_MASK (EFI_PAGE_SIZE - 1) struct efi_mem_desc { -- cgit v1.2.1 From dc6f3f48c5d8efeadf1d4956837f69fee22b0234 Mon Sep 17 00:00:00 2001 From: Heinrich Schuchardt Date: Wed, 10 Apr 2019 08:04:38 +0200 Subject: efi_loader: the development target should be the EBBR Two subsets of the UEFI specifications have been defined. The one for servers is "Server Base Boot Requirements System Software on ARM Platforms" (SBBR), the one for embedded systems is the "Embedded Base Boot Requirements (EBBR) Specification". Reaching compliance with thei EBBR is a more realistic development target than reaching complicance with the SBBR. Suggested-by: Alexander Graf Signed-off-by: Heinrich Schuchardt --- doc/README.uefi | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/doc/README.uefi b/doc/README.uefi index 66b6abece5..1d1039a6ae 100644 --- a/doc/README.uefi +++ b/doc/README.uefi @@ -14,9 +14,11 @@ and boot loaders like GRUB or the FreeBSD loader can be executed. ## Development target -The implementation of UEFI in U-Boot strives to reach the minimum requirements -described in "Server Base Boot Requirements System Software on ARM Platforms - -Version 1.1" [4]. +The implementation of UEFI in U-Boot strives to reach the requirements described +in the "Embedded Base Boot Requirements (EBBR) Specification - Release v1.0" +[4]. The "Server Base Boot Requirements System Software on ARM Platforms" [5] +describes a superset of the EBBR specification and may be used as further +reference. A full blown UEFI implementation would contradict the U-Boot design principle "keep it small". @@ -344,5 +346,7 @@ This driver is only available if U-Boot is configured with http://uefi.org/specifications - UEFI specifications * [2](./driver-model/README.txt) doc/driver-model/README.txt - Driver model * [3](./README.iscsi) doc/README.iscsi - iSCSI booting with U-Boot and iPXE -* [4](https://developer.arm.com/docs/den0044/latest/server-base-boot-requirements-system-software-on-arm-platforms-version-11) +* [4](https://github.com/ARM-software/ebbr/releases/download/v1.0/ebbr-v1.0.pdf) + Embedded Base Boot Requirements (EBBR) Specification - Release v1.0 +* [5](https://developer.arm.com/docs/den0044/latest/server-base-boot-requirements-system-software-on-arm-platforms-version-11) Server Base Boot Requirements System Software on ARM Platforms - Version 1.1 -- cgit v1.2.1 From 07805f203bec8e8e24837428c2fab39533168bf2 Mon Sep 17 00:00:00 2001 From: Heinrich Schuchardt Date: Thu, 11 Apr 2019 07:34:24 +0200 Subject: efi_loader: fix setting PlatformLang The UEFI variables PlatformLang and PlatformLangCodes specify the current firmware language and the list of all available languages. Currently their values are hard coded. With the patch a new configuration variable EFI_PLATFORM_LANG_CODES is provided. When initializing the UEFI subsystem this configuration variable is used to initialize PlatformLangCodes. The value of variable PlatformLang is read. If it is not set, the first language specified in EFI_PLATFORM_LANG_CODES is used to initialize PlatformLang. Suggested-by: Takahiro Akashi Signed-off-by: Heinrich Schuchardt --- lib/efi_loader/Kconfig | 10 +++++++ lib/efi_loader/efi_setup.c | 72 ++++++++++++++++++++++++++++++++++++---------- 2 files changed, 67 insertions(+), 15 deletions(-) diff --git a/lib/efi_loader/Kconfig b/lib/efi_loader/Kconfig index a6489ca534..50b050159c 100644 --- a/lib/efi_loader/Kconfig +++ b/lib/efi_loader/Kconfig @@ -26,6 +26,16 @@ config EFI_UNICODE_CAPITALIZATION set, only the the correct handling of the letters of the codepage used by the FAT file system is ensured. +config EFI_PLATFORM_LANG_CODES + string "Language codes supported by firmware" + depends on EFI_LOADER + default "en-US" + help + This value is used to initialize the PlatformLangCodes variable. Its + value is a semicolon (;) separated list of language codes in native + RFC 4646 format, e.g. "en-US;de-DE". The first language code is used + to initialize the PlatformLang variable. + config EFI_LOADER_BOUNCE_BUFFER bool "EFI Applications use bounce buffers for DMA operations" depends on EFI_LOADER && ARM64 diff --git a/lib/efi_loader/efi_setup.c b/lib/efi_loader/efi_setup.c index 6e9d5fe5b7..b32a7b3f93 100644 --- a/lib/efi_loader/efi_setup.c +++ b/lib/efi_loader/efi_setup.c @@ -10,44 +10,86 @@ #define OBJ_LIST_NOT_INITIALIZED 1 -/* Language code for American English according to RFC 4646 */ -#define EN_US L"en-US" - static efi_status_t efi_obj_list_initialized = OBJ_LIST_NOT_INITIALIZED; -/* Initialize and populate EFI object list */ -efi_status_t efi_init_obj_list(void) +/** + * efi_init_platform_lang() - define supported languages + * + * Set the PlatformLangCodes and PlatformLang variables. + * + * Return: status code + */ +static efi_status_t efi_init_platform_lang(void) { - efi_status_t ret = EFI_SUCCESS; + efi_status_t ret; + efi_uintn_t data_size = 0; + char *lang = CONFIG_EFI_PLATFORM_LANG_CODES; + char *pos; /* - * Variable PlatformLang defines the language that the machine has been - * configured for. + * Variable PlatformLangCodes defines the language codes that the + * machine can support. */ - ret = EFI_CALL(efi_set_variable(L"PlatformLang", + ret = EFI_CALL(efi_set_variable(L"PlatformLangCodes", &efi_global_variable_guid, EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS, - sizeof(EN_US), EN_US)); + sizeof(CONFIG_EFI_PLATFORM_LANG_CODES), + CONFIG_EFI_PLATFORM_LANG_CODES)); if (ret != EFI_SUCCESS) goto out; /* - * Variable PlatformLangCodes defines the language codes that the - * machine can support. + * Variable PlatformLang defines the language that the machine has been + * configured for. */ - ret = EFI_CALL(efi_set_variable(L"PlatformLangCodes", + ret = EFI_CALL(efi_get_variable(L"PlatformLang", &efi_global_variable_guid, + NULL, &data_size, &pos)); + if (ret == EFI_BUFFER_TOO_SMALL) { + /* The variable is already set. Do not change it. */ + ret = EFI_SUCCESS; + goto out; + } + + /* + * The list of supported languages is semicolon separated. Use the first + * language to initialize PlatformLang. + */ + pos = strchr(lang, ';'); + if (pos) + *pos = 0; + + ret = EFI_CALL(efi_set_variable(L"PlatformLang", + &efi_global_variable_guid, + EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS, - sizeof(EN_US), EN_US)); + 1 + strlen(lang), lang)); +out: if (ret != EFI_SUCCESS) - goto out; + printf("EFI: cannot initialize platform language settings\n"); + return ret; +} + +/** + * efi_init_obj_list() - Initialize and populate EFI object list + * + * Return: status code + */ +efi_status_t efi_init_obj_list(void) +{ + efi_status_t ret = EFI_SUCCESS; /* Initialize once only */ if (efi_obj_list_initialized != OBJ_LIST_NOT_INITIALIZED) return efi_obj_list_initialized; + /* Define supported languages */ + ret = efi_init_platform_lang(); + if (ret != EFI_SUCCESS) + goto out; + /* Initialize system table */ ret = efi_initialize_system_table(); if (ret != EFI_SUCCESS) -- cgit v1.2.1 From 74f5baa28bebf243b372d63a673ddf214cbc50b6 Mon Sep 17 00:00:00 2001 From: Patrick Delaunay Date: Wed, 10 Apr 2019 11:02:58 +0200 Subject: efi_loader: add protection for block_dev Check the value of block_dev before to use this pointer. This patch solves problem for the command "load" when ubifs is previously mounted: in this case the function blk_get_device_part_str("ubi 0") don't return error but return block_dev = NULL and then data abort. Signed-off-by: Patrick Delaunay Reviewed-by: Heinrich Schuchardt Signed-off-by: Heinrich Schuchardt --- lib/efi_loader/efi_device_path.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/efi_loader/efi_device_path.c b/lib/efi_loader/efi_device_path.c index 1b08ca8f62..d8c052d6ec 100644 --- a/lib/efi_loader/efi_device_path.c +++ b/lib/efi_loader/efi_device_path.c @@ -968,7 +968,7 @@ efi_status_t efi_dp_from_name(const char *dev, const char *devnr, if (!is_net) { part = blk_get_device_part_str(dev, devnr, &desc, &fs_partition, 1); - if (part < 0) + if (part < 0 || !desc) return EFI_INVALID_PARAMETER; if (device) -- cgit v1.2.1 From 9631fa0fd191adaa5521ee78369f62e975c57a06 Mon Sep 17 00:00:00 2001 From: Heinrich Schuchardt Date: Thu, 11 Apr 2019 20:08:54 +0200 Subject: efi_loader: update virtual address in efi_mem_carve_out Handle virtual address in efi_mem_carve_out() function when a new region is created to avoid issue in EFI memory map. Signed-off-by: Patrick Delaunay At boottime physical and virtual addressed have to be the same. This allowed to simplify the proposed logic. Reviewed-by: Heinrich Schuchardt --- lib/efi_loader/efi_memory.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/efi_loader/efi_memory.c b/lib/efi_loader/efi_memory.c index dbe29b8960..46681dc208 100644 --- a/lib/efi_loader/efi_memory.c +++ b/lib/efi_loader/efi_memory.c @@ -193,6 +193,7 @@ static s64 efi_mem_carve_out(struct efi_mem_list *map, free(map); } else { map->desc.physical_start = carve_end; + map->desc.virtual_start = carve_end; map->desc.num_pages = (map_end - carve_end) >> EFI_PAGE_SHIFT; } @@ -211,6 +212,7 @@ static s64 efi_mem_carve_out(struct efi_mem_list *map, newmap = calloc(1, sizeof(*newmap)); newmap->desc = map->desc; newmap->desc.physical_start = carve_start; + newmap->desc.virtual_start = carve_start; newmap->desc.num_pages = (map_end - carve_start) >> EFI_PAGE_SHIFT; /* Insert before current entry (descending address order) */ list_add_tail(&newmap->link, &map->link); -- cgit v1.2.1 From 207c5bcce11fef1aea1fd60f5e5b3cf6db0b2b79 Mon Sep 17 00:00:00 2001 From: Heinrich Schuchardt Date: Thu, 11 Apr 2019 19:59:31 +0200 Subject: efi_selftest: physical and virtual addresses must match At boottime physical and virtual addresses must match. Add a corresponding check to the memory unit test. Signed-off-by: Heinrich Schuchardt --- lib/efi_selftest/efi_selftest_memory.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/lib/efi_selftest/efi_selftest_memory.c b/lib/efi_selftest/efi_selftest_memory.c index 24b4438ce4..d41227b605 100644 --- a/lib/efi_selftest/efi_selftest_memory.c +++ b/lib/efi_selftest/efi_selftest_memory.c @@ -65,6 +65,11 @@ static int find_in_memory_map(efi_uintn_t map_size, for (i = 0; map_size; ++i, map_size -= desc_size) { struct efi_mem_desc *entry = &memory_map[i]; + if (entry->physical_start != entry->virtual_start) { + efi_st_error("Physical and virtual addresses do not match\n"); + return EFI_ST_FAILURE; + } + if (addr >= entry->physical_start && addr < entry->physical_start + (entry->num_pages << EFI_PAGE_SHIFT)) { -- cgit v1.2.1 From 7657ae12f38791be0b89ba5d4423439888cd749c Mon Sep 17 00:00:00 2001 From: Heinrich Schuchardt Date: Fri, 12 Apr 2019 06:59:49 +0200 Subject: efi_loader: export efi_install_multiple_protocol_interfaces Export function efi_install_multiple_protocol_interfaces() so that we can call it in others parts of the UEFI subsystem. Signed-off-by: Heinrich Schuchardt --- include/efi_loader.h | 3 +++ lib/efi_loader/efi_boottime.c | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/include/efi_loader.h b/include/efi_loader.h index 00b81c6010..f7bf732827 100644 --- a/include/efi_loader.h +++ b/include/efi_loader.h @@ -344,6 +344,9 @@ efi_status_t efi_remove_protocol(const efi_handle_t handle, void *protocol_interface); /* Delete all protocols from a handle */ efi_status_t efi_remove_all_protocols(const efi_handle_t handle); +/* Install multiple protocol interfaces */ +efi_status_t EFIAPI efi_install_multiple_protocol_interfaces + (efi_handle_t *handle, ...); /* Call this to create an event */ efi_status_t efi_create_event(uint32_t type, efi_uintn_t notify_tpl, void (EFIAPI *notify_function) ( diff --git a/lib/efi_loader/efi_boottime.c b/lib/efi_loader/efi_boottime.c index 31d11b8678..abc295e392 100644 --- a/lib/efi_loader/efi_boottime.c +++ b/lib/efi_loader/efi_boottime.c @@ -2267,7 +2267,7 @@ out: * * Return: status code */ -static efi_status_t EFIAPI efi_install_multiple_protocol_interfaces +efi_status_t EFIAPI efi_install_multiple_protocol_interfaces (efi_handle_t *handle, ...) { EFI_ENTRY("%p", handle); -- cgit v1.2.1 From f1465c159779853d99c0a293f5d7ee53c13aa837 Mon Sep 17 00:00:00 2001 From: Heinrich Schuchardt Date: Fri, 12 Apr 2019 07:14:43 +0200 Subject: efi_loader: simplify protocol installation By using InstallMultipleProtocolInterfaces() the coding for installing protocol interfaces on the root node can be simplified. Suggested-by: AKASHI Takahiro Signed-off-by: Heinrich Schuchardt --- lib/efi_loader/efi_root_node.c | 76 ++++++++++++++---------------------------- 1 file changed, 25 insertions(+), 51 deletions(-) diff --git a/lib/efi_loader/efi_root_node.c b/lib/efi_loader/efi_root_node.c index b58d9d8c96..392f5c4951 100644 --- a/lib/efi_loader/efi_root_node.c +++ b/lib/efi_loader/efi_root_node.c @@ -26,16 +26,10 @@ struct efi_root_dp { */ efi_status_t efi_root_node_register(void) { - efi_handle_t root; - efi_status_t ret; + efi_handle_t root = NULL; struct efi_root_dp *dp; - /* Create handle */ - ret = efi_create_handle(&root); - if (ret != EFI_SUCCESS) - return ret; - - /* Install device path protocol */ + /* Create device path protocol */ dp = calloc(1, sizeof(*dp)); if (!dp) return EFI_OUT_OF_RESOURCES; @@ -51,49 +45,29 @@ efi_status_t efi_root_node_register(void) dp->end.sub_type = DEVICE_PATH_SUB_TYPE_END; dp->end.length = sizeof(struct efi_device_path); - /* Install device path protocol */ - ret = efi_add_protocol(root, &efi_guid_device_path, dp); - if (ret != EFI_SUCCESS) - goto failure; - - /* Install device path to text protocol */ - ret = efi_add_protocol(root, &efi_guid_device_path_to_text_protocol, - (void *)&efi_device_path_to_text); - if (ret != EFI_SUCCESS) - goto failure; - - /* Install device path utilities protocol */ - ret = efi_add_protocol(root, &efi_guid_device_path_utilities_protocol, - (void *)&efi_device_path_utilities); - if (ret != EFI_SUCCESS) - goto failure; - - /* Install Unicode collation protocol */ - ret = efi_add_protocol(root, &efi_guid_unicode_collation_protocol, - (void *)&efi_unicode_collation_protocol); - if (ret != EFI_SUCCESS) - goto failure; - + /* Create root node and install protocols */ + return EFI_CALL(efi_install_multiple_protocol_interfaces(&root, + /* Device path protocol */ + &efi_guid_device_path, dp, + /* Device path to text protocol */ + &efi_guid_device_path_to_text_protocol, + (void *)&efi_device_path_to_text, + /* Device path utilities protocol */ + &efi_guid_device_path_utilities_protocol, + (void *)&efi_device_path_utilities, + /* Unicode collation protocol */ + &efi_guid_unicode_collation_protocol, + (void *)&efi_unicode_collation_protocol, #if CONFIG_IS_ENABLED(EFI_LOADER_HII) - /* Install HII string protocol */ - ret = efi_add_protocol(root, &efi_guid_hii_string_protocol, - (void *)&efi_hii_string); - if (ret != EFI_SUCCESS) - goto failure; - - /* Install HII database protocol */ - ret = efi_add_protocol(root, &efi_guid_hii_database_protocol, - (void *)&efi_hii_database); - if (ret != EFI_SUCCESS) - goto failure; - - /* Install HII configuration routing protocol */ - ret = efi_add_protocol(root, &efi_guid_hii_config_routing_protocol, - (void *)&efi_hii_config_routing); - if (ret != EFI_SUCCESS) - goto failure; + /* HII string protocol */ + &efi_guid_hii_string_protocol, + (void *)&efi_hii_string, + /* HII database protocol */ + &efi_guid_hii_database_protocol, + (void *)&efi_hii_database, + /* HII configuration routing protocol */ + &efi_guid_hii_config_routing_protocol, + (void *)&efi_hii_config_routing, #endif - -failure: - return ret; + NULL)); } -- cgit v1.2.1 From 29361ec4737c3e4de66aa7b8e87d8818ff6c0580 Mon Sep 17 00:00:00 2001 From: Ilias Apalodimas Date: Fri, 12 Apr 2019 21:26:28 +0300 Subject: Change FDT memory type from runtime data to boot services data Following Ard's suggestion: Runtime data sections are intended for data that is used by the runtime services implementation. Let's change the type to EFI_BOOT_SERVICES_DATA. This also fixes booting of armv7 using efi and fdtcontroladdr. Suggested-by: Ard Biesheuvel Signed-off-by: Ilias Apalodimas Acked-by: Ard Biesheuvel Reviewed-by: Heinrich Schuchardt --- cmd/bootefi.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cmd/bootefi.c b/cmd/bootefi.c index 3619a20e64..15ee4af456 100644 --- a/cmd/bootefi.c +++ b/cmd/bootefi.c @@ -111,13 +111,13 @@ static efi_status_t copy_fdt(void **fdtp) new_fdt_addr = (uintptr_t)map_sysmem(fdt_ram_start + 0x7f00000 + fdt_size, 0); ret = efi_allocate_pages(EFI_ALLOCATE_MAX_ADDRESS, - EFI_RUNTIME_SERVICES_DATA, fdt_pages, + EFI_BOOT_SERVICES_DATA, fdt_pages, &new_fdt_addr); if (ret != EFI_SUCCESS) { /* If we can't put it there, put it somewhere */ new_fdt_addr = (ulong)memalign(EFI_PAGE_SIZE, fdt_size); ret = efi_allocate_pages(EFI_ALLOCATE_MAX_ADDRESS, - EFI_RUNTIME_SERVICES_DATA, fdt_pages, + EFI_BOOT_SERVICES_DATA, fdt_pages, &new_fdt_addr); if (ret != EFI_SUCCESS) { printf("ERROR: Failed to reserve space for FDT\n"); -- cgit v1.2.1 From 8688b753916bfdde3c2911f14d4489c36e705db7 Mon Sep 17 00:00:00 2001 From: Heinrich Schuchardt Date: Fri, 12 Apr 2019 22:09:09 +0200 Subject: efi_selftest: expect boot services data for fdt In a previous patch the memory type used for the FDT has been changed to boot services data. We have to adjust the test. Correct an incorrect comment. The tested services are boot services. Signed-off-by: Heinrich Schuchardt --- lib/efi_selftest/efi_selftest_memory.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/efi_selftest/efi_selftest_memory.c b/lib/efi_selftest/efi_selftest_memory.c index d41227b605..5eeb42a9be 100644 --- a/lib/efi_selftest/efi_selftest_memory.c +++ b/lib/efi_selftest/efi_selftest_memory.c @@ -4,7 +4,7 @@ * * Copyright (c) 2018 Heinrich Schuchardt * - * This unit test checks the following runtime services: + * This unit test checks the following boottime services: * AllocatePages, FreePages, GetMemoryMap * * The memory type used for the device tree is checked. @@ -176,9 +176,9 @@ static int execute(void) /* Check memory reservation for the device tree */ if (fdt_addr && find_in_memory_map(map_size, memory_map, desc_size, fdt_addr, - EFI_RUNTIME_SERVICES_DATA) != EFI_ST_SUCCESS) { + EFI_BOOT_SERVICES_DATA) != EFI_ST_SUCCESS) { efi_st_error - ("Device tree not marked as runtime services data\n"); + ("Device tree not marked as boot services data\n"); return EFI_ST_FAILURE; } return EFI_ST_SUCCESS; -- cgit v1.2.1