summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSzuWei Lin <szuweilin@google.com>2017-04-17 01:45:09 +0000
committerandroid-build-merger <android-build-merger@google.com>2017-04-17 01:45:09 +0000
commit56e42407b843300bb4c9ff759f446078ca45e2cd (patch)
tree0c730d0a3e83db73cb55bd2536be90029955062e
parent4012a97e0bd99eaebfc99eb30aa4b06ac892a0bf (diff)
parent44ea8e620811ebd2ac41c61bca9e4daab3601eb0 (diff)
downloadplatform_system_libufdt-56e42407b843300bb4c9ff759f446078ca45e2cd.tar.gz
platform_system_libufdt-56e42407b843300bb4c9ff759f446078ca45e2cd.tar.bz2
platform_system_libufdt-56e42407b843300bb4c9ff759f446078ca45e2cd.zip
Code revise am: 8a7039c218 am: 9608fc02d1
am: 44ea8e6208 Change-Id: I68c4732fae790aa30e8cee7fe134bb4d788a4672
-rw-r--r--include/libufdt.h104
-rw-r--r--include/ufdt_types.h43
-rw-r--r--tests/src/fdt_overlay_test_app.c6
-rw-r--r--tests/src/ufdt_overlay_test_app.c6
-rw-r--r--ufdt_convert.c78
-rw-r--r--ufdt_node.c62
-rw-r--r--ufdt_overlay.c131
7 files changed, 177 insertions, 253 deletions
diff --git a/include/libufdt.h b/include/libufdt.h
index 7957bfa..0542b56 100644
--- a/include/libufdt.h
+++ b/include/libufdt.h
@@ -26,7 +26,7 @@
/*
* Allocates spaces for new ufdt_node who represents a fdt node at fdt_tag_ptr.
- * In order to get name pointer, it's neccassary to give the pointer to the
+ * In order to get name pointer, it's necessary to give the pointer to the
* entire fdt it belongs to.
*
*
@@ -148,7 +148,7 @@ uint32_t ufdt_node_get_phandle(const struct ufdt_node *node);
/*
* Constructs a ufdt whose base fdt is fdtp.
* Note that this function doesn't construct the entire tree.
- * To get the whole tree please call `fdt_to_ufdt(fdtp, fdt_size)`
+ * To get the whole tree please call `ufdt_from_fdt(fdtp, fdt_size)`
*
* @return: an empty ufdt with base fdtp = fdtp
*/
@@ -156,7 +156,7 @@ struct ufdt *ufdt_construct(void *fdtp);
/*
* Frees the space occupied by the ufdt, including all ufdt_nodes
- * with static_phandle_table.
+ * with ufdt_static_phandle_table.
*/
void ufdt_destruct(struct ufdt *tree);
@@ -191,7 +191,7 @@ int ufdt_get_string_off(const struct ufdt *tree, const char *s);
struct ufdt_node *ufdt_get_node_by_phandle(struct ufdt *tree, uint32_t phandle);
/*
- * Gets the pointer to the ufdt_node in tree with absoulte path =
+ * Gets the pointer to the ufdt_node in tree with absolute path =
* path[0..len-1].
* Absolute path has form "/path/to/node" or "some_alias/to/node".
* In later example, some_alias is a property in "/aliases" with data is a path
@@ -208,77 +208,16 @@ struct ufdt_node *ufdt_get_node_by_path_len(struct ufdt *tree, const char *path,
struct ufdt_node *ufdt_get_node_by_path(struct ufdt *tree, const char *path);
/*
- * END of ufdt methods.
- */
-
-/*
- * Compares function between 2 nodes, compare by name of each node.
- *
- * @return: x < 0 if a's name is lexicographically smaller
- * x == 0 if a, b has same name
- * x > 0 if a's name is lexicographically bigger
- */
-int node_cmp(const void *a, const void *b);
-
-/*
* Determines whether node->name equals to name[0..len-1]
*
* @return: true if they're equal.
* false otherwise
*/
-bool node_name_eq(const struct ufdt_node *node, const char *name, int len);
+bool ufdt_node_name_eq(const struct ufdt_node *node, const char *name, int len);
/*
- * Merges tree_b into tree_a with tree_b has all nodes except root disappeared.
- * Overwrite property in tree_a if there's one with same name in tree_b.
- * Otherwise add the property to tree_a.
- * For subnodes with the same name, recursively run this function.
- *
- * Ex:
- * tree_a : ta {
- * b = "b";
- * c = "c";
- * d {
- * e = "g";
- * };
- * };
- *
- * tree_b : tb {
- * c = "C";
- * g = "G";
- * d {
- * da = "dad";
- * };
- * h {
- * hh = "HH";
- * };
- * };
- *
- * The resulting trees will be:
- *
- * tree_a : ta {
- * b = "b";
- * c = "C";
- * g = "G";
- * d {
- * da = "dad";
- * e = "g";
- * };
- * h {
- * hh = "HH";
- * };
- * };
- *
- * tree_b : tb {
- * };
- *
- *
- * @return: 0 if merge success
- * < 0 otherwise
- *
- * @Time: O(# of nodes in tree_b + total length of all names in tree_b) w.h.p.
+ * END of ufdt methods.
*/
-int merge_ufdt_into(struct ufdt_node *tree_a, struct ufdt_node *tree_b);
/*
* BEGIN of ufdt output functions
@@ -292,7 +231,7 @@ int merge_ufdt_into(struct ufdt_node *tree_a, struct ufdt_node *tree_b);
*
* @Time: O(fdt_size + nlogn) where n = # of nodes in fdt.
*/
-struct ufdt *fdt_to_ufdt(void *fdtp, size_t fdt_size);
+struct ufdt *ufdt_from_fdt(void *fdtp, size_t fdt_size);
/*
* Sequentially dumps the whole ufdt to FDT buffer fdtp with buffer size
@@ -330,33 +269,4 @@ void ufdt_print(struct ufdt *tree);
* END of ufdt output functions
*/
-/*
- * Runs closure.func(node, closure.env) for all nodes in subtree rooted at
- * *node.
- * The order of each node being applied by the function is depth first.
- * Basically it's the same order as the order printed in ufdt_node_print().
- *
- * Example:
- *
- * void print_name(struct ufdt_node *node, void *env) {
- * printf("%s\n", node->name);
- * }
- *
- * struct ufdt_node_closure clos;
- * clos.func = print_name;
- * clos.env = NULL;
- * ufdt_map(tree, clos);
- *
- * Then you can print all names of nodes in tree.
- *
- * @Time: O((# of nodes in subtree rooted at *node) * avg. running time of the
- * function closure.func)
- */
-void ufdt_node_map(struct ufdt_node *node, struct ufdt_node_closure closure);
-
-/*
- * It's just ufdt_node_map(tree->root, closure);
- */
-void ufdt_map(struct ufdt *tree, struct ufdt_node_closure closure);
-
#endif /* LIBUFDT_H */
diff --git a/include/ufdt_types.h b/include/ufdt_types.h
index aebe615..b741f82 100644
--- a/include/ufdt_types.h
+++ b/include/ufdt_types.h
@@ -26,51 +26,54 @@
if (*it)
#define for_each_child(it, node) \
- if (tag_of(node) == FDT_BEGIN_NODE) \
- for ((it) = &(((struct fdt_node_ufdt_node *)node)->child); *it; \
+ if (ufdt_node_tag(node) == FDT_BEGIN_NODE) \
+ for ((it) = &(((struct ufdt_node_fdt_node *)node)->child); *it; \
it = &((*it)->sibling))
#define for_each_prop(it, node) \
- for_each_child(it, node) if (tag_of(*it) == FDT_PROP)
+ for_each_child(it, node) if (ufdt_node_tag(*it) == FDT_PROP)
#define for_each_node(it, node) \
- for_each_child(it, node) if (tag_of(*it) == FDT_BEGIN_NODE)
+ for_each_child(it, node) if (ufdt_node_tag(*it) == FDT_BEGIN_NODE)
/*
* Gets prop name from FDT requires complicated manipulation.
- * To avoid the manipulation, the *name pointer in fdt_prop_ufdt_node
+ * To avoid the manipulation, the *name pointer in ufdt_node_fdt_prop
* is pointed to the final destination of the prop name in FDT.
* For the FDT_BEGIN_NODE name, it can be obtained from FDT directly.
*/
-#define name_of(node) \
- ((tag_of(node) == FDT_BEGIN_NODE) \
+#define ufdt_node_name(node) \
+ ((ufdt_node_tag(node) == FDT_BEGIN_NODE) \
? (((const struct fdt_node_header *)((node)->fdt_tag_ptr))->name) \
- : (((const struct fdt_prop_ufdt_node *)node)->name))
+ : (((const struct ufdt_node_fdt_prop *)node)->name))
+
+#define ufdt_node_tag(node) \
+ ((node) ? fdt32_to_cpu(*(node)->fdt_tag_ptr) : FDT_END)
struct ufdt_node {
fdt32_t *fdt_tag_ptr;
struct ufdt_node *sibling;
};
-struct fdt_prop_ufdt_node {
+struct ufdt_node_fdt_prop {
struct ufdt_node parent;
const char *name;
};
-struct fdt_node_ufdt_node {
+struct ufdt_node_fdt_node {
struct ufdt_node parent;
struct ufdt_node *child;
struct ufdt_node **last_child_p;
};
-struct phandle_table_entry {
+struct ufdt_phandle_table_entry {
uint32_t phandle;
struct ufdt_node *node;
};
-struct static_phandle_table {
+struct ufdt_static_phandle_table {
int len;
- struct phandle_table_entry *data;
+ struct ufdt_phandle_table_entry *data;
};
struct ufdt {
@@ -79,19 +82,7 @@ struct ufdt {
int num_used_fdtps;
struct ufdt_node *root;
- struct static_phandle_table phandle_table;
+ struct ufdt_static_phandle_table phandle_table;
};
-typedef void func_on_ufdt_node(struct ufdt_node *, void *);
-
-struct ufdt_node_closure {
- func_on_ufdt_node *func;
- void *env;
-};
-
-static uint32_t tag_of(const struct ufdt_node *node) {
- if (!node) return FDT_END;
- return fdt32_to_cpu(*node->fdt_tag_ptr);
-}
-
#endif /* UFDT_TYPES_H */
diff --git a/tests/src/fdt_overlay_test_app.c b/tests/src/fdt_overlay_test_app.c
index 6420cea..3b65a7d 100644
--- a/tests/src/fdt_overlay_test_app.c
+++ b/tests/src/fdt_overlay_test_app.c
@@ -22,9 +22,7 @@
#include "util.h"
-
-int apply_ovleray_files(const char *out_filename,
- const char *base_filename,
+int apply_overlay_files(const char *out_filename, const char *base_filename,
const char *overlay_filename) {
int ret = 1;
char *base_buf = NULL;
@@ -80,7 +78,7 @@ int main(int argc, char **argv) {
const char *base_file = argv[1];
const char *overlay_file = argv[2];
const char *out_file = argv[3];
- int ret = apply_ovleray_files(out_file, base_file, overlay_file);
+ int ret = apply_overlay_files(out_file, base_file, overlay_file);
return ret;
}
diff --git a/tests/src/ufdt_overlay_test_app.c b/tests/src/ufdt_overlay_test_app.c
index 013ba1b..d7c4437 100644
--- a/tests/src/ufdt_overlay_test_app.c
+++ b/tests/src/ufdt_overlay_test_app.c
@@ -23,9 +23,7 @@
#include "util.h"
-
-int apply_ovleray_files(const char *out_filename,
- const char *base_filename,
+int apply_overlay_files(const char *out_filename, const char *base_filename,
const char *overlay_filename) {
int ret = 1;
char *base_buf = NULL;
@@ -85,7 +83,7 @@ int main(int argc, char **argv) {
const char *base_file = argv[1];
const char *overlay_file = argv[2];
const char *out_file = argv[3];
- int ret = apply_ovleray_files(out_file, base_file, overlay_file);
+ int ret = apply_overlay_files(out_file, base_file, overlay_file);
return ret;
}
diff --git a/ufdt_convert.c b/ufdt_convert.c
index c1e44a6..2d0750b 100644
--- a/ufdt_convert.c
+++ b/ufdt_convert.c
@@ -232,59 +232,9 @@ struct ufdt_node *ufdt_get_node_by_phandle(struct ufdt *tree,
return res;
}
-int merge_children(struct ufdt_node *node_a, struct ufdt_node *node_b) {
- int err = 0;
- struct ufdt_node *it;
- for (it = ((struct fdt_node_ufdt_node *)node_b)->child; it;) {
- struct ufdt_node *cur_node = it;
- it = it->sibling;
- cur_node->sibling = NULL;
- struct ufdt_node *target_node = NULL;
- if (tag_of(cur_node) == FDT_BEGIN_NODE) {
- target_node = ufdt_node_get_subnode_by_name(node_a, name_of(cur_node));
- } else {
- target_node = ufdt_node_get_property_by_name(node_a, name_of(cur_node));
- }
- if (target_node == NULL) {
- err = ufdt_node_add_child(node_a, cur_node);
- } else {
- err = merge_ufdt_into(target_node, cur_node);
- dto_free(cur_node);
- }
- if (err < 0) return -1;
- }
- /*
- * The ufdt_node* in node_b will be copied to node_a.
- * To prevent the ufdt_node from being freed twice
- * (main_tree and overlay_tree) at the end of function
- * ufdt_apply_overlay(), set this node in node_b
- * (overlay_tree) to NULL.
- */
- ((struct fdt_node_ufdt_node *)node_b)->child = NULL;
-
- return 0;
-}
-
-int merge_ufdt_into(struct ufdt_node *node_a, struct ufdt_node *node_b) {
- if (tag_of(node_a) == FDT_PROP) {
- node_a->fdt_tag_ptr = node_b->fdt_tag_ptr;
- return 0;
- }
-
- int err = 0;
- err = merge_children(node_a, node_b);
- if (err < 0) return -1;
-
- return 0;
-}
-
-void ufdt_map(struct ufdt *tree, struct ufdt_node_closure closure) {
- ufdt_node_map(tree->root, closure);
-}
-
static int count_phandle_node(struct ufdt_node *node) {
if (node == NULL) return 0;
- if (tag_of(node) != FDT_BEGIN_NODE) return 0;
+ if (ufdt_node_tag(node) != FDT_BEGIN_NODE) return 0;
int res = 0;
if (ufdt_node_get_phandle(node) > 0) res++;
struct ufdt_node **it;
@@ -293,9 +243,9 @@ static int count_phandle_node(struct ufdt_node *node) {
}
static void set_phandle_table_entry(struct ufdt_node *node,
- struct phandle_table_entry *data,
+ struct ufdt_phandle_table_entry *data,
int *cur) {
- if (node == NULL || tag_of(node) != FDT_BEGIN_NODE) return;
+ if (node == NULL || ufdt_node_tag(node) != FDT_BEGIN_NODE) return;
int ph = ufdt_node_get_phandle(node);
if (ph > 0) {
data[*cur].phandle = ph;
@@ -308,8 +258,8 @@ static void set_phandle_table_entry(struct ufdt_node *node,
}
int phandle_table_entry_cmp(const void *pa, const void *pb) {
- uint32_t ph_a = ((const struct phandle_table_entry *)pa)->phandle;
- uint32_t ph_b = ((const struct phandle_table_entry *)pb)->phandle;
+ uint32_t ph_a = ((const struct ufdt_phandle_table_entry *)pa)->phandle;
+ uint32_t ph_b = ((const struct ufdt_phandle_table_entry *)pb)->phandle;
if (ph_a < ph_b)
return -1;
else if (ph_a == ph_b)
@@ -318,18 +268,18 @@ int phandle_table_entry_cmp(const void *pa, const void *pb) {
return 1;
}
-struct static_phandle_table build_phandle_table(struct ufdt *tree) {
- struct static_phandle_table res;
+struct ufdt_static_phandle_table build_phandle_table(struct ufdt *tree) {
+ struct ufdt_static_phandle_table res;
res.len = count_phandle_node(tree->root);
- res.data = dto_malloc(sizeof(struct phandle_table_entry) * res.len);
+ res.data = dto_malloc(sizeof(struct ufdt_phandle_table_entry) * res.len);
int cur = 0;
set_phandle_table_entry(tree->root, res.data, &cur);
- dto_qsort(res.data, res.len, sizeof(struct phandle_table_entry),
+ dto_qsort(res.data, res.len, sizeof(struct ufdt_phandle_table_entry),
phandle_table_entry_cmp);
return res;
}
-struct ufdt *fdt_to_ufdt(void *fdtp, size_t fdt_size) {
+struct ufdt *ufdt_from_fdt(void *fdtp, size_t fdt_size) {
(void)(fdt_size); /* unused parameter */
int start_offset = fdt_path_offset(fdtp, "/");
@@ -367,7 +317,7 @@ static int _ufdt_get_property_nameoff(const struct ufdt *tree, const char *name,
static int _ufdt_output_property_to_fdt(
const struct ufdt *tree, void *fdtp,
- const struct fdt_prop_ufdt_node *prop_node, struct ufdt_prop_dict *dict) {
+ const struct ufdt_node_fdt_prop *prop_node, struct ufdt_prop_dict *dict) {
int nameoff = _ufdt_get_property_nameoff(tree, prop_node->name, dict);
if (nameoff == 0) return -1;
@@ -400,14 +350,14 @@ static int _ufdt_output_property_to_fdt(
static int _ufdt_output_node_to_fdt(const struct ufdt *tree, void *fdtp,
const struct ufdt_node *node,
struct ufdt_prop_dict *dict) {
- uint32_t tag = tag_of(node);
+ uint32_t tag = ufdt_node_tag(node);
if (tag == FDT_PROP) {
return _ufdt_output_property_to_fdt(
- tree, fdtp, (const struct fdt_prop_ufdt_node *)node, dict);
+ tree, fdtp, (const struct ufdt_node_fdt_prop *)node, dict);
}
- int err = fdt_begin_node(fdtp, name_of(node));
+ int err = fdt_begin_node(fdtp, ufdt_node_name(node));
if (err < 0) return -1;
struct ufdt_node **it;
diff --git a/ufdt_node.c b/ufdt_node.c
index 46c8d34..10a3bd9 100644
--- a/ufdt_node.c
+++ b/ufdt_node.c
@@ -16,17 +16,11 @@
#include "libufdt.h"
-int node_cmp(const void *a, const void *b) {
- const struct ufdt_node *na = *(struct ufdt_node **)a;
- const struct ufdt_node *nb = *(struct ufdt_node **)b;
- return dto_strcmp(name_of(na), name_of(nb));
-}
-
-bool node_name_eq(const struct ufdt_node *node, const char *name, int len) {
+bool ufdt_node_name_eq(const struct ufdt_node *node, const char *name, int len) {
if (!node) return false;
if (!name) return false;
- if (dto_strncmp(name_of(node), name, len) != 0) return false;
- if (name_of(node)[len] != '\0') return false;
+ if (dto_strncmp(ufdt_node_name(node), name, len) != 0) return false;
+ if (ufdt_node_name(node)[len] != '\0') return false;
return true;
}
@@ -38,14 +32,16 @@ struct ufdt_node *ufdt_node_construct(void *fdtp, fdt32_t *fdt_tag_ptr) {
uint32_t tag = fdt32_to_cpu(*fdt_tag_ptr);
if (tag == FDT_PROP) {
const struct fdt_property *prop = (const struct fdt_property *)fdt_tag_ptr;
- struct fdt_prop_ufdt_node *res = dto_malloc(sizeof(struct fdt_prop_ufdt_node));
+ struct ufdt_node_fdt_prop *res =
+ dto_malloc(sizeof(struct ufdt_node_fdt_prop));
if (res == NULL) return NULL;
res->parent.fdt_tag_ptr = fdt_tag_ptr;
res->parent.sibling = NULL;
res->name = fdt_string(fdtp, fdt32_to_cpu(prop->nameoff));
return (struct ufdt_node *)res;
} else {
- struct fdt_node_ufdt_node *res = dto_malloc(sizeof(struct fdt_node_ufdt_node));
+ struct ufdt_node_fdt_node *res =
+ dto_malloc(sizeof(struct ufdt_node_fdt_node));
if (res == NULL) return NULL;
res->parent.fdt_tag_ptr = fdt_tag_ptr;
res->parent.sibling = NULL;
@@ -58,29 +54,26 @@ struct ufdt_node *ufdt_node_construct(void *fdtp, fdt32_t *fdt_tag_ptr) {
void ufdt_node_destruct(struct ufdt_node *node) {
if (node == NULL) return;
- if (tag_of(node) == FDT_BEGIN_NODE) {
- ufdt_node_destruct(((struct fdt_node_ufdt_node *)node)->child);
+ if (ufdt_node_tag(node) == FDT_BEGIN_NODE) {
+ ufdt_node_destruct(((struct ufdt_node_fdt_node *)node)->child);
}
ufdt_node_destruct(node->sibling);
dto_free(node);
-
- return;
}
int ufdt_node_add_child(struct ufdt_node *parent, struct ufdt_node *child) {
if (!parent || !child) return -1;
- if (tag_of(parent) != FDT_BEGIN_NODE) return -1;
+ if (ufdt_node_tag(parent) != FDT_BEGIN_NODE) return -1;
int err = 0;
- uint32_t child_tag = tag_of(child);
-
+ uint32_t child_tag = ufdt_node_tag(child);
switch (child_tag) {
case FDT_PROP:
case FDT_BEGIN_NODE:
// Append the child node to the last child of parant node
- *((struct fdt_node_ufdt_node *)parent)->last_child_p = child;
- ((struct fdt_node_ufdt_node *)parent)->last_child_p = &child->sibling;
+ *((struct ufdt_node_fdt_node *)parent)->last_child_p = child;
+ ((struct ufdt_node_fdt_node *)parent)->last_child_p = &child->sibling;
break;
default:
@@ -99,7 +92,7 @@ struct ufdt_node *ufdt_node_get_subnode_by_name_len(const struct ufdt_node *node
const char *name, int len) {
struct ufdt_node **it = NULL;
for_each_node(it, node) {
- if (node_name_eq(*it, name, len)) return *it;
+ if (ufdt_node_name_eq(*it, name, len)) return *it;
}
return NULL;
}
@@ -115,7 +108,7 @@ struct ufdt_node *ufdt_node_get_property_by_name_len(
struct ufdt_node **it = NULL;
for_each_prop(it, node) {
- if (node_name_eq(*it, name, len)) return *it;
+ if (ufdt_node_name_eq(*it, name, len)) return *it;
}
return NULL;
}
@@ -126,7 +119,7 @@ struct ufdt_node *ufdt_node_get_property_by_name(const struct ufdt_node *node,
}
char *ufdt_node_get_fdt_prop_data(const struct ufdt_node *node, int *out_len) {
- if (!node || tag_of(node) != FDT_PROP) {
+ if (!node || ufdt_node_tag(node) != FDT_PROP) {
return NULL;
}
const struct fdt_property *prop = (struct fdt_property *)node->fdt_tag_ptr;
@@ -158,7 +151,7 @@ char *ufdt_node_get_fdt_prop_data_by_name(const struct ufdt_node *node,
*/
uint32_t ufdt_node_get_phandle(const struct ufdt_node *node) {
- if (!node || tag_of(node) != FDT_BEGIN_NODE) {
+ if (!node || ufdt_node_tag(node) != FDT_BEGIN_NODE) {
return 0;
}
int len = 0;
@@ -216,7 +209,7 @@ void ufdt_node_print(const struct ufdt_node *node, int depth) {
for (i = 0; i < depth * TAB_SIZE; i++) dto_print(" ");
uint32_t tag;
- tag = tag_of(node);
+ tag = ufdt_node_tag(node);
switch (tag) {
case FDT_BEGIN_NODE:
@@ -230,30 +223,17 @@ void ufdt_node_print(const struct ufdt_node *node, int depth) {
break;
}
- if (name_of(node)) {
- dto_print(":%s:\n", name_of(node));
+ if (ufdt_node_name(node)) {
+ dto_print(":%s:\n", ufdt_node_name(node));
} else {
dto_print("node name is NULL.\n");
}
- if (tag_of(node) == FDT_BEGIN_NODE) {
+ if (ufdt_node_tag(node) == FDT_BEGIN_NODE) {
struct ufdt_node **it;
for_each_prop(it, node) ufdt_node_print(*it, depth + 1);
for_each_node(it, node) ufdt_node_print(*it, depth + 1);
}
-
- return;
-}
-
-void ufdt_node_map(struct ufdt_node *node, struct ufdt_node_closure closure) {
- if (node == NULL) return;
- closure.func(node, closure.env);
- if (tag_of(node) == FDT_BEGIN_NODE) {
- struct ufdt_node **it;
- for_each_prop(it, node) ufdt_node_map(*it, closure);
- for_each_node(it, node) ufdt_node_map(*it, closure);
- }
- return;
}
diff --git a/ufdt_overlay.c b/ufdt_overlay.c
index d6e250e..08c8ac8 100644
--- a/ufdt_overlay.c
+++ b/ufdt_overlay.c
@@ -68,7 +68,7 @@ static void fdt_increase_u32(void *pos, uint32_t offset) {
* Gets the max phandle of a given ufdt.
*/
static uint32_t ufdt_get_max_phandle(struct ufdt *tree) {
- struct static_phandle_table sorted_table = tree->phandle_table;
+ struct ufdt_static_phandle_table sorted_table = tree->phandle_table;
if (sorted_table.len > 0)
return sorted_table.data[sorted_table.len - 1].phandle;
else
@@ -97,7 +97,7 @@ static void ufdt_node_try_increase_phandle(struct ufdt_node *node,
* in O(n) time.
*/
static void ufdt_try_increase_phandle(struct ufdt *tree, uint32_t offset) {
- struct static_phandle_table sorted_table = tree->phandle_table;
+ struct ufdt_static_phandle_table sorted_table = tree->phandle_table;
int i;
for (i = 0; i < sorted_table.len; i++) {
@@ -259,10 +259,11 @@ static int ufdt_overlay_do_fixups(struct ufdt *main_tree,
struct ufdt_node *fixups = *it;
char *symbol_path = ufdt_node_get_fdt_prop_data_by_name(
- main_symbols_node, name_of(fixups), &len);
+ main_symbols_node, ufdt_node_name(fixups), &len);
if (!symbol_path) {
- dto_error("Couldn't find '%s' symbol in main dtb\n", name_of(fixups));
+ dto_error("Couldn't find '%s' symbol in main dtb\n",
+ ufdt_node_name(fixups));
return -1;
}
@@ -294,7 +295,7 @@ static int ufdt_overlay_do_fixups(struct ufdt *main_tree,
* What is "overlay fragment"? The main purpose is to add some subtrees to the
* main_tree in order to complete the entire device tree.
*
- * A frgament consists of two parts: 1. the subtree to be added 2. where it
+ * A fragment consists of two parts: 1. the subtree to be added 2. where it
* should be added.
*
* Overlaying a fragment requires: 1. find the node in the main_tree 2. merge
@@ -303,6 +304,106 @@ static int ufdt_overlay_do_fixups(struct ufdt *main_tree,
/* BEGIN of applying fragments. */
+/* Proptyping predefined */
+static int merge_ufdt_into(struct ufdt_node *node_a, struct ufdt_node *node_b);
+
+/*
+ * Merges tree_b into tree_a with tree_b has all nodes except root disappeared.
+ * Overwrite property in tree_a if there's one with same name in tree_b.
+ * Otherwise add the property to tree_a.
+ * For subnodes with the same name, recursively run this function.
+ *
+ * Ex:
+ * tree_a : ta {
+ * b = "b";
+ * c = "c";
+ * d {
+ * e = "g";
+ * };
+ * };
+ *
+ * tree_b : tb {
+ * c = "C";
+ * g = "G";
+ * d {
+ * da = "dad";
+ * };
+ * h {
+ * hh = "HH";
+ * };
+ * };
+ *
+ * The resulting trees will be:
+ *
+ * tree_a : ta {
+ * b = "b";
+ * c = "C";
+ * g = "G";
+ * d {
+ * da = "dad";
+ * e = "g";
+ * };
+ * h {
+ * hh = "HH";
+ * };
+ * };
+ *
+ * tree_b : tb {
+ * };
+ *
+ *
+ * @return: 0 if merge success
+ * < 0 otherwise
+ *
+ * @Time: O(# of nodes in tree_b + total length of all names in tree_b) w.h.p.
+ */
+static int merge_children(struct ufdt_node *node_a, struct ufdt_node *node_b) {
+ int err = 0;
+ struct ufdt_node *it;
+ for (it = ((struct ufdt_node_fdt_node *)node_b)->child; it;) {
+ struct ufdt_node *cur_node = it;
+ it = it->sibling;
+ cur_node->sibling = NULL;
+ struct ufdt_node *target_node = NULL;
+ if (ufdt_node_tag(cur_node) == FDT_BEGIN_NODE) {
+ target_node =
+ ufdt_node_get_subnode_by_name(node_a, ufdt_node_name(cur_node));
+ } else {
+ target_node =
+ ufdt_node_get_property_by_name(node_a, ufdt_node_name(cur_node));
+ }
+ if (target_node == NULL) {
+ err = ufdt_node_add_child(node_a, cur_node);
+ } else {
+ err = merge_ufdt_into(target_node, cur_node);
+ }
+ if (err < 0) return -1;
+ }
+ /*
+ * The ufdt_node* in node_b will be copied to node_a.
+ * To prevent the ufdt_node from being freed twice
+ * (main_tree and overlay_tree) at the end of function
+ * ufdt_apply_overlay(), set this node in node_b
+ * (overlay_tree) to NULL.
+ */
+ ((struct ufdt_node_fdt_node *)node_b)->child = NULL;
+
+ return 0;
+}
+
+static int merge_ufdt_into(struct ufdt_node *node_a, struct ufdt_node *node_b) {
+ if (ufdt_node_tag(node_a) == FDT_PROP) {
+ node_a->fdt_tag_ptr = node_b->fdt_tag_ptr;
+ return 0;
+ }
+
+ int err = 0;
+ err = merge_children(node_a, node_b);
+ if (err < 0) return -1;
+
+ return 0;
+}
+
/*
* Overlay the overlay_node over target_node.
*/
@@ -369,8 +470,8 @@ static enum overlay_result ufdt_apply_fragment(struct ufdt *tree,
int err = ufdt_overlay_node(target_node, overlay_node);
if (err < 0) {
- dto_error("failed to overlay node %s to target %s\n", name_of(overlay_node),
- name_of(target_node));
+ dto_error("failed to overlay node %s to target %s\n",
+ ufdt_node_name(overlay_node), ufdt_node_name(target_node));
return OVERLAY_RESULT_MERGE_FAIL;
}
@@ -461,8 +562,8 @@ static int ufdt_local_fixup_node(struct ufdt_node *target_node,
struct ufdt_node *sub_target_node;
for_each_prop(it_local_fixups, local_fixups_node) {
- sub_target_node =
- ufdt_node_get_property_by_name(target_node, name_of(*it_local_fixups));
+ sub_target_node = ufdt_node_get_property_by_name(
+ target_node, ufdt_node_name(*it_local_fixups));
if (sub_target_node != NULL) {
int err = ufdt_local_fixup_prop(sub_target_node, *it_local_fixups,
@@ -474,8 +575,8 @@ static int ufdt_local_fixup_node(struct ufdt_node *target_node,
}
for_each_node(it_local_fixups, local_fixups_node) {
- sub_target_node =
- ufdt_node_get_node_by_path(target_node, name_of(*it_local_fixups));
+ sub_target_node = ufdt_node_get_node_by_path(
+ target_node, ufdt_node_name(*it_local_fixups));
if (sub_target_node != NULL) {
int err = ufdt_local_fixup_node(sub_target_node, *it_local_fixups,
phandle_offset);
@@ -641,12 +742,8 @@ struct fdt_header *ufdt_apply_overlay(struct fdt_header *main_fdt_header,
return NULL;
}
- struct ufdt *main_tree = NULL;
- struct ufdt *overlay_tree = NULL;
-
- main_tree = fdt_to_ufdt(main_fdt_header, main_fdt_size);
- overlay_tree = fdt_to_ufdt(overlay_fdtp, overlay_size);
-
+ struct ufdt *main_tree = ufdt_from_fdt(main_fdt_header, main_fdt_size);
+ struct ufdt *overlay_tree = ufdt_from_fdt(overlay_fdtp, overlay_size);
int err = ufdt_overlay_apply(main_tree, overlay_tree, overlay_size);
if (err < 0) {
goto fail;