efi_loader: Pass fdt address directly to bootefi cmd

The bootefi cmd today fetches its device tree pointer from either the
location appointed by "fdt addr" with a fallback to the U-Boot control
fdt.

This integration is unusual for U-Boot and diverges from the way we
usually handle parameters to boot commands. So let's pass the fdt
directly into the bootefi command instead and move the control fdt
logic into the distro boot script.

Signed-off-by: Alexander Graf <agraf@suse.de>
Acked-by: Stephen Warren <swarren@wwwdotorg.org>
Reviewed-by: Andreas Färber <afaerber@suse.de>
This commit is contained in:
Alexander Graf 2016-04-14 16:07:53 +02:00 committed by Tom Rini
parent 0c4b3880c1
commit 1c39809b92
2 changed files with 22 additions and 23 deletions

View file

@ -142,12 +142,11 @@ static void *copy_fdt(void *fdt)
* Load an EFI payload into a newly allocated piece of memory, register all * Load an EFI payload into a newly allocated piece of memory, register all
* EFI objects it would want to access and jump to it. * EFI objects it would want to access and jump to it.
*/ */
static unsigned long do_bootefi_exec(void *efi) static unsigned long do_bootefi_exec(void *efi, void *fdt)
{ {
ulong (*entry)(void *image_handle, struct efi_system_table *st); ulong (*entry)(void *image_handle, struct efi_system_table *st);
ulong fdt_pages, fdt_size, fdt_start, fdt_end; ulong fdt_pages, fdt_size, fdt_start, fdt_end;
bootm_headers_t img = { 0 }; bootm_headers_t img = { 0 };
void *fdt = working_fdt;
/* /*
* gd lives in a fixed register which may get clobbered while we execute * gd lives in a fixed register which may get clobbered while we execute
@ -155,13 +154,7 @@ static unsigned long do_bootefi_exec(void *efi)
*/ */
efi_save_gd(); efi_save_gd();
/* Update system table to point to our currently loaded FDT */ if (fdt && !fdt_check_header(fdt)) {
/* Fall back to included fdt if none was manually loaded */
if (!fdt && gd->fdt_blob)
fdt = (void *)gd->fdt_blob;
if (fdt) {
/* Prepare fdt for payload */ /* Prepare fdt for payload */
fdt = copy_fdt(fdt); fdt = copy_fdt(fdt);
@ -185,7 +178,7 @@ static unsigned long do_bootefi_exec(void *efi)
efi_add_memory_map(fdt_start, fdt_pages, efi_add_memory_map(fdt_start, fdt_pages,
EFI_BOOT_SERVICES_DATA, true); EFI_BOOT_SERVICES_DATA, true);
} else { } else {
printf("WARNING: No device tree loaded, expect boot to fail\n"); printf("WARNING: Invalid device tree, expect boot to fail\n");
systab.nr_tables = 0; systab.nr_tables = 0;
} }
@ -216,8 +209,8 @@ static unsigned long do_bootefi_exec(void *efi)
/* Interpreter command to boot an arbitrary EFI image from memory */ /* Interpreter command to boot an arbitrary EFI image from memory */
static int do_bootefi(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) static int do_bootefi(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{ {
char *saddr; char *saddr, *sfdt;
unsigned long addr; unsigned long addr, fdt_addr = 0;
int r = 0; int r = 0;
if (argc < 2) if (argc < 2)
@ -226,8 +219,13 @@ static int do_bootefi(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
addr = simple_strtoul(saddr, NULL, 16); addr = simple_strtoul(saddr, NULL, 16);
if (argc > 2) {
sfdt = argv[2];
fdt_addr = simple_strtoul(sfdt, NULL, 16);
}
printf("## Starting EFI application at 0x%08lx ...\n", addr); printf("## Starting EFI application at 0x%08lx ...\n", addr);
r = do_bootefi_exec((void *)addr); r = do_bootefi_exec((void *)addr, (void*)fdt_addr);
printf("## Application terminated, r = %d\n", r); printf("## Application terminated, r = %d\n", r);
if (r != 0) if (r != 0)
@ -238,16 +236,14 @@ static int do_bootefi(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
#ifdef CONFIG_SYS_LONGHELP #ifdef CONFIG_SYS_LONGHELP
static char bootefi_help_text[] = static char bootefi_help_text[] =
"<image address>\n" "<image address> [fdt address]\n"
" - boot EFI payload stored at address <image address>\n" " - boot EFI payload stored at address <image address>.\n"
"\n" " If specified, the device tree located at <fdt address> gets\n"
"Since most EFI payloads want to have a device tree provided, please\n" " exposed as EFI configuration table.\n";
"make sure you load a device tree using the fdt addr command before\n"
"executing bootefi.\n";
#endif #endif
U_BOOT_CMD( U_BOOT_CMD(
bootefi, 2, 0, do_bootefi, bootefi, 3, 0, do_bootefi,
"Boots an EFI payload from memory\n", "Boots an EFI payload from memory\n",
bootefi_help_text bootefi_help_text
); );

View file

@ -103,12 +103,15 @@
"boot_efi_binary=" \ "boot_efi_binary=" \
"load ${devtype} ${devnum}:${distro_bootpart} " \ "load ${devtype} ${devnum}:${distro_bootpart} " \
"${kernel_addr_r} efi/boot/"BOOTEFI_NAME"; " \ "${kernel_addr_r} efi/boot/"BOOTEFI_NAME"; " \
"bootefi ${kernel_addr_r}\0" \ "if fdt addr ${fdt_addr_r}; then " \
"bootefi ${kernel_addr_r} ${fdt_addr_r};" \
"else" \
"bootefi ${kernel_addr_r} ${fdtcontroladdr};" \
"fi\0" \
\ \
"load_efi_dtb=" \ "load_efi_dtb=" \
"load ${devtype} ${devnum}:${distro_bootpart} " \ "load ${devtype} ${devnum}:${distro_bootpart} " \
"${fdt_addr_r} ${prefix}${fdtfile}; " \ "${fdt_addr_r} ${prefix}${fdtfile}\0" \
"fdt addr ${fdt_addr_r}\0" \
\ \
"efi_dtb_prefixes=/ /dtb/ /dtb/current/\0" \ "efi_dtb_prefixes=/ /dtb/ /dtb/current/\0" \
"scan_dev_for_efi=" \ "scan_dev_for_efi=" \