pxe: Use a context pointer

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>
This commit is contained in:
Simon Glass 2021-10-14 12:47:56 -06:00 committed by Tom Rini
parent 3d24636e92
commit fd3fa5c394
4 changed files with 97 additions and 62 deletions

View File

@ -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. * 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; char *uuid_str;
@ -52,7 +52,7 @@ static int pxe_uuid_path(struct cmd_tbl *cmdtp, unsigned long pxefile_addr_r)
if (!uuid_str) if (!uuid_str)
return -ENOENT; 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. * 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]; char mac_str[21];
int err; int err;
@ -71,7 +71,7 @@ static int pxe_mac_path(struct cmd_tbl *cmdtp, unsigned long pxefile_addr_r)
if (err < 0) if (err < 0)
return err; 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. * 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]; char ip_addr[9];
int mask_pos, err; 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)); sprintf(ip_addr, "%08X", ntohl(net_ip.s_addr));
for (mask_pos = 7; mask_pos >= 0; mask_pos--) { 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) if (err > 0)
return err; return err;
@ -118,8 +118,10 @@ do_pxe_get(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
{ {
char *pxefile_addr_str; char *pxefile_addr_str;
unsigned long pxefile_addr_r; unsigned long pxefile_addr_r;
struct pxe_context ctx;
int err, i = 0; int err, i = 0;
pxe_setup_ctx(&ctx, cmdtp);
do_getfile = do_get_tftp; do_getfile = do_get_tftp;
if (argc != 1) 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 * Keep trying paths until we successfully get a file we're looking
* for. * for.
*/ */
if (pxe_uuid_path(cmdtp, pxefile_addr_r) > 0 || if (pxe_uuid_path(&ctx, pxefile_addr_r) > 0 ||
pxe_mac_path(cmdtp, pxefile_addr_r) > 0 || pxe_mac_path(&ctx, pxefile_addr_r) > 0 ||
pxe_ipaddr_paths(cmdtp, pxefile_addr_r) > 0) { pxe_ipaddr_paths(&ctx, pxefile_addr_r) > 0) {
printf("Config file found\n"); printf("Config file found\n");
return 0; return 0;
} }
while (pxe_default_paths[i]) { 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) { pxefile_addr_r) > 0) {
printf("Config file found\n"); printf("Config file found\n");
return 0; 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; unsigned long pxefile_addr_r;
struct pxe_menu *cfg; struct pxe_menu *cfg;
char *pxefile_addr_str; char *pxefile_addr_str;
struct pxe_context ctx;
pxe_setup_ctx(&ctx, cmdtp);
do_getfile = do_get_tftp; do_getfile = do_get_tftp;
if (argc == 1) { if (argc == 1) {
@ -191,14 +195,14 @@ do_pxe_boot(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
return 1; return 1;
} }
cfg = parse_pxefile(cmdtp, pxefile_addr_r); cfg = parse_pxefile(&ctx, pxefile_addr_r);
if (!cfg) { if (!cfg) {
printf("Error parsing config file\n"); printf("Error parsing config file\n");
return 1; return 1;
} }
handle_pxe_menu(cmdtp, cfg); handle_pxe_menu(&ctx, cfg);
destroy_pxe_menu(cfg); destroy_pxe_menu(cfg);

View File

@ -105,7 +105,7 @@ int (*do_getfile)(struct cmd_tbl *cmdtp, const char *file_path,
* *
* Returns 1 for success, or < 0 on error. * 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) unsigned long file_addr)
{ {
size_t path_len; 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); 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 file_addr)
{ {
unsigned long config_file_size; unsigned long config_file_size;
@ -144,7 +144,7 @@ int get_pxe_file(struct cmd_tbl *cmdtp, const char *file_path,
int err; int err;
char *buf; char *buf;
err = get_relfile(cmdtp, file_path, file_addr); err = get_relfile(ctx, file_path, file_addr);
if (err < 0) if (err < 0)
return err; return err;
@ -170,7 +170,7 @@ int get_pxe_file(struct cmd_tbl *cmdtp, const char *file_path,
#define PXELINUX_DIR "pxelinux.cfg/" #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) unsigned long pxefile_addr_r)
{ {
size_t base_len = strlen(PXELINUX_DIR); 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); 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. * 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) const char *envaddr_name)
{ {
unsigned long file_addr; 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) if (strict_strtoul(envaddr, 16, &file_addr) < 0)
return -EINVAL; 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'. * Loads fdt overlays specified in 'fdtoverlays'.
*/ */
#ifdef CONFIG_OF_LIBFDT_OVERLAY #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; char *fdtoverlay = label->fdtoverlays;
struct fdt_header *working_fdt; 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; goto skip_overlay;
/* Load overlay file */ /* Load overlay file */
err = get_relfile_envaddr(cmdtp, overlayfile, err = get_relfile_envaddr(ctx, overlayfile,
"fdtoverlay_addr_r"); "fdtoverlay_addr_r");
if (err < 0) { if (err < 0) {
printf("Failed loading overlay %s\n", overlayfile); 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 * If the label specifies an 'append' line, its contents will overwrite that
* of the 'bootargs' environment variable. * 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 *bootm_argv[] = { "bootm", NULL, NULL, NULL, NULL };
char *zboot_argv[] = { "zboot", NULL, "0", NULL, NULL }; char *zboot_argv[] = { "zboot", NULL, "0", NULL, NULL };
@ -448,7 +449,7 @@ static int label_boot(struct cmd_tbl *cmdtp, struct pxe_label *label)
} }
if (label->initrd) { 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", printf("Skipping %s for failure retrieving initrd\n",
label->name); label->name);
return 1; return 1;
@ -462,7 +463,7 @@ static int label_boot(struct cmd_tbl *cmdtp, struct pxe_label *label)
strncat(initrd_str, initrd_filesize, 9); strncat(initrd_str, initrd_filesize, 9);
} }
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", printf("Skipping %s for failure retrieving kernel\n",
label->name); label->name);
return 1; return 1;
@ -603,7 +604,7 @@ static int label_boot(struct cmd_tbl *cmdtp, struct pxe_label *label)
} }
if (fdtfile) { if (fdtfile) {
int err = get_relfile_envaddr(cmdtp, fdtfile, int err = get_relfile_envaddr(ctx, fdtfile,
"fdt_addr_r"); "fdt_addr_r");
free(fdtfilefree); free(fdtfilefree);
@ -619,7 +620,7 @@ static int label_boot(struct cmd_tbl *cmdtp, struct pxe_label *label)
#ifdef CONFIG_OF_LIBFDT_OVERLAY #ifdef CONFIG_OF_LIBFDT_OVERLAY
if (label->fdtoverlays) if (label->fdtoverlays)
label_boot_fdtoverlay(cmdtp, label); label_boot_fdtoverlay(ctx, label);
#endif #endif
} else { } else {
bootm_argv[3] = NULL; bootm_argv[3] = NULL;
@ -651,16 +652,16 @@ static int label_boot(struct cmd_tbl *cmdtp, struct pxe_label *label)
buf = map_sysmem(kernel_addr_r, 0); buf = map_sysmem(kernel_addr_r, 0);
/* Try bootm for legacy and FIT format image */ /* Try bootm for legacy and FIT format image */
if (genimg_get_format(buf) != IMAGE_FORMAT_INVALID) 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 */ /* Try booting an AArch64 Linux kernel image */
else if (IS_ENABLED(CONFIG_CMD_BOOTI)) 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 */ /* Try booting a Image */
else if (IS_ENABLED(CONFIG_CMD_BOOTZ)) 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 */ /* Try booting an x86_64 Linux kernel image */
else if (IS_ENABLED(CONFIG_CMD_ZBOOT)) else if (IS_ENABLED(CONFIG_CMD_ZBOOT))
do_zboot_parent(cmdtp, 0, zboot_argc, zboot_argv, NULL); do_zboot_parent(ctx->cmdtp, 0, zboot_argc, zboot_argv, NULL);
unmap_sysmem(buf); unmap_sysmem(buf);
@ -936,7 +937,7 @@ static int parse_integer(char **c, int *dst)
return 1; 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); struct pxe_menu *cfg, int nest_level);
/* /*
@ -947,7 +948,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 * include, nest_level has already been incremented and doesn't need to be
* incremented here. * 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) struct pxe_menu *cfg, int nest_level)
{ {
char *include_path; char *include_path;
@ -963,7 +964,7 @@ static int handle_include(struct cmd_tbl *cmdtp, char **c, unsigned long base,
return err; return err;
} }
err = get_pxe_file(cmdtp, include_path, base); err = get_pxe_file(ctx, include_path, base);
if (err < 0) { if (err < 0) {
printf("Couldn't retrieve %s\n", include_path); printf("Couldn't retrieve %s\n", include_path);
@ -971,7 +972,7 @@ static int handle_include(struct cmd_tbl *cmdtp, char **c, unsigned long base,
} }
buf = map_sysmem(base, 0); 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); unmap_sysmem(buf);
return ret; return ret;
@ -987,7 +988,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 * 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. * 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) unsigned long base, int nest_level)
{ {
struct token t; struct token t;
@ -1003,7 +1004,7 @@ static int parse_menu(struct cmd_tbl *cmdtp, char **c, struct pxe_menu *cfg,
break; break;
case T_INCLUDE: case T_INCLUDE:
err = handle_include(cmdtp, c, base, cfg, nest_level + 1); err = handle_include(ctx, c, base, cfg, nest_level + 1);
break; break;
case T_BACKGROUND: case T_BACKGROUND:
@ -1205,7 +1206,7 @@ static int parse_label(char **c, struct pxe_menu *cfg)
* *
* Returns 1 on success, < 0 on error. * 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 pxe_menu *cfg, int nest_level)
{ {
struct token t; struct token t;
@ -1228,7 +1229,7 @@ static int parse_pxefile_top(struct cmd_tbl *cmdtp, char *p, unsigned long base,
switch (t.type) { switch (t.type) {
case T_MENU: case T_MENU:
cfg->prompt = 1; cfg->prompt = 1;
err = parse_menu(cmdtp, &p, cfg, err = parse_menu(ctx, &p, cfg,
base + ALIGN(strlen(b) + 1, 4), base + ALIGN(strlen(b) + 1, 4),
nest_level); nest_level);
break; break;
@ -1255,7 +1256,7 @@ static int parse_pxefile_top(struct cmd_tbl *cmdtp, char *p, unsigned long base,
break; break;
case T_INCLUDE: case T_INCLUDE:
err = handle_include(cmdtp, &p, err = handle_include(ctx, &p,
base + ALIGN(strlen(b), 4), cfg, base + ALIGN(strlen(b), 4), cfg,
nest_level + 1); nest_level + 1);
break; break;
@ -1282,7 +1283,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) void destroy_pxe_menu(struct pxe_menu *cfg)
{ {
@ -1304,7 +1304,7 @@ void destroy_pxe_menu(struct pxe_menu *cfg)
free(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; struct pxe_menu *cfg;
char *buf; char *buf;
@ -1320,7 +1320,7 @@ struct pxe_menu *parse_pxefile(struct cmd_tbl *cmdtp, unsigned long menucfg)
INIT_LIST_HEAD(&cfg->labels); INIT_LIST_HEAD(&cfg->labels);
buf = map_sysmem(menucfg, 0); 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); unmap_sysmem(buf);
if (r < 0) { if (r < 0) {
@ -1388,7 +1388,8 @@ static struct menu *pxe_menu_to_menu(struct pxe_menu *cfg)
/* /*
* Try to boot any labels we have yet to attempt to boot. * 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 list_head *pos;
struct pxe_label *label; struct pxe_label *label;
@ -1397,11 +1398,11 @@ static void boot_unattempted_labels(struct cmd_tbl *cmdtp, struct pxe_menu *cfg)
label = list_entry(pos, struct pxe_label, list); label = list_entry(pos, struct pxe_label, list);
if (!label->attempted) 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; void *choice;
struct menu *m; struct menu *m;
@ -1410,7 +1411,7 @@ void handle_pxe_menu(struct cmd_tbl *cmdtp, struct pxe_menu *cfg)
if (IS_ENABLED(CONFIG_CMD_BMP)) { if (IS_ENABLED(CONFIG_CMD_BMP)) {
/* display BMP if available */ /* display BMP if available */
if (cfg->bmp) { 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)) if (CONFIG_IS_ENABLED(CMD_CLS))
run_command("cls", 0); run_command("cls", 0);
bmp_display(image_load_addr, bmp_display(image_load_addr,
@ -1442,12 +1443,17 @@ void handle_pxe_menu(struct cmd_tbl *cmdtp, struct pxe_menu *cfg)
*/ */
if (err == 1) { if (err == 1) {
err = label_boot(cmdtp, choice); err = label_boot(ctx, choice);
if (!err) if (!err)
return; return;
} else if (err != -ENOENT) { } else if (err != -ENOENT) {
return; 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;
} }

View File

@ -79,6 +79,23 @@ extern bool is_pxe;
extern int (*do_getfile)(struct cmd_tbl *cmdtp, const char *file_path, extern int (*do_getfile)(struct cmd_tbl *cmdtp, const char *file_path,
char *file_addr); 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); 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 * 'bootfile' was specified in the environment, the path to bootfile will be
* prepended to 'file_path' and the resulting path will be used. * 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_path: Path to file
* @file_addr: Address to place file * @file_addr: Address to place file
* Returns 1 on success, or < 0 for error * 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); 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 * to do the hard work, the location of the 'pxelinux.cfg' folder is generated
* from the bootfile path, as described in get_pxe_file(). * 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 * @file: Relative path to file
* @pxefile_addr_r: Address to load file * @pxefile_addr_r: Address to load file
* Returns 1 on success or < 0 on error. * 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); 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 * If this function returns, there weren't any labels that successfully
* booted, or the user interrupted the menu selection via ctrl+c. * 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 * @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 * parse_pxefile() - Parsing a pxe file
* *
* This is only used for the top-level file. * This is only used for the top-level file.
* *
* @cmdtp: Pointer to command-table entry for the initiating command * @ctx: PXE context (provided by the caller)
* @menucfg: Address of PXE file
*
* Returns NULL if there is an error, otherwise, returns a pointer to a * 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 * 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 * files it includes). The resulting pxe_menu struct can be free()'d by using
* the destroy_pxe_menu() function. * 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 * 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); 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 */ #endif /* __PXE_UTILS_H */

View File

@ -59,6 +59,7 @@ static int do_sysboot(struct cmd_tbl *cmdtp, int flag, int argc,
char *const argv[]) char *const argv[])
{ {
unsigned long pxefile_addr_r; unsigned long pxefile_addr_r;
struct pxe_context ctx;
struct pxe_menu *cfg; struct pxe_menu *cfg;
char *pxefile_addr_str; char *pxefile_addr_str;
char *filename; char *filename;
@ -90,6 +91,7 @@ static int do_sysboot(struct cmd_tbl *cmdtp, int flag, int argc,
env_set("bootfile", filename); env_set("bootfile", filename);
} }
pxe_setup_ctx(&ctx, cmdtp);
if (strstr(argv[3], "ext2")) { if (strstr(argv[3], "ext2")) {
do_getfile = do_get_ext2; do_getfile = do_get_ext2;
} else if (strstr(argv[3], "fat")) { } else if (strstr(argv[3], "fat")) {
@ -108,12 +110,12 @@ static int do_sysboot(struct cmd_tbl *cmdtp, int flag, int argc,
return 1; 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"); printf("Error reading config file\n");
return 1; return 1;
} }
cfg = parse_pxefile(cmdtp, pxefile_addr_r); cfg = parse_pxefile(&ctx, pxefile_addr_r);
if (!cfg) { if (!cfg) {
printf("Error parsing config file\n"); printf("Error parsing config file\n");
@ -123,7 +125,7 @@ static int do_sysboot(struct cmd_tbl *cmdtp, int flag, int argc,
if (prompt) if (prompt)
cfg->prompt = 1; cfg->prompt = 1;
handle_pxe_menu(cmdtp, cfg); handle_pxe_menu(&ctx, cfg);
destroy_pxe_menu(cfg); destroy_pxe_menu(cfg);