aboutsummaryrefslogtreecommitdiff
path: root/common/image-fdt.c
diff options
context:
space:
mode:
authorSimon Glass2013-05-08 08:06:01 +0000
committerTom Rini2013-05-14 15:37:25 -0400
commit13d06981a9829c9edcfd6f9f582d216fbaed95e5 (patch)
tree1e5df63856d117bc14acb5f669ac0dc405e91f06 /common/image-fdt.c
parent44d3a3066bc789b9a640e71322e593a9983023bb (diff)
image: Add device tree setup to image library
This seems to be a common function for several architectures, so create a common function rather than duplicating the code in each arch. Also make an attempt to avoid introducing #ifdefs in the new code, partly by removing useless #ifdefs around function declarations in the image.h header. Signed-off-by: Simon Glass <sjg@chromium.org>
Diffstat (limited to 'common/image-fdt.c')
-rw-r--r--common/image-fdt.c62
1 files changed, 62 insertions, 0 deletions
diff --git a/common/image-fdt.c b/common/image-fdt.c
index 8e8f35c1cff..158c9cfbf57 100644
--- a/common/image-fdt.c
+++ b/common/image-fdt.c
@@ -589,3 +589,65 @@ error:
*of_size = 0;
return 1;
}
+
+/*
+ * Verify the device tree.
+ *
+ * This function is called after all device tree fix-ups have been enacted,
+ * so that the final device tree can be verified. The definition of "verified"
+ * is up to the specific implementation. However, it generally means that the
+ * addresses of some of the devices in the device tree are compared with the
+ * actual addresses at which U-Boot has placed them.
+ *
+ * Returns 1 on success, 0 on failure. If 0 is returned, U-boot will halt the
+ * boot process.
+ */
+__weak int ft_verify_fdt(void *fdt)
+{
+ return 1;
+}
+
+__weak int arch_fixup_memory_node(void *blob)
+{
+ return 0;
+}
+
+int image_setup_libfdt(bootm_headers_t *images, void *blob,
+ int of_size, struct lmb *lmb)
+{
+ ulong *initrd_start = &images->initrd_start;
+ ulong *initrd_end = &images->initrd_end;
+ int ret;
+
+ if (fdt_chosen(blob, 1) < 0) {
+ puts("ERROR: /chosen node create failed");
+ puts(" - must RESET the board to recover.\n");
+ return -1;
+ }
+ arch_fixup_memory_node(blob);
+ if (IMAAGE_OF_BOARD_SETUP)
+ ft_board_setup(blob, gd->bd);
+ fdt_fixup_ethernet(blob);
+
+ /* Delete the old LMB reservation */
+ lmb_free(lmb, (phys_addr_t)(u32)(uintptr_t)blob,
+ (phys_size_t)fdt_totalsize(blob));
+
+ ret = fdt_resize(blob);
+ if (ret < 0)
+ return ret;
+ of_size = ret;
+
+ if (*initrd_start && *initrd_end) {
+ of_size += FDT_RAMDISK_OVERHEAD;
+ fdt_set_totalsize(blob, of_size);
+ }
+ /* Create a new LMB reservation */
+ lmb_reserve(lmb, (ulong)blob, of_size);
+
+ fdt_initrd(blob, *initrd_start, *initrd_end, 1);
+ if (!ft_verify_fdt(blob))
+ return -1;
+
+ return 0;
+}