summaryrefslogtreecommitdiff
path: root/lib/libfdt
diff options
context:
space:
mode:
Diffstat (limited to 'lib/libfdt')
-rw-r--r--lib/libfdt/Makefile17
-rw-r--r--lib/libfdt/fdt.c212
-rw-r--r--lib/libfdt/fdt.h67
-rw-r--r--lib/libfdt/fdt_addresses.c57
-rw-r--r--lib/libfdt/fdt_empty_tree.c39
-rw-r--r--lib/libfdt/fdt_overlay.c863
-rw-r--r--lib/libfdt/fdt_strerror.c63
-rw-r--r--lib/libfdt/fdt_sw.c256
-rw-r--r--lib/libfdt/libfdt_internal.h51
-rw-r--r--lib/libfdt/pylibfdt/libfdt.i449
-rwxr-xr-xlib/libfdt/pylibfdt/setup.py123
11 files changed, 25 insertions, 2172 deletions
diff --git a/lib/libfdt/Makefile b/lib/libfdt/Makefile
index 6ef8290f4e0..369bbf9ba36 100644
--- a/lib/libfdt/Makefile
+++ b/lib/libfdt/Makefile
@@ -5,15 +5,22 @@
# SPDX-License-Identifier: GPL-2.0+
#
+# Use upstream code.
obj-y += \
fdt.o \
- fdt_ro.o \
- fdt_rw.o \
fdt_strerror.o \
fdt_sw.o \
- fdt_wip.o \
fdt_empty_tree.o \
- fdt_addresses.o \
- fdt_region.o
+ fdt_addresses.o
obj-$(CONFIG_OF_LIBFDT_OVERLAY) += fdt_overlay.o
+
+# Locally modified for U-Boot.
+# TODO: split out the local modifiction.
+obj-y += \
+ fdt_ro.o \
+ fdt_rw.o \
+ fdt_wip.o \
+
+# U-Boot own file
+obj-y += fdt_region.o
diff --git a/lib/libfdt/fdt.c b/lib/libfdt/fdt.c
index 2055734012a..0958e6ba578 100644
--- a/lib/libfdt/fdt.c
+++ b/lib/libfdt/fdt.c
@@ -1,210 +1,2 @@
-/*
- * libfdt - Flat Device Tree manipulation
- * Copyright (C) 2006 David Gibson, IBM Corporation.
- * SPDX-License-Identifier: GPL-2.0+ BSD-2-Clause
- */
-#include <libfdt_env.h>
-
-#ifndef USE_HOSTCC
-#include <fdt.h>
-#include <libfdt.h>
-#else
-#include "fdt_host.h"
-#endif
-
-#include "libfdt_internal.h"
-
-int fdt_check_header(const void *fdt)
-{
- if (fdt_magic(fdt) == FDT_MAGIC) {
- /* Complete tree */
- if (fdt_version(fdt) < FDT_FIRST_SUPPORTED_VERSION)
- return -FDT_ERR_BADVERSION;
- if (fdt_last_comp_version(fdt) > FDT_LAST_SUPPORTED_VERSION)
- return -FDT_ERR_BADVERSION;
- } else if (fdt_magic(fdt) == FDT_SW_MAGIC) {
- /* Unfinished sequential-write blob */
- if (fdt_size_dt_struct(fdt) == 0)
- return -FDT_ERR_BADSTATE;
- } else {
- return -FDT_ERR_BADMAGIC;
- }
-
- return 0;
-}
-
-const void *fdt_offset_ptr(const void *fdt, int offset, unsigned int len)
-{
- unsigned absoffset = offset + fdt_off_dt_struct(fdt);
-
- if ((absoffset < offset)
- || ((absoffset + len) < absoffset)
- || (absoffset + len) > fdt_totalsize(fdt))
- return NULL;
-
- if (fdt_version(fdt) >= 0x11)
- if (((offset + len) < offset)
- || ((offset + len) > fdt_size_dt_struct(fdt)))
- return NULL;
-
- return _fdt_offset_ptr(fdt, offset);
-}
-
-uint32_t fdt_next_tag(const void *fdt, int startoffset, int *nextoffset)
-{
- const fdt32_t *tagp, *lenp;
- uint32_t tag;
- int offset = startoffset;
- const char *p;
-
- *nextoffset = -FDT_ERR_TRUNCATED;
- tagp = fdt_offset_ptr(fdt, offset, FDT_TAGSIZE);
- if (!tagp)
- return FDT_END; /* premature end */
- tag = fdt32_to_cpu(*tagp);
- offset += FDT_TAGSIZE;
-
- *nextoffset = -FDT_ERR_BADSTRUCTURE;
- switch (tag) {
- case FDT_BEGIN_NODE:
- /* skip name */
- do {
- p = fdt_offset_ptr(fdt, offset++, 1);
- } while (p && (*p != '\0'));
- if (!p)
- return FDT_END; /* premature end */
- break;
-
- case FDT_PROP:
- lenp = fdt_offset_ptr(fdt, offset, sizeof(*lenp));
- if (!lenp)
- return FDT_END; /* premature end */
- /* skip-name offset, length and value */
- offset += sizeof(struct fdt_property) - FDT_TAGSIZE
- + fdt32_to_cpu(*lenp);
- break;
-
- case FDT_END:
- case FDT_END_NODE:
- case FDT_NOP:
- break;
-
- default:
- return FDT_END;
- }
-
- if (!fdt_offset_ptr(fdt, startoffset, offset - startoffset))
- return FDT_END; /* premature end */
-
- *nextoffset = FDT_TAGALIGN(offset);
- return tag;
-}
-
-int _fdt_check_node_offset(const void *fdt, int offset)
-{
- if ((offset < 0) || (offset % FDT_TAGSIZE)
- || (fdt_next_tag(fdt, offset, &offset) != FDT_BEGIN_NODE))
- return -FDT_ERR_BADOFFSET;
-
- return offset;
-}
-
-int _fdt_check_prop_offset(const void *fdt, int offset)
-{
- if ((offset < 0) || (offset % FDT_TAGSIZE)
- || (fdt_next_tag(fdt, offset, &offset) != FDT_PROP))
- return -FDT_ERR_BADOFFSET;
-
- return offset;
-}
-
-int fdt_next_node(const void *fdt, int offset, int *depth)
-{
- int nextoffset = 0;
- uint32_t tag;
-
- if (offset >= 0)
- if ((nextoffset = _fdt_check_node_offset(fdt, offset)) < 0)
- return nextoffset;
-
- do {
- offset = nextoffset;
- tag = fdt_next_tag(fdt, offset, &nextoffset);
-
- switch (tag) {
- case FDT_PROP:
- case FDT_NOP:
- break;
-
- case FDT_BEGIN_NODE:
- if (depth)
- (*depth)++;
- break;
-
- case FDT_END_NODE:
- if (depth && ((--(*depth)) < 0))
- return nextoffset;
- break;
-
- case FDT_END:
- if ((nextoffset >= 0)
- || ((nextoffset == -FDT_ERR_TRUNCATED) && !depth))
- return -FDT_ERR_NOTFOUND;
- else
- return nextoffset;
- }
- } while (tag != FDT_BEGIN_NODE);
-
- return offset;
-}
-
-int fdt_first_subnode(const void *fdt, int offset)
-{
- int depth = 0;
-
- offset = fdt_next_node(fdt, offset, &depth);
- if (offset < 0 || depth != 1)
- return -FDT_ERR_NOTFOUND;
-
- return offset;
-}
-
-int fdt_next_subnode(const void *fdt, int offset)
-{
- int depth = 1;
-
- /*
- * With respect to the parent, the depth of the next subnode will be
- * the same as the last.
- */
- do {
- offset = fdt_next_node(fdt, offset, &depth);
- if (offset < 0 || depth < 1)
- return -FDT_ERR_NOTFOUND;
- } while (depth > 1);
-
- return offset;
-}
-
-const char *_fdt_find_string(const char *strtab, int tabsize, const char *s)
-{
- int len = strlen(s) + 1;
- const char *last = strtab + tabsize - len;
- const char *p;
-
- for (p = strtab; p <= last; p++)
- if (memcmp(p, s, len) == 0)
- return p;
- return NULL;
-}
-
-int fdt_move(const void *fdt, void *buf, int bufsize)
-{
- FDT_CHECK_HEADER(fdt);
-
- if (fdt_totalsize(fdt) > bufsize)
- return -FDT_ERR_NOSPACE;
-
- memmove(buf, fdt, fdt_totalsize(fdt));
- return 0;
-}
+#include <linux/libfdt_env.h>
+#include "../../scripts/dtc/libfdt/fdt.c"
diff --git a/lib/libfdt/fdt.h b/lib/libfdt/fdt.h
deleted file mode 100644
index 3134d78332d..00000000000
--- a/lib/libfdt/fdt.h
+++ /dev/null
@@ -1,67 +0,0 @@
-#ifndef _FDT_H
-#define _FDT_H
-/*
- * libfdt - Flat Device Tree manipulation
- * Copyright (C) 2006 David Gibson, IBM Corporation.
- * Copyright 2012 Kim Phillips, Freescale Semiconductor.
- *
- * SPDX-License-Identifier: GPL-2.0+ BSD-2-Clause
- */
-
-#ifndef __ASSEMBLY__
-
-struct fdt_header {
- fdt32_t magic; /* magic word FDT_MAGIC */
- fdt32_t totalsize; /* total size of DT block */
- fdt32_t off_dt_struct; /* offset to structure */
- fdt32_t off_dt_strings; /* offset to strings */
- fdt32_t off_mem_rsvmap; /* offset to memory reserve map */
- fdt32_t version; /* format version */
- fdt32_t last_comp_version; /* last compatible version */
-
- /* version 2 fields below */
- fdt32_t boot_cpuid_phys; /* Which physical CPU id we're
- booting on */
- /* version 3 fields below */
- fdt32_t size_dt_strings; /* size of the strings block */
-
- /* version 17 fields below */
- fdt32_t size_dt_struct; /* size of the structure block */
-};
-
-struct fdt_reserve_entry {
- fdt64_t address;
- fdt64_t size;
-};
-
-struct fdt_node_header {
- fdt32_t tag;
- char name[0];
-};
-
-struct fdt_property {
- fdt32_t tag;
- fdt32_t len;
- fdt32_t nameoff;
- char data[0];
-};
-
-#endif /* !__ASSEMBLY */
-
-#define FDT_MAGIC 0xd00dfeed /* 4: version, 4: total size */
-#define FDT_TAGSIZE sizeof(fdt32_t)
-
-#define FDT_BEGIN_NODE 0x1 /* Start node: full name */
-#define FDT_END_NODE 0x2 /* End node */
-#define FDT_PROP 0x3 /* Property: name off,
- size, content */
-#define FDT_NOP 0x4 /* nop */
-#define FDT_END 0x9
-
-#define FDT_V1_SIZE (7*sizeof(fdt32_t))
-#define FDT_V2_SIZE (FDT_V1_SIZE + sizeof(fdt32_t))
-#define FDT_V3_SIZE (FDT_V2_SIZE + sizeof(fdt32_t))
-#define FDT_V16_SIZE FDT_V3_SIZE
-#define FDT_V17_SIZE (FDT_V16_SIZE + sizeof(fdt32_t))
-
-#endif /* _FDT_H */
diff --git a/lib/libfdt/fdt_addresses.c b/lib/libfdt/fdt_addresses.c
index b6bc66ea323..b82a02936c3 100644
--- a/lib/libfdt/fdt_addresses.c
+++ b/lib/libfdt/fdt_addresses.c
@@ -1,55 +1,2 @@
-/*
- * libfdt - Flat Device Tree manipulation
- * Copyright (C) 2014 David Gibson <david@gibson.dropbear.id.au>
- * SPDX-License-Identifier: GPL-2.0+ BSD-2-Clause
- */
-#include <libfdt_env.h>
-
-#ifndef USE_HOSTCC
-#include <fdt.h>
-#include <libfdt.h>
-#else
-#include "fdt_host.h"
-#endif
-
-#include "libfdt_internal.h"
-
-int fdt_address_cells(const void *fdt, int nodeoffset)
-{
- const fdt32_t *ac;
- int val;
- int len;
-
- ac = fdt_getprop(fdt, nodeoffset, "#address-cells", &len);
- if (!ac)
- return 2;
-
- if (len != sizeof(*ac))
- return -FDT_ERR_BADNCELLS;
-
- val = fdt32_to_cpu(*ac);
- if ((val <= 0) || (val > FDT_MAX_NCELLS))
- return -FDT_ERR_BADNCELLS;
-
- return val;
-}
-
-int fdt_size_cells(const void *fdt, int nodeoffset)
-{
- const fdt32_t *sc;
- int val;
- int len;
-
- sc = fdt_getprop(fdt, nodeoffset, "#size-cells", &len);
- if (!sc)
- return 2;
-
- if (len != sizeof(*sc))
- return -FDT_ERR_BADNCELLS;
-
- val = fdt32_to_cpu(*sc);
- if ((val < 0) || (val > FDT_MAX_NCELLS))
- return -FDT_ERR_BADNCELLS;
-
- return val;
-}
+#include <linux/libfdt_env.h>
+#include "../../scripts/dtc/libfdt/fdt_addresses.c"
diff --git a/lib/libfdt/fdt_empty_tree.c b/lib/libfdt/fdt_empty_tree.c
index 6fde1eb9eda..2b4ae1062b0 100644
--- a/lib/libfdt/fdt_empty_tree.c
+++ b/lib/libfdt/fdt_empty_tree.c
@@ -1,37 +1,2 @@
-/*
- * libfdt - Flat Device Tree manipulation
- * Copyright (C) 2012 David Gibson, IBM Corporation.
- * SPDX-License-Identifier: GPL-2.0+ BSD-2-Clause
- */
-#include <libfdt_env.h>
-#include <fdt.h>
-#include <libfdt.h>
-
-#include "libfdt_internal.h"
-
-int fdt_create_empty_tree(void *buf, int bufsize)
-{
- int err;
-
- err = fdt_create(buf, bufsize);
- if (err)
- return err;
-
- err = fdt_finish_reservemap(buf);
- if (err)
- return err;
-
- err = fdt_begin_node(buf, "");
- if (err)
- return err;
-
- err = fdt_end_node(buf);
- if (err)
- return err;
-
- err = fdt_finish(buf);
- if (err)
- return err;
-
- return fdt_open_into(buf, buf, bufsize);
-}
+#include <linux/libfdt_env.h>
+#include "../../scripts/dtc/libfdt/fdt_empty_tree.c"
diff --git a/lib/libfdt/fdt_overlay.c b/lib/libfdt/fdt_overlay.c
index bd81241e665..575c827673e 100644
--- a/lib/libfdt/fdt_overlay.c
+++ b/lib/libfdt/fdt_overlay.c
@@ -1,861 +1,2 @@
-#include "libfdt_env.h"
-
-#include <fdt.h>
-#include <libfdt.h>
-
-#include "libfdt_internal.h"
-
-/**
- * overlay_get_target_phandle - retrieves the target phandle of a fragment
- * @fdto: pointer to the device tree overlay blob
- * @fragment: node offset of the fragment in the overlay
- *
- * overlay_get_target_phandle() retrieves the target phandle of an
- * overlay fragment when that fragment uses a phandle (target
- * property) instead of a path (target-path property).
- *
- * returns:
- * the phandle pointed by the target property
- * 0, if the phandle was not found
- * -1, if the phandle was malformed
- */
-static uint32_t overlay_get_target_phandle(const void *fdto, int fragment)
-{
- const fdt32_t *val;
- int len;
-
- val = fdt_getprop(fdto, fragment, "target", &len);
- if (!val)
- return 0;
-
- if ((len != sizeof(*val)) || (fdt32_to_cpu(*val) == (uint32_t)-1))
- return (uint32_t)-1;
-
- return fdt32_to_cpu(*val);
-}
-
-/**
- * overlay_get_target - retrieves the offset of a fragment's target
- * @fdt: Base device tree blob
- * @fdto: Device tree overlay blob
- * @fragment: node offset of the fragment in the overlay
- * @pathp: pointer which receives the path of the target (or NULL)
- *
- * overlay_get_target() retrieves the target offset in the base
- * device tree of a fragment, no matter how the actual targetting is
- * done (through a phandle or a path)
- *
- * returns:
- * the targetted node offset in the base device tree
- * Negative error code on error
- */
-static int overlay_get_target(const void *fdt, const void *fdto,
- int fragment, char const **pathp)
-{
- uint32_t phandle;
- const char *path = NULL;
- int path_len = 0, ret;
-
- /* Try first to do a phandle based lookup */
- phandle = overlay_get_target_phandle(fdto, fragment);
- if (phandle == (uint32_t)-1)
- return -FDT_ERR_BADPHANDLE;
-
- /* no phandle, try path */
- if (!phandle) {
- /* And then a path based lookup */
- path = fdt_getprop(fdto, fragment, "target-path", &path_len);
- if (path)
- ret = fdt_path_offset(fdt, path);
- else
- ret = path_len;
- } else
- ret = fdt_node_offset_by_phandle(fdt, phandle);
-
- /*
- * If we haven't found either a target or a
- * target-path property in a node that contains a
- * __overlay__ subnode (we wouldn't be called
- * otherwise), consider it a improperly written
- * overlay
- */
- if (ret < 0 && path_len == -FDT_ERR_NOTFOUND)
- ret = -FDT_ERR_BADOVERLAY;
-
- /* return on error */
- if (ret < 0)
- return ret;
-
- /* return pointer to path (if available) */
- if (pathp)
- *pathp = path ? path : NULL;
-
- return ret;
-}
-
-/**
- * overlay_phandle_add_offset - Increases a phandle by an offset
- * @fdt: Base device tree blob
- * @node: Device tree overlay blob
- * @name: Name of the property to modify (phandle or linux,phandle)
- * @delta: offset to apply
- *
- * overlay_phandle_add_offset() increments a node phandle by a given
- * offset.
- *
- * returns:
- * 0 on success.
- * Negative error code on error
- */
-static int overlay_phandle_add_offset(void *fdt, int node,
- const char *name, uint32_t delta)
-{
- const fdt32_t *val;
- uint32_t adj_val;
- int len;
-
- val = fdt_getprop(fdt, node, name, &len);
- if (!val)
- return len;
-
- if (len != sizeof(*val))
- return -FDT_ERR_BADPHANDLE;
-
- adj_val = fdt32_to_cpu(*val);
- if ((adj_val + delta) < adj_val)
- return -FDT_ERR_NOPHANDLES;
-
- adj_val += delta;
- if (adj_val == (uint32_t)-1)
- return -FDT_ERR_NOPHANDLES;
-
- return fdt_setprop_inplace_u32(fdt, node, name, adj_val);
-}
-
-/**
- * overlay_adjust_node_phandles - Offsets the phandles of a node
- * @fdto: Device tree overlay blob
- * @node: Offset of the node we want to adjust
- * @delta: Offset to shift the phandles of
- *
- * overlay_adjust_node_phandles() adds a constant to all the phandles
- * of a given node. This is mainly use as part of the overlay
- * application process, when we want to update all the overlay
- * phandles to not conflict with the overlays of the base device tree.
- *
- * returns:
- * 0 on success
- * Negative error code on failure
- */
-static int overlay_adjust_node_phandles(void *fdto, int node,
- uint32_t delta)
-{
- int child;
- int ret;
-
- ret = overlay_phandle_add_offset(fdto, node, "phandle", delta);
- if (ret && ret != -FDT_ERR_NOTFOUND)
- return ret;
-
- ret = overlay_phandle_add_offset(fdto, node, "linux,phandle", delta);
- if (ret && ret != -FDT_ERR_NOTFOUND)
- return ret;
-
- fdt_for_each_subnode(child, fdto, node) {
- ret = overlay_adjust_node_phandles(fdto, child, delta);
- if (ret)
- return ret;
- }
-
- return 0;
-}
-
-/**
- * overlay_adjust_local_phandles - Adjust the phandles of a whole overlay
- * @fdto: Device tree overlay blob
- * @delta: Offset to shift the phandles of
- *
- * overlay_adjust_local_phandles() adds a constant to all the
- * phandles of an overlay. This is mainly use as part of the overlay
- * application process, when we want to update all the overlay
- * phandles to not conflict with the overlays of the base device tree.
- *
- * returns:
- * 0 on success
- * Negative error code on failure
- */
-static int overlay_adjust_local_phandles(void *fdto, uint32_t delta)
-{
- /*
- * Start adjusting the phandles from the overlay root
- */
- return overlay_adjust_node_phandles(fdto, 0, delta);
-}
-
-/**
- * overlay_update_local_node_references - Adjust the overlay references
- * @fdto: Device tree overlay blob
- * @tree_node: Node offset of the node to operate on
- * @fixup_node: Node offset of the matching local fixups node
- * @delta: Offset to shift the phandles of
- *
- * overlay_update_local_nodes_references() update the phandles
- * pointing to a node within the device tree overlay by adding a
- * constant delta.
- *
- * This is mainly used as part of a device tree application process,
- * where you want the device tree overlays phandles to not conflict
- * with the ones from the base device tree before merging them.
- *
- * returns:
- * 0 on success
- * Negative error code on failure
- */
-static int overlay_update_local_node_references(void *fdto,
- int tree_node,
- int fixup_node,
- uint32_t delta)
-{
- int fixup_prop;
- int fixup_child;
- int ret;
-
- fdt_for_each_property_offset(fixup_prop, fdto, fixup_node) {
- const fdt32_t *fixup_val;
- const char *tree_val;
- const char *name;
- int fixup_len;
- int tree_len;
- int i;
-
- fixup_val = fdt_getprop_by_offset(fdto, fixup_prop,
- &name, &fixup_len);
- if (!fixup_val)
- return fixup_len;
-
- if (fixup_len % sizeof(uint32_t))
- return -FDT_ERR_BADOVERLAY;
-
- tree_val = fdt_getprop(fdto, tree_node, name, &tree_len);
- if (!tree_val) {
- if (tree_len == -FDT_ERR_NOTFOUND)
- return -FDT_ERR_BADOVERLAY;
-
- return tree_len;
- }
-
- for (i = 0; i < (fixup_len / sizeof(uint32_t)); i++) {
- fdt32_t adj_val;
- uint32_t poffset;
-
- poffset = fdt32_to_cpu(fixup_val[i]);
-
- /*
- * phandles to fixup can be unaligned.
- *
- * Use a memcpy for the architectures that do
- * not support unaligned accesses.
- */
- memcpy(&adj_val, tree_val + poffset, sizeof(adj_val));
-
- adj_val = cpu_to_fdt32(fdt32_to_cpu(adj_val) + delta);
-
- ret = fdt_setprop_inplace_namelen_partial(fdto,
- tree_node,
- name,
- strlen(name),
- poffset,
- &adj_val,
- sizeof(adj_val));
- if (ret == -FDT_ERR_NOSPACE)
- return -FDT_ERR_BADOVERLAY;
-
- if (ret)
- return ret;
- }
- }
-
- fdt_for_each_subnode(fixup_child, fdto, fixup_node) {
- const char *fixup_child_name = fdt_get_name(fdto, fixup_child,
- NULL);
- int tree_child;
-
- tree_child = fdt_subnode_offset(fdto, tree_node,
- fixup_child_name);
- if (tree_child == -FDT_ERR_NOTFOUND)
- return -FDT_ERR_BADOVERLAY;
- if (tree_child < 0)
- return tree_child;
-
- ret = overlay_update_local_node_references(fdto,
- tree_child,
- fixup_child,
- delta);
- if (ret)
- return ret;
- }
-
- return 0;
-}
-
-/**
- * overlay_update_local_references - Adjust the overlay references
- * @fdto: Device tree overlay blob
- * @delta: Offset to shift the phandles of
- *
- * overlay_update_local_references() update all the phandles pointing
- * to a node within the device tree overlay by adding a constant
- * delta to not conflict with the base overlay.
- *
- * This is mainly used as part of a device tree application process,
- * where you want the device tree overlays phandles to not conflict
- * with the ones from the base device tree before merging them.
- *
- * returns:
- * 0 on success
- * Negative error code on failure
- */
-static int overlay_update_local_references(void *fdto, uint32_t delta)
-{
- int fixups;
-
- fixups = fdt_path_offset(fdto, "/__local_fixups__");
- if (fixups < 0) {
- /* There's no local phandles to adjust, bail out */
- if (fixups == -FDT_ERR_NOTFOUND)
- return 0;
-
- return fixups;
- }
-
- /*
- * Update our local references from the root of the tree
- */
- return overlay_update_local_node_references(fdto, 0, fixups,
- delta);
-}
-
-/**
- * overlay_fixup_one_phandle - Set an overlay phandle to the base one
- * @fdt: Base Device Tree blob
- * @fdto: Device tree overlay blob
- * @symbols_off: Node offset of the symbols node in the base device tree
- * @path: Path to a node holding a phandle in the overlay
- * @path_len: number of path characters to consider
- * @name: Name of the property holding the phandle reference in the overlay
- * @name_len: number of name characters to consider
- * @poffset: Offset within the overlay property where the phandle is stored
- * @label: Label of the node referenced by the phandle
- *
- * overlay_fixup_one_phandle() resolves an overlay phandle pointing to
- * a node in the base device tree.
- *
- * This is part of the device tree overlay application process, when
- * you want all the phandles in the overlay to point to the actual
- * base dt nodes.
- *
- * returns:
- * 0 on success
- * Negative error code on failure
- */
-static int overlay_fixup_one_phandle(void *fdt, void *fdto,
- int symbols_off,
- const char *path, uint32_t path_len,
- const char *name, uint32_t name_len,
- int poffset, const char *label)
-{
- const char *symbol_path;
- uint32_t phandle;
- fdt32_t phandle_prop;
- int symbol_off, fixup_off;
- int prop_len;
-
- if (symbols_off < 0)
- return symbols_off;
-
- symbol_path = fdt_getprop(fdt, symbols_off, label,
- &prop_len);
- if (!symbol_path)
- return prop_len;
-
- symbol_off = fdt_path_offset(fdt, symbol_path);
- if (symbol_off < 0)
- return symbol_off;
-
- phandle = fdt_get_phandle(fdt, symbol_off);
- if (!phandle)
- return -FDT_ERR_NOTFOUND;
-
- fixup_off = fdt_path_offset_namelen(fdto, path, path_len);
- if (fixup_off == -FDT_ERR_NOTFOUND)
- return -FDT_ERR_BADOVERLAY;
- if (fixup_off < 0)
- return fixup_off;
-
- phandle_prop = cpu_to_fdt32(phandle);
- return fdt_setprop_inplace_namelen_partial(fdto, fixup_off,
- name, name_len, poffset,
- &phandle_prop,
- sizeof(phandle_prop));
-};
-
-/**
- * overlay_fixup_phandle - Set an overlay phandle to the base one
- * @fdt: Base Device Tree blob
- * @fdto: Device tree overlay blob
- * @symbols_off: Node offset of the symbols node in the base device tree
- * @property: Property offset in the overlay holding the list of fixups
- *
- * overlay_fixup_phandle() resolves all the overlay phandles pointed
- * to in a __fixups__ property, and updates them to match the phandles
- * in use in the base device tree.
- *
- * This is part of the device tree overlay application process, when
- * you want all the phandles in the overlay to point to the actual
- * base dt nodes.
- *
- * returns:
- * 0 on success
- * Negative error code on failure
- */
-static int overlay_fixup_phandle(void *fdt, void *fdto, int symbols_off,
- int property)
-{
- const char *value;
- const char *label;
- int len;
-
- value = fdt_getprop_by_offset(fdto, property,
- &label, &len);
- if (!value) {
- if (len == -FDT_ERR_NOTFOUND)
- return -FDT_ERR_INTERNAL;
-
- return len;
- }
-
- do {
- const char *path, *name, *fixup_end;
- const char *fixup_str = value;
- uint32_t path_len, name_len;
- uint32_t fixup_len;
- char *sep, *endptr;
- int poffset, ret;
-
- fixup_end = memchr(value, '\0', len);
- if (!fixup_end)
- return -FDT_ERR_BADOVERLAY;
- fixup_len = fixup_end - fixup_str;
-
- len -= fixup_len + 1;
- value += fixup_len + 1;
-
- path = fixup_str;
- sep = memchr(fixup_str, ':', fixup_len);
- if (!sep || *sep != ':')
- return -FDT_ERR_BADOVERLAY;
-
- path_len = sep - path;
- if (path_len == (fixup_len - 1))
- return -FDT_ERR_BADOVERLAY;
-
- fixup_len -= path_len + 1;
- name = sep + 1;
- sep = memchr(name, ':', fixup_len);
- if (!sep || *sep != ':')
- return -FDT_ERR_BADOVERLAY;
-
- name_len = sep - name;
- if (!name_len)
- return -FDT_ERR_BADOVERLAY;
-
- poffset = strtoul(sep + 1, &endptr, 10);
- if ((*endptr != '\0') || (endptr <= (sep + 1)))
- return -FDT_ERR_BADOVERLAY;
-
- ret = overlay_fixup_one_phandle(fdt, fdto, symbols_off,
- path, path_len, name, name_len,
- poffset, label);
- if (ret)
- return ret;
- } while (len > 0);
-
- return 0;
-}
-
-/**
- * overlay_fixup_phandles - Resolve the overlay phandles to the base
- * device tree
- * @fdt: Base Device Tree blob
- * @fdto: Device tree overlay blob
- *
- * overlay_fixup_phandles() resolves all the overlay phandles pointing
- * to nodes in the base device tree.
- *
- * This is one of the steps of the device tree overlay application
- * process, when you want all the phandles in the overlay to point to
- * the actual base dt nodes.
- *
- * returns:
- * 0 on success
- * Negative error code on failure
- */
-static int overlay_fixup_phandles(void *fdt, void *fdto)
-{
- int fixups_off, symbols_off;
- int property;
-
- /* We can have overlays without any fixups */
- fixups_off = fdt_path_offset(fdto, "/__fixups__");
- if (fixups_off == -FDT_ERR_NOTFOUND)
- return 0; /* nothing to do */
- if (fixups_off < 0)
- return fixups_off;
-
- /* And base DTs without symbols */
- symbols_off = fdt_path_offset(fdt, "/__symbols__");
- if ((symbols_off < 0 && (symbols_off != -FDT_ERR_NOTFOUND)))
- return symbols_off;
-
- fdt_for_each_property_offset(property, fdto, fixups_off) {
- int ret;
-
- ret = overlay_fixup_phandle(fdt, fdto, symbols_off, property);
- if (ret)
- return ret;
- }
-
- return 0;
-}
-
-/**
- * overlay_apply_node - Merges a node into the base device tree
- * @fdt: Base Device Tree blob
- * @target: Node offset in the base device tree to apply the fragment to
- * @fdto: Device tree overlay blob
- * @node: Node offset in the overlay holding the changes to merge
- *
- * overlay_apply_node() merges a node into a target base device tree
- * node pointed.
- *
- * This is part of the final step in the device tree overlay
- * application process, when all the phandles have been adjusted and
- * resolved and you just have to merge overlay into the base device
- * tree.
- *
- * returns:
- * 0 on success
- * Negative error code on failure
- */
-static int overlay_apply_node(void *fdt, int target,
- void *fdto, int node)
-{
- int property;
- int subnode;
-
- fdt_for_each_property_offset(property, fdto, node) {
- const char *name;
- const void *prop;
- int prop_len;
- int ret;
-
- prop = fdt_getprop_by_offset(fdto, property, &name,
- &prop_len);
- if (prop_len == -FDT_ERR_NOTFOUND)
- return -FDT_ERR_INTERNAL;
- if (prop_len < 0)
- return prop_len;
-
- ret = fdt_setprop(fdt, target, name, prop, prop_len);
- if (ret)
- return ret;
- }
-
- fdt_for_each_subnode(subnode, fdto, node) {
- const char *name = fdt_get_name(fdto, subnode, NULL);
- int nnode;
- int ret;
-
- nnode = fdt_add_subnode(fdt, target, name);
- if (nnode == -FDT_ERR_EXISTS) {
- nnode = fdt_subnode_offset(fdt, target, name);
- if (nnode == -FDT_ERR_NOTFOUND)
- return -FDT_ERR_INTERNAL;
- }
-
- if (nnode < 0)
- return nnode;
-
- ret = overlay_apply_node(fdt, nnode, fdto, subnode);
- if (ret)
- return ret;
- }
-
- return 0;
-}
-
-/**
- * overlay_merge - Merge an overlay into its base device tree
- * @fdt: Base Device Tree blob
- * @fdto: Device tree overlay blob
- *
- * overlay_merge() merges an overlay into its base device tree.
- *
- * This is the next to last step in the device tree overlay application
- * process, when all the phandles have been adjusted and resolved and
- * you just have to merge overlay into the base device tree.
- *
- * returns:
- * 0 on success
- * Negative error code on failure
- */
-static int overlay_merge(void *fdt, void *fdto)
-{
- int fragment;
-
- fdt_for_each_subnode(fragment, fdto, 0) {
- int overlay;
- int target;
- int ret;
-
- /*
- * Each fragments will have an __overlay__ node. If
- * they don't, it's not supposed to be merged
- */
- overlay = fdt_subnode_offset(fdto, fragment, "__overlay__");
- if (overlay == -FDT_ERR_NOTFOUND)
- continue;
-
- if (overlay < 0)
- return overlay;
-
- target = overlay_get_target(fdt, fdto, fragment, NULL);
- if (target < 0)
- return target;
-
- ret = overlay_apply_node(fdt, target, fdto, overlay);
- if (ret)
- return ret;
- }
-
- return 0;
-}
-
-static int get_path_len(const void *fdt, int nodeoffset)
-{
- int len = 0, namelen;
- const char *name;
-
- FDT_CHECK_HEADER(fdt);
-
- for (;;) {
- name = fdt_get_name(fdt, nodeoffset, &namelen);
- if (!name)
- return namelen;
-
- /* root? we're done */
- if (namelen == 0)
- break;
-
- nodeoffset = fdt_parent_offset(fdt, nodeoffset);
- if (nodeoffset < 0)
- return nodeoffset;
- len += namelen + 1;
- }
-
- /* in case of root pretend it's "/" */
- if (len == 0)
- len++;
- return len;
-}
-
-/**
- * overlay_symbol_update - Update the symbols of base tree after a merge
- * @fdt: Base Device Tree blob
- * @fdto: Device tree overlay blob
- *
- * overlay_symbol_update() updates the symbols of the base tree with the
- * symbols of the applied overlay
- *
- * This is the last step in the device tree overlay application
- * process, allowing the reference of overlay symbols by subsequent
- * overlay operations.
- *
- * returns:
- * 0 on success
- * Negative error code on failure
- */
-static int overlay_symbol_update(void *fdt, void *fdto)
-{
- int root_sym, ov_sym, prop, path_len, fragment, target;
- int len, frag_name_len, ret, rel_path_len;
- const char *s, *e;
- const char *path;
- const char *name;
- const char *frag_name;
- const char *rel_path;
- const char *target_path;
- char *buf;
- void *p;
-
- ov_sym = fdt_subnode_offset(fdto, 0, "__symbols__");
-
- /* if no overlay symbols exist no problem */
- if (ov_sym < 0)
- return 0;
-
- root_sym = fdt_subnode_offset(fdt, 0, "__symbols__");
-
- /* it no root symbols exist we should create them */
- if (root_sym == -FDT_ERR_NOTFOUND)
- root_sym = fdt_add_subnode(fdt, 0, "__symbols__");
-
- /* any error is fatal now */
- if (root_sym < 0)
- return root_sym;
-
- /* iterate over each overlay symbol */
- fdt_for_each_property_offset(prop, fdto, ov_sym) {
- path = fdt_getprop_by_offset(fdto, prop, &name, &path_len);
- if (!path)
- return path_len;
-
- /* verify it's a string property (terminated by a single \0) */
- if (path_len < 1 || memchr(path, '\0', path_len) != &path[path_len - 1])
- return -FDT_ERR_BADVALUE;
-
- /* keep end marker to avoid strlen() */
- e = path + path_len;
-
- /* format: /<fragment-name>/__overlay__/<relative-subnode-path> */
-
- if (*path != '/')
- return -FDT_ERR_BADVALUE;
-
- /* get fragment name first */
- s = strchr(path + 1, '/');
- if (!s)
- return -FDT_ERR_BADOVERLAY;
-
- frag_name = path + 1;
- frag_name_len = s - path - 1;
-
- /* verify format; safe since "s" lies in \0 terminated prop */
- len = sizeof("/__overlay__/") - 1;
- if ((e - s) < len || memcmp(s, "/__overlay__/", len))
- return -FDT_ERR_BADOVERLAY;
-
- rel_path = s + len;
- rel_path_len = e - rel_path;
-
- /* find the fragment index in which the symbol lies */
- ret = fdt_subnode_offset_namelen(fdto, 0, frag_name,
- frag_name_len);
- /* not found? */
- if (ret < 0)
- return -FDT_ERR_BADOVERLAY;
- fragment = ret;
-
- /* an __overlay__ subnode must exist */
- ret = fdt_subnode_offset(fdto, fragment, "__overlay__");
- if (ret < 0)
- return -FDT_ERR_BADOVERLAY;
-
- /* get the target of the fragment */
- ret = overlay_get_target(fdt, fdto, fragment, &target_path);
- if (ret < 0)
- return ret;
- target = ret;
-
- /* if we have a target path use */
- if (!target_path) {
- ret = get_path_len(fdt, target);
- if (ret < 0)
- return ret;
- len = ret;
- } else {
- len = strlen(target_path);
- }
-
- ret = fdt_setprop_placeholder(fdt, root_sym, name,
- len + (len > 1) + rel_path_len + 1, &p);
- if (ret < 0)
- return ret;
-
- if (!target_path) {
- /* again in case setprop_placeholder changed it */
- ret = overlay_get_target(fdt, fdto, fragment, &target_path);
- if (ret < 0)
- return ret;
- target = ret;
- }
-
- buf = p;
- if (len > 1) { /* target is not root */
- if (!target_path) {
- ret = fdt_get_path(fdt, target, buf, len + 1);
- if (ret < 0)
- return ret;
- } else
- memcpy(buf, target_path, len + 1);
-
- } else
- len--;
-
- buf[len] = '/';
- memcpy(buf + len + 1, rel_path, rel_path_len);
- buf[len + 1 + rel_path_len] = '\0';
- }
-
- return 0;
-}
-
-int fdt_overlay_apply(void *fdt, void *fdto)
-{
- uint32_t delta = fdt_get_max_phandle(fdt);
- int ret;
-
- FDT_CHECK_HEADER(fdt);
- FDT_CHECK_HEADER(fdto);
-
- ret = overlay_adjust_local_phandles(fdto, delta);
- if (ret)
- goto err;
-
- ret = overlay_update_local_references(fdto, delta);
- if (ret)
- goto err;
-
- ret = overlay_fixup_phandles(fdt, fdto);
- if (ret)
- goto err;
-
- ret = overlay_merge(fdt, fdto);
- if (ret)
- goto err;
-
- ret = overlay_symbol_update(fdt, fdto);
- if (ret)
- goto err;
-
- /*
- * The overlay has been damaged, erase its magic.
- */
- fdt_set_magic(fdto, ~0);
-
- return 0;
-
-err:
- /*
- * The overlay might have been damaged, erase its magic.
- */
- fdt_set_magic(fdto, ~0);
-
- /*
- * The base device tree might have been damaged, erase its
- * magic.
- */
- fdt_set_magic(fdt, ~0);
-
- return ret;
-}
+#include <linux/libfdt_env.h>
+#include "../../scripts/dtc/libfdt/fdt_overlay.c"
diff --git a/lib/libfdt/fdt_strerror.c b/lib/libfdt/fdt_strerror.c
index f89004c609f..408a88328fe 100644
--- a/lib/libfdt/fdt_strerror.c
+++ b/lib/libfdt/fdt_strerror.c
@@ -1,61 +1,2 @@
-/*
- * libfdt - Flat Device Tree manipulation
- * Copyright (C) 2006 David Gibson, IBM Corporation.
- * SPDX-License-Identifier: GPL-2.0+ BSD-2-Clause
- */
-#include <libfdt_env.h>
-
-#ifndef USE_HOSTCC
-#include <fdt.h>
-#include <libfdt.h>
-#else
-#include "fdt_host.h"
-#endif
-
-#include "libfdt_internal.h"
-
-struct fdt_errtabent {
- const char *str;
-};
-
-#define FDT_ERRTABENT(val) \
- [(val)] = { .str = #val, }
-
-static struct fdt_errtabent fdt_errtable[] = {
- FDT_ERRTABENT(FDT_ERR_NOTFOUND),
- FDT_ERRTABENT(FDT_ERR_EXISTS),
- FDT_ERRTABENT(FDT_ERR_NOSPACE),
-
- FDT_ERRTABENT(FDT_ERR_BADOFFSET),
- FDT_ERRTABENT(FDT_ERR_BADPATH),
- FDT_ERRTABENT(FDT_ERR_BADPHANDLE),
- FDT_ERRTABENT(FDT_ERR_BADSTATE),
-
- FDT_ERRTABENT(FDT_ERR_TRUNCATED),
- FDT_ERRTABENT(FDT_ERR_BADMAGIC),
- FDT_ERRTABENT(FDT_ERR_BADVERSION),
- FDT_ERRTABENT(FDT_ERR_BADSTRUCTURE),
- FDT_ERRTABENT(FDT_ERR_BADLAYOUT),
- FDT_ERRTABENT(FDT_ERR_INTERNAL),
- FDT_ERRTABENT(FDT_ERR_BADNCELLS),
- FDT_ERRTABENT(FDT_ERR_BADVALUE),
- FDT_ERRTABENT(FDT_ERR_BADOVERLAY),
- FDT_ERRTABENT(FDT_ERR_NOPHANDLES),
-};
-#define FDT_ERRTABSIZE (sizeof(fdt_errtable) / sizeof(fdt_errtable[0]))
-
-const char *fdt_strerror(int errval)
-{
- if (errval > 0)
- return "<valid offset/length>";
- else if (errval == 0)
- return "<no error>";
- else if (errval > -FDT_ERRTABSIZE) {
- const char *s = fdt_errtable[-errval].str;
-
- if (s)
- return s;
- }
-
- return "<unknown error>";
-}
+#include <linux/libfdt_env.h>
+#include "../../scripts/dtc/libfdt/fdt_strerror.c"
diff --git a/lib/libfdt/fdt_sw.c b/lib/libfdt/fdt_sw.c
index 70fd0265507..0da3ed92f31 100644
--- a/lib/libfdt/fdt_sw.c
+++ b/lib/libfdt/fdt_sw.c
@@ -1,254 +1,2 @@
-/*
- * libfdt - Flat Device Tree manipulation
- * Copyright (C) 2006 David Gibson, IBM Corporation.
- * SPDX-License-Identifier: GPL-2.0+ BSD-2-Clause
- */
-#include <libfdt_env.h>
-#include <fdt.h>
-#include <libfdt.h>
-
-#include "libfdt_internal.h"
-
-static int _fdt_sw_check_header(void *fdt)
-{
- if (fdt_magic(fdt) != FDT_SW_MAGIC)
- return -FDT_ERR_BADMAGIC;
- /* FIXME: should check more details about the header state */
- return 0;
-}
-
-#define FDT_SW_CHECK_HEADER(fdt) \
- { \
- int err; \
- if ((err = _fdt_sw_check_header(fdt)) != 0) \
- return err; \
- }
-
-static void *_fdt_grab_space(void *fdt, size_t len)
-{
- int offset = fdt_size_dt_struct(fdt);
- int spaceleft;
-
- spaceleft = fdt_totalsize(fdt) - fdt_off_dt_struct(fdt)
- - fdt_size_dt_strings(fdt);
-
- if ((offset + len < offset) || (offset + len > spaceleft))
- return NULL;
-
- fdt_set_size_dt_struct(fdt, offset + len);
- return _fdt_offset_ptr_w(fdt, offset);
-}
-
-int fdt_create(void *buf, int bufsize)
-{
- void *fdt = buf;
-
- if (bufsize < sizeof(struct fdt_header))
- return -FDT_ERR_NOSPACE;
-
- memset(buf, 0, bufsize);
-
- fdt_set_magic(fdt, FDT_SW_MAGIC);
- fdt_set_version(fdt, FDT_LAST_SUPPORTED_VERSION);
- fdt_set_last_comp_version(fdt, FDT_FIRST_SUPPORTED_VERSION);
- fdt_set_totalsize(fdt, bufsize);
-
- fdt_set_off_mem_rsvmap(fdt, FDT_ALIGN(sizeof(struct fdt_header),
- sizeof(struct fdt_reserve_entry)));
- fdt_set_off_dt_struct(fdt, fdt_off_mem_rsvmap(fdt));
- fdt_set_off_dt_strings(fdt, bufsize);
-
- return 0;
-}
-
-int fdt_resize(void *fdt, void *buf, int bufsize)
-{
- size_t headsize, tailsize;
- char *oldtail, *newtail;
-
- FDT_SW_CHECK_HEADER(fdt);
-
- headsize = fdt_off_dt_struct(fdt);
- tailsize = fdt_size_dt_strings(fdt);
-
- if ((headsize + tailsize) > bufsize)
- return -FDT_ERR_NOSPACE;
-
- oldtail = (char *)fdt + fdt_totalsize(fdt) - tailsize;
- newtail = (char *)buf + bufsize - tailsize;
-
- /* Two cases to avoid clobbering data if the old and new
- * buffers partially overlap */
- if (buf <= fdt) {
- memmove(buf, fdt, headsize);
- memmove(newtail, oldtail, tailsize);
- } else {
- memmove(newtail, oldtail, tailsize);
- memmove(buf, fdt, headsize);
- }
-
- fdt_set_off_dt_strings(buf, bufsize);
- fdt_set_totalsize(buf, bufsize);
-
- return 0;
-}
-
-int fdt_add_reservemap_entry(void *fdt, uint64_t addr, uint64_t size)
-{
- struct fdt_reserve_entry *re;
- int offset;
-
- FDT_SW_CHECK_HEADER(fdt);
-
- if (fdt_size_dt_struct(fdt))
- return -FDT_ERR_BADSTATE;
-
- offset = fdt_off_dt_struct(fdt);
- if ((offset + sizeof(*re)) > fdt_totalsize(fdt))
- return -FDT_ERR_NOSPACE;
-
- re = (struct fdt_reserve_entry *)((char *)fdt + offset);
- re->address = cpu_to_fdt64(addr);
- re->size = cpu_to_fdt64(size);
-
- fdt_set_off_dt_struct(fdt, offset + sizeof(*re));
-
- return 0;
-}
-
-int fdt_finish_reservemap(void *fdt)
-{
- return fdt_add_reservemap_entry(fdt, 0, 0);
-}
-
-int fdt_begin_node(void *fdt, const char *name)
-{
- struct fdt_node_header *nh;
- int namelen = strlen(name) + 1;
-
- FDT_SW_CHECK_HEADER(fdt);
-
- nh = _fdt_grab_space(fdt, sizeof(*nh) + FDT_TAGALIGN(namelen));
- if (! nh)
- return -FDT_ERR_NOSPACE;
-
- nh->tag = cpu_to_fdt32(FDT_BEGIN_NODE);
- memcpy(nh->name, name, namelen);
- return 0;
-}
-
-int fdt_end_node(void *fdt)
-{
- fdt32_t *en;
-
- FDT_SW_CHECK_HEADER(fdt);
-
- en = _fdt_grab_space(fdt, FDT_TAGSIZE);
- if (! en)
- return -FDT_ERR_NOSPACE;
-
- *en = cpu_to_fdt32(FDT_END_NODE);
- return 0;
-}
-
-static int _fdt_find_add_string(void *fdt, const char *s)
-{
- char *strtab = (char *)fdt + fdt_totalsize(fdt);
- const char *p;
- int strtabsize = fdt_size_dt_strings(fdt);
- int len = strlen(s) + 1;
- int struct_top, offset;
-
- p = _fdt_find_string(strtab - strtabsize, strtabsize, s);
- if (p)
- return p - strtab;
-
- /* Add it */
- offset = -strtabsize - len;
- struct_top = fdt_off_dt_struct(fdt) + fdt_size_dt_struct(fdt);
- if (fdt_totalsize(fdt) + offset < struct_top)
- return 0; /* no more room :( */
-
- memcpy(strtab + offset, s, len);
- fdt_set_size_dt_strings(fdt, strtabsize + len);
- return offset;
-}
-
-int fdt_property_placeholder(void *fdt, const char *name, int len, void **valp)
-{
- struct fdt_property *prop;
- int nameoff;
-
- FDT_SW_CHECK_HEADER(fdt);
-
- nameoff = _fdt_find_add_string(fdt, name);
- if (nameoff == 0)
- return -FDT_ERR_NOSPACE;
-
- prop = _fdt_grab_space(fdt, sizeof(*prop) + FDT_TAGALIGN(len));
- if (! prop)
- return -FDT_ERR_NOSPACE;
-
- prop->tag = cpu_to_fdt32(FDT_PROP);
- prop->nameoff = cpu_to_fdt32(nameoff);
- prop->len = cpu_to_fdt32(len);
- *valp = prop->data;
- return 0;
-}
-
-int fdt_property(void *fdt, const char *name, const void *val, int len)
-{
- void *ptr;
- int ret;
-
- ret = fdt_property_placeholder(fdt, name, len, &ptr);
- if (ret)
- return ret;
- memcpy(ptr, val, len);
- return 0;
-}
-
-int fdt_finish(void *fdt)
-{
- char *p = (char *)fdt;
- fdt32_t *end;
- int oldstroffset, newstroffset;
- uint32_t tag;
- int offset, nextoffset;
-
- FDT_SW_CHECK_HEADER(fdt);
-
- /* Add terminator */
- end = _fdt_grab_space(fdt, sizeof(*end));
- if (! end)
- return -FDT_ERR_NOSPACE;
- *end = cpu_to_fdt32(FDT_END);
-
- /* Relocate the string table */
- oldstroffset = fdt_totalsize(fdt) - fdt_size_dt_strings(fdt);
- newstroffset = fdt_off_dt_struct(fdt) + fdt_size_dt_struct(fdt);
- memmove(p + newstroffset, p + oldstroffset, fdt_size_dt_strings(fdt));
- fdt_set_off_dt_strings(fdt, newstroffset);
-
- /* Walk the structure, correcting string offsets */
- offset = 0;
- while ((tag = fdt_next_tag(fdt, offset, &nextoffset)) != FDT_END) {
- if (tag == FDT_PROP) {
- struct fdt_property *prop =
- _fdt_offset_ptr_w(fdt, offset);
- int nameoff;
-
- nameoff = fdt32_to_cpu(prop->nameoff);
- nameoff += fdt_size_dt_strings(fdt);
- prop->nameoff = cpu_to_fdt32(nameoff);
- }
- offset = nextoffset;
- }
- if (nextoffset < 0)
- return nextoffset;
-
- /* Finally, adjust the header */
- fdt_set_totalsize(fdt, newstroffset + fdt_size_dt_strings(fdt));
- fdt_set_magic(fdt, FDT_MAGIC);
- return 0;
-}
+#include <linux/libfdt_env.h>
+#include "../../scripts/dtc/libfdt/fdt_sw.c"
diff --git a/lib/libfdt/libfdt_internal.h b/lib/libfdt/libfdt_internal.h
index 9a79fe85dda..5197c5d6981 100644
--- a/lib/libfdt/libfdt_internal.h
+++ b/lib/libfdt/libfdt_internal.h
@@ -1,50 +1 @@
-#ifndef _LIBFDT_INTERNAL_H
-#define _LIBFDT_INTERNAL_H
-/*
- * libfdt - Flat Device Tree manipulation
- * Copyright (C) 2006 David Gibson, IBM Corporation.
- * SPDX-License-Identifier: GPL-2.0+ BSD-2-Clause
- */
-#include <fdt.h>
-
-#define FDT_ALIGN(x, a) (((x) + (a) - 1) & ~((a) - 1))
-#define FDT_TAGALIGN(x) (FDT_ALIGN((x), FDT_TAGSIZE))
-
-#define FDT_CHECK_HEADER(fdt) \
- { \
- int __err; \
- if ((__err = fdt_check_header(fdt)) != 0) \
- return __err; \
- }
-
-int _fdt_check_node_offset(const void *fdt, int offset);
-int _fdt_check_prop_offset(const void *fdt, int offset);
-const char *_fdt_find_string(const char *strtab, int tabsize, const char *s);
-int _fdt_node_end_offset(void *fdt, int nodeoffset);
-
-static inline const void *_fdt_offset_ptr(const void *fdt, int offset)
-{
- return (const char *)fdt + fdt_off_dt_struct(fdt) + offset;
-}
-
-static inline void *_fdt_offset_ptr_w(void *fdt, int offset)
-{
- return (void *)(uintptr_t)_fdt_offset_ptr(fdt, offset);
-}
-
-static inline const struct fdt_reserve_entry *_fdt_mem_rsv(const void *fdt, int n)
-{
- const struct fdt_reserve_entry *rsv_table =
- (const struct fdt_reserve_entry *)
- ((const char *)fdt + fdt_off_mem_rsvmap(fdt));
-
- return rsv_table + n;
-}
-static inline struct fdt_reserve_entry *_fdt_mem_rsv_w(void *fdt, int n)
-{
- return (void *)(uintptr_t)_fdt_mem_rsv(fdt, n);
-}
-
-#define FDT_SW_MAGIC (~FDT_MAGIC)
-
-#endif /* _LIBFDT_INTERNAL_H */
+#include "../../scripts/dtc/libfdt/libfdt_internal.h"
diff --git a/lib/libfdt/pylibfdt/libfdt.i b/lib/libfdt/pylibfdt/libfdt.i
deleted file mode 100644
index 5b1a8cf4d49..00000000000
--- a/lib/libfdt/pylibfdt/libfdt.i
+++ /dev/null
@@ -1,449 +0,0 @@
-/*
- * pylibfdt - Flat Device Tree manipulation in Python
- * Copyright (C) 2017 Google, Inc.
- * Written by Simon Glass <sjg@chromium.org>
- *
- * SPDX-License-Identifier: GPL-2.0+ BSD-2-Clause
- */
-
-%module libfdt
-
-%include <stdint.i>
-
-%{
-#define SWIG_FILE_WITH_INIT
-#include "libfdt.h"
-%}
-
-%pythoncode %{
-
-import struct
-
-# Error codes, corresponding to FDT_ERR_... in libfdt.h
-(NOTFOUND,
- EXISTS,
- NOSPACE,
- BADOFFSET,
- BADPATH,
- BADPHANDLE,
- BADSTATE,
- TRUNCATED,
- BADMAGIC,
- BADVERSION,
- BADSTRUCTURE,
- BADLAYOUT,
- INTERNAL,
- BADNCELLS,
- BADVALUE,
- BADOVERLAY,
- NOPHANDLES) = QUIET_ALL = range(1, 18)
-# QUIET_ALL can be passed as the 'quiet' parameter to avoid exceptions
-# altogether. All # functions passed this value will return an error instead
-# of raising an exception.
-
-# Pass this as the 'quiet' parameter to return -ENOTFOUND on NOTFOUND errors,
-# instead of raising an exception.
-QUIET_NOTFOUND = (NOTFOUND,)
-
-
-class FdtException(Exception):
- """An exception caused by an error such as one of the codes above"""
- def __init__(self, err):
- self.err = err
-
- def __str__(self):
- return 'pylibfdt error %d: %s' % (self.err, fdt_strerror(self.err))
-
-def strerror(fdt_err):
- """Get the string for an error number
-
- Args:
- fdt_err: Error number (-ve)
-
- Returns:
- String containing the associated error
- """
- return fdt_strerror(fdt_err)
-
-def check_err(val, quiet=()):
- """Raise an error if the return value is -ve
-
- This is used to check for errors returned by libfdt C functions.
-
- Args:
- val: Return value from a libfdt function
- quiet: Errors to ignore (empty to raise on all errors)
-
- Returns:
- val if val >= 0
-
- Raises
- FdtException if val < 0
- """
- if val < 0:
- if -val not in quiet:
- raise FdtException(val)
- return val
-
-def check_err_null(val, quiet=()):
- """Raise an error if the return value is NULL
-
- This is used to check for a NULL return value from certain libfdt C
- functions
-
- Args:
- val: Return value from a libfdt function
- quiet: Errors to ignore (empty to raise on all errors)
-
- Returns:
- val if val is a list, None if not
-
- Raises
- FdtException if val indicates an error was reported and the error
- is not in @quiet.
- """
- # Normally a list is returned which contains the data and its length.
- # If we get just an integer error code, it means the function failed.
- if not isinstance(val, list):
- if -val not in quiet:
- raise FdtException(val)
- return val
-
-class Fdt:
- """Device tree class, supporting all operations
-
- The Fdt object is created is created from a device tree binary file,
- e.g. with something like:
-
- fdt = Fdt(open("filename.dtb").read())
-
- Operations can then be performed using the methods in this class. Each
- method xxx(args...) corresponds to a libfdt function fdt_xxx(fdt, args...).
-
- All methods raise an FdtException if an error occurs. To avoid this
- behaviour a 'quiet' parameter is provided for some functions. This
- defaults to empty, but you can pass a list of errors that you expect.
- If one of these errors occurs, the function will return an error number
- (e.g. -NOTFOUND).
- """
- def __init__(self, data):
- self._fdt = bytearray(data)
- check_err(fdt_check_header(self._fdt));
-
- def subnode_offset(self, parentoffset, name, quiet=()):
- """Get the offset of a named subnode
-
- Args:
- parentoffset: Offset of the parent node to check
- name: Name of the required subnode, e.g. 'subnode@1'
- quiet: Errors to ignore (empty to raise on all errors)
-
- Returns:
- The node offset of the found node, if any
-
- Raises
- FdtException if there is no node with that name, or other error
- """
- return check_err(fdt_subnode_offset(self._fdt, parentoffset, name),
- quiet)
-
- def path_offset(self, path, quiet=()):
- """Get the offset for a given path
-
- Args:
- path: Path to the required node, e.g. '/node@3/subnode@1'
- quiet: Errors to ignore (empty to raise on all errors)
-
- Returns:
- Node offset
-
- Raises
- FdtException if the path is not valid or not found
- """
- return check_err(fdt_path_offset(self._fdt, path), quiet)
-
- def first_property_offset(self, nodeoffset, quiet=()):
- """Get the offset of the first property in a node offset
-
- Args:
- nodeoffset: Offset to the node to check
- quiet: Errors to ignore (empty to raise on all errors)
-
- Returns:
- Offset of the first property
-
- Raises
- FdtException if the associated node has no properties, or some
- other error occurred
- """
- return check_err(fdt_first_property_offset(self._fdt, nodeoffset),
- quiet)
-
- def next_property_offset(self, prop_offset, quiet=()):
- """Get the next property in a node
-
- Args:
- prop_offset: Offset of the previous property
- quiet: Errors to ignore (empty to raise on all errors)
-
- Returns:
- Offset of the next property
-
- Raises:
- FdtException if the associated node has no more properties, or
- some other error occurred
- """
- return check_err(fdt_next_property_offset(self._fdt, prop_offset),
- quiet)
-
- def get_name(self, nodeoffset):
- """Get the name of a node
-
- Args:
- nodeoffset: Offset of node to check
-
- Returns:
- Node name
-
- Raises:
- FdtException on error (e.g. nodeoffset is invalid)
- """
- return check_err_null(fdt_get_name(self._fdt, nodeoffset))[0]
-
- def get_property_by_offset(self, prop_offset, quiet=()):
- """Obtains a property that can be examined
-
- Args:
- prop_offset: Offset of property (e.g. from first_property_offset())
- quiet: Errors to ignore (empty to raise on all errors)
-
- Returns:
- Property object, or None if not found
-
- Raises:
- FdtException on error (e.g. invalid prop_offset or device
- tree format)
- """
- pdata = check_err_null(
- fdt_get_property_by_offset(self._fdt, prop_offset), quiet)
- if isinstance(pdata, (int)):
- return pdata
- return Property(pdata[0], pdata[1])
-
- def first_subnode(self, nodeoffset, quiet=()):
- """Find the first subnode of a parent node
-
- Args:
- nodeoffset: Node offset of parent node
- quiet: Errors to ignore (empty to raise on all errors)
-
- Returns:
- The offset of the first subnode, if any
-
- Raises:
- FdtException if no subnode found or other error occurs
- """
- return check_err(fdt_first_subnode(self._fdt, nodeoffset), quiet)
-
- def next_subnode(self, nodeoffset, quiet=()):
- """Find the next subnode
-
- Args:
- nodeoffset: Node offset of previous subnode
- quiet: Errors to ignore (empty to raise on all errors)
-
- Returns:
- The offset of the next subnode, if any
-
- Raises:
- FdtException if no more subnode found or other error occurs
- """
- return check_err(fdt_next_subnode(self._fdt, nodeoffset), quiet)
-
- def totalsize(self):
- """Return the total size of the device tree
-
- Returns:
- Total tree size in bytes
- """
- return check_err(fdt_totalsize(self._fdt))
-
- def off_dt_struct(self):
- """Return the start of the device tree struct area
-
- Returns:
- Start offset of struct area
- """
- return check_err(fdt_off_dt_struct(self._fdt))
-
- def pack(self, quiet=()):
- """Pack the device tree to remove unused space
-
- This adjusts the tree in place.
-
- Args:
- quiet: Errors to ignore (empty to raise on all errors)
-
- Raises:
- FdtException if any error occurs
- """
- return check_err(fdt_pack(self._fdt), quiet)
-
- def delprop(self, nodeoffset, prop_name):
- """Delete a property from a node
-
- Args:
- nodeoffset: Node offset containing property to delete
- prop_name: Name of property to delete
-
- Raises:
- FdtError if the property does not exist, or another error occurs
- """
- return check_err(fdt_delprop(self._fdt, nodeoffset, prop_name))
-
- def getprop(self, nodeoffset, prop_name, quiet=()):
- """Get a property from a node
-
- Args:
- nodeoffset: Node offset containing property to get
- prop_name: Name of property to get
- quiet: Errors to ignore (empty to raise on all errors)
-
- Returns:
- Value of property as a bytearray, or -ve error number
-
- Raises:
- FdtError if any error occurs (e.g. the property is not found)
- """
- pdata = check_err_null(fdt_getprop(self._fdt, nodeoffset, prop_name),
- quiet)
- if isinstance(pdata, (int)):
- return pdata
- return bytearray(pdata[0])
-
- def get_phandle(self, nodeoffset):
- """Get the phandle of a node
-
- Args:
- nodeoffset: Node offset to check
-
- Returns:
- phandle of node, or 0 if the node has no phandle or another error
- occurs
- """
- return fdt_get_phandle(self._fdt, nodeoffset)
-
- def parent_offset(self, nodeoffset, quiet=()):
- """Get the offset of a node's parent
-
- Args:
- nodeoffset: Node offset to check
- quiet: Errors to ignore (empty to raise on all errors)
-
- Returns:
- The offset of the parent node, if any
-
- Raises:
- FdtException if no parent found or other error occurs
- """
- return check_err(fdt_parent_offset(self._fdt, nodeoffset), quiet)
-
- def node_offset_by_phandle(self, phandle, quiet=()):
- """Get the offset of a node with the given phandle
-
- Args:
- phandle: Phandle to search for
- quiet: Errors to ignore (empty to raise on all errors)
-
- Returns:
- The offset of node with that phandle, if any
-
- Raises:
- FdtException if no node found or other error occurs
- """
- return check_err(fdt_node_offset_by_phandle(self._fdt, phandle), quiet)
-
-class Property:
- """Holds a device tree property name and value.
-
- This holds a copy of a property taken from the device tree. It does not
- reference the device tree, so if anything changes in the device tree,
- a Property object will remain valid.
-
- Properties:
- name: Property name
- value: Proper value as a bytearray
- """
- def __init__(self, name, value):
- self.name = name
- self.value = value
-%}
-
-%rename(fdt_property) fdt_property_func;
-
-typedef int fdt32_t;
-
-%include "libfdt/fdt.h"
-
-%include "typemaps.i"
-
-/* Most functions don't change the device tree, so use a const void * */
-%typemap(in) (const void *)(const void *fdt) {
- if (!PyByteArray_Check($input)) {
- SWIG_exception_fail(SWIG_TypeError, "in method '" "$symname"
- "', argument " "$argnum"" of type '" "$type""'");
- }
- $1 = (void *)PyByteArray_AsString($input);
- fdt = $1;
- fdt = fdt; /* avoid unused variable warning */
-}
-
-/* Some functions do change the device tree, so use void * */
-%typemap(in) (void *)(const void *fdt) {
- if (!PyByteArray_Check($input)) {
- SWIG_exception_fail(SWIG_TypeError, "in method '" "$symname"
- "', argument " "$argnum"" of type '" "$type""'");
- }
- $1 = PyByteArray_AsString($input);
- fdt = $1;
- fdt = fdt; /* avoid unused variable warning */
-}
-
-%typemap(out) (struct fdt_property *) {
- PyObject *buff;
-
- if ($1) {
- resultobj = PyString_FromString(
- fdt_string(fdt1, fdt32_to_cpu($1->nameoff)));
- buff = PyByteArray_FromStringAndSize(
- (const char *)($1 + 1), fdt32_to_cpu($1->len));
- resultobj = SWIG_Python_AppendOutput(resultobj, buff);
- }
-}
-
-%apply int *OUTPUT { int *lenp };
-
-/* typemap used for fdt_getprop() */
-%typemap(out) (const void *) {
- if (!$1)
- $result = Py_None;
- else
- $result = Py_BuildValue("s#", $1, *arg4);
-}
-
-/* We have both struct fdt_property and a function fdt_property() */
-%warnfilter(302) fdt_property;
-
-/* These are macros in the header so have to be redefined here */
-int fdt_magic(const void *fdt);
-int fdt_totalsize(const void *fdt);
-int fdt_off_dt_struct(const void *fdt);
-int fdt_off_dt_strings(const void *fdt);
-int fdt_off_mem_rsvmap(const void *fdt);
-int fdt_version(const void *fdt);
-int fdt_last_comp_version(const void *fdt);
-int fdt_boot_cpuid_phys(const void *fdt);
-int fdt_size_dt_strings(const void *fdt);
-int fdt_size_dt_struct(const void *fdt);
-
-%include <../libfdt/libfdt.h>
diff --git a/lib/libfdt/pylibfdt/setup.py b/lib/libfdt/pylibfdt/setup.py
deleted file mode 100755
index daf1089425d..00000000000
--- a/lib/libfdt/pylibfdt/setup.py
+++ /dev/null
@@ -1,123 +0,0 @@
-#!/usr/bin/env python
-
-"""
-setup.py file for SWIG libfdt
-Copyright (C) 2017 Google, Inc.
-Written by Simon Glass <sjg@chromium.org>
-
-SPDX-License-Identifier: GPL-2.0+ BSD-2-Clause
-
-Files to be built into the extension are provided in SOURCES
-C flags to use are provided in CPPFLAGS
-Object file directory is provided in OBJDIR
-Version is provided in VERSION
-
-If these variables are not given they are parsed from the Makefiles. This
-allows this script to be run stand-alone, e.g.:
-
- ./pylibfdt/setup.py install [--prefix=...]
-"""
-
-from distutils.core import setup, Extension
-import os
-import re
-import sys
-
-# Decodes a Makefile assignment line into key and value (and plus for +=)
-RE_KEY_VALUE = re.compile('(?P<key>\w+) *(?P<plus>[+])?= *(?P<value>.*)$')
-
-
-def ParseMakefile(fname):
- """Parse a Makefile to obtain its variables.
-
- This collects variable assigments of the form:
-
- VAR = value
- VAR += more
-
- It does not pick out := assignments, as these are not needed here. It does
- handle line continuation.
-
- Returns a dict:
- key: Variable name (e.g. 'VAR')
- value: Variable value (e.g. 'value more')
- """
- makevars = {}
- with open(fname) as fd:
- prev_text = '' # Continuation text from previous line(s)
- for line in fd.read().splitlines():
- if line and line[-1] == '\\': # Deal with line continuation
- prev_text += line[:-1]
- continue
- elif prev_text:
- line = prev_text + line
- prev_text = '' # Continuation is now used up
- m = RE_KEY_VALUE.match(line)
- if m:
- value = m.group('value') or ''
- key = m.group('key')
-
- # Appending to a variable inserts a space beforehand
- if 'plus' in m.groupdict() and key in makevars:
- makevars[key] += ' ' + value
- else:
- makevars[key] = value
- return makevars
-
-def GetEnvFromMakefiles():
- """Scan the Makefiles to obtain the settings we need.
-
- This assumes that this script is being run from the top-level directory,
- not the pylibfdt directory.
-
- Returns:
- Tuple with:
- List of swig options
- Version string
- List of files to build
- List of extra C preprocessor flags needed
- Object directory to use (always '')
- """
- basedir = os.path.dirname(os.path.dirname(os.path.abspath(sys.argv[0])))
- swig_opts = ['-I%s' % basedir]
- makevars = ParseMakefile(os.path.join(basedir, 'Makefile'))
- version = '%s.%s.%s' % (makevars['VERSION'], makevars['PATCHLEVEL'],
- makevars['SUBLEVEL'])
- makevars = ParseMakefile(os.path.join(basedir, 'libfdt', 'Makefile.libfdt'))
- files = makevars['LIBFDT_SRCS'].split()
- files = [os.path.join(basedir, 'libfdt', fname) for fname in files]
- files.append('pylibfdt/libfdt.i')
- cflags = ['-I%s' % basedir, '-I%s/libfdt' % basedir]
- objdir = ''
- return swig_opts, version, files, cflags, objdir
-
-
-progname = sys.argv[0]
-files = os.environ.get('SOURCES', '').split()
-cflags = os.environ.get('CPPFLAGS', '').split()
-objdir = os.environ.get('OBJDIR')
-version = os.environ.get('VERSION')
-swig_opts = os.environ.get('SWIG_OPTS', '').split()
-
-# If we were called directly rather than through our Makefile (which is often
-# the case with Python module installation), read the settings from the
-# Makefile.
-if not all((swig_opts, version, files, cflags, objdir)):
- swig_opts, version, files, cflags, objdir = GetEnvFromMakefiles()
-
-libfdt_module = Extension(
- '_libfdt',
- sources = files,
- extra_compile_args = cflags,
- swig_opts = swig_opts,
-)
-
-setup(
- name='libfdt',
- version= version,
- author='Simon Glass <sjg@chromium.org>',
- description='Python binding for libfdt',
- ext_modules=[libfdt_module],
- package_dir={'': objdir},
- py_modules=['pylibfdt/libfdt'],
-)