diff mbox series

[v3,03/18] pxe: Use a context pointer

Message ID 20211014184811.482560-4-sjg@chromium.org
State Accepted
Delegated to: Tom Rini
Headers show
Series pxe: Refactoring to tidy up and prepare for bootflow | expand

Commit Message

Simon Glass Oct. 14, 2021, 6:47 p.m. UTC
At present the PXE functions pass around a pointer to command-table entry
which is very strange. It is only needed in a few places and it is odd to
pass around a data structure from another module in this way.

For bootmethod we will need to provide some context information when
reading files.

Create a PXE context struct to hold the command-table-entry pointer and
pass that around instead. We can then add more things to the context as
needed.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

(no changes since v1)

 cmd/pxe.c       | 28 +++++++++--------
 cmd/pxe_utils.c | 80 ++++++++++++++++++++++++++-----------------------
 cmd/pxe_utils.h | 43 +++++++++++++++++++-------
 cmd/sysboot.c   |  8 +++--
 4 files changed, 97 insertions(+), 62 deletions(-)

Comments

Art Nikpal Oct. 18, 2021, 8:45 a.m. UTC | #1
OK nice

Reviewed and Tested on -master Mon 18 Oct 2021 04:40:29 PM CST
Reviewed-by: Artem Lapkin <email2tema@gmail.com>
Tested-by:  Artem Lapkin <email2tema@gmail.com>
Ramon Fried Nov. 9, 2021, 8:08 a.m. UTC | #2
On Thu, Oct 14, 2021 at 9:49 PM Simon Glass <sjg@chromium.org> wrote:
>
> At present the PXE functions pass around a pointer to command-table entry
> which is very strange. It is only needed in a few places and it is odd to
> pass around a data structure from another module in this way.
>
> For bootmethod we will need to provide some context information when
> reading files.
>
> Create a PXE context struct to hold the command-table-entry pointer and
> pass that around instead. We can then add more things to the context as
> needed.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
>
> (no changes since v1)
>
>  cmd/pxe.c       | 28 +++++++++--------
>  cmd/pxe_utils.c | 80 ++++++++++++++++++++++++++-----------------------
>  cmd/pxe_utils.h | 43 +++++++++++++++++++-------
>  cmd/sysboot.c   |  8 +++--
>  4 files changed, 97 insertions(+), 62 deletions(-)
>
> diff --git a/cmd/pxe.c b/cmd/pxe.c
> index 46ac08fa3a0..17ce54fc049 100644
> --- a/cmd/pxe.c
> +++ b/cmd/pxe.c
> @@ -43,7 +43,7 @@ static int do_get_tftp(struct cmd_tbl *cmdtp, const char *file_path,
>   *
>   * Returns 1 on success or < 0 on error.
>   */
> -static int pxe_uuid_path(struct cmd_tbl *cmdtp, unsigned long pxefile_addr_r)
> +static int pxe_uuid_path(struct pxe_context *ctx, unsigned long pxefile_addr_r)
>  {
>         char *uuid_str;
>
> @@ -52,7 +52,7 @@ static int pxe_uuid_path(struct cmd_tbl *cmdtp, unsigned long pxefile_addr_r)
>         if (!uuid_str)
>                 return -ENOENT;
>
> -       return get_pxelinux_path(cmdtp, uuid_str, pxefile_addr_r);
> +       return get_pxelinux_path(ctx, uuid_str, pxefile_addr_r);
>  }
>
>  /*
> @@ -61,7 +61,7 @@ static int pxe_uuid_path(struct cmd_tbl *cmdtp, unsigned long pxefile_addr_r)
>   *
>   * Returns 1 on success or < 0 on error.
>   */
> -static int pxe_mac_path(struct cmd_tbl *cmdtp, unsigned long pxefile_addr_r)
> +static int pxe_mac_path(struct pxe_context *ctx, unsigned long pxefile_addr_r)
>  {
>         char mac_str[21];
>         int err;
> @@ -71,7 +71,7 @@ static int pxe_mac_path(struct cmd_tbl *cmdtp, unsigned long pxefile_addr_r)
>         if (err < 0)
>                 return err;
>
> -       return get_pxelinux_path(cmdtp, mac_str, pxefile_addr_r);
> +       return get_pxelinux_path(ctx, mac_str, pxefile_addr_r);
>  }
>
>  /*
> @@ -81,7 +81,7 @@ static int pxe_mac_path(struct cmd_tbl *cmdtp, unsigned long pxefile_addr_r)
>   *
>   * Returns 1 on success or < 0 on error.
>   */
> -static int pxe_ipaddr_paths(struct cmd_tbl *cmdtp, unsigned long pxefile_addr_r)
> +static int pxe_ipaddr_paths(struct pxe_context *ctx, unsigned long pxefile_addr_r)
>  {
>         char ip_addr[9];
>         int mask_pos, err;
> @@ -89,7 +89,7 @@ static int pxe_ipaddr_paths(struct cmd_tbl *cmdtp, unsigned long pxefile_addr_r)
>         sprintf(ip_addr, "%08X", ntohl(net_ip.s_addr));
>
>         for (mask_pos = 7; mask_pos >= 0;  mask_pos--) {
> -               err = get_pxelinux_path(cmdtp, ip_addr, pxefile_addr_r);
> +               err = get_pxelinux_path(ctx, ip_addr, pxefile_addr_r);
>
>                 if (err > 0)
>                         return err;
> @@ -118,8 +118,10 @@ do_pxe_get(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
>  {
>         char *pxefile_addr_str;
>         unsigned long pxefile_addr_r;
> +       struct pxe_context ctx;
>         int err, i = 0;
>
> +       pxe_setup_ctx(&ctx, cmdtp);
>         do_getfile = do_get_tftp;
>
>         if (argc != 1)
> @@ -139,16 +141,16 @@ do_pxe_get(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
>          * Keep trying paths until we successfully get a file we're looking
>          * for.
>          */
> -       if (pxe_uuid_path(cmdtp, pxefile_addr_r) > 0 ||
> -           pxe_mac_path(cmdtp, pxefile_addr_r) > 0 ||
> -           pxe_ipaddr_paths(cmdtp, pxefile_addr_r) > 0) {
> +       if (pxe_uuid_path(&ctx, pxefile_addr_r) > 0 ||
> +           pxe_mac_path(&ctx, pxefile_addr_r) > 0 ||
> +           pxe_ipaddr_paths(&ctx, pxefile_addr_r) > 0) {
>                 printf("Config file found\n");
>
>                 return 0;
>         }
>
>         while (pxe_default_paths[i]) {
> -               if (get_pxelinux_path(cmdtp, pxe_default_paths[i],
> +               if (get_pxelinux_path(&ctx, pxe_default_paths[i],
>                                       pxefile_addr_r) > 0) {
>                         printf("Config file found\n");
>                         return 0;
> @@ -172,7 +174,9 @@ do_pxe_boot(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
>         unsigned long pxefile_addr_r;
>         struct pxe_menu *cfg;
>         char *pxefile_addr_str;
> +       struct pxe_context ctx;
>
> +       pxe_setup_ctx(&ctx, cmdtp);
>         do_getfile = do_get_tftp;
>
>         if (argc == 1) {
> @@ -191,14 +195,14 @@ do_pxe_boot(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
>                 return 1;
>         }
>
> -       cfg = parse_pxefile(cmdtp, pxefile_addr_r);
> +       cfg = parse_pxefile(&ctx, pxefile_addr_r);
>
>         if (!cfg) {
>                 printf("Error parsing config file\n");
>                 return 1;
>         }
>
> -       handle_pxe_menu(cmdtp, cfg);
> +       handle_pxe_menu(&ctx, cfg);
>
>         destroy_pxe_menu(cfg);
>
> diff --git a/cmd/pxe_utils.c b/cmd/pxe_utils.c
> index d7f4017efeb..280be55d9b3 100644
> --- a/cmd/pxe_utils.c
> +++ b/cmd/pxe_utils.c
> @@ -105,7 +105,7 @@ int (*do_getfile)(struct cmd_tbl *cmdtp, const char *file_path,
>   *
>   * Returns 1 for success, or < 0 on error.
>   */
> -static int get_relfile(struct cmd_tbl *cmdtp, const char *file_path,
> +static int get_relfile(struct pxe_context *ctx, const char *file_path,
>                        unsigned long file_addr)
>  {
>         size_t path_len;
> @@ -133,10 +133,10 @@ static int get_relfile(struct cmd_tbl *cmdtp, const char *file_path,
>
>         sprintf(addr_buf, "%lx", file_addr);
>
> -       return do_getfile(cmdtp, relfile, addr_buf);
> +       return do_getfile(ctx->cmdtp, relfile, addr_buf);
>  }
>
> -int get_pxe_file(struct cmd_tbl *cmdtp, const char *file_path,
> +int get_pxe_file(struct pxe_context *ctx, const char *file_path,
>                  unsigned long file_addr)
>  {
>         unsigned long config_file_size;
> @@ -144,7 +144,7 @@ int get_pxe_file(struct cmd_tbl *cmdtp, const char *file_path,
>         int err;
>         char *buf;
>
> -       err = get_relfile(cmdtp, file_path, file_addr);
> +       err = get_relfile(ctx, file_path, file_addr);
>
>         if (err < 0)
>                 return err;
> @@ -170,7 +170,7 @@ int get_pxe_file(struct cmd_tbl *cmdtp, const char *file_path,
>
>  #define PXELINUX_DIR "pxelinux.cfg/"
>
> -int get_pxelinux_path(struct cmd_tbl *cmdtp, const char *file,
> +int get_pxelinux_path(struct pxe_context *ctx, const char *file,
>                       unsigned long pxefile_addr_r)
>  {
>         size_t base_len = strlen(PXELINUX_DIR);
> @@ -184,7 +184,7 @@ int get_pxelinux_path(struct cmd_tbl *cmdtp, const char *file,
>
>         sprintf(path, PXELINUX_DIR "%s", file);
>
> -       return get_pxe_file(cmdtp, path, pxefile_addr_r);
> +       return get_pxe_file(ctx, path, pxefile_addr_r);
>  }
>
>  /*
> @@ -194,7 +194,7 @@ int get_pxelinux_path(struct cmd_tbl *cmdtp, const char *file,
>   *
>   * Returns 1 on success or < 0 on error.
>   */
> -static int get_relfile_envaddr(struct cmd_tbl *cmdtp, const char *file_path,
> +static int get_relfile_envaddr(struct pxe_context *ctx, const char *file_path,
>                                const char *envaddr_name)
>  {
>         unsigned long file_addr;
> @@ -208,7 +208,7 @@ static int get_relfile_envaddr(struct cmd_tbl *cmdtp, const char *file_path,
>         if (strict_strtoul(envaddr, 16, &file_addr) < 0)
>                 return -EINVAL;
>
> -       return get_relfile(cmdtp, file_path, file_addr);
> +       return get_relfile(ctx, file_path, file_addr);
>  }
>
>  /*
> @@ -317,7 +317,8 @@ static int label_localboot(struct pxe_label *label)
>   * Loads fdt overlays specified in 'fdtoverlays'.
>   */
>  #ifdef CONFIG_OF_LIBFDT_OVERLAY
> -static void label_boot_fdtoverlay(struct cmd_tbl *cmdtp, struct pxe_label *label)
> +static void label_boot_fdtoverlay(struct pxe_context *ctx,
> +                                 struct pxe_label *label)
>  {
>         char *fdtoverlay = label->fdtoverlays;
>         struct fdt_header *working_fdt;
> @@ -367,7 +368,7 @@ static void label_boot_fdtoverlay(struct cmd_tbl *cmdtp, struct pxe_label *label
>                         goto skip_overlay;
>
>                 /* Load overlay file */
> -               err = get_relfile_envaddr(cmdtp, overlayfile,
> +               err = get_relfile_envaddr(ctx, overlayfile,
>                                           "fdtoverlay_addr_r");
>                 if (err < 0) {
>                         printf("Failed loading overlay %s\n", overlayfile);
> @@ -414,7 +415,7 @@ skip_overlay:
>   * If the label specifies an 'append' line, its contents will overwrite that
>   * of the 'bootargs' environment variable.
>   */
> -static int label_boot(struct cmd_tbl *cmdtp, struct pxe_label *label)
> +static int label_boot(struct pxe_context *ctx, struct pxe_label *label)
>  {
>         char *bootm_argv[] = { "bootm", NULL, NULL, NULL, NULL };
>         char initrd_str[28];
> @@ -443,7 +444,7 @@ static int label_boot(struct cmd_tbl *cmdtp, struct pxe_label *label)
>         }
>
>         if (label->initrd) {
> -               if (get_relfile_envaddr(cmdtp, label->initrd, "ramdisk_addr_r") < 0) {
> +               if (get_relfile_envaddr(ctx, label->initrd, "ramdisk_addr_r") < 0) {
>                         printf("Skipping %s for failure retrieving initrd\n",
>                                label->name);
>                         return 1;
> @@ -456,7 +457,7 @@ static int label_boot(struct cmd_tbl *cmdtp, struct pxe_label *label)
>                 bootm_argc = 3;
>         }
>
> -       if (get_relfile_envaddr(cmdtp, label->kernel, "kernel_addr_r") < 0) {
> +       if (get_relfile_envaddr(ctx, label->kernel, "kernel_addr_r") < 0) {
>                 printf("Skipping %s for failure retrieving kernel\n",
>                        label->name);
>                 return 1;
> @@ -596,7 +597,7 @@ static int label_boot(struct cmd_tbl *cmdtp, struct pxe_label *label)
>                 }
>
>                 if (fdtfile) {
> -                       int err = get_relfile_envaddr(cmdtp, fdtfile,
> +                       int err = get_relfile_envaddr(ctx, fdtfile,
>                                                       "fdt_addr_r");
>
>                         free(fdtfilefree);
> @@ -612,7 +613,7 @@ static int label_boot(struct cmd_tbl *cmdtp, struct pxe_label *label)
>
>  #ifdef CONFIG_OF_LIBFDT_OVERLAY
>                         if (label->fdtoverlays)
> -                               label_boot_fdtoverlay(cmdtp, label);
> +                               label_boot_fdtoverlay(ctx, label);
>  #endif
>                 } else {
>                         bootm_argv[3] = NULL;
> @@ -632,16 +633,16 @@ static int label_boot(struct cmd_tbl *cmdtp, struct pxe_label *label)
>         buf = map_sysmem(kernel_addr, 0);
>         /* Try bootm for legacy and FIT format image */
>         if (genimg_get_format(buf) != IMAGE_FORMAT_INVALID)
> -               do_bootm(cmdtp, 0, bootm_argc, bootm_argv);
> +               do_bootm(ctx->cmdtp, 0, bootm_argc, bootm_argv);
>         /* Try booting an AArch64 Linux kernel image */
>         else if (IS_ENABLED(CONFIG_CMD_BOOTI))
> -               do_booti(cmdtp, 0, bootm_argc, bootm_argv);
> +               do_booti(ctx->cmdtp, 0, bootm_argc, bootm_argv);
>         /* Try booting a Image */
>         else if (IS_ENABLED(CONFIG_CMD_BOOTZ))
> -               do_bootz(cmdtp, 0, bootm_argc, bootm_argv);
> +               do_bootz(ctx->cmdtp, 0, bootm_argc, bootm_argv);
>         /* Try booting an x86_64 Linux kernel image */
>         else if (IS_ENABLED(CONFIG_CMD_ZBOOT))
> -               do_zboot_parent(cmdtp, 0, bootm_argc, bootm_argv, NULL);
> +               do_zboot_parent(ctx->cmdtp, 0, bootm_argc, bootm_argv, NULL);
>
>         unmap_sysmem(buf);
>
> @@ -917,7 +918,7 @@ static int parse_integer(char **c, int *dst)
>         return 1;
>  }
>
> -static int parse_pxefile_top(struct cmd_tbl *cmdtp, char *p, unsigned long base,
> +static int parse_pxefile_top(struct pxe_context *ctx, char *p, ulong base,
>                              struct pxe_menu *cfg, int nest_level);
>
>  /*
> @@ -928,7 +929,7 @@ static int parse_pxefile_top(struct cmd_tbl *cmdtp, char *p, unsigned long base,
>   * include, nest_level has already been incremented and doesn't need to be
>   * incremented here.
>   */
> -static int handle_include(struct cmd_tbl *cmdtp, char **c, unsigned long base,
> +static int handle_include(struct pxe_context *ctx, char **c, unsigned long base,
>                           struct pxe_menu *cfg, int nest_level)
>  {
>         char *include_path;
> @@ -944,7 +945,7 @@ static int handle_include(struct cmd_tbl *cmdtp, char **c, unsigned long base,
>                 return err;
>         }
>
> -       err = get_pxe_file(cmdtp, include_path, base);
> +       err = get_pxe_file(ctx, include_path, base);
>
>         if (err < 0) {
>                 printf("Couldn't retrieve %s\n", include_path);
> @@ -952,7 +953,7 @@ static int handle_include(struct cmd_tbl *cmdtp, char **c, unsigned long base,
>         }
>
>         buf = map_sysmem(base, 0);
> -       ret = parse_pxefile_top(cmdtp, buf, base, cfg, nest_level);
> +       ret = parse_pxefile_top(ctx, buf, base, cfg, nest_level);
>         unmap_sysmem(buf);
>
>         return ret;
> @@ -968,7 +969,7 @@ static int handle_include(struct cmd_tbl *cmdtp, char **c, unsigned long base,
>   * nest_level should be 1 when parsing the top level pxe file, 2 when parsing
>   * a file it includes, 3 when parsing a file included by that file, and so on.
>   */
> -static int parse_menu(struct cmd_tbl *cmdtp, char **c, struct pxe_menu *cfg,
> +static int parse_menu(struct pxe_context *ctx, char **c, struct pxe_menu *cfg,
>                       unsigned long base, int nest_level)
>  {
>         struct token t;
> @@ -984,7 +985,7 @@ static int parse_menu(struct cmd_tbl *cmdtp, char **c, struct pxe_menu *cfg,
>                 break;
>
>         case T_INCLUDE:
> -               err = handle_include(cmdtp, c, base, cfg, nest_level + 1);
> +               err = handle_include(ctx, c, base, cfg, nest_level + 1);
>                 break;
>
>         case T_BACKGROUND:
> @@ -1186,7 +1187,7 @@ static int parse_label(char **c, struct pxe_menu *cfg)
>   *
>   * Returns 1 on success, < 0 on error.
>   */
> -static int parse_pxefile_top(struct cmd_tbl *cmdtp, char *p, unsigned long base,
> +static int parse_pxefile_top(struct pxe_context *ctx, char *p, unsigned long base,
>                              struct pxe_menu *cfg, int nest_level)
>  {
>         struct token t;
> @@ -1209,7 +1210,7 @@ static int parse_pxefile_top(struct cmd_tbl *cmdtp, char *p, unsigned long base,
>                 switch (t.type) {
>                 case T_MENU:
>                         cfg->prompt = 1;
> -                       err = parse_menu(cmdtp, &p, cfg,
> +                       err = parse_menu(ctx, &p, cfg,
>                                          base + ALIGN(strlen(b) + 1, 4),
>                                          nest_level);
>                         break;
> @@ -1236,7 +1237,7 @@ static int parse_pxefile_top(struct cmd_tbl *cmdtp, char *p, unsigned long base,
>                         break;
>
>                 case T_INCLUDE:
> -                       err = handle_include(cmdtp, &p,
> +                       err = handle_include(ctx, &p,
>                                              base + ALIGN(strlen(b), 4), cfg,
>                                              nest_level + 1);
>                         break;
> @@ -1263,7 +1264,6 @@ static int parse_pxefile_top(struct cmd_tbl *cmdtp, char *p, unsigned long base,
>  }
>
>  /*
> - * Free the memory used by a pxe_menu and its labels.
>   */
>  void destroy_pxe_menu(struct pxe_menu *cfg)
>  {
> @@ -1285,7 +1285,7 @@ void destroy_pxe_menu(struct pxe_menu *cfg)
>         free(cfg);
>  }
>
> -struct pxe_menu *parse_pxefile(struct cmd_tbl *cmdtp, unsigned long menucfg)
> +struct pxe_menu *parse_pxefile(struct pxe_context *ctx, unsigned long menucfg)
>  {
>         struct pxe_menu *cfg;
>         char *buf;
> @@ -1301,7 +1301,7 @@ struct pxe_menu *parse_pxefile(struct cmd_tbl *cmdtp, unsigned long menucfg)
>         INIT_LIST_HEAD(&cfg->labels);
>
>         buf = map_sysmem(menucfg, 0);
> -       r = parse_pxefile_top(cmdtp, buf, menucfg, cfg, 1);
> +       r = parse_pxefile_top(ctx, buf, menucfg, cfg, 1);
>         unmap_sysmem(buf);
>
>         if (r < 0) {
> @@ -1369,7 +1369,8 @@ static struct menu *pxe_menu_to_menu(struct pxe_menu *cfg)
>  /*
>   * Try to boot any labels we have yet to attempt to boot.
>   */
> -static void boot_unattempted_labels(struct cmd_tbl *cmdtp, struct pxe_menu *cfg)
> +static void boot_unattempted_labels(struct pxe_context *ctx,
> +                                   struct pxe_menu *cfg)
>  {
>         struct list_head *pos;
>         struct pxe_label *label;
> @@ -1378,11 +1379,11 @@ static void boot_unattempted_labels(struct cmd_tbl *cmdtp, struct pxe_menu *cfg)
>                 label = list_entry(pos, struct pxe_label, list);
>
>                 if (!label->attempted)
> -                       label_boot(cmdtp, label);
> +                       label_boot(ctx, label);
>         }
>  }
>
> -void handle_pxe_menu(struct cmd_tbl *cmdtp, struct pxe_menu *cfg)
> +void handle_pxe_menu(struct pxe_context *ctx, struct pxe_menu *cfg)
>  {
>         void *choice;
>         struct menu *m;
> @@ -1391,7 +1392,7 @@ void handle_pxe_menu(struct cmd_tbl *cmdtp, struct pxe_menu *cfg)
>         if (IS_ENABLED(CONFIG_CMD_BMP)) {
>                 /* display BMP if available */
>                 if (cfg->bmp) {
> -                       if (get_relfile(cmdtp, cfg->bmp, image_load_addr)) {
> +                       if (get_relfile(ctx, cfg->bmp, image_load_addr)) {
>                                 if (CONFIG_IS_ENABLED(CMD_CLS))
>                                         run_command("cls", 0);
>                                 bmp_display(image_load_addr,
> @@ -1423,12 +1424,17 @@ void handle_pxe_menu(struct cmd_tbl *cmdtp, struct pxe_menu *cfg)
>          */
>
>         if (err == 1) {
> -               err = label_boot(cmdtp, choice);
> +               err = label_boot(ctx, choice);
>                 if (!err)
>                         return;
>         } else if (err != -ENOENT) {
>                 return;
>         }
>
> -       boot_unattempted_labels(cmdtp, cfg);
> +       boot_unattempted_labels(ctx, cfg);
> +}
> +
> +void pxe_setup_ctx(struct pxe_context *ctx, struct cmd_tbl *cmdtp)
> +{
> +       ctx->cmdtp = cmdtp;
>  }
> diff --git a/cmd/pxe_utils.h b/cmd/pxe_utils.h
> index 441beefa2bc..cd0d3371765 100644
> --- a/cmd/pxe_utils.h
> +++ b/cmd/pxe_utils.h
> @@ -79,6 +79,23 @@ extern bool is_pxe;
>
>  extern int (*do_getfile)(struct cmd_tbl *cmdtp, const char *file_path,
>                          char *file_addr);
> +
> +/**
> + * struct pxe_context - context information for PXE parsing
> + *
> + * @cmdtp: Pointer to command table to use when calling other commands
> + */
> +struct pxe_context {
> +       struct cmd_tbl *cmdtp;
> +};
> +
> +/**
> + * destroy_pxe_menu() - Destroy an allocated pxe structure
> + *
> + * Free the memory used by a pxe_menu and its labels
> + *
> + * @cfg: Config to destroy, previous returned from parse_pxefile()
> + */
>  void destroy_pxe_menu(struct pxe_menu *cfg);
>
>  /**
> @@ -88,12 +105,12 @@ void destroy_pxe_menu(struct pxe_menu *cfg);
>   * 'bootfile' was specified in the environment, the path to bootfile will be
>   * prepended to 'file_path' and the resulting path will be used.
>   *
> - * @cmdtp: Pointer to command-table entry for the initiating command
> + * @ctx: PXE context
>   * @file_path: Path to file
>   * @file_addr: Address to place file
>   * Returns 1 on success, or < 0 for error
>   */
> -int get_pxe_file(struct cmd_tbl *cmdtp, const char *file_path,
> +int get_pxe_file(struct pxe_context *ctx, const char *file_path,
>                  ulong file_addr);
>
>  /**
> @@ -103,12 +120,12 @@ int get_pxe_file(struct cmd_tbl *cmdtp, const char *file_path,
>   * to do the hard work, the location of the 'pxelinux.cfg' folder is generated
>   * from the bootfile path, as described in get_pxe_file().
>   *
> - * @cmdtp: Pointer to command-table entry for the initiating command
> + * @ctx: PXE context
>   * @file: Relative path to file
>   * @pxefile_addr_r: Address to load file
>   * Returns 1 on success or < 0 on error.
>   */
> -int get_pxelinux_path(struct cmd_tbl *cmdtp, const char *file,
> +int get_pxelinux_path(struct pxe_context *ctx, const char *file,
>                       ulong pxefile_addr_r);
>
>  /**
> @@ -123,25 +140,23 @@ int get_pxelinux_path(struct cmd_tbl *cmdtp, const char *file,
>   * If this function returns, there weren't any labels that successfully
>   * booted, or the user interrupted the menu selection via ctrl+c.
>   *
> - * @cmdtp: Pointer to command-table entry for the initiating command
> + * @ctx: PXE context
>   * @cfg: PXE menu
>   */
> -void handle_pxe_menu(struct cmd_tbl *cmdtp, struct pxe_menu *cfg);
> +void handle_pxe_menu(struct pxe_context *ctx, struct pxe_menu *cfg);
>
>  /**
>   * parse_pxefile() - Parsing a pxe file
>   *
>   * This is only used for the top-level file.
>   *
> - * @cmdtp: Pointer to command-table entry for the initiating command
> - * @menucfg: Address of PXE file
> - *
> + * @ctx: PXE context (provided by the caller)
>   * Returns NULL if there is an error, otherwise, returns a pointer to a
>   * pxe_menu struct populated with the results of parsing the pxe file (and any
>   * files it includes). The resulting pxe_menu struct can be free()'d by using
>   * the destroy_pxe_menu() function.
>   */
> -struct pxe_menu *parse_pxefile(struct cmd_tbl *cmdtp, ulong menucfg);
> +struct pxe_menu *parse_pxefile(struct pxe_context *ctx, ulong menucfg);
>
>  /**
>   * format_mac_pxe() - Convert a MAC address to PXE format
> @@ -159,4 +174,12 @@ struct pxe_menu *parse_pxefile(struct cmd_tbl *cmdtp, ulong menucfg);
>   */
>  int format_mac_pxe(char *outbuf, size_t outbuf_len);
>
> +/**
> + * pxe_setup_ctx() - Setup a new PXE context
> + *
> + * @ctx: Context to set up
> + * @cmdtp: Command table entry which started this action
> + */
> +void pxe_setup_ctx(struct pxe_context *ctx, struct cmd_tbl *cmdtp);
> +
>  #endif /* __PXE_UTILS_H */
> diff --git a/cmd/sysboot.c b/cmd/sysboot.c
> index af6a2f1b7f1..9ba713c8aae 100644
> --- a/cmd/sysboot.c
> +++ b/cmd/sysboot.c
> @@ -59,6 +59,7 @@ static int do_sysboot(struct cmd_tbl *cmdtp, int flag, int argc,
>                       char *const argv[])
>  {
>         unsigned long pxefile_addr_r;
> +       struct pxe_context ctx;
>         struct pxe_menu *cfg;
>         char *pxefile_addr_str;
>         char *filename;
> @@ -90,6 +91,7 @@ static int do_sysboot(struct cmd_tbl *cmdtp, int flag, int argc,
>                 env_set("bootfile", filename);
>         }
>
> +       pxe_setup_ctx(&ctx, cmdtp);
>         if (strstr(argv[3], "ext2")) {
>                 do_getfile = do_get_ext2;
>         } else if (strstr(argv[3], "fat")) {
> @@ -108,12 +110,12 @@ static int do_sysboot(struct cmd_tbl *cmdtp, int flag, int argc,
>                 return 1;
>         }
>
> -       if (get_pxe_file(cmdtp, filename, pxefile_addr_r) < 0) {
> +       if (get_pxe_file(&ctx, filename, pxefile_addr_r) < 0) {
>                 printf("Error reading config file\n");
>                 return 1;
>         }
>
> -       cfg = parse_pxefile(cmdtp, pxefile_addr_r);
> +       cfg = parse_pxefile(&ctx, pxefile_addr_r);
>
>         if (!cfg) {
>                 printf("Error parsing config file\n");
> @@ -123,7 +125,7 @@ static int do_sysboot(struct cmd_tbl *cmdtp, int flag, int argc,
>         if (prompt)
>                 cfg->prompt = 1;
>
> -       handle_pxe_menu(cmdtp, cfg);
> +       handle_pxe_menu(&ctx, cfg);
>
>         destroy_pxe_menu(cfg);
>
> --
> 2.33.0.1079.g6e70778dc9-goog
>
Reviewed-by: Ramon Fried <rfried.dev@gmail.com>
Tom Rini Nov. 12, 2021, 3:39 p.m. UTC | #3
On Thu, Oct 14, 2021 at 12:47:56PM -0600, Simon Glass wrote:

> At present the PXE functions pass around a pointer to command-table entry
> which is very strange. It is only needed in a few places and it is odd to
> pass around a data structure from another module in this way.
> 
> For bootmethod we will need to provide some context information when
> reading files.
> 
> Create a PXE context struct to hold the command-table-entry pointer and
> pass that around instead. We can then add more things to the context as
> needed.
> 
> Signed-off-by: Simon Glass <sjg@chromium.org>
> Reviewed-by: Artem Lapkin <email2tema@gmail.com>
> Tested-by:  Artem Lapkin <email2tema@gmail.com>
> Reviewed-by: Ramon Fried <rfried.dev@gmail.com>

Applied to u-boot/master, thanks!
diff mbox series

Patch

diff --git a/cmd/pxe.c b/cmd/pxe.c
index 46ac08fa3a0..17ce54fc049 100644
--- a/cmd/pxe.c
+++ b/cmd/pxe.c
@@ -43,7 +43,7 @@  static int do_get_tftp(struct cmd_tbl *cmdtp, const char *file_path,
  *
  * Returns 1 on success or < 0 on error.
  */
-static int pxe_uuid_path(struct cmd_tbl *cmdtp, unsigned long pxefile_addr_r)
+static int pxe_uuid_path(struct pxe_context *ctx, unsigned long pxefile_addr_r)
 {
 	char *uuid_str;
 
@@ -52,7 +52,7 @@  static int pxe_uuid_path(struct cmd_tbl *cmdtp, unsigned long pxefile_addr_r)
 	if (!uuid_str)
 		return -ENOENT;
 
-	return get_pxelinux_path(cmdtp, uuid_str, pxefile_addr_r);
+	return get_pxelinux_path(ctx, uuid_str, pxefile_addr_r);
 }
 
 /*
@@ -61,7 +61,7 @@  static int pxe_uuid_path(struct cmd_tbl *cmdtp, unsigned long pxefile_addr_r)
  *
  * Returns 1 on success or < 0 on error.
  */
-static int pxe_mac_path(struct cmd_tbl *cmdtp, unsigned long pxefile_addr_r)
+static int pxe_mac_path(struct pxe_context *ctx, unsigned long pxefile_addr_r)
 {
 	char mac_str[21];
 	int err;
@@ -71,7 +71,7 @@  static int pxe_mac_path(struct cmd_tbl *cmdtp, unsigned long pxefile_addr_r)
 	if (err < 0)
 		return err;
 
-	return get_pxelinux_path(cmdtp, mac_str, pxefile_addr_r);
+	return get_pxelinux_path(ctx, mac_str, pxefile_addr_r);
 }
 
 /*
@@ -81,7 +81,7 @@  static int pxe_mac_path(struct cmd_tbl *cmdtp, unsigned long pxefile_addr_r)
  *
  * Returns 1 on success or < 0 on error.
  */
-static int pxe_ipaddr_paths(struct cmd_tbl *cmdtp, unsigned long pxefile_addr_r)
+static int pxe_ipaddr_paths(struct pxe_context *ctx, unsigned long pxefile_addr_r)
 {
 	char ip_addr[9];
 	int mask_pos, err;
@@ -89,7 +89,7 @@  static int pxe_ipaddr_paths(struct cmd_tbl *cmdtp, unsigned long pxefile_addr_r)
 	sprintf(ip_addr, "%08X", ntohl(net_ip.s_addr));
 
 	for (mask_pos = 7; mask_pos >= 0;  mask_pos--) {
-		err = get_pxelinux_path(cmdtp, ip_addr, pxefile_addr_r);
+		err = get_pxelinux_path(ctx, ip_addr, pxefile_addr_r);
 
 		if (err > 0)
 			return err;
@@ -118,8 +118,10 @@  do_pxe_get(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
 {
 	char *pxefile_addr_str;
 	unsigned long pxefile_addr_r;
+	struct pxe_context ctx;
 	int err, i = 0;
 
+	pxe_setup_ctx(&ctx, cmdtp);
 	do_getfile = do_get_tftp;
 
 	if (argc != 1)
@@ -139,16 +141,16 @@  do_pxe_get(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
 	 * Keep trying paths until we successfully get a file we're looking
 	 * for.
 	 */
-	if (pxe_uuid_path(cmdtp, pxefile_addr_r) > 0 ||
-	    pxe_mac_path(cmdtp, pxefile_addr_r) > 0 ||
-	    pxe_ipaddr_paths(cmdtp, pxefile_addr_r) > 0) {
+	if (pxe_uuid_path(&ctx, pxefile_addr_r) > 0 ||
+	    pxe_mac_path(&ctx, pxefile_addr_r) > 0 ||
+	    pxe_ipaddr_paths(&ctx, pxefile_addr_r) > 0) {
 		printf("Config file found\n");
 
 		return 0;
 	}
 
 	while (pxe_default_paths[i]) {
-		if (get_pxelinux_path(cmdtp, pxe_default_paths[i],
+		if (get_pxelinux_path(&ctx, pxe_default_paths[i],
 				      pxefile_addr_r) > 0) {
 			printf("Config file found\n");
 			return 0;
@@ -172,7 +174,9 @@  do_pxe_boot(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
 	unsigned long pxefile_addr_r;
 	struct pxe_menu *cfg;
 	char *pxefile_addr_str;
+	struct pxe_context ctx;
 
+	pxe_setup_ctx(&ctx, cmdtp);
 	do_getfile = do_get_tftp;
 
 	if (argc == 1) {
@@ -191,14 +195,14 @@  do_pxe_boot(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
 		return 1;
 	}
 
-	cfg = parse_pxefile(cmdtp, pxefile_addr_r);
+	cfg = parse_pxefile(&ctx, pxefile_addr_r);
 
 	if (!cfg) {
 		printf("Error parsing config file\n");
 		return 1;
 	}
 
-	handle_pxe_menu(cmdtp, cfg);
+	handle_pxe_menu(&ctx, cfg);
 
 	destroy_pxe_menu(cfg);
 
diff --git a/cmd/pxe_utils.c b/cmd/pxe_utils.c
index d7f4017efeb..280be55d9b3 100644
--- a/cmd/pxe_utils.c
+++ b/cmd/pxe_utils.c
@@ -105,7 +105,7 @@  int (*do_getfile)(struct cmd_tbl *cmdtp, const char *file_path,
  *
  * Returns 1 for success, or < 0 on error.
  */
-static int get_relfile(struct cmd_tbl *cmdtp, const char *file_path,
+static int get_relfile(struct pxe_context *ctx, const char *file_path,
 		       unsigned long file_addr)
 {
 	size_t path_len;
@@ -133,10 +133,10 @@  static int get_relfile(struct cmd_tbl *cmdtp, const char *file_path,
 
 	sprintf(addr_buf, "%lx", file_addr);
 
-	return do_getfile(cmdtp, relfile, addr_buf);
+	return do_getfile(ctx->cmdtp, relfile, addr_buf);
 }
 
-int get_pxe_file(struct cmd_tbl *cmdtp, const char *file_path,
+int get_pxe_file(struct pxe_context *ctx, const char *file_path,
 		 unsigned long file_addr)
 {
 	unsigned long config_file_size;
@@ -144,7 +144,7 @@  int get_pxe_file(struct cmd_tbl *cmdtp, const char *file_path,
 	int err;
 	char *buf;
 
-	err = get_relfile(cmdtp, file_path, file_addr);
+	err = get_relfile(ctx, file_path, file_addr);
 
 	if (err < 0)
 		return err;
@@ -170,7 +170,7 @@  int get_pxe_file(struct cmd_tbl *cmdtp, const char *file_path,
 
 #define PXELINUX_DIR "pxelinux.cfg/"
 
-int get_pxelinux_path(struct cmd_tbl *cmdtp, const char *file,
+int get_pxelinux_path(struct pxe_context *ctx, const char *file,
 		      unsigned long pxefile_addr_r)
 {
 	size_t base_len = strlen(PXELINUX_DIR);
@@ -184,7 +184,7 @@  int get_pxelinux_path(struct cmd_tbl *cmdtp, const char *file,
 
 	sprintf(path, PXELINUX_DIR "%s", file);
 
-	return get_pxe_file(cmdtp, path, pxefile_addr_r);
+	return get_pxe_file(ctx, path, pxefile_addr_r);
 }
 
 /*
@@ -194,7 +194,7 @@  int get_pxelinux_path(struct cmd_tbl *cmdtp, const char *file,
  *
  * Returns 1 on success or < 0 on error.
  */
-static int get_relfile_envaddr(struct cmd_tbl *cmdtp, const char *file_path,
+static int get_relfile_envaddr(struct pxe_context *ctx, const char *file_path,
 			       const char *envaddr_name)
 {
 	unsigned long file_addr;
@@ -208,7 +208,7 @@  static int get_relfile_envaddr(struct cmd_tbl *cmdtp, const char *file_path,
 	if (strict_strtoul(envaddr, 16, &file_addr) < 0)
 		return -EINVAL;
 
-	return get_relfile(cmdtp, file_path, file_addr);
+	return get_relfile(ctx, file_path, file_addr);
 }
 
 /*
@@ -317,7 +317,8 @@  static int label_localboot(struct pxe_label *label)
  * Loads fdt overlays specified in 'fdtoverlays'.
  */
 #ifdef CONFIG_OF_LIBFDT_OVERLAY
-static void label_boot_fdtoverlay(struct cmd_tbl *cmdtp, struct pxe_label *label)
+static void label_boot_fdtoverlay(struct pxe_context *ctx,
+				  struct pxe_label *label)
 {
 	char *fdtoverlay = label->fdtoverlays;
 	struct fdt_header *working_fdt;
@@ -367,7 +368,7 @@  static void label_boot_fdtoverlay(struct cmd_tbl *cmdtp, struct pxe_label *label
 			goto skip_overlay;
 
 		/* Load overlay file */
-		err = get_relfile_envaddr(cmdtp, overlayfile,
+		err = get_relfile_envaddr(ctx, overlayfile,
 					  "fdtoverlay_addr_r");
 		if (err < 0) {
 			printf("Failed loading overlay %s\n", overlayfile);
@@ -414,7 +415,7 @@  skip_overlay:
  * If the label specifies an 'append' line, its contents will overwrite that
  * of the 'bootargs' environment variable.
  */
-static int label_boot(struct cmd_tbl *cmdtp, struct pxe_label *label)
+static int label_boot(struct pxe_context *ctx, struct pxe_label *label)
 {
 	char *bootm_argv[] = { "bootm", NULL, NULL, NULL, NULL };
 	char initrd_str[28];
@@ -443,7 +444,7 @@  static int label_boot(struct cmd_tbl *cmdtp, struct pxe_label *label)
 	}
 
 	if (label->initrd) {
-		if (get_relfile_envaddr(cmdtp, label->initrd, "ramdisk_addr_r") < 0) {
+		if (get_relfile_envaddr(ctx, label->initrd, "ramdisk_addr_r") < 0) {
 			printf("Skipping %s for failure retrieving initrd\n",
 			       label->name);
 			return 1;
@@ -456,7 +457,7 @@  static int label_boot(struct cmd_tbl *cmdtp, struct pxe_label *label)
 		bootm_argc = 3;
 	}
 
-	if (get_relfile_envaddr(cmdtp, label->kernel, "kernel_addr_r") < 0) {
+	if (get_relfile_envaddr(ctx, label->kernel, "kernel_addr_r") < 0) {
 		printf("Skipping %s for failure retrieving kernel\n",
 		       label->name);
 		return 1;
@@ -596,7 +597,7 @@  static int label_boot(struct cmd_tbl *cmdtp, struct pxe_label *label)
 		}
 
 		if (fdtfile) {
-			int err = get_relfile_envaddr(cmdtp, fdtfile,
+			int err = get_relfile_envaddr(ctx, fdtfile,
 						      "fdt_addr_r");
 
 			free(fdtfilefree);
@@ -612,7 +613,7 @@  static int label_boot(struct cmd_tbl *cmdtp, struct pxe_label *label)
 
 #ifdef CONFIG_OF_LIBFDT_OVERLAY
 			if (label->fdtoverlays)
-				label_boot_fdtoverlay(cmdtp, label);
+				label_boot_fdtoverlay(ctx, label);
 #endif
 		} else {
 			bootm_argv[3] = NULL;
@@ -632,16 +633,16 @@  static int label_boot(struct cmd_tbl *cmdtp, struct pxe_label *label)
 	buf = map_sysmem(kernel_addr, 0);
 	/* Try bootm for legacy and FIT format image */
 	if (genimg_get_format(buf) != IMAGE_FORMAT_INVALID)
-		do_bootm(cmdtp, 0, bootm_argc, bootm_argv);
+		do_bootm(ctx->cmdtp, 0, bootm_argc, bootm_argv);
 	/* Try booting an AArch64 Linux kernel image */
 	else if (IS_ENABLED(CONFIG_CMD_BOOTI))
-		do_booti(cmdtp, 0, bootm_argc, bootm_argv);
+		do_booti(ctx->cmdtp, 0, bootm_argc, bootm_argv);
 	/* Try booting a Image */
 	else if (IS_ENABLED(CONFIG_CMD_BOOTZ))
-		do_bootz(cmdtp, 0, bootm_argc, bootm_argv);
+		do_bootz(ctx->cmdtp, 0, bootm_argc, bootm_argv);
 	/* Try booting an x86_64 Linux kernel image */
 	else if (IS_ENABLED(CONFIG_CMD_ZBOOT))
-		do_zboot_parent(cmdtp, 0, bootm_argc, bootm_argv, NULL);
+		do_zboot_parent(ctx->cmdtp, 0, bootm_argc, bootm_argv, NULL);
 
 	unmap_sysmem(buf);
 
@@ -917,7 +918,7 @@  static int parse_integer(char **c, int *dst)
 	return 1;
 }
 
-static int parse_pxefile_top(struct cmd_tbl *cmdtp, char *p, unsigned long base,
+static int parse_pxefile_top(struct pxe_context *ctx, char *p, ulong base,
 			     struct pxe_menu *cfg, int nest_level);
 
 /*
@@ -928,7 +929,7 @@  static int parse_pxefile_top(struct cmd_tbl *cmdtp, char *p, unsigned long base,
  * include, nest_level has already been incremented and doesn't need to be
  * incremented here.
  */
-static int handle_include(struct cmd_tbl *cmdtp, char **c, unsigned long base,
+static int handle_include(struct pxe_context *ctx, char **c, unsigned long base,
 			  struct pxe_menu *cfg, int nest_level)
 {
 	char *include_path;
@@ -944,7 +945,7 @@  static int handle_include(struct cmd_tbl *cmdtp, char **c, unsigned long base,
 		return err;
 	}
 
-	err = get_pxe_file(cmdtp, include_path, base);
+	err = get_pxe_file(ctx, include_path, base);
 
 	if (err < 0) {
 		printf("Couldn't retrieve %s\n", include_path);
@@ -952,7 +953,7 @@  static int handle_include(struct cmd_tbl *cmdtp, char **c, unsigned long base,
 	}
 
 	buf = map_sysmem(base, 0);
-	ret = parse_pxefile_top(cmdtp, buf, base, cfg, nest_level);
+	ret = parse_pxefile_top(ctx, buf, base, cfg, nest_level);
 	unmap_sysmem(buf);
 
 	return ret;
@@ -968,7 +969,7 @@  static int handle_include(struct cmd_tbl *cmdtp, char **c, unsigned long base,
  * nest_level should be 1 when parsing the top level pxe file, 2 when parsing
  * a file it includes, 3 when parsing a file included by that file, and so on.
  */
-static int parse_menu(struct cmd_tbl *cmdtp, char **c, struct pxe_menu *cfg,
+static int parse_menu(struct pxe_context *ctx, char **c, struct pxe_menu *cfg,
 		      unsigned long base, int nest_level)
 {
 	struct token t;
@@ -984,7 +985,7 @@  static int parse_menu(struct cmd_tbl *cmdtp, char **c, struct pxe_menu *cfg,
 		break;
 
 	case T_INCLUDE:
-		err = handle_include(cmdtp, c, base, cfg, nest_level + 1);
+		err = handle_include(ctx, c, base, cfg, nest_level + 1);
 		break;
 
 	case T_BACKGROUND:
@@ -1186,7 +1187,7 @@  static int parse_label(char **c, struct pxe_menu *cfg)
  *
  * Returns 1 on success, < 0 on error.
  */
-static int parse_pxefile_top(struct cmd_tbl *cmdtp, char *p, unsigned long base,
+static int parse_pxefile_top(struct pxe_context *ctx, char *p, unsigned long base,
 			     struct pxe_menu *cfg, int nest_level)
 {
 	struct token t;
@@ -1209,7 +1210,7 @@  static int parse_pxefile_top(struct cmd_tbl *cmdtp, char *p, unsigned long base,
 		switch (t.type) {
 		case T_MENU:
 			cfg->prompt = 1;
-			err = parse_menu(cmdtp, &p, cfg,
+			err = parse_menu(ctx, &p, cfg,
 					 base + ALIGN(strlen(b) + 1, 4),
 					 nest_level);
 			break;
@@ -1236,7 +1237,7 @@  static int parse_pxefile_top(struct cmd_tbl *cmdtp, char *p, unsigned long base,
 			break;
 
 		case T_INCLUDE:
-			err = handle_include(cmdtp, &p,
+			err = handle_include(ctx, &p,
 					     base + ALIGN(strlen(b), 4), cfg,
 					     nest_level + 1);
 			break;
@@ -1263,7 +1264,6 @@  static int parse_pxefile_top(struct cmd_tbl *cmdtp, char *p, unsigned long base,
 }
 
 /*
- * Free the memory used by a pxe_menu and its labels.
  */
 void destroy_pxe_menu(struct pxe_menu *cfg)
 {
@@ -1285,7 +1285,7 @@  void destroy_pxe_menu(struct pxe_menu *cfg)
 	free(cfg);
 }
 
-struct pxe_menu *parse_pxefile(struct cmd_tbl *cmdtp, unsigned long menucfg)
+struct pxe_menu *parse_pxefile(struct pxe_context *ctx, unsigned long menucfg)
 {
 	struct pxe_menu *cfg;
 	char *buf;
@@ -1301,7 +1301,7 @@  struct pxe_menu *parse_pxefile(struct cmd_tbl *cmdtp, unsigned long menucfg)
 	INIT_LIST_HEAD(&cfg->labels);
 
 	buf = map_sysmem(menucfg, 0);
-	r = parse_pxefile_top(cmdtp, buf, menucfg, cfg, 1);
+	r = parse_pxefile_top(ctx, buf, menucfg, cfg, 1);
 	unmap_sysmem(buf);
 
 	if (r < 0) {
@@ -1369,7 +1369,8 @@  static struct menu *pxe_menu_to_menu(struct pxe_menu *cfg)
 /*
  * Try to boot any labels we have yet to attempt to boot.
  */
-static void boot_unattempted_labels(struct cmd_tbl *cmdtp, struct pxe_menu *cfg)
+static void boot_unattempted_labels(struct pxe_context *ctx,
+				    struct pxe_menu *cfg)
 {
 	struct list_head *pos;
 	struct pxe_label *label;
@@ -1378,11 +1379,11 @@  static void boot_unattempted_labels(struct cmd_tbl *cmdtp, struct pxe_menu *cfg)
 		label = list_entry(pos, struct pxe_label, list);
 
 		if (!label->attempted)
-			label_boot(cmdtp, label);
+			label_boot(ctx, label);
 	}
 }
 
-void handle_pxe_menu(struct cmd_tbl *cmdtp, struct pxe_menu *cfg)
+void handle_pxe_menu(struct pxe_context *ctx, struct pxe_menu *cfg)
 {
 	void *choice;
 	struct menu *m;
@@ -1391,7 +1392,7 @@  void handle_pxe_menu(struct cmd_tbl *cmdtp, struct pxe_menu *cfg)
 	if (IS_ENABLED(CONFIG_CMD_BMP)) {
 		/* display BMP if available */
 		if (cfg->bmp) {
-			if (get_relfile(cmdtp, cfg->bmp, image_load_addr)) {
+			if (get_relfile(ctx, cfg->bmp, image_load_addr)) {
 				if (CONFIG_IS_ENABLED(CMD_CLS))
 					run_command("cls", 0);
 				bmp_display(image_load_addr,
@@ -1423,12 +1424,17 @@  void handle_pxe_menu(struct cmd_tbl *cmdtp, struct pxe_menu *cfg)
 	 */
 
 	if (err == 1) {
-		err = label_boot(cmdtp, choice);
+		err = label_boot(ctx, choice);
 		if (!err)
 			return;
 	} else if (err != -ENOENT) {
 		return;
 	}
 
-	boot_unattempted_labels(cmdtp, cfg);
+	boot_unattempted_labels(ctx, cfg);
+}
+
+void pxe_setup_ctx(struct pxe_context *ctx, struct cmd_tbl *cmdtp)
+{
+	ctx->cmdtp = cmdtp;
 }
diff --git a/cmd/pxe_utils.h b/cmd/pxe_utils.h
index 441beefa2bc..cd0d3371765 100644
--- a/cmd/pxe_utils.h
+++ b/cmd/pxe_utils.h
@@ -79,6 +79,23 @@  extern bool is_pxe;
 
 extern int (*do_getfile)(struct cmd_tbl *cmdtp, const char *file_path,
 			 char *file_addr);
+
+/**
+ * struct pxe_context - context information for PXE parsing
+ *
+ * @cmdtp: Pointer to command table to use when calling other commands
+ */
+struct pxe_context {
+	struct cmd_tbl *cmdtp;
+};
+
+/**
+ * destroy_pxe_menu() - Destroy an allocated pxe structure
+ *
+ * Free the memory used by a pxe_menu and its labels
+ *
+ * @cfg: Config to destroy, previous returned from parse_pxefile()
+ */
 void destroy_pxe_menu(struct pxe_menu *cfg);
 
 /**
@@ -88,12 +105,12 @@  void destroy_pxe_menu(struct pxe_menu *cfg);
  * 'bootfile' was specified in the environment, the path to bootfile will be
  * prepended to 'file_path' and the resulting path will be used.
  *
- * @cmdtp: Pointer to command-table entry for the initiating command
+ * @ctx: PXE context
  * @file_path: Path to file
  * @file_addr: Address to place file
  * Returns 1 on success, or < 0 for error
  */
-int get_pxe_file(struct cmd_tbl *cmdtp, const char *file_path,
+int get_pxe_file(struct pxe_context *ctx, const char *file_path,
 		 ulong file_addr);
 
 /**
@@ -103,12 +120,12 @@  int get_pxe_file(struct cmd_tbl *cmdtp, const char *file_path,
  * to do the hard work, the location of the 'pxelinux.cfg' folder is generated
  * from the bootfile path, as described in get_pxe_file().
  *
- * @cmdtp: Pointer to command-table entry for the initiating command
+ * @ctx: PXE context
  * @file: Relative path to file
  * @pxefile_addr_r: Address to load file
  * Returns 1 on success or < 0 on error.
  */
-int get_pxelinux_path(struct cmd_tbl *cmdtp, const char *file,
+int get_pxelinux_path(struct pxe_context *ctx, const char *file,
 		      ulong pxefile_addr_r);
 
 /**
@@ -123,25 +140,23 @@  int get_pxelinux_path(struct cmd_tbl *cmdtp, const char *file,
  * If this function returns, there weren't any labels that successfully
  * booted, or the user interrupted the menu selection via ctrl+c.
  *
- * @cmdtp: Pointer to command-table entry for the initiating command
+ * @ctx: PXE context
  * @cfg: PXE menu
  */
-void handle_pxe_menu(struct cmd_tbl *cmdtp, struct pxe_menu *cfg);
+void handle_pxe_menu(struct pxe_context *ctx, struct pxe_menu *cfg);
 
 /**
  * parse_pxefile() - Parsing a pxe file
  *
  * This is only used for the top-level file.
  *
- * @cmdtp: Pointer to command-table entry for the initiating command
- * @menucfg: Address of PXE file
- *
+ * @ctx: PXE context (provided by the caller)
  * Returns NULL if there is an error, otherwise, returns a pointer to a
  * pxe_menu struct populated with the results of parsing the pxe file (and any
  * files it includes). The resulting pxe_menu struct can be free()'d by using
  * the destroy_pxe_menu() function.
  */
-struct pxe_menu *parse_pxefile(struct cmd_tbl *cmdtp, ulong menucfg);
+struct pxe_menu *parse_pxefile(struct pxe_context *ctx, ulong menucfg);
 
 /**
  * format_mac_pxe() - Convert a MAC address to PXE format
@@ -159,4 +174,12 @@  struct pxe_menu *parse_pxefile(struct cmd_tbl *cmdtp, ulong menucfg);
  */
 int format_mac_pxe(char *outbuf, size_t outbuf_len);
 
+/**
+ * pxe_setup_ctx() - Setup a new PXE context
+ *
+ * @ctx: Context to set up
+ * @cmdtp: Command table entry which started this action
+ */
+void pxe_setup_ctx(struct pxe_context *ctx, struct cmd_tbl *cmdtp);
+
 #endif /* __PXE_UTILS_H */
diff --git a/cmd/sysboot.c b/cmd/sysboot.c
index af6a2f1b7f1..9ba713c8aae 100644
--- a/cmd/sysboot.c
+++ b/cmd/sysboot.c
@@ -59,6 +59,7 @@  static int do_sysboot(struct cmd_tbl *cmdtp, int flag, int argc,
 		      char *const argv[])
 {
 	unsigned long pxefile_addr_r;
+	struct pxe_context ctx;
 	struct pxe_menu *cfg;
 	char *pxefile_addr_str;
 	char *filename;
@@ -90,6 +91,7 @@  static int do_sysboot(struct cmd_tbl *cmdtp, int flag, int argc,
 		env_set("bootfile", filename);
 	}
 
+	pxe_setup_ctx(&ctx, cmdtp);
 	if (strstr(argv[3], "ext2")) {
 		do_getfile = do_get_ext2;
 	} else if (strstr(argv[3], "fat")) {
@@ -108,12 +110,12 @@  static int do_sysboot(struct cmd_tbl *cmdtp, int flag, int argc,
 		return 1;
 	}
 
-	if (get_pxe_file(cmdtp, filename, pxefile_addr_r) < 0) {
+	if (get_pxe_file(&ctx, filename, pxefile_addr_r) < 0) {
 		printf("Error reading config file\n");
 		return 1;
 	}
 
-	cfg = parse_pxefile(cmdtp, pxefile_addr_r);
+	cfg = parse_pxefile(&ctx, pxefile_addr_r);
 
 	if (!cfg) {
 		printf("Error parsing config file\n");
@@ -123,7 +125,7 @@  static int do_sysboot(struct cmd_tbl *cmdtp, int flag, int argc,
 	if (prompt)
 		cfg->prompt = 1;
 
-	handle_pxe_menu(cmdtp, cfg);
+	handle_pxe_menu(&ctx, cfg);
 
 	destroy_pxe_menu(cfg);