diff options
| author | Gerald Van Baren <vanbaren@cideas.com> | 2007-05-12 09:47:25 -0400 | 
|---|---|---|
| committer | Gerald Van Baren <vanbaren@cideas.com> | 2007-08-10 19:21:36 -0400 | 
| commit | 25114033ab21788810c48ba4df103b649da1223b (patch) | |
| tree | 8c818f0b44a9099eb2fd135928d48126adc8a6cd /common/cmd_fdt.c | |
| parent | 38eb508e8e811e2e57628f445de3a24a23c7d804 (diff) | |
| download | olio-uboot-2014.01-25114033ab21788810c48ba4df103b649da1223b.tar.xz olio-uboot-2014.01-25114033ab21788810c48ba4df103b649da1223b.zip | |
FDT command improvements.
Fix "fdt set" so that it will create a non-existing property.
Add "fdt mknode" to create nodes.
Signed-off-by: Gerald Van Baren <vanbaren@cideas.com>
Diffstat (limited to 'common/cmd_fdt.c')
| -rw-r--r-- | common/cmd_fdt.c | 271 | 
1 files changed, 143 insertions, 128 deletions
| diff --git a/common/cmd_fdt.c b/common/cmd_fdt.c index a11998594..8402ca785 100644 --- a/common/cmd_fdt.c +++ b/common/cmd_fdt.c @@ -56,27 +56,38 @@ static char data[SCRATCHPAD];  static int fdt_valid(void);  static void print_data(const void *data, int len); +static int findnodeoffset(const char *pathp) +{ +	int  nodeoffset; + +	if (strcmp(pathp, "/") == 0) { +		nodeoffset = 0; +	} else { +		nodeoffset = fdt_path_offset (fdt, pathp); +		if (nodeoffset < 0) { +			/* +			 * Not found or something else bad happened. +			 */ +			printf ("findnodeoffset() libfdt: %s\n", fdt_strerror(nodeoffset)); +		} +	} +	return nodeoffset; +}  /*   * Flattened Device Tree command, see the help for parameter definitions.   */  int do_fdt (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])  { -	char		op; -  	if (argc < 2) {  		printf ("Usage:\n%s\n", cmdtp->usage);  		return 1;  	} -	/* -	 * Figure out which subcommand was given -	 */ -	op = argv[1][0];  	/********************************************************************  	 * Set the address of the fdt  	 ********************************************************************/ -	if (op == 'a') { +	if (argv[1][0] == 'a') {  		/*  		 * Set the address [and length] of the fdt.  		 */ @@ -102,7 +113,7 @@ int do_fdt (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])  				 */  				err = fdt_open_into(fdt, fdt, len);  				if (err != 0) { -					printf ("libfdt: %s\n", fdt_strerror(err)); +					printf ("libfdt fdt_open_into(): %s\n", fdt_strerror(err));  				}  			}  		} @@ -110,7 +121,7 @@ int do_fdt (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])  	/********************************************************************  	 * Move the fdt  	 ********************************************************************/ -	} else if (op == 'm') { +	} else if ((argv[1][0] == 'm') && (argv[1][1] == 'o')) {  		struct fdt_header *newaddr;  		int  len;  		int  err; @@ -150,15 +161,48 @@ int do_fdt (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])  		 */  		err = fdt_open_into(fdt, newaddr, len);  		if (err != 0) { -			printf ("libfdt: %s\n", fdt_strerror(err)); +			printf ("libfdt fdt_open_into(): %s\n", fdt_strerror(err));  			return 1;  		}  		fdt = newaddr;  	/******************************************************************** -	 * Set the value of a node in the fdt. +	 * Make a new node +	 ********************************************************************/ +	} else if ((argv[1][0] == 'm') && (argv[1][1] == 'k')) { +		char *pathp;		/* path */ +		char *nodep;		/* new node to add */ +		int  nodeoffset;	/* node offset from libfdt */ +		int  err; + +		/* +		 * Parameters: Node path, new node to be appended to the path. +		 */ +		if (argc < 4) { +			printf ("Usage:\n%s\n", cmdtp->usage); +			return 1; +		} + +		pathp = argv[2]; +		nodep = argv[3]; + +		nodeoffset = findnodeoffset(pathp); +		if (nodeoffset < 0) { +			/* +			 * Not found or something else bad happened. +			 */ +			return 1; +		} +		err = fdt_add_subnode(fdt, nodeoffset, nodep); +		if (err < 0) { +			printf ("libfdt fdt_add_subnode(): %s\n", fdt_strerror(err)); +			return 1; +		} + +	/******************************************************************** +	 * Set the value of a property in the fdt.  	 ********************************************************************/ -	} else if (op == 's') { +	} else if (argv[1][0] == 's') {  		char *pathp;		/* path */  		char *prop;			/* property */  		struct fdt_property *nodep;	/* node struct pointer */ @@ -183,102 +227,85 @@ int do_fdt (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])  		prop   = argv[3];  		newval = argv[4]; -		if (strcmp(pathp, "/") == 0) { -			nodeoffset = 0; -		} else { -			nodeoffset = fdt_path_offset (fdt, pathp); -			if (nodeoffset < 0) { -				/* -			 	 * Not found or something else bad happened. -			 	 */ -				printf ("libfdt: %s\n", fdt_strerror(nodeoffset)); -				return 1; -			} -		} -		nodep = fdt_getprop (fdt, nodeoffset, prop, &oldlen); -		if (oldlen < 0) { -			printf ("libfdt %s\n", fdt_strerror(oldlen)); -			return 1; -		} else if (oldlen == 0) { +		nodeoffset = findnodeoffset(pathp); +		if (nodeoffset < 0) {  			/* -			 * The specified property has no value +			 * Not found or something else bad happened.  			 */ -			printf("%s has no value, cannot set one (yet).\n", prop);  			return 1; -		} else { +		} +		/* +		 * Convert the new property +		 */ +		vp = data; +		if (*newval == '<') {  			/* -			 * Convert the new property +			 * Bigger values than bytes.  			 */ -			vp = data; -			if (*newval == '<') { -				/* -				 * Bigger values than bytes. -				 */ -				len = 0; -				newval++; -				while ((*newval != '>') && (*newval != '\0')) { -					cp = newval; -					tmp = simple_strtoul(cp, &newval, 16); -					if ((newval - cp) <= 2) { -						*vp = tmp & 0xFF; -						vp  += 1; -						len += 1; -					} else if ((newval - cp) <= 4) { -						*(uint16_t *)vp = __cpu_to_be16(tmp); -						vp  += 2; -						len += 2; -					} else if ((newval - cp) <= 8) { -						*(uint32_t *)vp = __cpu_to_be32(tmp); -						vp  += 4; -						len += 4; -					} else { -						printf("Sorry, I could not convert \"%s\"\n", cp); -						return 1; -					} -					while (*newval == ' ') -						newval++; -				} -				if (*newval != '>') { -					printf("Unexpected character '%c'\n", *newval); -					return 1; -				} -			} else if (*newval == '[') { -				/* -				 * Byte stream.  Convert the values. -				 */ -				len = 0; -				newval++; -				while ((*newval != ']') && (*newval != '\0')) { -					tmp = simple_strtoul(newval, &newval, 16); -					*vp++ = tmp & 0xFF; -					len++; -					while (*newval == ' ') -						newval++; -				} -				if (*newval != ']') { -					printf("Unexpected character '%c'\n", *newval); +			len = 0; +			newval++; +			while ((*newval != '>') && (*newval != '\0')) { +				cp = newval; +				tmp = simple_strtoul(cp, &newval, 16); +				if ((newval - cp) <= 2) { +					*vp = tmp & 0xFF; +					vp  += 1; +					len += 1; +				} else if ((newval - cp) <= 4) { +					*(uint16_t *)vp = __cpu_to_be16(tmp); +					vp  += 2; +					len += 2; +				} else if ((newval - cp) <= 8) { +					*(uint32_t *)vp = __cpu_to_be32(tmp); +					vp  += 4; +					len += 4; +				} else { +					printf("Sorry, I could not convert \"%s\"\n", cp);  					return 1;  				} -			} else { -				/* -				 * Assume it is a string.  Copy it into our data area for -				 * convenience (including the terminating '\0'). -				 */ -				len = strlen(newval) + 1; -				strcpy(data, newval); +				while (*newval == ' ') +					newval++;  			} - -			ret = fdt_setprop(fdt, nodeoffset, prop, data, len); -			if (ret < 0) { -				printf ("libfdt %s\n", fdt_strerror(ret)); +			if (*newval != '>') { +				printf("Unexpected character '%c'\n", *newval); +				return 1; +			} +		} else if (*newval == '[') { +			/* +			 * Byte stream.  Convert the values. +			 */ +			len = 0; +			newval++; +			while ((*newval != ']') && (*newval != '\0')) { +				tmp = simple_strtoul(newval, &newval, 16); +				*vp++ = tmp & 0xFF; +				len++; +				while (*newval == ' ') +					newval++; +			} +			if (*newval != ']') { +				printf("Unexpected character '%c'\n", *newval);  				return 1;  			} +		} else { +			/* +			 * Assume it is a string.  Copy it into our data area for +			 * convenience (including the terminating '\0'). +			 */ +			len = strlen(newval) + 1; +			strcpy(data, newval); +		} + +		ret = fdt_setprop(fdt, nodeoffset, prop, data, len); +		if (ret < 0) { +			printf ("libfdt fdt_setprop(): %s\n", fdt_strerror(ret)); +			return 1;  		}  	/********************************************************************  	 * Print (recursive) / List (single level)  	 ********************************************************************/ -	} else if ((op == 'p') || (op == 'l')) { +	} else if ((argv[1][0] == 'p') || (argv[1][0] == 'l')) {  		/*  		 * Recursively print (a portion of) the fdt.  		 */ @@ -297,7 +324,7 @@ int do_fdt (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])  		/*  		 * list is an alias for print, but limited to 1 level  		 */ -		if (op == 'l') { +		if (argv[1][0] == 'l') {  			depth = 1;  		} @@ -311,18 +338,12 @@ int do_fdt (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])  		else  			prop = NULL; -		if (strcmp(pathp, "/") == 0) { -			nodeoffset = 0; -			printf("/"); -		} else { -			nodeoffset = fdt_path_offset (fdt, pathp); -			if (nodeoffset < 0) { -				/* -				 * Not found or something else bad happened. -				 */ -				printf ("libfdt %s\n", fdt_strerror(nodeoffset)); -				return 1; -			} +		nodeoffset = findnodeoffset(pathp); +		if (nodeoffset < 0) { +			/* +			 * Not found or something else bad happened. +			 */ +			return 1;  		}  		/*  		 * The user passed in a property as well as node path.  Print only @@ -339,7 +360,7 @@ int do_fdt (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])  				printf("\n");  				return 0;  			} else { -				printf ("libfdt %s\n", fdt_strerror(len)); +				printf ("libfdt fdt_getprop(): %s\n", fdt_strerror(len));  				return 1;  			}  		} @@ -359,7 +380,7 @@ int do_fdt (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])  				level++;  				offstack[level] = nodeoffset;  				if (level >= MAX_LEVEL) { -					printf("Aaaiii <splat> nested too deep.\n"); +					printf("Aaaiii <splat> nested too deep. Aborting.\n");  					return 1;  				}  				break; @@ -374,7 +395,7 @@ int do_fdt (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])  			case FDT_PROP:  				nodep = fdt_getprop (fdt, offstack[level], pathp, &len);  				if (len < 0) { -					printf ("libfdt %s\n", fdt_strerror(len)); +					printf ("libfdt fdt_getprop(): %s\n", fdt_strerror(len));  					return 1;  				} else if (len == 0) {  					/* the property has no value */ @@ -403,7 +424,7 @@ int do_fdt (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])  	/********************************************************************  	 * Remove a property/node  	 ********************************************************************/ -	} else if (op == 'r') { +	} else if (argv[1][0] == 'r') {  		int  nodeoffset;	/* node offset from libfdt */  		int  err; @@ -411,17 +432,12 @@ int do_fdt (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])  		 * Get the path.  The root node is an oddball, the offset  		 * is zero and has no name.  		 */ -		if (strcmp(argv[2], "/") == 0) { -			nodeoffset = 0; -		} else { -			nodeoffset = fdt_path_offset (fdt, argv[2]); -			if (nodeoffset < 0) { -				/* -				 * Not found or something else bad happened. -				 */ -				printf ("libfdt %s\n", fdt_strerror(nodeoffset)); -				return 1; -			} +		nodeoffset = findnodeoffset(argv[2]); +		if (nodeoffset < 0) { +			/* +			 * Not found or something else bad happened. +			 */ +			return 1;  		}  		/*  		 * Do the delete.  A fourth parameter means delete a property, @@ -430,13 +446,13 @@ int do_fdt (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])  		if (argc > 3) {  			err = fdt_delprop(fdt, nodeoffset, argv[3]);  			if (err < 0) { -				printf("fdt_delprop libfdt: %s\n", fdt_strerror(err)); +				printf("libfdt fdt_delprop():  %s\n", fdt_strerror(err));  				return err;  			}  		} else {  			err = fdt_del_node(fdt, nodeoffset);  			if (err < 0) { -				printf("fdt_del_node libfdt: %s\n", fdt_strerror(err)); +				printf("libfdt fdt_del_node():  %s\n", fdt_strerror(err));  				return err;  			}  		} @@ -444,19 +460,19 @@ int do_fdt (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])  	/********************************************************************  	 * Create a chosen node  	 ********************************************************************/ -	} else if (op == 'c') { +	} else if (argv[1][0] == 'c') {  		fdt_chosen(fdt, 0, 0, 1);  	/********************************************************************  	 * Create a u-boot-env node  	 ********************************************************************/ -	} else if (op == 'e') { +	} else if (argv[1][0] == 'e') {  		fdt_env(fdt);  	/********************************************************************  	 * Create a bd_t node  	 ********************************************************************/ -	} else if (op == 'b') { +	} else if (argv[1][0] == 'b') {  		fdt_bd_t(fdt);  	/******************************************************************** @@ -486,7 +502,7 @@ static int fdt_valid(void)  		return 1;	/* valid */  	if (err < 0) { -		printf("libfdt: %s", fdt_strerror(err)); +		printf("libfdt fdt_check_header(): %s", fdt_strerror(err));  		/*  		 * Be more informative on bad version.  		 */ @@ -630,7 +646,6 @@ U_BOOT_CMD(  	"fdt bd_t   - Add/replace the \"/bd_t\" branch in the tree\n"  #endif  	"Hints:\n" -	" * Set a larger length with the fdt addr command to add to the blob.\n"  	" * If the property you are setting/printing has a '#' character,\n"  	"     you MUST escape it with a \\ character or quote it with \" or\n"  	"     it will be ignored as a comment.\n" |