Merge branch 'master' of git://git.denx.de/u-boot-fdt
This commit is contained in:
commit
71724830b4
182
common/cmd_fdt.c
182
common/cmd_fdt.c
@ -35,6 +35,9 @@
|
||||
|
||||
#define MAX_LEVEL 32 /* how deeply nested we will go */
|
||||
#define SCRATCHPAD 1024 /* bytes of scratchpad memory */
|
||||
#ifndef CONFIG_CMD_FDT_MAX_DUMP
|
||||
#define CONFIG_CMD_FDT_MAX_DUMP 64
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Global data (for the gd->bd)
|
||||
@ -44,6 +47,7 @@ DECLARE_GLOBAL_DATA_PTR;
|
||||
static int fdt_valid(void);
|
||||
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);
|
||||
|
||||
/*
|
||||
* The working_fdt points to our working flattened device tree.
|
||||
@ -60,6 +64,34 @@ void set_working_fdt_addr(void *addr)
|
||||
setenv("fdtaddr", buf);
|
||||
}
|
||||
|
||||
/*
|
||||
* Get a value from the fdt and format it to be set in the environment
|
||||
*/
|
||||
static int fdt_value_setenv(const void *nodep, int len, const char *var)
|
||||
{
|
||||
if (is_printable_string(nodep, len))
|
||||
setenv(var, (void *)nodep);
|
||||
else if (len == 4) {
|
||||
char buf[11];
|
||||
|
||||
sprintf(buf, "0x%08X", *(uint32_t *)nodep);
|
||||
setenv(var, buf);
|
||||
} else if (len%4 == 0 && len <= 20) {
|
||||
/* Needed to print things like sha1 hashes. */
|
||||
char buf[41];
|
||||
int i;
|
||||
|
||||
for (i = 0; i < len; i += sizeof(unsigned int))
|
||||
sprintf(buf + (i * 2), "%08x",
|
||||
*(unsigned int *)(nodep + i));
|
||||
setenv(var, buf);
|
||||
} else {
|
||||
printf("error: unprintable value\n");
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Flattened Device Tree command, see the help for parameter definitions.
|
||||
*/
|
||||
@ -250,6 +282,117 @@ int do_fdt (cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
|
||||
return 1;
|
||||
}
|
||||
|
||||
/********************************************************************
|
||||
* Get the value of a property in the working_fdt.
|
||||
********************************************************************/
|
||||
} else if (argv[1][0] == 'g') {
|
||||
char *subcmd; /* sub-command */
|
||||
char *pathp; /* path */
|
||||
char *prop; /* property */
|
||||
char *var; /* variable to store result */
|
||||
int nodeoffset; /* node offset from libfdt */
|
||||
const void *nodep; /* property node pointer */
|
||||
int len = 0; /* new length of the property */
|
||||
|
||||
/*
|
||||
* Parameters: Node path, property, optional value.
|
||||
*/
|
||||
if (argc < 5)
|
||||
return CMD_RET_USAGE;
|
||||
|
||||
subcmd = argv[2];
|
||||
|
||||
if (argc < 6 && subcmd[0] != 's')
|
||||
return CMD_RET_USAGE;
|
||||
|
||||
var = argv[3];
|
||||
pathp = argv[4];
|
||||
prop = argv[5];
|
||||
|
||||
nodeoffset = fdt_path_offset(working_fdt, pathp);
|
||||
if (nodeoffset < 0) {
|
||||
/*
|
||||
* Not found or something else bad happened.
|
||||
*/
|
||||
printf("libfdt fdt_path_offset() returned %s\n",
|
||||
fdt_strerror(nodeoffset));
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (subcmd[0] == 'n' || (subcmd[0] == 's' && argc == 5)) {
|
||||
int reqIndex = -1;
|
||||
int startDepth = fdt_node_depth(
|
||||
working_fdt, nodeoffset);
|
||||
int curDepth = startDepth;
|
||||
int curIndex = -1;
|
||||
int nextNodeOffset = fdt_next_node(
|
||||
working_fdt, nodeoffset, &curDepth);
|
||||
|
||||
if (subcmd[0] == 'n')
|
||||
reqIndex = simple_strtoul(argv[5], NULL, 16);
|
||||
|
||||
while (curDepth > startDepth) {
|
||||
if (curDepth == startDepth + 1)
|
||||
curIndex++;
|
||||
if (subcmd[0] == 'n' && curIndex == reqIndex) {
|
||||
const char *nodeName = fdt_get_name(
|
||||
working_fdt, nextNodeOffset, NULL);
|
||||
|
||||
setenv(var, (char *)nodeName);
|
||||
return 0;
|
||||
}
|
||||
nextNodeOffset = fdt_next_node(
|
||||
working_fdt, nextNodeOffset, &curDepth);
|
||||
if (nextNodeOffset < 0)
|
||||
break;
|
||||
}
|
||||
if (subcmd[0] == 's') {
|
||||
/* get the num nodes at this level */
|
||||
char buf[11];
|
||||
|
||||
sprintf(buf, "%d", curIndex + 1);
|
||||
setenv(var, buf);
|
||||
} else {
|
||||
/* node index not found */
|
||||
printf("libfdt node not found\n");
|
||||
return 1;
|
||||
}
|
||||
} else {
|
||||
nodep = fdt_getprop(
|
||||
working_fdt, nodeoffset, prop, &len);
|
||||
if (len == 0) {
|
||||
/* no property value */
|
||||
setenv(var, "");
|
||||
return 0;
|
||||
} else if (len > 0) {
|
||||
if (subcmd[0] == 'v') {
|
||||
int ret;
|
||||
|
||||
ret = fdt_value_setenv(nodep, len, var);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
} else if (subcmd[0] == 'a') {
|
||||
/* Get address */
|
||||
char buf[11];
|
||||
|
||||
sprintf(buf, "0x%08X", (uint32_t)nodep);
|
||||
setenv(var, buf);
|
||||
} else if (subcmd[0] == 's') {
|
||||
/* Get size */
|
||||
char buf[11];
|
||||
|
||||
sprintf(buf, "0x%08X", len);
|
||||
setenv(var, buf);
|
||||
} else
|
||||
return CMD_RET_USAGE;
|
||||
return 0;
|
||||
} else {
|
||||
printf("libfdt fdt_getprop(): %s\n",
|
||||
fdt_strerror(len));
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Print (recursive) / List (single level)
|
||||
*/
|
||||
@ -611,12 +754,12 @@ static int is_printable_string(const void *data, int len)
|
||||
if (len == 0)
|
||||
return 0;
|
||||
|
||||
/* must terminate with zero */
|
||||
if (s[len - 1] != '\0')
|
||||
/* must terminate with zero or '\n' */
|
||||
if (s[len - 1] != '\0' && s[len - 1] != '\n')
|
||||
return 0;
|
||||
|
||||
/* printable or a null byte (concatenated strings) */
|
||||
while (((*s == '\0') || isprint(*s)) && (len > 0)) {
|
||||
while (((*s == '\0') || isprint(*s) || isspace(*s)) && (len > 0)) {
|
||||
/*
|
||||
* If we see a null, there are three possibilities:
|
||||
* 1) If len == 1, it is the end of the string, printable
|
||||
@ -672,19 +815,28 @@ static void print_data(const void *data, int len)
|
||||
}
|
||||
|
||||
if ((len %4) == 0) {
|
||||
const u32 *p;
|
||||
if (len > CONFIG_CMD_FDT_MAX_DUMP)
|
||||
printf("* 0x%08x [0x%08x]", (unsigned int)data, len);
|
||||
else {
|
||||
const u32 *p;
|
||||
|
||||
printf("<");
|
||||
for (j = 0, p = data; j < len/4; j ++)
|
||||
printf("0x%x%s", fdt32_to_cpu(p[j]), j < (len/4 - 1) ? " " : "");
|
||||
printf(">");
|
||||
printf("<");
|
||||
for (j = 0, p = data; j < len/4; j++)
|
||||
printf("0x%08x%s", fdt32_to_cpu(p[j]),
|
||||
j < (len/4 - 1) ? " " : "");
|
||||
printf(">");
|
||||
}
|
||||
} else { /* anything else... hexdump */
|
||||
const u8 *s;
|
||||
if (len > CONFIG_CMD_FDT_MAX_DUMP)
|
||||
printf("* 0x%08x [0x%08x]", (unsigned int)data, len);
|
||||
else {
|
||||
const u8 *s;
|
||||
|
||||
printf("[");
|
||||
for (j = 0, s = data; j < len; j++)
|
||||
printf("%02x%s", s[j], j < len - 1 ? " " : "");
|
||||
printf("]");
|
||||
printf("[");
|
||||
for (j = 0, s = data; j < len; j++)
|
||||
printf("%02x%s", s[j], j < len - 1 ? " " : "");
|
||||
printf("]");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -824,6 +976,10 @@ U_BOOT_CMD(
|
||||
"fdt resize - Resize fdt to size + padding to 4k addr\n"
|
||||
"fdt print <path> [<prop>] - Recursive print starting at <path>\n"
|
||||
"fdt list <path> [<prop>] - Print one level starting at <path>\n"
|
||||
"fdt get value <var> <path> <prop> - Get <property> and store in <var>\n"
|
||||
"fdt get name <var> <path> <index> - Get name of node <index> and store in <var>\n"
|
||||
"fdt get addr <var> <path> <prop> - Get start address of <property> and store in <var>\n"
|
||||
"fdt get size <var> <path> [<prop>] - Get size of [<property>] or num nodes and store in <var>\n"
|
||||
"fdt set <path> <prop> [<val>] - Set <property> [to <val>]\n"
|
||||
"fdt mknode <path> <node> - Create a new node after <path>\n"
|
||||
"fdt rm <path> [<prop>] - Delete the node or <property>\n"
|
||||
|
@ -2496,6 +2496,36 @@ int fit_image_hash_get_value(const void *fit, int noffset, uint8_t **value,
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifndef USE_HOSTCC
|
||||
/**
|
||||
* fit_image_hash_get_ignore - get hash ignore flag
|
||||
* @fit: pointer to the FIT format image header
|
||||
* @noffset: hash node offset
|
||||
* @ignore: pointer to an int, will hold hash ignore flag
|
||||
*
|
||||
* fit_image_hash_get_ignore() finds hash ignore property in a given hash node.
|
||||
* If the property is found and non-zero, the hash algorithm is not verified by
|
||||
* u-boot automatically.
|
||||
*
|
||||
* returns:
|
||||
* 0, on ignore not found
|
||||
* value, on ignore found
|
||||
*/
|
||||
int fit_image_hash_get_ignore(const void *fit, int noffset, int *ignore)
|
||||
{
|
||||
int len;
|
||||
int *value;
|
||||
|
||||
value = (int *)fdt_getprop(fit, noffset, FIT_IGNORE_PROP, &len);
|
||||
if (value == NULL || len != sizeof(int))
|
||||
*ignore = 0;
|
||||
else
|
||||
*ignore = *value;
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* fit_set_timestamp - set node timestamp property
|
||||
* @fit: pointer to the FIT format image header
|
||||
@ -2759,6 +2789,9 @@ int fit_image_check_hashes(const void *fit, int image_noffset)
|
||||
char *algo;
|
||||
uint8_t *fit_value;
|
||||
int fit_value_len;
|
||||
#ifndef USE_HOSTCC
|
||||
int ignore;
|
||||
#endif
|
||||
uint8_t value[FIT_MAX_HASH_LEN];
|
||||
int value_len;
|
||||
int noffset;
|
||||
@ -2795,6 +2828,14 @@ int fit_image_check_hashes(const void *fit, int image_noffset)
|
||||
}
|
||||
printf("%s", algo);
|
||||
|
||||
#ifndef USE_HOSTCC
|
||||
fit_image_hash_get_ignore(fit, noffset, &ignore);
|
||||
if (ignore) {
|
||||
printf("-skipped ");
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (fit_image_hash_get_value(fit, noffset, &fit_value,
|
||||
&fit_value_len)) {
|
||||
err_msg = " error!\nCan't get hash value "
|
||||
@ -2820,6 +2861,11 @@ int fit_image_check_hashes(const void *fit, int image_noffset)
|
||||
}
|
||||
}
|
||||
|
||||
if (noffset == -FDT_ERR_TRUNCATED || noffset == -FDT_ERR_BADSTRUCTURE) {
|
||||
err_msg = " error!\nCorrupted or truncated tree";
|
||||
goto error;
|
||||
}
|
||||
|
||||
return 1;
|
||||
|
||||
error:
|
||||
|
@ -511,6 +511,7 @@ static inline int image_check_target_arch(const image_header_t *hdr)
|
||||
#define FIT_HASH_NODENAME "hash"
|
||||
#define FIT_ALGO_PROP "algo"
|
||||
#define FIT_VALUE_PROP "value"
|
||||
#define FIT_IGNORE_PROP "uboot-ignore"
|
||||
|
||||
/* image node */
|
||||
#define FIT_DATA_PROP "data"
|
||||
@ -595,6 +596,9 @@ int fit_image_get_data(const void *fit, int noffset,
|
||||
int fit_image_hash_get_algo(const void *fit, int noffset, char **algo);
|
||||
int fit_image_hash_get_value(const void *fit, int noffset, uint8_t **value,
|
||||
int *value_len);
|
||||
#ifndef USE_HOSTCC
|
||||
int fit_image_hash_get_ignore(const void *fit, int noffset, int *ignore);
|
||||
#endif
|
||||
|
||||
int fit_set_timestamp(void *fit, int noffset, time_t timestamp);
|
||||
int fit_set_hashes(void *fit);
|
||||
|
275
include/libfdt.h
275
include/libfdt.h
@ -852,17 +852,17 @@ int fdt_setprop_inplace(void *fdt, int nodeoffset, const char *name,
|
||||
const void *val, int len);
|
||||
|
||||
/**
|
||||
* fdt_setprop_inplace_cell - change the value of a single-cell property
|
||||
* fdt_setprop_inplace_u32 - change the value of a 32-bit integer property
|
||||
* @fdt: pointer to the device tree blob
|
||||
* @nodeoffset: offset of the node whose property to change
|
||||
* @name: name of the property to change
|
||||
* @val: cell (32-bit integer) value to replace the property with
|
||||
* @val: 32-bit integer value to replace the property with
|
||||
*
|
||||
* fdt_setprop_inplace_cell() replaces the value of a given property
|
||||
* with the 32-bit integer cell value in val, converting val to
|
||||
* big-endian if necessary. This function cannot change the size of a
|
||||
* property, and so will only work if the property already exists and
|
||||
* has length 4.
|
||||
* fdt_setprop_inplace_u32() replaces the value of a given property
|
||||
* with the 32-bit integer value in val, converting val to big-endian
|
||||
* if necessary. This function cannot change the size of a property,
|
||||
* and so will only work if the property already exists and has length
|
||||
* 4.
|
||||
*
|
||||
* This function will alter only the bytes in the blob which contain
|
||||
* the given property value, and will not alter or move any other part
|
||||
@ -871,7 +871,7 @@ int fdt_setprop_inplace(void *fdt, int nodeoffset, const char *name,
|
||||
* returns:
|
||||
* 0, on success
|
||||
* -FDT_ERR_NOSPACE, if the property's length is not equal to 4
|
||||
* -FDT_ERR_NOTFOUND, node does not have the named property
|
||||
* -FDT_ERR_NOTFOUND, node does not have the named property
|
||||
* -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
|
||||
* -FDT_ERR_BADMAGIC,
|
||||
* -FDT_ERR_BADVERSION,
|
||||
@ -879,13 +879,59 @@ int fdt_setprop_inplace(void *fdt, int nodeoffset, const char *name,
|
||||
* -FDT_ERR_BADSTRUCTURE,
|
||||
* -FDT_ERR_TRUNCATED, standard meanings
|
||||
*/
|
||||
static inline int fdt_setprop_inplace_cell(void *fdt, int nodeoffset,
|
||||
const char *name, uint32_t val)
|
||||
static inline int fdt_setprop_inplace_u32(void *fdt, int nodeoffset,
|
||||
const char *name, uint32_t val)
|
||||
{
|
||||
val = cpu_to_fdt32(val);
|
||||
return fdt_setprop_inplace(fdt, nodeoffset, name, &val, sizeof(val));
|
||||
}
|
||||
|
||||
/**
|
||||
* fdt_setprop_inplace_u64 - change the value of a 64-bit integer property
|
||||
* @fdt: pointer to the device tree blob
|
||||
* @nodeoffset: offset of the node whose property to change
|
||||
* @name: name of the property to change
|
||||
* @val: 64-bit integer value to replace the property with
|
||||
*
|
||||
* fdt_setprop_inplace_u64() replaces the value of a given property
|
||||
* with the 64-bit integer value in val, converting val to big-endian
|
||||
* if necessary. This function cannot change the size of a property,
|
||||
* and so will only work if the property already exists and has length
|
||||
* 8.
|
||||
*
|
||||
* This function will alter only the bytes in the blob which contain
|
||||
* the given property value, and will not alter or move any other part
|
||||
* of the tree.
|
||||
*
|
||||
* returns:
|
||||
* 0, on success
|
||||
* -FDT_ERR_NOSPACE, if the property's length is not equal to 8
|
||||
* -FDT_ERR_NOTFOUND, node does not have the named property
|
||||
* -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
|
||||
* -FDT_ERR_BADMAGIC,
|
||||
* -FDT_ERR_BADVERSION,
|
||||
* -FDT_ERR_BADSTATE,
|
||||
* -FDT_ERR_BADSTRUCTURE,
|
||||
* -FDT_ERR_TRUNCATED, standard meanings
|
||||
*/
|
||||
static inline int fdt_setprop_inplace_u64(void *fdt, int nodeoffset,
|
||||
const char *name, uint64_t val)
|
||||
{
|
||||
val = cpu_to_fdt64(val);
|
||||
return fdt_setprop_inplace(fdt, nodeoffset, name, &val, sizeof(val));
|
||||
}
|
||||
|
||||
/**
|
||||
* fdt_setprop_inplace_cell - change the value of a single-cell property
|
||||
*
|
||||
* This is an alternative name for fdt_setprop_inplace_u32()
|
||||
*/
|
||||
static inline int fdt_setprop_inplace_cell(void *fdt, int nodeoffset,
|
||||
const char *name, uint32_t val)
|
||||
{
|
||||
return fdt_setprop_inplace_u32(fdt, nodeoffset, name, val);
|
||||
}
|
||||
|
||||
/**
|
||||
* fdt_nop_property - replace a property with nop tags
|
||||
* @fdt: pointer to the device tree blob
|
||||
@ -945,11 +991,20 @@ int fdt_add_reservemap_entry(void *fdt, uint64_t addr, uint64_t size);
|
||||
int fdt_finish_reservemap(void *fdt);
|
||||
int fdt_begin_node(void *fdt, const char *name);
|
||||
int fdt_property(void *fdt, const char *name, const void *val, int len);
|
||||
static inline int fdt_property_cell(void *fdt, const char *name, uint32_t val)
|
||||
static inline int fdt_property_u32(void *fdt, const char *name, uint32_t val)
|
||||
{
|
||||
val = cpu_to_fdt32(val);
|
||||
return fdt_property(fdt, name, &val, sizeof(val));
|
||||
}
|
||||
static inline int fdt_property_u64(void *fdt, const char *name, uint64_t val)
|
||||
{
|
||||
val = cpu_to_fdt64(val);
|
||||
return fdt_property(fdt, name, &val, sizeof(val));
|
||||
}
|
||||
static inline int fdt_property_cell(void *fdt, const char *name, uint32_t val)
|
||||
{
|
||||
return fdt_property_u32(fdt, name, val);
|
||||
}
|
||||
#define fdt_property_string(fdt, name, str) \
|
||||
fdt_property(fdt, name, str, strlen(str)+1)
|
||||
int fdt_end_node(void *fdt);
|
||||
@ -959,6 +1014,7 @@ int fdt_finish(void *fdt);
|
||||
/* Read-write functions */
|
||||
/**********************************************************************/
|
||||
|
||||
int fdt_create_empty_tree(void *buf, int bufsize);
|
||||
int fdt_open_into(const void *fdt, void *buf, int bufsize);
|
||||
int fdt_pack(void *fdt);
|
||||
|
||||
@ -1068,14 +1124,14 @@ int fdt_setprop(void *fdt, int nodeoffset, const char *name,
|
||||
const void *val, int len);
|
||||
|
||||
/**
|
||||
* fdt_setprop_cell - set a property to a single cell value
|
||||
* fdt_setprop_u32 - set a property to a 32-bit integer
|
||||
* @fdt: pointer to the device tree blob
|
||||
* @nodeoffset: offset of the node whose property to change
|
||||
* @name: name of the property to change
|
||||
* @val: 32-bit integer value for the property (native endian)
|
||||
*
|
||||
* fdt_setprop_cell() sets the value of the named property in the
|
||||
* given node to the given cell value (converting to big-endian if
|
||||
* fdt_setprop_u32() sets the value of the named property in the given
|
||||
* node to the given 32-bit integer value (converting to big-endian if
|
||||
* necessary), or creates a new property with that value if it does
|
||||
* not already exist.
|
||||
*
|
||||
@ -1095,13 +1151,59 @@ int fdt_setprop(void *fdt, int nodeoffset, const char *name,
|
||||
* -FDT_ERR_BADLAYOUT,
|
||||
* -FDT_ERR_TRUNCATED, standard meanings
|
||||
*/
|
||||
static inline int fdt_setprop_cell(void *fdt, int nodeoffset, const char *name,
|
||||
uint32_t val)
|
||||
static inline int fdt_setprop_u32(void *fdt, int nodeoffset, const char *name,
|
||||
uint32_t val)
|
||||
{
|
||||
val = cpu_to_fdt32(val);
|
||||
return fdt_setprop(fdt, nodeoffset, name, &val, sizeof(val));
|
||||
}
|
||||
|
||||
/**
|
||||
* fdt_setprop_u64 - set a property to a 64-bit integer
|
||||
* @fdt: pointer to the device tree blob
|
||||
* @nodeoffset: offset of the node whose property to change
|
||||
* @name: name of the property to change
|
||||
* @val: 64-bit integer value for the property (native endian)
|
||||
*
|
||||
* fdt_setprop_u64() sets the value of the named property in the given
|
||||
* node to the given 64-bit integer value (converting to big-endian if
|
||||
* necessary), or creates a new property with that value if it does
|
||||
* not already exist.
|
||||
*
|
||||
* This function may insert or delete data from the blob, and will
|
||||
* therefore change the offsets of some existing nodes.
|
||||
*
|
||||
* returns:
|
||||
* 0, on success
|
||||
* -FDT_ERR_NOSPACE, there is insufficient free space in the blob to
|
||||
* contain the new property value
|
||||
* -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
|
||||
* -FDT_ERR_BADLAYOUT,
|
||||
* -FDT_ERR_BADMAGIC,
|
||||
* -FDT_ERR_BADVERSION,
|
||||
* -FDT_ERR_BADSTATE,
|
||||
* -FDT_ERR_BADSTRUCTURE,
|
||||
* -FDT_ERR_BADLAYOUT,
|
||||
* -FDT_ERR_TRUNCATED, standard meanings
|
||||
*/
|
||||
static inline int fdt_setprop_u64(void *fdt, int nodeoffset, const char *name,
|
||||
uint64_t val)
|
||||
{
|
||||
val = cpu_to_fdt64(val);
|
||||
return fdt_setprop(fdt, nodeoffset, name, &val, sizeof(val));
|
||||
}
|
||||
|
||||
/**
|
||||
* fdt_setprop_cell - set a property to a single cell value
|
||||
*
|
||||
* This is an alternative name for fdt_setprop_u32()
|
||||
*/
|
||||
static inline int fdt_setprop_cell(void *fdt, int nodeoffset, const char *name,
|
||||
uint32_t val)
|
||||
{
|
||||
return fdt_setprop_u32(fdt, nodeoffset, name, val);
|
||||
}
|
||||
|
||||
/**
|
||||
* fdt_setprop_string - set a property to a string value
|
||||
* @fdt: pointer to the device tree blob
|
||||
@ -1133,6 +1235,147 @@ static inline int fdt_setprop_cell(void *fdt, int nodeoffset, const char *name,
|
||||
#define fdt_setprop_string(fdt, nodeoffset, name, str) \
|
||||
fdt_setprop((fdt), (nodeoffset), (name), (str), strlen(str)+1)
|
||||
|
||||
/**
|
||||
* fdt_appendprop - append to or create a property
|
||||
* @fdt: pointer to the device tree blob
|
||||
* @nodeoffset: offset of the node whose property to change
|
||||
* @name: name of the property to append to
|
||||
* @val: pointer to data to append to the property value
|
||||
* @len: length of the data to append to the property value
|
||||
*
|
||||
* fdt_appendprop() appends the value to the named property in the
|
||||
* given node, creating the property if it does not already exist.
|
||||
*
|
||||
* This function may insert data into the blob, and will therefore
|
||||
* change the offsets of some existing nodes.
|
||||
*
|
||||
* returns:
|
||||
* 0, on success
|
||||
* -FDT_ERR_NOSPACE, there is insufficient free space in the blob to
|
||||
* contain the new property value
|
||||
* -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
|
||||
* -FDT_ERR_BADLAYOUT,
|
||||
* -FDT_ERR_BADMAGIC,
|
||||
* -FDT_ERR_BADVERSION,
|
||||
* -FDT_ERR_BADSTATE,
|
||||
* -FDT_ERR_BADSTRUCTURE,
|
||||
* -FDT_ERR_BADLAYOUT,
|
||||
* -FDT_ERR_TRUNCATED, standard meanings
|
||||
*/
|
||||
int fdt_appendprop(void *fdt, int nodeoffset, const char *name,
|
||||
const void *val, int len);
|
||||
|
||||
/**
|
||||
* fdt_appendprop_u32 - append a 32-bit integer value to a property
|
||||
* @fdt: pointer to the device tree blob
|
||||
* @nodeoffset: offset of the node whose property to change
|
||||
* @name: name of the property to change
|
||||
* @val: 32-bit integer value to append to the property (native endian)
|
||||
*
|
||||
* fdt_appendprop_u32() appends the given 32-bit integer value
|
||||
* (converting to big-endian if necessary) to the value of the named
|
||||
* property in the given node, or creates a new property with that
|
||||
* value if it does not already exist.
|
||||
*
|
||||
* This function may insert data into the blob, and will therefore
|
||||
* change the offsets of some existing nodes.
|
||||
*
|
||||
* returns:
|
||||
* 0, on success
|
||||
* -FDT_ERR_NOSPACE, there is insufficient free space in the blob to
|
||||
* contain the new property value
|
||||
* -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
|
||||
* -FDT_ERR_BADLAYOUT,
|
||||
* -FDT_ERR_BADMAGIC,
|
||||
* -FDT_ERR_BADVERSION,
|
||||
* -FDT_ERR_BADSTATE,
|
||||
* -FDT_ERR_BADSTRUCTURE,
|
||||
* -FDT_ERR_BADLAYOUT,
|
||||
* -FDT_ERR_TRUNCATED, standard meanings
|
||||
*/
|
||||
static inline int fdt_appendprop_u32(void *fdt, int nodeoffset,
|
||||
const char *name, uint32_t val)
|
||||
{
|
||||
val = cpu_to_fdt32(val);
|
||||
return fdt_appendprop(fdt, nodeoffset, name, &val, sizeof(val));
|
||||
}
|
||||
|
||||
/**
|
||||
* fdt_appendprop_u64 - append a 64-bit integer value to a property
|
||||
* @fdt: pointer to the device tree blob
|
||||
* @nodeoffset: offset of the node whose property to change
|
||||
* @name: name of the property to change
|
||||
* @val: 64-bit integer value to append to the property (native endian)
|
||||
*
|
||||
* fdt_appendprop_u64() appends the given 64-bit integer value
|
||||
* (converting to big-endian if necessary) to the value of the named
|
||||
* property in the given node, or creates a new property with that
|
||||
* value if it does not already exist.
|
||||
*
|
||||
* This function may insert data into the blob, and will therefore
|
||||
* change the offsets of some existing nodes.
|
||||
*
|
||||
* returns:
|
||||
* 0, on success
|
||||
* -FDT_ERR_NOSPACE, there is insufficient free space in the blob to
|
||||
* contain the new property value
|
||||
* -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
|
||||
* -FDT_ERR_BADLAYOUT,
|
||||
* -FDT_ERR_BADMAGIC,
|
||||
* -FDT_ERR_BADVERSION,
|
||||
* -FDT_ERR_BADSTATE,
|
||||
* -FDT_ERR_BADSTRUCTURE,
|
||||
* -FDT_ERR_BADLAYOUT,
|
||||
* -FDT_ERR_TRUNCATED, standard meanings
|
||||
*/
|
||||
static inline int fdt_appendprop_u64(void *fdt, int nodeoffset,
|
||||
const char *name, uint64_t val)
|
||||
{
|
||||
val = cpu_to_fdt64(val);
|
||||
return fdt_appendprop(fdt, nodeoffset, name, &val, sizeof(val));
|
||||
}
|
||||
|
||||
/**
|
||||
* fdt_appendprop_cell - append a single cell value to a property
|
||||
*
|
||||
* This is an alternative name for fdt_appendprop_u32()
|
||||
*/
|
||||
static inline int fdt_appendprop_cell(void *fdt, int nodeoffset,
|
||||
const char *name, uint32_t val)
|
||||
{
|
||||
return fdt_appendprop_u32(fdt, nodeoffset, name, val);
|
||||
}
|
||||
|
||||
/**
|
||||
* fdt_appendprop_string - append a string to a property
|
||||
* @fdt: pointer to the device tree blob
|
||||
* @nodeoffset: offset of the node whose property to change
|
||||
* @name: name of the property to change
|
||||
* @str: string value to append to the property
|
||||
*
|
||||
* fdt_appendprop_string() appends the given string to the value of
|
||||
* the named property in the given node, or creates a new property
|
||||
* with that value if it does not already exist.
|
||||
*
|
||||
* This function may insert data into the blob, and will therefore
|
||||
* change the offsets of some existing nodes.
|
||||
*
|
||||
* returns:
|
||||
* 0, on success
|
||||
* -FDT_ERR_NOSPACE, there is insufficient free space in the blob to
|
||||
* contain the new property value
|
||||
* -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
|
||||
* -FDT_ERR_BADLAYOUT,
|
||||
* -FDT_ERR_BADMAGIC,
|
||||
* -FDT_ERR_BADVERSION,
|
||||
* -FDT_ERR_BADSTATE,
|
||||
* -FDT_ERR_BADSTRUCTURE,
|
||||
* -FDT_ERR_BADLAYOUT,
|
||||
* -FDT_ERR_TRUNCATED, standard meanings
|
||||
*/
|
||||
#define fdt_appendprop_string(fdt, nodeoffset, name, str) \
|
||||
fdt_appendprop((fdt), (nodeoffset), (name), (str), strlen(str)+1)
|
||||
|
||||
/**
|
||||
* fdt_delprop - delete a property
|
||||
* @fdt: pointer to the device tree blob
|
||||
|
@ -27,7 +27,7 @@ LIB = $(obj)libfdt.o
|
||||
|
||||
SOBJS =
|
||||
|
||||
COBJS-libfdt += fdt.o fdt_ro.o fdt_rw.o fdt_strerror.o fdt_sw.o fdt_wip.o
|
||||
COBJS-libfdt += fdt.o fdt_ro.o fdt_rw.o fdt_strerror.o fdt_sw.o fdt_wip.o fdt_empty_tree.o
|
||||
|
||||
COBJS-$(CONFIG_OF_LIBFDT) += $(COBJS-libfdt)
|
||||
COBJS-$(CONFIG_FIT) += $(COBJS-libfdt)
|
||||
|
84
lib/libfdt/fdt_empty_tree.c
Normal file
84
lib/libfdt/fdt_empty_tree.c
Normal file
@ -0,0 +1,84 @@
|
||||
/*
|
||||
* libfdt - Flat Device Tree manipulation
|
||||
* Copyright (C) 2012 David Gibson, IBM Corporation.
|
||||
*
|
||||
* libfdt is dual licensed: you can use it either under the terms of
|
||||
* the GPL, or the BSD license, at your option.
|
||||
*
|
||||
* a) This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public
|
||||
* License along with this library; if not, write to the Free
|
||||
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
|
||||
* MA 02110-1301 USA
|
||||
*
|
||||
* Alternatively,
|
||||
*
|
||||
* b) Redistribution and use in source and binary forms, with or
|
||||
* without modification, are permitted provided that the following
|
||||
* conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#include "libfdt_env.h"
|
||||
|
||||
#include <fdt.h>
|
||||
#include <libfdt.h>
|
||||
|
||||
#include "libfdt_internal.h"
|
||||
|
||||
int fdt_create_empty_tree(void *buf, int bufsize)
|
||||
{
|
||||
int err;
|
||||
|
||||
err = fdt_create(buf, bufsize);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
err = fdt_finish_reservemap(buf);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
err = fdt_begin_node(buf, "");
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
err = fdt_end_node(buf);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
err = fdt_finish(buf);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
return fdt_open_into(buf, buf, bufsize);
|
||||
}
|
||||
|
@ -293,6 +293,33 @@ int fdt_setprop(void *fdt, int nodeoffset, const char *name,
|
||||
return 0;
|
||||
}
|
||||
|
||||
int fdt_appendprop(void *fdt, int nodeoffset, const char *name,
|
||||
const void *val, int len)
|
||||
{
|
||||
struct fdt_property *prop;
|
||||
int err, oldlen, newlen;
|
||||
|
||||
FDT_RW_CHECK_HEADER(fdt);
|
||||
|
||||
prop = fdt_get_property_w(fdt, nodeoffset, name, &oldlen);
|
||||
if (prop) {
|
||||
newlen = len + oldlen;
|
||||
err = _fdt_splice_struct(fdt, prop->data,
|
||||
FDT_TAGALIGN(oldlen),
|
||||
FDT_TAGALIGN(newlen));
|
||||
if (err)
|
||||
return err;
|
||||
prop->len = cpu_to_fdt32(newlen);
|
||||
memcpy(prop->data + oldlen, val, len);
|
||||
} else {
|
||||
err = _fdt_add_property(fdt, nodeoffset, name, len, &prop);
|
||||
if (err)
|
||||
return err;
|
||||
memcpy(prop->data, val, len);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int fdt_delprop(void *fdt, int nodeoffset, const char *name)
|
||||
{
|
||||
struct fdt_property *prop;
|
||||
|
Loading…
Reference in New Issue
Block a user