|
@@ -42,8 +42,7 @@
|
|
DECLARE_GLOBAL_DATA_PTR;
|
|
DECLARE_GLOBAL_DATA_PTR;
|
|
|
|
|
|
static int fdt_valid(void);
|
|
static int fdt_valid(void);
|
|
-static int fdt_parse_prop(char *pathp, char *prop, char *newval,
|
|
|
|
- char *data, int *len);
|
|
|
|
|
|
+static int fdt_parse_prop(char **newval, int count, char *data, int *len);
|
|
static int fdt_print(const char *pathp, char *prop, int depth);
|
|
static int fdt_print(const char *pathp, char *prop, int depth);
|
|
|
|
|
|
/*
|
|
/*
|
|
@@ -202,7 +201,7 @@ int do_fdt (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
|
|
if (argc == 4) {
|
|
if (argc == 4) {
|
|
len = 0;
|
|
len = 0;
|
|
} else {
|
|
} else {
|
|
- ret = fdt_parse_prop(pathp, prop, argv[4], data, &len);
|
|
|
|
|
|
+ ret = fdt_parse_prop(&argv[4], argc - 4, data, &len);
|
|
if (ret != 0)
|
|
if (ret != 0)
|
|
return ret;
|
|
return ret;
|
|
}
|
|
}
|
|
@@ -464,69 +463,77 @@ static int fdt_valid(void)
|
|
|
|
|
|
/*
|
|
/*
|
|
* Parse the user's input, partially heuristic. Valid formats:
|
|
* Parse the user's input, partially heuristic. Valid formats:
|
|
- * <00> - hex byte
|
|
|
|
- * <0011> - hex half word (16 bits)
|
|
|
|
- * <00112233> - hex word (32 bits)
|
|
|
|
- * - hex double words (64 bits) are not supported, must use
|
|
|
|
- * a byte stream instead.
|
|
|
|
|
|
+ * <0x00112233 4 05> - an array of cells. Numbers follow standard
|
|
|
|
+ * C conventions.
|
|
* [00 11 22 .. nn] - byte stream
|
|
* [00 11 22 .. nn] - byte stream
|
|
* "string" - If the the value doesn't start with "<" or "[", it is
|
|
* "string" - If the the value doesn't start with "<" or "[", it is
|
|
* treated as a string. Note that the quotes are
|
|
* treated as a string. Note that the quotes are
|
|
* stripped by the parser before we get the string.
|
|
* stripped by the parser before we get the string.
|
|
|
|
+ * newval: An array of strings containing the new property as specified
|
|
|
|
+ * on the command line
|
|
|
|
+ * count: The number of strings in the array
|
|
|
|
+ * data: A bytestream to be placed in the property
|
|
|
|
+ * len: The length of the resulting bytestream
|
|
*/
|
|
*/
|
|
-static int fdt_parse_prop(char *pathp, char *prop, char *newval,
|
|
|
|
- char *data, int *len)
|
|
|
|
|
|
+static int fdt_parse_prop(char **newval, int count, char *data, int *len)
|
|
{
|
|
{
|
|
char *cp; /* temporary char pointer */
|
|
char *cp; /* temporary char pointer */
|
|
|
|
+ char *newp; /* temporary newval char pointer */
|
|
unsigned long tmp; /* holds converted values */
|
|
unsigned long tmp; /* holds converted values */
|
|
|
|
+ int stridx = 0;
|
|
|
|
|
|
- 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) {
|
|
|
|
- *data = tmp & 0xFF;
|
|
|
|
- data += 1;
|
|
|
|
- *len += 1;
|
|
|
|
- } else if ((newval - cp) <= 4) {
|
|
|
|
- *(uint16_t *)data = __cpu_to_be16(tmp);
|
|
|
|
- data += 2;
|
|
|
|
- *len += 2;
|
|
|
|
- } else if ((newval - cp) <= 8) {
|
|
|
|
- *(uint32_t *)data = __cpu_to_be32(tmp);
|
|
|
|
- data += 4;
|
|
|
|
- *len += 4;
|
|
|
|
- } else {
|
|
|
|
|
|
+ *len = 0;
|
|
|
|
+ newp = newval[0];
|
|
|
|
+
|
|
|
|
+ /* An array of cells */
|
|
|
|
+ if (*newp == '<') {
|
|
|
|
+ newp++;
|
|
|
|
+ while ((*newp != '>') && (stridx < count)) {
|
|
|
|
+ /*
|
|
|
|
+ * Keep searching until we find that last ">"
|
|
|
|
+ * That way users don't have to escape the spaces
|
|
|
|
+ */
|
|
|
|
+ if (*newp == '\0') {
|
|
|
|
+ newp = newval[++stridx];
|
|
|
|
+ continue;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ cp = newp;
|
|
|
|
+ tmp = simple_strtoul(cp, &newp, 0);
|
|
|
|
+ *(uint32_t *)data = __cpu_to_be32(tmp);
|
|
|
|
+ data += 4;
|
|
|
|
+ *len += 4;
|
|
|
|
+
|
|
|
|
+ /* If the ptr didn't advance, something went wrong */
|
|
|
|
+ if ((newp - cp) <= 0) {
|
|
printf("Sorry, I could not convert \"%s\"\n",
|
|
printf("Sorry, I could not convert \"%s\"\n",
|
|
cp);
|
|
cp);
|
|
return 1;
|
|
return 1;
|
|
}
|
|
}
|
|
- while (*newval == ' ')
|
|
|
|
- newval++;
|
|
|
|
|
|
+
|
|
|
|
+ while (*newp == ' ')
|
|
|
|
+ newp++;
|
|
}
|
|
}
|
|
- if (*newval != '>') {
|
|
|
|
- printf("Unexpected character '%c'\n", *newval);
|
|
|
|
|
|
+
|
|
|
|
+ if (*newp != '>') {
|
|
|
|
+ printf("Unexpected character '%c'\n", *newp);
|
|
return 1;
|
|
return 1;
|
|
}
|
|
}
|
|
- } else if (*newval == '[') {
|
|
|
|
|
|
+ } else if (*newp == '[') {
|
|
/*
|
|
/*
|
|
* Byte stream. Convert the values.
|
|
* Byte stream. Convert the values.
|
|
*/
|
|
*/
|
|
- *len = 0;
|
|
|
|
- newval++;
|
|
|
|
- while ((*newval != ']') && (*newval != '\0')) {
|
|
|
|
- tmp = simple_strtoul(newval, &newval, 16);
|
|
|
|
|
|
+ newp++;
|
|
|
|
+ while ((*newp != ']') && (stridx < count)) {
|
|
|
|
+ tmp = simple_strtoul(newp, &newp, 16);
|
|
*data++ = tmp & 0xFF;
|
|
*data++ = tmp & 0xFF;
|
|
*len = *len + 1;
|
|
*len = *len + 1;
|
|
- while (*newval == ' ')
|
|
|
|
- newval++;
|
|
|
|
|
|
+ while (*newp == ' ')
|
|
|
|
+ newp++;
|
|
|
|
+ if (*newp != '\0')
|
|
|
|
+ newp = newval[++stridx];
|
|
}
|
|
}
|
|
- if (*newval != ']') {
|
|
|
|
|
|
+ if (*newp != ']') {
|
|
printf("Unexpected character '%c'\n", *newval);
|
|
printf("Unexpected character '%c'\n", *newval);
|
|
return 1;
|
|
return 1;
|
|
}
|
|
}
|
|
@@ -535,8 +542,11 @@ static int fdt_parse_prop(char *pathp, char *prop, char *newval,
|
|
* Assume it is a string. Copy it into our data area for
|
|
* Assume it is a string. Copy it into our data area for
|
|
* convenience (including the terminating '\0').
|
|
* convenience (including the terminating '\0').
|
|
*/
|
|
*/
|
|
- *len = strlen(newval) + 1;
|
|
|
|
- strcpy(data, newval);
|
|
|
|
|
|
+ while (stridx < count) {
|
|
|
|
+ *len = strlen(newp) + 1;
|
|
|
|
+ strcpy(data, newp);
|
|
|
|
+ newp = newval[++stridx];
|
|
|
|
+ }
|
|
}
|
|
}
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
@@ -593,7 +603,6 @@ static int is_printable_string(const void *data, int len)
|
|
static void print_data(const void *data, int len)
|
|
static void print_data(const void *data, int len)
|
|
{
|
|
{
|
|
int j;
|
|
int j;
|
|
- const u8 *s;
|
|
|
|
|
|
|
|
/* no data, don't print */
|
|
/* no data, don't print */
|
|
if (len == 0)
|
|
if (len == 0)
|
|
@@ -616,32 +625,20 @@ static void print_data(const void *data, int len)
|
|
return;
|
|
return;
|
|
}
|
|
}
|
|
|
|
|
|
- switch (len) {
|
|
|
|
- case 1: /* byte */
|
|
|
|
- printf("<0x%02x>", (*(u8 *) data) & 0xff);
|
|
|
|
- break;
|
|
|
|
- case 2: /* half-word */
|
|
|
|
- printf("<0x%04x>", be16_to_cpu(*(u16 *) data) & 0xffff);
|
|
|
|
- break;
|
|
|
|
- case 4: /* word */
|
|
|
|
- printf("<0x%08x>", be32_to_cpu(*(u32 *) data) & 0xffffffffU);
|
|
|
|
- break;
|
|
|
|
- case 8: /* double-word */
|
|
|
|
-#if __WORDSIZE == 64
|
|
|
|
- printf("<0x%016llx>", be64_to_cpu(*(uint64_t *) data));
|
|
|
|
-#else
|
|
|
|
- printf("<0x%08x ", be32_to_cpu(*(u32 *) data) & 0xffffffffU);
|
|
|
|
- data += 4;
|
|
|
|
- printf("0x%08x>", be32_to_cpu(*(u32 *) data) & 0xffffffffU);
|
|
|
|
-#endif
|
|
|
|
- break;
|
|
|
|
- default: /* anything else... hexdump */
|
|
|
|
|
|
+ if ((len %4) == 0) {
|
|
|
|
+ const u32 *p;
|
|
|
|
+
|
|
|
|
+ printf("<");
|
|
|
|
+ for (j = 0, p = data; j < len/4; j ++)
|
|
|
|
+ printf("0x%x%s", p[j], j < (len/4 - 1) ? " " : "");
|
|
|
|
+ printf(">");
|
|
|
|
+ } else { /* anything else... hexdump */
|
|
|
|
+ const u8 *s;
|
|
|
|
+
|
|
printf("[");
|
|
printf("[");
|
|
for (j = 0, s = data; j < len; j++)
|
|
for (j = 0, s = data; j < len; j++)
|
|
printf("%02x%s", s[j], j < len - 1 ? " " : "");
|
|
printf("%02x%s", s[j], j < len - 1 ? " " : "");
|
|
printf("]");
|
|
printf("]");
|
|
-
|
|
|
|
- break;
|
|
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
@@ -771,7 +768,7 @@ static int fdt_print(const char *pathp, char *prop, int depth)
|
|
/********************************************************************/
|
|
/********************************************************************/
|
|
|
|
|
|
U_BOOT_CMD(
|
|
U_BOOT_CMD(
|
|
- fdt, 5, 0, do_fdt,
|
|
|
|
|
|
+ fdt, 255, 0, do_fdt,
|
|
"fdt - flattened device tree utility commands\n",
|
|
"fdt - flattened device tree utility commands\n",
|
|
"addr <addr> [<length>] - Set the fdt location to <addr>\n"
|
|
"addr <addr> [<length>] - Set the fdt location to <addr>\n"
|
|
#ifdef CONFIG_OF_BOARD_SETUP
|
|
#ifdef CONFIG_OF_BOARD_SETUP
|