[U-Boot] [RFC PATCH 06/22] image: Add device tree setup to image library
Simon Glass
sjg at chromium.org
Thu Jan 10 15:58:09 CET 2013
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 at chromium.org>
---
common/image-fdt.c | 62 +++++++++++++++++++++++++++++++++++++++++++++++++
common/image.c | 50 +++++++++++++++++++++++++++++++++++++++
include/common.h | 9 +++++++
include/fdt_support.h | 2 -
include/image.h | 62 +++++++++++++++++++++++++++++++++++++++++-------
include/lmb.h | 2 -
6 files changed, 174 insertions(+), 13 deletions(-)
diff --git a/common/image-fdt.c b/common/image-fdt.c
index 1c88a16..e317735 100644
--- a/common/image-fdt.c
+++ b/common/image-fdt.c
@@ -606,3 +606,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;
+}
diff --git a/common/image.c b/common/image.c
index aa2818e..a5bae46 100644
--- a/common/image.c
+++ b/common/image.c
@@ -71,6 +71,10 @@ static const image_header_t *image_get_ramdisk(ulong rd_addr, uint8_t arch,
#include <u-boot/crc.h>
+#ifndef CONFIG_SYS_BARGSIZE
+#define CONFIG_SYS_BARGSIZE 512
+#endif
+
static const table_entry_t uimage_arch[] = {
{ IH_ARCH_INVALID, NULL, "Invalid ARCH", },
{ IH_ARCH_ALPHA, "alpha", "Alpha", },
@@ -1223,4 +1227,50 @@ int boot_get_kbd(struct lmb *lmb, bd_t **kbd)
return 0;
}
#endif /* CONFIG_SYS_BOOT_GET_KBD */
+
+#ifdef CONFIG_LMB
+int image_setup_linux(bootm_headers_t *images)
+{
+ ulong of_size = images->ft_len;
+ char **of_flat_tree = &images->ft_addr;
+ ulong *initrd_start = &images->initrd_start;
+ ulong *initrd_end = &images->initrd_end;
+ struct lmb *lmb = &images->lmb;
+ ulong rd_len;
+ int ret;
+
+ if (IMAGE_ENABLE_OF_LIBFDT)
+ boot_fdt_add_mem_rsv_regions(lmb, *of_flat_tree);
+
+ if (IMAGE_BOOT_GET_CMDLINE) {
+ ret = boot_get_cmdline(lmb, &images->cmdline_start,
+ &images->cmdline_end);
+ if (ret) {
+ puts("ERROR with allocation of cmdline\n");
+ return ret;
+ }
+ }
+ if (IMAGE_ENABLE_RAMDISK_HIGH) {
+ rd_len = images->rd_end - images->rd_start;
+ ret = boot_ramdisk_high(lmb, images->rd_start, rd_len,
+ initrd_start, initrd_end);
+ if (ret)
+ return ret;
+ }
+
+ if (IMAGE_ENABLE_OF_LIBFDT) {
+ ret = boot_relocate_fdt(lmb, of_flat_tree, &of_size);
+ if (ret)
+ return ret;
+ }
+
+ if (IMAGE_ENABLE_OF_LIBFDT && of_size) {
+ ret = image_setup_libfdt(images, *of_flat_tree, of_size, lmb);
+ if (ret)
+ return ret;
+ }
+
+ return 0;
+}
+#endif /* CONFIG_LMB */
#endif /* !USE_HOSTCC */
diff --git a/include/common.h b/include/common.h
index a25f4a8..3fbebaf 100644
--- a/include/common.h
+++ b/include/common.h
@@ -312,6 +312,15 @@ int mac_read_from_eeprom(void);
extern u8 _binary_dt_dtb_start[]; /* embedded device tree blob */
int set_cpu_clk_info(void);
+/* arch/$(ARCH)/lib/bootm.c */
+/**
+ * arch_fixup_memory_node() - Write arch-specific memory information to fdt
+ *
+ * @blob FDT blob to write to
+ * @return 0 if ok, or -ve FDT_ERR_... on failure
+ */
+int arch_fixup_memory_node(void *blob);
+
/* common/flash.c */
void flash_perror (int);
diff --git a/include/fdt_support.h b/include/fdt_support.h
index 4b9f84a..71ac168 100644
--- a/include/fdt_support.h
+++ b/include/fdt_support.h
@@ -78,11 +78,9 @@ static inline void fdt_fixup_crypto_node(void *blob, int sec_rev) {}
int fdt_pci_dma_ranges(void *blob, int phb_off, struct pci_controller *hose);
#endif
-#ifdef CONFIG_OF_BOARD_SETUP
void ft_board_setup(void *blob, bd_t *bd);
void ft_cpu_setup(void *blob, bd_t *bd);
void ft_pci_setup(void *blob, bd_t *bd);
-#endif
void set_working_fdt_addr(void *addr);
int fdt_resize(void *blob);
diff --git a/include/image.h b/include/image.h
index 589c949..6e7baf9 100644
--- a/include/image.h
+++ b/include/image.h
@@ -36,6 +36,9 @@
#include "compiler.h"
#include <asm/byteorder.h>
+/* Define this to avoid #ifdefs later on */
+struct lmb;
+
#ifdef USE_HOSTCC
/* new uImage format support enabled on host */
@@ -66,6 +69,31 @@
#define CONFIG_SHA1 /* and SHA1 */
#endif
+#ifdef CONFIG_SYS_BOOT_RAMDISK_HIGH
+#define IMAGE_ENABLE_RAMDISK_HIGH 1
+#else
+#define IMAGE_ENABLE_RAMDISK_HIGH 0
+#endif
+
+#ifdef CONFIG_OF_LIBFDT
+# define IMAGE_ENABLE_OF_LIBFDT 1
+#else
+# define IMAGE_ENABLE_OF_LIBFDT 0
+
+#endif
+
+#ifdef CONFIG_SYS_BOOT_GET_CMDLINE
+#define IMAGE_BOOT_GET_CMDLINE 1
+#else
+#define IMAGE_BOOT_GET_CMDLINE 0
+#endif
+
+#ifdef CONFIG_OF_BOARD_SETUP
+#define IMAAGE_OF_BOARD_SETUP 1
+#else
+#define IMAAGE_OF_BOARD_SETUP 0
+#endif
+
/*
* Operating System Codes
*/
@@ -248,9 +276,7 @@ typedef struct bootm_headers {
ulong rd_start, rd_end;/* ramdisk start/end */
-#ifdef CONFIG_OF_LIBFDT
char *ft_addr; /* flat dev tree address */
-#endif
ulong ft_len; /* length of flat device tree */
ulong initrd_start;
@@ -358,21 +384,14 @@ ulong genimg_get_image(ulong img_addr);
int boot_get_ramdisk(int argc, char * const argv[], bootm_headers_t *images,
uint8_t arch, ulong *rd_start, ulong *rd_end);
-
-#ifdef CONFIG_OF_LIBFDT
int boot_get_fdt(int flag, int argc, char * const argv[],
bootm_headers_t *images, char **of_flat_tree, ulong *of_size);
void boot_fdt_add_mem_rsv_regions(struct lmb *lmb, void *fdt_blob);
int boot_relocate_fdt(struct lmb *lmb, char **of_flat_tree, ulong *of_size);
-#endif
-#ifdef CONFIG_SYS_BOOT_RAMDISK_HIGH
int boot_ramdisk_high(struct lmb *lmb, ulong rd_data, ulong rd_len,
ulong *initrd_start, ulong *initrd_end);
-#endif /* CONFIG_SYS_BOOT_RAMDISK_HIGH */
-#ifdef CONFIG_SYS_BOOT_GET_CMDLINE
int boot_get_cmdline(struct lmb *lmb, ulong *cmd_start, ulong *cmd_end);
-#endif /* CONFIG_SYS_BOOT_GET_CMDLINE */
#ifdef CONFIG_SYS_BOOT_GET_KBD
int boot_get_kbd(struct lmb *lmb, bd_t **kbd);
#endif /* CONFIG_SYS_BOOT_GET_KBD */
@@ -514,6 +533,31 @@ static inline int image_check_target_arch(const image_header_t *hdr)
}
#endif /* USE_HOSTCC */
+/**
+ * Set up properties in the FDT
+ *
+ * This sets up properties in the FDT that is to be passed to linux.
+ *
+ * @images: Images information
+ * @blob: FDT to update
+ * @of_size: Size of the FDT
+ * @lmb: Points to logical memory block structure
+ * @return 0 if ok, <0 on failure
+ */
+int image_setup_libfdt(bootm_headers_t *images, void *blob,
+ int of_size, struct lmb *lmb);
+
+/**
+ * Set up the FDT to use for booting a kernel
+ *
+ * This performs ramdisk setup, sets up the FDT if required, and adds
+ * paramters to the FDT if libfdt is available.
+ *
+ * @param images Images information
+ * @return 0 if ok, <0 on failure
+ */
+int image_setup_linux(bootm_headers_t *images);
+
/*******************************************************************/
/* New uImage format specific code (prefixed with fit_) */
/*******************************************************************/
diff --git a/include/lmb.h b/include/lmb.h
index 5d1f4b6..43082a3 100644
--- a/include/lmb.h
+++ b/include/lmb.h
@@ -1,7 +1,6 @@
#ifndef _LINUX_LMB_H
#define _LINUX_LMB_H
#ifdef __KERNEL__
-#ifdef CONFIG_LMB
#include <asm/types.h>
/*
@@ -57,7 +56,6 @@ lmb_size_bytes(struct lmb_region *type, unsigned long region_nr)
void board_lmb_reserve(struct lmb *lmb);
void arch_lmb_reserve(struct lmb *lmb);
-#endif /* CONFIG_LMB */
#endif /* __KERNEL__ */
#endif /* _LINUX_LMB_H */
--
1.7.7.3
More information about the U-Boot
mailing list