diff options
| author | Albert ARIBAUD <albert.u.boot@aribaud.net> | 2013-05-11 00:06:03 +0200 | 
|---|---|---|
| committer | Albert ARIBAUD <albert.u.boot@aribaud.net> | 2013-05-11 00:06:03 +0200 | 
| commit | e825b100d209a9d3c79b2998452cafa94eec986a (patch) | |
| tree | e1654c4d745839eba8d37f67d15acde79382e23e /common/cmd_fdt.c | |
| parent | b03b25caea1ff3a501161f5bc1ad5e5b5b124e0c (diff) | |
| parent | 66a62ce0dc48d2319938c72f34a562f519c5d5c2 (diff) | |
| download | olio-uboot-2014.01-e825b100d209a9d3c79b2998452cafa94eec986a.tar.xz olio-uboot-2014.01-e825b100d209a9d3c79b2998452cafa94eec986a.zip | |
Merge branch 'u-boot-pxa/master' into 'u-boot-arm/master'
Diffstat (limited to 'common/cmd_fdt.c')
| -rw-r--r-- | common/cmd_fdt.c | 87 | 
1 files changed, 57 insertions, 30 deletions
| diff --git a/common/cmd_fdt.c b/common/cmd_fdt.c index ac77a08b7..edefd7773 100644 --- a/common/cmd_fdt.c +++ b/common/cmd_fdt.c @@ -31,6 +31,7 @@  #include <asm/global_data.h>  #include <libfdt.h>  #include <fdt_support.h> +#include <asm/io.h>  #define MAX_LEVEL	32		/* how deeply nested we will go */  #define SCRATCHPAD	1024		/* bytes of scratchpad memory */ @@ -43,7 +44,7 @@   */  DECLARE_GLOBAL_DATA_PTR; -static int fdt_valid(void); +static int fdt_valid(struct fdt_header **blobp);  static int fdt_parse_prop(char *const*newval, int count, char *data, int *len);  static int fdt_print(const char *pathp, char *prop, int depth);  static int is_printable_string(const void *data, int len); @@ -55,7 +56,10 @@ struct fdt_header *working_fdt;  void set_working_fdt_addr(void *addr)  { -	working_fdt = addr; +	void *buf; + +	buf = map_sysmem((ulong)addr, 0); +	working_fdt = buf;  	setenv_addr("fdtaddr", addr);  } @@ -100,40 +104,59 @@ static int do_fdt(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])  	 */  	if (argv[1][0] == 'a') {  		unsigned long addr; +		int control = 0; +		struct fdt_header *blob;  		/*  		 * Set the address [and length] of the fdt.  		 */ -		if (argc == 2) { -			if (!fdt_valid()) { +		argc -= 2; +		argv += 2; +/* Temporary #ifdef - some archs don't have fdt_blob yet */ +#ifdef CONFIG_OF_CONTROL +		if (argc && !strcmp(*argv, "-c")) { +			control = 1; +			argc--; +			argv++; +		} +#endif +		if (argc == 0) { +			if (control) +				blob = (struct fdt_header *)gd->fdt_blob; +			else +				blob = working_fdt; +			if (!blob || !fdt_valid(&blob))  				return 1; -			} -			printf("The address of the fdt is %p\n", working_fdt); +			printf("The address of the fdt is %#08lx\n", +			       control ? (ulong)blob : +					getenv_hex("fdtaddr", 0));  			return 0;  		} -		addr = simple_strtoul(argv[2], NULL, 16); -		set_working_fdt_addr((void *)addr); - -		if (!fdt_valid()) { +		addr = simple_strtoul(argv[0], NULL, 16); +		blob = map_sysmem(addr, 0); +		if (!fdt_valid(&blob))  			return 1; -		} +		if (control) +			gd->fdt_blob = blob; +		else +			set_working_fdt_addr(blob); -		if (argc >= 4) { +		if (argc >= 2) {  			int  len;  			int  err;  			/*  			 * Optional new length  			 */ -			len = simple_strtoul(argv[3], NULL, 16); -			if (len < fdt_totalsize(working_fdt)) { +			len = simple_strtoul(argv[1], NULL, 16); +			if (len < fdt_totalsize(blob)) {  				printf ("New length %d < existing length %d, "  					"ignoring.\n", -					len, fdt_totalsize(working_fdt)); +					len, fdt_totalsize(blob));  			} else {  				/*  				 * Open in place with a new length.  				 */ -				err = fdt_open_into(working_fdt, working_fdt, len); +				err = fdt_open_into(blob, blob, len);  				if (err != 0) {  					printf ("libfdt fdt_open_into(): %s\n",  						fdt_strerror(err)); @@ -167,9 +190,8 @@ static int do_fdt(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])  		 * Set the address and length of the fdt.  		 */  		working_fdt = (struct fdt_header *)simple_strtoul(argv[2], NULL, 16); -		if (!fdt_valid()) { +		if (!fdt_valid(&working_fdt))  			return 1; -		}  		newaddr = (struct fdt_header *)simple_strtoul(argv[3],NULL,16); @@ -592,16 +614,23 @@ static int do_fdt(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])  /****************************************************************************/ -static int fdt_valid(void) +/** + * fdt_valid() - Check if an FDT is valid. If not, change it to NULL + * + * @blobp: Pointer to FDT pointer + * @return 1 if OK, 0 if bad (in which case *blobp is set to NULL) + */ +static int fdt_valid(struct fdt_header **blobp)  { -	int  err; +	const void *blob = *blobp; +	int err; -	if (working_fdt == NULL) { +	if (blob == NULL) {  		printf ("The address of the fdt is invalid (NULL).\n");  		return 0;  	} -	err = fdt_check_header(working_fdt); +	err = fdt_check_header(blob);  	if (err == 0)  		return 1;	/* valid */ @@ -611,23 +640,21 @@ static int fdt_valid(void)  		 * Be more informative on bad version.  		 */  		if (err == -FDT_ERR_BADVERSION) { -			if (fdt_version(working_fdt) < +			if (fdt_version(blob) <  			    FDT_FIRST_SUPPORTED_VERSION) {  				printf (" - too old, fdt %d < %d", -					fdt_version(working_fdt), +					fdt_version(blob),  					FDT_FIRST_SUPPORTED_VERSION); -				working_fdt = NULL;  			} -			if (fdt_last_comp_version(working_fdt) > +			if (fdt_last_comp_version(blob) >  			    FDT_LAST_SUPPORTED_VERSION) {  				printf (" - too new, fdt %d > %d", -					fdt_version(working_fdt), +					fdt_version(blob),  					FDT_LAST_SUPPORTED_VERSION); -				working_fdt = NULL;  			} -			return 0;  		}  		printf("\n"); +		*blobp = NULL;  		return 0;  	}  	return 1; @@ -958,7 +985,7 @@ static int fdt_print(const char *pathp, char *prop, int depth)  /********************************************************************/  #ifdef CONFIG_SYS_LONGHELP  static char fdt_help_text[] = -	"addr   <addr> [<length>]        - Set the fdt location to <addr>\n" +	"addr [-c]  <addr> [<length>]   - Set the [control] fdt location to <addr>\n"  #ifdef CONFIG_OF_BOARD_SETUP  	"fdt boardsetup                      - Do board-specific set up\n"  #endif |