feat(libfdt): upgrade libfdt source files

Update the libfdt source files to the upstream commit e37c256 [1].

[1] https://github.com/dgibson/dtc/commit/e37c256

Change-Id: I00e29b467ff6f8c094f68245232a7cedeaa14aef
Signed-off-by: Daniel Boulby <daniel.boulby@arm.com>
This commit is contained in:
Daniel Boulby 2022-09-23 16:22:27 +01:00
parent 81f4abb8ec
commit 94b2f94bd6
9 changed files with 171 additions and 83 deletions

View file

@ -14,6 +14,7 @@ extern "C" {
#endif
#define FDT_FIRST_SUPPORTED_VERSION 0x02
#define FDT_LAST_COMPATIBLE_VERSION 0x10
#define FDT_LAST_SUPPORTED_VERSION 0x11
/* Error codes: informative error codes */
@ -101,7 +102,11 @@ extern "C" {
/* FDT_ERR_BADFLAGS: The function was passed a flags field that
* contains invalid flags or an invalid combination of flags. */
#define FDT_ERR_MAX 18
#define FDT_ERR_ALIGNMENT 19
/* FDT_ERR_ALIGNMENT: The device tree base address is not 8-byte
* aligned. */
#define FDT_ERR_MAX 19
/* constants */
#define FDT_MAX_PHANDLE 0xfffffffe
@ -122,11 +127,16 @@ static inline void *fdt_offset_ptr_w(void *fdt, int offset, int checklen)
uint32_t fdt_next_tag(const void *fdt, int offset, int *nextoffset);
/*
* Alignment helpers:
* These helpers access words from a device tree blob. They're
* built to work even with unaligned pointers on platforms (ike
* ARM) that don't like unaligned loads and stores
* External helpers to access words from a device tree blob. They're built
* to work even with unaligned pointers on platforms (such as ARMv5) that don't
* like unaligned loads and stores.
*/
static inline uint16_t fdt16_ld(const fdt16_t *p)
{
const uint8_t *bp = (const uint8_t *)p;
return ((uint16_t)bp[0] << 8) | bp[1];
}
static inline uint32_t fdt32_ld(const fdt32_t *p)
{
@ -184,23 +194,23 @@ int fdt_next_node(const void *fdt, int offset, int *depth);
/**
* fdt_first_subnode() - get offset of first direct subnode
*
* @fdt: FDT blob
* @offset: Offset of node to check
* @return offset of first subnode, or -FDT_ERR_NOTFOUND if there is none
*
* Return: offset of first subnode, or -FDT_ERR_NOTFOUND if there is none
*/
int fdt_first_subnode(const void *fdt, int offset);
/**
* fdt_next_subnode() - get offset of next direct subnode
* @fdt: FDT blob
* @offset: Offset of previous subnode
*
* After first calling fdt_first_subnode(), call this function repeatedly to
* get direct subnodes of a parent node.
*
* @fdt: FDT blob
* @offset: Offset of previous subnode
* @return offset of next subnode, or -FDT_ERR_NOTFOUND if there are no more
* subnodes
* Return: offset of next subnode, or -FDT_ERR_NOTFOUND if there are no more
* subnodes
*/
int fdt_next_subnode(const void *fdt, int offset);
@ -225,7 +235,6 @@ int fdt_next_subnode(const void *fdt, int offset);
* Note that this is implemented as a macro and @node is used as
* iterator in the loop. The parent variable be constant or even a
* literal.
*
*/
#define fdt_for_each_subnode(node, fdt, parent) \
for (node = fdt_first_subnode(fdt, parent); \
@ -269,17 +278,21 @@ fdt_set_hdr_(size_dt_struct);
/**
* fdt_header_size - return the size of the tree's header
* @fdt: pointer to a flattened device tree
*
* Return: size of DTB header in bytes
*/
size_t fdt_header_size(const void *fdt);
/**
* fdt_header_size_ - internal function which takes a version number
* fdt_header_size_ - internal function to get header size from a version number
* @version: devicetree version number
*
* Return: size of DTB header in bytes
*/
size_t fdt_header_size_(uint32_t version);
/**
* fdt_check_header - sanity check a device tree header
* @fdt: pointer to data which might be a flattened device tree
*
* fdt_check_header() checks that the given buffer contains what
@ -404,8 +417,7 @@ static inline uint32_t fdt_get_max_phandle(const void *fdt)
* highest phandle value in the device tree blob) will be returned in the
* @phandle parameter.
*
* Returns:
* 0 on success or a negative error-code on failure
* Return: 0 on success or a negative error-code on failure
*/
int fdt_generate_phandle(const void *fdt, uint32_t *phandle);
@ -425,9 +437,11 @@ int fdt_num_mem_rsv(const void *fdt);
/**
* fdt_get_mem_rsv - retrieve one memory reserve map entry
* @fdt: pointer to the device tree blob
* @address, @size: pointers to 64-bit variables
* @n: index of reserve map entry
* @address: pointer to 64-bit variable to hold the start address
* @size: pointer to 64-bit variable to hold the size of the entry
*
* On success, *address and *size will contain the address and size of
* On success, @address and @size will contain the address and size of
* the n-th reserve map entry from the device tree blob, in
* native-endian format.
*
@ -450,6 +464,8 @@ int fdt_get_mem_rsv(const void *fdt, int n, uint64_t *address, uint64_t *size);
* namelen characters of name for matching the subnode name. This is
* useful for finding subnodes based on a portion of a larger string,
* such as a full path.
*
* Return: offset of the subnode or -FDT_ERR_NOTFOUND if name not found.
*/
#ifndef SWIG /* Not available in Python */
int fdt_subnode_offset_namelen(const void *fdt, int parentoffset,
@ -489,6 +505,8 @@ int fdt_subnode_offset(const void *fdt, int parentoffset, const char *name);
*
* Identical to fdt_path_offset(), but only consider the first namelen
* characters of path as the path name.
*
* Return: offset of the node or negative libfdt error value otherwise
*/
#ifndef SWIG /* Not available in Python */
int fdt_path_offset_namelen(const void *fdt, const char *path, int namelen);
@ -588,9 +606,9 @@ int fdt_next_property_offset(const void *fdt, int offset);
/**
* fdt_for_each_property_offset - iterate over all properties of a node
*
* @property_offset: property offset (int, lvalue)
* @fdt: FDT blob (const void *)
* @node: node offset (int)
* @property: property offset (int, lvalue)
* @fdt: FDT blob (const void *)
* @node: node offset (int)
*
* This is actually a wrapper around a for loop and would be used like so:
*
@ -653,6 +671,9 @@ const struct fdt_property *fdt_get_property_by_offset(const void *fdt,
*
* Identical to fdt_get_property(), but only examine the first namelen
* characters of name for matching the property name.
*
* Return: pointer to the structure representing the property, or NULL
* if not found
*/
#ifndef SWIG /* Not available in Python */
const struct fdt_property *fdt_get_property_namelen(const void *fdt,
@ -745,6 +766,8 @@ const void *fdt_getprop_by_offset(const void *fdt, int offset,
*
* Identical to fdt_getprop(), but only examine the first namelen
* characters of name for matching the property name.
*
* Return: pointer to the property's value or NULL on error
*/
#ifndef SWIG /* Not available in Python */
const void *fdt_getprop_namelen(const void *fdt, int nodeoffset,
@ -766,10 +789,10 @@ static inline void *fdt_getprop_namelen_w(void *fdt, int nodeoffset,
* @lenp: pointer to an integer variable (will be overwritten) or NULL
*
* fdt_getprop() retrieves a pointer to the value of the property
* named 'name' of the node at offset nodeoffset (this will be a
* named @name of the node at offset @nodeoffset (this will be a
* pointer to within the device blob itself, not a copy of the value).
* If lenp is non-NULL, the length of the property value is also
* returned, in the integer pointed to by lenp.
* If @lenp is non-NULL, the length of the property value is also
* returned, in the integer pointed to by @lenp.
*
* returns:
* pointer to the property's value
@ -814,8 +837,11 @@ uint32_t fdt_get_phandle(const void *fdt, int nodeoffset);
* @name: name of the alias th look up
* @namelen: number of characters of name to consider
*
* Identical to fdt_get_alias(), but only examine the first namelen
* characters of name for matching the alias name.
* Identical to fdt_get_alias(), but only examine the first @namelen
* characters of @name for matching the alias name.
*
* Return: a pointer to the expansion of the alias named @name, if it exists,
* NULL otherwise
*/
#ifndef SWIG /* Not available in Python */
const char *fdt_get_alias_namelen(const void *fdt,
@ -828,7 +854,7 @@ const char *fdt_get_alias_namelen(const void *fdt,
* @name: name of the alias th look up
*
* fdt_get_alias() retrieves the value of a given alias. That is, the
* value of the property named 'name' in the node /aliases.
* value of the property named @name in the node /aliases.
*
* returns:
* a pointer to the expansion of the alias named 'name', if it exists
@ -1004,14 +1030,13 @@ int fdt_node_offset_by_prop_value(const void *fdt, int startoffset,
int fdt_node_offset_by_phandle(const void *fdt, uint32_t phandle);
/**
* fdt_node_check_compatible: check a node's compatible property
* fdt_node_check_compatible - check a node's compatible property
* @fdt: pointer to the device tree blob
* @nodeoffset: offset of a tree node
* @compatible: string to match against
*
*
* fdt_node_check_compatible() returns 0 if the given node contains a
* 'compatible' property with the given string as one of its elements,
* @compatible property with the given string as one of its elements,
* it returns non-zero otherwise, or on error.
*
* returns:
@ -1075,7 +1100,7 @@ int fdt_node_offset_by_compatible(const void *fdt, int startoffset,
* one or more strings, each terminated by \0, as is found in a device tree
* "compatible" property.
*
* @return: 1 if the string is found in the list, 0 not found, or invalid list
* Return: 1 if the string is found in the list, 0 not found, or invalid list
*/
int fdt_stringlist_contains(const char *strlist, int listlen, const char *str);
@ -1084,7 +1109,8 @@ int fdt_stringlist_contains(const char *strlist, int listlen, const char *str);
* @fdt: pointer to the device tree blob
* @nodeoffset: offset of a tree node
* @property: name of the property containing the string list
* @return:
*
* Return:
* the number of strings in the given property
* -FDT_ERR_BADVALUE if the property value is not NUL-terminated
* -FDT_ERR_NOTFOUND if the property does not exist
@ -1104,7 +1130,7 @@ int fdt_stringlist_count(const void *fdt, int nodeoffset, const char *property);
* small-valued cell properties, such as #address-cells, when searching for
* the empty string.
*
* @return:
* return:
* the index of the string in the list of strings
* -FDT_ERR_BADVALUE if the property value is not NUL-terminated
* -FDT_ERR_NOTFOUND if the property does not exist or does not contain
@ -1128,7 +1154,7 @@ int fdt_stringlist_search(const void *fdt, int nodeoffset, const char *property,
* If non-NULL, the length of the string (on success) or a negative error-code
* (on failure) will be stored in the integer pointer to by lenp.
*
* @return:
* Return:
* A pointer to the string at the given index in the string list or NULL on
* failure. On success the length of the string will be stored in the memory
* location pointed to by the lenp parameter, if non-NULL. On failure one of
@ -1217,6 +1243,8 @@ int fdt_size_cells(const void *fdt, int nodeoffset);
* starting from the given index, and using only the first characters
* of the name. It is useful when you want to manipulate only one value of
* an array and you have a string that doesn't end with \0.
*
* Return: 0 on success, negative libfdt error value otherwise
*/
#ifndef SWIG /* Not available in Python */
int fdt_setprop_inplace_namelen_partial(void *fdt, int nodeoffset,
@ -1330,8 +1358,13 @@ static inline int fdt_setprop_inplace_u64(void *fdt, int nodeoffset,
/**
* fdt_setprop_inplace_cell - change the value of a single-cell property
* @fdt: pointer to the device tree blob
* @nodeoffset: offset of the node containing the property
* @name: name of the property to change the value of
* @val: new value of the 32-bit cell
*
* This is an alternative name for fdt_setprop_inplace_u32()
* Return: 0 on success, negative libfdt error number otherwise.
*/
static inline int fdt_setprop_inplace_cell(void *fdt, int nodeoffset,
const char *name, uint32_t val)
@ -1403,7 +1436,7 @@ int fdt_nop_node(void *fdt, int nodeoffset);
/**
* fdt_create_with_flags - begin creation of a new fdt
* @fdt: pointer to memory allocated where fdt will be created
* @buf: pointer to memory allocated where fdt will be created
* @bufsize: size of the memory space at fdt
* @flags: a valid combination of FDT_CREATE_FLAG_ flags, or 0.
*
@ -1421,7 +1454,7 @@ int fdt_create_with_flags(void *buf, int bufsize, uint32_t flags);
/**
* fdt_create - begin creation of a new fdt
* @fdt: pointer to memory allocated where fdt will be created
* @buf: pointer to memory allocated where fdt will be created
* @bufsize: size of the memory space at fdt
*
* fdt_create() is equivalent to fdt_create_with_flags() with flags=0.
@ -1486,7 +1519,8 @@ int fdt_pack(void *fdt);
/**
* fdt_add_mem_rsv - add one memory reserve map entry
* @fdt: pointer to the device tree blob
* @address, @size: 64-bit values (native endian)
* @address: 64-bit start address of the reserve map entry
* @size: 64-bit size of the reserved region
*
* Adds a reserve map entry to the given blob reserving a region at
* address address of length size.
@ -1691,8 +1725,14 @@ static inline int fdt_setprop_u64(void *fdt, int nodeoffset, const char *name,
/**
* 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)
*
* This is an alternative name for fdt_setprop_u32()
*
* Return: 0 on success, negative libfdt error value otherwise.
*/
static inline int fdt_setprop_cell(void *fdt, int nodeoffset, const char *name,
uint32_t val)
@ -1863,8 +1903,14 @@ static inline int fdt_appendprop_u64(void *fdt, int nodeoffset,
/**
* fdt_appendprop_cell - append a single cell 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)
*
* This is an alternative name for fdt_appendprop_u32()
*
* Return: 0 on success, negative libfdt error value otherwise.
*/
static inline int fdt_appendprop_cell(void *fdt, int nodeoffset,
const char *name, uint32_t val)
@ -1967,13 +2013,16 @@ 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
* @name: name of the subnode to create
* @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
* 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.
*
* Return: structure block offset of the created subnode (>=0),
* negative libfdt error value otherwise
*/
#ifndef SWIG /* Not available in Python */
int fdt_add_subnode_namelen(void *fdt, int parentoffset,
@ -1992,7 +2041,7 @@ int fdt_add_subnode_namelen(void *fdt, int parentoffset,
*
* 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
@ -2067,6 +2116,24 @@ int fdt_del_node(void *fdt, int nodeoffset);
*/
int fdt_overlay_apply(void *fdt, void *fdto);
/**
* fdt_overlay_target_offset - retrieves the offset of a fragment's target
* @fdt: Base device tree blob
* @fdto: Device tree overlay blob
* @fragment_offset: node offset of the fragment in the overlay
* @pathp: pointer which receives the path of the target (or NULL)
*
* fdt_overlay_target_offset() retrieves the target offset in the base
* device tree of a fragment, no matter how the actual targeting is
* done (through a phandle or a path)
*
* returns:
* the targeted node offset in the base device tree
* Negative error code on error
*/
int fdt_overlay_target_offset(const void *fdt, const void *fdto,
int fragment_offset, char const **pathp);
/**********************************************************************/
/* Debugging / informational functions */
/**********************************************************************/

View file

@ -22,6 +22,10 @@ int32_t fdt_ro_probe_(const void *fdt)
if (can_assume(VALID_DTB))
return totalsize;
/* The device tree must be at an 8-byte aligned address */
if ((uintptr_t)fdt & 7)
return -FDT_ERR_ALIGNMENT;
if (fdt_magic(fdt) == FDT_MAGIC) {
/* Complete tree */
if (!can_assume(LATEST)) {
@ -86,6 +90,10 @@ int fdt_check_header(const void *fdt)
{
size_t hdrsize;
/* The device tree must be at an 8-byte aligned address */
if ((uintptr_t)fdt & 7)
return -FDT_ERR_ALIGNMENT;
if (fdt_magic(fdt) != FDT_MAGIC)
return -FDT_ERR_BADMAGIC;
if (!can_assume(LATEST)) {

View file

@ -73,7 +73,7 @@ int fdt_appendprop_addrrange(void *fdt, int parent, int nodeoffset,
/* check validity of address */
prop = data;
if (addr_cells == 1) {
if ((addr > UINT32_MAX) || ((UINT32_MAX + 1 - addr) < size))
if ((addr > UINT32_MAX) || (((uint64_t) UINT32_MAX + 1 - addr) < size))
return -FDT_ERR_BADVALUE;
fdt32_st(prop, (uint32_t)addr);

View file

@ -40,37 +40,22 @@ static uint32_t overlay_get_target_phandle(const void *fdto, int fragment)
return fdt32_to_cpu(*val);
}
/**
* overlay_get_target - retrieves the offset of a fragment's target
* @fdt: Base device tree blob
* @fdto: Device tree overlay blob
* @fragment: node offset of the fragment in the overlay
* @pathp: pointer which receives the path of the target (or NULL)
*
* overlay_get_target() retrieves the target offset in the base
* device tree of a fragment, no matter how the actual targeting is
* done (through a phandle or a path)
*
* returns:
* the targeted node offset in the base device tree
* Negative error code on error
*/
static int overlay_get_target(const void *fdt, const void *fdto,
int fragment, char const **pathp)
int fdt_overlay_target_offset(const void *fdt, const void *fdto,
int fragment_offset, char const **pathp)
{
uint32_t phandle;
const char *path = NULL;
int path_len = 0, ret;
/* Try first to do a phandle based lookup */
phandle = overlay_get_target_phandle(fdto, fragment);
phandle = overlay_get_target_phandle(fdto, fragment_offset);
if (phandle == (uint32_t)-1)
return -FDT_ERR_BADPHANDLE;
/* no phandle, try path */
if (!phandle) {
/* And then a path based lookup */
path = fdt_getprop(fdto, fragment, "target-path", &path_len);
path = fdt_getprop(fdto, fragment_offset, "target-path", &path_len);
if (path)
ret = fdt_path_offset(fdt, path);
else
@ -636,7 +621,7 @@ static int overlay_merge(void *fdt, void *fdto)
if (overlay < 0)
return overlay;
target = overlay_get_target(fdt, fdto, fragment, NULL);
target = fdt_overlay_target_offset(fdt, fdto, fragment, NULL);
if (target < 0)
return target;
@ -779,7 +764,7 @@ static int overlay_symbol_update(void *fdt, void *fdto)
return -FDT_ERR_BADOVERLAY;
/* get the target of the fragment */
ret = overlay_get_target(fdt, fdto, fragment, &target_path);
ret = fdt_overlay_target_offset(fdt, fdto, fragment, &target_path);
if (ret < 0)
return ret;
target = ret;
@ -801,7 +786,7 @@ static int overlay_symbol_update(void *fdt, void *fdto)
if (!target_path) {
/* again in case setprop_placeholder changed it */
ret = overlay_get_target(fdt, fdto, fragment, &target_path);
ret = fdt_overlay_target_offset(fdt, fdto, fragment, &target_path);
if (ret < 0)
return ret;
target = ret;

View file

@ -181,8 +181,8 @@ int fdt_get_mem_rsv(const void *fdt, int n, uint64_t *address, uint64_t *size)
if (!can_assume(VALID_INPUT) && !re)
return -FDT_ERR_BADOFFSET;
*address = fdt64_ld(&re->address);
*size = fdt64_ld(&re->size);
*address = fdt64_ld_(&re->address);
*size = fdt64_ld_(&re->size);
return 0;
}
@ -192,7 +192,7 @@ int fdt_num_mem_rsv(const void *fdt)
const struct fdt_reserve_entry *re;
for (i = 0; (re = fdt_mem_rsv(fdt, i)) != NULL; i++) {
if (fdt64_ld(&re->size) == 0)
if (fdt64_ld_(&re->size) == 0)
return i;
}
return -FDT_ERR_TRUNCATED;
@ -370,7 +370,7 @@ static const struct fdt_property *fdt_get_property_by_offset_(const void *fdt,
prop = fdt_offset_ptr_(fdt, offset);
if (lenp)
*lenp = fdt32_ld(&prop->len);
*lenp = fdt32_ld_(&prop->len);
return prop;
}
@ -408,7 +408,7 @@ static const struct fdt_property *fdt_get_property_namelen_(const void *fdt,
offset = -FDT_ERR_INTERNAL;
break;
}
if (fdt_string_eq_(fdt, fdt32_ld(&prop->nameoff),
if (fdt_string_eq_(fdt, fdt32_ld_(&prop->nameoff),
name, namelen)) {
if (poffset)
*poffset = offset;
@ -461,7 +461,7 @@ const void *fdt_getprop_namelen(const void *fdt, int nodeoffset,
/* Handle realignment */
if (!can_assume(LATEST) && fdt_version(fdt) < 0x10 &&
(poffset + sizeof(*prop)) % 8 && fdt32_ld(&prop->len) >= 8)
(poffset + sizeof(*prop)) % 8 && fdt32_ld_(&prop->len) >= 8)
return prop->data + 4;
return prop->data;
}
@ -479,22 +479,22 @@ const void *fdt_getprop_by_offset(const void *fdt, int offset,
int namelen;
if (!can_assume(VALID_INPUT)) {
name = fdt_get_string(fdt, fdt32_ld(&prop->nameoff),
name = fdt_get_string(fdt, fdt32_ld_(&prop->nameoff),
&namelen);
*namep = name;
if (!name) {
if (lenp)
*lenp = namelen;
return NULL;
}
*namep = name;
} else {
*namep = fdt_string(fdt, fdt32_ld(&prop->nameoff));
*namep = fdt_string(fdt, fdt32_ld_(&prop->nameoff));
}
}
/* Handle realignment */
if (!can_assume(LATEST) && fdt_version(fdt) < 0x10 &&
(offset + sizeof(*prop)) % 8 && fdt32_ld(&prop->len) >= 8)
(offset + sizeof(*prop)) % 8 && fdt32_ld_(&prop->len) >= 8)
return prop->data + 4;
return prop->data;
}
@ -519,7 +519,7 @@ uint32_t fdt_get_phandle(const void *fdt, int nodeoffset)
return 0;
}
return fdt32_ld(php);
return fdt32_ld_(php);
}
const char *fdt_get_alias_namelen(const void *fdt,

View file

@ -349,7 +349,10 @@ int fdt_add_subnode_namelen(void *fdt, int parentoffset,
return offset;
/* Try to place the new node after the parent's properties */
fdt_next_tag(fdt, parentoffset, &nextoffset); /* skip the BEGIN_NODE */
tag = fdt_next_tag(fdt, parentoffset, &nextoffset);
/* the fdt_subnode_offset_namelen() should ensure this never hits */
if (!can_assume(LIBFDT_FLAWLESS) && (tag != FDT_BEGIN_NODE))
return -FDT_ERR_INTERNAL;
do {
offset = nextoffset;
tag = fdt_next_tag(fdt, offset, &nextoffset);
@ -391,7 +394,9 @@ int fdt_del_node(void *fdt, int nodeoffset)
}
static void fdt_packblocks_(const char *old, char *new,
int mem_rsv_size, int struct_size)
int mem_rsv_size,
int struct_size,
int strings_size)
{
int mem_rsv_off, struct_off, strings_off;
@ -406,8 +411,7 @@ static void fdt_packblocks_(const char *old, char *new,
fdt_set_off_dt_struct(new, struct_off);
fdt_set_size_dt_struct(new, struct_size);
memmove(new + strings_off, old + fdt_off_dt_strings(old),
fdt_size_dt_strings(old));
memmove(new + strings_off, old + fdt_off_dt_strings(old), strings_size);
fdt_set_off_dt_strings(new, strings_off);
fdt_set_size_dt_strings(new, fdt_size_dt_strings(old));
}
@ -428,12 +432,14 @@ int fdt_open_into(const void *fdt, void *buf, int bufsize)
if (can_assume(LATEST) || fdt_version(fdt) >= 17) {
struct_size = fdt_size_dt_struct(fdt);
} else {
} else if (fdt_version(fdt) == 16) {
struct_size = 0;
while (fdt_next_tag(fdt, struct_size, &struct_size) != FDT_END)
;
if (struct_size < 0)
return struct_size;
} else {
return -FDT_ERR_BADVERSION;
}
if (can_assume(LIBFDT_ORDER) ||
@ -465,7 +471,8 @@ int fdt_open_into(const void *fdt, void *buf, int bufsize)
return -FDT_ERR_NOSPACE;
}
fdt_packblocks_(fdt, tmp, mem_rsv_size, struct_size);
fdt_packblocks_(fdt, tmp, mem_rsv_size, struct_size,
fdt_size_dt_strings(fdt));
memmove(buf, tmp, newsize);
fdt_set_magic(buf, FDT_MAGIC);
@ -485,7 +492,8 @@ int fdt_pack(void *fdt)
mem_rsv_size = (fdt_num_mem_rsv(fdt)+1)
* sizeof(struct fdt_reserve_entry);
fdt_packblocks_(fdt, fdt, mem_rsv_size, fdt_size_dt_struct(fdt));
fdt_packblocks_(fdt, fdt, mem_rsv_size, fdt_size_dt_struct(fdt),
fdt_size_dt_strings(fdt));
fdt_set_totalsize(fdt, fdt_data_size_(fdt));
return 0;

View file

@ -39,6 +39,7 @@ static struct fdt_errtabent fdt_errtable[] = {
FDT_ERRTABENT(FDT_ERR_BADOVERLAY),
FDT_ERRTABENT(FDT_ERR_NOPHANDLES),
FDT_ERRTABENT(FDT_ERR_BADFLAGS),
FDT_ERRTABENT(FDT_ERR_ALIGNMENT),
};
#define FDT_ERRTABSIZE ((int)(sizeof(fdt_errtable) / sizeof(fdt_errtable[0])))

View file

@ -377,7 +377,7 @@ int fdt_finish(void *fdt)
fdt_set_totalsize(fdt, newstroffset + fdt_size_dt_strings(fdt));
/* And fix up fields that were keeping intermediate state. */
fdt_set_last_comp_version(fdt, FDT_FIRST_SUPPORTED_VERSION);
fdt_set_last_comp_version(fdt, FDT_LAST_COMPATIBLE_VERSION);
fdt_set_magic(fdt, FDT_MAGIC);
return 0;

View file

@ -46,6 +46,25 @@ static inline struct fdt_reserve_entry *fdt_mem_rsv_w_(void *fdt, int n)
return (void *)(uintptr_t)fdt_mem_rsv_(fdt, n);
}
/*
* Internal helpers to access tructural elements of the device tree
* blob (rather than for exaple reading integers from within property
* values). We assume that we are either given a naturally aligned
* address for the platform or if we are not, we are on a platform
* where unaligned memory reads will be handled in a graceful manner.
* If not the external helpers fdtXX_ld() from libfdt.h can be used
* instead.
*/
static inline uint32_t fdt32_ld_(const fdt32_t *p)
{
return fdt32_to_cpu(*p);
}
static inline uint64_t fdt64_ld_(const fdt64_t *p)
{
return fdt64_to_cpu(*p);
}
#define FDT_SW_MAGIC (~FDT_MAGIC)
/**********************************************************************/