Commit 0de71d507157c4bd4fddcd3a419140d2b986eed2

Authored by Peter Tyser
Committed by Wolfgang Denk
1 parent 78acc472d9

Move libfdt/ into lib/

Move the libfdt directory into the common lib/ directory to clean up the
top-level directory.

Signed-off-by: Peter Tyser <ptyser@xes-inc.com>

Showing 21 changed files with 1844 additions and 1844 deletions Side-by-side Diff

... ... @@ -244,7 +244,7 @@
244 244 LIBS += drivers/video/libvideo.a
245 245 LIBS += drivers/watchdog/libwatchdog.a
246 246 LIBS += common/libcommon.a
247   -LIBS += libfdt/libfdt.a
  247 +LIBS += lib/libfdt/libfdt.a
248 248 LIBS += api/libapi.a
249 249 LIBS += post/libpost.a
250 250  
  1 +#
  2 +# (C) Copyright 2000-2007
  3 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
  4 +#
  5 +# See file CREDITS for list of people who contributed to this
  6 +# project.
  7 +#
  8 +# This program is free software; you can redistribute it and/or
  9 +# modify it under the terms of the GNU General Public License as
  10 +# published by the Free Software Foundation; either version 2 of
  11 +# the License, or (at your option) any later version.
  12 +#
  13 +# This program is distributed in the hope that it will be useful,
  14 +# but WITHOUT ANY WARRANTY; without even the implied warranty of
  15 +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16 +# GNU General Public License for more details.
  17 +#
  18 +# You should have received a copy of the GNU General Public License
  19 +# along with this program; if not, write to the Free Software
  20 +# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  21 +# MA 02111-1307 USA
  22 +#
  23 +
  24 +include $(TOPDIR)/config.mk
  25 +
  26 +LIB = $(obj)libfdt.a
  27 +
  28 +SOBJS =
  29 +
  30 +COBJS-libfdt += fdt.o fdt_ro.o fdt_rw.o fdt_strerror.o fdt_sw.o fdt_wip.o
  31 +
  32 +COBJS-$(CONFIG_OF_LIBFDT) += $(COBJS-libfdt)
  33 +COBJS-$(CONFIG_FIT) += $(COBJS-libfdt)
  34 +
  35 +
  36 +COBJS := $(sort $(COBJS-y))
  37 +SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c)
  38 +OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS))
  39 +
  40 +$(LIB): $(obj).depend $(OBJS)
  41 + $(AR) $(ARFLAGS) $@ $(OBJS)
  42 +
  43 +#########################################################################
  44 +
  45 +# defines $(obj).depend target
  46 +include $(SRCTREE)/rules.mk
  47 +
  48 +sinclude $(obj).depend
  49 +
  50 +#########################################################################
  1 +The libfdt functionality was written by David Gibson. The original
  2 +source came from the git repository:
  3 +
  4 +URL: git://ozlabs.org/home/dgibson/git/libfdt.git
  5 +
  6 +author David Gibson <dgibson@sneetch.(none)>
  7 + Fri, 23 Mar 2007 04:16:54 +0000 (15:16 +1100)
  8 +committer David Gibson <dgibson@sneetch.(none)>
  9 + Fri, 23 Mar 2007 04:16:54 +0000 (15:16 +1100)
  10 +commit 857f54e79f74429af20c2b5ecc00ee98af6a3b8b
  11 +tree 2f648f0f88225a51ded452968d28b4402df8ade0
  12 +parent 07a12a08005f3b5cd9337900a6551e450c07b515
  13 +
  14 +To adapt for u-boot usage, only the applicable files were copied and
  15 +imported into the u-boot git repository.
  16 +Omitted:
  17 +* GPL - u-boot comes with a copy of the GPL license
  18 +* test subdirectory - not directly useful for u-boot
  19 +
  20 +After importing, other customizations were performed. See the git log
  21 +for details.
  22 +
  23 +Jerry Van Baren
  1 +/*
  2 + * libfdt - Flat Device Tree manipulation
  3 + * Copyright (C) 2006 David Gibson, IBM Corporation.
  4 + *
  5 + * libfdt is dual licensed: you can use it either under the terms of
  6 + * the GPL, or the BSD license, at your option.
  7 + *
  8 + * a) This library is free software; you can redistribute it and/or
  9 + * modify it under the terms of the GNU General Public License as
  10 + * published by the Free Software Foundation; either version 2 of the
  11 + * License, or (at your option) any later version.
  12 + *
  13 + * This library is distributed in the hope that it will be useful,
  14 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16 + * GNU General Public License for more details.
  17 + *
  18 + * You should have received a copy of the GNU General Public
  19 + * License along with this library; if not, write to the Free
  20 + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
  21 + * MA 02110-1301 USA
  22 + *
  23 + * Alternatively,
  24 + *
  25 + * b) Redistribution and use in source and binary forms, with or
  26 + * without modification, are permitted provided that the following
  27 + * conditions are met:
  28 + *
  29 + * 1. Redistributions of source code must retain the above
  30 + * copyright notice, this list of conditions and the following
  31 + * disclaimer.
  32 + * 2. Redistributions in binary form must reproduce the above
  33 + * copyright notice, this list of conditions and the following
  34 + * disclaimer in the documentation and/or other materials
  35 + * provided with the distribution.
  36 + *
  37 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
  38 + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
  39 + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
  40 + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  41 + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
  42 + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  43 + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  44 + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  45 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  46 + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  47 + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
  48 + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
  49 + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  50 + */
  51 +#include "libfdt_env.h"
  52 +
  53 +#ifndef USE_HOSTCC
  54 +#include <fdt.h>
  55 +#include <libfdt.h>
  56 +#else
  57 +#include "fdt_host.h"
  58 +#endif
  59 +
  60 +#include "libfdt_internal.h"
  61 +
  62 +int fdt_check_header(const void *fdt)
  63 +{
  64 + if (fdt_magic(fdt) == FDT_MAGIC) {
  65 + /* Complete tree */
  66 + if (fdt_version(fdt) < FDT_FIRST_SUPPORTED_VERSION)
  67 + return -FDT_ERR_BADVERSION;
  68 + if (fdt_last_comp_version(fdt) > FDT_LAST_SUPPORTED_VERSION)
  69 + return -FDT_ERR_BADVERSION;
  70 + } else if (fdt_magic(fdt) == FDT_SW_MAGIC) {
  71 + /* Unfinished sequential-write blob */
  72 + if (fdt_size_dt_struct(fdt) == 0)
  73 + return -FDT_ERR_BADSTATE;
  74 + } else {
  75 + return -FDT_ERR_BADMAGIC;
  76 + }
  77 +
  78 + return 0;
  79 +}
  80 +
  81 +const void *fdt_offset_ptr(const void *fdt, int offset, unsigned int len)
  82 +{
  83 + const char *p;
  84 +
  85 + if (fdt_version(fdt) >= 0x11)
  86 + if (((offset + len) < offset)
  87 + || ((offset + len) > fdt_size_dt_struct(fdt)))
  88 + return NULL;
  89 +
  90 + p = _fdt_offset_ptr(fdt, offset);
  91 +
  92 + if (p + len < p)
  93 + return NULL;
  94 + return p;
  95 +}
  96 +
  97 +uint32_t fdt_next_tag(const void *fdt, int startoffset, int *nextoffset)
  98 +{
  99 + const uint32_t *tagp, *lenp;
  100 + uint32_t tag;
  101 + int offset = startoffset;
  102 + const char *p;
  103 +
  104 + *nextoffset = -FDT_ERR_TRUNCATED;
  105 + tagp = fdt_offset_ptr(fdt, offset, FDT_TAGSIZE);
  106 + if (!tagp)
  107 + return FDT_END; /* premature end */
  108 + tag = fdt32_to_cpu(*tagp);
  109 + offset += FDT_TAGSIZE;
  110 +
  111 + *nextoffset = -FDT_ERR_BADSTRUCTURE;
  112 + switch (tag) {
  113 + case FDT_BEGIN_NODE:
  114 + /* skip name */
  115 + do {
  116 + p = fdt_offset_ptr(fdt, offset++, 1);
  117 + } while (p && (*p != '\0'));
  118 + if (!p)
  119 + return FDT_END; /* premature end */
  120 + break;
  121 +
  122 + case FDT_PROP:
  123 + lenp = fdt_offset_ptr(fdt, offset, sizeof(*lenp));
  124 + if (!lenp)
  125 + return FDT_END; /* premature end */
  126 + /* skip-name offset, length and value */
  127 + offset += sizeof(struct fdt_property) - FDT_TAGSIZE
  128 + + fdt32_to_cpu(*lenp);
  129 + break;
  130 +
  131 + case FDT_END:
  132 + case FDT_END_NODE:
  133 + case FDT_NOP:
  134 + break;
  135 +
  136 + default:
  137 + return FDT_END;
  138 + }
  139 +
  140 + if (!fdt_offset_ptr(fdt, startoffset, offset - startoffset))
  141 + return FDT_END; /* premature end */
  142 +
  143 + *nextoffset = FDT_TAGALIGN(offset);
  144 + return tag;
  145 +}
  146 +
  147 +int _fdt_check_node_offset(const void *fdt, int offset)
  148 +{
  149 + if ((offset < 0) || (offset % FDT_TAGSIZE)
  150 + || (fdt_next_tag(fdt, offset, &offset) != FDT_BEGIN_NODE))
  151 + return -FDT_ERR_BADOFFSET;
  152 +
  153 + return offset;
  154 +}
  155 +
  156 +int fdt_next_node(const void *fdt, int offset, int *depth)
  157 +{
  158 + int nextoffset = 0;
  159 + uint32_t tag;
  160 +
  161 + if (offset >= 0)
  162 + if ((nextoffset = _fdt_check_node_offset(fdt, offset)) < 0)
  163 + return nextoffset;
  164 +
  165 + do {
  166 + offset = nextoffset;
  167 + tag = fdt_next_tag(fdt, offset, &nextoffset);
  168 +
  169 + switch (tag) {
  170 + case FDT_PROP:
  171 + case FDT_NOP:
  172 + break;
  173 +
  174 + case FDT_BEGIN_NODE:
  175 + if (depth)
  176 + (*depth)++;
  177 + break;
  178 +
  179 + case FDT_END_NODE:
  180 + if (depth && ((--(*depth)) < 0))
  181 + return nextoffset;
  182 + break;
  183 +
  184 + case FDT_END:
  185 + if ((nextoffset >= 0)
  186 + || ((nextoffset == -FDT_ERR_TRUNCATED) && !depth))
  187 + return -FDT_ERR_NOTFOUND;
  188 + else
  189 + return nextoffset;
  190 + }
  191 + } while (tag != FDT_BEGIN_NODE);
  192 +
  193 + return offset;
  194 +}
  195 +
  196 +const char *_fdt_find_string(const char *strtab, int tabsize, const char *s)
  197 +{
  198 + int len = strlen(s) + 1;
  199 + const char *last = strtab + tabsize - len;
  200 + const char *p;
  201 +
  202 + for (p = strtab; p <= last; p++)
  203 + if (memcmp(p, s, len) == 0)
  204 + return p;
  205 + return NULL;
  206 +}
  207 +
  208 +int fdt_move(const void *fdt, void *buf, int bufsize)
  209 +{
  210 + FDT_CHECK_HEADER(fdt);
  211 +
  212 + if (fdt_totalsize(fdt) > bufsize)
  213 + return -FDT_ERR_NOSPACE;
  214 +
  215 + memmove(buf, fdt, fdt_totalsize(fdt));
  216 + return 0;
  217 +}
  1 +/*
  2 + * libfdt - Flat Device Tree manipulation
  3 + * Copyright (C) 2006 David Gibson, IBM Corporation.
  4 + *
  5 + * libfdt is dual licensed: you can use it either under the terms of
  6 + * the GPL, or the BSD license, at your option.
  7 + *
  8 + * a) This library is free software; you can redistribute it and/or
  9 + * modify it under the terms of the GNU General Public License as
  10 + * published by the Free Software Foundation; either version 2 of the
  11 + * License, or (at your option) any later version.
  12 + *
  13 + * This library is distributed in the hope that it will be useful,
  14 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16 + * GNU General Public License for more details.
  17 + *
  18 + * You should have received a copy of the GNU General Public
  19 + * License along with this library; if not, write to the Free
  20 + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
  21 + * MA 02110-1301 USA
  22 + *
  23 + * Alternatively,
  24 + *
  25 + * b) Redistribution and use in source and binary forms, with or
  26 + * without modification, are permitted provided that the following
  27 + * conditions are met:
  28 + *
  29 + * 1. Redistributions of source code must retain the above
  30 + * copyright notice, this list of conditions and the following
  31 + * disclaimer.
  32 + * 2. Redistributions in binary form must reproduce the above
  33 + * copyright notice, this list of conditions and the following
  34 + * disclaimer in the documentation and/or other materials
  35 + * provided with the distribution.
  36 + *
  37 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
  38 + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
  39 + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
  40 + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  41 + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
  42 + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  43 + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  44 + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  45 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  46 + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  47 + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
  48 + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
  49 + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  50 + */
  51 +#include "libfdt_env.h"
  52 +
  53 +#ifndef USE_HOSTCC
  54 +#include <fdt.h>
  55 +#include <libfdt.h>
  56 +#else
  57 +#include "fdt_host.h"
  58 +#endif
  59 +
  60 +#include "libfdt_internal.h"
  61 +
  62 +static int _fdt_nodename_eq(const void *fdt, int offset,
  63 + const char *s, int len)
  64 +{
  65 + const char *p = fdt_offset_ptr(fdt, offset + FDT_TAGSIZE, len+1);
  66 +
  67 + if (! p)
  68 + /* short match */
  69 + return 0;
  70 +
  71 + if (memcmp(p, s, len) != 0)
  72 + return 0;
  73 +
  74 + if (p[len] == '\0')
  75 + return 1;
  76 + else if (!memchr(s, '@', len) && (p[len] == '@'))
  77 + return 1;
  78 + else
  79 + return 0;
  80 +}
  81 +
  82 +const char *fdt_string(const void *fdt, int stroffset)
  83 +{
  84 + return (const char *)fdt + fdt_off_dt_strings(fdt) + stroffset;
  85 +}
  86 +
  87 +static int _fdt_string_eq(const void *fdt, int stroffset,
  88 + const char *s, int len)
  89 +{
  90 + const char *p = fdt_string(fdt, stroffset);
  91 +
  92 + return (strlen(p) == len) && (memcmp(p, s, len) == 0);
  93 +}
  94 +
  95 +int fdt_get_mem_rsv(const void *fdt, int n, uint64_t *address, uint64_t *size)
  96 +{
  97 + FDT_CHECK_HEADER(fdt);
  98 + *address = fdt64_to_cpu(_fdt_mem_rsv(fdt, n)->address);
  99 + *size = fdt64_to_cpu(_fdt_mem_rsv(fdt, n)->size);
  100 + return 0;
  101 +}
  102 +
  103 +int fdt_num_mem_rsv(const void *fdt)
  104 +{
  105 + int i = 0;
  106 +
  107 + while (fdt64_to_cpu(_fdt_mem_rsv(fdt, i)->size) != 0)
  108 + i++;
  109 + return i;
  110 +}
  111 +
  112 +int fdt_subnode_offset_namelen(const void *fdt, int offset,
  113 + const char *name, int namelen)
  114 +{
  115 + int depth;
  116 +
  117 + FDT_CHECK_HEADER(fdt);
  118 +
  119 + for (depth = 0;
  120 + (offset >= 0) && (depth >= 0);
  121 + offset = fdt_next_node(fdt, offset, &depth))
  122 + if ((depth == 1)
  123 + && _fdt_nodename_eq(fdt, offset, name, namelen))
  124 + return offset;
  125 +
  126 + if (depth < 0)
  127 + return -FDT_ERR_NOTFOUND;
  128 + return offset; /* error */
  129 +}
  130 +
  131 +int fdt_subnode_offset(const void *fdt, int parentoffset,
  132 + const char *name)
  133 +{
  134 + return fdt_subnode_offset_namelen(fdt, parentoffset, name, strlen(name));
  135 +}
  136 +
  137 +int fdt_path_offset(const void *fdt, const char *path)
  138 +{
  139 + const char *end = path + strlen(path);
  140 + const char *p = path;
  141 + int offset = 0;
  142 +
  143 + FDT_CHECK_HEADER(fdt);
  144 +
  145 + /* see if we have an alias */
  146 + if (*path != '/') {
  147 + const char *q = strchr(path, '/');
  148 +
  149 + if (!q)
  150 + q = end;
  151 +
  152 + p = fdt_get_alias_namelen(fdt, p, q - p);
  153 + if (!p)
  154 + return -FDT_ERR_BADPATH;
  155 + offset = fdt_path_offset(fdt, p);
  156 +
  157 + p = q;
  158 + }
  159 +
  160 + while (*p) {
  161 + const char *q;
  162 +
  163 + while (*p == '/')
  164 + p++;
  165 + if (! *p)
  166 + return offset;
  167 + q = strchr(p, '/');
  168 + if (! q)
  169 + q = end;
  170 +
  171 + offset = fdt_subnode_offset_namelen(fdt, offset, p, q-p);
  172 + if (offset < 0)
  173 + return offset;
  174 +
  175 + p = q;
  176 + }
  177 +
  178 + return offset;
  179 +}
  180 +
  181 +const char *fdt_get_name(const void *fdt, int nodeoffset, int *len)
  182 +{
  183 + const struct fdt_node_header *nh = _fdt_offset_ptr(fdt, nodeoffset);
  184 + int err;
  185 +
  186 + if (((err = fdt_check_header(fdt)) != 0)
  187 + || ((err = _fdt_check_node_offset(fdt, nodeoffset)) < 0))
  188 + goto fail;
  189 +
  190 + if (len)
  191 + *len = strlen(nh->name);
  192 +
  193 + return nh->name;
  194 +
  195 + fail:
  196 + if (len)
  197 + *len = err;
  198 + return NULL;
  199 +}
  200 +
  201 +const struct fdt_property *fdt_get_property_namelen(const void *fdt,
  202 + int nodeoffset,
  203 + const char *name,
  204 + int namelen, int *lenp)
  205 +{
  206 + uint32_t tag;
  207 + const struct fdt_property *prop;
  208 + int offset, nextoffset;
  209 + int err;
  210 +
  211 + if (((err = fdt_check_header(fdt)) != 0)
  212 + || ((err = _fdt_check_node_offset(fdt, nodeoffset)) < 0))
  213 + goto fail;
  214 +
  215 + nextoffset = err;
  216 + do {
  217 + offset = nextoffset;
  218 +
  219 + tag = fdt_next_tag(fdt, offset, &nextoffset);
  220 + switch (tag) {
  221 + case FDT_END:
  222 + if (nextoffset < 0)
  223 + err = nextoffset;
  224 + else
  225 + /* FDT_END tag with unclosed nodes */
  226 + err = -FDT_ERR_BADSTRUCTURE;
  227 + goto fail;
  228 +
  229 + case FDT_PROP:
  230 + prop = _fdt_offset_ptr(fdt, offset);
  231 + if (_fdt_string_eq(fdt, fdt32_to_cpu(prop->nameoff),
  232 + name, namelen)) {
  233 + /* Found it! */
  234 + if (lenp)
  235 + *lenp = fdt32_to_cpu(prop->len);
  236 +
  237 + return prop;
  238 + }
  239 + break;
  240 + }
  241 + } while ((tag != FDT_BEGIN_NODE) && (tag != FDT_END_NODE));
  242 +
  243 + err = -FDT_ERR_NOTFOUND;
  244 + fail:
  245 + if (lenp)
  246 + *lenp = err;
  247 + return NULL;
  248 +}
  249 +
  250 +const struct fdt_property *fdt_get_property(const void *fdt,
  251 + int nodeoffset,
  252 + const char *name, int *lenp)
  253 +{
  254 + return fdt_get_property_namelen(fdt, nodeoffset, name,
  255 + strlen(name), lenp);
  256 +}
  257 +
  258 +const void *fdt_getprop_namelen(const void *fdt, int nodeoffset,
  259 + const char *name, int namelen, int *lenp)
  260 +{
  261 + const struct fdt_property *prop;
  262 +
  263 + prop = fdt_get_property_namelen(fdt, nodeoffset, name, namelen, lenp);
  264 + if (! prop)
  265 + return NULL;
  266 +
  267 + return prop->data;
  268 +}
  269 +
  270 +const void *fdt_getprop(const void *fdt, int nodeoffset,
  271 + const char *name, int *lenp)
  272 +{
  273 + return fdt_getprop_namelen(fdt, nodeoffset, name, strlen(name), lenp);
  274 +}
  275 +
  276 +uint32_t fdt_get_phandle(const void *fdt, int nodeoffset)
  277 +{
  278 + const uint32_t *php;
  279 + int len;
  280 +
  281 + php = fdt_getprop(fdt, nodeoffset, "linux,phandle", &len);
  282 + if (!php || (len != sizeof(*php)))
  283 + return 0;
  284 +
  285 + return fdt32_to_cpu(*php);
  286 +}
  287 +
  288 +const char *fdt_get_alias_namelen(const void *fdt,
  289 + const char *name, int namelen)
  290 +{
  291 + int aliasoffset;
  292 +
  293 + aliasoffset = fdt_path_offset(fdt, "/aliases");
  294 + if (aliasoffset < 0)
  295 + return NULL;
  296 +
  297 + return fdt_getprop_namelen(fdt, aliasoffset, name, namelen, NULL);
  298 +}
  299 +
  300 +const char *fdt_get_alias(const void *fdt, const char *name)
  301 +{
  302 + return fdt_get_alias_namelen(fdt, name, strlen(name));
  303 +}
  304 +
  305 +int fdt_get_path(const void *fdt, int nodeoffset, char *buf, int buflen)
  306 +{
  307 + int pdepth = 0, p = 0;
  308 + int offset, depth, namelen;
  309 + const char *name;
  310 +
  311 + FDT_CHECK_HEADER(fdt);
  312 +
  313 + if (buflen < 2)
  314 + return -FDT_ERR_NOSPACE;
  315 +
  316 + for (offset = 0, depth = 0;
  317 + (offset >= 0) && (offset <= nodeoffset);
  318 + offset = fdt_next_node(fdt, offset, &depth)) {
  319 + while (pdepth > depth) {
  320 + do {
  321 + p--;
  322 + } while (buf[p-1] != '/');
  323 + pdepth--;
  324 + }
  325 +
  326 + if (pdepth >= depth) {
  327 + name = fdt_get_name(fdt, offset, &namelen);
  328 + if (!name)
  329 + return namelen;
  330 + if ((p + namelen + 1) <= buflen) {
  331 + memcpy(buf + p, name, namelen);
  332 + p += namelen;
  333 + buf[p++] = '/';
  334 + pdepth++;
  335 + }
  336 + }
  337 +
  338 + if (offset == nodeoffset) {
  339 + if (pdepth < (depth + 1))
  340 + return -FDT_ERR_NOSPACE;
  341 +
  342 + if (p > 1) /* special case so that root path is "/", not "" */
  343 + p--;
  344 + buf[p] = '\0';
  345 + return 0;
  346 + }
  347 + }
  348 +
  349 + if ((offset == -FDT_ERR_NOTFOUND) || (offset >= 0))
  350 + return -FDT_ERR_BADOFFSET;
  351 + else if (offset == -FDT_ERR_BADOFFSET)
  352 + return -FDT_ERR_BADSTRUCTURE;
  353 +
  354 + return offset; /* error from fdt_next_node() */
  355 +}
  356 +
  357 +int fdt_supernode_atdepth_offset(const void *fdt, int nodeoffset,
  358 + int supernodedepth, int *nodedepth)
  359 +{
  360 + int offset, depth;
  361 + int supernodeoffset = -FDT_ERR_INTERNAL;
  362 +
  363 + FDT_CHECK_HEADER(fdt);
  364 +
  365 + if (supernodedepth < 0)
  366 + return -FDT_ERR_NOTFOUND;
  367 +
  368 + for (offset = 0, depth = 0;
  369 + (offset >= 0) && (offset <= nodeoffset);
  370 + offset = fdt_next_node(fdt, offset, &depth)) {
  371 + if (depth == supernodedepth)
  372 + supernodeoffset = offset;
  373 +
  374 + if (offset == nodeoffset) {
  375 + if (nodedepth)
  376 + *nodedepth = depth;
  377 +
  378 + if (supernodedepth > depth)
  379 + return -FDT_ERR_NOTFOUND;
  380 + else
  381 + return supernodeoffset;
  382 + }
  383 + }
  384 +
  385 + if ((offset == -FDT_ERR_NOTFOUND) || (offset >= 0))
  386 + return -FDT_ERR_BADOFFSET;
  387 + else if (offset == -FDT_ERR_BADOFFSET)
  388 + return -FDT_ERR_BADSTRUCTURE;
  389 +
  390 + return offset; /* error from fdt_next_node() */
  391 +}
  392 +
  393 +int fdt_node_depth(const void *fdt, int nodeoffset)
  394 +{
  395 + int nodedepth;
  396 + int err;
  397 +
  398 + err = fdt_supernode_atdepth_offset(fdt, nodeoffset, 0, &nodedepth);
  399 + if (err)
  400 + return (err < 0) ? err : -FDT_ERR_INTERNAL;
  401 + return nodedepth;
  402 +}
  403 +
  404 +int fdt_parent_offset(const void *fdt, int nodeoffset)
  405 +{
  406 + int nodedepth = fdt_node_depth(fdt, nodeoffset);
  407 +
  408 + if (nodedepth < 0)
  409 + return nodedepth;
  410 + return fdt_supernode_atdepth_offset(fdt, nodeoffset,
  411 + nodedepth - 1, NULL);
  412 +}
  413 +
  414 +int fdt_node_offset_by_prop_value(const void *fdt, int startoffset,
  415 + const char *propname,
  416 + const void *propval, int proplen)
  417 +{
  418 + int offset;
  419 + const void *val;
  420 + int len;
  421 +
  422 + FDT_CHECK_HEADER(fdt);
  423 +
  424 + /* FIXME: The algorithm here is pretty horrible: we scan each
  425 + * property of a node in fdt_getprop(), then if that didn't
  426 + * find what we want, we scan over them again making our way
  427 + * to the next node. Still it's the easiest to implement
  428 + * approach; performance can come later. */
  429 + for (offset = fdt_next_node(fdt, startoffset, NULL);
  430 + offset >= 0;
  431 + offset = fdt_next_node(fdt, offset, NULL)) {
  432 + val = fdt_getprop(fdt, offset, propname, &len);
  433 + if (val && (len == proplen)
  434 + && (memcmp(val, propval, len) == 0))
  435 + return offset;
  436 + }
  437 +
  438 + return offset; /* error from fdt_next_node() */
  439 +}
  440 +
  441 +int fdt_node_offset_by_phandle(const void *fdt, uint32_t phandle)
  442 +{
  443 + if ((phandle == 0) || (phandle == -1))
  444 + return -FDT_ERR_BADPHANDLE;
  445 + phandle = cpu_to_fdt32(phandle);
  446 + return fdt_node_offset_by_prop_value(fdt, -1, "linux,phandle",
  447 + &phandle, sizeof(phandle));
  448 +}
  449 +
  450 +static int _fdt_stringlist_contains(const char *strlist, int listlen,
  451 + const char *str)
  452 +{
  453 + int len = strlen(str);
  454 + const char *p;
  455 +
  456 + while (listlen >= len) {
  457 + if (memcmp(str, strlist, len+1) == 0)
  458 + return 1;
  459 + p = memchr(strlist, '\0', listlen);
  460 + if (!p)
  461 + return 0; /* malformed strlist.. */
  462 + listlen -= (p-strlist) + 1;
  463 + strlist = p + 1;
  464 + }
  465 + return 0;
  466 +}
  467 +
  468 +int fdt_node_check_compatible(const void *fdt, int nodeoffset,
  469 + const char *compatible)
  470 +{
  471 + const void *prop;
  472 + int len;
  473 +
  474 + prop = fdt_getprop(fdt, nodeoffset, "compatible", &len);
  475 + if (!prop)
  476 + return len;
  477 + if (_fdt_stringlist_contains(prop, len, compatible))
  478 + return 0;
  479 + else
  480 + return 1;
  481 +}
  482 +
  483 +int fdt_node_offset_by_compatible(const void *fdt, int startoffset,
  484 + const char *compatible)
  485 +{
  486 + int offset, err;
  487 +
  488 + FDT_CHECK_HEADER(fdt);
  489 +
  490 + /* FIXME: The algorithm here is pretty horrible: we scan each
  491 + * property of a node in fdt_node_check_compatible(), then if
  492 + * that didn't find what we want, we scan over them again
  493 + * making our way to the next node. Still it's the easiest to
  494 + * implement approach; performance can come later. */
  495 + for (offset = fdt_next_node(fdt, startoffset, NULL);
  496 + offset >= 0;
  497 + offset = fdt_next_node(fdt, offset, NULL)) {
  498 + err = fdt_node_check_compatible(fdt, offset, compatible);
  499 + if ((err < 0) && (err != -FDT_ERR_NOTFOUND))
  500 + return err;
  501 + else if (err == 0)
  502 + return offset;
  503 + }
  504 +
  505 + return offset; /* error from fdt_next_node() */
  506 +}
  1 +/*
  2 + * libfdt - Flat Device Tree manipulation
  3 + * Copyright (C) 2006 David Gibson, IBM Corporation.
  4 + *
  5 + * libfdt is dual licensed: you can use it either under the terms of
  6 + * the GPL, or the BSD license, at your option.
  7 + *
  8 + * a) This library is free software; you can redistribute it and/or
  9 + * modify it under the terms of the GNU General Public License as
  10 + * published by the Free Software Foundation; either version 2 of the
  11 + * License, or (at your option) any later version.
  12 + *
  13 + * This library is distributed in the hope that it will be useful,
  14 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16 + * GNU General Public License for more details.
  17 + *
  18 + * You should have received a copy of the GNU General Public
  19 + * License along with this library; if not, write to the Free
  20 + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
  21 + * MA 02110-1301 USA
  22 + *
  23 + * Alternatively,
  24 + *
  25 + * b) Redistribution and use in source and binary forms, with or
  26 + * without modification, are permitted provided that the following
  27 + * conditions are met:
  28 + *
  29 + * 1. Redistributions of source code must retain the above
  30 + * copyright notice, this list of conditions and the following
  31 + * disclaimer.
  32 + * 2. Redistributions in binary form must reproduce the above
  33 + * copyright notice, this list of conditions and the following
  34 + * disclaimer in the documentation and/or other materials
  35 + * provided with the distribution.
  36 + *
  37 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
  38 + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
  39 + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
  40 + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  41 + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
  42 + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  43 + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  44 + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  45 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  46 + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  47 + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
  48 + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
  49 + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  50 + */
  51 +#include "libfdt_env.h"
  52 +
  53 +#ifndef USE_HOSTCC
  54 +#include <fdt.h>
  55 +#include <libfdt.h>
  56 +#else
  57 +#include "fdt_host.h"
  58 +#endif
  59 +
  60 +#include "libfdt_internal.h"
  61 +
  62 +static int _fdt_blocks_misordered(const void *fdt,
  63 + int mem_rsv_size, int struct_size)
  64 +{
  65 + return (fdt_off_mem_rsvmap(fdt) < FDT_ALIGN(sizeof(struct fdt_header), 8))
  66 + || (fdt_off_dt_struct(fdt) <
  67 + (fdt_off_mem_rsvmap(fdt) + mem_rsv_size))
  68 + || (fdt_off_dt_strings(fdt) <
  69 + (fdt_off_dt_struct(fdt) + struct_size))
  70 + || (fdt_totalsize(fdt) <
  71 + (fdt_off_dt_strings(fdt) + fdt_size_dt_strings(fdt)));
  72 +}
  73 +
  74 +static int _fdt_rw_check_header(void *fdt)
  75 +{
  76 + FDT_CHECK_HEADER(fdt);
  77 +
  78 + if (fdt_version(fdt) < 17)
  79 + return -FDT_ERR_BADVERSION;
  80 + if (_fdt_blocks_misordered(fdt, sizeof(struct fdt_reserve_entry),
  81 + fdt_size_dt_struct(fdt)))
  82 + return -FDT_ERR_BADLAYOUT;
  83 + if (fdt_version(fdt) > 17)
  84 + fdt_set_version(fdt, 17);
  85 +
  86 + return 0;
  87 +}
  88 +
  89 +#define FDT_RW_CHECK_HEADER(fdt) \
  90 + { \
  91 + int err; \
  92 + if ((err = _fdt_rw_check_header(fdt)) != 0) \
  93 + return err; \
  94 + }
  95 +
  96 +static inline int _fdt_data_size(void *fdt)
  97 +{
  98 + return fdt_off_dt_strings(fdt) + fdt_size_dt_strings(fdt);
  99 +}
  100 +
  101 +static int _fdt_splice(void *fdt, void *splicepoint, int oldlen, int newlen)
  102 +{
  103 + char *p = splicepoint;
  104 + char *end = (char *)fdt + _fdt_data_size(fdt);
  105 +
  106 + if (((p + oldlen) < p) || ((p + oldlen) > end))
  107 + return -FDT_ERR_BADOFFSET;
  108 + if ((end - oldlen + newlen) > ((char *)fdt + fdt_totalsize(fdt)))
  109 + return -FDT_ERR_NOSPACE;
  110 + memmove(p + newlen, p + oldlen, end - p - oldlen);
  111 + return 0;
  112 +}
  113 +
  114 +static int _fdt_splice_mem_rsv(void *fdt, struct fdt_reserve_entry *p,
  115 + int oldn, int newn)
  116 +{
  117 + int delta = (newn - oldn) * sizeof(*p);
  118 + int err;
  119 + err = _fdt_splice(fdt, p, oldn * sizeof(*p), newn * sizeof(*p));
  120 + if (err)
  121 + return err;
  122 + fdt_set_off_dt_struct(fdt, fdt_off_dt_struct(fdt) + delta);
  123 + fdt_set_off_dt_strings(fdt, fdt_off_dt_strings(fdt) + delta);
  124 + return 0;
  125 +}
  126 +
  127 +static int _fdt_splice_struct(void *fdt, void *p,
  128 + int oldlen, int newlen)
  129 +{
  130 + int delta = newlen - oldlen;
  131 + int err;
  132 +
  133 + if ((err = _fdt_splice(fdt, p, oldlen, newlen)))
  134 + return err;
  135 +
  136 + fdt_set_size_dt_struct(fdt, fdt_size_dt_struct(fdt) + delta);
  137 + fdt_set_off_dt_strings(fdt, fdt_off_dt_strings(fdt) + delta);
  138 + return 0;
  139 +}
  140 +
  141 +static int _fdt_splice_string(void *fdt, int newlen)
  142 +{
  143 + void *p = (char *)fdt
  144 + + fdt_off_dt_strings(fdt) + fdt_size_dt_strings(fdt);
  145 + int err;
  146 +
  147 + if ((err = _fdt_splice(fdt, p, 0, newlen)))
  148 + return err;
  149 +
  150 + fdt_set_size_dt_strings(fdt, fdt_size_dt_strings(fdt) + newlen);
  151 + return 0;
  152 +}
  153 +
  154 +static int _fdt_find_add_string(void *fdt, const char *s)
  155 +{
  156 + char *strtab = (char *)fdt + fdt_off_dt_strings(fdt);
  157 + const char *p;
  158 + char *new;
  159 + int len = strlen(s) + 1;
  160 + int err;
  161 +
  162 + p = _fdt_find_string(strtab, fdt_size_dt_strings(fdt), s);
  163 + if (p)
  164 + /* found it */
  165 + return (p - strtab);
  166 +
  167 + new = strtab + fdt_size_dt_strings(fdt);
  168 + err = _fdt_splice_string(fdt, len);
  169 + if (err)
  170 + return err;
  171 +
  172 + memcpy(new, s, len);
  173 + return (new - strtab);
  174 +}
  175 +
  176 +int fdt_add_mem_rsv(void *fdt, uint64_t address, uint64_t size)
  177 +{
  178 + struct fdt_reserve_entry *re;
  179 + int err;
  180 +
  181 + FDT_RW_CHECK_HEADER(fdt);
  182 +
  183 + re = _fdt_mem_rsv_w(fdt, fdt_num_mem_rsv(fdt));
  184 + err = _fdt_splice_mem_rsv(fdt, re, 0, 1);
  185 + if (err)
  186 + return err;
  187 +
  188 + re->address = cpu_to_fdt64(address);
  189 + re->size = cpu_to_fdt64(size);
  190 + return 0;
  191 +}
  192 +
  193 +int fdt_del_mem_rsv(void *fdt, int n)
  194 +{
  195 + struct fdt_reserve_entry *re = _fdt_mem_rsv_w(fdt, n);
  196 + int err;
  197 +
  198 + FDT_RW_CHECK_HEADER(fdt);
  199 +
  200 + if (n >= fdt_num_mem_rsv(fdt))
  201 + return -FDT_ERR_NOTFOUND;
  202 +
  203 + err = _fdt_splice_mem_rsv(fdt, re, 1, 0);
  204 + if (err)
  205 + return err;
  206 + return 0;
  207 +}
  208 +
  209 +static int _fdt_resize_property(void *fdt, int nodeoffset, const char *name,
  210 + int len, struct fdt_property **prop)
  211 +{
  212 + int oldlen;
  213 + int err;
  214 +
  215 + *prop = fdt_get_property_w(fdt, nodeoffset, name, &oldlen);
  216 + if (! (*prop))
  217 + return oldlen;
  218 +
  219 + if ((err = _fdt_splice_struct(fdt, (*prop)->data, FDT_TAGALIGN(oldlen),
  220 + FDT_TAGALIGN(len))))
  221 + return err;
  222 +
  223 + (*prop)->len = cpu_to_fdt32(len);
  224 + return 0;
  225 +}
  226 +
  227 +static int _fdt_add_property(void *fdt, int nodeoffset, const char *name,
  228 + int len, struct fdt_property **prop)
  229 +{
  230 + int proplen;
  231 + int nextoffset;
  232 + int namestroff;
  233 + int err;
  234 +
  235 + if ((nextoffset = _fdt_check_node_offset(fdt, nodeoffset)) < 0)
  236 + return nextoffset;
  237 +
  238 + namestroff = _fdt_find_add_string(fdt, name);
  239 + if (namestroff < 0)
  240 + return namestroff;
  241 +
  242 + *prop = _fdt_offset_ptr_w(fdt, nextoffset);
  243 + proplen = sizeof(**prop) + FDT_TAGALIGN(len);
  244 +
  245 + err = _fdt_splice_struct(fdt, *prop, 0, proplen);
  246 + if (err)
  247 + return err;
  248 +
  249 + (*prop)->tag = cpu_to_fdt32(FDT_PROP);
  250 + (*prop)->nameoff = cpu_to_fdt32(namestroff);
  251 + (*prop)->len = cpu_to_fdt32(len);
  252 + return 0;
  253 +}
  254 +
  255 +int fdt_set_name(void *fdt, int nodeoffset, const char *name)
  256 +{
  257 + char *namep;
  258 + int oldlen, newlen;
  259 + int err;
  260 +
  261 + FDT_RW_CHECK_HEADER(fdt);
  262 +
  263 + namep = (char *)(uintptr_t)fdt_get_name(fdt, nodeoffset, &oldlen);
  264 + if (!namep)
  265 + return oldlen;
  266 +
  267 + newlen = strlen(name);
  268 +
  269 + err = _fdt_splice_struct(fdt, namep, FDT_TAGALIGN(oldlen+1),
  270 + FDT_TAGALIGN(newlen+1));
  271 + if (err)
  272 + return err;
  273 +
  274 + memcpy(namep, name, newlen+1);
  275 + return 0;
  276 +}
  277 +
  278 +int fdt_setprop(void *fdt, int nodeoffset, const char *name,
  279 + const void *val, int len)
  280 +{
  281 + struct fdt_property *prop;
  282 + int err;
  283 +
  284 + FDT_RW_CHECK_HEADER(fdt);
  285 +
  286 + err = _fdt_resize_property(fdt, nodeoffset, name, len, &prop);
  287 + if (err == -FDT_ERR_NOTFOUND)
  288 + err = _fdt_add_property(fdt, nodeoffset, name, len, &prop);
  289 + if (err)
  290 + return err;
  291 +
  292 + memcpy(prop->data, val, len);
  293 + return 0;
  294 +}
  295 +
  296 +int fdt_delprop(void *fdt, int nodeoffset, const char *name)
  297 +{
  298 + struct fdt_property *prop;
  299 + int len, proplen;
  300 +
  301 + FDT_RW_CHECK_HEADER(fdt);
  302 +
  303 + prop = fdt_get_property_w(fdt, nodeoffset, name, &len);
  304 + if (! prop)
  305 + return len;
  306 +
  307 + proplen = sizeof(*prop) + FDT_TAGALIGN(len);
  308 + return _fdt_splice_struct(fdt, prop, proplen, 0);
  309 +}
  310 +
  311 +int fdt_add_subnode_namelen(void *fdt, int parentoffset,
  312 + const char *name, int namelen)
  313 +{
  314 + struct fdt_node_header *nh;
  315 + int offset, nextoffset;
  316 + int nodelen;
  317 + int err;
  318 + uint32_t tag;
  319 + uint32_t *endtag;
  320 +
  321 + FDT_RW_CHECK_HEADER(fdt);
  322 +
  323 + offset = fdt_subnode_offset_namelen(fdt, parentoffset, name, namelen);
  324 + if (offset >= 0)
  325 + return -FDT_ERR_EXISTS;
  326 + else if (offset != -FDT_ERR_NOTFOUND)
  327 + return offset;
  328 +
  329 + /* Try to place the new node after the parent's properties */
  330 + fdt_next_tag(fdt, parentoffset, &nextoffset); /* skip the BEGIN_NODE */
  331 + do {
  332 + offset = nextoffset;
  333 + tag = fdt_next_tag(fdt, offset, &nextoffset);
  334 + } while ((tag == FDT_PROP) || (tag == FDT_NOP));
  335 +
  336 + nh = _fdt_offset_ptr_w(fdt, offset);
  337 + nodelen = sizeof(*nh) + FDT_TAGALIGN(namelen+1) + FDT_TAGSIZE;
  338 +
  339 + err = _fdt_splice_struct(fdt, nh, 0, nodelen);
  340 + if (err)
  341 + return err;
  342 +
  343 + nh->tag = cpu_to_fdt32(FDT_BEGIN_NODE);
  344 + memset(nh->name, 0, FDT_TAGALIGN(namelen+1));
  345 + memcpy(nh->name, name, namelen);
  346 + endtag = (uint32_t *)((char *)nh + nodelen - FDT_TAGSIZE);
  347 + *endtag = cpu_to_fdt32(FDT_END_NODE);
  348 +
  349 + return offset;
  350 +}
  351 +
  352 +int fdt_add_subnode(void *fdt, int parentoffset, const char *name)
  353 +{
  354 + return fdt_add_subnode_namelen(fdt, parentoffset, name, strlen(name));
  355 +}
  356 +
  357 +int fdt_del_node(void *fdt, int nodeoffset)
  358 +{
  359 + int endoffset;
  360 +
  361 + FDT_RW_CHECK_HEADER(fdt);
  362 +
  363 + endoffset = _fdt_node_end_offset(fdt, nodeoffset);
  364 + if (endoffset < 0)
  365 + return endoffset;
  366 +
  367 + return _fdt_splice_struct(fdt, _fdt_offset_ptr_w(fdt, nodeoffset),
  368 + endoffset - nodeoffset, 0);
  369 +}
  370 +
  371 +static void _fdt_packblocks(const char *old, char *new,
  372 + int mem_rsv_size, int struct_size)
  373 +{
  374 + int mem_rsv_off, struct_off, strings_off;
  375 +
  376 + mem_rsv_off = FDT_ALIGN(sizeof(struct fdt_header), 8);
  377 + struct_off = mem_rsv_off + mem_rsv_size;
  378 + strings_off = struct_off + struct_size;
  379 +
  380 + memmove(new + mem_rsv_off, old + fdt_off_mem_rsvmap(old), mem_rsv_size);
  381 + fdt_set_off_mem_rsvmap(new, mem_rsv_off);
  382 +
  383 + memmove(new + struct_off, old + fdt_off_dt_struct(old), struct_size);
  384 + fdt_set_off_dt_struct(new, struct_off);
  385 + fdt_set_size_dt_struct(new, struct_size);
  386 +
  387 + memmove(new + strings_off, old + fdt_off_dt_strings(old),
  388 + fdt_size_dt_strings(old));
  389 + fdt_set_off_dt_strings(new, strings_off);
  390 + fdt_set_size_dt_strings(new, fdt_size_dt_strings(old));
  391 +}
  392 +
  393 +int fdt_open_into(const void *fdt, void *buf, int bufsize)
  394 +{
  395 + int err;
  396 + int mem_rsv_size, struct_size;
  397 + int newsize;
  398 + const char *fdtstart = fdt;
  399 + const char *fdtend = fdtstart + fdt_totalsize(fdt);
  400 + char *tmp;
  401 +
  402 + FDT_CHECK_HEADER(fdt);
  403 +
  404 + mem_rsv_size = (fdt_num_mem_rsv(fdt)+1)
  405 + * sizeof(struct fdt_reserve_entry);
  406 +
  407 + if (fdt_version(fdt) >= 17) {
  408 + struct_size = fdt_size_dt_struct(fdt);
  409 + } else {
  410 + struct_size = 0;
  411 + while (fdt_next_tag(fdt, struct_size, &struct_size) != FDT_END)
  412 + ;
  413 + if (struct_size < 0)
  414 + return struct_size;
  415 + }
  416 +
  417 + if (!_fdt_blocks_misordered(fdt, mem_rsv_size, struct_size)) {
  418 + /* no further work necessary */
  419 + err = fdt_move(fdt, buf, bufsize);
  420 + if (err)
  421 + return err;
  422 + fdt_set_version(buf, 17);
  423 + fdt_set_size_dt_struct(buf, struct_size);
  424 + fdt_set_totalsize(buf, bufsize);
  425 + return 0;
  426 + }
  427 +
  428 + /* Need to reorder */
  429 + newsize = FDT_ALIGN(sizeof(struct fdt_header), 8) + mem_rsv_size
  430 + + struct_size + fdt_size_dt_strings(fdt);
  431 +
  432 + if (bufsize < newsize)
  433 + return -FDT_ERR_NOSPACE;
  434 +
  435 + /* First attempt to build converted tree at beginning of buffer */
  436 + tmp = buf;
  437 + /* But if that overlaps with the old tree... */
  438 + if (((tmp + newsize) > fdtstart) && (tmp < fdtend)) {
  439 + /* Try right after the old tree instead */
  440 + tmp = (char *)(uintptr_t)fdtend;
  441 + if ((tmp + newsize) > ((char *)buf + bufsize))
  442 + return -FDT_ERR_NOSPACE;
  443 + }
  444 +
  445 + _fdt_packblocks(fdt, tmp, mem_rsv_size, struct_size);
  446 + memmove(buf, tmp, newsize);
  447 +
  448 + fdt_set_magic(buf, FDT_MAGIC);
  449 + fdt_set_totalsize(buf, bufsize);
  450 + fdt_set_version(buf, 17);
  451 + fdt_set_last_comp_version(buf, 16);
  452 + fdt_set_boot_cpuid_phys(buf, fdt_boot_cpuid_phys(fdt));
  453 +
  454 + return 0;
  455 +}
  456 +
  457 +int fdt_pack(void *fdt)
  458 +{
  459 + int mem_rsv_size;
  460 +
  461 + FDT_RW_CHECK_HEADER(fdt);
  462 +
  463 + mem_rsv_size = (fdt_num_mem_rsv(fdt)+1)
  464 + * sizeof(struct fdt_reserve_entry);
  465 + _fdt_packblocks(fdt, fdt, mem_rsv_size, fdt_size_dt_struct(fdt));
  466 + fdt_set_totalsize(fdt, _fdt_data_size(fdt));
  467 +
  468 + return 0;
  469 +}
lib/libfdt/fdt_strerror.c
  1 +/*
  2 + * libfdt - Flat Device Tree manipulation
  3 + * Copyright (C) 2006 David Gibson, IBM Corporation.
  4 + *
  5 + * libfdt is dual licensed: you can use it either under the terms of
  6 + * the GPL, or the BSD license, at your option.
  7 + *
  8 + * a) This library is free software; you can redistribute it and/or
  9 + * modify it under the terms of the GNU General Public License as
  10 + * published by the Free Software Foundation; either version 2 of the
  11 + * License, or (at your option) any later version.
  12 + *
  13 + * This library is distributed in the hope that it will be useful,
  14 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16 + * GNU General Public License for more details.
  17 + *
  18 + * You should have received a copy of the GNU General Public
  19 + * License along with this library; if not, write to the Free
  20 + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
  21 + * MA 02110-1301 USA
  22 + *
  23 + * Alternatively,
  24 + *
  25 + * b) Redistribution and use in source and binary forms, with or
  26 + * without modification, are permitted provided that the following
  27 + * conditions are met:
  28 + *
  29 + * 1. Redistributions of source code must retain the above
  30 + * copyright notice, this list of conditions and the following
  31 + * disclaimer.
  32 + * 2. Redistributions in binary form must reproduce the above
  33 + * copyright notice, this list of conditions and the following
  34 + * disclaimer in the documentation and/or other materials
  35 + * provided with the distribution.
  36 + *
  37 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
  38 + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
  39 + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
  40 + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  41 + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
  42 + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  43 + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  44 + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  45 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  46 + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  47 + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
  48 + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
  49 + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  50 + */
  51 +#include "libfdt_env.h"
  52 +
  53 +#ifndef USE_HOSTCC
  54 +#include <fdt.h>
  55 +#include <libfdt.h>
  56 +#else
  57 +#include "fdt_host.h"
  58 +#endif
  59 +
  60 +#include "libfdt_internal.h"
  61 +
  62 +struct fdt_errtabent {
  63 + const char *str;
  64 +};
  65 +
  66 +#define FDT_ERRTABENT(val) \
  67 + [(val)] = { .str = #val, }
  68 +
  69 +static struct fdt_errtabent fdt_errtable[] = {
  70 + FDT_ERRTABENT(FDT_ERR_NOTFOUND),
  71 + FDT_ERRTABENT(FDT_ERR_EXISTS),
  72 + FDT_ERRTABENT(FDT_ERR_NOSPACE),
  73 +
  74 + FDT_ERRTABENT(FDT_ERR_BADOFFSET),
  75 + FDT_ERRTABENT(FDT_ERR_BADPATH),
  76 + FDT_ERRTABENT(FDT_ERR_BADSTATE),
  77 +
  78 + FDT_ERRTABENT(FDT_ERR_TRUNCATED),
  79 + FDT_ERRTABENT(FDT_ERR_BADMAGIC),
  80 + FDT_ERRTABENT(FDT_ERR_BADVERSION),
  81 + FDT_ERRTABENT(FDT_ERR_BADSTRUCTURE),
  82 + FDT_ERRTABENT(FDT_ERR_BADLAYOUT),
  83 +};
  84 +#define FDT_ERRTABSIZE (sizeof(fdt_errtable) / sizeof(fdt_errtable[0]))
  85 +
  86 +const char *fdt_strerror(int errval)
  87 +{
  88 + if (errval > 0)
  89 + return "<valid offset/length>";
  90 + else if (errval == 0)
  91 + return "<no error>";
  92 + else if (errval > -FDT_ERRTABSIZE) {
  93 + const char *s = fdt_errtable[-errval].str;
  94 +
  95 + if (s)
  96 + return s;
  97 + }
  98 +
  99 + return "<unknown error>";
  100 +}
  1 +/*
  2 + * libfdt - Flat Device Tree manipulation
  3 + * Copyright (C) 2006 David Gibson, IBM Corporation.
  4 + *
  5 + * libfdt is dual licensed: you can use it either under the terms of
  6 + * the GPL, or the BSD license, at your option.
  7 + *
  8 + * a) This library is free software; you can redistribute it and/or
  9 + * modify it under the terms of the GNU General Public License as
  10 + * published by the Free Software Foundation; either version 2 of the
  11 + * License, or (at your option) any later version.
  12 + *
  13 + * This library is distributed in the hope that it will be useful,
  14 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16 + * GNU General Public License for more details.
  17 + *
  18 + * You should have received a copy of the GNU General Public
  19 + * License along with this library; if not, write to the Free
  20 + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
  21 + * MA 02110-1301 USA
  22 + *
  23 + * Alternatively,
  24 + *
  25 + * b) Redistribution and use in source and binary forms, with or
  26 + * without modification, are permitted provided that the following
  27 + * conditions are met:
  28 + *
  29 + * 1. Redistributions of source code must retain the above
  30 + * copyright notice, this list of conditions and the following
  31 + * disclaimer.
  32 + * 2. Redistributions in binary form must reproduce the above
  33 + * copyright notice, this list of conditions and the following
  34 + * disclaimer in the documentation and/or other materials
  35 + * provided with the distribution.
  36 + *
  37 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
  38 + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
  39 + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
  40 + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  41 + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
  42 + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  43 + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  44 + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  45 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  46 + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  47 + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
  48 + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
  49 + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  50 + */
  51 +#include "libfdt_env.h"
  52 +
  53 +#include <fdt.h>
  54 +#include <libfdt.h>
  55 +
  56 +#include "libfdt_internal.h"
  57 +
  58 +static int _fdt_sw_check_header(void *fdt)
  59 +{
  60 + if (fdt_magic(fdt) != FDT_SW_MAGIC)
  61 + return -FDT_ERR_BADMAGIC;
  62 + /* FIXME: should check more details about the header state */
  63 + return 0;
  64 +}
  65 +
  66 +#define FDT_SW_CHECK_HEADER(fdt) \
  67 + { \
  68 + int err; \
  69 + if ((err = _fdt_sw_check_header(fdt)) != 0) \
  70 + return err; \
  71 + }
  72 +
  73 +static void *_fdt_grab_space(void *fdt, size_t len)
  74 +{
  75 + int offset = fdt_size_dt_struct(fdt);
  76 + int spaceleft;
  77 +
  78 + spaceleft = fdt_totalsize(fdt) - fdt_off_dt_struct(fdt)
  79 + - fdt_size_dt_strings(fdt);
  80 +
  81 + if ((offset + len < offset) || (offset + len > spaceleft))
  82 + return NULL;
  83 +
  84 + fdt_set_size_dt_struct(fdt, offset + len);
  85 + return _fdt_offset_ptr_w(fdt, offset);
  86 +}
  87 +
  88 +int fdt_create(void *buf, int bufsize)
  89 +{
  90 + void *fdt = buf;
  91 +
  92 + if (bufsize < sizeof(struct fdt_header))
  93 + return -FDT_ERR_NOSPACE;
  94 +
  95 + memset(buf, 0, bufsize);
  96 +
  97 + fdt_set_magic(fdt, FDT_SW_MAGIC);
  98 + fdt_set_version(fdt, FDT_LAST_SUPPORTED_VERSION);
  99 + fdt_set_last_comp_version(fdt, FDT_FIRST_SUPPORTED_VERSION);
  100 + fdt_set_totalsize(fdt, bufsize);
  101 +
  102 + fdt_set_off_mem_rsvmap(fdt, FDT_ALIGN(sizeof(struct fdt_header),
  103 + sizeof(struct fdt_reserve_entry)));
  104 + fdt_set_off_dt_struct(fdt, fdt_off_mem_rsvmap(fdt));
  105 + fdt_set_off_dt_strings(fdt, bufsize);
  106 +
  107 + return 0;
  108 +}
  109 +
  110 +int fdt_add_reservemap_entry(void *fdt, uint64_t addr, uint64_t size)
  111 +{
  112 + struct fdt_reserve_entry *re;
  113 + int offset;
  114 +
  115 + FDT_SW_CHECK_HEADER(fdt);
  116 +
  117 + if (fdt_size_dt_struct(fdt))
  118 + return -FDT_ERR_BADSTATE;
  119 +
  120 + offset = fdt_off_dt_struct(fdt);
  121 + if ((offset + sizeof(*re)) > fdt_totalsize(fdt))
  122 + return -FDT_ERR_NOSPACE;
  123 +
  124 + re = (struct fdt_reserve_entry *)((char *)fdt + offset);
  125 + re->address = cpu_to_fdt64(addr);
  126 + re->size = cpu_to_fdt64(size);
  127 +
  128 + fdt_set_off_dt_struct(fdt, offset + sizeof(*re));
  129 +
  130 + return 0;
  131 +}
  132 +
  133 +int fdt_finish_reservemap(void *fdt)
  134 +{
  135 + return fdt_add_reservemap_entry(fdt, 0, 0);
  136 +}
  137 +
  138 +int fdt_begin_node(void *fdt, const char *name)
  139 +{
  140 + struct fdt_node_header *nh;
  141 + int namelen = strlen(name) + 1;
  142 +
  143 + FDT_SW_CHECK_HEADER(fdt);
  144 +
  145 + nh = _fdt_grab_space(fdt, sizeof(*nh) + FDT_TAGALIGN(namelen));
  146 + if (! nh)
  147 + return -FDT_ERR_NOSPACE;
  148 +
  149 + nh->tag = cpu_to_fdt32(FDT_BEGIN_NODE);
  150 + memcpy(nh->name, name, namelen);
  151 + return 0;
  152 +}
  153 +
  154 +int fdt_end_node(void *fdt)
  155 +{
  156 + uint32_t *en;
  157 +
  158 + FDT_SW_CHECK_HEADER(fdt);
  159 +
  160 + en = _fdt_grab_space(fdt, FDT_TAGSIZE);
  161 + if (! en)
  162 + return -FDT_ERR_NOSPACE;
  163 +
  164 + *en = cpu_to_fdt32(FDT_END_NODE);
  165 + return 0;
  166 +}
  167 +
  168 +static int _fdt_find_add_string(void *fdt, const char *s)
  169 +{
  170 + char *strtab = (char *)fdt + fdt_totalsize(fdt);
  171 + const char *p;
  172 + int strtabsize = fdt_size_dt_strings(fdt);
  173 + int len = strlen(s) + 1;
  174 + int struct_top, offset;
  175 +
  176 + p = _fdt_find_string(strtab - strtabsize, strtabsize, s);
  177 + if (p)
  178 + return p - strtab;
  179 +
  180 + /* Add it */
  181 + offset = -strtabsize - len;
  182 + struct_top = fdt_off_dt_struct(fdt) + fdt_size_dt_struct(fdt);
  183 + if (fdt_totalsize(fdt) + offset < struct_top)
  184 + return 0; /* no more room :( */
  185 +
  186 + memcpy(strtab + offset, s, len);
  187 + fdt_set_size_dt_strings(fdt, strtabsize + len);
  188 + return offset;
  189 +}
  190 +
  191 +int fdt_property(void *fdt, const char *name, const void *val, int len)
  192 +{
  193 + struct fdt_property *prop;
  194 + int nameoff;
  195 +
  196 + FDT_SW_CHECK_HEADER(fdt);
  197 +
  198 + nameoff = _fdt_find_add_string(fdt, name);
  199 + if (nameoff == 0)
  200 + return -FDT_ERR_NOSPACE;
  201 +
  202 + prop = _fdt_grab_space(fdt, sizeof(*prop) + FDT_TAGALIGN(len));
  203 + if (! prop)
  204 + return -FDT_ERR_NOSPACE;
  205 +
  206 + prop->tag = cpu_to_fdt32(FDT_PROP);
  207 + prop->nameoff = cpu_to_fdt32(nameoff);
  208 + prop->len = cpu_to_fdt32(len);
  209 + memcpy(prop->data, val, len);
  210 + return 0;
  211 +}
  212 +
  213 +int fdt_finish(void *fdt)
  214 +{
  215 + char *p = (char *)fdt;
  216 + uint32_t *end;
  217 + int oldstroffset, newstroffset;
  218 + uint32_t tag;
  219 + int offset, nextoffset;
  220 +
  221 + FDT_SW_CHECK_HEADER(fdt);
  222 +
  223 + /* Add terminator */
  224 + end = _fdt_grab_space(fdt, sizeof(*end));
  225 + if (! end)
  226 + return -FDT_ERR_NOSPACE;
  227 + *end = cpu_to_fdt32(FDT_END);
  228 +
  229 + /* Relocate the string table */
  230 + oldstroffset = fdt_totalsize(fdt) - fdt_size_dt_strings(fdt);
  231 + newstroffset = fdt_off_dt_struct(fdt) + fdt_size_dt_struct(fdt);
  232 + memmove(p + newstroffset, p + oldstroffset, fdt_size_dt_strings(fdt));
  233 + fdt_set_off_dt_strings(fdt, newstroffset);
  234 +
  235 + /* Walk the structure, correcting string offsets */
  236 + offset = 0;
  237 + while ((tag = fdt_next_tag(fdt, offset, &nextoffset)) != FDT_END) {
  238 + if (tag == FDT_PROP) {
  239 + struct fdt_property *prop =
  240 + _fdt_offset_ptr_w(fdt, offset);
  241 + int nameoff;
  242 +
  243 + nameoff = fdt32_to_cpu(prop->nameoff);
  244 + nameoff += fdt_size_dt_strings(fdt);
  245 + prop->nameoff = cpu_to_fdt32(nameoff);
  246 + }
  247 + offset = nextoffset;
  248 + }
  249 + if (nextoffset < 0)
  250 + return nextoffset;
  251 +
  252 + /* Finally, adjust the header */
  253 + fdt_set_totalsize(fdt, newstroffset + fdt_size_dt_strings(fdt));
  254 + fdt_set_magic(fdt, FDT_MAGIC);
  255 + return 0;
  256 +}
lib/libfdt/fdt_wip.c
  1 +/*
  2 + * libfdt - Flat Device Tree manipulation
  3 + * Copyright (C) 2006 David Gibson, IBM Corporation.
  4 + *
  5 + * libfdt is dual licensed: you can use it either under the terms of
  6 + * the GPL, or the BSD license, at your option.
  7 + *
  8 + * a) This library is free software; you can redistribute it and/or
  9 + * modify it under the terms of the GNU General Public License as
  10 + * published by the Free Software Foundation; either version 2 of the
  11 + * License, or (at your option) any later version.
  12 + *
  13 + * This library is distributed in the hope that it will be useful,
  14 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16 + * GNU General Public License for more details.
  17 + *
  18 + * You should have received a copy of the GNU General Public
  19 + * License along with this library; if not, write to the Free
  20 + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
  21 + * MA 02110-1301 USA
  22 + *
  23 + * Alternatively,
  24 + *
  25 + * b) Redistribution and use in source and binary forms, with or
  26 + * without modification, are permitted provided that the following
  27 + * conditions are met:
  28 + *
  29 + * 1. Redistributions of source code must retain the above
  30 + * copyright notice, this list of conditions and the following
  31 + * disclaimer.
  32 + * 2. Redistributions in binary form must reproduce the above
  33 + * copyright notice, this list of conditions and the following
  34 + * disclaimer in the documentation and/or other materials
  35 + * provided with the distribution.
  36 + *
  37 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
  38 + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
  39 + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
  40 + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  41 + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
  42 + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  43 + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  44 + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  45 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  46 + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  47 + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
  48 + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
  49 + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  50 + */
  51 +#include "libfdt_env.h"
  52 +
  53 +#ifndef USE_HOSTCC
  54 +#include <fdt.h>
  55 +#include <libfdt.h>
  56 +#else
  57 +#include "fdt_host.h"
  58 +#endif
  59 +
  60 +#include "libfdt_internal.h"
  61 +
  62 +int fdt_setprop_inplace(void *fdt, int nodeoffset, const char *name,
  63 + const void *val, int len)
  64 +{
  65 + void *propval;
  66 + int proplen;
  67 +
  68 + propval = fdt_getprop_w(fdt, nodeoffset, name, &proplen);
  69 + if (! propval)
  70 + return proplen;
  71 +
  72 + if (proplen != len)
  73 + return -FDT_ERR_NOSPACE;
  74 +
  75 + memcpy(propval, val, len);
  76 + return 0;
  77 +}
  78 +
  79 +static void _fdt_nop_region(void *start, int len)
  80 +{
  81 + uint32_t *p;
  82 +
  83 + for (p = start; (char *)p < ((char *)start + len); p++)
  84 + *p = cpu_to_fdt32(FDT_NOP);
  85 +}
  86 +
  87 +int fdt_nop_property(void *fdt, int nodeoffset, const char *name)
  88 +{
  89 + struct fdt_property *prop;
  90 + int len;
  91 +
  92 + prop = fdt_get_property_w(fdt, nodeoffset, name, &len);
  93 + if (! prop)
  94 + return len;
  95 +
  96 + _fdt_nop_region(prop, len + sizeof(*prop));
  97 +
  98 + return 0;
  99 +}
  100 +
  101 +int _fdt_node_end_offset(void *fdt, int offset)
  102 +{
  103 + int depth = 0;
  104 +
  105 + while ((offset >= 0) && (depth >= 0))
  106 + offset = fdt_next_node(fdt, offset, &depth);
  107 +
  108 + return offset;
  109 +}
  110 +
  111 +int fdt_nop_node(void *fdt, int nodeoffset)
  112 +{
  113 + int endoffset;
  114 +
  115 + endoffset = _fdt_node_end_offset(fdt, nodeoffset);
  116 + if (endoffset < 0)
  117 + return endoffset;
  118 +
  119 + _fdt_nop_region(fdt_offset_ptr_w(fdt, nodeoffset, 0),
  120 + endoffset - nodeoffset);
  121 + return 0;
  122 +}
lib/libfdt/libfdt_internal.h
  1 +#ifndef _LIBFDT_INTERNAL_H
  2 +#define _LIBFDT_INTERNAL_H
  3 +/*
  4 + * libfdt - Flat Device Tree manipulation
  5 + * Copyright (C) 2006 David Gibson, IBM Corporation.
  6 + *
  7 + * libfdt is dual licensed: you can use it either under the terms of
  8 + * the GPL, or the BSD license, at your option.
  9 + *
  10 + * a) This library is free software; you can redistribute it and/or
  11 + * modify it under the terms of the GNU General Public License as
  12 + * published by the Free Software Foundation; either version 2 of the
  13 + * License, or (at your option) any later version.
  14 + *
  15 + * This library is distributed in the hope that it will be useful,
  16 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  17 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  18 + * GNU General Public License for more details.
  19 + *
  20 + * You should have received a copy of the GNU General Public
  21 + * License along with this library; if not, write to the Free
  22 + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
  23 + * MA 02110-1301 USA
  24 + *
  25 + * Alternatively,
  26 + *
  27 + * b) Redistribution and use in source and binary forms, with or
  28 + * without modification, are permitted provided that the following
  29 + * conditions are met:
  30 + *
  31 + * 1. Redistributions of source code must retain the above
  32 + * copyright notice, this list of conditions and the following
  33 + * disclaimer.
  34 + * 2. Redistributions in binary form must reproduce the above
  35 + * copyright notice, this list of conditions and the following
  36 + * disclaimer in the documentation and/or other materials
  37 + * provided with the distribution.
  38 + *
  39 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
  40 + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
  41 + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
  42 + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  43 + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
  44 + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  45 + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  46 + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  47 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  48 + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  49 + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
  50 + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
  51 + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  52 + */
  53 +#include <fdt.h>
  54 +
  55 +#define FDT_ALIGN(x, a) (((x) + (a) - 1) & ~((a) - 1))
  56 +#define FDT_TAGALIGN(x) (FDT_ALIGN((x), FDT_TAGSIZE))
  57 +
  58 +#define FDT_CHECK_HEADER(fdt) \
  59 + { \
  60 + int err; \
  61 + if ((err = fdt_check_header(fdt)) != 0) \
  62 + return err; \
  63 + }
  64 +
  65 +int _fdt_check_node_offset(const void *fdt, int offset);
  66 +const char *_fdt_find_string(const char *strtab, int tabsize, const char *s);
  67 +int _fdt_node_end_offset(void *fdt, int nodeoffset);
  68 +
  69 +static inline const void *_fdt_offset_ptr(const void *fdt, int offset)
  70 +{
  71 + return (const char *)fdt + fdt_off_dt_struct(fdt) + offset;
  72 +}
  73 +
  74 +static inline void *_fdt_offset_ptr_w(void *fdt, int offset)
  75 +{
  76 + return (void *)(uintptr_t)_fdt_offset_ptr(fdt, offset);
  77 +}
  78 +
  79 +static inline const struct fdt_reserve_entry *_fdt_mem_rsv(const void *fdt, int n)
  80 +{
  81 + const struct fdt_reserve_entry *rsv_table =
  82 + (const struct fdt_reserve_entry *)
  83 + ((const char *)fdt + fdt_off_mem_rsvmap(fdt));
  84 +
  85 + return rsv_table + n;
  86 +}
  87 +static inline struct fdt_reserve_entry *_fdt_mem_rsv_w(void *fdt, int n)
  88 +{
  89 + return (void *)(uintptr_t)_fdt_mem_rsv(fdt, n);
  90 +}
  91 +
  92 +#define FDT_SW_MAGIC (~FDT_MAGIC)
  93 +
  94 +#endif /* _LIBFDT_INTERNAL_H */
libfdt/Makefile
1   -#
2   -# (C) Copyright 2000-2007
3   -# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
4   -#
5   -# See file CREDITS for list of people who contributed to this
6   -# project.
7   -#
8   -# This program is free software; you can redistribute it and/or
9   -# modify it under the terms of the GNU General Public License as
10   -# published by the Free Software Foundation; either version 2 of
11   -# the License, or (at your option) any later version.
12   -#
13   -# This program is distributed in the hope that it will be useful,
14   -# but WITHOUT ANY WARRANTY; without even the implied warranty of
15   -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16   -# GNU General Public License for more details.
17   -#
18   -# You should have received a copy of the GNU General Public License
19   -# along with this program; if not, write to the Free Software
20   -# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
21   -# MA 02111-1307 USA
22   -#
23   -
24   -include $(TOPDIR)/config.mk
25   -
26   -LIB = $(obj)libfdt.a
27   -
28   -SOBJS =
29   -
30   -COBJS-libfdt += fdt.o fdt_ro.o fdt_rw.o fdt_strerror.o fdt_sw.o fdt_wip.o
31   -
32   -COBJS-$(CONFIG_OF_LIBFDT) += $(COBJS-libfdt)
33   -COBJS-$(CONFIG_FIT) += $(COBJS-libfdt)
34   -
35   -
36   -COBJS := $(sort $(COBJS-y))
37   -SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c)
38   -OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS))
39   -
40   -$(LIB): $(obj).depend $(OBJS)
41   - $(AR) $(ARFLAGS) $@ $(OBJS)
42   -
43   -#########################################################################
44   -
45   -# defines $(obj).depend target
46   -include $(SRCTREE)/rules.mk
47   -
48   -sinclude $(obj).depend
49   -
50   -#########################################################################
libfdt/README
1   -The libfdt functionality was written by David Gibson. The original
2   -source came from the git repository:
3   -
4   -URL: git://ozlabs.org/home/dgibson/git/libfdt.git
5   -
6   -author David Gibson <dgibson@sneetch.(none)>
7   - Fri, 23 Mar 2007 04:16:54 +0000 (15:16 +1100)
8   -committer David Gibson <dgibson@sneetch.(none)>
9   - Fri, 23 Mar 2007 04:16:54 +0000 (15:16 +1100)
10   -commit 857f54e79f74429af20c2b5ecc00ee98af6a3b8b
11   -tree 2f648f0f88225a51ded452968d28b4402df8ade0
12   -parent 07a12a08005f3b5cd9337900a6551e450c07b515
13   -
14   -To adapt for u-boot usage, only the applicable files were copied and
15   -imported into the u-boot git repository.
16   -Omitted:
17   -* GPL - u-boot comes with a copy of the GPL license
18   -* test subdirectory - not directly useful for u-boot
19   -
20   -After importing, other customizations were performed. See the git log
21   -for details.
22   -
23   -Jerry Van Baren
libfdt/fdt.c
1   -/*
2   - * libfdt - Flat Device Tree manipulation
3   - * Copyright (C) 2006 David Gibson, IBM Corporation.
4   - *
5   - * libfdt is dual licensed: you can use it either under the terms of
6   - * the GPL, or the BSD license, at your option.
7   - *
8   - * a) This library is free software; you can redistribute it and/or
9   - * modify it under the terms of the GNU General Public License as
10   - * published by the Free Software Foundation; either version 2 of the
11   - * License, or (at your option) any later version.
12   - *
13   - * This library is distributed in the hope that it will be useful,
14   - * but WITHOUT ANY WARRANTY; without even the implied warranty of
15   - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16   - * GNU General Public License for more details.
17   - *
18   - * You should have received a copy of the GNU General Public
19   - * License along with this library; if not, write to the Free
20   - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
21   - * MA 02110-1301 USA
22   - *
23   - * Alternatively,
24   - *
25   - * b) Redistribution and use in source and binary forms, with or
26   - * without modification, are permitted provided that the following
27   - * conditions are met:
28   - *
29   - * 1. Redistributions of source code must retain the above
30   - * copyright notice, this list of conditions and the following
31   - * disclaimer.
32   - * 2. Redistributions in binary form must reproduce the above
33   - * copyright notice, this list of conditions and the following
34   - * disclaimer in the documentation and/or other materials
35   - * provided with the distribution.
36   - *
37   - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
38   - * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
39   - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
40   - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
41   - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
42   - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
43   - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
44   - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
45   - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
46   - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
47   - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
48   - * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
49   - * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
50   - */
51   -#include "libfdt_env.h"
52   -
53   -#ifndef USE_HOSTCC
54   -#include <fdt.h>
55   -#include <libfdt.h>
56   -#else
57   -#include "fdt_host.h"
58   -#endif
59   -
60   -#include "libfdt_internal.h"
61   -
62   -int fdt_check_header(const void *fdt)
63   -{
64   - if (fdt_magic(fdt) == FDT_MAGIC) {
65   - /* Complete tree */
66   - if (fdt_version(fdt) < FDT_FIRST_SUPPORTED_VERSION)
67   - return -FDT_ERR_BADVERSION;
68   - if (fdt_last_comp_version(fdt) > FDT_LAST_SUPPORTED_VERSION)
69   - return -FDT_ERR_BADVERSION;
70   - } else if (fdt_magic(fdt) == FDT_SW_MAGIC) {
71   - /* Unfinished sequential-write blob */
72   - if (fdt_size_dt_struct(fdt) == 0)
73   - return -FDT_ERR_BADSTATE;
74   - } else {
75   - return -FDT_ERR_BADMAGIC;
76   - }
77   -
78   - return 0;
79   -}
80   -
81   -const void *fdt_offset_ptr(const void *fdt, int offset, unsigned int len)
82   -{
83   - const char *p;
84   -
85   - if (fdt_version(fdt) >= 0x11)
86   - if (((offset + len) < offset)
87   - || ((offset + len) > fdt_size_dt_struct(fdt)))
88   - return NULL;
89   -
90   - p = _fdt_offset_ptr(fdt, offset);
91   -
92   - if (p + len < p)
93   - return NULL;
94   - return p;
95   -}
96   -
97   -uint32_t fdt_next_tag(const void *fdt, int startoffset, int *nextoffset)
98   -{
99   - const uint32_t *tagp, *lenp;
100   - uint32_t tag;
101   - int offset = startoffset;
102   - const char *p;
103   -
104   - *nextoffset = -FDT_ERR_TRUNCATED;
105   - tagp = fdt_offset_ptr(fdt, offset, FDT_TAGSIZE);
106   - if (!tagp)
107   - return FDT_END; /* premature end */
108   - tag = fdt32_to_cpu(*tagp);
109   - offset += FDT_TAGSIZE;
110   -
111   - *nextoffset = -FDT_ERR_BADSTRUCTURE;
112   - switch (tag) {
113   - case FDT_BEGIN_NODE:
114   - /* skip name */
115   - do {
116   - p = fdt_offset_ptr(fdt, offset++, 1);
117   - } while (p && (*p != '\0'));
118   - if (!p)
119   - return FDT_END; /* premature end */
120   - break;
121   -
122   - case FDT_PROP:
123   - lenp = fdt_offset_ptr(fdt, offset, sizeof(*lenp));
124   - if (!lenp)
125   - return FDT_END; /* premature end */
126   - /* skip-name offset, length and value */
127   - offset += sizeof(struct fdt_property) - FDT_TAGSIZE
128   - + fdt32_to_cpu(*lenp);
129   - break;
130   -
131   - case FDT_END:
132   - case FDT_END_NODE:
133   - case FDT_NOP:
134   - break;
135   -
136   - default:
137   - return FDT_END;
138   - }
139   -
140   - if (!fdt_offset_ptr(fdt, startoffset, offset - startoffset))
141   - return FDT_END; /* premature end */
142   -
143   - *nextoffset = FDT_TAGALIGN(offset);
144   - return tag;
145   -}
146   -
147   -int _fdt_check_node_offset(const void *fdt, int offset)
148   -{
149   - if ((offset < 0) || (offset % FDT_TAGSIZE)
150   - || (fdt_next_tag(fdt, offset, &offset) != FDT_BEGIN_NODE))
151   - return -FDT_ERR_BADOFFSET;
152   -
153   - return offset;
154   -}
155   -
156   -int fdt_next_node(const void *fdt, int offset, int *depth)
157   -{
158   - int nextoffset = 0;
159   - uint32_t tag;
160   -
161   - if (offset >= 0)
162   - if ((nextoffset = _fdt_check_node_offset(fdt, offset)) < 0)
163   - return nextoffset;
164   -
165   - do {
166   - offset = nextoffset;
167   - tag = fdt_next_tag(fdt, offset, &nextoffset);
168   -
169   - switch (tag) {
170   - case FDT_PROP:
171   - case FDT_NOP:
172   - break;
173   -
174   - case FDT_BEGIN_NODE:
175   - if (depth)
176   - (*depth)++;
177   - break;
178   -
179   - case FDT_END_NODE:
180   - if (depth && ((--(*depth)) < 0))
181   - return nextoffset;
182   - break;
183   -
184   - case FDT_END:
185   - if ((nextoffset >= 0)
186   - || ((nextoffset == -FDT_ERR_TRUNCATED) && !depth))
187   - return -FDT_ERR_NOTFOUND;
188   - else
189   - return nextoffset;
190   - }
191   - } while (tag != FDT_BEGIN_NODE);
192   -
193   - return offset;
194   -}
195   -
196   -const char *_fdt_find_string(const char *strtab, int tabsize, const char *s)
197   -{
198   - int len = strlen(s) + 1;
199   - const char *last = strtab + tabsize - len;
200   - const char *p;
201   -
202   - for (p = strtab; p <= last; p++)
203   - if (memcmp(p, s, len) == 0)
204   - return p;
205   - return NULL;
206   -}
207   -
208   -int fdt_move(const void *fdt, void *buf, int bufsize)
209   -{
210   - FDT_CHECK_HEADER(fdt);
211   -
212   - if (fdt_totalsize(fdt) > bufsize)
213   - return -FDT_ERR_NOSPACE;
214   -
215   - memmove(buf, fdt, fdt_totalsize(fdt));
216   - return 0;
217   -}
libfdt/fdt_ro.c
1   -/*
2   - * libfdt - Flat Device Tree manipulation
3   - * Copyright (C) 2006 David Gibson, IBM Corporation.
4   - *
5   - * libfdt is dual licensed: you can use it either under the terms of
6   - * the GPL, or the BSD license, at your option.
7   - *
8   - * a) This library is free software; you can redistribute it and/or
9   - * modify it under the terms of the GNU General Public License as
10   - * published by the Free Software Foundation; either version 2 of the
11   - * License, or (at your option) any later version.
12   - *
13   - * This library is distributed in the hope that it will be useful,
14   - * but WITHOUT ANY WARRANTY; without even the implied warranty of
15   - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16   - * GNU General Public License for more details.
17   - *
18   - * You should have received a copy of the GNU General Public
19   - * License along with this library; if not, write to the Free
20   - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
21   - * MA 02110-1301 USA
22   - *
23   - * Alternatively,
24   - *
25   - * b) Redistribution and use in source and binary forms, with or
26   - * without modification, are permitted provided that the following
27   - * conditions are met:
28   - *
29   - * 1. Redistributions of source code must retain the above
30   - * copyright notice, this list of conditions and the following
31   - * disclaimer.
32   - * 2. Redistributions in binary form must reproduce the above
33   - * copyright notice, this list of conditions and the following
34   - * disclaimer in the documentation and/or other materials
35   - * provided with the distribution.
36   - *
37   - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
38   - * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
39   - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
40   - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
41   - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
42   - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
43   - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
44   - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
45   - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
46   - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
47   - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
48   - * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
49   - * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
50   - */
51   -#include "libfdt_env.h"
52   -
53   -#ifndef USE_HOSTCC
54   -#include <fdt.h>
55   -#include <libfdt.h>
56   -#else
57   -#include "fdt_host.h"
58   -#endif
59   -
60   -#include "libfdt_internal.h"
61   -
62   -static int _fdt_nodename_eq(const void *fdt, int offset,
63   - const char *s, int len)
64   -{
65   - const char *p = fdt_offset_ptr(fdt, offset + FDT_TAGSIZE, len+1);
66   -
67   - if (! p)
68   - /* short match */
69   - return 0;
70   -
71   - if (memcmp(p, s, len) != 0)
72   - return 0;
73   -
74   - if (p[len] == '\0')
75   - return 1;
76   - else if (!memchr(s, '@', len) && (p[len] == '@'))
77   - return 1;
78   - else
79   - return 0;
80   -}
81   -
82   -const char *fdt_string(const void *fdt, int stroffset)
83   -{
84   - return (const char *)fdt + fdt_off_dt_strings(fdt) + stroffset;
85   -}
86   -
87   -static int _fdt_string_eq(const void *fdt, int stroffset,
88   - const char *s, int len)
89   -{
90   - const char *p = fdt_string(fdt, stroffset);
91   -
92   - return (strlen(p) == len) && (memcmp(p, s, len) == 0);
93   -}
94   -
95   -int fdt_get_mem_rsv(const void *fdt, int n, uint64_t *address, uint64_t *size)
96   -{
97   - FDT_CHECK_HEADER(fdt);
98   - *address = fdt64_to_cpu(_fdt_mem_rsv(fdt, n)->address);
99   - *size = fdt64_to_cpu(_fdt_mem_rsv(fdt, n)->size);
100   - return 0;
101   -}
102   -
103   -int fdt_num_mem_rsv(const void *fdt)
104   -{
105   - int i = 0;
106   -
107   - while (fdt64_to_cpu(_fdt_mem_rsv(fdt, i)->size) != 0)
108   - i++;
109   - return i;
110   -}
111   -
112   -int fdt_subnode_offset_namelen(const void *fdt, int offset,
113   - const char *name, int namelen)
114   -{
115   - int depth;
116   -
117   - FDT_CHECK_HEADER(fdt);
118   -
119   - for (depth = 0;
120   - (offset >= 0) && (depth >= 0);
121   - offset = fdt_next_node(fdt, offset, &depth))
122   - if ((depth == 1)
123   - && _fdt_nodename_eq(fdt, offset, name, namelen))
124   - return offset;
125   -
126   - if (depth < 0)
127   - return -FDT_ERR_NOTFOUND;
128   - return offset; /* error */
129   -}
130   -
131   -int fdt_subnode_offset(const void *fdt, int parentoffset,
132   - const char *name)
133   -{
134   - return fdt_subnode_offset_namelen(fdt, parentoffset, name, strlen(name));
135   -}
136   -
137   -int fdt_path_offset(const void *fdt, const char *path)
138   -{
139   - const char *end = path + strlen(path);
140   - const char *p = path;
141   - int offset = 0;
142   -
143   - FDT_CHECK_HEADER(fdt);
144   -
145   - /* see if we have an alias */
146   - if (*path != '/') {
147   - const char *q = strchr(path, '/');
148   -
149   - if (!q)
150   - q = end;
151   -
152   - p = fdt_get_alias_namelen(fdt, p, q - p);
153   - if (!p)
154   - return -FDT_ERR_BADPATH;
155   - offset = fdt_path_offset(fdt, p);
156   -
157   - p = q;
158   - }
159   -
160   - while (*p) {
161   - const char *q;
162   -
163   - while (*p == '/')
164   - p++;
165   - if (! *p)
166   - return offset;
167   - q = strchr(p, '/');
168   - if (! q)
169   - q = end;
170   -
171   - offset = fdt_subnode_offset_namelen(fdt, offset, p, q-p);
172   - if (offset < 0)
173   - return offset;
174   -
175   - p = q;
176   - }
177   -
178   - return offset;
179   -}
180   -
181   -const char *fdt_get_name(const void *fdt, int nodeoffset, int *len)
182   -{
183   - const struct fdt_node_header *nh = _fdt_offset_ptr(fdt, nodeoffset);
184   - int err;
185   -
186   - if (((err = fdt_check_header(fdt)) != 0)
187   - || ((err = _fdt_check_node_offset(fdt, nodeoffset)) < 0))
188   - goto fail;
189   -
190   - if (len)
191   - *len = strlen(nh->name);
192   -
193   - return nh->name;
194   -
195   - fail:
196   - if (len)
197   - *len = err;
198   - return NULL;
199   -}
200   -
201   -const struct fdt_property *fdt_get_property_namelen(const void *fdt,
202   - int nodeoffset,
203   - const char *name,
204   - int namelen, int *lenp)
205   -{
206   - uint32_t tag;
207   - const struct fdt_property *prop;
208   - int offset, nextoffset;
209   - int err;
210   -
211   - if (((err = fdt_check_header(fdt)) != 0)
212   - || ((err = _fdt_check_node_offset(fdt, nodeoffset)) < 0))
213   - goto fail;
214   -
215   - nextoffset = err;
216   - do {
217   - offset = nextoffset;
218   -
219   - tag = fdt_next_tag(fdt, offset, &nextoffset);
220   - switch (tag) {
221   - case FDT_END:
222   - if (nextoffset < 0)
223   - err = nextoffset;
224   - else
225   - /* FDT_END tag with unclosed nodes */
226   - err = -FDT_ERR_BADSTRUCTURE;
227   - goto fail;
228   -
229   - case FDT_PROP:
230   - prop = _fdt_offset_ptr(fdt, offset);
231   - if (_fdt_string_eq(fdt, fdt32_to_cpu(prop->nameoff),
232   - name, namelen)) {
233   - /* Found it! */
234   - if (lenp)
235   - *lenp = fdt32_to_cpu(prop->len);
236   -
237   - return prop;
238   - }
239   - break;
240   - }
241   - } while ((tag != FDT_BEGIN_NODE) && (tag != FDT_END_NODE));
242   -
243   - err = -FDT_ERR_NOTFOUND;
244   - fail:
245   - if (lenp)
246   - *lenp = err;
247   - return NULL;
248   -}
249   -
250   -const struct fdt_property *fdt_get_property(const void *fdt,
251   - int nodeoffset,
252   - const char *name, int *lenp)
253   -{
254   - return fdt_get_property_namelen(fdt, nodeoffset, name,
255   - strlen(name), lenp);
256   -}
257   -
258   -const void *fdt_getprop_namelen(const void *fdt, int nodeoffset,
259   - const char *name, int namelen, int *lenp)
260   -{
261   - const struct fdt_property *prop;
262   -
263   - prop = fdt_get_property_namelen(fdt, nodeoffset, name, namelen, lenp);
264   - if (! prop)
265   - return NULL;
266   -
267   - return prop->data;
268   -}
269   -
270   -const void *fdt_getprop(const void *fdt, int nodeoffset,
271   - const char *name, int *lenp)
272   -{
273   - return fdt_getprop_namelen(fdt, nodeoffset, name, strlen(name), lenp);
274   -}
275   -
276   -uint32_t fdt_get_phandle(const void *fdt, int nodeoffset)
277   -{
278   - const uint32_t *php;
279   - int len;
280   -
281   - php = fdt_getprop(fdt, nodeoffset, "linux,phandle", &len);
282   - if (!php || (len != sizeof(*php)))
283   - return 0;
284   -
285   - return fdt32_to_cpu(*php);
286   -}
287   -
288   -const char *fdt_get_alias_namelen(const void *fdt,
289   - const char *name, int namelen)
290   -{
291   - int aliasoffset;
292   -
293   - aliasoffset = fdt_path_offset(fdt, "/aliases");
294   - if (aliasoffset < 0)
295   - return NULL;
296   -
297   - return fdt_getprop_namelen(fdt, aliasoffset, name, namelen, NULL);
298   -}
299   -
300   -const char *fdt_get_alias(const void *fdt, const char *name)
301   -{
302   - return fdt_get_alias_namelen(fdt, name, strlen(name));
303   -}
304   -
305   -int fdt_get_path(const void *fdt, int nodeoffset, char *buf, int buflen)
306   -{
307   - int pdepth = 0, p = 0;
308   - int offset, depth, namelen;
309   - const char *name;
310   -
311   - FDT_CHECK_HEADER(fdt);
312   -
313   - if (buflen < 2)
314   - return -FDT_ERR_NOSPACE;
315   -
316   - for (offset = 0, depth = 0;
317   - (offset >= 0) && (offset <= nodeoffset);
318   - offset = fdt_next_node(fdt, offset, &depth)) {
319   - while (pdepth > depth) {
320   - do {
321   - p--;
322   - } while (buf[p-1] != '/');
323   - pdepth--;
324   - }
325   -
326   - if (pdepth >= depth) {
327   - name = fdt_get_name(fdt, offset, &namelen);
328   - if (!name)
329   - return namelen;
330   - if ((p + namelen + 1) <= buflen) {
331   - memcpy(buf + p, name, namelen);
332   - p += namelen;
333   - buf[p++] = '/';
334   - pdepth++;
335   - }
336   - }
337   -
338   - if (offset == nodeoffset) {
339   - if (pdepth < (depth + 1))
340   - return -FDT_ERR_NOSPACE;
341   -
342   - if (p > 1) /* special case so that root path is "/", not "" */
343   - p--;
344   - buf[p] = '\0';
345   - return 0;
346   - }
347   - }
348   -
349   - if ((offset == -FDT_ERR_NOTFOUND) || (offset >= 0))
350   - return -FDT_ERR_BADOFFSET;
351   - else if (offset == -FDT_ERR_BADOFFSET)
352   - return -FDT_ERR_BADSTRUCTURE;
353   -
354   - return offset; /* error from fdt_next_node() */
355   -}
356   -
357   -int fdt_supernode_atdepth_offset(const void *fdt, int nodeoffset,
358   - int supernodedepth, int *nodedepth)
359   -{
360   - int offset, depth;
361   - int supernodeoffset = -FDT_ERR_INTERNAL;
362   -
363   - FDT_CHECK_HEADER(fdt);
364   -
365   - if (supernodedepth < 0)
366   - return -FDT_ERR_NOTFOUND;
367   -
368   - for (offset = 0, depth = 0;
369   - (offset >= 0) && (offset <= nodeoffset);
370   - offset = fdt_next_node(fdt, offset, &depth)) {
371   - if (depth == supernodedepth)
372   - supernodeoffset = offset;
373   -
374   - if (offset == nodeoffset) {
375   - if (nodedepth)
376   - *nodedepth = depth;
377   -
378   - if (supernodedepth > depth)
379   - return -FDT_ERR_NOTFOUND;
380   - else
381   - return supernodeoffset;
382   - }
383   - }
384   -
385   - if ((offset == -FDT_ERR_NOTFOUND) || (offset >= 0))
386   - return -FDT_ERR_BADOFFSET;
387   - else if (offset == -FDT_ERR_BADOFFSET)
388   - return -FDT_ERR_BADSTRUCTURE;
389   -
390   - return offset; /* error from fdt_next_node() */
391   -}
392   -
393   -int fdt_node_depth(const void *fdt, int nodeoffset)
394   -{
395   - int nodedepth;
396   - int err;
397   -
398   - err = fdt_supernode_atdepth_offset(fdt, nodeoffset, 0, &nodedepth);
399   - if (err)
400   - return (err < 0) ? err : -FDT_ERR_INTERNAL;
401   - return nodedepth;
402   -}
403   -
404   -int fdt_parent_offset(const void *fdt, int nodeoffset)
405   -{
406   - int nodedepth = fdt_node_depth(fdt, nodeoffset);
407   -
408   - if (nodedepth < 0)
409   - return nodedepth;
410   - return fdt_supernode_atdepth_offset(fdt, nodeoffset,
411   - nodedepth - 1, NULL);
412   -}
413   -
414   -int fdt_node_offset_by_prop_value(const void *fdt, int startoffset,
415   - const char *propname,
416   - const void *propval, int proplen)
417   -{
418   - int offset;
419   - const void *val;
420   - int len;
421   -
422   - FDT_CHECK_HEADER(fdt);
423   -
424   - /* FIXME: The algorithm here is pretty horrible: we scan each
425   - * property of a node in fdt_getprop(), then if that didn't
426   - * find what we want, we scan over them again making our way
427   - * to the next node. Still it's the easiest to implement
428   - * approach; performance can come later. */
429   - for (offset = fdt_next_node(fdt, startoffset, NULL);
430   - offset >= 0;
431   - offset = fdt_next_node(fdt, offset, NULL)) {
432   - val = fdt_getprop(fdt, offset, propname, &len);
433   - if (val && (len == proplen)
434   - && (memcmp(val, propval, len) == 0))
435   - return offset;
436   - }
437   -
438   - return offset; /* error from fdt_next_node() */
439   -}
440   -
441   -int fdt_node_offset_by_phandle(const void *fdt, uint32_t phandle)
442   -{
443   - if ((phandle == 0) || (phandle == -1))
444   - return -FDT_ERR_BADPHANDLE;
445   - phandle = cpu_to_fdt32(phandle);
446   - return fdt_node_offset_by_prop_value(fdt, -1, "linux,phandle",
447   - &phandle, sizeof(phandle));
448   -}
449   -
450   -static int _fdt_stringlist_contains(const char *strlist, int listlen,
451   - const char *str)
452   -{
453   - int len = strlen(str);
454   - const char *p;
455   -
456   - while (listlen >= len) {
457   - if (memcmp(str, strlist, len+1) == 0)
458   - return 1;
459   - p = memchr(strlist, '\0', listlen);
460   - if (!p)
461   - return 0; /* malformed strlist.. */
462   - listlen -= (p-strlist) + 1;
463   - strlist = p + 1;
464   - }
465   - return 0;
466   -}
467   -
468   -int fdt_node_check_compatible(const void *fdt, int nodeoffset,
469   - const char *compatible)
470   -{
471   - const void *prop;
472   - int len;
473   -
474   - prop = fdt_getprop(fdt, nodeoffset, "compatible", &len);
475   - if (!prop)
476   - return len;
477   - if (_fdt_stringlist_contains(prop, len, compatible))
478   - return 0;
479   - else
480   - return 1;
481   -}
482   -
483   -int fdt_node_offset_by_compatible(const void *fdt, int startoffset,
484   - const char *compatible)
485   -{
486   - int offset, err;
487   -
488   - FDT_CHECK_HEADER(fdt);
489   -
490   - /* FIXME: The algorithm here is pretty horrible: we scan each
491   - * property of a node in fdt_node_check_compatible(), then if
492   - * that didn't find what we want, we scan over them again
493   - * making our way to the next node. Still it's the easiest to
494   - * implement approach; performance can come later. */
495   - for (offset = fdt_next_node(fdt, startoffset, NULL);
496   - offset >= 0;
497   - offset = fdt_next_node(fdt, offset, NULL)) {
498   - err = fdt_node_check_compatible(fdt, offset, compatible);
499   - if ((err < 0) && (err != -FDT_ERR_NOTFOUND))
500   - return err;
501   - else if (err == 0)
502   - return offset;
503   - }
504   -
505   - return offset; /* error from fdt_next_node() */
506   -}
libfdt/fdt_rw.c
1   -/*
2   - * libfdt - Flat Device Tree manipulation
3   - * Copyright (C) 2006 David Gibson, IBM Corporation.
4   - *
5   - * libfdt is dual licensed: you can use it either under the terms of
6   - * the GPL, or the BSD license, at your option.
7   - *
8   - * a) This library is free software; you can redistribute it and/or
9   - * modify it under the terms of the GNU General Public License as
10   - * published by the Free Software Foundation; either version 2 of the
11   - * License, or (at your option) any later version.
12   - *
13   - * This library is distributed in the hope that it will be useful,
14   - * but WITHOUT ANY WARRANTY; without even the implied warranty of
15   - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16   - * GNU General Public License for more details.
17   - *
18   - * You should have received a copy of the GNU General Public
19   - * License along with this library; if not, write to the Free
20   - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
21   - * MA 02110-1301 USA
22   - *
23   - * Alternatively,
24   - *
25   - * b) Redistribution and use in source and binary forms, with or
26   - * without modification, are permitted provided that the following
27   - * conditions are met:
28   - *
29   - * 1. Redistributions of source code must retain the above
30   - * copyright notice, this list of conditions and the following
31   - * disclaimer.
32   - * 2. Redistributions in binary form must reproduce the above
33   - * copyright notice, this list of conditions and the following
34   - * disclaimer in the documentation and/or other materials
35   - * provided with the distribution.
36   - *
37   - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
38   - * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
39   - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
40   - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
41   - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
42   - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
43   - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
44   - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
45   - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
46   - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
47   - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
48   - * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
49   - * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
50   - */
51   -#include "libfdt_env.h"
52   -
53   -#ifndef USE_HOSTCC
54   -#include <fdt.h>
55   -#include <libfdt.h>
56   -#else
57   -#include "fdt_host.h"
58   -#endif
59   -
60   -#include "libfdt_internal.h"
61   -
62   -static int _fdt_blocks_misordered(const void *fdt,
63   - int mem_rsv_size, int struct_size)
64   -{
65   - return (fdt_off_mem_rsvmap(fdt) < FDT_ALIGN(sizeof(struct fdt_header), 8))
66   - || (fdt_off_dt_struct(fdt) <
67   - (fdt_off_mem_rsvmap(fdt) + mem_rsv_size))
68   - || (fdt_off_dt_strings(fdt) <
69   - (fdt_off_dt_struct(fdt) + struct_size))
70   - || (fdt_totalsize(fdt) <
71   - (fdt_off_dt_strings(fdt) + fdt_size_dt_strings(fdt)));
72   -}
73   -
74   -static int _fdt_rw_check_header(void *fdt)
75   -{
76   - FDT_CHECK_HEADER(fdt);
77   -
78   - if (fdt_version(fdt) < 17)
79   - return -FDT_ERR_BADVERSION;
80   - if (_fdt_blocks_misordered(fdt, sizeof(struct fdt_reserve_entry),
81   - fdt_size_dt_struct(fdt)))
82   - return -FDT_ERR_BADLAYOUT;
83   - if (fdt_version(fdt) > 17)
84   - fdt_set_version(fdt, 17);
85   -
86   - return 0;
87   -}
88   -
89   -#define FDT_RW_CHECK_HEADER(fdt) \
90   - { \
91   - int err; \
92   - if ((err = _fdt_rw_check_header(fdt)) != 0) \
93   - return err; \
94   - }
95   -
96   -static inline int _fdt_data_size(void *fdt)
97   -{
98   - return fdt_off_dt_strings(fdt) + fdt_size_dt_strings(fdt);
99   -}
100   -
101   -static int _fdt_splice(void *fdt, void *splicepoint, int oldlen, int newlen)
102   -{
103   - char *p = splicepoint;
104   - char *end = (char *)fdt + _fdt_data_size(fdt);
105   -
106   - if (((p + oldlen) < p) || ((p + oldlen) > end))
107   - return -FDT_ERR_BADOFFSET;
108   - if ((end - oldlen + newlen) > ((char *)fdt + fdt_totalsize(fdt)))
109   - return -FDT_ERR_NOSPACE;
110   - memmove(p + newlen, p + oldlen, end - p - oldlen);
111   - return 0;
112   -}
113   -
114   -static int _fdt_splice_mem_rsv(void *fdt, struct fdt_reserve_entry *p,
115   - int oldn, int newn)
116   -{
117   - int delta = (newn - oldn) * sizeof(*p);
118   - int err;
119   - err = _fdt_splice(fdt, p, oldn * sizeof(*p), newn * sizeof(*p));
120   - if (err)
121   - return err;
122   - fdt_set_off_dt_struct(fdt, fdt_off_dt_struct(fdt) + delta);
123   - fdt_set_off_dt_strings(fdt, fdt_off_dt_strings(fdt) + delta);
124   - return 0;
125   -}
126   -
127   -static int _fdt_splice_struct(void *fdt, void *p,
128   - int oldlen, int newlen)
129   -{
130   - int delta = newlen - oldlen;
131   - int err;
132   -
133   - if ((err = _fdt_splice(fdt, p, oldlen, newlen)))
134   - return err;
135   -
136   - fdt_set_size_dt_struct(fdt, fdt_size_dt_struct(fdt) + delta);
137   - fdt_set_off_dt_strings(fdt, fdt_off_dt_strings(fdt) + delta);
138   - return 0;
139   -}
140   -
141   -static int _fdt_splice_string(void *fdt, int newlen)
142   -{
143   - void *p = (char *)fdt
144   - + fdt_off_dt_strings(fdt) + fdt_size_dt_strings(fdt);
145   - int err;
146   -
147   - if ((err = _fdt_splice(fdt, p, 0, newlen)))
148   - return err;
149   -
150   - fdt_set_size_dt_strings(fdt, fdt_size_dt_strings(fdt) + newlen);
151   - return 0;
152   -}
153   -
154   -static int _fdt_find_add_string(void *fdt, const char *s)
155   -{
156   - char *strtab = (char *)fdt + fdt_off_dt_strings(fdt);
157   - const char *p;
158   - char *new;
159   - int len = strlen(s) + 1;
160   - int err;
161   -
162   - p = _fdt_find_string(strtab, fdt_size_dt_strings(fdt), s);
163   - if (p)
164   - /* found it */
165   - return (p - strtab);
166   -
167   - new = strtab + fdt_size_dt_strings(fdt);
168   - err = _fdt_splice_string(fdt, len);
169   - if (err)
170   - return err;
171   -
172   - memcpy(new, s, len);
173   - return (new - strtab);
174   -}
175   -
176   -int fdt_add_mem_rsv(void *fdt, uint64_t address, uint64_t size)
177   -{
178   - struct fdt_reserve_entry *re;
179   - int err;
180   -
181   - FDT_RW_CHECK_HEADER(fdt);
182   -
183   - re = _fdt_mem_rsv_w(fdt, fdt_num_mem_rsv(fdt));
184   - err = _fdt_splice_mem_rsv(fdt, re, 0, 1);
185   - if (err)
186   - return err;
187   -
188   - re->address = cpu_to_fdt64(address);
189   - re->size = cpu_to_fdt64(size);
190   - return 0;
191   -}
192   -
193   -int fdt_del_mem_rsv(void *fdt, int n)
194   -{
195   - struct fdt_reserve_entry *re = _fdt_mem_rsv_w(fdt, n);
196   - int err;
197   -
198   - FDT_RW_CHECK_HEADER(fdt);
199   -
200   - if (n >= fdt_num_mem_rsv(fdt))
201   - return -FDT_ERR_NOTFOUND;
202   -
203   - err = _fdt_splice_mem_rsv(fdt, re, 1, 0);
204   - if (err)
205   - return err;
206   - return 0;
207   -}
208   -
209   -static int _fdt_resize_property(void *fdt, int nodeoffset, const char *name,
210   - int len, struct fdt_property **prop)
211   -{
212   - int oldlen;
213   - int err;
214   -
215   - *prop = fdt_get_property_w(fdt, nodeoffset, name, &oldlen);
216   - if (! (*prop))
217   - return oldlen;
218   -
219   - if ((err = _fdt_splice_struct(fdt, (*prop)->data, FDT_TAGALIGN(oldlen),
220   - FDT_TAGALIGN(len))))
221   - return err;
222   -
223   - (*prop)->len = cpu_to_fdt32(len);
224   - return 0;
225   -}
226   -
227   -static int _fdt_add_property(void *fdt, int nodeoffset, const char *name,
228   - int len, struct fdt_property **prop)
229   -{
230   - int proplen;
231   - int nextoffset;
232   - int namestroff;
233   - int err;
234   -
235   - if ((nextoffset = _fdt_check_node_offset(fdt, nodeoffset)) < 0)
236   - return nextoffset;
237   -
238   - namestroff = _fdt_find_add_string(fdt, name);
239   - if (namestroff < 0)
240   - return namestroff;
241   -
242   - *prop = _fdt_offset_ptr_w(fdt, nextoffset);
243   - proplen = sizeof(**prop) + FDT_TAGALIGN(len);
244   -
245   - err = _fdt_splice_struct(fdt, *prop, 0, proplen);
246   - if (err)
247   - return err;
248   -
249   - (*prop)->tag = cpu_to_fdt32(FDT_PROP);
250   - (*prop)->nameoff = cpu_to_fdt32(namestroff);
251   - (*prop)->len = cpu_to_fdt32(len);
252   - return 0;
253   -}
254   -
255   -int fdt_set_name(void *fdt, int nodeoffset, const char *name)
256   -{
257   - char *namep;
258   - int oldlen, newlen;
259   - int err;
260   -
261   - FDT_RW_CHECK_HEADER(fdt);
262   -
263   - namep = (char *)(uintptr_t)fdt_get_name(fdt, nodeoffset, &oldlen);
264   - if (!namep)
265   - return oldlen;
266   -
267   - newlen = strlen(name);
268   -
269   - err = _fdt_splice_struct(fdt, namep, FDT_TAGALIGN(oldlen+1),
270   - FDT_TAGALIGN(newlen+1));
271   - if (err)
272   - return err;
273   -
274   - memcpy(namep, name, newlen+1);
275   - return 0;
276   -}
277   -
278   -int fdt_setprop(void *fdt, int nodeoffset, const char *name,
279   - const void *val, int len)
280   -{
281   - struct fdt_property *prop;
282   - int err;
283   -
284   - FDT_RW_CHECK_HEADER(fdt);
285   -
286   - err = _fdt_resize_property(fdt, nodeoffset, name, len, &prop);
287   - if (err == -FDT_ERR_NOTFOUND)
288   - err = _fdt_add_property(fdt, nodeoffset, name, len, &prop);
289   - if (err)
290   - return err;
291   -
292   - memcpy(prop->data, val, len);
293   - return 0;
294   -}
295   -
296   -int fdt_delprop(void *fdt, int nodeoffset, const char *name)
297   -{
298   - struct fdt_property *prop;
299   - int len, proplen;
300   -
301   - FDT_RW_CHECK_HEADER(fdt);
302   -
303   - prop = fdt_get_property_w(fdt, nodeoffset, name, &len);
304   - if (! prop)
305   - return len;
306   -
307   - proplen = sizeof(*prop) + FDT_TAGALIGN(len);
308   - return _fdt_splice_struct(fdt, prop, proplen, 0);
309   -}
310   -
311   -int fdt_add_subnode_namelen(void *fdt, int parentoffset,
312   - const char *name, int namelen)
313   -{
314   - struct fdt_node_header *nh;
315   - int offset, nextoffset;
316   - int nodelen;
317   - int err;
318   - uint32_t tag;
319   - uint32_t *endtag;
320   -
321   - FDT_RW_CHECK_HEADER(fdt);
322   -
323   - offset = fdt_subnode_offset_namelen(fdt, parentoffset, name, namelen);
324   - if (offset >= 0)
325   - return -FDT_ERR_EXISTS;
326   - else if (offset != -FDT_ERR_NOTFOUND)
327   - return offset;
328   -
329   - /* Try to place the new node after the parent's properties */
330   - fdt_next_tag(fdt, parentoffset, &nextoffset); /* skip the BEGIN_NODE */
331   - do {
332   - offset = nextoffset;
333   - tag = fdt_next_tag(fdt, offset, &nextoffset);
334   - } while ((tag == FDT_PROP) || (tag == FDT_NOP));
335   -
336   - nh = _fdt_offset_ptr_w(fdt, offset);
337   - nodelen = sizeof(*nh) + FDT_TAGALIGN(namelen+1) + FDT_TAGSIZE;
338   -
339   - err = _fdt_splice_struct(fdt, nh, 0, nodelen);
340   - if (err)
341   - return err;
342   -
343   - nh->tag = cpu_to_fdt32(FDT_BEGIN_NODE);
344   - memset(nh->name, 0, FDT_TAGALIGN(namelen+1));
345   - memcpy(nh->name, name, namelen);
346   - endtag = (uint32_t *)((char *)nh + nodelen - FDT_TAGSIZE);
347   - *endtag = cpu_to_fdt32(FDT_END_NODE);
348   -
349   - return offset;
350   -}
351   -
352   -int fdt_add_subnode(void *fdt, int parentoffset, const char *name)
353   -{
354   - return fdt_add_subnode_namelen(fdt, parentoffset, name, strlen(name));
355   -}
356   -
357   -int fdt_del_node(void *fdt, int nodeoffset)
358   -{
359   - int endoffset;
360   -
361   - FDT_RW_CHECK_HEADER(fdt);
362   -
363   - endoffset = _fdt_node_end_offset(fdt, nodeoffset);
364   - if (endoffset < 0)
365   - return endoffset;
366   -
367   - return _fdt_splice_struct(fdt, _fdt_offset_ptr_w(fdt, nodeoffset),
368   - endoffset - nodeoffset, 0);
369   -}
370   -
371   -static void _fdt_packblocks(const char *old, char *new,
372   - int mem_rsv_size, int struct_size)
373   -{
374   - int mem_rsv_off, struct_off, strings_off;
375   -
376   - mem_rsv_off = FDT_ALIGN(sizeof(struct fdt_header), 8);
377   - struct_off = mem_rsv_off + mem_rsv_size;
378   - strings_off = struct_off + struct_size;
379   -
380   - memmove(new + mem_rsv_off, old + fdt_off_mem_rsvmap(old), mem_rsv_size);
381   - fdt_set_off_mem_rsvmap(new, mem_rsv_off);
382   -
383   - memmove(new + struct_off, old + fdt_off_dt_struct(old), struct_size);
384   - fdt_set_off_dt_struct(new, struct_off);
385   - fdt_set_size_dt_struct(new, struct_size);
386   -
387   - memmove(new + strings_off, old + fdt_off_dt_strings(old),
388   - fdt_size_dt_strings(old));
389   - fdt_set_off_dt_strings(new, strings_off);
390   - fdt_set_size_dt_strings(new, fdt_size_dt_strings(old));
391   -}
392   -
393   -int fdt_open_into(const void *fdt, void *buf, int bufsize)
394   -{
395   - int err;
396   - int mem_rsv_size, struct_size;
397   - int newsize;
398   - const char *fdtstart = fdt;
399   - const char *fdtend = fdtstart + fdt_totalsize(fdt);
400   - char *tmp;
401   -
402   - FDT_CHECK_HEADER(fdt);
403   -
404   - mem_rsv_size = (fdt_num_mem_rsv(fdt)+1)
405   - * sizeof(struct fdt_reserve_entry);
406   -
407   - if (fdt_version(fdt) >= 17) {
408   - struct_size = fdt_size_dt_struct(fdt);
409   - } else {
410   - struct_size = 0;
411   - while (fdt_next_tag(fdt, struct_size, &struct_size) != FDT_END)
412   - ;
413   - if (struct_size < 0)
414   - return struct_size;
415   - }
416   -
417   - if (!_fdt_blocks_misordered(fdt, mem_rsv_size, struct_size)) {
418   - /* no further work necessary */
419   - err = fdt_move(fdt, buf, bufsize);
420   - if (err)
421   - return err;
422   - fdt_set_version(buf, 17);
423   - fdt_set_size_dt_struct(buf, struct_size);
424   - fdt_set_totalsize(buf, bufsize);
425   - return 0;
426   - }
427   -
428   - /* Need to reorder */
429   - newsize = FDT_ALIGN(sizeof(struct fdt_header), 8) + mem_rsv_size
430   - + struct_size + fdt_size_dt_strings(fdt);
431   -
432   - if (bufsize < newsize)
433   - return -FDT_ERR_NOSPACE;
434   -
435   - /* First attempt to build converted tree at beginning of buffer */
436   - tmp = buf;
437   - /* But if that overlaps with the old tree... */
438   - if (((tmp + newsize) > fdtstart) && (tmp < fdtend)) {
439   - /* Try right after the old tree instead */
440   - tmp = (char *)(uintptr_t)fdtend;
441   - if ((tmp + newsize) > ((char *)buf + bufsize))
442   - return -FDT_ERR_NOSPACE;
443   - }
444   -
445   - _fdt_packblocks(fdt, tmp, mem_rsv_size, struct_size);
446   - memmove(buf, tmp, newsize);
447   -
448   - fdt_set_magic(buf, FDT_MAGIC);
449   - fdt_set_totalsize(buf, bufsize);
450   - fdt_set_version(buf, 17);
451   - fdt_set_last_comp_version(buf, 16);
452   - fdt_set_boot_cpuid_phys(buf, fdt_boot_cpuid_phys(fdt));
453   -
454   - return 0;
455   -}
456   -
457   -int fdt_pack(void *fdt)
458   -{
459   - int mem_rsv_size;
460   -
461   - FDT_RW_CHECK_HEADER(fdt);
462   -
463   - mem_rsv_size = (fdt_num_mem_rsv(fdt)+1)
464   - * sizeof(struct fdt_reserve_entry);
465   - _fdt_packblocks(fdt, fdt, mem_rsv_size, fdt_size_dt_struct(fdt));
466   - fdt_set_totalsize(fdt, _fdt_data_size(fdt));
467   -
468   - return 0;
469   -}
libfdt/fdt_strerror.c
1   -/*
2   - * libfdt - Flat Device Tree manipulation
3   - * Copyright (C) 2006 David Gibson, IBM Corporation.
4   - *
5   - * libfdt is dual licensed: you can use it either under the terms of
6   - * the GPL, or the BSD license, at your option.
7   - *
8   - * a) This library is free software; you can redistribute it and/or
9   - * modify it under the terms of the GNU General Public License as
10   - * published by the Free Software Foundation; either version 2 of the
11   - * License, or (at your option) any later version.
12   - *
13   - * This library is distributed in the hope that it will be useful,
14   - * but WITHOUT ANY WARRANTY; without even the implied warranty of
15   - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16   - * GNU General Public License for more details.
17   - *
18   - * You should have received a copy of the GNU General Public
19   - * License along with this library; if not, write to the Free
20   - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
21   - * MA 02110-1301 USA
22   - *
23   - * Alternatively,
24   - *
25   - * b) Redistribution and use in source and binary forms, with or
26   - * without modification, are permitted provided that the following
27   - * conditions are met:
28   - *
29   - * 1. Redistributions of source code must retain the above
30   - * copyright notice, this list of conditions and the following
31   - * disclaimer.
32   - * 2. Redistributions in binary form must reproduce the above
33   - * copyright notice, this list of conditions and the following
34   - * disclaimer in the documentation and/or other materials
35   - * provided with the distribution.
36   - *
37   - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
38   - * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
39   - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
40   - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
41   - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
42   - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
43   - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
44   - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
45   - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
46   - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
47   - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
48   - * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
49   - * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
50   - */
51   -#include "libfdt_env.h"
52   -
53   -#ifndef USE_HOSTCC
54   -#include <fdt.h>
55   -#include <libfdt.h>
56   -#else
57   -#include "fdt_host.h"
58   -#endif
59   -
60   -#include "libfdt_internal.h"
61   -
62   -struct fdt_errtabent {
63   - const char *str;
64   -};
65   -
66   -#define FDT_ERRTABENT(val) \
67   - [(val)] = { .str = #val, }
68   -
69   -static struct fdt_errtabent fdt_errtable[] = {
70   - FDT_ERRTABENT(FDT_ERR_NOTFOUND),
71   - FDT_ERRTABENT(FDT_ERR_EXISTS),
72   - FDT_ERRTABENT(FDT_ERR_NOSPACE),
73   -
74   - FDT_ERRTABENT(FDT_ERR_BADOFFSET),
75   - FDT_ERRTABENT(FDT_ERR_BADPATH),
76   - FDT_ERRTABENT(FDT_ERR_BADSTATE),
77   -
78   - FDT_ERRTABENT(FDT_ERR_TRUNCATED),
79   - FDT_ERRTABENT(FDT_ERR_BADMAGIC),
80   - FDT_ERRTABENT(FDT_ERR_BADVERSION),
81   - FDT_ERRTABENT(FDT_ERR_BADSTRUCTURE),
82   - FDT_ERRTABENT(FDT_ERR_BADLAYOUT),
83   -};
84   -#define FDT_ERRTABSIZE (sizeof(fdt_errtable) / sizeof(fdt_errtable[0]))
85   -
86   -const char *fdt_strerror(int errval)
87   -{
88   - if (errval > 0)
89   - return "<valid offset/length>";
90   - else if (errval == 0)
91   - return "<no error>";
92   - else if (errval > -FDT_ERRTABSIZE) {
93   - const char *s = fdt_errtable[-errval].str;
94   -
95   - if (s)
96   - return s;
97   - }
98   -
99   - return "<unknown error>";
100   -}
libfdt/fdt_sw.c
1   -/*
2   - * libfdt - Flat Device Tree manipulation
3   - * Copyright (C) 2006 David Gibson, IBM Corporation.
4   - *
5   - * libfdt is dual licensed: you can use it either under the terms of
6   - * the GPL, or the BSD license, at your option.
7   - *
8   - * a) This library is free software; you can redistribute it and/or
9   - * modify it under the terms of the GNU General Public License as
10   - * published by the Free Software Foundation; either version 2 of the
11   - * License, or (at your option) any later version.
12   - *
13   - * This library is distributed in the hope that it will be useful,
14   - * but WITHOUT ANY WARRANTY; without even the implied warranty of
15   - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16   - * GNU General Public License for more details.
17   - *
18   - * You should have received a copy of the GNU General Public
19   - * License along with this library; if not, write to the Free
20   - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
21   - * MA 02110-1301 USA
22   - *
23   - * Alternatively,
24   - *
25   - * b) Redistribution and use in source and binary forms, with or
26   - * without modification, are permitted provided that the following
27   - * conditions are met:
28   - *
29   - * 1. Redistributions of source code must retain the above
30   - * copyright notice, this list of conditions and the following
31   - * disclaimer.
32   - * 2. Redistributions in binary form must reproduce the above
33   - * copyright notice, this list of conditions and the following
34   - * disclaimer in the documentation and/or other materials
35   - * provided with the distribution.
36   - *
37   - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
38   - * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
39   - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
40   - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
41   - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
42   - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
43   - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
44   - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
45   - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
46   - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
47   - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
48   - * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
49   - * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
50   - */
51   -#include "libfdt_env.h"
52   -
53   -#include <fdt.h>
54   -#include <libfdt.h>
55   -
56   -#include "libfdt_internal.h"
57   -
58   -static int _fdt_sw_check_header(void *fdt)
59   -{
60   - if (fdt_magic(fdt) != FDT_SW_MAGIC)
61   - return -FDT_ERR_BADMAGIC;
62   - /* FIXME: should check more details about the header state */
63   - return 0;
64   -}
65   -
66   -#define FDT_SW_CHECK_HEADER(fdt) \
67   - { \
68   - int err; \
69   - if ((err = _fdt_sw_check_header(fdt)) != 0) \
70   - return err; \
71   - }
72   -
73   -static void *_fdt_grab_space(void *fdt, size_t len)
74   -{
75   - int offset = fdt_size_dt_struct(fdt);
76   - int spaceleft;
77   -
78   - spaceleft = fdt_totalsize(fdt) - fdt_off_dt_struct(fdt)
79   - - fdt_size_dt_strings(fdt);
80   -
81   - if ((offset + len < offset) || (offset + len > spaceleft))
82   - return NULL;
83   -
84   - fdt_set_size_dt_struct(fdt, offset + len);
85   - return _fdt_offset_ptr_w(fdt, offset);
86   -}
87   -
88   -int fdt_create(void *buf, int bufsize)
89   -{
90   - void *fdt = buf;
91   -
92   - if (bufsize < sizeof(struct fdt_header))
93   - return -FDT_ERR_NOSPACE;
94   -
95   - memset(buf, 0, bufsize);
96   -
97   - fdt_set_magic(fdt, FDT_SW_MAGIC);
98   - fdt_set_version(fdt, FDT_LAST_SUPPORTED_VERSION);
99   - fdt_set_last_comp_version(fdt, FDT_FIRST_SUPPORTED_VERSION);
100   - fdt_set_totalsize(fdt, bufsize);
101   -
102   - fdt_set_off_mem_rsvmap(fdt, FDT_ALIGN(sizeof(struct fdt_header),
103   - sizeof(struct fdt_reserve_entry)));
104   - fdt_set_off_dt_struct(fdt, fdt_off_mem_rsvmap(fdt));
105   - fdt_set_off_dt_strings(fdt, bufsize);
106   -
107   - return 0;
108   -}
109   -
110   -int fdt_add_reservemap_entry(void *fdt, uint64_t addr, uint64_t size)
111   -{
112   - struct fdt_reserve_entry *re;
113   - int offset;
114   -
115   - FDT_SW_CHECK_HEADER(fdt);
116   -
117   - if (fdt_size_dt_struct(fdt))
118   - return -FDT_ERR_BADSTATE;
119   -
120   - offset = fdt_off_dt_struct(fdt);
121   - if ((offset + sizeof(*re)) > fdt_totalsize(fdt))
122   - return -FDT_ERR_NOSPACE;
123   -
124   - re = (struct fdt_reserve_entry *)((char *)fdt + offset);
125   - re->address = cpu_to_fdt64(addr);
126   - re->size = cpu_to_fdt64(size);
127   -
128   - fdt_set_off_dt_struct(fdt, offset + sizeof(*re));
129   -
130   - return 0;
131   -}
132   -
133   -int fdt_finish_reservemap(void *fdt)
134   -{
135   - return fdt_add_reservemap_entry(fdt, 0, 0);
136   -}
137   -
138   -int fdt_begin_node(void *fdt, const char *name)
139   -{
140   - struct fdt_node_header *nh;
141   - int namelen = strlen(name) + 1;
142   -
143   - FDT_SW_CHECK_HEADER(fdt);
144   -
145   - nh = _fdt_grab_space(fdt, sizeof(*nh) + FDT_TAGALIGN(namelen));
146   - if (! nh)
147   - return -FDT_ERR_NOSPACE;
148   -
149   - nh->tag = cpu_to_fdt32(FDT_BEGIN_NODE);
150   - memcpy(nh->name, name, namelen);
151   - return 0;
152   -}
153   -
154   -int fdt_end_node(void *fdt)
155   -{
156   - uint32_t *en;
157   -
158   - FDT_SW_CHECK_HEADER(fdt);
159   -
160   - en = _fdt_grab_space(fdt, FDT_TAGSIZE);
161   - if (! en)
162   - return -FDT_ERR_NOSPACE;
163   -
164   - *en = cpu_to_fdt32(FDT_END_NODE);
165   - return 0;
166   -}
167   -
168   -static int _fdt_find_add_string(void *fdt, const char *s)
169   -{
170   - char *strtab = (char *)fdt + fdt_totalsize(fdt);
171   - const char *p;
172   - int strtabsize = fdt_size_dt_strings(fdt);
173   - int len = strlen(s) + 1;
174   - int struct_top, offset;
175   -
176   - p = _fdt_find_string(strtab - strtabsize, strtabsize, s);
177   - if (p)
178   - return p - strtab;
179   -
180   - /* Add it */
181   - offset = -strtabsize - len;
182   - struct_top = fdt_off_dt_struct(fdt) + fdt_size_dt_struct(fdt);
183   - if (fdt_totalsize(fdt) + offset < struct_top)
184   - return 0; /* no more room :( */
185   -
186   - memcpy(strtab + offset, s, len);
187   - fdt_set_size_dt_strings(fdt, strtabsize + len);
188   - return offset;
189   -}
190   -
191   -int fdt_property(void *fdt, const char *name, const void *val, int len)
192   -{
193   - struct fdt_property *prop;
194   - int nameoff;
195   -
196   - FDT_SW_CHECK_HEADER(fdt);
197   -
198   - nameoff = _fdt_find_add_string(fdt, name);
199   - if (nameoff == 0)
200   - return -FDT_ERR_NOSPACE;
201   -
202   - prop = _fdt_grab_space(fdt, sizeof(*prop) + FDT_TAGALIGN(len));
203   - if (! prop)
204   - return -FDT_ERR_NOSPACE;
205   -
206   - prop->tag = cpu_to_fdt32(FDT_PROP);
207   - prop->nameoff = cpu_to_fdt32(nameoff);
208   - prop->len = cpu_to_fdt32(len);
209   - memcpy(prop->data, val, len);
210   - return 0;
211   -}
212   -
213   -int fdt_finish(void *fdt)
214   -{
215   - char *p = (char *)fdt;
216   - uint32_t *end;
217   - int oldstroffset, newstroffset;
218   - uint32_t tag;
219   - int offset, nextoffset;
220   -
221   - FDT_SW_CHECK_HEADER(fdt);
222   -
223   - /* Add terminator */
224   - end = _fdt_grab_space(fdt, sizeof(*end));
225   - if (! end)
226   - return -FDT_ERR_NOSPACE;
227   - *end = cpu_to_fdt32(FDT_END);
228   -
229   - /* Relocate the string table */
230   - oldstroffset = fdt_totalsize(fdt) - fdt_size_dt_strings(fdt);
231   - newstroffset = fdt_off_dt_struct(fdt) + fdt_size_dt_struct(fdt);
232   - memmove(p + newstroffset, p + oldstroffset, fdt_size_dt_strings(fdt));
233   - fdt_set_off_dt_strings(fdt, newstroffset);
234   -
235   - /* Walk the structure, correcting string offsets */
236   - offset = 0;
237   - while ((tag = fdt_next_tag(fdt, offset, &nextoffset)) != FDT_END) {
238   - if (tag == FDT_PROP) {
239   - struct fdt_property *prop =
240   - _fdt_offset_ptr_w(fdt, offset);
241   - int nameoff;
242   -
243   - nameoff = fdt32_to_cpu(prop->nameoff);
244   - nameoff += fdt_size_dt_strings(fdt);
245   - prop->nameoff = cpu_to_fdt32(nameoff);
246   - }
247   - offset = nextoffset;
248   - }
249   - if (nextoffset < 0)
250   - return nextoffset;
251   -
252   - /* Finally, adjust the header */
253   - fdt_set_totalsize(fdt, newstroffset + fdt_size_dt_strings(fdt));
254   - fdt_set_magic(fdt, FDT_MAGIC);
255   - return 0;
256   -}
libfdt/fdt_wip.c
1   -/*
2   - * libfdt - Flat Device Tree manipulation
3   - * Copyright (C) 2006 David Gibson, IBM Corporation.
4   - *
5   - * libfdt is dual licensed: you can use it either under the terms of
6   - * the GPL, or the BSD license, at your option.
7   - *
8   - * a) This library is free software; you can redistribute it and/or
9   - * modify it under the terms of the GNU General Public License as
10   - * published by the Free Software Foundation; either version 2 of the
11   - * License, or (at your option) any later version.
12   - *
13   - * This library is distributed in the hope that it will be useful,
14   - * but WITHOUT ANY WARRANTY; without even the implied warranty of
15   - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16   - * GNU General Public License for more details.
17   - *
18   - * You should have received a copy of the GNU General Public
19   - * License along with this library; if not, write to the Free
20   - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
21   - * MA 02110-1301 USA
22   - *
23   - * Alternatively,
24   - *
25   - * b) Redistribution and use in source and binary forms, with or
26   - * without modification, are permitted provided that the following
27   - * conditions are met:
28   - *
29   - * 1. Redistributions of source code must retain the above
30   - * copyright notice, this list of conditions and the following
31   - * disclaimer.
32   - * 2. Redistributions in binary form must reproduce the above
33   - * copyright notice, this list of conditions and the following
34   - * disclaimer in the documentation and/or other materials
35   - * provided with the distribution.
36   - *
37   - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
38   - * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
39   - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
40   - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
41   - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
42   - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
43   - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
44   - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
45   - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
46   - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
47   - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
48   - * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
49   - * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
50   - */
51   -#include "libfdt_env.h"
52   -
53   -#ifndef USE_HOSTCC
54   -#include <fdt.h>
55   -#include <libfdt.h>
56   -#else
57   -#include "fdt_host.h"
58   -#endif
59   -
60   -#include "libfdt_internal.h"
61   -
62   -int fdt_setprop_inplace(void *fdt, int nodeoffset, const char *name,
63   - const void *val, int len)
64   -{
65   - void *propval;
66   - int proplen;
67   -
68   - propval = fdt_getprop_w(fdt, nodeoffset, name, &proplen);
69   - if (! propval)
70   - return proplen;
71   -
72   - if (proplen != len)
73   - return -FDT_ERR_NOSPACE;
74   -
75   - memcpy(propval, val, len);
76   - return 0;
77   -}
78   -
79   -static void _fdt_nop_region(void *start, int len)
80   -{
81   - uint32_t *p;
82   -
83   - for (p = start; (char *)p < ((char *)start + len); p++)
84   - *p = cpu_to_fdt32(FDT_NOP);
85   -}
86   -
87   -int fdt_nop_property(void *fdt, int nodeoffset, const char *name)
88   -{
89   - struct fdt_property *prop;
90   - int len;
91   -
92   - prop = fdt_get_property_w(fdt, nodeoffset, name, &len);
93   - if (! prop)
94   - return len;
95   -
96   - _fdt_nop_region(prop, len + sizeof(*prop));
97   -
98   - return 0;
99   -}
100   -
101   -int _fdt_node_end_offset(void *fdt, int offset)
102   -{
103   - int depth = 0;
104   -
105   - while ((offset >= 0) && (depth >= 0))
106   - offset = fdt_next_node(fdt, offset, &depth);
107   -
108   - return offset;
109   -}
110   -
111   -int fdt_nop_node(void *fdt, int nodeoffset)
112   -{
113   - int endoffset;
114   -
115   - endoffset = _fdt_node_end_offset(fdt, nodeoffset);
116   - if (endoffset < 0)
117   - return endoffset;
118   -
119   - _fdt_nop_region(fdt_offset_ptr_w(fdt, nodeoffset, 0),
120   - endoffset - nodeoffset);
121   - return 0;
122   -}
libfdt/libfdt_internal.h
1   -#ifndef _LIBFDT_INTERNAL_H
2   -#define _LIBFDT_INTERNAL_H
3   -/*
4   - * libfdt - Flat Device Tree manipulation
5   - * Copyright (C) 2006 David Gibson, IBM Corporation.
6   - *
7   - * libfdt is dual licensed: you can use it either under the terms of
8   - * the GPL, or the BSD license, at your option.
9   - *
10   - * a) This library is free software; you can redistribute it and/or
11   - * modify it under the terms of the GNU General Public License as
12   - * published by the Free Software Foundation; either version 2 of the
13   - * License, or (at your option) any later version.
14   - *
15   - * This library is distributed in the hope that it will be useful,
16   - * but WITHOUT ANY WARRANTY; without even the implied warranty of
17   - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18   - * GNU General Public License for more details.
19   - *
20   - * You should have received a copy of the GNU General Public
21   - * License along with this library; if not, write to the Free
22   - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
23   - * MA 02110-1301 USA
24   - *
25   - * Alternatively,
26   - *
27   - * b) Redistribution and use in source and binary forms, with or
28   - * without modification, are permitted provided that the following
29   - * conditions are met:
30   - *
31   - * 1. Redistributions of source code must retain the above
32   - * copyright notice, this list of conditions and the following
33   - * disclaimer.
34   - * 2. Redistributions in binary form must reproduce the above
35   - * copyright notice, this list of conditions and the following
36   - * disclaimer in the documentation and/or other materials
37   - * provided with the distribution.
38   - *
39   - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
40   - * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
41   - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
42   - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
43   - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
44   - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
45   - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
46   - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
47   - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48   - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
49   - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
50   - * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
51   - * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
52   - */
53   -#include <fdt.h>
54   -
55   -#define FDT_ALIGN(x, a) (((x) + (a) - 1) & ~((a) - 1))
56   -#define FDT_TAGALIGN(x) (FDT_ALIGN((x), FDT_TAGSIZE))
57   -
58   -#define FDT_CHECK_HEADER(fdt) \
59   - { \
60   - int err; \
61   - if ((err = fdt_check_header(fdt)) != 0) \
62   - return err; \
63   - }
64   -
65   -int _fdt_check_node_offset(const void *fdt, int offset);
66   -const char *_fdt_find_string(const char *strtab, int tabsize, const char *s);
67   -int _fdt_node_end_offset(void *fdt, int nodeoffset);
68   -
69   -static inline const void *_fdt_offset_ptr(const void *fdt, int offset)
70   -{
71   - return (const char *)fdt + fdt_off_dt_struct(fdt) + offset;
72   -}
73   -
74   -static inline void *_fdt_offset_ptr_w(void *fdt, int offset)
75   -{
76   - return (void *)(uintptr_t)_fdt_offset_ptr(fdt, offset);
77   -}
78   -
79   -static inline const struct fdt_reserve_entry *_fdt_mem_rsv(const void *fdt, int n)
80   -{
81   - const struct fdt_reserve_entry *rsv_table =
82   - (const struct fdt_reserve_entry *)
83   - ((const char *)fdt + fdt_off_mem_rsvmap(fdt));
84   -
85   - return rsv_table + n;
86   -}
87   -static inline struct fdt_reserve_entry *_fdt_mem_rsv_w(void *fdt, int n)
88   -{
89   - return (void *)(uintptr_t)_fdt_mem_rsv(fdt, n);
90   -}
91   -
92   -#define FDT_SW_MAGIC (~FDT_MAGIC)
93   -
94   -#endif /* _LIBFDT_INTERNAL_H */
... ... @@ -122,7 +122,7 @@
122 122 # now $(obj) is defined
123 123 HOSTSRCS += $(addprefix $(SRCTREE)/,$(EXT_OBJ_FILES-y:.o=.c))
124 124 HOSTSRCS += $(addprefix $(SRCTREE)/tools/,$(OBJ_FILES-y:.o=.c))
125   -HOSTSRCS += $(addprefix $(SRCTREE)/libfdt/,$(LIBFDT_OBJ_FILES-y:.o=.c))
  125 +HOSTSRCS += $(addprefix $(SRCTREE)/lib/libfdt/,$(LIBFDT_OBJ_FILES-y:.o=.c))
126 126 BINS := $(addprefix $(obj),$(sort $(BIN_FILES-y)))
127 127 LIBFDT_OBJS := $(addprefix $(obj),$(LIBFDT_OBJ_FILES-y))
128 128  
... ... @@ -136,7 +136,7 @@
136 136 HOSTCPPFLAGS = -idirafter $(SRCTREE)/include \
137 137 -idirafter $(OBJTREE)/include2 \
138 138 -idirafter $(OBJTREE)/include \
139   - -I $(SRCTREE)/libfdt \
  139 + -I $(SRCTREE)/lib/libfdt \
140 140 -I $(SRCTREE)/tools \
141 141 -DTEXT_BASE=$(TEXT_BASE) -DUSE_HOSTCC \
142 142 -D__KERNEL_STRICT_NAMES
... ... @@ -199,7 +199,7 @@
199 199 $(obj)%.o: $(SRCTREE)/lib/%.c
200 200 $(HOSTCC) -g $(HOSTCFLAGS) -c -o $@ $<
201 201  
202   -$(obj)%.o: $(SRCTREE)/libfdt/%.c
  202 +$(obj)%.o: $(SRCTREE)/lib/libfdt/%.c
203 203 $(HOSTCC) -g $(HOSTCFLAGS_NOPED) -c -o $@ $<
204 204  
205 205 subdirs:
... ... @@ -41,7 +41,7 @@
41 41 # now $(obj) is defined
42 42 SRCS += $(addprefix $(SRCTREE)/,$(EXT_OBJ_FILES-y:.o=.c))
43 43 SRCS += $(addprefix $(SRCTREE)/tools/,$(OBJ_FILES-y:.o=.c))
44   -SRCS += $(addprefix $(SRCTREE)/libfdt/,$(LIBFDT_OBJ_FILES-y:.o=.c))
  44 +SRCS += $(addprefix $(SRCTREE)/lib/libfdt/,$(LIBFDT_OBJ_FILES-y:.o=.c))
45 45 BINS := $(addprefix $(obj),$(sort $(BIN_FILES-y)))
46 46 LIBFDT_OBJS := $(addprefix $(obj),$(LIBFDT_OBJ_FILES-y))
47 47  
... ... @@ -52,7 +52,7 @@
52 52 HOSTCPPFLAGS = -idirafter $(SRCTREE)/include \
53 53 -idirafter $(OBJTREE)/include2 \
54 54 -idirafter $(OBJTREE)/include \
55   - -I $(SRCTREE)/libfdt \
  55 + -I $(SRCTREE)/lib/libfdt \
56 56 -I $(SRCTREE)/tools \
57 57 -DUSE_HOSTCC -D__KERNEL_STRICT_NAMES
58 58  
... ... @@ -81,7 +81,7 @@
81 81 $(obj)%.o: $(SRCTREE)/lib/%.c
82 82 $(CC) -g $(HOSTCFLAGS) -c -o $@ $<
83 83  
84   -$(obj)%.o: $(SRCTREE)/libfdt/%.c
  84 +$(obj)%.o: $(SRCTREE)/lib/libfdt/%.c
85 85 $(CC) -g $(HOSTCFLAGS_NOPED) -c -o $@ $<
86 86  
87 87 clean: