Merge patch series "bootflow: bootmeth_efi: Fix network efi boot."

To quote the author:

Currently bootmeth_efi crashes while doing a network (dhcp) boot.
This patch series fixes issues and both network and disk boot works.

# Do not modify or remove the line above.
# Everything below it will be ignored.
#
# Please enter a commit message to explain why this merge is necessary,
# especially if it merges an updated upstream into a topic branch.
#
# An empty message aborts the commit.
This commit is contained in:
Tom Rini 2023-12-09 13:16:14 -05:00
commit dd29208815
2 changed files with 29 additions and 9 deletions

View File

@ -160,7 +160,6 @@ static int efiload_read_file(struct bootflow *bflow, ulong addr)
if (ret) if (ret)
return log_msg_ret("read", ret); return log_msg_ret("read", ret);
bflow->buf = map_sysmem(addr, bflow->size); bflow->buf = map_sysmem(addr, bflow->size);
bflow->flags |= BOOTFLOWF_STATIC_BUF;
set_efi_bootdev(desc, bflow); set_efi_bootdev(desc, bflow);
@ -313,6 +312,7 @@ static int distro_efi_try_bootflow_files(struct udevice *dev,
*/ */
} else { } else {
log_debug("No device tree available\n"); log_debug("No device tree available\n");
bflow->flags |= BOOTFLOWF_USE_BUILTIN_FDT;
} }
return 0; return 0;
@ -323,7 +323,7 @@ static int distro_efi_read_bootflow_net(struct bootflow *bflow)
char file_addr[17], fname[256]; char file_addr[17], fname[256];
char *tftp_argv[] = {"tftp", file_addr, fname, NULL}; char *tftp_argv[] = {"tftp", file_addr, fname, NULL};
struct cmd_tbl cmdtp = {}; /* dummy */ struct cmd_tbl cmdtp = {}; /* dummy */
const char *addr_str, *fdt_addr_str; const char *addr_str, *fdt_addr_str, *bootfile_name;
int ret, arch, size; int ret, arch, size;
ulong addr, fdt_addr; ulong addr, fdt_addr;
char str[36]; char str[36];
@ -339,7 +339,7 @@ static int distro_efi_read_bootflow_net(struct bootflow *bflow)
ret = env_set("bootp_vci", str); ret = env_set("bootp_vci", str);
if (ret) if (ret)
return log_msg_ret("vcs", ret); return log_msg_ret("vcs", ret);
ret = env_set_ulong("bootp_arch", arch); ret = env_set_hex("bootp_arch", arch);
if (ret) if (ret)
return log_msg_ret("ars", ret); return log_msg_ret("ars", ret);
@ -360,6 +360,12 @@ static int distro_efi_read_bootflow_net(struct bootflow *bflow)
return log_msg_ret("sz", -EINVAL); return log_msg_ret("sz", -EINVAL);
bflow->size = size; bflow->size = size;
/* bootfile should be setup by dhcp*/
bootfile_name = env_get("bootfile");
if (!bootfile_name)
return log_msg_ret("bootfile_name", ret);
bflow->fname = strdup(bootfile_name);
/* do the hideous EFI hack */ /* do the hideous EFI hack */
efi_set_bootdev("Net", "", bflow->fname, map_sysmem(addr, 0), efi_set_bootdev("Net", "", bflow->fname, map_sysmem(addr, 0),
bflow->size); bflow->size);
@ -385,6 +391,7 @@ static int distro_efi_read_bootflow_net(struct bootflow *bflow)
bflow->fdt_addr = fdt_addr; bflow->fdt_addr = fdt_addr;
} else { } else {
log_debug("No device tree available\n"); log_debug("No device tree available\n");
bflow->flags |= BOOTFLOWF_USE_BUILTIN_FDT;
} }
bflow->state = BOOTFLOWST_READY; bflow->state = BOOTFLOWST_READY;
@ -396,6 +403,12 @@ static int distro_efi_read_bootflow(struct udevice *dev, struct bootflow *bflow)
{ {
int ret; int ret;
/*
* bootmeth_efi doesn't allocate any buffer neither for blk nor net device
* set flag to avoid freeing static buffer.
*/
bflow->flags |= BOOTFLOWF_STATIC_BUF;
if (bootmeth_uses_network(bflow)) { if (bootmeth_uses_network(bflow)) {
/* we only support reading from one device, so ignore 'dev' */ /* we only support reading from one device, so ignore 'dev' */
ret = distro_efi_read_bootflow_net(bflow); ret = distro_efi_read_bootflow_net(bflow);
@ -423,13 +436,11 @@ static int distro_efi_boot(struct udevice *dev, struct bootflow *bflow)
return log_msg_ret("read", ret); return log_msg_ret("read", ret);
/* /*
* use the provided device tree if available, else fall back to * use the provided device tree if not using the built-in fdt
* the control FDT
*/ */
if (bflow->fdt_fname) if (bflow->flags & ~BOOTFLOWF_USE_BUILTIN_FDT)
fdt = bflow->fdt_addr; fdt = bflow->fdt_addr;
else
fdt = (ulong)map_to_sysmem(gd->fdt_blob);
} else { } else {
/* /*
* This doesn't actually work for network devices: * This doesn't actually work for network devices:
@ -446,7 +457,14 @@ static int distro_efi_boot(struct udevice *dev, struct bootflow *bflow)
* At some point we can add a real interface to bootefi so we can call * At some point we can add a real interface to bootefi so we can call
* this directly. For now, go through the CLI, like distro boot. * this directly. For now, go through the CLI, like distro boot.
*/ */
snprintf(cmd, sizeof(cmd), "bootefi %lx %lx", kernel, fdt); if (bflow->flags & BOOTFLOWF_USE_BUILTIN_FDT) {
log_debug("Booting with built-in fdt\n");
snprintf(cmd, sizeof(cmd), "bootefi %lx", kernel);
} else {
log_debug("Booting with external fdt\n");
snprintf(cmd, sizeof(cmd), "bootefi %lx %lx", kernel, fdt);
}
if (run_command(cmd, 0)) if (run_command(cmd, 0))
return log_msg_ret("run", -EINVAL); return log_msg_ret("run", -EINVAL);

View File

@ -45,10 +45,12 @@ enum bootflow_state_t {
* CONFIG_OF_HAS_PRIOR_STAGE is enabled * CONFIG_OF_HAS_PRIOR_STAGE is enabled
* @BOOTFLOWF_STATIC_BUF: Indicates that @bflow->buf is statically set, rather * @BOOTFLOWF_STATIC_BUF: Indicates that @bflow->buf is statically set, rather
* than being allocated by malloc(). * than being allocated by malloc().
* @BOOTFLOWF_USE_BUILTIN_FDT : Indicates that current bootflow uses built-in FDT
*/ */
enum bootflow_flags_t { enum bootflow_flags_t {
BOOTFLOWF_USE_PRIOR_FDT = 1 << 0, BOOTFLOWF_USE_PRIOR_FDT = 1 << 0,
BOOTFLOWF_STATIC_BUF = 1 << 1, BOOTFLOWF_STATIC_BUF = 1 << 1,
BOOTFLOWF_USE_BUILTIN_FDT = 1 << 2,
}; };
/** /**