/* SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause) */#ifndef LIBFDT_H#define LIBFDT_H/* * libfdt - Flat Device Tree manipulation * Copyright (C) 2006 David Gibson, IBM Corporation. */ #include "libfdt_env.h"#include "fdt.h" #ifdef __cplusplusextern "C" {#endif #define FDT_FIRST_SUPPORTED_VERSION 0x02#define FDT_LAST_COMPATIBLE_VERSION 0x10#define FDT_LAST_SUPPORTED_VERSION 0x11 /* Error codes: informative error codes */#define FDT_ERR_NOTFOUND 1 /* FDT_ERR_NOTFOUND: The requested node or property does not exist */#define FDT_ERR_EXISTS 2 /* FDT_ERR_EXISTS: Attempted to create a node or property which * already exists */#define FDT_ERR_NOSPACE 3 /* FDT_ERR_NOSPACE: Operation needed to expand the device * tree, but its buffer did not have sufficient space to * contain the expanded tree. Use fdt_open_into() to move the * device tree to a buffer with more space. */ /* Error codes: codes for bad parameters */#define FDT_ERR_BADOFFSET 4 /* FDT_ERR_BADOFFSET: Function was passed a structure block * offset which is out-of-bounds, or which points to an * unsuitable part of the structure for the operation. */#define FDT_ERR_BADPATH 5 /* FDT_ERR_BADPATH: Function was passed a badly formatted path * (e.g. missing a leading / for a function which requires an * absolute path) */#define FDT_ERR_BADPHANDLE 6 /* FDT_ERR_BADPHANDLE: Function was passed an invalid phandle. * This can be caused either by an invalid phandle property * length, or the phandle value was either 0 or -1, which are * not permitted. */#define FDT_ERR_BADSTATE 7 /* FDT_ERR_BADSTATE: Function was passed an incomplete device * tree created by the sequential-write functions, which is * not sufficiently complete for the requested operation. */ /* Error codes: codes for bad device tree blobs */#define FDT_ERR_TRUNCATED 8 /* FDT_ERR_TRUNCATED: FDT or a sub-block is improperly * terminated (overflows, goes outside allowed bounds, or * isn't properly terminated). */#define FDT_ERR_BADMAGIC 9 /* FDT_ERR_BADMAGIC: Given "device tree" appears not to be a * device tree at all - it is missing the flattened device * tree magic number. */#define FDT_ERR_BADVERSION 10 /* FDT_ERR_BADVERSION: Given device tree has a version which * can't be handled by the requested operation. For * read-write functions, this may mean that fdt_open_into() is * required to convert the tree to the expected version. */#define FDT_ERR_BADSTRUCTURE 11 /* FDT_ERR_BADSTRUCTURE: Given device tree has a corrupt * structure block or other serious error (e.g. misnested * nodes, or subnodes preceding properties). */#define FDT_ERR_BADLAYOUT 12 /* FDT_ERR_BADLAYOUT: For read-write functions, the given * device tree has it's sub-blocks in an order that the * function can't handle (memory reserve map, then structure, * then strings). Use fdt_open_into() to reorganize the tree * into a form suitable for the read-write operations. */ /* "Can't happen" error indicating a bug in libfdt */#define FDT_ERR_INTERNAL 13 /* FDT_ERR_INTERNAL: libfdt has failed an internal assertion. * Should never be returned, if it is, it indicates a bug in * libfdt itself. */ /* Errors in device tree content */#define FDT_ERR_BADNCELLS 14 /* FDT_ERR_BADNCELLS: Device tree has a #address-cells, #size-cells * or similar property with a bad format or value */ #define FDT_ERR_BADVALUE 15 /* FDT_ERR_BADVALUE: Device tree has a property with an unexpected * value. For example: a property expected to contain a string list * is not NUL-terminated within the length of its value. */ #define FDT_ERR_BADOVERLAY 16 /* FDT_ERR_BADOVERLAY: The device tree overlay, while * correctly structured, cannot be applied due to some * unexpected or missing value, property or node. */ #define FDT_ERR_NOPHANDLES 17 /* FDT_ERR_NOPHANDLES: The device tree doesn't have any * phandle available anymore without causing an overflow */ #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_ALIGNMENT 19 /* FDT_ERR_ALIGNMENT: The device tree base address is not 8-byte * aligned. */ #define FDT_ERR_MAX 19 /* constants */#define FDT_MAX_PHANDLE 0xfffffffe /* Valid values for phandles range from 1 to 2^32-2. */ /**********************************************************************//* Low-level functions (you probably don't need these) *//**********************************************************************/ /** * fdt_offset_ptr - safely get a byte range within the device tree blob * @fdt: Pointer to the device tree blob * @offset: Offset within the blob to the desired byte range * @checklen: Required length of the byte range * * fdt_offset_ptr() returns a pointer to the byte range of length @checklen at * the given @offset within the device tree blob, after verifying that the byte * range fits entirely within the blob and does not overflow. * * returns: * pointer to the byte range, on success * NULL, if the requested range does not fit within the blob */#ifndef SWIG /* This function is not useful in Python */const void *fdt_offset_ptr(const void *fdt, int offset, unsigned int checklen);#endifstatic inline void *fdt_offset_ptr_w(void *fdt, int offset, int checklen){ return (void *)(uintptr_t)fdt_offset_ptr(fdt, offset, checklen);} /** * fdt_next_tag - get next tag in the device tree * @fdt: Pointer to the device tree blob * @offset: Offset within the blob to start searching * @nextoffset: Pointer to variable to store the offset of the next tag * * fdt_next_tag() returns the tag type of the next tag in the device tree * blob starting from the given @offset. If @nextoffset is non-NULL, it will * be set to the offset immediately following the tag. * * returns: * the tag type (FDT_BEGIN_NODE, FDT_END_NODE, FDT_PROP, FDT_NOP, FDT_END), * FDT_END, if offset is out of bounds */uint32_t fdt_next_tag(const void *fdt, int offset, int *nextoffset); /* * External helpers to access words from a device tree blob. They're built * to work even with unaligned pointers on platforms (such as ARMv5) that don't * like unaligned loads and stores. */static inline uint16_t fdt16_ld(const fdt16_t *p){ const uint8_t *bp = (const uint8_t *)p; return ((uint16_t)bp[0] << 8) | bp[1];} static inline uint32_t fdt32_ld(const fdt32_t *p){ 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 *//**********************************************************************/ int fdt_next_node(const void *fdt, int offset, int *depth); /** * fdt_first_subnode() - get offset of first direct subnode * @fdt: FDT blob * @offset: Offset of node to check * * Return: offset of first subnode, or -FDT_ERR_NOTFOUND if there is none */int fdt_first_subnode(const void *fdt, int offset); /** * fdt_next_subnode() - get offset of next direct subnode * @fdt: FDT blob * @offset: Offset of previous subnode * * After first calling fdt_first_subnode(), call this function repeatedly to * get direct subnodes of a parent node. * * Return: offset of next subnode, or -FDT_ERR_NOTFOUND if there are no more * subnodes */int fdt_next_subnode(const void *fdt, int offset); /** * fdt_for_each_subnode - iterate over all subnodes of a parent * * @node: child node (int, lvalue) * @fdt: FDT blob (const void *) * @parent: parent node (int) * * This is actually a wrapper around a for loop and would be used like so: * * fdt_for_each_subnode(node, fdt, parent) { * Use node * ... * } * * if ((node < 0) && (node != -FDT_ERR_NOTFOUND)) { * Error handling * } * * Note that this is implemented as a macro and @node is used as * iterator in the loop. The parent variable be constant or even a * literal. */#define fdt_for_each_subnode(node, fdt, parent) \ for (node = fdt_first_subnode(fdt, parent); \ node >= 0; \ node = fdt_next_subnode(fdt, node)) /**********************************************************************//* General functions *//**********************************************************************/#define fdt_get_header(fdt, field) \ (fdt32_ld(&((const struct fdt_header *)(fdt))->field))#define fdt_magic(fdt) (fdt_get_header(fdt, magic))#define fdt_totalsize(fdt) (fdt_get_header(fdt, totalsize))#define fdt_off_dt_struct(fdt) (fdt_get_header(fdt, off_dt_struct))#define fdt_off_dt_strings(fdt) (fdt_get_header(fdt, off_dt_strings))#define fdt_off_mem_rsvmap(fdt) (fdt_get_header(fdt, off_mem_rsvmap))#define fdt_version(fdt) (fdt_get_header(fdt, version))#define fdt_last_comp_version(fdt) (fdt_get_header(fdt, last_comp_version))#define fdt_boot_cpuid_phys(fdt) (fdt_get_header(fdt, boot_cpuid_phys))#define fdt_size_dt_strings(fdt) (fdt_get_header(fdt, size_dt_strings))#define fdt_size_dt_struct(fdt) (fdt_get_header(fdt, size_dt_struct)) #define fdt_set_hdr_(name) \ static inline void fdt_set_##name(void *fdt, uint32_t val) \ { \ struct fdt_header *fdth = (struct fdt_header *)fdt; \ fdth->name = cpu_to_fdt32(val); \ }fdt_set_hdr_(magic)fdt_set_hdr_(totalsize)fdt_set_hdr_(off_dt_struct)fdt_set_hdr_(off_dt_strings)fdt_set_hdr_(off_mem_rsvmap)fdt_set_hdr_(version)fdt_set_hdr_(last_comp_version)fdt_set_hdr_(boot_cpuid_phys)fdt_set_hdr_(size_dt_strings)fdt_set_hdr_(size_dt_struct)#undef fdt_set_hdr_ /** * fdt_header_size - return the size of the tree's header * @fdt: pointer to a flattened device tree * * Return: size of DTB header in bytes */size_t fdt_header_size(const void *fdt); /** * fdt_header_size_ - internal function to get header size from a version number * @version: device tree version number * * Return: size of DTB header in bytes */size_t fdt_header_size_(uint32_t version); /** * fdt_check_header - sanity check a device tree header * @fdt: pointer to data which might be a flattened device tree * * fdt_check_header() checks that the given buffer contains what * appears to be a flattened device tree, and that the header contains * valid information (to the extent that can be determined from the * header alone). * * returns: * 0, if the buffer appears to contain a valid device tree * -FDT_ERR_BADMAGIC, * -FDT_ERR_BADVERSION, * -FDT_ERR_BADSTATE, * -FDT_ERR_TRUNCATED, standard meanings, as above */int fdt_check_header(const void *fdt); /** * fdt_move - move a device tree around in memory * @fdt: pointer to the device tree to move * @buf: pointer to memory where the device is to be moved * @bufsize: size of the memory space at buf * * fdt_move() relocates, if possible, the device tree blob located at * fdt to the buffer at buf of size bufsize. The buffer may overlap * with the existing device tree blob at fdt. Therefore, * fdt_move(fdt, fdt, fdt_totalsize(fdt)) * should always succeed. * * returns: * 0, on success * -FDT_ERR_NOSPACE, bufsize is insufficient to contain the device tree * -FDT_ERR_BADMAGIC, * -FDT_ERR_BADVERSION, * -FDT_ERR_BADSTATE, standard meanings */int fdt_move(const void *fdt, void *buf, int bufsize); /**********************************************************************//* Read-only functions *//**********************************************************************/ /** * fdt_check_full - check device tree validity * @fdt: pointer to the device tree blob * @bufsize: size of the buffer containing the device tree * * fdt_check_full() checks that the given buffer contains a valid * flattened device tree and that the tree structure is internally * consistent. This is a more thorough check than fdt_check_header(). * * returns: * 0, on success * -FDT_ERR_BADMAGIC, * -FDT_ERR_BADVERSION, * -FDT_ERR_BADSTATE, * -FDT_ERR_BADSTRUCTURE, * -FDT_ERR_TRUNCATED, standard meanings */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: pointer to the device tree blob * @stroffset: offset of the string within the strings block (native endian) * * fdt_string() retrieves a pointer to a single string from the * strings block of the device tree blob at fdt. * * 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_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: pointer to the device tree blob * * fdt_get_max_phandle retrieves the highest phandle in the given * device tree. This will ignore badly formatted phandles, or phandles * with a value of 0 or -1. * * This function is deprecated in favour of fdt_find_max_phandle(). * * returns: * the highest phandle on success * 0, if no phandle was found in the device tree * -1, if an error occurred */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. * * Return: 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: pointer to the device tree blob * * Returns the number of entries in the device tree blob's memory * reservation map. This does not include the terminating 0,0 entry * or any other (0,0) entries reserved for expansion. * * returns: * the number of entries */int fdt_num_mem_rsv(const void *fdt); /** * fdt_get_mem_rsv - retrieve one memory reserve map entry * @fdt: pointer to the device tree blob * @n: index of reserve map entry * @address: pointer to 64-bit variable to hold the start address * @size: pointer to 64-bit variable to hold the size of the entry * * On success, @address and @size will contain the address and size of * the n-th reserve map entry from the device tree blob, in * native-endian format. * * returns: * 0, on success * -FDT_ERR_BADMAGIC, * -FDT_ERR_BADVERSION, * -FDT_ERR_BADSTATE, standard meanings */int fdt_get_mem_rsv(const void *fdt, int n, uint64_t *address, uint64_t *size); Lines 1–500 of 2540. Load more
/* SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause) */ #ifndef LIBFDT_H #define LIBFDT_H /* * libfdt - Flat Device Tree manipulation * Copyright (C) 2006 David Gibson, IBM Corporation. */ #include "libfdt_env.h" #include "fdt.h" #ifdef __cplusplus extern "C" { #endif #define FDT_FIRST_SUPPORTED_VERSION 0x02 #define FDT_LAST_COMPATIBLE_VERSION 0x10 #define FDT_LAST_SUPPORTED_VERSION 0x11 /* Error codes: informative error codes */ #define FDT_ERR_NOTFOUND 1 /* FDT_ERR_NOTFOUND: The requested node or property does not exist */ #define FDT_ERR_EXISTS 2 /* FDT_ERR_EXISTS: Attempted to create a node or property which * already exists */ #define FDT_ERR_NOSPACE 3 /* FDT_ERR_NOSPACE: Operation needed to expand the device * tree, but its buffer did not have sufficient space to * contain the expanded tree. Use fdt_open_into() to move the * device tree to a buffer with more space. */ /* Error codes: codes for bad parameters */ #define FDT_ERR_BADOFFSET 4 /* FDT_ERR_BADOFFSET: Function was passed a structure block * offset which is out-of-bounds, or which points to an * unsuitable part of the structure for the operation. */ #define FDT_ERR_BADPATH 5 /* FDT_ERR_BADPATH: Function was passed a badly formatted path * (e.g. missing a leading / for a function which requires an * absolute path) */ #define FDT_ERR_BADPHANDLE 6 /* FDT_ERR_BADPHANDLE: Function was passed an invalid phandle. * This can be caused either by an invalid phandle property * length, or the phandle value was either 0 or -1, which are * not permitted. */ #define FDT_ERR_BADSTATE 7 /* FDT_ERR_BADSTATE: Function was passed an incomplete device * tree created by the sequential-write functions, which is * not sufficiently complete for the requested operation. */ /* Error codes: codes for bad device tree blobs */ #define FDT_ERR_TRUNCATED 8 /* FDT_ERR_TRUNCATED: FDT or a sub-block is improperly * terminated (overflows, goes outside allowed bounds, or * isn't properly terminated). */ #define FDT_ERR_BADMAGIC 9 /* FDT_ERR_BADMAGIC: Given "device tree" appears not to be a * device tree at all - it is missing the flattened device * tree magic number. */ #define FDT_ERR_BADVERSION 10 /* FDT_ERR_BADVERSION: Given device tree has a version which * can't be handled by the requested operation. For * read-write functions, this may mean that fdt_open_into() is * required to convert the tree to the expected version. */ #define FDT_ERR_BADSTRUCTURE 11 /* FDT_ERR_BADSTRUCTURE: Given device tree has a corrupt * structure block or other serious error (e.g. misnested * nodes, or subnodes preceding properties). */ #define FDT_ERR_BADLAYOUT 12 /* FDT_ERR_BADLAYOUT: For read-write functions, the given * device tree has it's sub-blocks in an order that the * function can't handle (memory reserve map, then structure, * then strings). Use fdt_open_into() to reorganize the tree * into a form suitable for the read-write operations. */ /* "Can't happen" error indicating a bug in libfdt */ #define FDT_ERR_INTERNAL 13 /* FDT_ERR_INTERNAL: libfdt has failed an internal assertion. * Should never be returned, if it is, it indicates a bug in * libfdt itself. */ /* Errors in device tree content */ #define FDT_ERR_BADNCELLS 14 /* FDT_ERR_BADNCELLS: Device tree has a #address-cells, #size-cells * or similar property with a bad format or value */ #define FDT_ERR_BADVALUE 15 /* FDT_ERR_BADVALUE: Device tree has a property with an unexpected * value. For example: a property expected to contain a string list * is not NUL-terminated within the length of its value. */ #define FDT_ERR_BADOVERLAY 16 /* FDT_ERR_BADOVERLAY: The device tree overlay, while * correctly structured, cannot be applied due to some * unexpected or missing value, property or node. */ #define FDT_ERR_NOPHANDLES 17 /* FDT_ERR_NOPHANDLES: The device tree doesn't have any * phandle available anymore without causing an overflow */ #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_ALIGNMENT 19 /* FDT_ERR_ALIGNMENT: The device tree base address is not 8-byte * aligned. */ #define FDT_ERR_MAX 19 /* constants */ #define FDT_MAX_PHANDLE 0xfffffffe /* Valid values for phandles range from 1 to 2^32-2. */ /**********************************************************************/ /* Low-level functions (you probably don't need these) */ /**********************************************************************/ /** * fdt_offset_ptr - safely get a byte range within the device tree blob * @fdt: Pointer to the device tree blob * @offset: Offset within the blob to the desired byte range * @checklen: Required length of the byte range * * fdt_offset_ptr() returns a pointer to the byte range of length @checklen at * the given @offset within the device tree blob, after verifying that the byte * range fits entirely within the blob and does not overflow. * * returns: * pointer to the byte range, on success * NULL, if the requested range does not fit within the blob */ #ifndef SWIG /* This function is not useful in Python */ const void *fdt_offset_ptr(const void *fdt, int offset, unsigned int checklen); #endif static inline void *fdt_offset_ptr_w(void *fdt, int offset, int checklen) { return (void *)(uintptr_t)fdt_offset_ptr(fdt, offset, checklen); } /** * fdt_next_tag - get next tag in the device tree * @fdt: Pointer to the device tree blob * @offset: Offset within the blob to start searching * @nextoffset: Pointer to variable to store the offset of the next tag * * fdt_next_tag() returns the tag type of the next tag in the device tree * blob starting from the given @offset. If @nextoffset is non-NULL, it will * be set to the offset immediately following the tag. * * returns: * the tag type (FDT_BEGIN_NODE, FDT_END_NODE, FDT_PROP, FDT_NOP, FDT_END), * FDT_END, if offset is out of bounds */ uint32_t fdt_next_tag(const void *fdt, int offset, int *nextoffset); /* * External helpers to access words from a device tree blob. They're built * to work even with unaligned pointers on platforms (such as ARMv5) that don't * like unaligned loads and stores. */ static inline uint16_t fdt16_ld(const fdt16_t *p) { const uint8_t *bp = (const uint8_t *)p; return ((uint16_t)bp[0] << 8) | bp[1]; } static inline uint32_t fdt32_ld(const fdt32_t *p) { 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 */ /**********************************************************************/ int fdt_next_node(const void *fdt, int offset, int *depth); /** * fdt_first_subnode() - get offset of first direct subnode * @fdt: FDT blob * @offset: Offset of node to check * * Return: offset of first subnode, or -FDT_ERR_NOTFOUND if there is none */ int fdt_first_subnode(const void *fdt, int offset); /** * fdt_next_subnode() - get offset of next direct subnode * @fdt: FDT blob * @offset: Offset of previous subnode * * After first calling fdt_first_subnode(), call this function repeatedly to * get direct subnodes of a parent node. * * Return: offset of next subnode, or -FDT_ERR_NOTFOUND if there are no more * subnodes */ int fdt_next_subnode(const void *fdt, int offset); /** * fdt_for_each_subnode - iterate over all subnodes of a parent * * @node: child node (int, lvalue) * @fdt: FDT blob (const void *) * @parent: parent node (int) * * This is actually a wrapper around a for loop and would be used like so: * * fdt_for_each_subnode(node, fdt, parent) { * Use node * ... * } * * if ((node < 0) && (node != -FDT_ERR_NOTFOUND)) { * Error handling * } * * Note that this is implemented as a macro and @node is used as * iterator in the loop. The parent variable be constant or even a * literal. */ #define fdt_for_each_subnode(node, fdt, parent) \ for (node = fdt_first_subnode(fdt, parent); \ node >= 0; \ node = fdt_next_subnode(fdt, node)) /**********************************************************************/ /* General functions */ /**********************************************************************/ #define fdt_get_header(fdt, field) \ (fdt32_ld(&((const struct fdt_header *)(fdt))->field)) #define fdt_magic(fdt) (fdt_get_header(fdt, magic)) #define fdt_totalsize(fdt) (fdt_get_header(fdt, totalsize)) #define fdt_off_dt_struct(fdt) (fdt_get_header(fdt, off_dt_struct)) #define fdt_off_dt_strings(fdt) (fdt_get_header(fdt, off_dt_strings)) #define fdt_off_mem_rsvmap(fdt) (fdt_get_header(fdt, off_mem_rsvmap)) #define fdt_version(fdt) (fdt_get_header(fdt, version)) #define fdt_last_comp_version(fdt) (fdt_get_header(fdt, last_comp_version)) #define fdt_boot_cpuid_phys(fdt) (fdt_get_header(fdt, boot_cpuid_phys)) #define fdt_size_dt_strings(fdt) (fdt_get_header(fdt, size_dt_strings)) #define fdt_size_dt_struct(fdt) (fdt_get_header(fdt, size_dt_struct)) #define fdt_set_hdr_(name) \ static inline void fdt_set_##name(void *fdt, uint32_t val) \ { \ struct fdt_header *fdth = (struct fdt_header *)fdt; \ fdth->name = cpu_to_fdt32(val); \ } fdt_set_hdr_(magic) fdt_set_hdr_(totalsize) fdt_set_hdr_(off_dt_struct) fdt_set_hdr_(off_dt_strings) fdt_set_hdr_(off_mem_rsvmap) fdt_set_hdr_(version) fdt_set_hdr_(last_comp_version) fdt_set_hdr_(boot_cpuid_phys) fdt_set_hdr_(size_dt_strings) fdt_set_hdr_(size_dt_struct) #undef fdt_set_hdr_ /** * fdt_header_size - return the size of the tree's header * @fdt: pointer to a flattened device tree * * Return: size of DTB header in bytes */ size_t fdt_header_size(const void *fdt); /** * fdt_header_size_ - internal function to get header size from a version number * @version: device tree version number * * Return: size of DTB header in bytes */ size_t fdt_header_size_(uint32_t version); /** * fdt_check_header - sanity check a device tree header * @fdt: pointer to data which might be a flattened device tree * * fdt_check_header() checks that the given buffer contains what * appears to be a flattened device tree, and that the header contains * valid information (to the extent that can be determined from the * header alone). * * returns: * 0, if the buffer appears to contain a valid device tree * -FDT_ERR_BADMAGIC, * -FDT_ERR_BADVERSION, * -FDT_ERR_BADSTATE, * -FDT_ERR_TRUNCATED, standard meanings, as above */ int fdt_check_header(const void *fdt); /** * fdt_move - move a device tree around in memory * @fdt: pointer to the device tree to move * @buf: pointer to memory where the device is to be moved * @bufsize: size of the memory space at buf * * fdt_move() relocates, if possible, the device tree blob located at * fdt to the buffer at buf of size bufsize. The buffer may overlap * with the existing device tree blob at fdt. Therefore, * fdt_move(fdt, fdt, fdt_totalsize(fdt)) * should always succeed. * * returns: * 0, on success * -FDT_ERR_NOSPACE, bufsize is insufficient to contain the device tree * -FDT_ERR_BADMAGIC, * -FDT_ERR_BADVERSION, * -FDT_ERR_BADSTATE, standard meanings */ int fdt_move(const void *fdt, void *buf, int bufsize); /**********************************************************************/ /* Read-only functions */ /**********************************************************************/ /** * fdt_check_full - check device tree validity * @fdt: pointer to the device tree blob * @bufsize: size of the buffer containing the device tree * * fdt_check_full() checks that the given buffer contains a valid * flattened device tree and that the tree structure is internally * consistent. This is a more thorough check than fdt_check_header(). * * returns: * 0, on success * -FDT_ERR_BADMAGIC, * -FDT_ERR_BADVERSION, * -FDT_ERR_BADSTATE, * -FDT_ERR_BADSTRUCTURE, * -FDT_ERR_TRUNCATED, standard meanings */ 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: pointer to the device tree blob * @stroffset: offset of the string within the strings block (native endian) * * fdt_string() retrieves a pointer to a single string from the * strings block of the device tree blob at fdt. * * 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_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: pointer to the device tree blob * * fdt_get_max_phandle retrieves the highest phandle in the given * device tree. This will ignore badly formatted phandles, or phandles * with a value of 0 or -1. * * This function is deprecated in favour of fdt_find_max_phandle(). * * returns: * the highest phandle on success * 0, if no phandle was found in the device tree * -1, if an error occurred */ 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. * * Return: 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: pointer to the device tree blob * * Returns the number of entries in the device tree blob's memory * reservation map. This does not include the terminating 0,0 entry * or any other (0,0) entries reserved for expansion. * * returns: * the number of entries */ int fdt_num_mem_rsv(const void *fdt); /** * fdt_get_mem_rsv - retrieve one memory reserve map entry * @fdt: pointer to the device tree blob * @n: index of reserve map entry * @address: pointer to 64-bit variable to hold the start address * @size: pointer to 64-bit variable to hold the size of the entry * * On success, @address and @size will contain the address and size of * the n-th reserve map entry from the device tree blob, in * native-endian format. * * returns: * 0, on success * -FDT_ERR_BADMAGIC, * -FDT_ERR_BADVERSION, * -FDT_ERR_BADSTATE, standard meanings */ int fdt_get_mem_rsv(const void *fdt, int n, uint64_t *address, uint64_t *size);