diff options
| author | SzuWei Lin <szuweilin@google.com> | 2017-04-17 01:45:09 +0000 |
|---|---|---|
| committer | android-build-merger <android-build-merger@google.com> | 2017-04-17 01:45:09 +0000 |
| commit | 56e42407b843300bb4c9ff759f446078ca45e2cd (patch) | |
| tree | 0c730d0a3e83db73cb55bd2536be90029955062e | |
| parent | 4012a97e0bd99eaebfc99eb30aa4b06ac892a0bf (diff) | |
| parent | 44ea8e620811ebd2ac41c61bca9e4daab3601eb0 (diff) | |
| download | platform_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.h | 104 | ||||
| -rw-r--r-- | include/ufdt_types.h | 43 | ||||
| -rw-r--r-- | tests/src/fdt_overlay_test_app.c | 6 | ||||
| -rw-r--r-- | tests/src/ufdt_overlay_test_app.c | 6 | ||||
| -rw-r--r-- | ufdt_convert.c | 78 | ||||
| -rw-r--r-- | ufdt_node.c | 62 | ||||
| -rw-r--r-- | ufdt_overlay.c | 131 |
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; |
