summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--common/spl/spl_fit.c86
1 files changed, 56 insertions, 30 deletions
diff --git a/common/spl/spl_fit.c b/common/spl/spl_fit.c
index 32d9ee5901..c496f45b72 100644
--- a/common/spl/spl_fit.c
+++ b/common/spl/spl_fit.c
@@ -218,6 +218,30 @@ static int spl_load_fit_image(struct spl_load_info *info, ulong sector,
return 0;
}
+static int spl_fit_append_fdt(struct spl_image_info *spl_image,
+ struct spl_load_info *info, ulong sector,
+ void *fit, int images, ulong base_offset)
+{
+ struct spl_image_info image_info;
+ int node, ret;
+
+ /* Figure out which device tree the board wants to use */
+ node = spl_fit_get_image_node(fit, images, FIT_FDT_PROP, 0);
+ if (node < 0) {
+ debug("%s: cannot find FDT node\n", __func__);
+ return node;
+ }
+
+ /*
+ * Read the device tree and place it after the image.
+ * Align the destination address to ARCH_DMA_MINALIGN.
+ */
+ image_info.load_addr = spl_image->load_addr + spl_image->size;
+ ret = spl_load_fit_image(info, sector, fit, base_offset, node,
+ &image_info);
+ return ret;
+}
+
int spl_load_simple_fit(struct spl_image_info *spl_image,
struct spl_load_info *info, ulong sector, void *fit)
{
@@ -225,7 +249,6 @@ int spl_load_simple_fit(struct spl_image_info *spl_image,
ulong size;
unsigned long count;
struct spl_image_info image_info;
- bool boot_os = false;
int node = -1;
int images, ret;
int base_offset, align_len = ARCH_DMA_MINALIGN - 1;
@@ -273,17 +296,18 @@ int spl_load_simple_fit(struct spl_image_info *spl_image,
return -1;
}
+ /*
+ * Find the U-Boot image using the following search order:
+ * - start at 'firmware' (e.g. an ARM Trusted Firmware)
+ * - fall back 'kernel' (e.g. a Falcon-mode OS boot
+ * - fall back to using the first 'loadables' entry
+ */
+ if (node < 0)
+ node = spl_fit_get_image_node(fit, images, "firmware", 0);
#ifdef CONFIG_SPL_OS_BOOT
- /* Find OS image first */
- node = spl_fit_get_image_node(fit, images, FIT_KERNEL_PROP, 0);
if (node < 0)
- debug("No kernel image.\n");
- else
- boot_os = true;
+ node = spl_fit_get_image_node(fit, images, FIT_KERNEL_PROP, 0);
#endif
- /* find the U-Boot image */
- if (node < 0)
- node = spl_fit_get_image_node(fit, images, "firmware", 0);
if (node < 0) {
debug("could not find firmware image, trying loadables...\n");
node = spl_fit_get_image_node(fit, images, "loadables", 0);
@@ -305,34 +329,29 @@ int spl_load_simple_fit(struct spl_image_info *spl_image,
if (ret)
return ret;
-#ifdef CONFIG_SPL_OS_BOOT
+ /*
+ * For backward compatibility, we treat the first node that is
+ * as a U-Boot image, if no OS-type has been declared.
+ */
if (!fit_image_get_os(fit, node, &spl_image->os))
debug("Image OS is %s\n", genimg_get_os_name(spl_image->os));
-#else
- spl_image->os = IH_OS_U_BOOT;
+#if !defined(CONFIG_SPL_OS_BOOT)
+ else
+ spl_image->os = IH_OS_U_BOOT;
#endif
- if (!boot_os) {
- /* Figure out which device tree the board wants to use */
- node = spl_fit_get_image_node(fit, images, FIT_FDT_PROP, 0);
- if (node < 0) {
- debug("%s: cannot find FDT node\n", __func__);
- return node;
- }
-
- /*
- * Read the device tree and place it after the image.
- * Align the destination address to ARCH_DMA_MINALIGN.
- */
- image_info.load_addr = spl_image->load_addr + spl_image->size;
- ret = spl_load_fit_image(info, sector, fit, base_offset, node,
- &image_info);
- if (ret < 0)
- return ret;
- }
+ /*
+ * Booting a next-stage U-Boot may require us to append the FDT.
+ * We allow this to fail, as the U-Boot image might embed its FDT.
+ */
+ if (spl_image->os == IH_OS_U_BOOT)
+ spl_fit_append_fdt(spl_image, info, sector, fit,
+ images, base_offset);
/* Now check if there are more images for us to load */
for (; ; index++) {
+ uint8_t os_type = IH_OS_INVALID;
+
node = spl_fit_get_image_node(fit, images, "loadables", index);
if (node < 0)
break;
@@ -342,6 +361,13 @@ int spl_load_simple_fit(struct spl_image_info *spl_image,
if (ret < 0)
continue;
+ if (!fit_image_get_os(fit, node, &os_type))
+ debug("Loadable is %s\n", genimg_get_os_name(os_type));
+
+ if (spl_image->os == IH_OS_U_BOOT)
+ spl_fit_append_fdt(spl_image, info, sector,
+ fit, images, base_offset);
+
/*
* If the "firmware" image did not provide an entry point,
* use the first valid entry point from the loadables.