-/** @file\r
-*\r
-* Copyright (c) 2011-2012, ARM Limited. All rights reserved.\r
-* \r
-* This program and the accompanying materials \r
-* are licensed and made available under the terms and conditions of the BSD License \r
-* which accompanies this distribution. The full text of the license may be found at \r
-* http://opensource.org/licenses/bsd-license.php \r
-*\r
-* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
-* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r
-*\r
-**/\r
-\r
#ifndef _FDT_H\r
#define _FDT_H\r
+/*\r
+ * libfdt - Flat Device Tree manipulation\r
+ * Copyright (C) 2006 David Gibson, IBM Corporation.\r
+ * Copyright 2012 Kim Phillips, Freescale Semiconductor.\r
+ *\r
+ * libfdt is dual licensed: you can use it either under the terms of\r
+ * the GPL, or the BSD license, at your option.\r
+ *\r
+ * a) This library is free software; you can redistribute it and/or\r
+ * modify it under the terms of the GNU General Public License as\r
+ * published by the Free Software Foundation; either version 2 of the\r
+ * License, or (at your option) any later version.\r
+ *\r
+ * This library is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public\r
+ * License along with this library; if not, write to the Free\r
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,\r
+ * MA 02110-1301 USA\r
+ *\r
+ * Alternatively,\r
+ *\r
+ * b) Redistribution and use in source and binary forms, with or\r
+ * without modification, are permitted provided that the following\r
+ * conditions are met:\r
+ *\r
+ * 1. Redistributions of source code must retain the above\r
+ * copyright notice, this list of conditions and the following\r
+ * disclaimer.\r
+ * 2. Redistributions in binary form must reproduce the above\r
+ * copyright notice, this list of conditions and the following\r
+ * disclaimer in the documentation and/or other materials\r
+ * provided with the distribution.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND\r
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,\r
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\r
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\r
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR\r
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\r
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\r
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\r
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\r
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\r
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR\r
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,\r
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
+ */\r
\r
#ifndef __ASSEMBLY__\r
\r
struct fdt_header {\r
- uint32_t magic; /* magic word FDT_MAGIC */\r
- uint32_t totalsize; /* total size of DT block */\r
- uint32_t off_dt_struct; /* offset to structure */\r
- uint32_t off_dt_strings; /* offset to strings */\r
- uint32_t off_mem_rsvmap; /* offset to memory reserve map */\r
- uint32_t version; /* format version */\r
- uint32_t last_comp_version; /* last compatible version */\r
+ fdt32_t magic; /* magic word FDT_MAGIC */\r
+ fdt32_t totalsize; /* total size of DT block */\r
+ fdt32_t off_dt_struct; /* offset to structure */\r
+ fdt32_t off_dt_strings; /* offset to strings */\r
+ fdt32_t off_mem_rsvmap; /* offset to memory reserve map */\r
+ fdt32_t version; /* format version */\r
+ fdt32_t last_comp_version; /* last compatible version */\r
\r
/* version 2 fields below */\r
- uint32_t boot_cpuid_phys; /* Which physical CPU id we're\r
+ fdt32_t boot_cpuid_phys; /* Which physical CPU id we're\r
booting on */\r
/* version 3 fields below */\r
- uint32_t size_dt_strings; /* size of the strings block */\r
+ fdt32_t size_dt_strings; /* size of the strings block */\r
\r
/* version 17 fields below */\r
- uint32_t size_dt_struct; /* size of the structure block */\r
+ fdt32_t size_dt_struct; /* size of the structure block */\r
};\r
\r
struct fdt_reserve_entry {\r
- uint64_t address;\r
- uint64_t size;\r
+ fdt64_t address;\r
+ fdt64_t size;\r
};\r
\r
struct fdt_node_header {\r
- uint32_t tag;\r
+ fdt32_t tag;\r
char name[0];\r
};\r
\r
struct fdt_property {\r
- uint32_t tag;\r
- uint32_t len;\r
- uint32_t nameoff;\r
+ fdt32_t tag;\r
+ fdt32_t len;\r
+ fdt32_t nameoff;\r
char data[0];\r
};\r
\r
#endif /* !__ASSEMBLY */\r
\r
#define FDT_MAGIC 0xd00dfeed /* 4: version, 4: total size */\r
-#define FDT_TAGSIZE sizeof(uint32_t)\r
+#define FDT_TAGSIZE sizeof(fdt32_t)\r
\r
#define FDT_BEGIN_NODE 0x1 /* Start node: full name */\r
#define FDT_END_NODE 0x2 /* End node */\r
#define FDT_NOP 0x4 /* nop */\r
#define FDT_END 0x9\r
\r
-#define FDT_V1_SIZE (7*sizeof(uint32_t))\r
-#define FDT_V2_SIZE (FDT_V1_SIZE + sizeof(uint32_t))\r
-#define FDT_V3_SIZE (FDT_V2_SIZE + sizeof(uint32_t))\r
+#define FDT_V1_SIZE (7*sizeof(fdt32_t))\r
+#define FDT_V2_SIZE (FDT_V1_SIZE + sizeof(fdt32_t))\r
+#define FDT_V3_SIZE (FDT_V2_SIZE + sizeof(fdt32_t))\r
#define FDT_V16_SIZE FDT_V3_SIZE\r
-#define FDT_V17_SIZE (FDT_V16_SIZE + sizeof(uint32_t))\r
+#define FDT_V17_SIZE (FDT_V16_SIZE + sizeof(fdt32_t))\r
\r
#endif /* _FDT_H */\r
\r
int fdt_next_node(const void *fdt, int offset, int *depth);\r
\r
+/**\r
+ * fdt_first_subnode() - get offset of first direct subnode\r
+ *\r
+ * @fdt: FDT blob\r
+ * @offset: Offset of node to check\r
+ * @return offset of first subnode, or -FDT_ERR_NOTFOUND if there is none\r
+ */\r
+int fdt_first_subnode(const void *fdt, int offset);\r
+\r
+/**\r
+ * fdt_next_subnode() - get offset of next direct subnode\r
+ *\r
+ * After first calling fdt_first_subnode(), call this function repeatedly to\r
+ * get direct subnodes of a parent node.\r
+ *\r
+ * @fdt: FDT blob\r
+ * @offset: Offset of previous subnode\r
+ * @return offset of next subnode, or -FDT_ERR_NOTFOUND if there are no more\r
+ * subnodes\r
+ */\r
+int fdt_next_subnode(const void *fdt, int offset);\r
+\r
/**********************************************************************/\r
/* General functions */\r
/**********************************************************************/\r
* value of the property named 'name' in the node /aliases.\r
*\r
* returns:\r
- * a pointer to the expansion of the alias named 'name', of it exists\r
+ * a pointer to the expansion of the alias named 'name', if it exists\r
* NULL, if the given alias or the /aliases node does not exist\r
*/\r
const char *fdt_get_alias(const void *fdt, const char *name);\r
int fdt_node_offset_by_compatible(const void *fdt, int startoffset,\r
const char *compatible);\r
\r
+/**\r
+ * fdt_stringlist_contains - check a string list property for a string\r
+ * @strlist: Property containing a list of strings to check\r
+ * @listlen: Length of property\r
+ * @str: String to search for\r
+ *\r
+ * This is a utility function provided for convenience. The list contains\r
+ * one or more strings, each terminated by \0, as is found in a device tree\r
+ * "compatible" property.\r
+ *\r
+ * @return: 1 if the string is found in the list, 0 not found, or invalid list\r
+ */\r
+int fdt_stringlist_contains(const char *strlist, int listlen, const char *str);\r
+\r
/**********************************************************************/\r
/* Write-in-place functions */\r
/**********************************************************************/\r
static inline int fdt_setprop_inplace_u32(void *fdt, int nodeoffset,\r
const char *name, uint32_t val)\r
{\r
- val = cpu_to_fdt32(val);\r
- return fdt_setprop_inplace(fdt, nodeoffset, name, &val, sizeof(val));\r
+ fdt32_t tmp = cpu_to_fdt32(val);\r
+ return fdt_setprop_inplace(fdt, nodeoffset, name, &tmp, sizeof(tmp));\r
}\r
\r
/**\r
static inline int fdt_setprop_inplace_u64(void *fdt, int nodeoffset,\r
const char *name, uint64_t val)\r
{\r
- val = cpu_to_fdt64(val);\r
- return fdt_setprop_inplace(fdt, nodeoffset, name, &val, sizeof(val));\r
+ fdt64_t tmp = cpu_to_fdt64(val);\r
+ return fdt_setprop_inplace(fdt, nodeoffset, name, &tmp, sizeof(tmp));\r
}\r
\r
/**\r
int fdt_property(void *fdt, const char *name, const void *val, int len);\r
static inline int fdt_property_u32(void *fdt, const char *name, uint32_t val)\r
{\r
- val = cpu_to_fdt32(val);\r
- return fdt_property(fdt, name, &val, sizeof(val));\r
+ fdt32_t tmp = cpu_to_fdt32(val);\r
+ return fdt_property(fdt, name, &tmp, sizeof(tmp));\r
}\r
static inline int fdt_property_u64(void *fdt, const char *name, uint64_t val)\r
{\r
- val = cpu_to_fdt64(val);\r
- return fdt_property(fdt, name, &val, sizeof(val));\r
+ fdt64_t tmp = cpu_to_fdt64(val);\r
+ return fdt_property(fdt, name, &tmp, sizeof(tmp));\r
}\r
static inline int fdt_property_cell(void *fdt, const char *name, uint32_t val)\r
{\r
static inline int fdt_setprop_u32(void *fdt, int nodeoffset, const char *name,\r
uint32_t val)\r
{\r
- val = cpu_to_fdt32(val);\r
- return fdt_setprop(fdt, nodeoffset, name, &val, sizeof(val));\r
+ fdt32_t tmp = cpu_to_fdt32(val);\r
+ return fdt_setprop(fdt, nodeoffset, name, &tmp, sizeof(tmp));\r
}\r
\r
/**\r
static inline int fdt_setprop_u64(void *fdt, int nodeoffset, const char *name,\r
uint64_t val)\r
{\r
- val = cpu_to_fdt64(val);\r
- return fdt_setprop(fdt, nodeoffset, name, &val, sizeof(val));\r
+ fdt64_t tmp = cpu_to_fdt64(val);\r
+ return fdt_setprop(fdt, nodeoffset, name, &tmp, sizeof(tmp));\r
}\r
\r
/**\r
static inline int fdt_appendprop_u32(void *fdt, int nodeoffset,\r
const char *name, uint32_t val)\r
{\r
- val = cpu_to_fdt32(val);\r
- return fdt_appendprop(fdt, nodeoffset, name, &val, sizeof(val));\r
+ fdt32_t tmp = cpu_to_fdt32(val);\r
+ return fdt_appendprop(fdt, nodeoffset, name, &tmp, sizeof(tmp));\r
}\r
\r
/**\r
static inline int fdt_appendprop_u64(void *fdt, int nodeoffset,\r
const char *name, uint64_t val)\r
{\r
- val = cpu_to_fdt64(val);\r
- return fdt_appendprop(fdt, nodeoffset, name, &val, sizeof(val));\r
+ fdt64_t tmp = cpu_to_fdt64(val);\r
+ return fdt_appendprop(fdt, nodeoffset, name, &tmp, sizeof(tmp));\r
}\r
\r
/**\r
/** @file\r
*\r
-* Copyright (c) 2011-2012, ARM Limited. All rights reserved.\r
+* Copyright (c) 2011-2014, ARM Limited. All rights reserved.\r
* \r
* This program and the accompanying materials \r
* are licensed and made available under the terms and conditions of the BSD License \r
#include <Library/BaseLib.h>\r
#include <Library/BaseMemoryLib.h>\r
\r
+typedef UINT16 fdt16_t;\r
+typedef UINT32 fdt32_t;\r
+typedef UINT64 fdt64_t;\r
+\r
typedef UINT8 uint8_t;\r
typedef UINT16 uint16_t;\r
typedef UINT32 uint32_t;\r
typedef UINTN uintptr_t;\r
typedef UINTN size_t;\r
\r
-static inline uint16_t fdt16_to_cpu(uint16_t x)\r
+static inline uint16_t fdt16_to_cpu(fdt16_t x)\r
{\r
return SwapBytes16 (x);\r
}\r
#define cpu_to_fdt16(x) fdt16_to_cpu(x)\r
\r
-static inline uint32_t fdt32_to_cpu(uint32_t x)\r
+static inline uint32_t fdt32_to_cpu(fdt32_t x)\r
{\r
return SwapBytes32 (x);\r
}\r
#define cpu_to_fdt32(x) fdt32_to_cpu(x)\r
\r
-static inline uint64_t fdt64_to_cpu(uint64_t x)\r
+static inline uint64_t fdt64_to_cpu(fdt64_t x)\r
{\r
return SwapBytes64 (x);\r
}\r
\r
uint32_t fdt_next_tag(const void *fdt, int startoffset, int *nextoffset)\r
{\r
- const uint32_t *tagp, *lenp;\r
+ const fdt32_t *tagp, *lenp;\r
uint32_t tag;\r
int offset = startoffset;\r
const char *p;\r
return offset;\r
}\r
\r
+int fdt_first_subnode(const void *fdt, int offset)\r
+{\r
+ int depth = 0;\r
+\r
+ offset = fdt_next_node(fdt, offset, &depth);\r
+ if (offset < 0 || depth != 1)\r
+ return -FDT_ERR_NOTFOUND;\r
+\r
+ return offset;\r
+}\r
+\r
+int fdt_next_subnode(const void *fdt, int offset)\r
+{\r
+ int depth = 1;\r
+\r
+ /*\r
+ * With respect to the parent, the depth of the next subnode will be\r
+ * the same as the last.\r
+ */\r
+ do {\r
+ offset = fdt_next_node(fdt, offset, &depth);\r
+ if (offset < 0 || depth < 1)\r
+ return -FDT_ERR_NOTFOUND;\r
+ } while (depth > 1);\r
+\r
+ return offset;\r
+}\r
+\r
const char *_fdt_find_string(const char *strtab, int tabsize, const char *s)\r
{\r
int len = strlen(s) + 1;\r
\r
uint32_t fdt_get_phandle(const void *fdt, int nodeoffset)\r
{\r
- const uint32_t *php;\r
+ const fdt32_t *php;\r
int len;\r
\r
/* FIXME: This is a bit sub-optimal, since we potentially scan\r
return offset; /* error from fdt_next_node() */\r
}\r
\r
-static int _fdt_stringlist_contains(const char *strlist, int listlen,\r
- const char *str)\r
+int fdt_stringlist_contains(const char *strlist, int listlen, const char *str)\r
{\r
int len = strlen(str);\r
const char *p;\r
prop = fdt_getprop(fdt, nodeoffset, "compatible", &len);\r
if (!prop)\r
return len;\r
- if (_fdt_stringlist_contains(prop, len, compatible))\r
+ if (fdt_stringlist_contains(prop, len, compatible))\r
return 0;\r
else\r
return 1;\r
int nodelen;\r
int err;\r
uint32_t tag;\r
- uint32_t *endtag;\r
+ fdt32_t *endtag;\r
\r
FDT_RW_CHECK_HEADER(fdt);\r
\r
nh->tag = cpu_to_fdt32(FDT_BEGIN_NODE);\r
memset(nh->name, 0, FDT_TAGALIGN(namelen+1));\r
memcpy(nh->name, name, namelen);\r
- endtag = (uint32_t *)((char *)nh + nodelen - FDT_TAGSIZE);\r
+ endtag = (fdt32_t *)((char *)nh + nodelen - FDT_TAGSIZE);\r
*endtag = cpu_to_fdt32(FDT_END_NODE);\r
\r
return offset;\r
\r
int fdt_end_node(void *fdt)\r
{\r
- uint32_t *en;\r
+ fdt32_t *en;\r
\r
FDT_SW_CHECK_HEADER(fdt);\r
\r
int fdt_finish(void *fdt)\r
{\r
char *p = (char *)fdt;\r
- uint32_t *end;\r
+ fdt32_t *end;\r
int oldstroffset, newstroffset;\r
uint32_t tag;\r
int offset, nextoffset;\r
\r
static void _fdt_nop_region(void *start, int len)\r
{\r
- uint32_t *p;\r
+ fdt32_t *p;\r
\r
for (p = start; (char *)p < ((char *)start + len); p++)\r
*p = cpu_to_fdt32(FDT_NOP);\r
fdt_strerror;
fdt_offset_ptr;
fdt_next_tag;
+ fdt_appendprop;
+ fdt_create_empty_tree;
+ fdt_first_property_offset;
+ fdt_get_property_by_offset;
+ fdt_getprop_by_offset;
+ fdt_next_property_offset;
local:
*;