spl: x86: Correct the binman symbols for SPL
[platform/kernel/u-boot.git] / common / spl / spl.c
index bb91b76..4449074 100644 (file)
@@ -16,6 +16,7 @@
 #include <init.h>
 #include <irq_func.h>
 #include <log.h>
+#include <mapmem.h>
 #include <serial.h>
 #include <spl.h>
 #include <asm/global_data.h>
@@ -23,6 +24,9 @@
 #include <nand.h>
 #include <fat.h>
 #include <u-boot/crc.h>
+#if CONFIG_IS_ENABLED(BANNER_PRINT)
+#include <timestamp.h>
+#endif
 #include <version.h>
 #include <image.h>
 #include <malloc.h>
@@ -50,14 +54,19 @@ binman_sym_declare(ulong, u_boot_any, image_pos);
 binman_sym_declare(ulong, u_boot_any, size);
 
 #ifdef CONFIG_TPL
-binman_sym_declare(ulong, spl, image_pos);
-binman_sym_declare(ulong, spl, size);
+binman_sym_declare(ulong, u_boot_spl, image_pos);
+binman_sym_declare(ulong, u_boot_spl, size);
 #endif
 
+/* Define board data structure */
+static struct bd_info bdata __attribute__ ((section(".data")));
+
+#if CONFIG_IS_ENABLED(SHOW_BOOT_PROGRESS)
 /*
  * Board-specific Platform code can reimplement show_boot_progress () if needed
  */
 __weak void show_boot_progress(int val) {}
+#endif
 
 #if defined(CONFIG_SPL_OS_BOOT) || CONFIG_IS_ENABLED(HANDOFF) || \
        defined(CONFIG_SPL_ATF)
@@ -78,7 +87,7 @@ __weak int dram_init_banksize(void)
  * 0 to not start u-boot
  * positive if u-boot should start
  */
-#ifdef CONFIG_SPL_OS_BOOT
+#if CONFIG_IS_ENABLED(OS_BOOT)
 __weak int spl_start_uboot(void)
 {
        puts(SPL_TPL_PROMPT
@@ -134,14 +143,14 @@ void spl_fixup_fdt(void *fdt_blob)
 ulong spl_get_image_pos(void)
 {
        return spl_phase() == PHASE_TPL ?
-               binman_sym(ulong, spl, image_pos) :
+               binman_sym(ulong, u_boot_spl, image_pos) :
                binman_sym(ulong, u_boot_any, image_pos);
 }
 
 ulong spl_get_image_size(void)
 {
        return spl_phase() == PHASE_TPL ?
-               binman_sym(ulong, spl, size) :
+               binman_sym(ulong, u_boot_spl, size) :
                binman_sym(ulong, u_boot_any, size);
 }
 
@@ -161,6 +170,23 @@ __weak void spl_board_prepare_for_linux(void)
        /* Nothing to do! */
 }
 
+__weak void spl_board_prepare_for_optee(void *fdt)
+{
+}
+
+__weak const char *spl_board_loader_name(u32 boot_device)
+{
+       return NULL;
+}
+
+#if CONFIG_IS_ENABLED(OPTEE_IMAGE)
+__weak void __noreturn jump_to_image_optee(struct spl_image_info *spl_image)
+{
+       spl_optee_entry(NULL, NULL, spl_image->fdt_addr,
+                       (void *)spl_image->entry_point);
+}
+#endif
+
 __weak void spl_board_prepare_for_boot(void)
 {
        /* Nothing to do! */
@@ -168,7 +194,7 @@ __weak void spl_board_prepare_for_boot(void)
 
 __weak struct image_header *spl_get_load_buffer(ssize_t offset, size_t size)
 {
-       return (struct image_header *)(CONFIG_SYS_TEXT_BASE + offset);
+       return map_sysmem(CONFIG_SYS_TEXT_BASE + offset, 0);
 }
 
 void spl_set_header_raw_uboot(struct spl_image_info *spl_image)
@@ -194,14 +220,14 @@ void spl_set_header_raw_uboot(struct spl_image_info *spl_image)
        spl_image->name = "U-Boot";
 }
 
-#ifdef CONFIG_SPL_LOAD_FIT_FULL
+#if CONFIG_IS_ENABLED(LOAD_FIT_FULL)
 /* Parse and load full fitImage in SPL */
 static int spl_load_fit_image(struct spl_image_info *spl_image,
                              const struct image_header *header)
 {
        bootm_headers_t images;
        const char *fit_uname_config = NULL;
-       const char *fit_uname_fdt = FIT_FDT_PROP;
+       uintptr_t fdt_hack;
        const char *uname;
        ulong fw_data = 0, dt_data = 0, img_data = 0;
        ulong fw_len = 0, dt_len = 0, img_len = 0;
@@ -214,15 +240,33 @@ static int spl_load_fit_image(struct spl_image_info *spl_image,
        ret = fit_image_load(&images, (ulong)header,
                             NULL, &fit_uname_config,
                             IH_ARCH_DEFAULT, IH_TYPE_STANDALONE, -1,
-                            FIT_LOAD_REQUIRED, &fw_data, &fw_len);
+                            FIT_LOAD_OPTIONAL, &fw_data, &fw_len);
+       if (ret >= 0) {
+               printf("DEPRECATED: 'standalone = ' property.");
+               printf("Please use either 'firmware =' or 'kernel ='\n");
+       } else {
+               ret = fit_image_load(&images, (ulong)header, NULL,
+                                    &fit_uname_config, IH_ARCH_DEFAULT,
+                                    IH_TYPE_FIRMWARE, -1, FIT_LOAD_OPTIONAL,
+                                    &fw_data, &fw_len);
+       }
+
+       if (ret < 0) {
+               ret = fit_image_load(&images, (ulong)header, NULL,
+                                    &fit_uname_config, IH_ARCH_DEFAULT,
+                                    IH_TYPE_KERNEL, -1, FIT_LOAD_OPTIONAL,
+                                    &fw_data, &fw_len);
+       }
+
        if (ret < 0)
                return ret;
 
        spl_image->size = fw_len;
        spl_image->entry_point = fw_data;
        spl_image->load_addr = fw_data;
-       spl_image->os = IH_OS_U_BOOT;
-       spl_image->name = "U-Boot";
+       if (fit_image_get_os(header, ret, &spl_image->os))
+               spl_image->os = IH_OS_INVALID;
+       spl_image->name = genimg_get_os_name(spl_image->os);
 
        debug(SPL_TPL_PROMPT "payload image: %32s load addr: 0x%lx size: %d\n",
              spl_image->name, spl_image->load_addr, spl_image->size);
@@ -230,13 +274,21 @@ static int spl_load_fit_image(struct spl_image_info *spl_image,
 #ifdef CONFIG_SPL_FIT_SIGNATURE
        images.verify = 1;
 #endif
-       ret = fit_image_load(&images, (ulong)header,
-                      &fit_uname_fdt, &fit_uname_config,
+       ret = fit_image_load(&images, (ulong)header, NULL, &fit_uname_config,
                       IH_ARCH_DEFAULT, IH_TYPE_FLATDT, -1,
                       FIT_LOAD_OPTIONAL, &dt_data, &dt_len);
-       if (ret >= 0)
+       if (ret >= 0) {
                spl_image->fdt_addr = (void *)dt_data;
 
+               if (spl_image->os == IH_OS_U_BOOT) {
+                       /* HACK: U-boot expects FDT at a specific address */
+                       fdt_hack = spl_image->load_addr + spl_image->size;
+                       fdt_hack = (fdt_hack + 3) & ~3;
+                       debug("Relocating FDT to %p\n", spl_image->fdt_addr);
+                       memcpy((void *)fdt_hack, spl_image->fdt_addr, dt_len);
+               }
+       }
+
        conf_noffset = fit_conf_get_node((const void *)header,
                                         fit_uname_config);
        if (conf_noffset <= 0)
@@ -264,6 +316,13 @@ static int spl_load_fit_image(struct spl_image_info *spl_image,
 }
 #endif
 
+__weak int spl_parse_board_header(struct spl_image_info *spl_image,
+                                 const struct spl_boot_device *bootdev,
+                                 const void *image_header, size_t size)
+{
+       return -EINVAL;
+}
+
 __weak int spl_parse_legacy_header(struct spl_image_info *spl_image,
                                   const struct image_header *header)
 {
@@ -273,9 +332,10 @@ __weak int spl_parse_legacy_header(struct spl_image_info *spl_image,
 }
 
 int spl_parse_image_header(struct spl_image_info *spl_image,
+                          const struct spl_boot_device *bootdev,
                           const struct image_header *header)
 {
-#ifdef CONFIG_SPL_LOAD_FIT_FULL
+#if CONFIG_IS_ENABLED(LOAD_FIT_FULL)
        int ret = spl_load_fit_image(spl_image, header);
 
        if (!ret)
@@ -300,7 +360,7 @@ int spl_parse_image_header(struct spl_image_info *spl_image,
                panic("** no mkimage signature but raw image not supported");
 #endif
 
-#ifdef CONFIG_SPL_OS_BOOT
+#if CONFIG_IS_ENABLED(OS_BOOT)
                ulong start, end;
 
                if (!bootz_setup((ulong)header, &start, &end)) {
@@ -316,6 +376,9 @@ int spl_parse_image_header(struct spl_image_info *spl_image,
                }
 #endif
 
+               if (!spl_parse_board_header(spl_image, bootdev, (const void *)header, sizeof(*header)))
+                       return 0;
+
 #ifdef CONFIG_SPL_RAW_IMAGE_SUPPORT
                /* Signature not found - assume u-boot.bin */
                debug("mkimage signature not found - ih_magic = %x\n",
@@ -352,7 +415,7 @@ static int setup_spl_handoff(void)
 {
        struct spl_handoff *ho;
 
-       ho = bloblist_ensure(BLOBLISTT_SPL_HANDOFF, sizeof(struct spl_handoff));
+       ho = bloblist_ensure(BLOBLISTT_U_BOOT_SPL_HANDOFF, sizeof(struct spl_handoff));
        if (!ho)
                return -ENOENT;
 
@@ -369,7 +432,7 @@ static int write_spl_handoff(void)
        struct spl_handoff *ho;
        int ret;
 
-       ho = bloblist_find(BLOBLISTT_SPL_HANDOFF, sizeof(struct spl_handoff));
+       ho = bloblist_find(BLOBLISTT_U_BOOT_SPL_HANDOFF, sizeof(struct spl_handoff));
        if (!ho)
                return -ENOENT;
        handoff_save_dram(ho);
@@ -386,6 +449,22 @@ static inline int write_spl_handoff(void) { return 0; }
 
 #endif /* HANDOFF */
 
+/**
+ * get_bootstage_id() - Get the bootstage ID to emit
+ *
+ * @start: true if this is for starting SPL, false for ending it
+ * Return: bootstage ID to use
+ */
+static enum bootstage_id get_bootstage_id(bool start)
+{
+       enum u_boot_phase phase = spl_phase();
+
+       if (IS_ENABLED(CONFIG_TPL_BUILD) && phase == PHASE_TPL)
+               return start ? BOOTSTAGE_ID_START_TPL : BOOTSTAGE_ID_END_TPL;
+       else
+               return start ? BOOTSTAGE_ID_START_SPL : BOOTSTAGE_ID_END_SPL;
+}
+
 static int spl_common_init(bool setup_malloc)
 {
        int ret;
@@ -416,8 +495,8 @@ static int spl_common_init(bool setup_malloc)
                              __func__, ret);
        }
 #endif /* CONFIG_BOOTSTAGE_STASH */
-       bootstage_mark_name(spl_phase() == PHASE_TPL ? BOOTSTAGE_ID_START_TPL :
-                           BOOTSTAGE_ID_START_SPL, SPL_TPL_NAME);
+       bootstage_mark_name(get_bootstage_id(true),
+                           spl_phase_name(spl_phase()));
 #if CONFIG_IS_ENABLED(LOG)
        ret = log_init();
        if (ret) {
@@ -425,7 +504,7 @@ static int spl_common_init(bool setup_malloc)
                return ret;
        }
 #endif
-       if (CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA)) {
+       if (CONFIG_IS_ENABLED(OF_REAL)) {
                ret = fdtdec_setup();
                if (ret) {
                        debug("fdtdec_setup() returned error %d\n", ret);
@@ -447,19 +526,14 @@ static int spl_common_init(bool setup_malloc)
        return 0;
 }
 
-int spl_alloc_bd(void)
+void spl_set_bd(void)
 {
        /*
         * NOTE: On some platforms (e.g. x86) bdata may be in flash and not
         * writeable.
         */
-       if (!gd->bd) {
-               gd->bd = malloc(sizeof(*gd->bd));
-               if (!gd->bd)
-                       return -ENOMEM;
-       }
-
-       return 0;
+       if (!gd->bd)
+               gd->bd = &bdata;
 }
 
 int spl_early_init(void)
@@ -520,6 +594,12 @@ static struct spl_image_loader *spl_ll_find_loader(uint boot_device)
        return NULL;
 }
 
+__weak int spl_check_board_image(struct spl_image_info *spl_image,
+                                const struct spl_boot_device *bootdev)
+{
+       return 0;
+}
+
 static int spl_load_image(struct spl_image_info *spl_image,
                          struct spl_image_loader *loader)
 {
@@ -541,6 +621,9 @@ static int spl_load_image(struct spl_image_info *spl_image,
                }
        }
 #endif
+       if (!ret)
+               ret = spl_check_board_image(spl_image, &bootdev);
+
        return ret;
 }
 
@@ -550,32 +633,42 @@ static int spl_load_image(struct spl_image_info *spl_image,
  * @spl_image: Place to put the image details if successful
  * @spl_boot_list: List of boot devices to try
  * @count: Number of elements in spl_boot_list
- * @return 0 if OK, -ve on error
+ * Return: 0 if OK, -ENODEV if there were no boot devices
+ *     if CONFIG_SHOW_ERRORS is enabled, returns -ENXIO if there were
+ *     devices but none worked
  */
 static int boot_from_devices(struct spl_image_info *spl_image,
                             u32 spl_boot_list[], int count)
 {
+       int ret = -ENODEV;
        int i;
 
        for (i = 0; i < count && spl_boot_list[i] != BOOT_DEVICE_NONE; i++) {
                struct spl_image_loader *loader;
-
-               loader = spl_ll_find_loader(spl_boot_list[i]);
-#if defined(CONFIG_SPL_SERIAL_SUPPORT) \
-    && defined(CONFIG_SPL_LIBCOMMON_SUPPORT)    \
-    && !defined(CONFIG_SILENT_CONSOLE)
-               if (loader)
-                       printf("Trying to boot from %s\n", loader->name);
-               else
-                       puts(SPL_TPL_PROMPT "Unsupported Boot Device!\n");
-#endif
+               int bootdev = spl_boot_list[i];
+
+               if (CONFIG_IS_ENABLED(SHOW_ERRORS))
+                       ret = -ENXIO;
+               loader = spl_ll_find_loader(bootdev);
+               if (CONFIG_IS_ENABLED(SERIAL) &&
+                   CONFIG_IS_ENABLED(LIBCOMMON_SUPPORT) &&
+                   !IS_ENABLED(CONFIG_SILENT_CONSOLE)) {
+                       if (loader)
+                               printf("Trying to boot from %s\n",
+                                      spl_loader_name(loader));
+                       else if (CONFIG_IS_ENABLED(SHOW_ERRORS))
+                               printf(SPL_TPL_PROMPT
+                                      "Unsupported Boot Device %d\n", bootdev);
+                       else
+                               puts(SPL_TPL_PROMPT "Unsupported Boot Device!\n");
+               }
                if (loader && !spl_load_image(spl_image, loader)) {
-                       spl_image->boot_device = spl_boot_list[i];
+                       spl_image->boot_device = bootdev;
                        return 0;
                }
        }
 
-       return -ENODEV;
+       return ret;
 }
 
 #if defined(CONFIG_SPL_FRAMEWORK_BOARD_INIT_F)
@@ -609,6 +702,8 @@ void board_init_r(gd_t *dummy1, ulong dummy2)
 
        debug(">>" SPL_TPL_PROMPT "board_init_r()\n");
 
+       spl_set_bd();
+
 #if defined(CONFIG_SYS_SPL_MALLOC_START)
        mem_malloc_init(CONFIG_SYS_SPL_MALLOC_START,
                        CONFIG_SYS_SPL_MALLOC_SIZE);
@@ -618,10 +713,6 @@ void board_init_r(gd_t *dummy1, ulong dummy2)
                if (spl_init())
                        hang();
        }
-       if (IS_ENABLED(CONFIG_SPL_ALLOC_BD) && spl_alloc_bd()) {
-               puts("Cannot alloc bd\n");
-               hang();
-       }
 #if !defined(CONFIG_PPC) && !defined(CONFIG_ARCH_MX6)
        /*
         * timer_init() does not exist on PPC systems. The timer is initialized
@@ -652,7 +743,7 @@ void board_init_r(gd_t *dummy1, ulong dummy2)
        spl_board_init();
 #endif
 
-#if defined(CONFIG_SPL_WATCHDOG_SUPPORT) && CONFIG_IS_ENABLED(WDT)
+#if defined(CONFIG_SPL_WATCHDOG) && CONFIG_IS_ENABLED(WDT)
        initr_watchdog();
 #endif
 
@@ -669,9 +760,15 @@ void board_init_r(gd_t *dummy1, ulong dummy2)
        spl_image.boot_device = BOOT_DEVICE_NONE;
        board_boot_order(spl_boot_list);
 
-       if (boot_from_devices(&spl_image, spl_boot_list,
-                             ARRAY_SIZE(spl_boot_list))) {
-               puts(SPL_TPL_PROMPT "failed to boot from all boot devices\n");
+       ret = boot_from_devices(&spl_image, spl_boot_list,
+                               ARRAY_SIZE(spl_boot_list));
+       if (ret) {
+               if (CONFIG_IS_ENABLED(SHOW_ERRORS) &&
+                   CONFIG_IS_ENABLED(LIBCOMMON_SUPPORT))
+                       printf(SPL_TPL_PROMPT "failed to boot from all boot devices (err=%d)\n",
+                              ret);
+               else
+                       puts(SPL_TPL_PROMPT "failed to boot from all boot devices\n");
                hang();
        }
 
@@ -689,9 +786,6 @@ void board_init_r(gd_t *dummy1, ulong dummy2)
                               ret);
        }
 
-#ifdef CONFIG_CPU_V7M
-       spl_image.entry_point |= 0x1;
-#endif
        switch (spl_image.os) {
        case IH_OS_U_BOOT:
                debug("Jumping to %s...\n", spl_phase_name(spl_next_phase()));
@@ -703,11 +797,11 @@ void board_init_r(gd_t *dummy1, ulong dummy2)
                spl_invoke_atf(&spl_image);
                break;
 #endif
-#if CONFIG_IS_ENABLED(OPTEE)
+#if CONFIG_IS_ENABLED(OPTEE_IMAGE)
        case IH_OS_TEE:
                debug("Jumping to U-Boot via OP-TEE\n");
-               spl_optee_entry(NULL, NULL, spl_image.fdt_addr,
-                               (void *)spl_image.entry_point);
+               spl_board_prepare_for_optee(spl_image.fdt_addr);
+               jump_to_image_optee(&spl_image);
                break;
 #endif
 #if CONFIG_IS_ENABLED(OPENSBI)
@@ -716,7 +810,7 @@ void board_init_r(gd_t *dummy1, ulong dummy2)
                spl_invoke_opensbi(&spl_image);
                break;
 #endif
-#ifdef CONFIG_SPL_OS_BOOT
+#if CONFIG_IS_ENABLED(OS_BOOT)
        case IH_OS_LINUX:
                debug("Jumping to Linux\n");
 #if defined(CONFIG_SYS_SPL_ARGS_ADDR)
@@ -732,8 +826,7 @@ void board_init_r(gd_t *dummy1, ulong dummy2)
        debug("SPL malloc() used 0x%lx bytes (%ld KB)\n", gd->malloc_ptr,
              gd->malloc_ptr / 1024);
 #endif
-       bootstage_mark_name(spl_phase() == PHASE_TPL ? BOOTSTAGE_ID_END_TPL :
-                           BOOTSTAGE_ID_END_SPL, "end " SPL_TPL_NAME);
+       bootstage_mark_name(get_bootstage_id(false), "end phase");
 #ifdef CONFIG_BOOTSTAGE_STASH
        ret = bootstage_stash((void *)CONFIG_BOOTSTAGE_STASH_ADDR,
                              CONFIG_BOOTSTAGE_STASH_SIZE);
@@ -751,7 +844,7 @@ void board_init_r(gd_t *dummy1, ulong dummy2)
  */
 void preloader_console_init(void)
 {
-#ifdef CONFIG_SPL_SERIAL_SUPPORT
+#ifdef CONFIG_SPL_SERIAL
        gd->baudrate = CONFIG_BAUDRATE;
 
        serial_init();          /* serial communications setup */
@@ -806,7 +899,7 @@ __weak void spl_relocate_stack_check(void)
  * All of this is done using the same layout and alignments as done in
  * board_init_f_init_reserve() / board_init_f_alloc_reserve().
  *
- * @return new stack location, or 0 to use the same stack
+ * Return: new stack location, or 0 to use the same stack
  */
 ulong spl_relocate_stack_gd(void)
 {