From 7a597259d26f84a63350b6a1af5b29445e9d451b Mon Sep 17 00:00:00 2001 From: Heinrich Schuchardt Date: Thu, 28 Nov 2019 06:46:09 +0100 Subject: efi_loader: pass address to efi_install_fdt() As part of moving the parsing of command line arguments to do_bootefi() call efi_install_fdt() with the address of the device tree instead of a string. If the address is EFI_FDT_USE_INTERNAL (= 0), the internal device tree is used. Signed-off-by: Heinrich Schuchardt --- cmd/bootefi.c | 32 ++++++++++++++++++-------------- 1 file changed, 18 insertions(+), 14 deletions(-) (limited to 'cmd') diff --git a/cmd/bootefi.c b/cmd/bootefi.c index f613cce7e26..2b190a3edda 100644 --- a/cmd/bootefi.c +++ b/cmd/bootefi.c @@ -196,40 +196,39 @@ static void *get_config_table(const efi_guid_t *guid) #endif /* !CONFIG_IS_ENABLED(GENERATE_ACPI_TABLE) */ /** - * efi_install_fdt() - install fdt passed by a command argument + * efi_install_fdt() - install device tree * - * If fdt_opt is available, the device tree located at that memory address will + * If fdt_addr is available, the device tree located at that memory address will * will be installed as configuration table, otherwise the device tree located * at the address indicated by environment variable fdtcontroladdr will be used. * - * On architectures (x86) using ACPI tables device trees shall not be installed - * as configuration table. + * On architectures using ACPI tables device trees shall not be installed as + * configuration table. * - * @fdt_opt: pointer to argument + * @fdt_addr: address of device tree or EFI_FDT_USE_INTERNAL to use the + * internal device tree as indicated by environment variable + * fdtcontroladdr * Return: status code */ -static efi_status_t efi_install_fdt(const char *fdt_opt) +static efi_status_t efi_install_fdt(uintptr_t fdt_addr) { /* * 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_opt) { + if (fdt_addr) { printf("ERROR: can't have ACPI table and device tree.\n"); return EFI_LOAD_ERROR; } #else - unsigned long fdt_addr; void *fdt; bootm_headers_t img = { 0 }; efi_status_t ret; - if (fdt_opt) { - fdt_addr = simple_strtoul(fdt_opt, NULL, 16); - if (!fdt_addr) - return EFI_INVALID_PARAMETER; - } else { + if (fdt_addr == EFI_FDT_USE_INTERNAL) { + const char *fdt_opt; + /* Look for device tree that is already installed */ if (get_config_table(&efi_guid_fdt)) return EFI_SUCCESS; @@ -556,6 +555,7 @@ static int do_efi_selftest(void) static int do_bootefi(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { efi_status_t ret; + uintptr_t fdt_addr; if (argc < 2) return CMD_RET_USAGE; @@ -568,7 +568,11 @@ static int do_bootefi(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) return CMD_RET_FAILURE; } - ret = efi_install_fdt(argc > 2 ? argv[2] : NULL); + if (argc > 2) + fdt_addr = simple_strtoul(argv[2], NULL, 16); + else + fdt_addr = EFI_FDT_USE_INTERNAL; + ret = efi_install_fdt(fdt_addr); if (ret == EFI_INVALID_PARAMETER) return CMD_RET_USAGE; else if (ret != EFI_SUCCESS) -- cgit v1.3.1 From 753aa18f176af214b8f054c45f99bc20dfb15938 Mon Sep 17 00:00:00 2001 From: Heinrich Schuchardt Date: Wed, 4 Dec 2019 12:31:12 +0100 Subject: efi_loader: use hardware device tree by default If the bootefi command is called without passing the address of a device tree, the internal device tree is used. For devices with a hardware device tree it is preferable to used the hardware device tree in this case. Signed-off-by: Heinrich Schuchardt --- cmd/bootefi.c | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) (limited to 'cmd') diff --git a/cmd/bootefi.c b/cmd/bootefi.c index 2b190a3edda..a3e2a051263 100644 --- a/cmd/bootefi.c +++ b/cmd/bootefi.c @@ -200,14 +200,16 @@ static void *get_config_table(const efi_guid_t *guid) * * If fdt_addr is available, the device tree located at that memory address will * will be installed as configuration table, otherwise the device tree located - * at the address indicated by environment variable fdtcontroladdr will be used. + * at the address indicated by environment variable fdt_addr or as fallback + * fdtcontroladdr will be used. * * On architectures using ACPI tables device trees shall not be installed as * configuration table. * * @fdt_addr: address of device tree or EFI_FDT_USE_INTERNAL to use the - * internal device tree as indicated by environment variable - * fdtcontroladdr + * the hardware device tree as indicated by environment variable + * fdt_addr or as fallback the internal device tree as indicated by + * the environment variable fdtcontroladdr * Return: status code */ static efi_status_t efi_install_fdt(uintptr_t fdt_addr) @@ -232,15 +234,19 @@ static efi_status_t efi_install_fdt(uintptr_t fdt_addr) /* Look for device tree that is already installed */ if (get_config_table(&efi_guid_fdt)) return EFI_SUCCESS; - /* Use our own device tree as default */ - fdt_opt = env_get("fdtcontroladdr"); + /* Check if there is a hardware device tree */ + fdt_opt = env_get("fdt_addr"); + /* Use our own device tree as fallback */ if (!fdt_opt) { - printf("ERROR: need device tree\n"); - return EFI_NOT_FOUND; + fdt_opt = env_get("fdtcontroladdr"); + if (!fdt_opt) { + printf("ERROR: need device tree\n"); + return EFI_NOT_FOUND; + } } fdt_addr = simple_strtoul(fdt_opt, NULL, 16); if (!fdt_addr) { - printf("ERROR: invalid $fdtcontroladdr\n"); + printf("ERROR: invalid $fdt_addr or $fdtcontroladdr\n"); return EFI_LOAD_ERROR; } } -- cgit v1.3.1 From f9ceb6ac1443b824e94a9df9ec1dfb2bc742e451 Mon Sep 17 00:00:00 2001 From: Heinrich Schuchardt Date: Sat, 7 Dec 2019 20:51:06 +0100 Subject: efi_loader: carve out efi_run_image() Provide public function efi_run_imager() which can be used to run an UEFI image from memory. Signed-off-by: Heinrich Schuchardt --- cmd/bootefi.c | 51 ++++++++++++++++++++++++++++++++------------------- include/efi_loader.h | 2 ++ 2 files changed, 34 insertions(+), 19 deletions(-) (limited to 'cmd') diff --git a/cmd/bootefi.c b/cmd/bootefi.c index a3e2a051263..15b4ff95159 100644 --- a/cmd/bootefi.c +++ b/cmd/bootefi.c @@ -360,11 +360,8 @@ static int do_efibootmgr(void) static int do_bootefi_image(const char *image_opt) { void *image_buf; - struct efi_device_path *device_path, *image_path; - struct efi_device_path *file_path = NULL; unsigned long addr, size; const char *size_str; - efi_handle_t mem_handle = NULL, handle; efi_status_t ret; #ifdef CONFIG_CMD_BOOTEFI_HELLO @@ -382,8 +379,10 @@ static int do_bootefi_image(const char *image_opt) image_buf = map_sysmem(addr, size); memcpy(image_buf, __efi_helloworld_begin, size); - device_path = NULL; - image_path = NULL; + efi_free_pool(bootefi_device_path); + efi_free_pool(bootefi_image_path); + bootefi_device_path = NULL; + bootefi_image_path = NULL; } else #endif { @@ -399,19 +398,37 @@ static int do_bootefi_image(const char *image_opt) return CMD_RET_USAGE; image_buf = map_sysmem(addr, size); - - device_path = bootefi_device_path; - image_path = bootefi_image_path; } + ret = efi_run_image(image_buf, size); + + if (ret != EFI_SUCCESS) + return CMD_RET_FAILURE; + + return CMD_RET_SUCCESS; +} + +/** + * efi_run_image() - run loaded UEFI image + * + * @source_buffer: memory address of the UEFI image + * @source_size: size of the UEFI image + * Return: status code + */ +efi_status_t efi_run_image(void *source_buffer, efi_uintn_t source_size) +{ + efi_handle_t mem_handle = NULL, handle; + struct efi_device_path *file_path = NULL; + efi_status_t ret; - if (!device_path && !image_path) { + if (!bootefi_device_path || !bootefi_image_path) { /* * Special case for efi payload not loaded from disk, * such as 'bootefi hello' or for example payload * loaded directly into memory via JTAG, etc: */ file_path = efi_dp_from_mem(EFI_RESERVED_MEMORY_TYPE, - (uintptr_t)image_buf, size); + (uintptr_t)source_buffer, + source_size); /* * Make sure that device for device_path exist * in load_image(). Otherwise, shell and grub will fail. @@ -425,12 +442,12 @@ static int do_bootefi_image(const char *image_opt) if (ret != EFI_SUCCESS) goto out; } else { - assert(device_path && image_path); - file_path = efi_dp_append(device_path, image_path); + file_path = efi_dp_append(bootefi_device_path, + bootefi_image_path); } - ret = EFI_CALL(efi_load_image(false, efi_root, - file_path, image_buf, size, &handle)); + ret = EFI_CALL(efi_load_image(false, efi_root, file_path, source_buffer, + source_size, &handle)); if (ret != EFI_SUCCESS) goto out; @@ -441,11 +458,7 @@ out: efi_delete_handle(mem_handle); if (file_path) efi_free_pool(file_path); - - if (ret != EFI_SUCCESS) - return CMD_RET_FAILURE; - - return CMD_RET_SUCCESS; + return ret; } #ifdef CONFIG_CMD_BOOTEFI_SELFTEST diff --git a/include/efi_loader.h b/include/efi_loader.h index 3a220893298..1e1fe52bc0f 100644 --- a/include/efi_loader.h +++ b/include/efi_loader.h @@ -341,6 +341,8 @@ extern struct list_head efi_register_notify_events; /* Initialize efi execution environment */ efi_status_t efi_init_obj_list(void); +/* Run loaded UEFI image */ +efi_status_t efi_run_image(void *source_buffer, efi_uintn_t source_size); /* Initialize variable services */ efi_status_t efi_init_variables(void); /* Notify ExitBootServices() is called */ -- cgit v1.3.1 From f64f223256f32e86d97ec32eea7dc36d5e9c5fd9 Mon Sep 17 00:00:00 2001 From: Heinrich Schuchardt Date: Sun, 8 Dec 2019 01:07:01 +0100 Subject: efi_loader: export efi_install_fdt() Use a pointer to addressable memory instead of a "physical" address in the virtual address space of the sandbox to efi_install_fdt(). Export the efi_install_fdt() function. Signed-off-by: Heinrich Schuchardt --- cmd/bootefi.c | 24 ++++++++++++++---------- include/efi_loader.h | 4 +++- 2 files changed, 17 insertions(+), 11 deletions(-) (limited to 'cmd') diff --git a/cmd/bootefi.c b/cmd/bootefi.c index 15b4ff95159..78c8b8dbd16 100644 --- a/cmd/bootefi.c +++ b/cmd/bootefi.c @@ -212,24 +212,24 @@ static void *get_config_table(const efi_guid_t *guid) * the environment variable fdtcontroladdr * Return: status code */ -static efi_status_t efi_install_fdt(uintptr_t fdt_addr) +efi_status_t efi_install_fdt(void *fdt) { /* * 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_addr) { + if (fdt) { printf("ERROR: can't have ACPI table and device tree.\n"); return EFI_LOAD_ERROR; } #else - void *fdt; bootm_headers_t img = { 0 }; efi_status_t ret; - if (fdt_addr == EFI_FDT_USE_INTERNAL) { + if (fdt == EFI_FDT_USE_INTERNAL) { const char *fdt_opt; + uintptr_t fdt_addr; /* Look for device tree that is already installed */ if (get_config_table(&efi_guid_fdt)) @@ -249,10 +249,10 @@ static efi_status_t efi_install_fdt(uintptr_t fdt_addr) printf("ERROR: invalid $fdt_addr or $fdtcontroladdr\n"); return EFI_LOAD_ERROR; } + fdt = map_sysmem(fdt_addr, 0); } /* Install device tree */ - fdt = map_sysmem(fdt_addr, 0); if (fdt_check_header(fdt)) { printf("ERROR: invalid device tree\n"); return EFI_LOAD_ERROR; @@ -574,7 +574,7 @@ static int do_efi_selftest(void) static int do_bootefi(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { efi_status_t ret; - uintptr_t fdt_addr; + void *fdt; if (argc < 2) return CMD_RET_USAGE; @@ -587,11 +587,15 @@ static int do_bootefi(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) return CMD_RET_FAILURE; } - if (argc > 2) + if (argc > 2) { + uintptr_t fdt_addr; + fdt_addr = simple_strtoul(argv[2], NULL, 16); - else - fdt_addr = EFI_FDT_USE_INTERNAL; - ret = efi_install_fdt(fdt_addr); + fdt = map_sysmem(fdt_addr, 0); + } else { + fdt = EFI_FDT_USE_INTERNAL; + } + ret = efi_install_fdt(fdt); if (ret == EFI_INVALID_PARAMETER) return CMD_RET_USAGE; else if (ret != EFI_SUCCESS) diff --git a/include/efi_loader.h b/include/efi_loader.h index 1e1fe52bc0f..4d401f69d75 100644 --- a/include/efi_loader.h +++ b/include/efi_loader.h @@ -35,7 +35,7 @@ static inline int guidcmp(const void *g1, const void *g2) 0x9a, 0xab, 0x3a, 0x7d, 0xbf, 0x40, 0xc4, 0x82) /* Use internal device tree when starting UEFI application */ -#define EFI_FDT_USE_INTERNAL 0UL +#define EFI_FDT_USE_INTERNAL NULL /* Root node */ extern efi_handle_t efi_root; @@ -341,6 +341,8 @@ extern struct list_head efi_register_notify_events; /* Initialize efi execution environment */ efi_status_t efi_init_obj_list(void); +/* Install device tree */ +efi_status_t efi_install_fdt(void *fdt); /* Run loaded UEFI image */ efi_status_t efi_run_image(void *source_buffer, efi_uintn_t source_size); /* Initialize variable services */ -- cgit v1.3.1 From a3850e40e1bd64f99f91960953003ca31ee6fd0b Mon Sep 17 00:00:00 2001 From: Heinrich Schuchardt Date: Fri, 3 Jan 2020 22:53:42 +0100 Subject: efi_loader: free load options after execution When be launch a binary via bootefi the bootargs environment variable is used to set the load options in the loaded image protocol. Free memory allocated for load options when the UEFI binary exits. Signed-off-by: Heinrich Schuchardt --- cmd/bootefi.c | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) (limited to 'cmd') diff --git a/cmd/bootefi.c b/cmd/bootefi.c index 78c8b8dbd16..56bdff33c64 100644 --- a/cmd/bootefi.c +++ b/cmd/bootefi.c @@ -28,11 +28,13 @@ static struct efi_device_path *bootefi_device_path; /** * Set the load options of an image from an environment variable. * - * @handle: the image handle - * @env_var: name of the environment variable - * Return: status code + * @handle: the image handle + * @env_var: name of the environment variable + * @load_options: pointer to load options (output) + * Return: status code */ -static efi_status_t set_load_options(efi_handle_t handle, const char *env_var) +static efi_status_t set_load_options(efi_handle_t handle, const char *env_var, + u16 **load_options) { struct efi_loaded_image *loaded_image_info; size_t size; @@ -40,6 +42,7 @@ static efi_status_t set_load_options(efi_handle_t handle, const char *env_var) u16 *pos; efi_status_t ret; + *load_options = NULL; ret = EFI_CALL(systab.boottime->open_protocol( handle, &efi_guid_loaded_image, @@ -64,6 +67,7 @@ static efi_status_t set_load_options(efi_handle_t handle, const char *env_var) return EFI_OUT_OF_RESOURCES; } pos = loaded_image_info->load_options; + *load_options = pos; utf8_utf16_strcpy(&pos, env); loaded_image_info->load_options_size = size * 2; @@ -298,9 +302,10 @@ static efi_status_t do_bootefi_exec(efi_handle_t handle) efi_status_t ret; efi_uintn_t exit_data_size = 0; u16 *exit_data = NULL; + u16 *load_options; /* Transfer environment variable as load options */ - ret = set_load_options(handle, "bootargs"); + ret = set_load_options(handle, "bootargs", &load_options); if (ret != EFI_SUCCESS) return ret; @@ -314,12 +319,7 @@ static efi_status_t do_bootefi_exec(efi_handle_t handle) efi_restore_gd(); - /* - * FIXME: Who is responsible for - * free(loaded_image_info->load_options); - * Once efi_exit() is implemented correctly, - * handle itself doesn't exist here. - */ + free(load_options); return ret; } @@ -469,6 +469,7 @@ static efi_status_t bootefi_run_prepare(const char *load_options_path, struct efi_loaded_image **loaded_image_infop) { efi_status_t ret; + u16 *load_options; ret = efi_setup_loaded_image(device_path, image_path, image_objp, loaded_image_infop); @@ -476,7 +477,8 @@ static efi_status_t bootefi_run_prepare(const char *load_options_path, return ret; /* Transfer environment variable as load options */ - return set_load_options((efi_handle_t)*image_objp, load_options_path); + return set_load_options((efi_handle_t)*image_objp, load_options_path, + &load_options); } /** -- cgit v1.3.1 From 173cd9e73ad833bf479cc5b400de5ca738ef7510 Mon Sep 17 00:00:00 2001 From: Heinrich Schuchardt Date: Tue, 7 Jan 2020 06:02:33 +0100 Subject: cmd: efidebug: simplify get_guid_text() When we hit a matching GUID we can directly return the text. There is no need for a check after the loop. efi_guid_t is defined as 8 byte aligned but GUIDs in packed structures do not follow this alignment. Do not require the argument of get_guid_text() to be correctly aligned. Signed-off-by: Heinrich Schuchardt --- cmd/efidebug.c | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) (limited to 'cmd') diff --git a/cmd/efidebug.c b/cmd/efidebug.c index 1fff4390dea..45ed5be8853 100644 --- a/cmd/efidebug.c +++ b/cmd/efidebug.c @@ -254,24 +254,27 @@ static const struct { }; /** - * get_guid_text - get string of protocol guid - * @guid: Protocol guid - * Return: String + * get_guid_text - get string of GUID * - * Return string for display to represent the protocol. + * Return description of GUID. + * + * @guid: GUID + * Return: description of GUID or NULL */ -static const char *get_guid_text(const efi_guid_t *guid) +static const char *get_guid_text(const void *guid) { int i; - for (i = 0; i < ARRAY_SIZE(guid_list); i++) + for (i = 0; i < ARRAY_SIZE(guid_list); i++) { + /* + * As guidcmp uses memcmp() we can safely accept unaligned + * GUIDs. + */ if (!guidcmp(&guid_list[i].guid, guid)) - break; + return guid_list[i].text; + } - if (i != ARRAY_SIZE(guid_list)) - return guid_list[i].text; - else - return NULL; + return NULL; } /** -- cgit v1.3.1 From 986e0648840710b55a93587fc166296365e03f24 Mon Sep 17 00:00:00 2001 From: Heinrich Schuchardt Date: Tue, 7 Jan 2020 05:57:47 +0100 Subject: cmd: efidebug: new sub-command tables Provide sub-command for efidebug to list configuration tables. Signed-off-by: Heinrich Schuchardt --- cmd/efidebug.c | 47 ++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 46 insertions(+), 1 deletion(-) (limited to 'cmd') diff --git a/cmd/efidebug.c b/cmd/efidebug.c index 45ed5be8853..78fc6497827 100644 --- a/cmd/efidebug.c +++ b/cmd/efidebug.c @@ -251,6 +251,19 @@ static const struct { "PXE Base Code", EFI_PXE_BASE_CODE_PROTOCOL_GUID, }, + /* Configuration table GUIDs */ + { + "ACPI table", + EFI_ACPI_TABLE_GUID, + }, + { + "device tree", + EFI_FDT_GUID, + }, + { + "SMBIOS table", + SMBIOS_TABLE_GUID, + }, }; /** @@ -480,6 +493,34 @@ static int do_efi_show_memmap(cmd_tbl_t *cmdtp, int flag, return CMD_RET_SUCCESS; } +/** + * do_efi_show_tables() - show UEFI configuration tables + * + * @cmdtp: Command table + * @flag: Command flag + * @argc: Number of arguments + * @argv: Argument array + * Return: CMD_RET_SUCCESS on success, CMD_RET_RET_FAILURE on failure + * + * Implement efidebug "tables" sub-command. + * Show UEFI configuration tables. + */ +static int do_efi_show_tables(cmd_tbl_t *cmdtp, int flag, + int argc, char * const argv[]) +{ + efi_uintn_t i; + const char *guid_str; + + for (i = 0; i < systab.nr_tables; ++i) { + guid_str = get_guid_text(&systab.tables[i].guid); + if (!guid_str) + guid_str = ""; + printf("%pUl %s\n", &systab.tables[i].guid, guid_str); + } + + return CMD_RET_SUCCESS; +} + /** * do_efi_boot_add() - set UEFI load option * @@ -1047,6 +1088,8 @@ static cmd_tbl_t cmd_efidebug_sub[] = { "", ""), U_BOOT_CMD_MKENT(memmap, CONFIG_SYS_MAXARGS, 1, do_efi_show_memmap, "", ""), + U_BOOT_CMD_MKENT(tables, CONFIG_SYS_MAXARGS, 1, do_efi_show_tables, + "", ""), }; /** @@ -1114,7 +1157,9 @@ static char efidebug_help_text[] = "efidebug images\n" " - show loaded images\n" "efidebug memmap\n" - " - show uefi memory map\n"; + " - show uefi memory map\n" + "efidebug tables\n" + " - show UEFI configuration tables\n"; #endif U_BOOT_CMD( -- cgit v1.3.1 From 07e2fe797115b1239c513ba12caa017978322da0 Mon Sep 17 00:00:00 2001 From: Heinrich Schuchardt Date: Tue, 7 Jan 2020 07:48:15 +0100 Subject: cmd: efidebug: capitalize UEFI %s/uefi/UEFI/g Signed-off-by: Heinrich Schuchardt --- cmd/efidebug.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'cmd') diff --git a/cmd/efidebug.c b/cmd/efidebug.c index 78fc6497827..576e95b395d 100644 --- a/cmd/efidebug.c +++ b/cmd/efidebug.c @@ -1149,15 +1149,15 @@ static char efidebug_help_text[] = " - set/show UEFI boot order\n" "\n" "efidebug devices\n" - " - show uefi devices\n" + " - show UEFI devices\n" "efidebug drivers\n" - " - show uefi drivers\n" + " - show UEFI drivers\n" "efidebug dh\n" - " - show uefi handles\n" + " - show UEFI handles\n" "efidebug images\n" " - show loaded images\n" "efidebug memmap\n" - " - show uefi memory map\n" + " - show UEFI memory map\n" "efidebug tables\n" " - show UEFI configuration tables\n"; #endif -- cgit v1.3.1 From ecc7fdaa9ef191e023fbc138e3466ccf05f6af20 Mon Sep 17 00:00:00 2001 From: Cristian Ciocaltea Date: Tue, 24 Dec 2019 18:05:39 +0200 Subject: bootm: Add a bootm command for type IH_OS_EFI Add support for booting EFI binaries contained in FIT images. A typical usage scenario is chain-loading GRUB2 in a verified boot environment. Signed-off-by: Cristian Ciocaltea Reviewed-by: Heinrich Schuchardt --- cmd/Kconfig | 7 +++++++ common/bootm_os.c | 56 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 63 insertions(+) (limited to 'cmd') diff --git a/cmd/Kconfig b/cmd/Kconfig index 4e29e7b3c54..a6bfa87e081 100644 --- a/cmd/Kconfig +++ b/cmd/Kconfig @@ -259,6 +259,13 @@ config CMD_BOOTM help Boot an application image from the memory. +config BOOTM_EFI + bool "Support booting UEFI FIT images" + depends on CMD_BOOTEFI && CMD_BOOTM && FIT + default y + help + Support booting UEFI FIT images via the bootm command. + config CMD_BOOTZ bool "bootz" help diff --git a/common/bootm_os.c b/common/bootm_os.c index d89ddc32b0d..1d58462509c 100644 --- a/common/bootm_os.c +++ b/common/bootm_os.c @@ -7,10 +7,12 @@ #include #include #include +#include #include #include #include #include +#include #include #include @@ -498,6 +500,57 @@ static int do_bootm_tee(int flag, int argc, char * const argv[], } #endif +#ifdef CONFIG_BOOTM_EFI +static int do_bootm_efi(int flag, int argc, char * const argv[], + bootm_headers_t *images) +{ + int ret; + efi_status_t efi_ret; + void *image_buf; + + if (flag != BOOTM_STATE_OS_GO) + return 0; + + /* Locate FDT, if provided */ + ret = bootm_find_images(flag, argc, argv); + if (ret) + return ret; + + /* Initialize EFI drivers */ + efi_ret = efi_init_obj_list(); + if (efi_ret != EFI_SUCCESS) { + printf("## Failed to initialize UEFI sub-system: r = %lu\n", + efi_ret & ~EFI_ERROR_MASK); + return 1; + } + + /* Install device tree */ + efi_ret = efi_install_fdt(images->ft_len + ? images->ft_addr : EFI_FDT_USE_INTERNAL); + if (efi_ret != EFI_SUCCESS) { + printf("## Failed to install device tree: r = %lu\n", + efi_ret & ~EFI_ERROR_MASK); + return 1; + } + + /* Run EFI image */ + printf("## Transferring control to EFI (at address %08lx) ...\n", + images->ep); + bootstage_mark(BOOTSTAGE_ID_RUN_OS); + + image_buf = map_sysmem(images->ep, images->os.image_len); + + efi_ret = efi_run_image(image_buf, images->os.image_len); + if (efi_ret != EFI_SUCCESS) { + printf("## Failed to run EFI image: r = %lu\n", + efi_ret & ~EFI_ERROR_MASK); + return 1; + } + + return 0; +} +#endif + static boot_os_fn *boot_os[] = { [IH_OS_U_BOOT] = do_bootm_standalone, #ifdef CONFIG_BOOTM_LINUX @@ -534,6 +587,9 @@ static boot_os_fn *boot_os[] = { #ifdef CONFIG_BOOTM_OPTEE [IH_OS_TEE] = do_bootm_tee, #endif +#ifdef CONFIG_BOOTM_EFI + [IH_OS_EFI] = do_bootm_efi, +#endif }; /* Allow for arch specific config before we boot */ -- cgit v1.3.1 From 4f24ac08afccd5f51f0b4c7023fc8cf45efe8163 Mon Sep 17 00:00:00 2001 From: Heinrich Schuchardt Date: Tue, 24 Dec 2019 22:17:37 +0100 Subject: cmd: add rng command For the RNG uclass we currently only have a test working on the sandbox. Provide a command to test the hardware random number generator on non-sandbox systems. Signed-off-by: Heinrich Schuchardt --- cmd/Kconfig | 7 +++++++ cmd/Makefile | 1 + cmd/rng.c | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 64 insertions(+) create mode 100644 cmd/rng.c (limited to 'cmd') diff --git a/cmd/Kconfig b/cmd/Kconfig index a6bfa87e081..7a78343e6b3 100644 --- a/cmd/Kconfig +++ b/cmd/Kconfig @@ -1672,6 +1672,13 @@ config CMD_GETTIME milliseconds. See also the 'bootstage' command which provides more flexibility for boot timing. +config CMD_RNG + bool "rng command" + depends on DM_RNG + select HEXDUMP + help + Print bytes from the hardware random number generator. + # TODO: rename to CMD_SLEEP config CMD_MISC bool "sleep" diff --git a/cmd/Makefile b/cmd/Makefile index 12e898d9620..8df39f3a19f 100644 --- a/cmd/Makefile +++ b/cmd/Makefile @@ -117,6 +117,7 @@ obj-$(CONFIG_CMD_READ) += read.o obj-$(CONFIG_CMD_REGINFO) += reginfo.o obj-$(CONFIG_CMD_REISER) += reiser.o obj-$(CONFIG_CMD_REMOTEPROC) += remoteproc.o +obj-$(CONFIG_CMD_RNG) += rng.o obj-$(CONFIG_CMD_ROCKUSB) += rockusb.o obj-$(CONFIG_SANDBOX) += host.o obj-$(CONFIG_CMD_SATA) += sata.o diff --git a/cmd/rng.c b/cmd/rng.c new file mode 100644 index 00000000000..36ca7a101c1 --- /dev/null +++ b/cmd/rng.c @@ -0,0 +1,56 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * The 'rng' command prints bytes from the hardware random number generator. + * + * Copyright (c) 2019, Heinrich Schuchardt + */ +#include +#include +#include +#include +#include + +static int do_rng(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +{ + size_t n = 0x40; + struct udevice *dev; + void *buf; + int ret = CMD_RET_SUCCESS; + + if (uclass_get_device(UCLASS_RNG, 0, &dev) || !dev) { + printf("No RNG device\n"); + return CMD_RET_FAILURE; + } + + if (argc >= 2) + n = simple_strtoul(argv[1], NULL, 16); + + buf = malloc(n); + if (!buf) { + printf("Out of memory\n"); + return CMD_RET_FAILURE; + } + + if (dm_rng_read(dev, buf, n)) { + printf("Reading RNG failed\n"); + ret = CMD_RET_FAILURE; + } else { + print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, buf, n); + } + + free(buf); + + return ret; +} + +#ifdef CONFIG_SYS_LONGHELP +static char rng_help_text[] = + "[n]\n" + " - print n random bytes\n"; +#endif + +U_BOOT_CMD( + rng, 2, 0, do_rng, + "print bytes from the hardware random number generator", + rng_help_text +); -- cgit v1.3.1