arm: a37xx: pci: Fix a3700_fdt_fix_pcie_regions() function
[pandora-u-boot.git] / cmd / pxe_utils.c
index 9ec7e3b..71c5af4 100644 (file)
@@ -5,10 +5,16 @@
  */
 
 #include <common.h>
+#include <command.h>
 #include <env.h>
+#include <image.h>
+#include <log.h>
 #include <malloc.h>
 #include <mapmem.h>
 #include <lcd.h>
+#include <net.h>
+#include <fdt_support.h>
+#include <linux/libfdt.h>
 #include <linux/string.h>
 #include <linux/ctype.h>
 #include <errno.h>
@@ -22,7 +28,7 @@
 
 #include "pxe_utils.h"
 
-#define MAX_TFTP_PATH_LEN 127
+#define MAX_TFTP_PATH_LEN 512
 
 bool is_pxe;
 
@@ -78,14 +84,14 @@ static int get_bootfile_path(const char *file_path, char *bootfile_path,
 
        last_slash = strrchr(bootfile, '/');
 
-       if (last_slash == NULL                          )
+       if (!last_slash)
                goto ret;
 
        path_len = (last_slash - bootfile) + 1;
 
        if (bootfile_path_size < path_len) {
                printf("bootfile_path too small. (%zd < %zd)\n",
-                               bootfile_path_size, path_len);
+                      bootfile_path_size, path_len);
 
                return -1;
        }
@@ -98,7 +104,8 @@ static int get_bootfile_path(const char *file_path, char *bootfile_path,
        return 1;
 }
 
-int (*do_getfile)(cmd_tbl_t *cmdtp, const char *file_path, char *file_addr);
+int (*do_getfile)(struct cmd_tbl *cmdtp, const char *file_path,
+                 char *file_addr);
 
 /*
  * As in pxelinux, paths to files referenced from files we retrieve are
@@ -108,11 +115,11 @@ int (*do_getfile)(cmd_tbl_t *cmdtp, const char *file_path, char *file_addr);
  *
  * Returns 1 for success, or < 0 on error.
  */
-static int get_relfile(cmd_tbl_t *cmdtp, const char *file_path,
-       unsigned long file_addr)
+static int get_relfile(struct cmd_tbl *cmdtp, const char *file_path,
+                      unsigned long file_addr)
 {
        size_t path_len;
-       char relfile[MAX_TFTP_PATH_LEN+1];
+       char relfile[MAX_TFTP_PATH_LEN + 1];
        char addr_buf[18];
        int err;
 
@@ -125,9 +132,7 @@ static int get_relfile(cmd_tbl_t *cmdtp, const char *file_path,
        path_len += strlen(relfile);
 
        if (path_len > MAX_TFTP_PATH_LEN) {
-               printf("Base path too long (%s%s)\n",
-                                       relfile,
-                                       file_path);
+               printf("Base path too long (%s%s)\n", relfile, file_path);
 
                return -ENAMETOOLONG;
        }
@@ -148,8 +153,8 @@ static int get_relfile(cmd_tbl_t *cmdtp, const char *file_path,
  *
  * Returns 1 on success, or < 0 for error.
  */
-int get_pxe_file(cmd_tbl_t *cmdtp, const char *file_path,
-       unsigned long file_addr)
+int get_pxe_file(struct cmd_tbl *cmdtp, const char *file_path,
+                unsigned long file_addr)
 {
        unsigned long config_file_size;
        char *tftp_filesize;
@@ -182,7 +187,6 @@ int get_pxe_file(cmd_tbl_t *cmdtp, const char *file_path,
 
 #define PXELINUX_DIR "pxelinux.cfg/"
 
-
 /*
  * Retrieves a file in the 'pxelinux.cfg' folder. Since this uses get_pxe_file
  * to do the hard work, the location of the 'pxelinux.cfg' folder is generated
@@ -190,15 +194,15 @@ int get_pxe_file(cmd_tbl_t *cmdtp, const char *file_path,
  *
  * Returns 1 on success or < 0 on error.
  */
-int get_pxelinux_path(cmd_tbl_t *cmdtp, const char *file,
-       unsigned long pxefile_addr_r)
+int get_pxelinux_path(struct cmd_tbl *cmdtp, const char *file,
+                     unsigned long pxefile_addr_r)
 {
        size_t base_len = strlen(PXELINUX_DIR);
-       char path[MAX_TFTP_PATH_LEN+1];
+       char path[MAX_TFTP_PATH_LEN + 1];
 
        if (base_len + strlen(file) > MAX_TFTP_PATH_LEN) {
                printf("path (%s%s) too long, skipping\n",
-                               PXELINUX_DIR, file);
+                      PXELINUX_DIR, file);
                return -ENAMETOOLONG;
        }
 
@@ -214,7 +218,8 @@ int get_pxelinux_path(cmd_tbl_t *cmdtp, const char *file,
  *
  * Returns 1 on success or < 0 on error.
  */
-static int get_relfile_envaddr(cmd_tbl_t *cmdtp, const char *file_path, const char *envaddr_name)
+static int get_relfile_envaddr(struct cmd_tbl *cmdtp, const char *file_path,
+                              const char *envaddr_name)
 {
        unsigned long file_addr;
        char *envaddr;
@@ -281,6 +286,9 @@ static void label_destroy(struct pxe_label *label)
        if (label->fdtdir)
                free(label->fdtdir);
 
+       if (label->fdtoverlays)
+               free(label->fdtoverlays);
+
        free(label);
 }
 
@@ -319,7 +327,8 @@ static int label_localboot(struct pxe_label *label)
        if (label->append) {
                char bootargs[CONFIG_SYS_CBSIZE];
 
-               cli_simple_process_macros(label->append, bootargs);
+               cli_simple_process_macros(label->append, bootargs,
+                                         sizeof(bootargs));
                env_set("bootargs", bootargs);
        }
 
@@ -328,6 +337,92 @@ static int label_localboot(struct pxe_label *label)
        return run_command_list(localcmd, strlen(localcmd), 0);
 }
 
+/*
+ * Loads fdt overlays specified in 'fdtoverlays'.
+ */
+#ifdef CONFIG_OF_LIBFDT_OVERLAY
+static void label_boot_fdtoverlay(struct cmd_tbl *cmdtp, struct pxe_label *label)
+{
+       char *fdtoverlay = label->fdtoverlays;
+       struct fdt_header *working_fdt;
+       char *fdtoverlay_addr_env;
+       ulong fdtoverlay_addr;
+       ulong fdt_addr;
+       int err;
+
+       /* Get the main fdt and map it */
+       fdt_addr = simple_strtoul(env_get("fdt_addr_r"), NULL, 16);
+       working_fdt = map_sysmem(fdt_addr, 0);
+       err = fdt_check_header(working_fdt);
+       if (err)
+               return;
+
+       /* Get the specific overlay loading address */
+       fdtoverlay_addr_env = env_get("fdtoverlay_addr_r");
+       if (!fdtoverlay_addr_env) {
+               printf("Invalid fdtoverlay_addr_r for loading overlays\n");
+               return;
+       }
+
+       fdtoverlay_addr = simple_strtoul(fdtoverlay_addr_env, NULL, 16);
+
+       /* Cycle over the overlay files and apply them in order */
+       do {
+               struct fdt_header *blob;
+               char *overlayfile;
+               char *end;
+               int len;
+
+               /* Drop leading spaces */
+               while (*fdtoverlay == ' ')
+                       ++fdtoverlay;
+
+               /* Copy a single filename if multiple provided */
+               end = strstr(fdtoverlay, " ");
+               if (end) {
+                       len = (int)(end - fdtoverlay);
+                       overlayfile = malloc(len + 1);
+                       strncpy(overlayfile, fdtoverlay, len);
+                       overlayfile[len] = '\0';
+               } else
+                       overlayfile = fdtoverlay;
+
+               if (!strlen(overlayfile))
+                       goto skip_overlay;
+
+               /* Load overlay file */
+               err = get_relfile_envaddr(cmdtp, overlayfile,
+                                         "fdtoverlay_addr_r");
+               if (err < 0) {
+                       printf("Failed loading overlay %s\n", overlayfile);
+                       goto skip_overlay;
+               }
+
+               /* Resize main fdt */
+               fdt_shrink_to_minimum(working_fdt, 8192);
+
+               blob = map_sysmem(fdtoverlay_addr, 0);
+               err = fdt_check_header(blob);
+               if (err) {
+                       printf("Invalid overlay %s, skipping\n",
+                              overlayfile);
+                       goto skip_overlay;
+               }
+
+               err = fdt_overlay_apply_verbose(working_fdt, blob);
+               if (err) {
+                       printf("Failed to apply overlay %s, skipping\n",
+                              overlayfile);
+                       goto skip_overlay;
+               }
+
+skip_overlay:
+               if (end)
+                       free(overlayfile);
+       } while ((fdtoverlay = strstr(fdtoverlay, " ")));
+}
+#endif
+
 /*
  * Boot according to the contents of a pxe_label.
  *
@@ -343,7 +438,7 @@ static int label_localboot(struct pxe_label *label)
  * If the label specifies an 'append' line, its contents will overwrite that
  * of the 'bootargs' environment variable.
  */
-static int label_boot(cmd_tbl_t *cmdtp, struct pxe_label *label)
+static int label_boot(struct cmd_tbl *cmdtp, struct pxe_label *label)
 {
        char *bootm_argv[] = { "bootm", NULL, NULL, NULL, NULL };
        char initrd_str[28];
@@ -365,16 +460,16 @@ static int label_boot(cmd_tbl_t *cmdtp, struct pxe_label *label)
                return 0;
        }
 
-       if (label->kernel == NULL) {
+       if (!label->kernel) {
                printf("No kernel given, skipping %s\n",
-                               label->name);
+                      label->name);
                return 1;
        }
 
        if (label->initrd) {
                if (get_relfile_envaddr(cmdtp, label->initrd, "ramdisk_addr_r") < 0) {
                        printf("Skipping %s for failure retrieving initrd\n",
-                                       label->name);
+                              label->name);
                        return 1;
                }
 
@@ -387,7 +482,7 @@ static int label_boot(cmd_tbl_t *cmdtp, struct pxe_label *label)
 
        if (get_relfile_envaddr(cmdtp, label->kernel, "kernel_addr_r") < 0) {
                printf("Skipping %s for failure retrieving kernel\n",
-                               label->name);
+                      label->name);
                return 1;
        }
 
@@ -397,15 +492,16 @@ static int label_boot(cmd_tbl_t *cmdtp, struct pxe_label *label)
                        env_get("gatewayip"), env_get("netmask"));
        }
 
-#ifdef CONFIG_CMD_NET
-       if (label->ipappend & 0x2) {
-               int err;
-               strcpy(mac_str, " BOOTIF=");
-               err = format_mac_pxe(mac_str + 8, sizeof(mac_str) - 8);
-               if (err < 0)
-                       mac_str[0] = '\0';
+       if (IS_ENABLED(CONFIG_CMD_NET)) {
+               if (label->ipappend & 0x2) {
+                       int err;
+
+                       strcpy(mac_str, " BOOTIF=");
+                       err = format_mac_pxe(mac_str + 8, sizeof(mac_str) - 8);
+                       if (err < 0)
+                               mac_str[0] = '\0';
+               }
        }
-#endif
 
        if ((label->ipappend & 0x3) || label->append) {
                char bootargs[CONFIG_SYS_CBSIZE] = "";
@@ -418,17 +514,18 @@ static int label_boot(cmd_tbl_t *cmdtp, struct pxe_label *label)
                               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)
+                       strncpy(bootargs, label->append, sizeof(bootargs));
+
+               strcat(bootargs, ip_str);
+               strcat(bootargs, mac_str);
+
+               cli_simple_process_macros(bootargs, finalbootargs,
+                                         sizeof(finalbootargs));
+               env_set("bootargs", finalbootargs);
+               printf("append: %s\n", finalbootargs);
        }
 
        bootm_argv[1] = env_get("kernel_addr_r");
@@ -447,11 +544,14 @@ static int label_boot(cmd_tbl_t *cmdtp, struct pxe_label *label)
 
        /*
         * fdt usage is optional:
-        * It handles the following scenarios. All scenarios are exclusive
+        * It handles the following scenarios.
+        *
+        * Scenario 1: If fdt_addr_r specified and "fdt" or "fdtdir" label is
+        * defined in pxe file, retrieve fdt blob from server. Pass fdt_addr_r to
+        * bootm, and adjust argc appropriately.
         *
-        * Scenario 1: If fdt_addr_r specified and "fdt" label is defined in
-        * pxe file, retrieve fdt blob from server. Pass fdt_addr_r to bootm,
-        * and adjust argc appropriately.
+        * If retrieve fails and no exact fdt blob is specified in pxe file with
+        * "fdt" label, try Scenario 2.
         *
         * Scenario 2: If there is an fdt_addr specified, pass it along to
         * bootm, and adjust argc appropriately.
@@ -512,13 +612,24 @@ static int label_boot(cmd_tbl_t *cmdtp, struct pxe_label *label)
                }
 
                if (fdtfile) {
-                       int err = get_relfile_envaddr(cmdtp, fdtfile, "fdt_addr_r");
+                       int err = get_relfile_envaddr(cmdtp, fdtfile,
+                                                     "fdt_addr_r");
+
                        free(fdtfilefree);
                        if (err < 0) {
-                               printf("Skipping %s for failure retrieving fdt\n",
-                                               label->name);
-                               goto cleanup;
+                               bootm_argv[3] = NULL;
+
+                               if (label->fdt) {
+                                       printf("Skipping %s for failure retrieving FDT\n",
+                                              label->name);
+                                       goto cleanup;
+                               }
                        }
+
+#ifdef CONFIG_OF_LIBFDT_OVERLAY
+                       if (label->fdtoverlays)
+                               label_boot_fdtoverlay(cmdtp, label);
+#endif
                } else {
                        bootm_argv[3] = NULL;
                }
@@ -538,15 +649,16 @@ static int label_boot(cmd_tbl_t *cmdtp, struct pxe_label *label)
        /* Try bootm for legacy and FIT format image */
        if (genimg_get_format(buf) != IMAGE_FORMAT_INVALID)
                do_bootm(cmdtp, 0, bootm_argc, bootm_argv);
-#ifdef CONFIG_CMD_BOOTI
        /* Try booting an AArch64 Linux kernel image */
-       else
+       else if (IS_ENABLED(CONFIG_CMD_BOOTI))
                do_booti(cmdtp, 0, bootm_argc, bootm_argv);
-#elif defined(CONFIG_CMD_BOOTZ)
        /* Try booting a Image */
-       else
+       else if (IS_ENABLED(CONFIG_CMD_BOOTZ))
                do_bootz(cmdtp, 0, bootm_argc, bootm_argv);
-#endif
+       /* 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);
+
        unmap_sysmem(buf);
 
 cleanup:
@@ -576,6 +688,7 @@ enum token_type {
        T_INCLUDE,
        T_FDT,
        T_FDTDIR,
+       T_FDTOVERLAYS,
        T_ONTIMEOUT,
        T_IPAPPEND,
        T_BACKGROUND,
@@ -610,6 +723,7 @@ static const struct token keywords[] = {
        {"fdt", T_FDT},
        {"devicetreedir", T_FDTDIR},
        {"fdtdir", T_FDTDIR},
+       {"fdtoverlays", T_FDTOVERLAYS},
        {"ontimeout", T_ONTIMEOUT,},
        {"ipappend", T_IPAPPEND,},
        {"background", T_BACKGROUND,},
@@ -659,7 +773,8 @@ static char *get_string(char **p, struct token *t, char delim, int lower)
         * e is incremented until we find the ending delimiter, or a NUL byte
         * is reached. Then, we take e - b to find the length of the token.
         */
-       b = e = *p;
+       b = *p;
+       e = *p;
 
        while (*e) {
                if ((delim == ' ' && isspace(*e)) || delim == *e)
@@ -818,8 +933,8 @@ static int parse_integer(char **c, int *dst)
        return 1;
 }
 
-static int parse_pxefile_top(cmd_tbl_t *cmdtp, char *p, unsigned long base,
-       struct pxe_menu *cfg, int nest_level);
+static int parse_pxefile_top(struct cmd_tbl *cmdtp, char *p, unsigned long base,
+                            struct pxe_menu *cfg, int nest_level);
 
 /*
  * Parse an include statement, and retrieve and parse the file it mentions.
@@ -829,8 +944,8 @@ static int parse_pxefile_top(cmd_tbl_t *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(cmd_tbl_t *cmdtp, char **c, unsigned long base,
-                               struct pxe_menu *cfg, int nest_level)
+static int handle_include(struct cmd_tbl *cmdtp, char **c, unsigned long base,
+                         struct pxe_menu *cfg, int nest_level)
 {
        char *include_path;
        char *s = *c;
@@ -841,8 +956,7 @@ static int handle_include(cmd_tbl_t *cmdtp, char **c, unsigned long base,
        err = parse_sliteral(c, &include_path);
 
        if (err < 0) {
-               printf("Expected include path: %.*s\n",
-                                (int)(*c - s), s);
+               printf("Expected include path: %.*s\n", (int)(*c - s), s);
                return err;
        }
 
@@ -870,8 +984,8 @@ static int handle_include(cmd_tbl_t *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(cmd_tbl_t *cmdtp, char **c, struct pxe_menu *cfg,
-                               unsigned long base, int nest_level)
+static int parse_menu(struct cmd_tbl *cmdtp, char **c, struct pxe_menu *cfg,
+                     unsigned long base, int nest_level)
 {
        struct token t;
        char *s = *c;
@@ -886,8 +1000,7 @@ static int parse_menu(cmd_tbl_t *cmdtp, char **c, struct pxe_menu *cfg,
                break;
 
        case T_INCLUDE:
-               err = handle_include(cmdtp, c, base, cfg,
-                                               nest_level + 1);
+               err = handle_include(cmdtp, c, base, cfg, nest_level + 1);
                break;
 
        case T_BACKGROUND:
@@ -896,7 +1009,7 @@ static int parse_menu(cmd_tbl_t *cmdtp, char **c, struct pxe_menu *cfg,
 
        default:
                printf("Ignoring malformed menu command: %.*s\n",
-                               (int)(*c - s), s);
+                      (int)(*c - s), s);
        }
 
        if (err < 0)
@@ -911,7 +1024,7 @@ static int parse_menu(cmd_tbl_t *cmdtp, char **c, struct pxe_menu *cfg,
  * Handles parsing a 'menu line' when we're parsing a label.
  */
 static int parse_label_menu(char **c, struct pxe_menu *cfg,
-                               struct pxe_label *label)
+                           struct pxe_label *label)
 {
        struct token t;
        char *s;
@@ -934,7 +1047,7 @@ static int parse_label_menu(char **c, struct pxe_menu *cfg,
                break;
        default:
                printf("Ignoring malformed menu command: %.*s\n",
-                               (int)(*c - s), s);
+                      (int)(*c - s), s);
        }
 
        eol_or_eof(c);
@@ -1043,6 +1156,11 @@ static int parse_label(char **c, struct pxe_menu *cfg)
                                err = parse_sliteral(c, &label->fdtdir);
                        break;
 
+               case T_FDTOVERLAYS:
+                       if (!label->fdtoverlays)
+                               err = parse_sliteral(c, &label->fdtoverlays);
+                       break;
+
                case T_LOCALBOOT:
                        label->localboot = 1;
                        err = parse_integer(c, &label->localboot_val);
@@ -1084,8 +1202,8 @@ static int parse_label(char **c, struct pxe_menu *cfg)
  *
  * Returns 1 on success, < 0 on error.
  */
-static int parse_pxefile_top(cmd_tbl_t *cmdtp, char *p, unsigned long base,
-                               struct pxe_menu *cfg, int nest_level)
+static int parse_pxefile_top(struct cmd_tbl *cmdtp, char *p, unsigned long base,
+                            struct pxe_menu *cfg, int nest_level)
 {
        struct token t;
        char *s, *b, *label_name;
@@ -1108,8 +1226,8 @@ static int parse_pxefile_top(cmd_tbl_t *cmdtp, char *p, unsigned long base,
                case T_MENU:
                        cfg->prompt = 1;
                        err = parse_menu(cmdtp, &p, cfg,
-                               base + ALIGN(strlen(b) + 1, 4),
-                               nest_level);
+                                        base + ALIGN(strlen(b) + 1, 4),
+                                        nest_level);
                        break;
 
                case T_TIMEOUT:
@@ -1135,8 +1253,8 @@ static int parse_pxefile_top(cmd_tbl_t *cmdtp, char *p, unsigned long base,
 
                case T_INCLUDE:
                        err = handle_include(cmdtp, &p,
-                               base + ALIGN(strlen(b), 4), cfg,
-                               nest_level + 1);
+                                            base + ALIGN(strlen(b), 4), cfg,
+                                            nest_level + 1);
                        break;
 
                case T_PROMPT:
@@ -1151,7 +1269,7 @@ static int parse_pxefile_top(cmd_tbl_t *cmdtp, char *p, unsigned long base,
 
                default:
                        printf("Ignoring unknown command: %.*s\n",
-                                                       (int)(p - s), s);
+                              (int)(p - s), s);
                        eol_or_eof(&p);
                }
 
@@ -1192,7 +1310,7 @@ void destroy_pxe_menu(struct pxe_menu *cfg)
  * files it includes). The resulting pxe_menu struct can be free()'d by using
  * the destroy_pxe_menu() function.
  */
-struct pxe_menu *parse_pxefile(cmd_tbl_t *cmdtp, unsigned long menucfg)
+struct pxe_menu *parse_pxefile(struct cmd_tbl *cmdtp, unsigned long menucfg)
 {
        struct pxe_menu *cfg;
        char *buf;
@@ -1236,7 +1354,7 @@ 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, DIV_ROUND_UP(cfg->timeout, 10),
-                       cfg->prompt, label_print, NULL, NULL);
+                       cfg->prompt, NULL, label_print, NULL, NULL);
 
        if (!m)
                return NULL;
@@ -1252,7 +1370,6 @@ static struct menu *pxe_menu_to_menu(struct pxe_menu *cfg)
                if (cfg->default_label &&
                    (strcmp(label->name, cfg->default_label) == 0))
                        default_num = label->num;
-
        }
 
        /*
@@ -1277,7 +1394,7 @@ 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(cmd_tbl_t *cmdtp, struct pxe_menu *cfg)
+static void boot_unattempted_labels(struct cmd_tbl *cmdtp, struct pxe_menu *cfg)
 {
        struct list_head *pos;
        struct pxe_label *label;
@@ -1302,25 +1419,26 @@ static void boot_unattempted_labels(cmd_tbl_t *cmdtp, struct pxe_menu *cfg)
  * If this function returns, there weren't any labels that successfully
  * booted, or the user interrupted the menu selection via ctrl+c.
  */
-void handle_pxe_menu(cmd_tbl_t *cmdtp, struct pxe_menu *cfg)
+void handle_pxe_menu(struct cmd_tbl *cmdtp, struct pxe_menu *cfg)
 {
        void *choice;
        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);
+       if (IS_ENABLED(CONFIG_CMD_BMP)) {
+               /* display BMP if available */
+               if (cfg->bmp) {
+                       if (get_relfile(cmdtp, cfg->bmp, image_load_addr)) {
+                               if (CONFIG_IS_ENABLED(CMD_CLS))
+                                       run_command("cls", 0);
+                               bmp_display(image_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)