From 3e8576dd363fe516ceec1ddc4aff51bc5a3d4bd7 Mon Sep 17 00:00:00 2001 From: Olivier Martin Date: Wed, 12 Feb 2014 15:11:29 +0000 Subject: [PATCH] EmbeddedPkg/FdtLib: Updated libfdt to 1.4.0 Last commit from git://git.jdl.com/software/dtc.git: commit 65cc4d2748a2c2e6f27f1cf39e07a5dbabd80ebf Author: Jon Loeliger Date: Sat Jun 22 12:54:28 2013 -0500 Tag Version 1.4.0 Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Olivier Martin git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@15237 6f19259b-4bc3-4df7-8a09-765794883524 --- EmbeddedPkg/Include/fdt.h | 107 +++++++++++++++++-------- EmbeddedPkg/Include/libfdt.h | 70 ++++++++++++---- EmbeddedPkg/Include/libfdt_env.h | 12 ++- EmbeddedPkg/Library/FdtLib/fdt.c | 30 ++++++- EmbeddedPkg/Library/FdtLib/fdt_ro.c | 7 +- EmbeddedPkg/Library/FdtLib/fdt_rw.c | 4 +- EmbeddedPkg/Library/FdtLib/fdt_sw.c | 4 +- EmbeddedPkg/Library/FdtLib/fdt_wip.c | 2 +- EmbeddedPkg/Library/FdtLib/version.lds | 6 ++ 9 files changed, 176 insertions(+), 66 deletions(-) diff --git a/EmbeddedPkg/Include/fdt.h b/EmbeddedPkg/Include/fdt.h index 3b7c37102d..0187749f19 100644 --- a/EmbeddedPkg/Include/fdt.h +++ b/EmbeddedPkg/Include/fdt.h @@ -1,62 +1,99 @@ -/** @file -* -* Copyright (c) 2011-2012, ARM Limited. All rights reserved. -* -* This program and the accompanying materials -* are licensed and made available under the terms and conditions of the BSD License -* which accompanies this distribution. The full text of the license may be found at -* http://opensource.org/licenses/bsd-license.php -* -* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -* -**/ - #ifndef _FDT_H #define _FDT_H +/* + * libfdt - Flat Device Tree manipulation + * Copyright (C) 2006 David Gibson, IBM Corporation. + * 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 __ASSEMBLY__ struct fdt_header { - uint32_t magic; /* magic word FDT_MAGIC */ - uint32_t totalsize; /* total size of DT block */ - uint32_t off_dt_struct; /* offset to structure */ - uint32_t off_dt_strings; /* offset to strings */ - uint32_t off_mem_rsvmap; /* offset to memory reserve map */ - uint32_t version; /* format version */ - uint32_t last_comp_version; /* last compatible version */ + fdt32_t magic; /* magic word FDT_MAGIC */ + fdt32_t totalsize; /* total size of DT block */ + fdt32_t off_dt_struct; /* offset to structure */ + fdt32_t off_dt_strings; /* offset to strings */ + fdt32_t off_mem_rsvmap; /* offset to memory reserve map */ + fdt32_t version; /* format version */ + fdt32_t last_comp_version; /* last compatible version */ /* version 2 fields below */ - uint32_t boot_cpuid_phys; /* Which physical CPU id we're + fdt32_t boot_cpuid_phys; /* Which physical CPU id we're booting on */ /* version 3 fields below */ - uint32_t size_dt_strings; /* size of the strings block */ + fdt32_t size_dt_strings; /* size of the strings block */ /* version 17 fields below */ - uint32_t size_dt_struct; /* size of the structure block */ + fdt32_t size_dt_struct; /* size of the structure block */ }; struct fdt_reserve_entry { - uint64_t address; - uint64_t size; + fdt64_t address; + fdt64_t size; }; struct fdt_node_header { - uint32_t tag; + fdt32_t tag; char name[0]; }; struct fdt_property { - uint32_t tag; - uint32_t len; - uint32_t nameoff; + fdt32_t tag; + fdt32_t len; + fdt32_t nameoff; char data[0]; }; #endif /* !__ASSEMBLY */ #define FDT_MAGIC 0xd00dfeed /* 4: version, 4: total size */ -#define FDT_TAGSIZE sizeof(uint32_t) +#define FDT_TAGSIZE sizeof(fdt32_t) #define FDT_BEGIN_NODE 0x1 /* Start node: full name */ #define FDT_END_NODE 0x2 /* End node */ @@ -65,10 +102,10 @@ struct fdt_property { #define FDT_NOP 0x4 /* nop */ #define FDT_END 0x9 -#define FDT_V1_SIZE (7*sizeof(uint32_t)) -#define FDT_V2_SIZE (FDT_V1_SIZE + sizeof(uint32_t)) -#define FDT_V3_SIZE (FDT_V2_SIZE + sizeof(uint32_t)) +#define FDT_V1_SIZE (7*sizeof(fdt32_t)) +#define FDT_V2_SIZE (FDT_V1_SIZE + sizeof(fdt32_t)) +#define FDT_V3_SIZE (FDT_V2_SIZE + sizeof(fdt32_t)) #define FDT_V16_SIZE FDT_V3_SIZE -#define FDT_V17_SIZE (FDT_V16_SIZE + sizeof(uint32_t)) +#define FDT_V17_SIZE (FDT_V16_SIZE + sizeof(fdt32_t)) #endif /* _FDT_H */ diff --git a/EmbeddedPkg/Include/libfdt.h b/EmbeddedPkg/Include/libfdt.h index 85fe324c4d..212cb995df 100644 --- a/EmbeddedPkg/Include/libfdt.h +++ b/EmbeddedPkg/Include/libfdt.h @@ -136,6 +136,28 @@ uint32_t fdt_next_tag(const void *fdt, int offset, int *nextoffset); 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 + * + * After first calling fdt_first_subnode(), call this function repeatedly to + * get direct subnodes of a parent node. + * + * @fdt: FDT blob + * @offset: Offset of previous subnode + * @return offset of next subnode, or -FDT_ERR_NOTFOUND if there are no more + * subnodes + */ +int fdt_next_subnode(const void *fdt, int offset); + /**********************************************************************/ /* General functions */ /**********************************************************************/ @@ -582,7 +604,7 @@ const char *fdt_get_alias_namelen(const void *fdt, * value of the property named 'name' in the node /aliases. * * returns: - * a pointer to the expansion of the alias named 'name', of it exists + * a pointer to the expansion of the alias named 'name', if it exists * NULL, if the given alias or the /aliases node does not exist */ const char *fdt_get_alias(const void *fdt, const char *name); @@ -816,6 +838,20 @@ int fdt_node_check_compatible(const void *fdt, int nodeoffset, int fdt_node_offset_by_compatible(const void *fdt, int startoffset, const char *compatible); +/** + * fdt_stringlist_contains - check a string list property for a string + * @strlist: Property containing a list of strings to check + * @listlen: Length of property + * @str: String to search for + * + * This is a utility function provided for convenience. The list contains + * one or more strings, each terminated by \0, as is found in a device tree + * "compatible" property. + * + * @return: 1 if the string is found in the list, 0 not found, or invalid list + */ +int fdt_stringlist_contains(const char *strlist, int listlen, const char *str); + /**********************************************************************/ /* Write-in-place functions */ /**********************************************************************/ @@ -882,8 +918,8 @@ int fdt_setprop_inplace(void *fdt, int nodeoffset, const char *name, static inline int fdt_setprop_inplace_u32(void *fdt, int nodeoffset, const char *name, uint32_t val) { - val = cpu_to_fdt32(val); - return fdt_setprop_inplace(fdt, nodeoffset, name, &val, sizeof(val)); + fdt32_t tmp = cpu_to_fdt32(val); + return fdt_setprop_inplace(fdt, nodeoffset, name, &tmp, sizeof(tmp)); } /** @@ -917,8 +953,8 @@ static inline int fdt_setprop_inplace_u32(void *fdt, int nodeoffset, static inline int fdt_setprop_inplace_u64(void *fdt, int nodeoffset, const char *name, uint64_t val) { - val = cpu_to_fdt64(val); - return fdt_setprop_inplace(fdt, nodeoffset, name, &val, sizeof(val)); + fdt64_t tmp = cpu_to_fdt64(val); + return fdt_setprop_inplace(fdt, nodeoffset, name, &tmp, sizeof(tmp)); } /** @@ -993,13 +1029,13 @@ int fdt_begin_node(void *fdt, const char *name); int fdt_property(void *fdt, const char *name, const void *val, int len); static inline int fdt_property_u32(void *fdt, const char *name, uint32_t val) { - val = cpu_to_fdt32(val); - return fdt_property(fdt, name, &val, sizeof(val)); + fdt32_t tmp = cpu_to_fdt32(val); + return fdt_property(fdt, name, &tmp, sizeof(tmp)); } static inline int fdt_property_u64(void *fdt, const char *name, uint64_t val) { - val = cpu_to_fdt64(val); - return fdt_property(fdt, name, &val, sizeof(val)); + fdt64_t tmp = cpu_to_fdt64(val); + return fdt_property(fdt, name, &tmp, sizeof(tmp)); } static inline int fdt_property_cell(void *fdt, const char *name, uint32_t val) { @@ -1154,8 +1190,8 @@ int fdt_setprop(void *fdt, int nodeoffset, const char *name, static inline int fdt_setprop_u32(void *fdt, int nodeoffset, const char *name, uint32_t val) { - val = cpu_to_fdt32(val); - return fdt_setprop(fdt, nodeoffset, name, &val, sizeof(val)); + fdt32_t tmp = cpu_to_fdt32(val); + return fdt_setprop(fdt, nodeoffset, name, &tmp, sizeof(tmp)); } /** @@ -1189,8 +1225,8 @@ static inline int fdt_setprop_u32(void *fdt, int nodeoffset, const char *name, static inline int fdt_setprop_u64(void *fdt, int nodeoffset, const char *name, uint64_t val) { - val = cpu_to_fdt64(val); - return fdt_setprop(fdt, nodeoffset, name, &val, sizeof(val)); + fdt64_t tmp = cpu_to_fdt64(val); + return fdt_setprop(fdt, nodeoffset, name, &tmp, sizeof(tmp)); } /** @@ -1296,8 +1332,8 @@ int fdt_appendprop(void *fdt, int nodeoffset, const char *name, static inline int fdt_appendprop_u32(void *fdt, int nodeoffset, const char *name, uint32_t val) { - val = cpu_to_fdt32(val); - return fdt_appendprop(fdt, nodeoffset, name, &val, sizeof(val)); + fdt32_t tmp = cpu_to_fdt32(val); + return fdt_appendprop(fdt, nodeoffset, name, &tmp, sizeof(tmp)); } /** @@ -1331,8 +1367,8 @@ static inline int fdt_appendprop_u32(void *fdt, int nodeoffset, static inline int fdt_appendprop_u64(void *fdt, int nodeoffset, const char *name, uint64_t val) { - val = cpu_to_fdt64(val); - return fdt_appendprop(fdt, nodeoffset, name, &val, sizeof(val)); + fdt64_t tmp = cpu_to_fdt64(val); + return fdt_appendprop(fdt, nodeoffset, name, &tmp, sizeof(tmp)); } /** diff --git a/EmbeddedPkg/Include/libfdt_env.h b/EmbeddedPkg/Include/libfdt_env.h index 6cc311fe73..a8ab463493 100644 --- a/EmbeddedPkg/Include/libfdt_env.h +++ b/EmbeddedPkg/Include/libfdt_env.h @@ -1,6 +1,6 @@ /** @file * -* Copyright (c) 2011-2012, ARM Limited. All rights reserved. +* Copyright (c) 2011-2014, ARM Limited. All rights reserved. * * This program and the accompanying materials * are licensed and made available under the terms and conditions of the BSD License @@ -18,6 +18,10 @@ #include #include +typedef UINT16 fdt16_t; +typedef UINT32 fdt32_t; +typedef UINT64 fdt64_t; + typedef UINT8 uint8_t; typedef UINT16 uint16_t; typedef UINT32 uint32_t; @@ -25,19 +29,19 @@ typedef UINT64 uint64_t; typedef UINTN uintptr_t; typedef UINTN size_t; -static inline uint16_t fdt16_to_cpu(uint16_t x) +static inline uint16_t fdt16_to_cpu(fdt16_t x) { return SwapBytes16 (x); } #define cpu_to_fdt16(x) fdt16_to_cpu(x) -static inline uint32_t fdt32_to_cpu(uint32_t x) +static inline uint32_t fdt32_to_cpu(fdt32_t x) { return SwapBytes32 (x); } #define cpu_to_fdt32(x) fdt32_to_cpu(x) -static inline uint64_t fdt64_to_cpu(uint64_t x) +static inline uint64_t fdt64_to_cpu(fdt64_t x) { return SwapBytes64 (x); } diff --git a/EmbeddedPkg/Library/FdtLib/fdt.c b/EmbeddedPkg/Library/FdtLib/fdt.c index 151fcb2ab0..963952820b 100644 --- a/EmbeddedPkg/Library/FdtLib/fdt.c +++ b/EmbeddedPkg/Library/FdtLib/fdt.c @@ -92,7 +92,7 @@ const void *fdt_offset_ptr(const void *fdt, int offset, unsigned int len) uint32_t fdt_next_tag(const void *fdt, int startoffset, int *nextoffset) { - const uint32_t *tagp, *lenp; + const fdt32_t *tagp, *lenp; uint32_t tag; int offset = startoffset; const char *p; @@ -198,6 +198,34 @@ int fdt_next_node(const void *fdt, int offset, int *depth) return offset; } +int fdt_first_subnode(const void *fdt, int offset) +{ + int depth = 0; + + offset = fdt_next_node(fdt, offset, &depth); + if (offset < 0 || depth != 1) + return -FDT_ERR_NOTFOUND; + + return offset; +} + +int fdt_next_subnode(const void *fdt, int offset) +{ + int depth = 1; + + /* + * With respect to the parent, the depth of the next subnode will be + * the same as the last. + */ + do { + offset = fdt_next_node(fdt, offset, &depth); + if (offset < 0 || depth < 1) + return -FDT_ERR_NOTFOUND; + } while (depth > 1); + + return offset; +} + const char *_fdt_find_string(const char *strtab, int tabsize, const char *s) { int len = strlen(s) + 1; diff --git a/EmbeddedPkg/Library/FdtLib/fdt_ro.c b/EmbeddedPkg/Library/FdtLib/fdt_ro.c index 9ae6b5ecc5..2055891e71 100644 --- a/EmbeddedPkg/Library/FdtLib/fdt_ro.c +++ b/EmbeddedPkg/Library/FdtLib/fdt_ro.c @@ -323,7 +323,7 @@ const void *fdt_getprop(const void *fdt, int nodeoffset, uint32_t fdt_get_phandle(const void *fdt, int nodeoffset) { - const uint32_t *php; + const fdt32_t *php; int len; /* FIXME: This is a bit sub-optimal, since we potentially scan @@ -516,8 +516,7 @@ int fdt_node_offset_by_phandle(const void *fdt, uint32_t phandle) return offset; /* error from fdt_next_node() */ } -static int _fdt_stringlist_contains(const char *strlist, int listlen, - const char *str) +int fdt_stringlist_contains(const char *strlist, int listlen, const char *str) { int len = strlen(str); const char *p; @@ -543,7 +542,7 @@ int fdt_node_check_compatible(const void *fdt, int nodeoffset, prop = fdt_getprop(fdt, nodeoffset, "compatible", &len); if (!prop) return len; - if (_fdt_stringlist_contains(prop, len, compatible)) + if (fdt_stringlist_contains(prop, len, compatible)) return 0; else return 1; diff --git a/EmbeddedPkg/Library/FdtLib/fdt_rw.c b/EmbeddedPkg/Library/FdtLib/fdt_rw.c index 1d95a73ec1..7a2bcf3d07 100644 --- a/EmbeddedPkg/Library/FdtLib/fdt_rw.c +++ b/EmbeddedPkg/Library/FdtLib/fdt_rw.c @@ -342,7 +342,7 @@ int fdt_add_subnode_namelen(void *fdt, int parentoffset, int nodelen; int err; uint32_t tag; - uint32_t *endtag; + fdt32_t *endtag; FDT_RW_CHECK_HEADER(fdt); @@ -369,7 +369,7 @@ int fdt_add_subnode_namelen(void *fdt, int parentoffset, nh->tag = cpu_to_fdt32(FDT_BEGIN_NODE); memset(nh->name, 0, FDT_TAGALIGN(namelen+1)); memcpy(nh->name, name, namelen); - endtag = (uint32_t *)((char *)nh + nodelen - FDT_TAGSIZE); + endtag = (fdt32_t *)((char *)nh + nodelen - FDT_TAGSIZE); *endtag = cpu_to_fdt32(FDT_END_NODE); return offset; diff --git a/EmbeddedPkg/Library/FdtLib/fdt_sw.c b/EmbeddedPkg/Library/FdtLib/fdt_sw.c index 240fabc554..991919b436 100644 --- a/EmbeddedPkg/Library/FdtLib/fdt_sw.c +++ b/EmbeddedPkg/Library/FdtLib/fdt_sw.c @@ -153,7 +153,7 @@ int fdt_begin_node(void *fdt, const char *name) int fdt_end_node(void *fdt) { - uint32_t *en; + fdt32_t *en; FDT_SW_CHECK_HEADER(fdt); @@ -213,7 +213,7 @@ int fdt_property(void *fdt, const char *name, const void *val, int len) int fdt_finish(void *fdt) { char *p = (char *)fdt; - uint32_t *end; + fdt32_t *end; int oldstroffset, newstroffset; uint32_t tag; int offset, nextoffset; diff --git a/EmbeddedPkg/Library/FdtLib/fdt_wip.c b/EmbeddedPkg/Library/FdtLib/fdt_wip.c index e009a88f51..3f2b58172b 100644 --- a/EmbeddedPkg/Library/FdtLib/fdt_wip.c +++ b/EmbeddedPkg/Library/FdtLib/fdt_wip.c @@ -74,7 +74,7 @@ int fdt_setprop_inplace(void *fdt, int nodeoffset, const char *name, static void _fdt_nop_region(void *start, int len) { - uint32_t *p; + fdt32_t *p; for (p = start; (char *)p < ((char *)start + len); p++) *p = cpu_to_fdt32(FDT_NOP); diff --git a/EmbeddedPkg/Library/FdtLib/version.lds b/EmbeddedPkg/Library/FdtLib/version.lds index 3c3994e27f..80b322bed6 100644 --- a/EmbeddedPkg/Library/FdtLib/version.lds +++ b/EmbeddedPkg/Library/FdtLib/version.lds @@ -48,6 +48,12 @@ LIBFDT_1.2 { 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: *; -- 2.39.2