Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
Menu
Open sidebar
adam.huang
Arm Trusted Firmware
Commits
7b94e4b9
Commit
7b94e4b9
authored
Jan 23, 2017
by
danh-arm
Committed by
GitHub
Jan 23, 2017
Browse files
Merge pull request #813 from antonio-nino-diaz-arm/an/libfdt
Update libfdt to version 1.4.2
parents
23beccc9
29440c19
Changes
7
Hide whitespace changes
Inline
Side-by-side
Makefile
View file @
7b94e4b9
...
...
@@ -66,7 +66,7 @@ INC_DIRS_TO_CHECK := $(sort $(filter-out \
include/lib,
\
$(
wildcard
include/
*
)))
LIB_DIRS_TO_CHECK
:=
$(
sort
$(
filter-out
\
lib/libfdt
\
lib/libfdt
%
\
lib/stdlib,
\
$(
wildcard
lib/
*
)))
ROOT_DIRS_TO_CHECK
:=
$(
sort
$(
filter-out
\
...
...
@@ -568,7 +568,7 @@ realclean distclean:
checkcodebase
:
locate-checkpatch
@
echo
" CHECKING STYLE"
@
if
test
-d
.git
;
then
\
git ls-files |
grep
-E
-v
libfdt
\
|
stdlib
\
|
docs
\
|\.
md |
\
git ls-files |
grep
-E
-v
'
libfdt|stdlib|docs|\.md
'
|
\
while
read
GIT_FILE
;
\
do
${CHECKPATCH}
${CHECKCODE_ARGS}
-f
$$
GIT_FILE
;
\
done
;
\
...
...
include/lib/libfdt/fdt.h
View file @
7b94e4b9
...
...
@@ -53,7 +53,7 @@
*/
/*
* Portions copyright (c) 2016, ARM Limited and Contributors.
* Portions copyright (c) 2016
-2017
, ARM Limited and Contributors.
* All rights reserved.
*/
...
...
include/lib/libfdt/libfdt.h
View file @
7b94e4b9
...
...
@@ -52,7 +52,7 @@
*/
/*
* Portions copyright (c) 2016, ARM Limited and Contributors.
* Portions copyright (c) 2016
-2017
, ARM Limited and Contributors.
* All rights reserved.
*/
...
...
@@ -126,7 +126,12 @@
/* FDT_ERR_BADNCELLS: Device tree has a #address-cells, #size-cells
* or similar property with a bad format or value */
#define FDT_ERR_MAX 14
#define FDT_ERR_BADVALUE 15
/* FDT_ERR_BADVALUE: Device tree has a property with an unexpected
* value. For example: a property expected to contain a string list
* is not NUL-terminated within the length of its value. */
#define FDT_ERR_MAX 15
/**********************************************************************/
/* Low-level functions (you probably don't need these) */
...
...
@@ -168,27 +173,55 @@ int fdt_first_subnode(const void *fdt, int offset);
*/
int
fdt_next_subnode
(
const
void
*
fdt
,
int
offset
);
/**
* fdt_for_each_subnode - iterate over all subnodes of a parent
*
* @node: child node (int, lvalue)
* @fdt: FDT blob (const void *)
* @parent: parent node (int)
*
* This is actually a wrapper around a for loop and would be used like so:
*
* fdt_for_each_subnode(node, fdt, parent) {
* Use node
* ...
* }
*
* if ((node < 0) && (node != -FDT_ERR_NOT_FOUND)) {
* Error handling
* }
*
* 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); \
node >= 0; \
node = fdt_next_subnode(fdt, node))
/**********************************************************************/
/* General functions */
/**********************************************************************/
#define fdt_get_header(fdt, field) \
(fdt32_to_cpu(((const struct fdt_header *)(fdt))->field))
#define fdt_magic(fdt)
(fdt_get_header(fdt, magic))
#define fdt_magic(fdt) (fdt_get_header(fdt, magic))
#define fdt_totalsize(fdt) (fdt_get_header(fdt, totalsize))
#define fdt_off_dt_struct(fdt) (fdt_get_header(fdt, off_dt_struct))
#define fdt_off_dt_strings(fdt) (fdt_get_header(fdt, off_dt_strings))
#define fdt_off_mem_rsvmap(fdt) (fdt_get_header(fdt, off_mem_rsvmap))
#define fdt_version(fdt) (fdt_get_header(fdt, version))
#define fdt_last_comp_version(fdt)
(fdt_get_header(fdt, last_comp_version))
#define fdt_boot_cpuid_phys(fdt)
(fdt_get_header(fdt, boot_cpuid_phys))
#define fdt_size_dt_strings(fdt)
(fdt_get_header(fdt, size_dt_strings))
#define fdt_last_comp_version(fdt) (fdt_get_header(fdt, last_comp_version))
#define fdt_boot_cpuid_phys(fdt) (fdt_get_header(fdt, boot_cpuid_phys))
#define fdt_size_dt_strings(fdt) (fdt_get_header(fdt, size_dt_strings))
#define fdt_size_dt_struct(fdt) (fdt_get_header(fdt, size_dt_struct))
#define __fdt_set_hdr(name) \
static inline void fdt_set_##name(void *fdt, uint32_t val) \
{ \
struct fdt_header *fdth = (struct fdt_header*)fdt; \
struct fdt_header *fdth = (struct fdt_header
*)fdt; \
fdth->name = cpu_to_fdt32(val); \
}
__fdt_set_hdr
(
magic
)
...
...
@@ -258,6 +291,21 @@ int fdt_move(const void *fdt, void *buf, int bufsize);
*/
const
char
*
fdt_string
(
const
void
*
fdt
,
int
stroffset
);
/**
* fdt_get_max_phandle - retrieves the highest phandle in a tree
* @fdt: pointer to the device tree blob
*
* fdt_get_max_phandle retrieves the highest phandle in the given
* device tree. This will ignore badly formatted phandles, or phandles
* with a value of 0 or -1.
*
* returns:
* the highest phandle on success
* 0, if no phandle was found in the device tree
* -1, if an error occurred
*/
uint32_t
fdt_get_max_phandle
(
const
void
*
fdt
);
/**
* fdt_num_mem_rsv - retrieve the number of memory reserve map entries
* @fdt: pointer to the device tree blob
...
...
@@ -318,8 +366,9 @@ int fdt_subnode_offset_namelen(const void *fdt, int parentoffset,
* returns:
* structure block offset of the requested 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_BADMAGIC,
* -FDT_ERR_BADOFFSET, if parentoffset did not point to an FDT_BEGIN_NODE
* tag
* -FDT_ERR_BADMAGIC,
* -FDT_ERR_BADVERSION,
* -FDT_ERR_BADSTATE,
* -FDT_ERR_BADSTRUCTURE,
...
...
@@ -327,6 +376,17 @@ int fdt_subnode_offset_namelen(const void *fdt, int parentoffset,
*/
int
fdt_subnode_offset
(
const
void
*
fdt
,
int
parentoffset
,
const
char
*
name
);
/**
* fdt_path_offset_namelen - find a tree node by its full path
* @fdt: pointer to the device tree blob
* @path: full path of the node to locate
* @namelen: number of characters of path to consider
*
* Identical to fdt_path_offset(), but only consider the first namelen
* characters of path as the path name.
*/
int
fdt_path_offset_namelen
(
const
void
*
fdt
,
const
char
*
path
,
int
namelen
);
/**
* fdt_path_offset - find a tree node by its full path
* @fdt: pointer to the device tree blob
...
...
@@ -340,7 +400,8 @@ int fdt_subnode_offset(const void *fdt, int parentoffset, const char *name);
* address).
*
* returns:
* structure block offset of the node with the requested path (>=0), on success
* structure block offset of the node with the requested path (>=0), on
* success
* -FDT_ERR_BADPATH, given path does not begin with '/' or is invalid
* -FDT_ERR_NOTFOUND, if the requested node does not exist
* -FDT_ERR_BADMAGIC,
...
...
@@ -364,10 +425,12 @@ int fdt_path_offset(const void *fdt, const char *path);
*
* returns:
* pointer to the node's name, on success
* If lenp is non-NULL, *lenp contains the length of that name (>=0)
* If lenp is non-NULL, *lenp contains the length of that name
* (>=0)
* NULL, on error
* if lenp is non-NULL *lenp contains an error code (<0):
* -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
* -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE
* tag
* -FDT_ERR_BADMAGIC,
* -FDT_ERR_BADVERSION,
* -FDT_ERR_BADSTATE, standard meanings
...
...
@@ -415,6 +478,33 @@ int fdt_first_property_offset(const void *fdt, int nodeoffset);
*/
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)
*
* This is actually a wrapper around a for loop and would be used like so:
*
* fdt_for_each_property_offset(property, fdt, node) {
* Use property
* ...
* }
*
* if ((property < 0) && (property != -FDT_ERR_NOT_FOUND)) {
* Error handling
* }
*
* Note that this is implemented as a macro and property is used as
* iterator in the loop. The node variable can be constant or even a
* literal.
*/
#define fdt_for_each_property_offset(property, fdt, node) \
for (property = fdt_first_property_offset(fdt, node); \
property >= 0; \
property = fdt_next_property_offset(fdt, property))
/**
* fdt_get_property_by_offset - retrieve the property at a given offset
* @fdt: pointer to the device tree blob
...
...
@@ -451,8 +541,8 @@ const struct fdt_property *fdt_get_property_by_offset(const void *fdt,
* @namelen: number of characters of name to consider
* @lenp: pointer to an integer variable (will be overwritten) or NULL
*
* Identical to fdt_get_property
_namelen
(), but only examine the first
*
namelen
characters of name for matching the property name.
* Identical to fdt_get_property(), but only examine the first
namelen
* characters of name for matching the property name.
*/
const
struct
fdt_property
*
fdt_get_property_namelen
(
const
void
*
fdt
,
int
nodeoffset
,
...
...
@@ -479,7 +569,8 @@ const struct fdt_property *fdt_get_property_namelen(const void *fdt,
* NULL, on error
* if lenp is non-NULL, *lenp contains an error code (<0):
* -FDT_ERR_NOTFOUND, node does not have named property
* -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
* -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE
* tag
* -FDT_ERR_BADMAGIC,
* -FDT_ERR_BADVERSION,
* -FDT_ERR_BADSTATE,
...
...
@@ -543,6 +634,13 @@ const void *fdt_getprop_by_offset(const void *fdt, int offset,
*/
const
void
*
fdt_getprop_namelen
(
const
void
*
fdt
,
int
nodeoffset
,
const
char
*
name
,
int
namelen
,
int
*
lenp
);
static
inline
void
*
fdt_getprop_namelen_w
(
void
*
fdt
,
int
nodeoffset
,
const
char
*
name
,
int
namelen
,
int
*
lenp
)
{
return
(
void
*
)(
uintptr_t
)
fdt_getprop_namelen
(
fdt
,
nodeoffset
,
name
,
namelen
,
lenp
);
}
/**
* fdt_getprop - retrieve the value of a given property
...
...
@@ -564,7 +662,8 @@ const void *fdt_getprop_namelen(const void *fdt, int nodeoffset,
* NULL, on error
* if lenp is non-NULL, *lenp contains an error code (<0):
* -FDT_ERR_NOTFOUND, node does not have named property
* -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
* -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE
* tag
* -FDT_ERR_BADMAGIC,
* -FDT_ERR_BADVERSION,
* -FDT_ERR_BADSTATE,
...
...
@@ -636,7 +735,7 @@ const char *fdt_get_alias(const void *fdt, const char *name);
* 0, on success
* buf contains the absolute path of the node at
* nodeoffset, as a NUL-terminated string.
*
-FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag
* -FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag
* -FDT_ERR_NOSPACE, the path of the given node is longer than (bufsize-1)
* characters and will not fit in the given buffer.
* -FDT_ERR_BADMAGIC,
...
...
@@ -666,11 +765,11 @@ int fdt_get_path(const void *fdt, int nodeoffset, char *buf, int buflen);
* structure from the start to nodeoffset.
*
* returns:
* structure block offset of the node at node offset's ancestor
* of depth supernodedepth (>=0), on success
* -FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag
* -FDT_ERR_NOTFOUND, supernodedepth was greater than the depth of nodeoffset
* -FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag
* -FDT_ERR_NOTFOUND, supernodedepth was greater than the depth of
* nodeoffset
* -FDT_ERR_BADMAGIC,
* -FDT_ERR_BADVERSION,
* -FDT_ERR_BADSTATE,
...
...
@@ -692,7 +791,7 @@ int fdt_supernode_atdepth_offset(const void *fdt, int nodeoffset,
*
* returns:
* depth of the node at nodeoffset (>=0), on success
*
-FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag
* -FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag
* -FDT_ERR_BADMAGIC,
* -FDT_ERR_BADVERSION,
* -FDT_ERR_BADSTATE,
...
...
@@ -715,7 +814,7 @@ int fdt_node_depth(const void *fdt, int nodeoffset);
* returns:
* structure block offset of the parent of the node at nodeoffset
* (>=0), on success
*
-FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag
* -FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag
* -FDT_ERR_BADMAGIC,
* -FDT_ERR_BADVERSION,
* -FDT_ERR_BADSTATE,
...
...
@@ -755,7 +854,7 @@ int fdt_parent_offset(const void *fdt, int nodeoffset);
* on success
* -FDT_ERR_NOTFOUND, no node matching the criterion exists in the
* tree after startoffset
*
-FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag
* -FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag
* -FDT_ERR_BADMAGIC,
* -FDT_ERR_BADVERSION,
* -FDT_ERR_BADSTATE,
...
...
@@ -802,7 +901,7 @@ int fdt_node_offset_by_phandle(const void *fdt, uint32_t phandle);
* 1, if the node has a 'compatible' property, but it does not list
* the given string
* -FDT_ERR_NOTFOUND, if the given node has no 'compatible' property
*
-FDT_ERR_BADOFFSET, if nodeoffset does not refer to a BEGIN_NODE tag
* -FDT_ERR_BADOFFSET, if nodeoffset does not refer to a BEGIN_NODE tag
* -FDT_ERR_BADMAGIC,
* -FDT_ERR_BADVERSION,
* -FDT_ERR_BADSTATE,
...
...
@@ -839,7 +938,7 @@ int fdt_node_check_compatible(const void *fdt, int nodeoffset,
* on success
* -FDT_ERR_NOTFOUND, no node matching the criterion exists in the
* tree after startoffset
*
-FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag
* -FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag
* -FDT_ERR_BADMAGIC,
* -FDT_ERR_BADVERSION,
* -FDT_ERR_BADSTATE,
...
...
@@ -862,6 +961,68 @@ int fdt_node_offset_by_compatible(const void *fdt, int startoffset,
*/
int
fdt_stringlist_contains
(
const
char
*
strlist
,
int
listlen
,
const
char
*
str
);
/**
* fdt_stringlist_count - count the number of strings in a string list
* @fdt: pointer to the device tree blob
* @nodeoffset: offset of a tree node
* @property: name of the property containing the string list
* @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
*/
int
fdt_stringlist_count
(
const
void
*
fdt
,
int
nodeoffset
,
const
char
*
property
);
/**
* fdt_stringlist_search - find a string in a string list and return its index
* @fdt: pointer to the device tree blob
* @nodeoffset: offset of a tree node
* @property: name of the property containing the string list
* @string: string to look up in the string list
*
* Note that it is possible for this function to succeed on property values
* that are not NUL-terminated. That's because the function will stop after
* finding the first occurrence of @string. This can for example happen with
* small-valued cell properties, such as #address-cells, when searching for
* the empty string.
*
* @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
* the given string
*/
int
fdt_stringlist_search
(
const
void
*
fdt
,
int
nodeoffset
,
const
char
*
property
,
const
char
*
string
);
/**
* fdt_stringlist_get() - obtain the string at a given index in a string list
* @fdt: pointer to the device tree blob
* @nodeoffset: offset of a tree node
* @property: name of the property containing the string list
* @index: index of the string to return
* @lenp: return location for the string length or an error code on failure
*
* Note that this will successfully extract strings from properties with
* non-NUL-terminated values. For example on small-valued cell properties
* this function will return the empty string.
*
* 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:
* 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
* the following negative error codes will be returned in the lenp parameter
* (if non-NULL):
* -FDT_ERR_BADVALUE if the property value is not NUL-terminated
* -FDT_ERR_NOTFOUND if the property does not exist
*/
const
char
*
fdt_stringlist_get
(
const
void
*
fdt
,
int
nodeoffset
,
const
char
*
property
,
int
index
,
int
*
lenp
);
/**********************************************************************/
/* Read-only functions (addressing related) */
/**********************************************************************/
...
...
@@ -887,7 +1048,8 @@ int fdt_stringlist_contains(const char *strlist, int listlen, const char *str);
* returns:
* 0 <= n < FDT_MAX_NCELLS, on success
* 2, if the node has no #address-cells property
* -FDT_ERR_BADNCELLS, if the node has a badly formatted or invalid #address-cells property
* -FDT_ERR_BADNCELLS, if the node has a badly formatted or invalid
* #address-cells property
* -FDT_ERR_BADMAGIC,
* -FDT_ERR_BADVERSION,
* -FDT_ERR_BADSTATE,
...
...
@@ -907,7 +1069,8 @@ int fdt_address_cells(const void *fdt, int nodeoffset);
* returns:
* 0 <= n < FDT_MAX_NCELLS, on success
* 2, if the node has no #address-cells property
* -FDT_ERR_BADNCELLS, if the node has a badly formatted or invalid #size-cells property
* -FDT_ERR_BADNCELLS, if the node has a badly formatted or invalid
* #size-cells property
* -FDT_ERR_BADMAGIC,
* -FDT_ERR_BADVERSION,
* -FDT_ERR_BADSTATE,
...
...
@@ -921,6 +1084,27 @@ int fdt_size_cells(const void *fdt, int nodeoffset);
/* Write-in-place functions */
/**********************************************************************/
/**
* fdt_setprop_inplace_namelen_partial - 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
* @namelen: number of characters of name to consider
* @idx: index of the property to change in the array
* @val: pointer to data to replace the property value with
* @len: length of the property value
*
* Identical to fdt_setprop_inplace(), but modifies the given property
* 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.
*/
int
fdt_setprop_inplace_namelen_partial
(
void
*
fdt
,
int
nodeoffset
,
const
char
*
name
,
int
namelen
,
uint32_t
idx
,
const
void
*
val
,
int
len
);
/**
* fdt_setprop_inplace - change a property's value, but not its size
* @fdt: pointer to the device tree blob
...
...
@@ -1531,9 +1715,11 @@ int fdt_add_subnode_namelen(void *fdt, int parentoffset,
* change the offsets of some existing nodes.
* returns:
* structure block offset of the created nodeequested subnode (>=0), on success
* 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_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
...
...
lib/libfdt/fdt.c
View file @
7b94e4b9
...
...
@@ -76,18 +76,19 @@ int fdt_check_header(const void *fdt)
const
void
*
fdt_offset_ptr
(
const
void
*
fdt
,
int
offset
,
unsigned
int
len
)
{
const
char
*
p
;
unsigned
absoffset
=
offset
+
fdt_off_dt_struct
(
fdt
);
if
((
absoffset
<
offset
)
||
((
absoffset
+
len
)
<
absoffset
)
||
(
absoffset
+
len
)
>
fdt_totalsize
(
fdt
))
return
NULL
;
if
(
fdt_version
(
fdt
)
>=
0x11
)
if
(((
offset
+
len
)
<
offset
)
||
((
offset
+
len
)
>
fdt_size_dt_struct
(
fdt
)))
return
NULL
;
p
=
_fdt_offset_ptr
(
fdt
,
offset
);
if
(
p
+
len
<
p
)
return
NULL
;
return
p
;
return
_fdt_offset_ptr
(
fdt
,
offset
);
}
uint32_t
fdt_next_tag
(
const
void
*
fdt
,
int
startoffset
,
int
*
nextoffset
)
...
...
lib/libfdt/fdt_ro.c
View file @
7b94e4b9
...
...
@@ -88,6 +88,32 @@ static int _fdt_string_eq(const void *fdt, int stroffset,
return
(
strlen
(
p
)
==
len
)
&&
(
memcmp
(
p
,
s
,
len
)
==
0
);
}
uint32_t
fdt_get_max_phandle
(
const
void
*
fdt
)
{
uint32_t
max_phandle
=
0
;
int
offset
;
for
(
offset
=
fdt_next_node
(
fdt
,
-
1
,
NULL
);;
offset
=
fdt_next_node
(
fdt
,
offset
,
NULL
))
{
uint32_t
phandle
;
if
(
offset
==
-
FDT_ERR_NOTFOUND
)
return
max_phandle
;
if
(
offset
<
0
)
return
(
uint32_t
)
-
1
;
phandle
=
fdt_get_phandle
(
fdt
,
offset
);
if
(
phandle
==
(
uint32_t
)
-
1
)
continue
;
if
(
phandle
>
max_phandle
)
max_phandle
=
phandle
;
}
return
0
;
}
int
fdt_get_mem_rsv
(
const
void
*
fdt
,
int
n
,
uint64_t
*
address
,
uint64_t
*
size
)
{
FDT_CHECK_HEADER
(
fdt
);
...
...
@@ -154,9 +180,9 @@ int fdt_subnode_offset(const void *fdt, int parentoffset,
return
fdt_subnode_offset_namelen
(
fdt
,
parentoffset
,
name
,
strlen
(
name
));
}
int
fdt_path_offset
(
const
void
*
fdt
,
const
char
*
path
)
int
fdt_path_offset
_namelen
(
const
void
*
fdt
,
const
char
*
path
,
int
namelen
)
{
const
char
*
end
=
path
+
strlen
(
path
)
;
const
char
*
end
=
path
+
namelen
;
const
char
*
p
=
path
;
int
offset
=
0
;
...
...
@@ -164,7 +190,7 @@ int fdt_path_offset(const void *fdt, const char *path)
/* see if we have an alias */
if
(
*
path
!=
'/'
)
{
const
char
*
q
=
str
chr
(
path
,
'/'
);
const
char
*
q
=
mem
chr
(
path
,
'/'
,
end
-
p
);
if
(
!
q
)
q
=
end
;
...
...
@@ -177,14 +203,15 @@ int fdt_path_offset(const void *fdt, const char *path)
p
=
q
;
}
while
(
*
p
)
{
while
(
p
<
end
)
{
const
char
*
q
;
while
(
*
p
==
'/'
)
while
(
*
p
==
'/'
)
{
p
++
;
if
(
!
*
p
)
return
offset
;
q
=
strchr
(
p
,
'/'
);
if
(
p
==
end
)
return
offset
;
}
q
=
memchr
(
p
,
'/'
,
end
-
p
);
if
(
!
q
)
q
=
end
;
...
...
@@ -198,6 +225,11 @@ int fdt_path_offset(const void *fdt, const char *path)
return
offset
;
}
int
fdt_path_offset
(
const
void
*
fdt
,
const
char
*
path
)
{
return
fdt_path_offset_namelen
(
fdt
,
path
,
strlen
(
path
));
}
const
char
*
fdt_get_name
(
const
void
*
fdt
,
int
nodeoffset
,
int
*
len
)
{
const
struct
fdt_node_header
*
nh
=
_fdt_offset_ptr
(
fdt
,
nodeoffset
);
...
...
@@ -532,6 +564,106 @@ int fdt_stringlist_contains(const char *strlist, int listlen, const char *str)
return
0
;
}
int
fdt_stringlist_count
(
const
void
*
fdt
,
int
nodeoffset
,
const
char
*
property
)
{
const
char
*
list
,
*
end
;
int
length
,
count
=
0
;
list
=
fdt_getprop
(
fdt
,
nodeoffset
,
property
,
&
length
);
if
(
!
list
)
return
-
length
;
end
=
list
+
length
;
while
(
list
<
end
)
{
length
=
strnlen
(
list
,
end
-
list
)
+
1
;
/* Abort if the last string isn't properly NUL-terminated. */
if
(
list
+
length
>
end
)
return
-
FDT_ERR_BADVALUE
;
list
+=
length
;
count
++
;
}
return
count
;
}
int
fdt_stringlist_search
(
const
void
*
fdt
,
int
nodeoffset
,
const
char
*
property
,
const
char
*
string
)
{
int
length
,
len
,
idx
=
0
;
const
char
*
list
,
*
end
;
list
=
fdt_getprop
(
fdt
,
nodeoffset
,
property
,
&
length
);
if
(
!
list
)
return
-
length
;
len
=
strlen
(
string
)
+
1
;
end
=
list
+
length
;
while
(
list
<
end
)
{
length
=
strnlen
(
list
,
end
-
list
)
+
1
;
/* Abort if the last string isn't properly NUL-terminated. */
if
(
list
+
length
>
end
)
return
-
FDT_ERR_BADVALUE
;
if
(
length
==
len
&&
memcmp
(
list
,
string
,
length
)
==
0
)
return
idx
;
list
+=
length
;
idx
++
;
}
return
-
FDT_ERR_NOTFOUND
;
}
const
char
*
fdt_stringlist_get
(
const
void
*
fdt
,
int
nodeoffset
,
const
char
*
property
,
int
idx
,
int
*
lenp
)
{
const
char
*
list
,
*
end
;
int
length
;
list
=
fdt_getprop
(
fdt
,
nodeoffset
,
property
,
&
length
);
if
(
!
list
)
{
if
(
lenp
)
*
lenp
=
length
;
return
NULL
;
}
end
=
list
+
length
;
while
(
list
<
end
)
{
length
=
strnlen
(
list
,
end
-
list
)
+
1
;
/* Abort if the last string isn't properly NUL-terminated. */
if
(
list
+
length
>
end
)
{
if
(
lenp
)
*
lenp
=
-
FDT_ERR_BADVALUE
;
return
NULL
;
}
if
(
idx
==
0
)
{
if
(
lenp
)
*
lenp
=
length
-
1
;
return
list
;
}
list
+=
length
;
idx
--
;
}
if
(
lenp
)
*
lenp
=
-
FDT_ERR_NOTFOUND
;
return
NULL
;
}
int
fdt_node_check_compatible
(
const
void
*
fdt
,
int
nodeoffset
,
const
char
*
compatible
)
{
...
...
@@ -541,10 +673,8 @@ int fdt_node_check_compatible(const void *fdt, int nodeoffset,
prop
=
fdt_getprop
(
fdt
,
nodeoffset
,
"compatible"
,
&
len
);
if
(
!
prop
)
return
len
;
if
(
fdt_stringlist_contains
(
prop
,
len
,
compatible
))
return
0
;
else
return
1
;
return
!
fdt_stringlist_contains
(
prop
,
len
,
compatible
);
}
int
fdt_node_offset_by_compatible
(
const
void
*
fdt
,
int
startoffset
,
...
...
lib/libfdt/fdt_rw.c
View file @
7b94e4b9
...
...
@@ -101,6 +101,8 @@ static int _fdt_splice(void *fdt, void *splicepoint, int oldlen, int newlen)
if
(((
p
+
oldlen
)
<
p
)
||
((
p
+
oldlen
)
>
end
))
return
-
FDT_ERR_BADOFFSET
;
if
((
p
<
(
char
*
)
fdt
)
||
((
end
-
oldlen
+
newlen
)
<
(
char
*
)
fdt
))
return
-
FDT_ERR_BADOFFSET
;
if
((
end
-
oldlen
+
newlen
)
>
((
char
*
)
fdt
+
fdt_totalsize
(
fdt
)))
return
-
FDT_ERR_NOSPACE
;
memmove
(
p
+
newlen
,
p
+
oldlen
,
end
-
p
-
oldlen
);
...
...
@@ -189,17 +191,13 @@ int fdt_add_mem_rsv(void *fdt, uint64_t address, uint64_t size)
int
fdt_del_mem_rsv
(
void
*
fdt
,
int
n
)
{
struct
fdt_reserve_entry
*
re
=
_fdt_mem_rsv_w
(
fdt
,
n
);
int
err
;
FDT_RW_CHECK_HEADER
(
fdt
);
if
(
n
>=
fdt_num_mem_rsv
(
fdt
))
return
-
FDT_ERR_NOTFOUND
;
err
=
_fdt_splice_mem_rsv
(
fdt
,
re
,
1
,
0
);
if
(
err
)
return
err
;
return
0
;
return
_fdt_splice_mem_rsv
(
fdt
,
re
,
1
,
0
);
}
static
int
_fdt_resize_property
(
void
*
fdt
,
int
nodeoffset
,
const
char
*
name
,
...
...
lib/libfdt/fdt_wip.c
View file @
7b94e4b9
...
...
@@ -55,21 +55,42 @@
#include "libfdt_internal.h"
int
fdt_setprop_inplace_namelen_partial
(
void
*
fdt
,
int
nodeoffset
,
const
char
*
name
,
int
namelen
,
uint32_t
idx
,
const
void
*
val
,
int
len
)
{
void
*
propval
;
int
proplen
;
propval
=
fdt_getprop_namelen_w
(
fdt
,
nodeoffset
,
name
,
namelen
,
&
proplen
);
if
(
!
propval
)
return
proplen
;
if
(
proplen
<
(
len
+
idx
))
return
-
FDT_ERR_NOSPACE
;
memcpy
((
char
*
)
propval
+
idx
,
val
,
len
);
return
0
;
}
int
fdt_setprop_inplace
(
void
*
fdt
,
int
nodeoffset
,
const
char
*
name
,
const
void
*
val
,
int
len
)
{
void
*
propval
;
const
void
*
propval
;
int
proplen
;
propval
=
fdt_getprop
_w
(
fdt
,
nodeoffset
,
name
,
&
proplen
);
propval
=
fdt_getprop
(
fdt
,
nodeoffset
,
name
,
&
proplen
);
if
(
!
propval
)
return
proplen
;
if
(
proplen
!=
len
)
return
-
FDT_ERR_NOSPACE
;
memcpy
(
propval
,
val
,
len
);
return
0
;
return
fdt_setprop_inplace_namelen_partial
(
fdt
,
nodeoffset
,
name
,
strlen
(
name
),
0
,
val
,
len
);
}
static
void
_fdt_nop_region
(
void
*
start
,
int
len
)
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment