diff options
Diffstat (limited to 'common/cmd_fdt.c')
| -rw-r--r-- | common/cmd_fdt.c | 301 | 
1 files changed, 31 insertions, 270 deletions
| diff --git a/common/cmd_fdt.c b/common/cmd_fdt.c index 968bade62..08fe3512d 100644 --- a/common/cmd_fdt.c +++ b/common/cmd_fdt.c @@ -30,9 +30,11 @@  #include <linux/types.h>  #ifdef CONFIG_OF_LIBFDT +  #include <asm/global_data.h>  #include <fdt.h>  #include <libfdt.h> +#include <fdt_support.h>  #define MAX_LEVEL	32		/* how deeply nested we will go */  #define SCRATCHPAD	1024	/* bytes of scratchpad memory */ @@ -53,9 +55,6 @@ static char data[SCRATCHPAD];   */  static int fdt_valid(void);  static void print_data(const void *data, int len); -static int fdt_chosen(void *fdt, ulong initrd_start, ulong initrd_end); -static int fdt_env(void *fdt); -static int fdt_bd_t(void *fdt);  /* @@ -437,7 +436,7 @@ int do_fdt (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])  	 * Create a chosen node  	 ********************************************************************/  	} else if (op == 'c') { -		fdt_chosen(fdt, 0, 0); +		fdt_chosen(fdt, 0, 0, 1);  	/********************************************************************  	 * Create a u-boot-env node @@ -466,25 +465,36 @@ int do_fdt (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])  static int fdt_valid(void)  { +	int  err; +  	if (fdt == NULL) { -		printf ("The address of the fdt is invalid.\n"); -		return 0; -	} -	if (!fdt || (fdt_magic(fdt) != FDT_MAGIC)) { -		fdt = NULL; -		printf ("Unrecognized fdt: bad magic\n"); -		return 0; -	} -	if (fdt_version(fdt) < FDT_FIRST_SUPPORTED_VERSION) { -		printf ("Unsupported fdt version: $d < %d\n", -			FDT_FIRST_SUPPORTED_VERSION, fdt_version(fdt)); -		fdt = NULL; +		printf ("The address of the fdt is invalid (NULL).\n");  		return 0;  	} -	if (fdt_last_comp_version(fdt) > FDT_LAST_SUPPORTED_VERSION) { -		printf ("Unsupported fdt version: $d > %d\n", -			fdt_version(fdt), FDT_LAST_SUPPORTED_VERSION); -		fdt = NULL; + +	err = fdt_check_header(fdt); +	if (err == 0) +		return 1;	/* valid */ + +	if (err < 0) { +		printf("libfdt: %s", fdt_strerror(err)); +		/* +		 * Be more informative on bad version. +		 */ +		if (err == -FDT_ERR_BADVERSION) { +			if (fdt_version(fdt) < FDT_FIRST_SUPPORTED_VERSION) { +				printf (" - too old, fdt $d < %d", +					fdt_version(fdt), FDT_FIRST_SUPPORTED_VERSION); +				fdt = NULL; +			} +			if (fdt_last_comp_version(fdt) > FDT_LAST_SUPPORTED_VERSION) { +				printf (" - too new, fdt $d > %d", +					fdt_version(fdt), FDT_LAST_SUPPORTED_VERSION); +				fdt = NULL; +			} +			return 0; +		} +		printf("\n");  		return 0;  	}  	return 1; @@ -593,255 +603,6 @@ static void print_data(const void *data, int len)  /********************************************************************/ -static int fdt_chosen(void *fdt, ulong initrd_start, ulong initrd_end) -{ -	bd_t *bd = gd->bd; -	int   nodeoffset; -	int   err; -	u32   tmp;			/* used to set 32 bit integer properties */ -	char  *str;			/* used to set string properties */ -	ulong clock; - -	if (initrd_start && initrd_end) { -		err = fdt_add_reservemap_entry(fdt, -			initrd_start, initrd_end - initrd_start + 1); -		if (err < 0) { -			printf("libfdt: %s\n", fdt_strerror(err)); -			return err; -		} -	} - -	/* -	 * See if we already have a "chosen" node, create it if not. -	 */ -	nodeoffset = fdt_path_offset (fdt, "/chosen"); -	if (nodeoffset < 0) { -		/* -		 * Create a new node "/chosen" (offset 0 is root level) -		 */ -		nodeoffset = fdt_add_subnode(fdt, 0, "chosen"); -		if (nodeoffset < 0) { -			printf("libfdt: %s\n", fdt_strerror(nodeoffset)); -			return nodeoffset; -		} -	} - -	str = getenv("bootargs"); -	if (str != NULL) { -		err = fdt_setprop(fdt, nodeoffset, "bootargs", str, strlen(str)+1); -		if (err < 0) -			printf("libfdt: %s\n", fdt_strerror(err)); -	} -	if (initrd_start && initrd_end) { -		tmp = __cpu_to_be32(initrd_start); -		err = fdt_setprop(fdt, nodeoffset, "linux,initrd-start", &tmp, sizeof(tmp)); -		if (err < 0) -			printf("libfdt: %s\n", fdt_strerror(err)); -		tmp = __cpu_to_be32(initrd_end); -		err = fdt_setprop(fdt, nodeoffset, "linux,initrd-end", &tmp, sizeof(tmp)); -		if (err < 0) -			printf("libfdt: %s\n", fdt_strerror(err)); -	} -#ifdef OF_STDOUT_PATH -	err = fdt_setprop(fdt, nodeoffset, "linux,stdout-path", OF_STDOUT_PATH, strlen(OF_STDOUT_PATH)+1); -	if (err < 0) -		printf("libfdt: %s\n", fdt_strerror(err)); -#endif - -	nodeoffset = fdt_path_offset (fdt, "/cpus"); -	if (nodeoffset >= 0) { -		clock = cpu_to_be32(bd->bi_intfreq); -		err = fdt_setprop(fdt, nodeoffset, "clock-frequency", &clock, 4); -		if (err < 0) -			printf("libfdt: %s\n", fdt_strerror(err)); -	} -#ifdef OF_TBCLK -	nodeoffset = fdt_path_offset (fdt, "/cpus/" OF_CPU "/timebase-frequency"); -	if (nodeoffset >= 0) { -		clock = cpu_to_be32(OF_TBCLK); -		err = fdt_setprop(fdt, nodeoffset, "clock-frequency", &clock, 4); -		if (err < 0) -			printf("libfdt: %s\n", fdt_strerror(err)); -	} -#endif -} - -/********************************************************************/ - -#ifdef CONFIG_OF_HAS_BD_T - -/* Function that returns a character from the environment */ -extern uchar(*env_get_char) (int); - -#define BDM(x)	{	.name = #x, .offset = offsetof(bd_t, bi_ ##x ) } - -static const struct { -	const char *name; -	int offset; -} bd_map[] = { -	BDM(memstart), -	BDM(memsize), -	BDM(flashstart), -	BDM(flashsize), -	BDM(flashoffset), -	BDM(sramstart), -	BDM(sramsize), -#if defined(CONFIG_5xx) || defined(CONFIG_8xx) || defined(CONFIG_8260) \ -	|| defined(CONFIG_E500) -	BDM(immr_base), -#endif -#if defined(CONFIG_MPC5xxx) -	BDM(mbar_base), -#endif -#if defined(CONFIG_MPC83XX) -	BDM(immrbar), -#endif -#if defined(CONFIG_MPC8220) -	BDM(mbar_base), -	BDM(inpfreq), -	BDM(pcifreq), -	BDM(pevfreq), -	BDM(flbfreq), -	BDM(vcofreq), -#endif -	BDM(bootflags), -	BDM(ip_addr), -	BDM(intfreq), -	BDM(busfreq), -#ifdef CONFIG_CPM2 -	BDM(cpmfreq), -	BDM(brgfreq), -	BDM(sccfreq), -	BDM(vco), -#endif -#if defined(CONFIG_MPC5xxx) -	BDM(ipbfreq), -	BDM(pcifreq), -#endif -	BDM(baudrate), -}; - -static int fdt_env(void *fdt) -{ -	int   nodeoffset; -	int   err; -	int   k, nxt; -	int i; -	static char tmpenv[256]; - -	/* -	 * See if we already have a "u-boot-env" node, delete it if so. -	 * Then create a new empty node. -	 */ -	nodeoffset = fdt_path_offset (fdt, "/u-boot-env"); -	if (nodeoffset >= 0) { -		err = fdt_del_node(fdt, nodeoffset); -		if (err < 0) { -			printf("libfdt: %s\n", fdt_strerror(err)); -			return err; -		} -	} -	/* -	 * Create a new node "/u-boot-env" (offset 0 is root level) -	 */ -	nodeoffset = fdt_add_subnode(fdt, 0, "u-boot-env"); -	if (nodeoffset < 0) { -		printf("libfdt: %s\n", fdt_strerror(nodeoffset)); -		return nodeoffset; -	} - -	for (i = 0; env_get_char(i) != '\0'; i = nxt + 1) { -		char *s, *lval, *rval; - -		/* -		 * Find the end of the name=definition -		 */ -		for (nxt = i; env_get_char(nxt) != '\0'; ++nxt) -			; -		s = tmpenv; -		for (k = i; k < nxt && s < &tmpenv[sizeof(tmpenv) - 1]; ++k) -			*s++ = env_get_char(k); -		*s++ = '\0'; -		lval = tmpenv; -		/* -		 * Find the first '=': it separates the name from the value -		 */ -		s = strchr(tmpenv, '='); -		if (s != NULL) { -			*s++ = '\0'; -			rval = s; -		} else -			continue; -		err = fdt_setprop(fdt, nodeoffset, lval, rval, strlen(rval)+1); -		if (err < 0) { -			printf("\"%s\" - libfdt: %s\n", lval, fdt_strerror(err)); -			return err; -		} -	} -	return 0; -} -#endif /* CONFIG_OF_HAS_UBOOT_ENV */ - -/********************************************************************/ - -#ifdef CONFIG_OF_HAS_BD_T -static int fdt_bd_t(void *fdt) -{ -	bd_t *bd = gd->bd; -	int   nodeoffset; -	int   err; -	u32   tmp;			/* used to set 32 bit integer properties */ -	int i; - -	/* -	 * See if we already have a "bd_t" node, delete it if so. -	 * Then create a new empty node. -	 */ -	nodeoffset = fdt_path_offset (fdt, "/bd_t"); -	if (nodeoffset >= 0) { -		err = fdt_del_node(fdt, nodeoffset); -		if (err < 0) { -			printf("libfdt: %s\n", fdt_strerror(err)); -			return err; -		} -	} -	/* -	 * Create a new node "/bd_t" (offset 0 is root level) -	 */ -	nodeoffset = fdt_add_subnode(fdt, 0, "bd_t"); -	if (nodeoffset < 0) { -		printf("libfdt: %s\n", fdt_strerror(nodeoffset)); -		return nodeoffset; -	} -	/* -	 * Use the string/pointer structure to create the entries... -	 */ -	for (i = 0; i < sizeof(bd_map)/sizeof(bd_map[0]); i++) { -		tmp = cpu_to_be32(getenv("bootargs")); -		err = fdt_setprop(fdt, nodeoffset, bd_map[i].name, &tmp, sizeof(tmp)); -		if (err < 0) -			printf("libfdt: %s\n", fdt_strerror(err)); -	} -	/* -	 * Add a couple of oddball entries... -	 */ -	err = fdt_setprop(fdt, nodeoffset, "enetaddr", &bd->bi_enetaddr, 6); -	if (err < 0) -		printf("libfdt: %s\n", fdt_strerror(err)); -	err = fdt_setprop(fdt, nodeoffset, "ethspeed", &bd->bi_ethspeed, 4); -	if (err < 0) -		printf("libfdt: %s\n", fdt_strerror(err)); - -#ifdef CONFIG_OF_BOARD_SETUP -	ft_board_setup(fdt, bd); -#endif - -	return 0; -} -#endif /* CONFIG_OF_HAS_BD_T */ - -/********************************************************************/ -  U_BOOT_CMD(  	fdt,	5,	0,	do_fdt,  	"fdt     - flattened device tree utility commands\n", @@ -871,4 +632,4 @@ U_BOOT_CMD(  	"          fdt set   /cpus \"#address-cells\" \"[00 00 00 01]\"\n"  ); -#endif /* CONFIG_OF_FLAT_TREE */ +#endif /* CONFIG_OF_LIBFDT */ |