Merge branch 'master' of git://www.denx.de/git/u-boot-fdt

This commit is contained in:
Wolfgang Denk 2008-01-09 11:28:56 +01:00
commit d2ba6bd8f4
5 changed files with 380 additions and 50 deletions

View file

@ -184,23 +184,28 @@ int do_fdt (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
} else if (argv[1][0] == 's') {
char *pathp; /* path */
char *prop; /* property */
char *newval; /* value from the user (as a string) */
int nodeoffset; /* node offset from libfdt */
static char data[SCRATCHPAD]; /* storage for the property */
int len; /* new length of the property */
int ret; /* return value */
/*
* Parameters: Node path, property, value.
* Parameters: Node path, property, optional value.
*/
if (argc < 5) {
if (argc < 4) {
printf ("Usage:\n%s\n", cmdtp->usage);
return 1;
}
pathp = argv[2];
prop = argv[3];
newval = argv[4];
if (argc == 4) {
len = 0;
} else {
ret = fdt_parse_prop(pathp, prop, argv[4], data, &len);
if (ret != 0)
return ret;
}
nodeoffset = fdt_path_offset (fdt, pathp);
if (nodeoffset < 0) {
@ -211,9 +216,6 @@ int do_fdt (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
fdt_strerror(nodeoffset));
return 1;
}
ret = fdt_parse_prop(pathp, prop, newval, data, &len);
if (ret != 0)
return ret;
ret = fdt_setprop(fdt, nodeoffset, prop, data, len);
if (ret < 0) {
@ -681,7 +683,7 @@ U_BOOT_CMD(
#ifdef CONFIG_OF_BOARD_SETUP
"fdt boardsetup - Do board-specific set up\n"
#endif
"fdt move <fdt> <newaddr> <length> - Copy the fdt to <addr>\n"
"fdt move <fdt> <newaddr> <length> - Copy the fdt to <addr> and make it active\n"
"fdt print <path> [<prop>] - Recursive print starting at <path>\n"
"fdt list <path> [<prop>] - Print one level starting at <path>\n"
"fdt set <path> <prop> [<val>] - Set <property> [to <val>]\n"
@ -694,10 +696,6 @@ U_BOOT_CMD(
#ifdef CONFIG_OF_HAS_BD_T
"fdt bd_t - Add/replace the /bd_t branch in the tree\n"
#endif
"Hints:\n"
" If the property you are setting/printing has a '#' character or spaces,\n"
" you MUST escape it with a \\ character or quote it with \".\n"
"Examples: fdt print / # print the whole tree\n"
" fdt print /cpus \"#address-cells\"\n"
" fdt set /cpus \"#address-cells\" \"[00 00 00 01]\"\n"
"NOTE: If the path or property you are setting/printing has a '#' character\n"
" or spaces, you MUST escape it with a \\ character or quote it with \".\n"
);

View file

@ -111,6 +111,7 @@ int fdt_chosen(void *fdt, ulong initrd_start, ulong initrd_end, int force)
int err;
u32 tmp; /* used to set 32 bit integer properties */
char *str; /* used to set string properties */
const char *path;
err = fdt_check_header(fdt);
if (err < 0) {
@ -148,14 +149,7 @@ int fdt_chosen(void *fdt, ulong initrd_start, ulong initrd_end, int force)
nodeoffset = fdt_path_offset (fdt, "/chosen");
/*
* If we have a "chosen" node already the "force the writing"
* is not set, our job is done.
*/
if ((nodeoffset >= 0) && !force)
return 0;
/*
* No "chosen" node in the blob: create it.
* If there is no "chosen" node in the blob, create it.
*/
if (nodeoffset < 0) {
/*
@ -170,42 +164,55 @@ int fdt_chosen(void *fdt, ulong initrd_start, ulong initrd_end, int force)
}
/*
* Update pre-existing properties, create them if non-existant.
* Create /chosen properites that don't exist in the fdt.
* If the property exists, update it only if the "force" parameter
* is true.
*/
str = getenv("bootargs");
if (str != NULL) {
err = fdt_setprop(fdt, nodeoffset,
"bootargs", str, strlen(str)+1);
if (err < 0)
printf("WARNING: could not set bootargs %s.\n",
fdt_strerror(err));
path = fdt_getprop(fdt, nodeoffset, "bootargs", NULL);
if ((path == NULL) || force) {
err = fdt_setprop(fdt, nodeoffset,
"bootargs", str, strlen(str)+1);
if (err < 0)
printf("WARNING: could not set bootargs %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("WARNING: "
"could not set linux,initrd-start %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("WARNING: could not set linux,initrd-end %s.\n",
fdt_strerror(err));
path = fdt_getprop(fdt, nodeoffset, "linux,initrd-start", NULL);
if ((path == NULL) || force) {
tmp = __cpu_to_be32(initrd_start);
err = fdt_setprop(fdt, nodeoffset,
"linux,initrd-start", &tmp, sizeof(tmp));
if (err < 0)
printf("WARNING: "
"could not set linux,initrd-start %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("WARNING: could not set linux,initrd-end %s.\n",
fdt_strerror(err));
}
}
#ifdef CONFIG_OF_STDOUT_VIA_ALIAS
err = fdt_fixup_stdout(fdt, nodeoffset);
path = fdt_getprop(fdt, nodeoffset, "linux,stdout-path", NULL);
if ((path == NULL) || force)
err = fdt_fixup_stdout(fdt, nodeoffset);
#endif
#ifdef OF_STDOUT_PATH
err = fdt_setprop(fdt, nodeoffset,
"linux,stdout-path", OF_STDOUT_PATH, strlen(OF_STDOUT_PATH)+1);
if (err < 0)
printf("WARNING: could not set linux,stdout-path %s.\n",
fdt_strerror(err));
path = fdt_getprop(fdt, nodeoffset, "linux,stdout-path", NULL);
if ((path == NULL) || force) {
err = fdt_setprop(fdt, nodeoffset,
"linux,stdout-path", OF_STDOUT_PATH, strlen(OF_STDOUT_PATH)+1);
if (err < 0)
printf("WARNING: could not set linux,stdout-path %s.\n",
fdt_strerror(err));
}
#endif
return err;

View file

@ -46,6 +46,8 @@ void do_fixup_by_compat_u32(void *fdt, const char *compat,
const char *prop, u32 val, int create);
int fdt_fixup_memory(void *blob, u64 start, u64 size);
void fdt_fixup_ethernet(void *fdt, bd_t *bd);
int fdt_find_and_setprop(void *fdt, const char *node, const char *prop,
const void *val, int len, int create);
#ifdef CONFIG_OF_HAS_UBOOT_ENV
int fdt_env(void *fdt);

View file

@ -655,8 +655,65 @@ int fdt_node_offset_by_compatible(const void *fdt, int startoffset,
/* Write-in-place functions */
/**********************************************************************/
/**
* fdt_setprop_inplace - change a property's value, but not its size
* @fdt: pointer to the device tree blob
* @nodeoffset: offset of the node whose property to change
* @name: name of the property to change
* @val: pointer to data to replace the property value with
* @len: length of the property value
*
* fdt_setprop_inplace() replaces the value of a given property with
* the data in val, of length len. This function cannot change the
* size of a property, and so will only work if len is equal to the
* current length of the property.
*
* 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 len is not equal to the property's current length
* -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
*/
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: 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
*
* 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.
*
* 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 4
* -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_cell(void *fdt, int nodeoffset,
const char *name, uint32_t val)
{
@ -664,7 +721,54 @@ static inline int fdt_setprop_inplace_cell(void *fdt, int nodeoffset,
return fdt_setprop_inplace(fdt, nodeoffset, name, &val, sizeof(val));
}
/**
* fdt_nop_property - replace a property with nop tags
* @fdt: pointer to the device tree blob
* @nodeoffset: offset of the node whose property to nop
* @name: name of the property to nop
*
* fdt_nop_property() will replace a given property's representation
* in the blob with FDT_NOP tags, effectively removing it from the
* tree.
*
* This function will alter only the bytes in the blob which contain
* the property, and will not alter or move any other part of the
* tree.
*
* returns:
* 0, on success
* -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
*/
int fdt_nop_property(void *fdt, int nodeoffset, const char *name);
/**
* fdt_nop_node - replace a node (subtree) with nop tags
* @fdt: pointer to the device tree blob
* @nodeoffset: offset of the node to nop
*
* fdt_nop_node() will replace a given node's representation in the
* blob, including all its subnodes, if any, with FDT_NOP tags,
* effectively removing it from the tree.
*
* This function will alter only the bytes in the blob which contain
* the node and its properties and subnodes, and will not alter or
* move any other part of the tree.
*
* returns:
* 0, on success
* -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
*/
int fdt_nop_node(void *fdt, int nodeoffset);
/**********************************************************************/
@ -693,23 +797,242 @@ int fdt_finish(void *fdt);
int fdt_open_into(const void *fdt, void *buf, int bufsize);
int fdt_pack(void *fdt);
/**
* fdt_add_mem_rsv - add one memory reserve map entry
* @fdt: pointer to the device tree blob
* @addres, @size: 64-bit values (native endian)
*
* Adds a reserve map entry to the given blob reserving a region at
* address address of length size.
*
* This function will insert data into the reserve map and will
* therfore change the indexes of some entries in the table.
*
* returns:
* 0, on success
* -FDT_ERR_NOSPACE, there is insufficient free space in the blob to
* contain the new reservation entry
* -FDT_ERR_BADMAGIC,
* -FDT_ERR_BADVERSION,
* -FDT_ERR_BADSTATE,
* -FDT_ERR_BADSTRUCTURE,
* -FDT_ERR_BADLAYOUT,
* -FDT_ERR_TRUNCATED, standard meanings
*/
int fdt_add_mem_rsv(void *fdt, uint64_t address, uint64_t size);
/**
* fdt_del_mem_rsv - remove a memory reserve map entry
* @fdt: pointer to the device tree blob
* @n: entry to remove
*
* fdt_del_mem_rsv() removes the n-th memory reserve map entry from
* the blob.
*
* This function will delete data from the reservation table and will
* therfore change the indexes of some entries in the table.
*
* returns:
* 0, on success
* -FDT_ERR_NOTFOUND, there is no entry of the given index (i.e. there
* are less than n+1 reserve map entries)
* -FDT_ERR_BADMAGIC,
* -FDT_ERR_BADVERSION,
* -FDT_ERR_BADSTATE,
* -FDT_ERR_BADSTRUCTURE,
* -FDT_ERR_BADLAYOUT,
* -FDT_ERR_TRUNCATED, standard meanings
*/
int fdt_del_mem_rsv(void *fdt, int n);
/**
* fdt_setprop - create or change 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: pointer to data to set the property value to
* @len: length of the property value
*
* fdt_setprop() sets the value of the named property in the given
* node to the given value and length, creeating the property 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
*/
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: 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
* 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_cell(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_string - set a property to a string value
* @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 for the property
*
* fdt_setprop_string() sets the value of the named property in the
* given node to the given string value (using the length of the
* string to determine the new length of the property), 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
*/
#define fdt_setprop_string(fdt, nodeoffset, name, str) \
fdt_setprop((fdt), (nodeoffset), (name), (str), strlen(str)+1)
/**
* fdt_delprop - delete a property
* @fdt: pointer to the device tree blob
* @nodeoffset: offset of the node whose property to nop
* @name: name of the property to nop
*
* fdt_del_property() will delete the given property.
*
* This function will delete data from the blob, and will therefore
* change the offsets of some existing nodes.
*
* returns:
* 0, on success
* -FDT_ERR_NOTFOUND, node does not have the named property
* -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_TRUNCATED, standard meanings
*/
int fdt_delprop(void *fdt, int nodeoffset, const char *name);
/**
* fdt_add_subnode_namelen - creates a new node based on substring
* @fdt: pointer to the device tree blob
* @parentoffset: structure block offset of a node
* @name: name of the subnode to locate
* @namelen: number of characters of name to consider
*
* Identical to fdt_add_subnode(), but use only the first namelen
* characters of name as the name of the new node. This is useful for
* creating subnodes based on a portion of a larger string, such as a
* full path.
*/
int fdt_add_subnode_namelen(void *fdt, int parentoffset,
const char *name, int namelen);
/**
* fdt_add_subnode - creates a new node
* @fdt: pointer to the device tree blob
* @parentoffset: structure block offset of a node
* @name: name of the subnode to locate
*
* fdt_add_subnode() creates a new node as a subnode of the node at
* structure block offset parentoffset, with the given name (which
* should include the unit address, if any).
*
* This function will insert data into the blob, and will therefore
* change the offsets of some existing nodes.
* returns:
* structure block offset of the created nodeequested subnode (>=0), on success
* -FDT_ERR_NOTFOUND, if the requested subnode does not exist
* -FDT_ERR_BADOFFSET, if parentoffset did not point to an FDT_BEGIN_NODE tag
* -FDT_ERR_EXISTS, if the node at parentoffset already has a subnode of
* the given name
* -FDT_ERR_NOSPACE, if there is insufficient free space in the
* blob to contain the new node
* -FDT_ERR_NOSPACE
* -FDT_ERR_BADLAYOUT
* -FDT_ERR_BADMAGIC,
* -FDT_ERR_BADVERSION,
* -FDT_ERR_BADSTATE,
* -FDT_ERR_BADSTRUCTURE,
* -FDT_ERR_TRUNCATED, standard meanings.
*/
int fdt_add_subnode(void *fdt, int parentoffset, const char *name);
/**
* fdt_del_node - delete a node (subtree)
* @fdt: pointer to the device tree blob
* @nodeoffset: offset of the node to nop
*
* fdt_del_node() will remove the given node, including all its
* subnodes if any, from the blob.
*
* This function will delete data from the blob, and will therefore
* change the offsets of some existing nodes.
*
* returns:
* 0, on success
* -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_TRUNCATED, standard meanings
*/
int fdt_del_node(void *fdt, int nodeoffset);
/**********************************************************************/

View file

@ -358,12 +358,12 @@ static void _packblocks(const void *fdt, void *buf,
memmove(buf + mem_rsv_off, fdt + fdt_off_mem_rsvmap(fdt), mem_rsv_size);
fdt_set_off_mem_rsvmap(buf, mem_rsv_off);
memcpy(buf + struct_off, fdt + fdt_off_dt_struct(fdt), struct_size);
memmove(buf + struct_off, fdt + fdt_off_dt_struct(fdt), struct_size);
fdt_set_off_dt_struct(buf, struct_off);
fdt_set_size_dt_struct(buf, struct_size);
memcpy(buf + strings_off, fdt + fdt_off_dt_strings(fdt),
fdt_size_dt_strings(fdt));
memmove(buf + strings_off, fdt + fdt_off_dt_strings(fdt),
fdt_size_dt_strings(fdt));
fdt_set_off_dt_strings(buf, strings_off);
fdt_set_size_dt_strings(buf, fdt_size_dt_strings(fdt));
}