+// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright 2010-2011 Calxeda, Inc.
* Copyright (c) 2014, NVIDIA CORPORATION. All rights reserved.
- *
- * SPDX-License-Identifier: GPL-2.0+
*/
#include <common.h>
#include <command.h>
+#include <env.h>
#include <malloc.h>
#include <mapmem.h>
+#include <lcd.h>
#include <linux/string.h>
#include <linux/ctype.h>
#include <errno.h>
#include <linux/list.h>
#include <fs.h>
+#include <splash.h>
#include <asm/io.h>
#include "menu.h"
const char *pxe_default_paths[] = {
#ifdef CONFIG_SYS_SOC
+#ifdef CONFIG_SYS_BOARD
+ "default-" CONFIG_SYS_ARCH "-" CONFIG_SYS_SOC "-" CONFIG_SYS_BOARD,
+#endif
"default-" CONFIG_SYS_ARCH "-" CONFIG_SYS_SOC,
#endif
"default-" CONFIG_SYS_ARCH,
static bool is_pxe;
/*
- * Like getenv, but prints an error if envvar isn't defined in the
- * environment. It always returns what getenv does, so it can be used in
- * place of getenv without changing error handling otherwise.
+ * Like env_get, but prints an error if envvar isn't defined in the
+ * environment. It always returns what env_get does, so it can be used in
+ * place of env_get without changing error handling otherwise.
*/
static char *from_env(const char *envvar)
{
char *ret;
- ret = getenv(envvar);
+ ret = env_get(envvar);
if (!ret)
printf("missing environment variable: %s\n", envvar);
return -EINVAL;
}
- if (!eth_getenv_enetaddr_by_index("eth", eth_get_dev_index(),
- ethaddr))
+ if (!eth_env_get_enetaddr_by_index("eth", eth_get_dev_index(), ethaddr))
return -ENOENT;
sprintf(outbuf, "01-%02x-%02x-%02x-%02x-%02x-%02x",
char *name;
char *menu;
char *kernel;
+ char *config;
char *append;
char *initrd;
char *fdt;
*
* title - the name of the menu as given by a 'menu title' line.
* default_label - the name of the default label, if any.
+ * bmp - the bmp file name which is displayed in background
* timeout - time in tenths of a second to wait for a user key-press before
* booting the default label.
* prompt - if 0, don't prompt for a choice unless the timeout period is
struct pxe_menu {
char *title;
char *default_label;
+ char *bmp;
int timeout;
int prompt;
struct list_head labels;
if (label->kernel)
free(label->kernel);
+ if (label->config)
+ free(label->config);
+
if (label->append)
free(label->append);
/*
* Boot a label that specified 'localboot'. This requires that the 'localcmd'
- * environment variable is defined. Its contents will be executed as U-boot
+ * environment variable is defined. Its contents will be executed as U-Boot
* command. If the label specified an 'append' line, its contents will be
* used to overwrite the contents of the 'bootargs' environment variable prior
* to running 'localcmd'.
char bootargs[CONFIG_SYS_CBSIZE];
cli_simple_process_macros(label->append, bootargs);
- setenv("bootargs", bootargs);
+ env_set("bootargs", bootargs);
}
debug("running: %s\n", localcmd);
static int label_boot(cmd_tbl_t *cmdtp, struct pxe_label *label)
{
char *bootm_argv[] = { "bootm", NULL, NULL, NULL, NULL };
- char initrd_str[22];
+ char initrd_str[28];
char mac_str[29] = "";
char ip_str[68] = "";
- int bootm_argc = 3;
+ char *fit_addr = NULL;
+ int bootm_argc = 2;
int len = 0;
ulong kernel_addr;
void *buf;
}
bootm_argv[2] = initrd_str;
- strcpy(bootm_argv[2], getenv("ramdisk_addr_r"));
+ strncpy(bootm_argv[2], env_get("ramdisk_addr_r"), 18);
strcat(bootm_argv[2], ":");
- strcat(bootm_argv[2], getenv("filesize"));
- } else {
- bootm_argv[2] = "-";
+ strncat(bootm_argv[2], env_get("filesize"), 9);
}
if (get_relfile_envaddr(cmdtp, label->kernel, "kernel_addr_r") < 0) {
if (label->ipappend & 0x1) {
sprintf(ip_str, " ip=%s:%s:%s:%s",
- getenv("ipaddr"), getenv("serverip"),
- getenv("gatewayip"), getenv("netmask"));
+ env_get("ipaddr"), env_get("serverip"),
+ env_get("gatewayip"), env_get("netmask"));
}
#ifdef CONFIG_CMD_NET
strlen(ip_str), strlen(mac_str),
sizeof(bootargs));
return 1;
+ } else {
+ if (label->append)
+ strncpy(bootargs, label->append,
+ sizeof(bootargs));
+ strcat(bootargs, ip_str);
+ strcat(bootargs, mac_str);
+
+ cli_simple_process_macros(bootargs, finalbootargs);
+ env_set("bootargs", finalbootargs);
+ printf("append: %s\n", finalbootargs);
}
+ }
- if (label->append)
- strcpy(bootargs, label->append);
- strcat(bootargs, ip_str);
- strcat(bootargs, mac_str);
+ bootm_argv[1] = env_get("kernel_addr_r");
+ /* for FIT, append the configuration identifier */
+ if (label->config) {
+ int len = strlen(bootm_argv[1]) + strlen(label->config) + 1;
- cli_simple_process_macros(bootargs, finalbootargs);
- setenv("bootargs", finalbootargs);
- printf("append: %s\n", finalbootargs);
+ fit_addr = malloc(len);
+ if (!fit_addr) {
+ printf("malloc fail (FIT address)\n");
+ return 1;
+ }
+ snprintf(fit_addr, len, "%s%s", bootm_argv[1], label->config);
+ bootm_argv[1] = fit_addr;
}
- bootm_argv[1] = getenv("kernel_addr_r");
-
/*
* fdt usage is optional:
* It handles the following scenarios. All scenarios are exclusive
*
* Scenario 3: fdt blob is not available.
*/
- bootm_argv[3] = getenv("fdt_addr_r");
+ bootm_argv[3] = env_get("fdt_addr_r");
/* if fdt label is defined then get fdt from server */
if (bootm_argv[3]) {
} else if (label->fdtdir) {
char *f1, *f2, *f3, *f4, *slash;
- f1 = getenv("fdtfile");
+ f1 = env_get("fdtfile");
if (f1) {
f2 = "";
f3 = "";
* or the boot scripts should set $fdtfile
* before invoking "pxe" or "sysboot".
*/
- f1 = getenv("soc");
+ f1 = env_get("soc");
f2 = "-";
- f3 = getenv("board");
+ f3 = env_get("board");
f4 = ".dtb";
}
fdtfilefree = malloc(len);
if (!fdtfilefree) {
printf("malloc fail (FDT filename)\n");
- return 1;
+ goto cleanup;
}
snprintf(fdtfilefree, len, "%s%s%s%s%s%s",
if (err < 0) {
printf("Skipping %s for failure retrieving fdt\n",
label->name);
- return 1;
+ goto cleanup;
}
} else {
bootm_argv[3] = NULL;
}
if (!bootm_argv[3])
- bootm_argv[3] = getenv("fdt_addr");
+ bootm_argv[3] = env_get("fdt_addr");
- if (bootm_argv[3])
+ if (bootm_argv[3]) {
+ if (!bootm_argv[2])
+ bootm_argv[2] = "-";
bootm_argc = 4;
+ }
kernel_addr = genimg_get_kernel_addr(bootm_argv[1]);
buf = map_sysmem(kernel_addr, 0);
do_bootz(cmdtp, 0, bootm_argc, bootm_argv);
#endif
unmap_sysmem(buf);
+
+cleanup:
+ if (fit_addr)
+ free(fit_addr);
return 1;
}
T_FDTDIR,
T_ONTIMEOUT,
T_IPAPPEND,
+ T_BACKGROUND,
T_INVALID
};
{"fdtdir", T_FDTDIR},
{"ontimeout", T_ONTIMEOUT,},
{"ipappend", T_IPAPPEND,},
+ {"background", T_BACKGROUND,},
{NULL, T_INVALID}
};
nest_level + 1);
break;
+ case T_BACKGROUND:
+ err = parse_sliteral(c, &cfg->bmp);
+ break;
+
default:
printf("Ignoring malformed menu command: %.*s\n",
(int)(*c - s), s);
return 0;
}
+/*
+ * Handles parsing a 'kernel' label.
+ * expecting "filename" or "<fit_filename>#cfg"
+ */
+static int parse_label_kernel(char **c, struct pxe_label *label)
+{
+ char *s;
+ int err;
+
+ err = parse_sliteral(c, &label->kernel);
+ if (err < 0)
+ return err;
+
+ s = strstr(label->kernel, "#");
+ if (!s)
+ return 1;
+
+ label->config = malloc(strlen(s) + 1);
+ if (!label->config)
+ return -ENOMEM;
+
+ strcpy(label->config, s);
+ *s = 0;
+
+ return 1;
+}
+
/*
* Parses a label and adds it to the list of labels for a menu.
*
case T_KERNEL:
case T_LINUX:
- err = parse_sliteral(c, &label->kernel);
+ err = parse_label_kernel(c, label);
break;
case T_APPEND:
}
/*
- * Converts a pxe_menu struct into a menu struct for use with U-boot's generic
+ * Converts a pxe_menu struct into a menu struct for use with U-Boot's generic
* menu code.
*/
static struct menu *pxe_menu_to_menu(struct pxe_menu *cfg)
/*
* Create a menu and add items for all the labels.
*/
- m = menu_create(cfg->title, cfg->timeout, cfg->prompt, label_print,
- NULL, NULL);
+ m = menu_create(cfg->title, DIV_ROUND_UP(cfg->timeout, 10),
+ cfg->prompt, label_print, NULL, NULL);
if (!m)
return NULL;
struct menu *m;
int err;
+#ifdef CONFIG_CMD_BMP
+ /* display BMP if available */
+ if (cfg->bmp) {
+ if (get_relfile(cmdtp, cfg->bmp, load_addr)) {
+ run_command("cls", 0);
+ bmp_display(load_addr,
+ BMP_ALIGN_CENTER, BMP_ALIGN_CENTER);
+ } else {
+ printf("Skipping background bmp %s for failure\n",
+ cfg->bmp);
+ }
+ }
+#endif
+
m = pxe_menu_to_menu(cfg);
if (!m)
return;
}
if (argc < 6)
- filename = getenv("bootfile");
+ filename = env_get("bootfile");
else {
filename = argv[5];
- setenv("bootfile", filename);
+ env_set("bootfile", filename);
}
if (strstr(argv[3], "ext2"))