Browse Source

Add a flattened device tree (fdt) command (2 of 2)

Modifications to the existing code to support the new fdt command.
Gerald Van Baren 18 năm trước cách đây
mục cha
commit
213bf8c822

+ 25 - 8
README

@@ -164,6 +164,7 @@ Directory Hierarchy:
 - lib_mips	Files generic to MIPS	 architecture
 - lib_nios	Files generic to NIOS	 architecture
 - lib_ppc	Files generic to PowerPC architecture
+- libfdt 	Library files to support flattened device trees
 - net		Networking code
 - post		Power On Self Test
 - rtc		Real Time Clock drivers
@@ -430,12 +431,23 @@ The following options need to be configured:
 		expect it to be in bytes, others in MB.
 		Define CONFIG_MEMSIZE_IN_BYTES to make it in bytes.
 
-		CONFIG_OF_FLAT_TREE
+		CONFIG_OF_LIBFDT / CONFIG_OF_FLAT_TREE
 
 		New kernel versions are expecting firmware settings to be
-		passed using flat open firmware trees.
-		The environment variable "disable_of", when set, disables this
-		functionality.
+		passed using flattened device trees (based on open firmware
+		concepts).
+
+		CONFIG_OF_LIBFDT
+		 * New libfdt-based support
+		 * Adds the "fdt" command
+		 * The bootm command does _not_ modify the fdt
+
+		CONFIG_OF_FLAT_TREE
+		 * Deprecated, see CONFIG_OF_LIBFDT
+		 * Original ft_build.c-based support
+		 * Automatically modifies the dft as part of the bootm command
+		 * The environment variable "disable_of", when set,
+		     disables this functionality.
 
 		CONFIG_OF_FLAT_TREE_MAX_SIZE
 
@@ -448,13 +460,16 @@ The following options need to be configured:
 
 		CONFIG_OF_HAS_BD_T
 
-		The resulting flat device tree will have a copy of the bd_t.
-		Space should be pre-allocated in the dts for the bd_t.
+		 * CONFIG_OF_LIBFDT - enables the "fdt bd_t" command
+		 * CONFIG_OF_FLAT_TREE - The resulting flat device tree
+		     will have a copy of the bd_t.  Space should be
+		     pre-allocated in the dts for the bd_t.
 
 		CONFIG_OF_HAS_UBOOT_ENV
 
-		The resulting flat device tree will have a copy of u-boot's
-		environment variables
+		 * CONFIG_OF_LIBFDT - enables the "fdt bd_t" command
+		 * CONFIG_OF_FLAT_TREE - The resulting flat device tree
+		     will have a copy of u-boot's environment variables
 
 		CONFIG_OF_BOARD_SETUP
 
@@ -721,6 +736,8 @@ The following options need to be configured:
 
 		#define CONFIG_COMMANDS (CFG_CMD_ALL & ~CFG_CMD_NET)
 
+	Other Commands:
+		fdt (flattened device tree) command: CONFIG_OF_LIBFDT
 
 	Note:	Don't enable the "icache" and "dcache" commands
 		(configuration option CFG_CMD_CACHE) unless you know

+ 6 - 0
board/mpc8360emds/config.mk

@@ -26,3 +26,9 @@
 #
 
 TEXT_BASE = 0xFE000000
+
+#
+# Additional board-specific libraries
+#
+BOARDLIBS = libfdt/libfdt.a
+

+ 24 - 6
board/mpc8360emds/mpc8360emds.c

@@ -31,6 +31,10 @@
 #if defined(CONFIG_OF_FLAT_TREE)
 #include <ft_build.h>
 #endif
+#if defined(CONFIG_OF_LIBFDT)
+#include <libfdt.h>
+#include <libfdt_env.h>
+#endif
 
 const qe_iop_conf_t qe_iop_conf_tab[] = {
 	/* GETH1 */
@@ -658,22 +662,36 @@ U_BOOT_CMD(ecc, 4, 0, do_ecc,
 	   "  - disables injects\n" "  - re-inits memory");
 #endif				/* if defined(CONFIG_DDR_ECC) && defined(CONFIG_DDR_ECC_CMD) */
 
-#if defined(CONFIG_OF_FLAT_TREE) && defined(CONFIG_OF_BOARD_SETUP)
+#if (defined(CONFIG_OF_FLAT_TREE) || defined(CONFIG_OF_LIBFDT)) \
+     && defined(CONFIG_OF_BOARD_SETUP)
 void
 ft_board_setup(void *blob, bd_t *bd)
 {
+#if defined(CONFIG_OF_LIBFDT)
+	int nodeoffset;
+	int err;
+	int tmp[2];
+
+	nodeoffset = fdt_path_offset (fdt, "/memory");
+	if (nodeoffset >= 0) {
+		tmp[0] = cpu_to_be32(bd->bi_memstart);
+		tmp[1] = cpu_to_be32(bd->bi_memsize);
+		err = fdt_setprop(fdt, nodeoffset, "reg", tmp, sizeof(tmp));
+	}
+#else
 	u32 *p;
 	int len;
 
-#ifdef CONFIG_PCI
-	ft_pci_setup(blob, bd);
-#endif
-	ft_cpu_setup(blob, bd);
-
 	p = ft_get_prop(blob, "/memory/reg", &len);
 	if (p != NULL) {
 		*p++ = cpu_to_be32(bd->bi_memstart);
 		*p = cpu_to_be32(bd->bi_memsize);
 	}
+#endif
+
+#ifdef CONFIG_PCI
+	ft_pci_setup(blob, bd);
+#endif
+	ft_cpu_setup(blob, bd);
 }
 #endif

+ 20 - 0
board/mpc8360emds/pci.c

@@ -21,6 +21,10 @@
 #if defined(CONFIG_OF_FLAT_TREE)
 #include <ft_build.h>
 #endif
+#if defined(CONFIG_OF_LIBFDT)
+#include <libfdt.h>
+#include <libfdt_env.h>
+#endif
 
 #include <asm/fsl_i2c.h>
 
@@ -299,6 +303,22 @@ void pci_init_board(void)
 }
 #endif				/* CONFIG_PCISLAVE */
 
+#if defined(CONFIG_OF_LIBFDT)
+void
+ft_pci_setup(void *blob, bd_t *bd)
+{
+	int nodeoffset;
+	int err;
+	int tmp[2];
+
+	nodeoffset = fdt_path_offset (fdt, "/" OF_SOC "/pci@8500");
+	if (nodeoffset >= 0) {
+		tmp[0] = cpu_to_be32(hose[0].first_busno);
+		tmp[1] = cpu_to_be32(hose[0].last_busno);
+		err = fdt_setprop(fdt, nodeoffset, "bus-range", tmp, sizeof(tmp));
+	}
+}
+#endif				/* CONFIG_OF_LIBFDT */
 #ifdef CONFIG_OF_FLAT_TREE
 void
 ft_pci_setup(void *blob, bd_t *bd)

+ 1 - 1
common/Makefile

@@ -32,7 +32,7 @@ COBJS	= main.o ACEX1K.o altera.o bedbug.o circbuf.o cmd_autoscript.o \
 	  cmd_cache.o cmd_console.o \
 	  cmd_date.o cmd_dcr.o cmd_diag.o cmd_display.o cmd_doc.o cmd_dtt.o \
 	  cmd_eeprom.o cmd_elf.o cmd_ext2.o \
-	  cmd_fat.o cmd_fdc.o cmd_fdos.o cmd_flash.o cmd_fpga.o \
+	  cmd_fat.o cmd_fdc.o cmd_fdt.o cmd_fdos.o cmd_flash.o cmd_fpga.o \
 	  cmd_i2c.o cmd_ide.o cmd_immap.o cmd_itest.o cmd_jffs2.o \
 	  cmd_load.o cmd_log.o \
 	  cmd_mem.o cmd_mii.o cmd_misc.o cmd_mmc.o \

+ 55 - 10
common/cmd_bootm.c

@@ -34,7 +34,11 @@
 #include <environment.h>
 #include <asm/byteorder.h>
 
-#ifdef CONFIG_OF_FLAT_TREE
+#if defined(CONFIG_OF_LIBFDT)
+#include <fdt.h>
+#include <libfdt.h>
+#endif
+#if defined(CONFIG_OF_FLAT_TREE) 
 #include <ft_build.h>
 #endif
 
@@ -467,7 +471,7 @@ U_BOOT_CMD(
  	"[addr [arg ...]]\n    - boot application image stored in memory\n"
  	"\tpassing arguments 'arg ...'; when booting a Linux kernel,\n"
  	"\t'arg' can be the address of an initrd image\n"
-#ifdef CONFIG_OF_FLAT_TREE
+#if defined(CONFIG_OF_FLAT_TREE) || defined(CONFIG_OF_LIBFDT)
 	"\tWhen booting a Linux kernel which requires a flat device-tree\n"
 	"\ta third argument is required which is the address of the of the\n"
 	"\tdevice-tree blob. To boot that kernel without an initrd image,\n"
@@ -529,7 +533,7 @@ do_bootm_linux (cmd_tbl_t *cmdtp, int flag,
 	bd_t	*kbd;
 	void	(*kernel)(bd_t *, ulong, ulong, ulong, ulong);
 	image_header_t *hdr = &header;
-#ifdef CONFIG_OF_FLAT_TREE
+#if defined(CONFIG_OF_FLAT_TREE) || defined(CONFIG_OF_LIBFDT)
 	char	*of_flat_tree = NULL;
 	ulong	of_data = 0;
 #endif
@@ -622,7 +626,7 @@ do_bootm_linux (cmd_tbl_t *cmdtp, int flag,
 	 * Check if there is an initrd image
 	 */
 
-#ifdef CONFIG_OF_FLAT_TREE
+#if defined(CONFIG_OF_FLAT_TREE) || defined(CONFIG_OF_LIBFDT)
 	/* Look for a '-' which indicates to ignore the ramdisk argument */
 	if (argc >= 3 && strcmp(argv[2], "-") ==  0) {
 			debug ("Skipping initrd\n");
@@ -739,12 +743,15 @@ do_bootm_linux (cmd_tbl_t *cmdtp, int flag,
 		len = data = 0;
 	}
 
-#ifdef CONFIG_OF_FLAT_TREE
+#if defined(CONFIG_OF_FLAT_TREE) || defined(CONFIG_OF_LIBFDT)
 	if(argc > 3) {
 		of_flat_tree = (char *) simple_strtoul(argv[3], NULL, 16);
 		hdr = (image_header_t *)of_flat_tree;
-
-		if  (*(ulong *)of_flat_tree == OF_DT_HEADER) {
+#if defined(CONFIG_OF_LIBFDT)
+		if (be32_to_cpu(fdt_magic(of_flat_tree)) == FDT_MAGIC) {
+#else
+		if (*(ulong *)of_flat_tree == OF_DT_HEADER) {
+#endif
 #ifndef CFG_NO_FLASH
 			if (addr2info((ulong)of_flat_tree) != NULL)
 				of_data = (ulong)of_flat_tree;
@@ -787,7 +794,11 @@ do_bootm_linux (cmd_tbl_t *cmdtp, int flag,
 				printf("ERROR: uImage is not uncompressed\n");
 				return;
 			}
+#if defined(CONFIG_OF_LIBFDT)
+			if (be32_to_cpu(fdt_magic(of_flat_tree + sizeof(image_header_t))) != FDT_MAGIC) {
+#else
 			if (*((ulong *)(of_flat_tree + sizeof(image_header_t))) != OF_DT_HEADER) {
+#endif
 				printf ("ERROR: uImage data is not a flat device tree\n");
 				return;
 			}
@@ -824,12 +835,20 @@ do_bootm_linux (cmd_tbl_t *cmdtp, int flag,
 			of_data += 4 - tail;
 		}
 
+#if defined(CONFIG_OF_LIBFDT)
+		if (be32_to_cpu(fdt_magic(of_data)) != FDT_MAGIC) {
+#else
 		if (((struct boot_param_header *)of_data)->magic != OF_DT_HEADER) {
+#endif
 			printf ("ERROR: image is not a flat device tree\n");
 			return;
 		}
 
+#if defined(CONFIG_OF_LIBFDT)
+		if (be32_to_cpu(fdt_totalsize(of_data)) !=  ntohl(len_ptr[2])) {
+#else
 		if (((struct boot_param_header *)of_data)->totalsize != ntohl(len_ptr[2])) {
+#endif
 			printf ("ERROR: flat device tree size does not agree with image\n");
 			return;
 		}
@@ -913,7 +932,31 @@ do_bootm_linux (cmd_tbl_t *cmdtp, int flag,
 	unlock_ram_in_cache();
 #endif
 
-#ifdef CONFIG_OF_FLAT_TREE
+#if defined(CONFIG_OF_LIBFDT)
+	/* move of_flat_tree if needed */
+	if (of_data) {
+		int err;
+		ulong of_start, of_len;
+		of_len = be32_to_cpu(fdt_totalsize(of_data));
+		/* provide extra 8k pad */
+		if (initrd_start)
+			of_start = initrd_start - of_len - 8192;
+		else
+			of_start  = (ulong)kbd - of_len - 8192;
+		of_start &= ~(4096 - 1);	/* align on page */
+		debug ("## device tree at 0x%08lX ... 0x%08lX (len=%ld=0x%lX)\n",
+			of_data, of_data + of_len - 1, of_len, of_len);
+
+
+		printf ("   Loading Device Tree to %08lx, end %08lx ... ",
+			of_start, of_start + of_len - 1);
+		err = fdt_open_into(of_start, of_data, of_len);
+		if (err != 0) {
+			printf ("libfdt: %s\n", fdt_strerror(err));
+		}
+	}
+#endif
+#if defined(CONFIG_OF_FLAT_TREE)
 	/* move of_flat_tree if needed */
 	if (of_data) {
 		ulong of_start, of_len;
@@ -942,13 +985,13 @@ do_bootm_linux (cmd_tbl_t *cmdtp, int flag,
 	 *   r6: Start of command line string
 	 *   r7: End   of command line string
 	 */
-#ifdef CONFIG_OF_FLAT_TREE
+#if defined(CONFIG_OF_FLAT_TREE) || defined(CONFIG_OF_LIBFDT)
 	if (!of_flat_tree)	/* no device tree; boot old style */
 #endif
 		(*kernel) (kbd, initrd_start, initrd_end, cmd_start, cmd_end);
 		/* does not return */
 
-#ifdef CONFIG_OF_FLAT_TREE
+#if defined(CONFIG_OF_FLAT_TREE) || defined(CONFIG_OF_LIBFDT)
 	/*
 	 * Linux Kernel Parameters (passing device tree):
 	 *   r3: ptr to OF flat tree, followed by the board info data
@@ -957,8 +1000,10 @@ do_bootm_linux (cmd_tbl_t *cmdtp, int flag,
 	 *   r6: NULL
 	 *   r7: NULL
 	 */
+#if defined(CONFIG_OF_FLAT_TREE)
 	ft_setup(of_flat_tree, kbd, initrd_start, initrd_end);
 	/* ft_dump_blob(of_flat_tree); */
+#endif
 
 	(*kernel) ((bd_t *)of_flat_tree, (ulong)kernel, 0, 0, 0);
 #endif

+ 101 - 1
cpu/mpc83xx/cpu.c

@@ -30,8 +30,14 @@
 #include <watchdog.h>
 #include <command.h>
 #include <mpc83xx.h>
-#include <ft_build.h>
 #include <asm/processor.h>
+#if defined(CONFIG_OF_FLAT_TREE)
+#include <ft_build.h>
+#endif
+#if defined(CONFIG_OF_LIBFDT)
+#include <libfdt.h>
+#include <libfdt_env.h>
+#endif
 
 DECLARE_GLOBAL_DATA_PTR;
 
@@ -291,6 +297,100 @@ void watchdog_reset (void)
 }
 #endif
 
+#if defined(CONFIG_OF_LIBFDT)
+
+/*
+ * Fixups to the fdt.  If "create" is TRUE, the node is created
+ * unconditionally.  If "create" is FALSE, the node is updated
+ * only if it already exists.
+ */
+#define	FT_UPDATE	0x00000000		/* update existing property only */
+#define	FT_CREATE	0x00000001		/* create property if it doesn't exist */
+#define	FT_BUSFREQ	0x00000002		/* source is bd->bi_busfreq */
+#define	FT_ENETADDR	0x00000004		/* source is bd->bi_enetaddr */
+static const struct {
+	int  createflags;
+	char *node;
+	char *prop;
+} fixup_props[] = {
+	{	FT_CREATE | FT_BUSFREQ,
+		"/cpus/" OF_CPU,
+		 "bus-frequency",
+	},
+	{	FT_CREATE | FT_BUSFREQ,
+		"/cpus/" OF_SOC,
+		"bus-frequency"
+	},
+	{	FT_CREATE | FT_BUSFREQ,
+		"/" OF_SOC "/serial@4500/",
+		"clock-frequency"
+	},
+	{	FT_CREATE | FT_BUSFREQ,
+		"/" OF_SOC "/serial@4600/",
+		"clock-frequency"
+	},
+#ifdef CONFIG_MPC83XX_TSEC1
+	{	FT_UPDATE | FT_ENETADDR,
+		"/" OF_SOC "/ethernet@24000,
+		"mac-address",
+	},
+	{	FT_UPDATE | FT_ENETADDR,
+		"/" OF_SOC "/ethernet@24000,
+		"local-mac-address",
+	},
+#endif
+#ifdef CONFIG_MPC83XX_TSEC2
+	{	FT_UPDATE | FT_ENETADDR,
+		"/" OF_SOC "/ethernet@25000,
+		"mac-address",
+	},
+	{	FT_UPDATE | FT_ENETADDR,
+		"/" OF_SOC "/ethernet@25000,
+		"local-mac-address",
+	},
+#endif
+};
+
+void
+ft_cpu_setup(void *blob, bd_t *bd)
+{
+	int   nodeoffset;
+	int   err;
+	int j;
+
+	for (j = 0; j < (sizeof(fixup_props) / sizeof(fixup_props[0])); j++) {
+		nodeoffset = fdt_path_offset (fdt, fixup_props[j].node);
+		if (nodeoffset >= 0) {
+			/*
+			 * If unconditional create or the property already exists...
+			 */
+			if ((fixup_props[j].createflags & FT_CREATE) ||
+				(fdt_get_property(fdt, nodeoffset, fixup_props[j].prop, 0))) {
+				if (fixup_props[j].createflags & FT_BUSFREQ) {
+					u32   tmp;
+
+					tmp = cpu_to_be32(bd->bi_busfreq);
+					err = fdt_setprop(fdt, nodeoffset,
+							fixup_props[j].prop, &tmp, sizeof(tmp));
+				} else if (fixup_props[j].createflags & FT_ENETADDR) {
+					err = fdt_setprop(fdt, nodeoffset,
+							fixup_props[j].prop, bd->bi_enetaddr, 6);
+				} else {
+					printf("ft_cpu_setup: %s %s has no flag for the value to set\n",
+						fixup_props[j].node, 
+						fixup_props[j].prop);
+				}
+				if (err < 0)
+					printf("libfdt: %s %s returned %s\n",
+						fixup_props[j].node, 
+						fixup_props[j].prop,
+						fdt_strerror(err));
+			}
+		}
+	}
+}
+#endif
+
 #if defined(CONFIG_OF_FLAT_TREE)
 void
 ft_cpu_setup(void *blob, bd_t *bd)

+ 5 - 1
include/configs/MPC8360EMDS.h

@@ -342,8 +342,12 @@
 #endif
 
 /* pass open firmware flat tree */
-#define CONFIG_OF_FLAT_TREE	1
+#define CONFIG_OF_LIBFDT	1
+#undef  CONFIG_OF_FLAT_TREE
 #define CONFIG_OF_BOARD_SETUP	1
+#define CONFIG_OF_HAS_BD_T	1
+#define CONFIG_OF_HAS_UBOOT_ENV	1
+
 
 /* maximum size of the flat tree (8K) */
 #define OF_FLAT_TREE_MAX_SIZE	8192