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
946d5f67
Commit
946d5f67
authored
Jul 08, 2020
by
Sandrine Bailleux
Committed by
TrustedFirmware Code Review
Jul 08, 2020
Browse files
Merge "Upgrade libfdt source files" into integration
parents
99c447f4
243ce5d5
Changes
14
Hide whitespace changes
Inline
Side-by-side
include/lib/libfdt/fdt.h
View file @
946d5f67
/* SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause) */
#ifndef FDT_H
#ifndef FDT_H
#define FDT_H
#define FDT_H
/*
/*
* libfdt - Flat Device Tree manipulation
* libfdt - Flat Device Tree manipulation
* Copyright (C) 2006 David Gibson, IBM Corporation.
* Copyright (C) 2006 David Gibson, IBM Corporation.
* Copyright 2012 Kim Phillips, Freescale Semiconductor.
* Copyright 2012 Kim Phillips, Freescale Semiconductor.
*
* 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.
*/
*/
#ifndef __ASSEMBLER__
#ifndef __ASSEMBLER__
...
@@ -90,7 +45,7 @@ struct fdt_property {
...
@@ -90,7 +45,7 @@ struct fdt_property {
char
data
[
0
];
char
data
[
0
];
};
};
#endif
/* !__ASSEMBLER__
*/
#endif
/* !__ASSEMBLER__*/
#define FDT_MAGIC 0xd00dfeed
/* 4: version, 4: total size */
#define FDT_MAGIC 0xd00dfeed
/* 4: version, 4: total size */
#define FDT_TAGSIZE sizeof(fdt32_t)
#define FDT_TAGSIZE sizeof(fdt32_t)
...
...
include/lib/libfdt/libfdt.h
View file @
946d5f67
/* SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause) */
#ifndef LIBFDT_H
#ifndef LIBFDT_H
#define LIBFDT_H
#define LIBFDT_H
/*
/*
* libfdt - Flat Device Tree manipulation
* libfdt - Flat Device Tree manipulation
* Copyright (C) 2006 David Gibson, IBM Corporation.
* Copyright (C) 2006 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 <libfdt_env.h>
...
@@ -90,8 +45,9 @@
...
@@ -90,8 +45,9 @@
/* Error codes: codes for bad device tree blobs */
/* Error codes: codes for bad device tree blobs */
#define FDT_ERR_TRUNCATED 8
#define FDT_ERR_TRUNCATED 8
/* FDT_ERR_TRUNCATED: Structure block of the given device tree
/* FDT_ERR_TRUNCATED: FDT or a sub-block is improperly
* ends without an FDT_END tag. */
* terminated (overflows, goes outside allowed bounds, or
* isn't properly terminated). */
#define FDT_ERR_BADMAGIC 9
#define FDT_ERR_BADMAGIC 9
/* FDT_ERR_BADMAGIC: Given "device tree" appears not to be a
/* FDT_ERR_BADMAGIC: Given "device tree" appears not to be a
* device tree at all - it is missing the flattened device
* device tree at all - it is missing the flattened device
...
@@ -137,7 +93,15 @@
...
@@ -137,7 +93,15 @@
/* FDT_ERR_NOPHANDLES: The device tree doesn't have any
/* FDT_ERR_NOPHANDLES: The device tree doesn't have any
* phandle available anymore without causing an overflow */
* phandle available anymore without causing an overflow */
#define FDT_ERR_MAX 17
#define FDT_ERR_BADFLAGS 18
/* 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
/* constants */
#define FDT_MAX_PHANDLE 0xfffffffe
/* Valid values for phandles range from 1 to 2^32-2. */
/**********************************************************************/
/**********************************************************************/
/* Low-level functions (you probably don't need these) */
/* Low-level functions (you probably don't need these) */
...
@@ -153,6 +117,61 @@ static inline void *fdt_offset_ptr_w(void *fdt, int offset, int checklen)
...
@@ -153,6 +117,61 @@ 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
);
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
*/
static
inline
uint32_t
fdt32_ld
(
const
fdt32_t
*
p
)
{
const
uint8_t
*
bp
=
(
const
uint8_t
*
)
p
;
return
((
uint32_t
)
bp
[
0
]
<<
24
)
|
((
uint32_t
)
bp
[
1
]
<<
16
)
|
((
uint32_t
)
bp
[
2
]
<<
8
)
|
bp
[
3
];
}
static
inline
void
fdt32_st
(
void
*
property
,
uint32_t
value
)
{
uint8_t
*
bp
=
(
uint8_t
*
)
property
;
bp
[
0
]
=
value
>>
24
;
bp
[
1
]
=
(
value
>>
16
)
&
0xff
;
bp
[
2
]
=
(
value
>>
8
)
&
0xff
;
bp
[
3
]
=
value
&
0xff
;
}
static
inline
uint64_t
fdt64_ld
(
const
fdt64_t
*
p
)
{
const
uint8_t
*
bp
=
(
const
uint8_t
*
)
p
;
return
((
uint64_t
)
bp
[
0
]
<<
56
)
|
((
uint64_t
)
bp
[
1
]
<<
48
)
|
((
uint64_t
)
bp
[
2
]
<<
40
)
|
((
uint64_t
)
bp
[
3
]
<<
32
)
|
((
uint64_t
)
bp
[
4
]
<<
24
)
|
((
uint64_t
)
bp
[
5
]
<<
16
)
|
((
uint64_t
)
bp
[
6
]
<<
8
)
|
bp
[
7
];
}
static
inline
void
fdt64_st
(
void
*
property
,
uint64_t
value
)
{
uint8_t
*
bp
=
(
uint8_t
*
)
property
;
bp
[
0
]
=
value
>>
56
;
bp
[
1
]
=
(
value
>>
48
)
&
0xff
;
bp
[
2
]
=
(
value
>>
40
)
&
0xff
;
bp
[
3
]
=
(
value
>>
32
)
&
0xff
;
bp
[
4
]
=
(
value
>>
24
)
&
0xff
;
bp
[
5
]
=
(
value
>>
16
)
&
0xff
;
bp
[
6
]
=
(
value
>>
8
)
&
0xff
;
bp
[
7
]
=
value
&
0xff
;
}
/**********************************************************************/
/**********************************************************************/
/* Traversal functions */
/* Traversal functions */
/**********************************************************************/
/**********************************************************************/
...
@@ -195,7 +214,7 @@ int fdt_next_subnode(const void *fdt, int offset);
...
@@ -195,7 +214,7 @@ int fdt_next_subnode(const void *fdt, int offset);
* ...
* ...
* }
* }
*
*
* if ((node < 0) && (node != -FDT_ERR_NOT
_
FOUND)) {
* if ((node < 0) && (node != -FDT_ERR_NOTFOUND)) {
* Error handling
* Error handling
* }
* }
*
*
...
@@ -213,7 +232,7 @@ int fdt_next_subnode(const void *fdt, int offset);
...
@@ -213,7 +232,7 @@ int fdt_next_subnode(const void *fdt, int offset);
/* General functions */
/* General functions */
/**********************************************************************/
/**********************************************************************/
#define fdt_get_header(fdt, field) \
#define fdt_get_header(fdt, field) \
(fdt32_
to_cpu(
((const struct fdt_header *)(fdt))->field))
(fdt32_
ld(&
((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_totalsize(fdt) (fdt_get_header(fdt, totalsize))
#define fdt_off_dt_struct(fdt) (fdt_get_header(fdt, off_dt_struct))
#define fdt_off_dt_struct(fdt) (fdt_get_header(fdt, off_dt_struct))
...
@@ -244,18 +263,32 @@ fdt_set_hdr_(size_dt_struct);
...
@@ -244,18 +263,32 @@ fdt_set_hdr_(size_dt_struct);
#undef fdt_set_hdr_
#undef fdt_set_hdr_
/**
/**
* fdt_check_header - sanity check a device tree or possible device tree
* fdt_header_size - return the size of the tree's header
* @fdt: pointer to a flattened device tree
*/
size_t
fdt_header_size
(
const
void
*
fdt
);
/**
* fdt_header_size_ - internal function which takes a version number
*/
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: pointer to data which might be a flattened device tree
*
*
* fdt_check_header() checks that the given buffer contains what
* fdt_check_header() checks that the given buffer contains what
* appears to be a flattened device tree with sane information in its
* appears to be a flattened device tree, and that the header contains
* header.
* valid information (to the extent that can be determined from the
* header alone).
*
*
* returns:
* returns:
* 0, if the buffer appears to contain a valid device tree
* 0, if the buffer appears to contain a valid device tree
* -FDT_ERR_BADMAGIC,
* -FDT_ERR_BADMAGIC,
* -FDT_ERR_BADVERSION,
* -FDT_ERR_BADVERSION,
* -FDT_ERR_BADSTATE, standard meanings, as above
* -FDT_ERR_BADSTATE,
* -FDT_ERR_TRUNCATED, standard meanings, as above
*/
*/
int
fdt_check_header
(
const
void
*
fdt
);
int
fdt_check_header
(
const
void
*
fdt
);
...
@@ -284,6 +317,24 @@ int fdt_move(const void *fdt, void *buf, int bufsize);
...
@@ -284,6 +317,24 @@ int fdt_move(const void *fdt, void *buf, int bufsize);
/* Read-only functions */
/* Read-only functions */
/**********************************************************************/
/**********************************************************************/
int
fdt_check_full
(
const
void
*
fdt
,
size_t
bufsize
);
/**
* fdt_get_string - retrieve a string from the strings block of a device tree
* @fdt: pointer to the device tree blob
* @stroffset: offset of the string within the strings block (native endian)
* @lenp: optional pointer to return the string's length
*
* fdt_get_string() retrieves a pointer to a single string from the
* strings block of the device tree blob at fdt, and optionally also
* returns the string's length in *lenp.
*
* returns:
* a pointer to the string, on success
* NULL, if stroffset is out of bounds, or doesn't point to a valid string
*/
const
char
*
fdt_get_string
(
const
void
*
fdt
,
int
stroffset
,
int
*
lenp
);
/**
/**
* fdt_string - retrieve a string from the strings block of a device tree
* fdt_string - retrieve a string from the strings block of a device tree
* @fdt: pointer to the device tree blob
* @fdt: pointer to the device tree blob
...
@@ -294,10 +345,24 @@ int fdt_move(const void *fdt, void *buf, int bufsize);
...
@@ -294,10 +345,24 @@ int fdt_move(const void *fdt, void *buf, int bufsize);
*
*
* returns:
* returns:
* a pointer to the string, on success
* a pointer to the string, on success
* NULL, if stroffset is out of bounds
* NULL, if stroffset is out of bounds
, or doesn't point to a valid string
*/
*/
const
char
*
fdt_string
(
const
void
*
fdt
,
int
stroffset
);
const
char
*
fdt_string
(
const
void
*
fdt
,
int
stroffset
);
/**
* fdt_find_max_phandle - find and return the highest phandle in a tree
* @fdt: pointer to the device tree blob
* @phandle: return location for the highest phandle value found in the tree
*
* fdt_find_max_phandle() finds the highest phandle value in the given device
* tree. The value returned in @phandle is only valid if the function returns
* success.
*
* returns:
* 0 on success or a negative error code on failure
*/
int
fdt_find_max_phandle
(
const
void
*
fdt
,
uint32_t
*
phandle
);
/**
/**
* fdt_get_max_phandle - retrieves the highest phandle in a tree
* fdt_get_max_phandle - retrieves the highest phandle in a tree
* @fdt: pointer to the device tree blob
* @fdt: pointer to the device tree blob
...
@@ -306,12 +371,39 @@ const char *fdt_string(const void *fdt, int stroffset);
...
@@ -306,12 +371,39 @@ const char *fdt_string(const void *fdt, int stroffset);
* device tree. This will ignore badly formatted phandles, or phandles
* device tree. This will ignore badly formatted phandles, or phandles
* with a value of 0 or -1.
* with a value of 0 or -1.
*
*
* This function is deprecated in favour of fdt_find_max_phandle().
*
* returns:
* returns:
* the highest phandle on success
* the highest phandle on success
* 0, if no phandle was found in the device tree
* 0, if no phandle was found in the device tree
* -1, if an error occurred
* -1, if an error occurred
*/
*/
uint32_t
fdt_get_max_phandle
(
const
void
*
fdt
);
static
inline
uint32_t
fdt_get_max_phandle
(
const
void
*
fdt
)
{
uint32_t
phandle
;
int
err
;
err
=
fdt_find_max_phandle
(
fdt
,
&
phandle
);
if
(
err
<
0
)
return
(
uint32_t
)
-
1
;
return
phandle
;
}
/**
* fdt_generate_phandle - return a new, unused phandle for a device tree blob
* @fdt: pointer to the device tree blob
* @phandle: return location for the new phandle
*
* Walks the device tree blob and looks for the highest phandle value. On
* success, the new, unused phandle value (one higher than the previously
* 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
*/
int
fdt_generate_phandle
(
const
void
*
fdt
,
uint32_t
*
phandle
);
/**
/**
* fdt_num_mem_rsv - retrieve the number of memory reserve map entries
* fdt_num_mem_rsv - retrieve the number of memory reserve map entries
...
@@ -503,7 +595,7 @@ int fdt_next_property_offset(const void *fdt, int offset);
...
@@ -503,7 +595,7 @@ int fdt_next_property_offset(const void *fdt, int offset);
* ...
* ...
* }
* }
*
*
* if ((property < 0) && (property != -FDT_ERR_NOT
_
FOUND)) {
* if ((property < 0) && (property != -FDT_ERR_NOTFOUND)) {
* Error handling
* Error handling
* }
* }
*
*
...
@@ -606,7 +698,7 @@ static inline struct fdt_property *fdt_get_property_w(void *fdt, int nodeoffset,
...
@@ -606,7 +698,7 @@ static inline struct fdt_property *fdt_get_property_w(void *fdt, int nodeoffset,
/**
/**
* fdt_getprop_by_offset - retrieve the value of a property at a given offset
* fdt_getprop_by_offset - retrieve the value of a property at a given offset
* @fdt: pointer to the device tree blob
* @fdt: pointer to the device tree blob
* @ffset: offset of the property to read
* @
o
ffset: offset of the property to read
* @namep: pointer to a string variable (will be overwritten) or NULL
* @namep: pointer to a string variable (will be overwritten) or NULL
* @lenp: pointer to an integer variable (will be overwritten) or NULL
* @lenp: pointer to an integer variable (will be overwritten) or NULL
*
*
...
@@ -1090,7 +1182,7 @@ int fdt_address_cells(const void *fdt, int nodeoffset);
...
@@ -1090,7 +1182,7 @@ int fdt_address_cells(const void *fdt, int nodeoffset);
*
*
* returns:
* returns:
* 0 <= n < FDT_MAX_NCELLS, on success
* 0 <= n < FDT_MAX_NCELLS, on success
*
2
, if the node has no #
address
-cells property
*
1
, if the node has no #
size
-cells property
* -FDT_ERR_BADNCELLS, if the node has a badly formatted or invalid
* -FDT_ERR_BADNCELLS, if the node has a badly formatted or invalid
* #size-cells property
* #size-cells property
* -FDT_ERR_BADMAGIC,
* -FDT_ERR_BADMAGIC,
...
@@ -1297,7 +1389,45 @@ int fdt_nop_node(void *fdt, int nodeoffset);
...
@@ -1297,7 +1389,45 @@ int fdt_nop_node(void *fdt, int nodeoffset);
/* Sequential write functions */
/* Sequential write functions */
/**********************************************************************/
/**********************************************************************/
/* fdt_create_with_flags flags */
#define FDT_CREATE_FLAG_NO_NAME_DEDUP 0x1
/* FDT_CREATE_FLAG_NO_NAME_DEDUP: Do not try to de-duplicate property
* names in the fdt. This can result in faster creation times, but
* a larger fdt. */
#define FDT_CREATE_FLAGS_ALL (FDT_CREATE_FLAG_NO_NAME_DEDUP)
/**
* fdt_create_with_flags - begin creation of a new fdt
* @fdt: 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.
*
* fdt_create_with_flags() begins the process of creating a new fdt with
* the sequential write interface.
*
* fdt creation process must end with fdt_finished() to produce a valid fdt.
*
* returns:
* 0, on success
* -FDT_ERR_NOSPACE, bufsize is insufficient for a minimal fdt
* -FDT_ERR_BADFLAGS, flags is not valid
*/
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
* @bufsize: size of the memory space at fdt
*
* fdt_create() is equivalent to fdt_create_with_flags() with flags=0.
*
* returns:
* 0, on success
* -FDT_ERR_NOSPACE, bufsize is insufficient for a minimal fdt
*/
int
fdt_create
(
void
*
buf
,
int
bufsize
);
int
fdt_create
(
void
*
buf
,
int
bufsize
);
int
fdt_resize
(
void
*
fdt
,
void
*
buf
,
int
bufsize
);
int
fdt_resize
(
void
*
fdt
,
void
*
buf
,
int
bufsize
);
int
fdt_add_reservemap_entry
(
void
*
fdt
,
uint64_t
addr
,
uint64_t
size
);
int
fdt_add_reservemap_entry
(
void
*
fdt
,
uint64_t
addr
,
uint64_t
size
);
int
fdt_finish_reservemap
(
void
*
fdt
);
int
fdt_finish_reservemap
(
void
*
fdt
);
...
@@ -1313,10 +1443,13 @@ static inline int fdt_property_u64(void *fdt, const char *name, uint64_t val)
...
@@ -1313,10 +1443,13 @@ static inline int fdt_property_u64(void *fdt, const char *name, uint64_t val)
fdt64_t
tmp
=
cpu_to_fdt64
(
val
);
fdt64_t
tmp
=
cpu_to_fdt64
(
val
);
return
fdt_property
(
fdt
,
name
,
&
tmp
,
sizeof
(
tmp
));
return
fdt_property
(
fdt
,
name
,
&
tmp
,
sizeof
(
tmp
));
}
}
#ifndef SWIG
/* Not available in Python */
static
inline
int
fdt_property_cell
(
void
*
fdt
,
const
char
*
name
,
uint32_t
val
)
static
inline
int
fdt_property_cell
(
void
*
fdt
,
const
char
*
name
,
uint32_t
val
)
{
{
return
fdt_property_u32
(
fdt
,
name
,
val
);
return
fdt_property_u32
(
fdt
,
name
,
val
);
}
}
#endif
/**
/**
* fdt_property_placeholder - add a new property and return a ptr to its value
* fdt_property_placeholder - add a new property and return a ptr to its value
...
@@ -1765,6 +1898,43 @@ static inline int fdt_appendprop_cell(void *fdt, int nodeoffset,
...
@@ -1765,6 +1898,43 @@ static inline int fdt_appendprop_cell(void *fdt, int nodeoffset,
#define fdt_appendprop_string(fdt, nodeoffset, name, str) \
#define fdt_appendprop_string(fdt, nodeoffset, name, str) \
fdt_appendprop((fdt), (nodeoffset), (name), (str), strlen(str)+1)
fdt_appendprop((fdt), (nodeoffset), (name), (str), strlen(str)+1)
/**
* fdt_appendprop_addrrange - append a address range property
* @fdt: pointer to the device tree blob
* @parent: offset of the parent node
* @nodeoffset: offset of the node to add a property at
* @name: name of property
* @addr: start address of a given range
* @size: size of a given range
*
* fdt_appendprop_addrrange() appends an address range value (start
* address and size) 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.
* If "name" is not specified, a default "reg" is used.
* Cell sizes are determined by parent's #address-cells and #size-cells.
*
* This function may insert data into the blob, and will therefore
* change the offsets of some existing nodes.
*
* returns:
* 0, on success
* -FDT_ERR_BADLAYOUT,
* -FDT_ERR_BADMAGIC,
* -FDT_ERR_BADNCELLS, if the node has a badly formatted or invalid
* #address-cells property
* -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
* -FDT_ERR_BADSTATE,
* -FDT_ERR_BADSTRUCTURE,
* -FDT_ERR_BADVERSION,
* -FDT_ERR_BADVALUE, addr or size doesn't fit to respective cells size
* -FDT_ERR_NOSPACE, there is insufficient free space in the blob to
* contain a new property
* -FDT_ERR_TRUNCATED, standard meanings
*/
int
fdt_appendprop_addrrange
(
void
*
fdt
,
int
parent
,
int
nodeoffset
,
const
char
*
name
,
uint64_t
addr
,
uint64_t
size
);
/**
/**
* fdt_delprop - delete a property
* fdt_delprop - delete a property
* @fdt: pointer to the device tree blob
* @fdt: pointer to the device tree blob
...
...
include/lib/libfdt/libfdt_env.h
View file @
946d5f67
/* SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause) */
#ifndef LIBFDT_ENV_H
#ifndef LIBFDT_ENV_H
#define LIBFDT_ENV_H
#define LIBFDT_ENV_H
/*
/*
* libfdt - Flat Device Tree manipulation
* libfdt - Flat Device Tree manipulation
* Copyright (C) 2006 David Gibson, IBM Corporation.
* Copyright (C) 2006 David Gibson, IBM Corporation.
* Copyright 2012 Kim Phillips, Freescale Semiconductor.
* Copyright 2012 Kim Phillips, Freescale Semiconductor.
*
* 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 <stdbool.h>
#include <stddef.h>
#include <stddef.h>
#include <stdint.h>
#include <stdint.h>
#include <stdlib.h>
#include <stdlib.h>
#include <string.h>
#include <string.h>
#include <limits.h>
#ifdef __CHECKER__
#ifdef __CHECKER__
#define FDT_FORCE __attribute__((force))
#define FDT_FORCE __attribute__((force))
...
...
lib/libfdt/fdt.c
View file @
946d5f67
// SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause)
/*
/*
* libfdt - Flat Device Tree manipulation
* libfdt - Flat Device Tree manipulation
* Copyright (C) 2006 David Gibson, IBM Corporation.
* Copyright (C) 2006 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 "libfdt_env.h"
...
@@ -55,22 +10,125 @@
...
@@ -55,22 +10,125 @@
#include "libfdt_internal.h"
#include "libfdt_internal.h"
int
fdt_check_header
(
const
void
*
fdt
)
/*
* Minimal sanity check for a read-only tree. fdt_ro_probe_() checks
* that the given buffer contains what appears to be a flattened
* device tree with sane information in its header.
*/
int32_t
fdt_ro_probe_
(
const
void
*
fdt
)
{
{
uint32_t
totalsize
=
fdt_totalsize
(
fdt
);
if
(
can_assume
(
VALID_DTB
))
return
totalsize
;
if
(
fdt_magic
(
fdt
)
==
FDT_MAGIC
)
{
if
(
fdt_magic
(
fdt
)
==
FDT_MAGIC
)
{
/* Complete tree */
/* Complete tree */
if
(
fdt_version
(
fdt
)
<
FDT_FIRST_SUPPORTED_VERSION
)
if
(
!
can_assume
(
LATEST
))
{
return
-
FDT_ERR_BADVERSION
;
if
(
fdt_version
(
fdt
)
<
FDT_FIRST_SUPPORTED_VERSION
)
if
(
fdt_last_comp_version
(
fdt
)
>
FDT_LAST_SUPPORTED_VERSION
)
return
-
FDT_ERR_BADVERSION
;
return
-
FDT_ERR_BADVERSION
;
if
(
fdt_last_comp_version
(
fdt
)
>
FDT_LAST_SUPPORTED_VERSION
)
return
-
FDT_ERR_BADVERSION
;
}
}
else
if
(
fdt_magic
(
fdt
)
==
FDT_SW_MAGIC
)
{
}
else
if
(
fdt_magic
(
fdt
)
==
FDT_SW_MAGIC
)
{
/* Unfinished sequential-write blob */
/* Unfinished sequential-write blob */
if
(
fdt_size_dt_struct
(
fdt
)
==
0
)
if
(
!
can_assume
(
VALID_INPUT
)
&&
fdt_size_dt_struct
(
fdt
)
==
0
)
return
-
FDT_ERR_BADSTATE
;
return
-
FDT_ERR_BADSTATE
;
}
else
{
}
else
{
return
-
FDT_ERR_BADMAGIC
;
return
-
FDT_ERR_BADMAGIC
;
}
}
if
(
totalsize
<
INT32_MAX
)
return
totalsize
;
else
return
-
FDT_ERR_TRUNCATED
;
}
static
int
check_off_
(
uint32_t
hdrsize
,
uint32_t
totalsize
,
uint32_t
off
)
{
return
(
off
>=
hdrsize
)
&&
(
off
<=
totalsize
);
}
static
int
check_block_
(
uint32_t
hdrsize
,
uint32_t
totalsize
,
uint32_t
base
,
uint32_t
size
)
{
if
(
!
check_off_
(
hdrsize
,
totalsize
,
base
))
return
0
;
/* block start out of bounds */
if
((
base
+
size
)
<
base
)
return
0
;
/* overflow */
if
(
!
check_off_
(
hdrsize
,
totalsize
,
base
+
size
))
return
0
;
/* block end out of bounds */
return
1
;
}
size_t
fdt_header_size_
(
uint32_t
version
)
{
if
(
version
<=
1
)
return
FDT_V1_SIZE
;
else
if
(
version
<=
2
)
return
FDT_V2_SIZE
;
else
if
(
version
<=
3
)
return
FDT_V3_SIZE
;
else
if
(
version
<=
16
)
return
FDT_V16_SIZE
;
else
return
FDT_V17_SIZE
;
}
size_t
fdt_header_size
(
const
void
*
fdt
)
{
return
can_assume
(
LATEST
)
?
FDT_V17_SIZE
:
fdt_header_size_
(
fdt_version
(
fdt
));
}
int
fdt_check_header
(
const
void
*
fdt
)
{
size_t
hdrsize
;
if
(
fdt_magic
(
fdt
)
!=
FDT_MAGIC
)
return
-
FDT_ERR_BADMAGIC
;
if
(
!
can_assume
(
LATEST
))
{
if
((
fdt_version
(
fdt
)
<
FDT_FIRST_SUPPORTED_VERSION
)
||
(
fdt_last_comp_version
(
fdt
)
>
FDT_LAST_SUPPORTED_VERSION
))
return
-
FDT_ERR_BADVERSION
;
if
(
fdt_version
(
fdt
)
<
fdt_last_comp_version
(
fdt
))
return
-
FDT_ERR_BADVERSION
;
}
hdrsize
=
fdt_header_size
(
fdt
);
if
(
!
can_assume
(
VALID_DTB
))
{
if
((
fdt_totalsize
(
fdt
)
<
hdrsize
)
||
(
fdt_totalsize
(
fdt
)
>
INT_MAX
))
return
-
FDT_ERR_TRUNCATED
;
/* Bounds check memrsv block */
if
(
!
check_off_
(
hdrsize
,
fdt_totalsize
(
fdt
),
fdt_off_mem_rsvmap
(
fdt
)))
return
-
FDT_ERR_TRUNCATED
;
}
if
(
!
can_assume
(
VALID_DTB
))
{
/* Bounds check structure block */
if
(
!
can_assume
(
LATEST
)
&&
fdt_version
(
fdt
)
<
17
)
{
if
(
!
check_off_
(
hdrsize
,
fdt_totalsize
(
fdt
),
fdt_off_dt_struct
(
fdt
)))
return
-
FDT_ERR_TRUNCATED
;
}
else
{
if
(
!
check_block_
(
hdrsize
,
fdt_totalsize
(
fdt
),
fdt_off_dt_struct
(
fdt
),
fdt_size_dt_struct
(
fdt
)))
return
-
FDT_ERR_TRUNCATED
;
}
/* Bounds check strings block */
if
(
!
check_block_
(
hdrsize
,
fdt_totalsize
(
fdt
),
fdt_off_dt_strings
(
fdt
),
fdt_size_dt_strings
(
fdt
)))
return
-
FDT_ERR_TRUNCATED
;
}
return
0
;
return
0
;
}
}
...
@@ -78,12 +136,13 @@ const void *fdt_offset_ptr(const void *fdt, int offset, unsigned int len)
...
@@ -78,12 +136,13 @@ const void *fdt_offset_ptr(const void *fdt, int offset, unsigned int len)
{
{
unsigned
absoffset
=
offset
+
fdt_off_dt_struct
(
fdt
);
unsigned
absoffset
=
offset
+
fdt_off_dt_struct
(
fdt
);
if
((
absoffset
<
offset
)
if
(
!
can_assume
(
VALID_INPUT
))
||
((
absoffset
+
len
)
<
absoffset
)
if
((
absoffset
<
offset
)
||
(
absoffset
+
len
)
>
fdt_totalsize
(
fdt
))
||
((
absoffset
+
len
)
<
absoffset
)
return
NULL
;
||
(
absoffset
+
len
)
>
fdt_totalsize
(
fdt
))
return
NULL
;
if
(
fdt_version
(
fdt
)
>=
0x11
)
if
(
can_assume
(
LATEST
)
||
fdt_version
(
fdt
)
>=
0x11
)
if
(((
offset
+
len
)
<
offset
)
if
(((
offset
+
len
)
<
offset
)
||
((
offset
+
len
)
>
fdt_size_dt_struct
(
fdt
)))
||
((
offset
+
len
)
>
fdt_size_dt_struct
(
fdt
)))
return
NULL
;
return
NULL
;
...
@@ -100,7 +159,7 @@ uint32_t fdt_next_tag(const void *fdt, int startoffset, int *nextoffset)
...
@@ -100,7 +159,7 @@ uint32_t fdt_next_tag(const void *fdt, int startoffset, int *nextoffset)
*
nextoffset
=
-
FDT_ERR_TRUNCATED
;
*
nextoffset
=
-
FDT_ERR_TRUNCATED
;
tagp
=
fdt_offset_ptr
(
fdt
,
offset
,
FDT_TAGSIZE
);
tagp
=
fdt_offset_ptr
(
fdt
,
offset
,
FDT_TAGSIZE
);
if
(
!
tagp
)
if
(
!
can_assume
(
VALID_DTB
)
&&
!
tagp
)
return
FDT_END
;
/* premature end */
return
FDT_END
;
/* premature end */
tag
=
fdt32_to_cpu
(
*
tagp
);
tag
=
fdt32_to_cpu
(
*
tagp
);
offset
+=
FDT_TAGSIZE
;
offset
+=
FDT_TAGSIZE
;
...
@@ -112,18 +171,19 @@ uint32_t fdt_next_tag(const void *fdt, int startoffset, int *nextoffset)
...
@@ -112,18 +171,19 @@ uint32_t fdt_next_tag(const void *fdt, int startoffset, int *nextoffset)
do
{
do
{
p
=
fdt_offset_ptr
(
fdt
,
offset
++
,
1
);
p
=
fdt_offset_ptr
(
fdt
,
offset
++
,
1
);
}
while
(
p
&&
(
*
p
!=
'\0'
));
}
while
(
p
&&
(
*
p
!=
'\0'
));
if
(
!
p
)
if
(
!
can_assume
(
VALID_DTB
)
&&
!
p
)
return
FDT_END
;
/* premature end */
return
FDT_END
;
/* premature end */
break
;
break
;
case
FDT_PROP
:
case
FDT_PROP
:
lenp
=
fdt_offset_ptr
(
fdt
,
offset
,
sizeof
(
*
lenp
));
lenp
=
fdt_offset_ptr
(
fdt
,
offset
,
sizeof
(
*
lenp
));
if
(
!
lenp
)
if
(
!
can_assume
(
VALID_DTB
)
&&
!
lenp
)
return
FDT_END
;
/* premature end */
return
FDT_END
;
/* premature end */
/* skip-name offset, length and value */
/* skip-name offset, length and value */
offset
+=
sizeof
(
struct
fdt_property
)
-
FDT_TAGSIZE
offset
+=
sizeof
(
struct
fdt_property
)
-
FDT_TAGSIZE
+
fdt32_to_cpu
(
*
lenp
);
+
fdt32_to_cpu
(
*
lenp
);
if
(
fdt_version
(
fdt
)
<
0x10
&&
fdt32_to_cpu
(
*
lenp
)
>=
8
&&
if
(
!
can_assume
(
LATEST
)
&&
fdt_version
(
fdt
)
<
0x10
&&
fdt32_to_cpu
(
*
lenp
)
>=
8
&&
((
offset
-
fdt32_to_cpu
(
*
lenp
))
%
8
)
!=
0
)
((
offset
-
fdt32_to_cpu
(
*
lenp
))
%
8
)
!=
0
)
offset
+=
4
;
offset
+=
4
;
break
;
break
;
...
@@ -146,6 +206,8 @@ uint32_t fdt_next_tag(const void *fdt, int startoffset, int *nextoffset)
...
@@ -146,6 +206,8 @@ uint32_t fdt_next_tag(const void *fdt, int startoffset, int *nextoffset)
int
fdt_check_node_offset_
(
const
void
*
fdt
,
int
offset
)
int
fdt_check_node_offset_
(
const
void
*
fdt
,
int
offset
)
{
{
if
(
can_assume
(
VALID_INPUT
))
return
offset
;
if
((
offset
<
0
)
||
(
offset
%
FDT_TAGSIZE
)
if
((
offset
<
0
)
||
(
offset
%
FDT_TAGSIZE
)
||
(
fdt_next_tag
(
fdt
,
offset
,
&
offset
)
!=
FDT_BEGIN_NODE
))
||
(
fdt_next_tag
(
fdt
,
offset
,
&
offset
)
!=
FDT_BEGIN_NODE
))
return
-
FDT_ERR_BADOFFSET
;
return
-
FDT_ERR_BADOFFSET
;
...
@@ -244,7 +306,7 @@ const char *fdt_find_string_(const char *strtab, int tabsize, const char *s)
...
@@ -244,7 +306,7 @@ const char *fdt_find_string_(const char *strtab, int tabsize, const char *s)
int
fdt_move
(
const
void
*
fdt
,
void
*
buf
,
int
bufsize
)
int
fdt_move
(
const
void
*
fdt
,
void
*
buf
,
int
bufsize
)
{
{
FDT_
CHECK_HEADER
(
fdt
);
FDT_
RO_PROBE
(
fdt
);
if
(
fdt_totalsize
(
fdt
)
>
bufsize
)
if
(
fdt_totalsize
(
fdt
)
>
bufsize
)
return
-
FDT_ERR_NOSPACE
;
return
-
FDT_ERR_NOSPACE
;
...
...
lib/libfdt/fdt_addresses.c
View file @
946d5f67
// SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause)
/*
/*
* libfdt - Flat Device Tree manipulation
* libfdt - Flat Device Tree manipulation
* Copyright (C) 2014 David Gibson <david@gibson.dropbear.id.au>
* Copyright (C) 2014 David Gibson <david@gibson.dropbear.id.au>
*
* Copyright (C) 2018 embedded brains GmbH
* 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 "libfdt_env.h"
...
@@ -55,42 +11,91 @@
...
@@ -55,42 +11,91 @@
#include "libfdt_internal.h"
#include "libfdt_internal.h"
int
fdt
_address
_cells
(
const
void
*
fdt
,
int
nodeoffset
)
static
int
fdt_cells
(
const
void
*
fdt
,
int
nodeoffset
,
const
char
*
name
)
{
{
const
fdt32_t
*
a
c
;
const
fdt32_t
*
c
;
int
val
;
u
int
32_t
val
;
int
len
;
int
len
;
a
c
=
fdt_getprop
(
fdt
,
nodeoffset
,
"#address-cells"
,
&
len
);
c
=
fdt_getprop
(
fdt
,
nodeoffset
,
name
,
&
len
);
if
(
!
a
c
)
if
(
!
c
)
return
2
;
return
len
;
if
(
len
!=
sizeof
(
*
a
c
))
if
(
len
!=
sizeof
(
*
c
))
return
-
FDT_ERR_BADNCELLS
;
return
-
FDT_ERR_BADNCELLS
;
val
=
fdt32_to_cpu
(
*
a
c
);
val
=
fdt32_to_cpu
(
*
c
);
if
((
val
<=
0
)
||
(
val
>
FDT_MAX_NCELLS
)
)
if
(
val
>
FDT_MAX_NCELLS
)
return
-
FDT_ERR_BADNCELLS
;
return
-
FDT_ERR_BADNCELLS
;
return
(
int
)
val
;
}
int
fdt_address_cells
(
const
void
*
fdt
,
int
nodeoffset
)
{
int
val
;
val
=
fdt_cells
(
fdt
,
nodeoffset
,
"#address-cells"
);
if
(
val
==
0
)
return
-
FDT_ERR_BADNCELLS
;
if
(
val
==
-
FDT_ERR_NOTFOUND
)
return
2
;
return
val
;
return
val
;
}
}
int
fdt_size_cells
(
const
void
*
fdt
,
int
nodeoffset
)
int
fdt_size_cells
(
const
void
*
fdt
,
int
nodeoffset
)
{
{
const
fdt32_t
*
sc
;
int
val
;
int
val
;
int
len
;
sc
=
fdt_getprop
(
fdt
,
nodeoffset
,
"#size-cells"
,
&
len
);
val
=
fdt_cells
(
fdt
,
nodeoffset
,
"#size-cells"
);
if
(
!
sc
)
if
(
val
==
-
FDT_ERR_NOTFOUND
)
return
2
;
return
1
;
return
val
;
}
/* This function assumes that [address|size]_cells is 1 or 2 */
int
fdt_appendprop_addrrange
(
void
*
fdt
,
int
parent
,
int
nodeoffset
,
const
char
*
name
,
uint64_t
addr
,
uint64_t
size
)
{
int
addr_cells
,
size_cells
,
ret
;
uint8_t
data
[
sizeof
(
fdt64_t
)
*
2
],
*
prop
;
if
(
len
!=
sizeof
(
*
sc
))
ret
=
fdt_address_cells
(
fdt
,
parent
);
if
(
ret
<
0
)
return
ret
;
addr_cells
=
ret
;
ret
=
fdt_size_cells
(
fdt
,
parent
);
if
(
ret
<
0
)
return
ret
;
size_cells
=
ret
;
/* check validity of address */
prop
=
data
;
if
(
addr_cells
==
1
)
{
if
((
addr
>
UINT32_MAX
)
||
((
UINT32_MAX
+
1
-
addr
)
<
size
))
return
-
FDT_ERR_BADVALUE
;
fdt32_st
(
prop
,
(
uint32_t
)
addr
);
}
else
if
(
addr_cells
==
2
)
{
fdt64_st
(
prop
,
addr
);
}
else
{
return
-
FDT_ERR_BADNCELLS
;
return
-
FDT_ERR_BADNCELLS
;
}
val
=
fdt32_to_cpu
(
*
sc
);
/* check validity of size */
if
((
val
<
0
)
||
(
val
>
FDT_MAX_NCELLS
))
prop
+=
addr_cells
*
sizeof
(
fdt32_t
);
if
(
size_cells
==
1
)
{
if
(
size
>
UINT32_MAX
)
return
-
FDT_ERR_BADVALUE
;
fdt32_st
(
prop
,
(
uint32_t
)
size
);
}
else
if
(
size_cells
==
2
)
{
fdt64_st
(
prop
,
size
);
}
else
{
return
-
FDT_ERR_BADNCELLS
;
return
-
FDT_ERR_BADNCELLS
;
}
return
val
;
return
fdt_appendprop
(
fdt
,
nodeoffset
,
name
,
data
,
(
addr_cells
+
size_cells
)
*
sizeof
(
fdt32_t
));
}
}
lib/libfdt/fdt_empty_tree.c
View file @
946d5f67
// SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause)
/*
/*
* libfdt - Flat Device Tree manipulation
* libfdt - Flat Device Tree manipulation
* Copyright (C) 2012 David Gibson, IBM Corporation.
* 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 "libfdt_env.h"
...
...
lib/libfdt/fdt_overlay.c
View file @
946d5f67
// SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause)
/*
/*
* libfdt - Flat Device Tree manipulation
* libfdt - Flat Device Tree manipulation
* Copyright (C) 2016 Free Electrons
* Copyright (C) 2016 Free Electrons
* Copyright (C) 2016 NextThing Co.
* Copyright (C) 2016 NextThing Co.
*
* 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 "libfdt_env.h"
...
@@ -93,11 +48,11 @@ static uint32_t overlay_get_target_phandle(const void *fdto, int fragment)
...
@@ -93,11 +48,11 @@ static uint32_t overlay_get_target_phandle(const void *fdto, int fragment)
* @pathp: pointer which receives the path of the target (or NULL)
* @pathp: pointer which receives the path of the target (or NULL)
*
*
* overlay_get_target() retrieves the target offset in the base
* overlay_get_target() retrieves the target offset in the base
* device tree of a fragment, no matter how the actual target
t
ing is
* device tree of a fragment, no matter how the actual targeting is
* done (through a phandle or a path)
* done (through a phandle or a path)
*
*
* returns:
* returns:
* the target
t
ed node offset in the base device tree
* the targeted node offset in the base device tree
* Negative error code on error
* Negative error code on error
*/
*/
static
int
overlay_get_target
(
const
void
*
fdt
,
const
void
*
fdto
,
static
int
overlay_get_target
(
const
void
*
fdt
,
const
void
*
fdto
,
...
@@ -697,7 +652,7 @@ static int get_path_len(const void *fdt, int nodeoffset)
...
@@ -697,7 +652,7 @@ static int get_path_len(const void *fdt, int nodeoffset)
int
len
=
0
,
namelen
;
int
len
=
0
,
namelen
;
const
char
*
name
;
const
char
*
name
;
FDT_
CHECK_HEADER
(
fdt
);
FDT_
RO_PROBE
(
fdt
);
for
(;;)
{
for
(;;)
{
name
=
fdt_get_name
(
fdt
,
nodeoffset
,
&
namelen
);
name
=
fdt_get_name
(
fdt
,
nodeoffset
,
&
namelen
);
...
@@ -778,26 +733,36 @@ static int overlay_symbol_update(void *fdt, void *fdto)
...
@@ -778,26 +733,36 @@ static int overlay_symbol_update(void *fdt, void *fdto)
/* keep end marker to avoid strlen() */
/* keep end marker to avoid strlen() */
e
=
path
+
path_len
;
e
=
path
+
path_len
;
/* format: /<fragment-name>/__overlay__/<relative-subnode-path> */
if
(
*
path
!=
'/'
)
if
(
*
path
!=
'/'
)
return
-
FDT_ERR_BADVALUE
;
return
-
FDT_ERR_BADVALUE
;
/* get fragment name first */
/* get fragment name first */
s
=
strchr
(
path
+
1
,
'/'
);
s
=
strchr
(
path
+
1
,
'/'
);
if
(
!
s
)
if
(
!
s
)
{
return
-
FDT_ERR_BADOVERLAY
;
/* Symbol refers to something that won't end
* up in the target tree */
continue
;
}
frag_name
=
path
+
1
;
frag_name
=
path
+
1
;
frag_name_len
=
s
-
path
-
1
;
frag_name_len
=
s
-
path
-
1
;
/* verify format; safe since "s" lies in \0 terminated prop */
/* verify format; safe since "s" lies in \0 terminated prop */
len
=
sizeof
(
"/__overlay__/"
)
-
1
;
len
=
sizeof
(
"/__overlay__/"
)
-
1
;
if
((
e
-
s
)
<
len
||
memcmp
(
s
,
"/__overlay__/"
,
len
))
if
((
e
-
s
)
>
len
&&
(
memcmp
(
s
,
"/__overlay__/"
,
len
)
==
0
))
{
return
-
FDT_ERR_BADOVERLAY
;
/* /<fragment-name>/__overlay__/<relative-subnode-path> */
rel_path
=
s
+
len
;
rel_path
=
s
+
len
;
rel_path_len
=
e
-
rel_path
-
1
;
rel_path_len
=
e
-
rel_path
;
}
else
if
((
e
-
s
)
==
len
&&
(
memcmp
(
s
,
"/__overlay__"
,
len
-
1
)
==
0
))
{
/* /<fragment-name>/__overlay__ */
rel_path
=
""
;
rel_path_len
=
0
;
}
else
{
/* Symbol refers to something that won't end
* up in the target tree */
continue
;
}
/* find the fragment index in which the symbol lies */
/* find the fragment index in which the symbol lies */
ret
=
fdt_subnode_offset_namelen
(
fdto
,
0
,
frag_name
,
ret
=
fdt_subnode_offset_namelen
(
fdto
,
0
,
frag_name
,
...
@@ -863,11 +828,15 @@ static int overlay_symbol_update(void *fdt, void *fdto)
...
@@ -863,11 +828,15 @@ static int overlay_symbol_update(void *fdt, void *fdto)
int
fdt_overlay_apply
(
void
*
fdt
,
void
*
fdto
)
int
fdt_overlay_apply
(
void
*
fdt
,
void
*
fdto
)
{
{
uint32_t
delta
=
fdt_get_max_phandle
(
fdt
)
;
uint32_t
delta
;
int
ret
;
int
ret
;
FDT_CHECK_HEADER
(
fdt
);
FDT_RO_PROBE
(
fdt
);
FDT_CHECK_HEADER
(
fdto
);
FDT_RO_PROBE
(
fdto
);
ret
=
fdt_find_max_phandle
(
fdt
,
&
delta
);
if
(
ret
)
goto
err
;
ret
=
overlay_adjust_local_phandles
(
fdto
,
delta
);
ret
=
overlay_adjust_local_phandles
(
fdto
,
delta
);
if
(
ret
)
if
(
ret
)
...
...
lib/libfdt/fdt_ro.c
View file @
946d5f67
// SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause)
/*
/*
* libfdt - Flat Device Tree manipulation
* libfdt - Flat Device Tree manipulation
* Copyright (C) 2006 David Gibson, IBM Corporation.
* Copyright (C) 2006 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 "libfdt_env.h"
...
@@ -76,60 +31,169 @@ static int fdt_nodename_eq_(const void *fdt, int offset,
...
@@ -76,60 +31,169 @@ static int fdt_nodename_eq_(const void *fdt, int offset,
return
0
;
return
0
;
}
}
const
char
*
fdt_get_string
(
const
void
*
fdt
,
int
stroffset
,
int
*
lenp
)
{
int32_t
totalsize
;
uint32_t
absoffset
;
size_t
len
;
int
err
;
const
char
*
s
,
*
n
;
if
(
can_assume
(
VALID_INPUT
))
{
s
=
(
const
char
*
)
fdt
+
fdt_off_dt_strings
(
fdt
)
+
stroffset
;
if
(
lenp
)
*
lenp
=
strlen
(
s
);
return
s
;
}
totalsize
=
fdt_ro_probe_
(
fdt
);
err
=
totalsize
;
if
(
totalsize
<
0
)
goto
fail
;
err
=
-
FDT_ERR_BADOFFSET
;
absoffset
=
stroffset
+
fdt_off_dt_strings
(
fdt
);
if
(
absoffset
>=
totalsize
)
goto
fail
;
len
=
totalsize
-
absoffset
;
if
(
fdt_magic
(
fdt
)
==
FDT_MAGIC
)
{
if
(
stroffset
<
0
)
goto
fail
;
if
(
can_assume
(
LATEST
)
||
fdt_version
(
fdt
)
>=
17
)
{
if
(
stroffset
>=
fdt_size_dt_strings
(
fdt
))
goto
fail
;
if
((
fdt_size_dt_strings
(
fdt
)
-
stroffset
)
<
len
)
len
=
fdt_size_dt_strings
(
fdt
)
-
stroffset
;
}
}
else
if
(
fdt_magic
(
fdt
)
==
FDT_SW_MAGIC
)
{
if
((
stroffset
>=
0
)
||
(
stroffset
<
-
fdt_size_dt_strings
(
fdt
)))
goto
fail
;
if
((
-
stroffset
)
<
len
)
len
=
-
stroffset
;
}
else
{
err
=
-
FDT_ERR_INTERNAL
;
goto
fail
;
}
s
=
(
const
char
*
)
fdt
+
absoffset
;
n
=
memchr
(
s
,
'\0'
,
len
);
if
(
!
n
)
{
/* missing terminating NULL */
err
=
-
FDT_ERR_TRUNCATED
;
goto
fail
;
}
if
(
lenp
)
*
lenp
=
n
-
s
;
return
s
;
fail:
if
(
lenp
)
*
lenp
=
err
;
return
NULL
;
}
const
char
*
fdt_string
(
const
void
*
fdt
,
int
stroffset
)
const
char
*
fdt_string
(
const
void
*
fdt
,
int
stroffset
)
{
{
return
(
const
char
*
)
fdt
+
fdt_off_d
t_string
s
(
fdt
)
+
stroffset
;
return
fdt_ge
t_string
(
fdt
,
stroffset
,
NULL
)
;
}
}
static
int
fdt_string_eq_
(
const
void
*
fdt
,
int
stroffset
,
static
int
fdt_string_eq_
(
const
void
*
fdt
,
int
stroffset
,
const
char
*
s
,
int
len
)
const
char
*
s
,
int
len
)
{
{
const
char
*
p
=
fdt_string
(
fdt
,
stroffset
);
int
slen
;
const
char
*
p
=
fdt_get_string
(
fdt
,
stroffset
,
&
slen
);
return
(
strlen
(
p
)
==
len
)
&&
(
memcmp
(
p
,
s
,
len
)
==
0
);
return
p
&&
(
slen
==
len
)
&&
(
memcmp
(
p
,
s
,
len
)
==
0
);
}
}
u
int
32_t
fdt_
get
_max_phandle
(
const
void
*
fdt
)
int
fdt_
find
_max_phandle
(
const
void
*
fdt
,
uint32_t
*
phandle
)
{
{
uint32_t
max
_phandle
=
0
;
uint32_t
max
=
0
;
int
offset
;
int
offset
=
-
1
;
for
(
offset
=
fdt_next_node
(
fdt
,
-
1
,
NULL
);;
while
(
true
)
{
offset
=
fdt_next_node
(
fdt
,
offset
,
NULL
))
{
uint32_t
value
;
uint32_t
phandle
;
if
(
offset
==
-
FDT_ERR_NOTFOUND
)
offset
=
fdt_next_node
(
fdt
,
offset
,
NULL
);
return
max_phandle
;
if
(
offset
<
0
)
{
if
(
offset
==
-
FDT_ERR_NOTFOUND
)
break
;
if
(
offset
<
0
)
return
offset
;
return
(
uint32_t
)
-
1
;
}
phandle
=
fdt_get_phandle
(
fdt
,
offset
);
value
=
fdt_get_phandle
(
fdt
,
offset
);
if
(
phandle
==
(
uint32_t
)
-
1
)
continue
;
if
(
phandl
e
>
max
_phandle
)
if
(
valu
e
>
max
)
max
_phandle
=
phandl
e
;
max
=
valu
e
;
}
}
if
(
phandle
)
*
phandle
=
max
;
return
0
;
return
0
;
}
}
int
fdt_generate_phandle
(
const
void
*
fdt
,
uint32_t
*
phandle
)
{
uint32_t
max
;
int
err
;
err
=
fdt_find_max_phandle
(
fdt
,
&
max
);
if
(
err
<
0
)
return
err
;
if
(
max
==
FDT_MAX_PHANDLE
)
return
-
FDT_ERR_NOPHANDLES
;
if
(
phandle
)
*
phandle
=
max
+
1
;
return
0
;
}
static
const
struct
fdt_reserve_entry
*
fdt_mem_rsv
(
const
void
*
fdt
,
int
n
)
{
int
offset
=
n
*
sizeof
(
struct
fdt_reserve_entry
);
int
absoffset
=
fdt_off_mem_rsvmap
(
fdt
)
+
offset
;
if
(
!
can_assume
(
VALID_INPUT
))
{
if
(
absoffset
<
fdt_off_mem_rsvmap
(
fdt
))
return
NULL
;
if
(
absoffset
>
fdt_totalsize
(
fdt
)
-
sizeof
(
struct
fdt_reserve_entry
))
return
NULL
;
}
return
fdt_mem_rsv_
(
fdt
,
n
);
}
int
fdt_get_mem_rsv
(
const
void
*
fdt
,
int
n
,
uint64_t
*
address
,
uint64_t
*
size
)
int
fdt_get_mem_rsv
(
const
void
*
fdt
,
int
n
,
uint64_t
*
address
,
uint64_t
*
size
)
{
{
FDT_CHECK_HEADER
(
fdt
);
const
struct
fdt_reserve_entry
*
re
;
*
address
=
fdt64_to_cpu
(
fdt_mem_rsv_
(
fdt
,
n
)
->
address
);
*
size
=
fdt64_to_cpu
(
fdt_mem_rsv_
(
fdt
,
n
)
->
size
);
FDT_RO_PROBE
(
fdt
);
re
=
fdt_mem_rsv
(
fdt
,
n
);
if
(
!
can_assume
(
VALID_INPUT
)
&&
!
re
)
return
-
FDT_ERR_BADOFFSET
;
*
address
=
fdt64_ld
(
&
re
->
address
);
*
size
=
fdt64_ld
(
&
re
->
size
);
return
0
;
return
0
;
}
}
int
fdt_num_mem_rsv
(
const
void
*
fdt
)
int
fdt_num_mem_rsv
(
const
void
*
fdt
)
{
{
int
i
=
0
;
int
i
;
const
struct
fdt_reserve_entry
*
re
;
while
(
fdt64_to_cpu
(
fdt_mem_rsv_
(
fdt
,
i
)
->
size
)
!=
0
)
for
(
i
=
0
;
(
re
=
fdt_mem_rsv
(
fdt
,
i
))
!=
NULL
;
i
++
)
{
i
++
;
if
(
fdt64_ld
(
&
re
->
size
)
==
0
)
return
i
;
return
i
;
}
return
-
FDT_ERR_TRUNCATED
;
}
}
static
int
nextprop_
(
const
void
*
fdt
,
int
offset
)
static
int
nextprop_
(
const
void
*
fdt
,
int
offset
)
...
@@ -161,7 +225,7 @@ int fdt_subnode_offset_namelen(const void *fdt, int offset,
...
@@ -161,7 +225,7 @@ int fdt_subnode_offset_namelen(const void *fdt, int offset,
{
{
int
depth
;
int
depth
;
FDT_
CHECK_HEADER
(
fdt
);
FDT_
RO_PROBE
(
fdt
);
for
(
depth
=
0
;
for
(
depth
=
0
;
(
offset
>=
0
)
&&
(
depth
>=
0
);
(
offset
>=
0
)
&&
(
depth
>=
0
);
...
@@ -187,7 +251,7 @@ int fdt_path_offset_namelen(const void *fdt, const char *path, int namelen)
...
@@ -187,7 +251,7 @@ int fdt_path_offset_namelen(const void *fdt, const char *path, int namelen)
const
char
*
p
=
path
;
const
char
*
p
=
path
;
int
offset
=
0
;
int
offset
=
0
;
FDT_
CHECK_HEADER
(
fdt
);
FDT_
RO_PROBE
(
fdt
);
/* see if we have an alias */
/* see if we have an alias */
if
(
*
path
!=
'/'
)
{
if
(
*
path
!=
'/'
)
{
...
@@ -237,13 +301,13 @@ const char *fdt_get_name(const void *fdt, int nodeoffset, int *len)
...
@@ -237,13 +301,13 @@ const char *fdt_get_name(const void *fdt, int nodeoffset, int *len)
const
char
*
nameptr
;
const
char
*
nameptr
;
int
err
;
int
err
;
if
(((
err
=
fdt_
check_header
(
fdt
))
!=
0
)
if
(((
err
=
fdt_
ro_probe_
(
fdt
))
<
0
)
||
((
err
=
fdt_check_node_offset_
(
fdt
,
nodeoffset
))
<
0
))
||
((
err
=
fdt_check_node_offset_
(
fdt
,
nodeoffset
))
<
0
))
goto
fail
;
goto
fail
;
nameptr
=
nh
->
name
;
nameptr
=
nh
->
name
;
if
(
fdt_version
(
fdt
)
<
0x10
)
{
if
(
!
can_assume
(
LATEST
)
&&
fdt_version
(
fdt
)
<
0x10
)
{
/*
/*
* For old FDT versions, match the naming conventions of V16:
* For old FDT versions, match the naming conventions of V16:
* give only the leaf name (after all /). The actual tree
* give only the leaf name (after all /). The actual tree
...
@@ -294,7 +358,8 @@ static const struct fdt_property *fdt_get_property_by_offset_(const void *fdt,
...
@@ -294,7 +358,8 @@ static const struct fdt_property *fdt_get_property_by_offset_(const void *fdt,
int
err
;
int
err
;
const
struct
fdt_property
*
prop
;
const
struct
fdt_property
*
prop
;
if
((
err
=
fdt_check_prop_offset_
(
fdt
,
offset
))
<
0
)
{
if
(
!
can_assume
(
VALID_INPUT
)
&&
(
err
=
fdt_check_prop_offset_
(
fdt
,
offset
))
<
0
)
{
if
(
lenp
)
if
(
lenp
)
*
lenp
=
err
;
*
lenp
=
err
;
return
NULL
;
return
NULL
;
...
@@ -303,7 +368,7 @@ static const struct fdt_property *fdt_get_property_by_offset_(const void *fdt,
...
@@ -303,7 +368,7 @@ static const struct fdt_property *fdt_get_property_by_offset_(const void *fdt,
prop
=
fdt_offset_ptr_
(
fdt
,
offset
);
prop
=
fdt_offset_ptr_
(
fdt
,
offset
);
if
(
lenp
)
if
(
lenp
)
*
lenp
=
fdt32_
to_cpu
(
prop
->
len
);
*
lenp
=
fdt32_
ld
(
&
prop
->
len
);
return
prop
;
return
prop
;
}
}
...
@@ -315,7 +380,7 @@ const struct fdt_property *fdt_get_property_by_offset(const void *fdt,
...
@@ -315,7 +380,7 @@ const struct fdt_property *fdt_get_property_by_offset(const void *fdt,
/* Prior to version 16, properties may need realignment
/* Prior to version 16, properties may need realignment
* and this API does not work. fdt_getprop_*() will, however. */
* and this API does not work. fdt_getprop_*() will, however. */
if
(
fdt_version
(
fdt
)
<
0x10
)
{
if
(
!
can_assume
(
LATEST
)
&&
fdt_version
(
fdt
)
<
0x10
)
{
if
(
lenp
)
if
(
lenp
)
*
lenp
=
-
FDT_ERR_BADVERSION
;
*
lenp
=
-
FDT_ERR_BADVERSION
;
return
NULL
;
return
NULL
;
...
@@ -336,11 +401,12 @@ static const struct fdt_property *fdt_get_property_namelen_(const void *fdt,
...
@@ -336,11 +401,12 @@ static const struct fdt_property *fdt_get_property_namelen_(const void *fdt,
(
offset
=
fdt_next_property_offset
(
fdt
,
offset
)))
{
(
offset
=
fdt_next_property_offset
(
fdt
,
offset
)))
{
const
struct
fdt_property
*
prop
;
const
struct
fdt_property
*
prop
;
if
(
!
(
prop
=
fdt_get_property_by_offset_
(
fdt
,
offset
,
lenp
)))
{
prop
=
fdt_get_property_by_offset_
(
fdt
,
offset
,
lenp
);
if
(
!
can_assume
(
LIBFDT_FLAWLESS
)
&&
!
prop
)
{
offset
=
-
FDT_ERR_INTERNAL
;
offset
=
-
FDT_ERR_INTERNAL
;
break
;
break
;
}
}
if
(
fdt_string_eq_
(
fdt
,
fdt32_
to_cpu
(
prop
->
nameoff
),
if
(
fdt_string_eq_
(
fdt
,
fdt32_
ld
(
&
prop
->
nameoff
),
name
,
namelen
))
{
name
,
namelen
))
{
if
(
poffset
)
if
(
poffset
)
*
poffset
=
offset
;
*
poffset
=
offset
;
...
@@ -361,7 +427,7 @@ const struct fdt_property *fdt_get_property_namelen(const void *fdt,
...
@@ -361,7 +427,7 @@ const struct fdt_property *fdt_get_property_namelen(const void *fdt,
{
{
/* Prior to version 16, properties may need realignment
/* Prior to version 16, properties may need realignment
* and this API does not work. fdt_getprop_*() will, however. */
* and this API does not work. fdt_getprop_*() will, however. */
if
(
fdt_version
(
fdt
)
<
0x10
)
{
if
(
!
can_assume
(
LATEST
)
&&
fdt_version
(
fdt
)
<
0x10
)
{
if
(
lenp
)
if
(
lenp
)
*
lenp
=
-
FDT_ERR_BADVERSION
;
*
lenp
=
-
FDT_ERR_BADVERSION
;
return
NULL
;
return
NULL
;
...
@@ -392,8 +458,8 @@ const void *fdt_getprop_namelen(const void *fdt, int nodeoffset,
...
@@ -392,8 +458,8 @@ const void *fdt_getprop_namelen(const void *fdt, int nodeoffset,
return
NULL
;
return
NULL
;
/* Handle realignment */
/* Handle realignment */
if
(
fdt_version
(
fdt
)
<
0x10
&&
(
poffset
+
sizeof
(
*
prop
))
%
8
&&
if
(
!
can_assume
(
LATEST
)
&&
fdt_version
(
fdt
)
<
0x10
&&
fdt32_to_cpu
(
prop
->
len
)
>=
8
)
(
poffset
+
sizeof
(
*
prop
))
%
8
&&
fdt32_ld
(
&
prop
->
len
)
>=
8
)
return
prop
->
data
+
4
;
return
prop
->
data
+
4
;
return
prop
->
data
;
return
prop
->
data
;
}
}
...
@@ -406,12 +472,27 @@ const void *fdt_getprop_by_offset(const void *fdt, int offset,
...
@@ -406,12 +472,27 @@ const void *fdt_getprop_by_offset(const void *fdt, int offset,
prop
=
fdt_get_property_by_offset_
(
fdt
,
offset
,
lenp
);
prop
=
fdt_get_property_by_offset_
(
fdt
,
offset
,
lenp
);
if
(
!
prop
)
if
(
!
prop
)
return
NULL
;
return
NULL
;
if
(
namep
)
if
(
namep
)
{
*
namep
=
fdt_string
(
fdt
,
fdt32_to_cpu
(
prop
->
nameoff
));
const
char
*
name
;
int
namelen
;
if
(
!
can_assume
(
VALID_INPUT
))
{
name
=
fdt_get_string
(
fdt
,
fdt32_ld
(
&
prop
->
nameoff
),
&
namelen
);
if
(
!
name
)
{
if
(
lenp
)
*
lenp
=
namelen
;
return
NULL
;
}
*
namep
=
name
;
}
else
{
*
namep
=
fdt_string
(
fdt
,
fdt32_ld
(
&
prop
->
nameoff
));
}
}
/* Handle realignment */
/* Handle realignment */
if
(
fdt_version
(
fdt
)
<
0x10
&&
(
offset
+
sizeof
(
*
prop
))
%
8
&&
if
(
!
can_assume
(
LATEST
)
&&
fdt_version
(
fdt
)
<
0x10
&&
fdt32_to_cpu
(
prop
->
len
)
>=
8
)
(
offset
+
sizeof
(
*
prop
))
%
8
&&
fdt32_ld
(
&
prop
->
len
)
>=
8
)
return
prop
->
data
+
4
;
return
prop
->
data
+
4
;
return
prop
->
data
;
return
prop
->
data
;
}
}
...
@@ -436,7 +517,7 @@ uint32_t fdt_get_phandle(const void *fdt, int nodeoffset)
...
@@ -436,7 +517,7 @@ uint32_t fdt_get_phandle(const void *fdt, int nodeoffset)
return
0
;
return
0
;
}
}
return
fdt32_
to_cpu
(
*
php
);
return
fdt32_
ld
(
php
);
}
}
const
char
*
fdt_get_alias_namelen
(
const
void
*
fdt
,
const
char
*
fdt_get_alias_namelen
(
const
void
*
fdt
,
...
@@ -462,7 +543,7 @@ int fdt_get_path(const void *fdt, int nodeoffset, char *buf, int buflen)
...
@@ -462,7 +543,7 @@ int fdt_get_path(const void *fdt, int nodeoffset, char *buf, int buflen)
int
offset
,
depth
,
namelen
;
int
offset
,
depth
,
namelen
;
const
char
*
name
;
const
char
*
name
;
FDT_
CHECK_HEADER
(
fdt
);
FDT_
RO_PROBE
(
fdt
);
if
(
buflen
<
2
)
if
(
buflen
<
2
)
return
-
FDT_ERR_NOSPACE
;
return
-
FDT_ERR_NOSPACE
;
...
@@ -514,7 +595,7 @@ int fdt_supernode_atdepth_offset(const void *fdt, int nodeoffset,
...
@@ -514,7 +595,7 @@ int fdt_supernode_atdepth_offset(const void *fdt, int nodeoffset,
int
offset
,
depth
;
int
offset
,
depth
;
int
supernodeoffset
=
-
FDT_ERR_INTERNAL
;
int
supernodeoffset
=
-
FDT_ERR_INTERNAL
;
FDT_
CHECK_HEADER
(
fdt
);
FDT_
RO_PROBE
(
fdt
);
if
(
supernodedepth
<
0
)
if
(
supernodedepth
<
0
)
return
-
FDT_ERR_NOTFOUND
;
return
-
FDT_ERR_NOTFOUND
;
...
@@ -536,10 +617,12 @@ int fdt_supernode_atdepth_offset(const void *fdt, int nodeoffset,
...
@@ -536,10 +617,12 @@ int fdt_supernode_atdepth_offset(const void *fdt, int nodeoffset,
}
}
}
}
if
((
offset
==
-
FDT_ERR_NOTFOUND
)
||
(
offset
>=
0
))
if
(
!
can_assume
(
VALID_INPUT
))
{
return
-
FDT_ERR_BADOFFSET
;
if
((
offset
==
-
FDT_ERR_NOTFOUND
)
||
(
offset
>=
0
))
else
if
(
offset
==
-
FDT_ERR_BADOFFSET
)
return
-
FDT_ERR_BADOFFSET
;
return
-
FDT_ERR_BADSTRUCTURE
;
else
if
(
offset
==
-
FDT_ERR_BADOFFSET
)
return
-
FDT_ERR_BADSTRUCTURE
;
}
return
offset
;
/* error from fdt_next_node() */
return
offset
;
/* error from fdt_next_node() */
}
}
...
@@ -551,7 +634,8 @@ int fdt_node_depth(const void *fdt, int nodeoffset)
...
@@ -551,7 +634,8 @@ int fdt_node_depth(const void *fdt, int nodeoffset)
err
=
fdt_supernode_atdepth_offset
(
fdt
,
nodeoffset
,
0
,
&
nodedepth
);
err
=
fdt_supernode_atdepth_offset
(
fdt
,
nodeoffset
,
0
,
&
nodedepth
);
if
(
err
)
if
(
err
)
return
(
err
<
0
)
?
err
:
-
FDT_ERR_INTERNAL
;
return
(
can_assume
(
LIBFDT_FLAWLESS
)
||
err
<
0
)
?
err
:
-
FDT_ERR_INTERNAL
;
return
nodedepth
;
return
nodedepth
;
}
}
...
@@ -573,7 +657,7 @@ int fdt_node_offset_by_prop_value(const void *fdt, int startoffset,
...
@@ -573,7 +657,7 @@ int fdt_node_offset_by_prop_value(const void *fdt, int startoffset,
const
void
*
val
;
const
void
*
val
;
int
len
;
int
len
;
FDT_
CHECK_HEADER
(
fdt
);
FDT_
RO_PROBE
(
fdt
);
/* FIXME: The algorithm here is pretty horrible: we scan each
/* FIXME: The algorithm here is pretty horrible: we scan each
* property of a node in fdt_getprop(), then if that didn't
* property of a node in fdt_getprop(), then if that didn't
...
@@ -599,7 +683,7 @@ int fdt_node_offset_by_phandle(const void *fdt, uint32_t phandle)
...
@@ -599,7 +683,7 @@ int fdt_node_offset_by_phandle(const void *fdt, uint32_t phandle)
if
((
phandle
==
0
)
||
(
phandle
==
-
1
))
if
((
phandle
==
0
)
||
(
phandle
==
-
1
))
return
-
FDT_ERR_BADPHANDLE
;
return
-
FDT_ERR_BADPHANDLE
;
FDT_
CHECK_HEADER
(
fdt
);
FDT_
RO_PROBE
(
fdt
);
/* FIXME: The algorithm here is pretty horrible: we
/* FIXME: The algorithm here is pretty horrible: we
* potentially scan each property of a node in
* potentially scan each property of a node in
...
@@ -752,7 +836,7 @@ int fdt_node_offset_by_compatible(const void *fdt, int startoffset,
...
@@ -752,7 +836,7 @@ int fdt_node_offset_by_compatible(const void *fdt, int startoffset,
{
{
int
offset
,
err
;
int
offset
,
err
;
FDT_
CHECK_HEADER
(
fdt
);
FDT_
RO_PROBE
(
fdt
);
/* FIXME: The algorithm here is pretty horrible: we scan each
/* FIXME: The algorithm here is pretty horrible: we scan each
* property of a node in fdt_node_check_compatible(), then if
* property of a node in fdt_node_check_compatible(), then if
...
...
lib/libfdt/fdt_rw.c
View file @
946d5f67
// SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause)
/*
/*
* libfdt - Flat Device Tree manipulation
* libfdt - Flat Device Tree manipulation
* Copyright (C) 2006 David Gibson, IBM Corporation.
* Copyright (C) 2006 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 "libfdt_env.h"
...
@@ -67,29 +22,31 @@ static int fdt_blocks_misordered_(const void *fdt,
...
@@ -67,29 +22,31 @@ static int fdt_blocks_misordered_(const void *fdt,
(
fdt_off_dt_strings
(
fdt
)
+
fdt_size_dt_strings
(
fdt
)));
(
fdt_off_dt_strings
(
fdt
)
+
fdt_size_dt_strings
(
fdt
)));
}
}
static
int
fdt_rw_
check_header
_
(
void
*
fdt
)
static
int
fdt_rw_
probe
_
(
void
*
fdt
)
{
{
FDT_CHECK_HEADER
(
fdt
);
if
(
can_assume
(
VALID_DTB
))
return
0
;
FDT_RO_PROBE
(
fdt
);
if
(
fdt_version
(
fdt
)
<
17
)
if
(
!
can_assume
(
LATEST
)
&&
fdt_version
(
fdt
)
<
17
)
return
-
FDT_ERR_BADVERSION
;
return
-
FDT_ERR_BADVERSION
;
if
(
fdt_blocks_misordered_
(
fdt
,
sizeof
(
struct
fdt_reserve_entry
),
if
(
fdt_blocks_misordered_
(
fdt
,
sizeof
(
struct
fdt_reserve_entry
),
fdt_size_dt_struct
(
fdt
)))
fdt_size_dt_struct
(
fdt
)))
return
-
FDT_ERR_BADLAYOUT
;
return
-
FDT_ERR_BADLAYOUT
;
if
(
fdt_version
(
fdt
)
>
17
)
if
(
!
can_assume
(
LATEST
)
&&
fdt_version
(
fdt
)
>
17
)
fdt_set_version
(
fdt
,
17
);
fdt_set_version
(
fdt
,
17
);
return
0
;
return
0
;
}
}
#define FDT_RW_
CHECK_HEADER
(fdt) \
#define FDT_RW_
PROBE
(fdt) \
{ \
{ \
int err_; \
int err_; \
if ((err_ = fdt_rw_
check_header
_(fdt)) != 0) \
if ((err_ = fdt_rw_
probe
_(fdt)) != 0) \
return err_; \
return err_; \
}
}
static
inline
int
fdt_data_size_
(
void
*
fdt
)
static
inline
unsigned
int
fdt_data_size_
(
void
*
fdt
)
{
{
return
fdt_off_dt_strings
(
fdt
)
+
fdt_size_dt_strings
(
fdt
);
return
fdt_off_dt_strings
(
fdt
)
+
fdt_size_dt_strings
(
fdt
);
}
}
...
@@ -97,15 +54,16 @@ static inline int fdt_data_size_(void *fdt)
...
@@ -97,15 +54,16 @@ static inline int fdt_data_size_(void *fdt)
static
int
fdt_splice_
(
void
*
fdt
,
void
*
splicepoint
,
int
oldlen
,
int
newlen
)
static
int
fdt_splice_
(
void
*
fdt
,
void
*
splicepoint
,
int
oldlen
,
int
newlen
)
{
{
char
*
p
=
splicepoint
;
char
*
p
=
splicepoint
;
char
*
end
=
(
char
*
)
fdt
+
fdt_data_size_
(
fdt
);
unsigned
int
dsize
=
fdt_data_size_
(
fdt
);
size_t
soff
=
p
-
(
char
*
)
fdt
;
if
((
(
p
+
oldlen
)
<
p
)
||
(
(
p
+
oldlen
)
>
end
))
if
((
oldlen
<
0
)
||
(
soff
+
oldlen
<
soff
)
||
(
soff
+
oldlen
>
dsize
))
return
-
FDT_ERR_BADOFFSET
;
return
-
FDT_ERR_BADOFFSET
;
if
((
p
<
(
char
*
)
fdt
)
||
(
(
end
-
oldlen
+
newlen
)
<
(
char
*
)
fdt
))
if
((
p
<
(
char
*
)
fdt
)
||
(
dsize
+
newlen
<
oldlen
))
return
-
FDT_ERR_BADOFFSET
;
return
-
FDT_ERR_BADOFFSET
;
if
(
(
end
-
oldlen
+
newlen
)
>
((
char
*
)
fdt
+
fdt_totalsize
(
fdt
))
)
if
(
dsize
-
oldlen
+
newlen
>
fdt_totalsize
(
fdt
))
return
-
FDT_ERR_NOSPACE
;
return
-
FDT_ERR_NOSPACE
;
memmove
(
p
+
newlen
,
p
+
oldlen
,
end
-
p
-
oldlen
);
memmove
(
p
+
newlen
,
p
+
oldlen
,
((
char
*
)
fdt
+
dsize
)
-
(
p
+
oldlen
)
)
;
return
0
;
return
0
;
}
}
...
@@ -136,6 +94,14 @@ static int fdt_splice_struct_(void *fdt, void *p,
...
@@ -136,6 +94,14 @@ static int fdt_splice_struct_(void *fdt, void *p,
return
0
;
return
0
;
}
}
/* Must only be used to roll back in case of error */
static
void
fdt_del_last_string_
(
void
*
fdt
,
const
char
*
s
)
{
int
newlen
=
strlen
(
s
)
+
1
;
fdt_set_size_dt_strings
(
fdt
,
fdt_size_dt_strings
(
fdt
)
-
newlen
);
}
static
int
fdt_splice_string_
(
void
*
fdt
,
int
newlen
)
static
int
fdt_splice_string_
(
void
*
fdt
,
int
newlen
)
{
{
void
*
p
=
(
char
*
)
fdt
void
*
p
=
(
char
*
)
fdt
...
@@ -149,7 +115,16 @@ static int fdt_splice_string_(void *fdt, int newlen)
...
@@ -149,7 +115,16 @@ static int fdt_splice_string_(void *fdt, int newlen)
return
0
;
return
0
;
}
}
static
int
fdt_find_add_string_
(
void
*
fdt
,
const
char
*
s
)
/**
* fdt_find_add_string_() - Find or allocate a string
*
* @fdt: pointer to the device tree to check/adjust
* @s: string to find/add
* @allocated: Set to 0 if the string was found, 1 if not found and so
* allocated. Ignored if can_assume(NO_ROLLBACK)
* @return offset of string in the string table (whether found or added)
*/
static
int
fdt_find_add_string_
(
void
*
fdt
,
const
char
*
s
,
int
*
allocated
)
{
{
char
*
strtab
=
(
char
*
)
fdt
+
fdt_off_dt_strings
(
fdt
);
char
*
strtab
=
(
char
*
)
fdt
+
fdt_off_dt_strings
(
fdt
);
const
char
*
p
;
const
char
*
p
;
...
@@ -157,6 +132,9 @@ static int fdt_find_add_string_(void *fdt, const char *s)
...
@@ -157,6 +132,9 @@ static int fdt_find_add_string_(void *fdt, const char *s)
int
len
=
strlen
(
s
)
+
1
;
int
len
=
strlen
(
s
)
+
1
;
int
err
;
int
err
;
if
(
!
can_assume
(
NO_ROLLBACK
))
*
allocated
=
0
;
p
=
fdt_find_string_
(
strtab
,
fdt_size_dt_strings
(
fdt
),
s
);
p
=
fdt_find_string_
(
strtab
,
fdt_size_dt_strings
(
fdt
),
s
);
if
(
p
)
if
(
p
)
/* found it */
/* found it */
...
@@ -167,6 +145,9 @@ static int fdt_find_add_string_(void *fdt, const char *s)
...
@@ -167,6 +145,9 @@ static int fdt_find_add_string_(void *fdt, const char *s)
if
(
err
)
if
(
err
)
return
err
;
return
err
;
if
(
!
can_assume
(
NO_ROLLBACK
))
*
allocated
=
1
;
memcpy
(
new
,
s
,
len
);
memcpy
(
new
,
s
,
len
);
return
(
new
-
strtab
);
return
(
new
-
strtab
);
}
}
...
@@ -176,7 +157,7 @@ int fdt_add_mem_rsv(void *fdt, uint64_t address, uint64_t size)
...
@@ -176,7 +157,7 @@ int fdt_add_mem_rsv(void *fdt, uint64_t address, uint64_t size)
struct
fdt_reserve_entry
*
re
;
struct
fdt_reserve_entry
*
re
;
int
err
;
int
err
;
FDT_RW_
CHECK_HEADER
(
fdt
);
FDT_RW_
PROBE
(
fdt
);
re
=
fdt_mem_rsv_w_
(
fdt
,
fdt_num_mem_rsv
(
fdt
));
re
=
fdt_mem_rsv_w_
(
fdt
,
fdt_num_mem_rsv
(
fdt
));
err
=
fdt_splice_mem_rsv_
(
fdt
,
re
,
0
,
1
);
err
=
fdt_splice_mem_rsv_
(
fdt
,
re
,
0
,
1
);
...
@@ -192,7 +173,7 @@ int fdt_del_mem_rsv(void *fdt, int n)
...
@@ -192,7 +173,7 @@ int fdt_del_mem_rsv(void *fdt, int n)
{
{
struct
fdt_reserve_entry
*
re
=
fdt_mem_rsv_w_
(
fdt
,
n
);
struct
fdt_reserve_entry
*
re
=
fdt_mem_rsv_w_
(
fdt
,
n
);
FDT_RW_
CHECK_HEADER
(
fdt
);
FDT_RW_
PROBE
(
fdt
);
if
(
n
>=
fdt_num_mem_rsv
(
fdt
))
if
(
n
>=
fdt_num_mem_rsv
(
fdt
))
return
-
FDT_ERR_NOTFOUND
;
return
-
FDT_ERR_NOTFOUND
;
...
@@ -225,11 +206,12 @@ static int fdt_add_property_(void *fdt, int nodeoffset, const char *name,
...
@@ -225,11 +206,12 @@ static int fdt_add_property_(void *fdt, int nodeoffset, const char *name,
int
nextoffset
;
int
nextoffset
;
int
namestroff
;
int
namestroff
;
int
err
;
int
err
;
int
allocated
;
if
((
nextoffset
=
fdt_check_node_offset_
(
fdt
,
nodeoffset
))
<
0
)
if
((
nextoffset
=
fdt_check_node_offset_
(
fdt
,
nodeoffset
))
<
0
)
return
nextoffset
;
return
nextoffset
;
namestroff
=
fdt_find_add_string_
(
fdt
,
name
);
namestroff
=
fdt_find_add_string_
(
fdt
,
name
,
&
allocated
);
if
(
namestroff
<
0
)
if
(
namestroff
<
0
)
return
namestroff
;
return
namestroff
;
...
@@ -237,8 +219,12 @@ static int fdt_add_property_(void *fdt, int nodeoffset, const char *name,
...
@@ -237,8 +219,12 @@ static int fdt_add_property_(void *fdt, int nodeoffset, const char *name,
proplen
=
sizeof
(
**
prop
)
+
FDT_TAGALIGN
(
len
);
proplen
=
sizeof
(
**
prop
)
+
FDT_TAGALIGN
(
len
);
err
=
fdt_splice_struct_
(
fdt
,
*
prop
,
0
,
proplen
);
err
=
fdt_splice_struct_
(
fdt
,
*
prop
,
0
,
proplen
);
if
(
err
)
if
(
err
)
{
/* Delete the string if we failed to add it */
if
(
!
can_assume
(
NO_ROLLBACK
)
&&
allocated
)
fdt_del_last_string_
(
fdt
,
name
);
return
err
;
return
err
;
}
(
*
prop
)
->
tag
=
cpu_to_fdt32
(
FDT_PROP
);
(
*
prop
)
->
tag
=
cpu_to_fdt32
(
FDT_PROP
);
(
*
prop
)
->
nameoff
=
cpu_to_fdt32
(
namestroff
);
(
*
prop
)
->
nameoff
=
cpu_to_fdt32
(
namestroff
);
...
@@ -252,7 +238,7 @@ int fdt_set_name(void *fdt, int nodeoffset, const char *name)
...
@@ -252,7 +238,7 @@ int fdt_set_name(void *fdt, int nodeoffset, const char *name)
int
oldlen
,
newlen
;
int
oldlen
,
newlen
;
int
err
;
int
err
;
FDT_RW_
CHECK_HEADER
(
fdt
);
FDT_RW_
PROBE
(
fdt
);
namep
=
(
char
*
)(
uintptr_t
)
fdt_get_name
(
fdt
,
nodeoffset
,
&
oldlen
);
namep
=
(
char
*
)(
uintptr_t
)
fdt_get_name
(
fdt
,
nodeoffset
,
&
oldlen
);
if
(
!
namep
)
if
(
!
namep
)
...
@@ -275,7 +261,7 @@ int fdt_setprop_placeholder(void *fdt, int nodeoffset, const char *name,
...
@@ -275,7 +261,7 @@ int fdt_setprop_placeholder(void *fdt, int nodeoffset, const char *name,
struct
fdt_property
*
prop
;
struct
fdt_property
*
prop
;
int
err
;
int
err
;
FDT_RW_
CHECK_HEADER
(
fdt
);
FDT_RW_
PROBE
(
fdt
);
err
=
fdt_resize_property_
(
fdt
,
nodeoffset
,
name
,
len
,
&
prop
);
err
=
fdt_resize_property_
(
fdt
,
nodeoffset
,
name
,
len
,
&
prop
);
if
(
err
==
-
FDT_ERR_NOTFOUND
)
if
(
err
==
-
FDT_ERR_NOTFOUND
)
...
@@ -308,7 +294,7 @@ int fdt_appendprop(void *fdt, int nodeoffset, const char *name,
...
@@ -308,7 +294,7 @@ int fdt_appendprop(void *fdt, int nodeoffset, const char *name,
struct
fdt_property
*
prop
;
struct
fdt_property
*
prop
;
int
err
,
oldlen
,
newlen
;
int
err
,
oldlen
,
newlen
;
FDT_RW_
CHECK_HEADER
(
fdt
);
FDT_RW_
PROBE
(
fdt
);
prop
=
fdt_get_property_w
(
fdt
,
nodeoffset
,
name
,
&
oldlen
);
prop
=
fdt_get_property_w
(
fdt
,
nodeoffset
,
name
,
&
oldlen
);
if
(
prop
)
{
if
(
prop
)
{
...
@@ -334,7 +320,7 @@ int fdt_delprop(void *fdt, int nodeoffset, const char *name)
...
@@ -334,7 +320,7 @@ int fdt_delprop(void *fdt, int nodeoffset, const char *name)
struct
fdt_property
*
prop
;
struct
fdt_property
*
prop
;
int
len
,
proplen
;
int
len
,
proplen
;
FDT_RW_
CHECK_HEADER
(
fdt
);
FDT_RW_
PROBE
(
fdt
);
prop
=
fdt_get_property_w
(
fdt
,
nodeoffset
,
name
,
&
len
);
prop
=
fdt_get_property_w
(
fdt
,
nodeoffset
,
name
,
&
len
);
if
(
!
prop
)
if
(
!
prop
)
...
@@ -354,7 +340,7 @@ int fdt_add_subnode_namelen(void *fdt, int parentoffset,
...
@@ -354,7 +340,7 @@ int fdt_add_subnode_namelen(void *fdt, int parentoffset,
uint32_t
tag
;
uint32_t
tag
;
fdt32_t
*
endtag
;
fdt32_t
*
endtag
;
FDT_RW_
CHECK_HEADER
(
fdt
);
FDT_RW_
PROBE
(
fdt
);
offset
=
fdt_subnode_offset_namelen
(
fdt
,
parentoffset
,
name
,
namelen
);
offset
=
fdt_subnode_offset_namelen
(
fdt
,
parentoffset
,
name
,
namelen
);
if
(
offset
>=
0
)
if
(
offset
>=
0
)
...
@@ -394,7 +380,7 @@ int fdt_del_node(void *fdt, int nodeoffset)
...
@@ -394,7 +380,7 @@ int fdt_del_node(void *fdt, int nodeoffset)
{
{
int
endoffset
;
int
endoffset
;
FDT_RW_
CHECK_HEADER
(
fdt
);
FDT_RW_
PROBE
(
fdt
);
endoffset
=
fdt_node_end_offset_
(
fdt
,
nodeoffset
);
endoffset
=
fdt_node_end_offset_
(
fdt
,
nodeoffset
);
if
(
endoffset
<
0
)
if
(
endoffset
<
0
)
...
@@ -435,12 +421,12 @@ int fdt_open_into(const void *fdt, void *buf, int bufsize)
...
@@ -435,12 +421,12 @@ int fdt_open_into(const void *fdt, void *buf, int bufsize)
const
char
*
fdtend
=
fdtstart
+
fdt_totalsize
(
fdt
);
const
char
*
fdtend
=
fdtstart
+
fdt_totalsize
(
fdt
);
char
*
tmp
;
char
*
tmp
;
FDT_
CHECK_HEADER
(
fdt
);
FDT_
RO_PROBE
(
fdt
);
mem_rsv_size
=
(
fdt_num_mem_rsv
(
fdt
)
+
1
)
mem_rsv_size
=
(
fdt_num_mem_rsv
(
fdt
)
+
1
)
*
sizeof
(
struct
fdt_reserve_entry
);
*
sizeof
(
struct
fdt_reserve_entry
);
if
(
fdt_version
(
fdt
)
>=
17
)
{
if
(
can_assume
(
LATEST
)
||
fdt_version
(
fdt
)
>=
17
)
{
struct_size
=
fdt_size_dt_struct
(
fdt
);
struct_size
=
fdt_size_dt_struct
(
fdt
);
}
else
{
}
else
{
struct_size
=
0
;
struct_size
=
0
;
...
@@ -450,7 +436,8 @@ int fdt_open_into(const void *fdt, void *buf, int bufsize)
...
@@ -450,7 +436,8 @@ int fdt_open_into(const void *fdt, void *buf, int bufsize)
return
struct_size
;
return
struct_size
;
}
}
if
(
!
fdt_blocks_misordered_
(
fdt
,
mem_rsv_size
,
struct_size
))
{
if
(
can_assume
(
LIBFDT_ORDER
)
||
!
fdt_blocks_misordered_
(
fdt
,
mem_rsv_size
,
struct_size
))
{
/* no further work necessary */
/* no further work necessary */
err
=
fdt_move
(
fdt
,
buf
,
bufsize
);
err
=
fdt_move
(
fdt
,
buf
,
bufsize
);
if
(
err
)
if
(
err
)
...
@@ -494,7 +481,7 @@ int fdt_pack(void *fdt)
...
@@ -494,7 +481,7 @@ int fdt_pack(void *fdt)
{
{
int
mem_rsv_size
;
int
mem_rsv_size
;
FDT_RW_
CHECK_HEADER
(
fdt
);
FDT_RW_
PROBE
(
fdt
);
mem_rsv_size
=
(
fdt_num_mem_rsv
(
fdt
)
+
1
)
mem_rsv_size
=
(
fdt_num_mem_rsv
(
fdt
)
+
1
)
*
sizeof
(
struct
fdt_reserve_entry
);
*
sizeof
(
struct
fdt_reserve_entry
);
...
...
lib/libfdt/fdt_strerror.c
View file @
946d5f67
// SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause)
/*
/*
* libfdt - Flat Device Tree manipulation
* libfdt - Flat Device Tree manipulation
* Copyright (C) 2006 David Gibson, IBM Corporation.
* Copyright (C) 2006 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.
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
*/
#include "libfdt_env.h"
#include "libfdt_env.h"
...
@@ -82,6 +38,7 @@ static struct fdt_errtabent fdt_errtable[] = {
...
@@ -82,6 +38,7 @@ static struct fdt_errtabent fdt_errtable[] = {
FDT_ERRTABENT
(
FDT_ERR_BADVALUE
),
FDT_ERRTABENT
(
FDT_ERR_BADVALUE
),
FDT_ERRTABENT
(
FDT_ERR_BADOVERLAY
),
FDT_ERRTABENT
(
FDT_ERR_BADOVERLAY
),
FDT_ERRTABENT
(
FDT_ERR_NOPHANDLES
),
FDT_ERRTABENT
(
FDT_ERR_NOPHANDLES
),
FDT_ERRTABENT
(
FDT_ERR_BADFLAGS
),
};
};
#define FDT_ERRTABSIZE (sizeof(fdt_errtable) / sizeof(fdt_errtable[0]))
#define FDT_ERRTABSIZE (sizeof(fdt_errtable) / sizeof(fdt_errtable[0]))
...
...
lib/libfdt/fdt_sw.c
View file @
946d5f67
// SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause)
/*
/*
* libfdt - Flat Device Tree manipulation
* libfdt - Flat Device Tree manipulation
* Copyright (C) 2006 David Gibson, IBM Corporation.
* Copyright (C) 2006 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 "libfdt_env.h"
...
@@ -55,21 +10,87 @@
...
@@ -55,21 +10,87 @@
#include "libfdt_internal.h"
#include "libfdt_internal.h"
static
int
fdt_sw_
check_header
_
(
void
*
fdt
)
static
int
fdt_sw_
probe
_
(
void
*
fdt
)
{
{
if
(
fdt_magic
(
fdt
)
!=
FDT_SW_MAGIC
)
if
(
!
can_assume
(
VALID_INPUT
))
{
return
-
FDT_ERR_BADMAGIC
;
if
(
fdt_magic
(
fdt
)
==
FDT_MAGIC
)
/* FIXME: should check more details about the header state */
return
-
FDT_ERR_BADSTATE
;
else
if
(
fdt_magic
(
fdt
)
!=
FDT_SW_MAGIC
)
return
-
FDT_ERR_BADMAGIC
;
}
return
0
;
return
0
;
}
}
#define FDT_SW_
CHECK_HEADER
(fdt) \
#define FDT_SW_
PROBE
(fdt) \
{ \
{ \
int err; \
int err; \
if ((err = fdt_sw_
check_header
_(fdt)) != 0) \
if ((err = fdt_sw_
probe
_(fdt)) != 0) \
return err; \
return err; \
}
}
/* 'memrsv' state: Initial state after fdt_create()
*
* Allowed functions:
* fdt_add_reservmap_entry()
* fdt_finish_reservemap() [moves to 'struct' state]
*/
static
int
fdt_sw_probe_memrsv_
(
void
*
fdt
)
{
int
err
=
fdt_sw_probe_
(
fdt
);
if
(
err
)
return
err
;
if
(
!
can_assume
(
VALID_INPUT
)
&&
fdt_off_dt_strings
(
fdt
)
!=
0
)
return
-
FDT_ERR_BADSTATE
;
return
0
;
}
#define FDT_SW_PROBE_MEMRSV(fdt) \
{ \
int err; \
if ((err = fdt_sw_probe_memrsv_(fdt)) != 0) \
return err; \
}
/* 'struct' state: Enter this state after fdt_finish_reservemap()
*
* Allowed functions:
* fdt_begin_node()
* fdt_end_node()
* fdt_property*()
* fdt_finish() [moves to 'complete' state]
*/
static
int
fdt_sw_probe_struct_
(
void
*
fdt
)
{
int
err
=
fdt_sw_probe_
(
fdt
);
if
(
err
)
return
err
;
if
(
!
can_assume
(
VALID_INPUT
)
&&
fdt_off_dt_strings
(
fdt
)
!=
fdt_totalsize
(
fdt
))
return
-
FDT_ERR_BADSTATE
;
return
0
;
}
#define FDT_SW_PROBE_STRUCT(fdt) \
{ \
int err; \
if ((err = fdt_sw_probe_struct_(fdt)) != 0) \
return err; \
}
static
inline
uint32_t
sw_flags
(
void
*
fdt
)
{
/* assert: (fdt_magic(fdt) == FDT_SW_MAGIC) */
return
fdt_last_comp_version
(
fdt
);
}
/* 'complete' state: Enter this state after fdt_finish()
*
* Allowed functions: none
*/
static
void
*
fdt_grab_space_
(
void
*
fdt
,
size_t
len
)
static
void
*
fdt_grab_space_
(
void
*
fdt
,
size_t
len
)
{
{
int
offset
=
fdt_size_dt_struct
(
fdt
);
int
offset
=
fdt_size_dt_struct
(
fdt
);
...
@@ -85,38 +106,59 @@ static void *fdt_grab_space_(void *fdt, size_t len)
...
@@ -85,38 +106,59 @@ static void *fdt_grab_space_(void *fdt, size_t len)
return
fdt_offset_ptr_w_
(
fdt
,
offset
);
return
fdt_offset_ptr_w_
(
fdt
,
offset
);
}
}
int
fdt_create
(
void
*
buf
,
int
bufsize
)
int
fdt_create
_with_flags
(
void
*
buf
,
int
bufsize
,
uint32_t
flags
)
{
{
const
size_t
hdrsize
=
FDT_ALIGN
(
sizeof
(
struct
fdt_header
),
sizeof
(
struct
fdt_reserve_entry
));
void
*
fdt
=
buf
;
void
*
fdt
=
buf
;
if
(
bufsize
<
size
of
(
struct
fdt_header
)
)
if
(
bufsize
<
hdr
size
)
return
-
FDT_ERR_NOSPACE
;
return
-
FDT_ERR_NOSPACE
;
if
(
flags
&
~
FDT_CREATE_FLAGS_ALL
)
return
-
FDT_ERR_BADFLAGS
;
memset
(
buf
,
0
,
bufsize
);
memset
(
buf
,
0
,
bufsize
);
/*
* magic and last_comp_version keep intermediate state during the fdt
* creation process, which is replaced with the proper FDT format by
* fdt_finish().
*
* flags should be accessed with sw_flags().
*/
fdt_set_magic
(
fdt
,
FDT_SW_MAGIC
);
fdt_set_magic
(
fdt
,
FDT_SW_MAGIC
);
fdt_set_version
(
fdt
,
FDT_LAST_SUPPORTED_VERSION
);
fdt_set_version
(
fdt
,
FDT_LAST_SUPPORTED_VERSION
);
fdt_set_last_comp_version
(
fdt
,
FDT_FIRST_SUPPORTED_VERSION
);
fdt_set_last_comp_version
(
fdt
,
flags
);
fdt_set_totalsize
(
fdt
,
bufsize
);
fdt_set_totalsize
(
fdt
,
bufsize
);
fdt_set_off_mem_rsvmap
(
fdt
,
FDT_ALIGN
(
sizeof
(
struct
fdt_header
),
fdt_set_off_mem_rsvmap
(
fdt
,
hdrsize
);
sizeof
(
struct
fdt_reserve_entry
)));
fdt_set_off_dt_struct
(
fdt
,
fdt_off_mem_rsvmap
(
fdt
));
fdt_set_off_dt_struct
(
fdt
,
fdt_off_mem_rsvmap
(
fdt
));
fdt_set_off_dt_strings
(
fdt
,
bufsize
);
fdt_set_off_dt_strings
(
fdt
,
0
);
return
0
;
return
0
;
}
}
int
fdt_create
(
void
*
buf
,
int
bufsize
)
{
return
fdt_create_with_flags
(
buf
,
bufsize
,
0
);
}
int
fdt_resize
(
void
*
fdt
,
void
*
buf
,
int
bufsize
)
int
fdt_resize
(
void
*
fdt
,
void
*
buf
,
int
bufsize
)
{
{
size_t
headsize
,
tailsize
;
size_t
headsize
,
tailsize
;
char
*
oldtail
,
*
newtail
;
char
*
oldtail
,
*
newtail
;
FDT_SW_
CHECK_HEADER
(
fdt
);
FDT_SW_
PROBE
(
fdt
);
headsize
=
fdt_off_dt_struct
(
fdt
);
headsize
=
fdt_off_dt_struct
(
fdt
)
+
fdt_size_dt_struct
(
fdt
)
;
tailsize
=
fdt_size_dt_strings
(
fdt
);
tailsize
=
fdt_size_dt_strings
(
fdt
);
if
(
!
can_assume
(
VALID_DTB
)
&&
headsize
+
tailsize
>
fdt_totalsize
(
fdt
))
return
-
FDT_ERR_INTERNAL
;
if
((
headsize
+
tailsize
)
>
bufsize
)
if
((
headsize
+
tailsize
)
>
bufsize
)
return
-
FDT_ERR_NOSPACE
;
return
-
FDT_ERR_NOSPACE
;
...
@@ -133,8 +175,9 @@ int fdt_resize(void *fdt, void *buf, int bufsize)
...
@@ -133,8 +175,9 @@ int fdt_resize(void *fdt, void *buf, int bufsize)
memmove
(
buf
,
fdt
,
headsize
);
memmove
(
buf
,
fdt
,
headsize
);
}
}
fdt_set_off_dt_strings
(
buf
,
bufsize
);
fdt_set_totalsize
(
buf
,
bufsize
);
fdt_set_totalsize
(
buf
,
bufsize
);
if
(
fdt_off_dt_strings
(
buf
))
fdt_set_off_dt_strings
(
buf
,
bufsize
);
return
0
;
return
0
;
}
}
...
@@ -144,10 +187,7 @@ int fdt_add_reservemap_entry(void *fdt, uint64_t addr, uint64_t size)
...
@@ -144,10 +187,7 @@ int fdt_add_reservemap_entry(void *fdt, uint64_t addr, uint64_t size)
struct
fdt_reserve_entry
*
re
;
struct
fdt_reserve_entry
*
re
;
int
offset
;
int
offset
;
FDT_SW_CHECK_HEADER
(
fdt
);
FDT_SW_PROBE_MEMRSV
(
fdt
);
if
(
fdt_size_dt_struct
(
fdt
))
return
-
FDT_ERR_BADSTATE
;
offset
=
fdt_off_dt_struct
(
fdt
);
offset
=
fdt_off_dt_struct
(
fdt
);
if
((
offset
+
sizeof
(
*
re
))
>
fdt_totalsize
(
fdt
))
if
((
offset
+
sizeof
(
*
re
))
>
fdt_totalsize
(
fdt
))
...
@@ -164,16 +204,23 @@ int fdt_add_reservemap_entry(void *fdt, uint64_t addr, uint64_t size)
...
@@ -164,16 +204,23 @@ int fdt_add_reservemap_entry(void *fdt, uint64_t addr, uint64_t size)
int
fdt_finish_reservemap
(
void
*
fdt
)
int
fdt_finish_reservemap
(
void
*
fdt
)
{
{
return
fdt_add_reservemap_entry
(
fdt
,
0
,
0
);
int
err
=
fdt_add_reservemap_entry
(
fdt
,
0
,
0
);
if
(
err
)
return
err
;
fdt_set_off_dt_strings
(
fdt
,
fdt_totalsize
(
fdt
));
return
0
;
}
}
int
fdt_begin_node
(
void
*
fdt
,
const
char
*
name
)
int
fdt_begin_node
(
void
*
fdt
,
const
char
*
name
)
{
{
struct
fdt_node_header
*
nh
;
struct
fdt_node_header
*
nh
;
int
namelen
=
strlen
(
name
)
+
1
;
int
namelen
;
FDT_SW_
CHECK_HEADER
(
fdt
);
FDT_SW_
PROBE_STRUCT
(
fdt
);
namelen
=
strlen
(
name
)
+
1
;
nh
=
fdt_grab_space_
(
fdt
,
sizeof
(
*
nh
)
+
FDT_TAGALIGN
(
namelen
));
nh
=
fdt_grab_space_
(
fdt
,
sizeof
(
*
nh
)
+
FDT_TAGALIGN
(
namelen
));
if
(
!
nh
)
if
(
!
nh
)
return
-
FDT_ERR_NOSPACE
;
return
-
FDT_ERR_NOSPACE
;
...
@@ -187,7 +234,7 @@ int fdt_end_node(void *fdt)
...
@@ -187,7 +234,7 @@ int fdt_end_node(void *fdt)
{
{
fdt32_t
*
en
;
fdt32_t
*
en
;
FDT_SW_
CHECK_HEADER
(
fdt
);
FDT_SW_
PROBE_STRUCT
(
fdt
);
en
=
fdt_grab_space_
(
fdt
,
FDT_TAGSIZE
);
en
=
fdt_grab_space_
(
fdt
,
FDT_TAGSIZE
);
if
(
!
en
)
if
(
!
en
)
...
@@ -197,19 +244,13 @@ int fdt_end_node(void *fdt)
...
@@ -197,19 +244,13 @@ int fdt_end_node(void *fdt)
return
0
;
return
0
;
}
}
static
int
fdt_
find_
add_string_
(
void
*
fdt
,
const
char
*
s
)
static
int
fdt_add_string_
(
void
*
fdt
,
const
char
*
s
)
{
{
char
*
strtab
=
(
char
*
)
fdt
+
fdt_totalsize
(
fdt
);
char
*
strtab
=
(
char
*
)
fdt
+
fdt_totalsize
(
fdt
);
const
char
*
p
;
int
strtabsize
=
fdt_size_dt_strings
(
fdt
);
int
strtabsize
=
fdt_size_dt_strings
(
fdt
);
int
len
=
strlen
(
s
)
+
1
;
int
len
=
strlen
(
s
)
+
1
;
int
struct_top
,
offset
;
int
struct_top
,
offset
;
p
=
fdt_find_string_
(
strtab
-
strtabsize
,
strtabsize
,
s
);
if
(
p
)
return
p
-
strtab
;
/* Add it */
offset
=
-
strtabsize
-
len
;
offset
=
-
strtabsize
-
len
;
struct_top
=
fdt_off_dt_struct
(
fdt
)
+
fdt_size_dt_struct
(
fdt
);
struct_top
=
fdt_off_dt_struct
(
fdt
)
+
fdt_size_dt_struct
(
fdt
);
if
(
fdt_totalsize
(
fdt
)
+
offset
<
struct_top
)
if
(
fdt_totalsize
(
fdt
)
+
offset
<
struct_top
)
...
@@ -220,20 +261,56 @@ static int fdt_find_add_string_(void *fdt, const char *s)
...
@@ -220,20 +261,56 @@ static int fdt_find_add_string_(void *fdt, const char *s)
return
offset
;
return
offset
;
}
}
/* Must only be used to roll back in case of error */
static
void
fdt_del_last_string_
(
void
*
fdt
,
const
char
*
s
)
{
int
strtabsize
=
fdt_size_dt_strings
(
fdt
);
int
len
=
strlen
(
s
)
+
1
;
fdt_set_size_dt_strings
(
fdt
,
strtabsize
-
len
);
}
static
int
fdt_find_add_string_
(
void
*
fdt
,
const
char
*
s
,
int
*
allocated
)
{
char
*
strtab
=
(
char
*
)
fdt
+
fdt_totalsize
(
fdt
);
int
strtabsize
=
fdt_size_dt_strings
(
fdt
);
const
char
*
p
;
*
allocated
=
0
;
p
=
fdt_find_string_
(
strtab
-
strtabsize
,
strtabsize
,
s
);
if
(
p
)
return
p
-
strtab
;
*
allocated
=
1
;
return
fdt_add_string_
(
fdt
,
s
);
}
int
fdt_property_placeholder
(
void
*
fdt
,
const
char
*
name
,
int
len
,
void
**
valp
)
int
fdt_property_placeholder
(
void
*
fdt
,
const
char
*
name
,
int
len
,
void
**
valp
)
{
{
struct
fdt_property
*
prop
;
struct
fdt_property
*
prop
;
int
nameoff
;
int
nameoff
;
int
allocated
;
FDT_SW_
CHECK_HEADER
(
fdt
);
FDT_SW_
PROBE_STRUCT
(
fdt
);
nameoff
=
fdt_find_add_string_
(
fdt
,
name
);
/* String de-duplication can be slow, _NO_NAME_DEDUP skips it */
if
(
sw_flags
(
fdt
)
&
FDT_CREATE_FLAG_NO_NAME_DEDUP
)
{
allocated
=
1
;
nameoff
=
fdt_add_string_
(
fdt
,
name
);
}
else
{
nameoff
=
fdt_find_add_string_
(
fdt
,
name
,
&
allocated
);
}
if
(
nameoff
==
0
)
if
(
nameoff
==
0
)
return
-
FDT_ERR_NOSPACE
;
return
-
FDT_ERR_NOSPACE
;
prop
=
fdt_grab_space_
(
fdt
,
sizeof
(
*
prop
)
+
FDT_TAGALIGN
(
len
));
prop
=
fdt_grab_space_
(
fdt
,
sizeof
(
*
prop
)
+
FDT_TAGALIGN
(
len
));
if
(
!
prop
)
if
(
!
prop
)
{
if
(
allocated
)
fdt_del_last_string_
(
fdt
,
name
);
return
-
FDT_ERR_NOSPACE
;
return
-
FDT_ERR_NOSPACE
;
}
prop
->
tag
=
cpu_to_fdt32
(
FDT_PROP
);
prop
->
tag
=
cpu_to_fdt32
(
FDT_PROP
);
prop
->
nameoff
=
cpu_to_fdt32
(
nameoff
);
prop
->
nameoff
=
cpu_to_fdt32
(
nameoff
);
...
@@ -262,7 +339,7 @@ int fdt_finish(void *fdt)
...
@@ -262,7 +339,7 @@ int fdt_finish(void *fdt)
uint32_t
tag
;
uint32_t
tag
;
int
offset
,
nextoffset
;
int
offset
,
nextoffset
;
FDT_SW_
CHECK_HEADER
(
fdt
);
FDT_SW_
PROBE_STRUCT
(
fdt
);
/* Add terminator */
/* Add terminator */
end
=
fdt_grab_space_
(
fdt
,
sizeof
(
*
end
));
end
=
fdt_grab_space_
(
fdt
,
sizeof
(
*
end
));
...
@@ -295,6 +372,10 @@ int fdt_finish(void *fdt)
...
@@ -295,6 +372,10 @@ int fdt_finish(void *fdt)
/* Finally, adjust the header */
/* Finally, adjust the header */
fdt_set_totalsize
(
fdt
,
newstroffset
+
fdt_size_dt_strings
(
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_magic
(
fdt
,
FDT_MAGIC
);
fdt_set_magic
(
fdt
,
FDT_MAGIC
);
return
0
;
return
0
;
}
}
lib/libfdt/fdt_wip.c
View file @
946d5f67
// SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause)
/*
/*
* libfdt - Flat Device Tree manipulation
* libfdt - Flat Device Tree manipulation
* Copyright (C) 2006 David Gibson, IBM Corporation.
* Copyright (C) 2006 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 "libfdt_env.h"
...
...
lib/libfdt/libfdt_internal.h
View file @
946d5f67
/* SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause) */
#ifndef LIBFDT_INTERNAL_H
#ifndef LIBFDT_INTERNAL_H
#define LIBFDT_INTERNAL_H
#define LIBFDT_INTERNAL_H
/*
/*
* libfdt - Flat Device Tree manipulation
* libfdt - Flat Device Tree manipulation
* Copyright (C) 2006 David Gibson, IBM Corporation.
* Copyright (C) 2006 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 <fdt.h>
#include <fdt.h>
#define FDT_ALIGN(x, a) (((x) + (a) - 1) & ~((a) - 1))
#define FDT_ALIGN(x, a) (((x) + (a) - 1) & ~((a) - 1))
#define FDT_TAGALIGN(x) (FDT_ALIGN((x), FDT_TAGSIZE))
#define FDT_TAGALIGN(x) (FDT_ALIGN((x), FDT_TAGSIZE))
#define FDT_CHECK_HEADER(fdt) \
int32_t
fdt_ro_probe_
(
const
void
*
fdt
);
{ \
#define FDT_RO_PROBE(fdt) \
int err_; \
{ \
if ((err_ = fdt_check_header(fdt)) != 0) \
int32_t totalsize_; \
return err_; \
if ((totalsize_ = fdt_ro_probe_(fdt)) < 0) \
return totalsize_; \
}
}
int
fdt_check_node_offset_
(
const
void
*
fdt
,
int
offset
);
int
fdt_check_node_offset_
(
const
void
*
fdt
,
int
offset
);
...
@@ -92,4 +48,126 @@ static inline struct fdt_reserve_entry *fdt_mem_rsv_w_(void *fdt, int n)
...
@@ -92,4 +48,126 @@ static inline struct fdt_reserve_entry *fdt_mem_rsv_w_(void *fdt, int n)
#define FDT_SW_MAGIC (~FDT_MAGIC)
#define FDT_SW_MAGIC (~FDT_MAGIC)
/**********************************************************************/
/* Checking controls */
/**********************************************************************/
#ifndef FDT_ASSUME_MASK
#define FDT_ASSUME_MASK 0
#endif
/*
* Defines assumptions which can be enabled. Each of these can be enabled
* individually. For maximum safety, don't enable any assumptions!
*
* For minimal code size and no safety, use ASSUME_PERFECT at your own risk.
* You should have another method of validating the device tree, such as a
* signature or hash check before using libfdt.
*
* For situations where security is not a concern it may be safe to enable
* ASSUME_SANE.
*/
enum
{
/*
* This does essentially no checks. Only the latest device-tree
* version is correctly handled. Inconsistencies or errors in the device
* tree may cause undefined behaviour or crashes. Invalid parameters
* passed to libfdt may do the same.
*
* If an error occurs when modifying the tree it may leave the tree in
* an intermediate (but valid) state. As an example, adding a property
* where there is insufficient space may result in the property name
* being added to the string table even though the property itself is
* not added to the struct section.
*
* Only use this if you have a fully validated device tree with
* the latest supported version and wish to minimise code size.
*/
ASSUME_PERFECT
=
0xff
,
/*
* This assumes that the device tree is sane. i.e. header metadata
* and basic hierarchy are correct.
*
* With this assumption enabled, normal device trees produced by libfdt
* and the compiler should be handled safely. Malicious device trees and
* complete garbage may cause libfdt to behave badly or crash. Truncated
* device trees (e.g. those only partially loaded) can also cause
* problems.
*
* Note: Only checks that relate exclusively to the device tree itself
* (not the parameters passed to libfdt) are disabled by this
* assumption. This includes checking headers, tags and the like.
*/
ASSUME_VALID_DTB
=
1
<<
0
,
/*
* This builds on ASSUME_VALID_DTB and further assumes that libfdt
* functions are called with valid parameters, i.e. not trigger
* FDT_ERR_BADOFFSET or offsets that are out of bounds. It disables any
* extensive checking of parameters and the device tree, making various
* assumptions about correctness.
*
* It doesn't make sense to enable this assumption unless
* ASSUME_VALID_DTB is also enabled.
*/
ASSUME_VALID_INPUT
=
1
<<
1
,
/*
* This disables checks for device-tree version and removes all code
* which handles older versions.
*
* Only enable this if you know you have a device tree with the latest
* version.
*/
ASSUME_LATEST
=
1
<<
2
,
/*
* This assumes that it is OK for a failed addition to the device tree,
* due to lack of space or some other problem, to skip any rollback
* steps (such as dropping the property name from the string table).
* This is safe to enable in most circumstances, even though it may
* leave the tree in a sub-optimal state.
*/
ASSUME_NO_ROLLBACK
=
1
<<
3
,
/*
* This assumes that the device tree components appear in a 'convenient'
* order, i.e. the memory reservation block first, then the structure
* block and finally the string block.
*
* This order is not specified by the device-tree specification,
* but is expected by libfdt. The device-tree compiler always created
* device trees with this order.
*
* This assumption disables a check in fdt_open_into() and removes the
* ability to fix the problem there. This is safe if you know that the
* device tree is correctly ordered. See fdt_blocks_misordered_().
*/
ASSUME_LIBFDT_ORDER
=
1
<<
4
,
/*
* This assumes that libfdt itself does not have any internal bugs. It
* drops certain checks that should never be needed unless libfdt has an
* undiscovered bug.
*
* This can generally be considered safe to enable.
*/
ASSUME_LIBFDT_FLAWLESS
=
1
<<
5
,
};
/**
* can_assume_() - check if a particular assumption is enabled
*
* @mask: Mask to check (ASSUME_...)
* @return true if that assumption is enabled, else false
*/
static
inline
bool
can_assume_
(
int
mask
)
{
return
FDT_ASSUME_MASK
&
mask
;
}
/** helper macros for checking assumptions */
#define can_assume(_assume) can_assume_(ASSUME_ ## _assume)
#endif
/* LIBFDT_INTERNAL_H */
#endif
/* LIBFDT_INTERNAL_H */
plat/arm/board/juno/jmptbl.i
View file @
946d5f67
...
@@ -29,6 +29,8 @@ fdt fdt_stringlist_search
...
@@ -29,6 +29,8 @@ fdt fdt_stringlist_search
fdt
fdt_get_alias_namelen
fdt
fdt_get_alias_namelen
fdt
fdt_path_offset
fdt
fdt_path_offset
fdt
fdt_path_offset_namelen
fdt
fdt_path_offset_namelen
fdt
fdt_address_cells
fdt
fdt_size_cells
fdt
fdt_get_name
fdt
fdt_get_name
fdt
fdt_get_alias
fdt
fdt_get_alias
fdt
fdt_node_offset_by_phandle
fdt
fdt_node_offset_by_phandle
...
...
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