Home | History | Annotate | Download | only in include
      1 /*
      2  * Copyright (C) 2016 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #ifndef LIBUFDT_H
     18 #define LIBUFDT_H
     19 
     20 #include "libufdt_sysdeps.h"
     21 #include "ufdt_types.h"
     22 
     23 /*
     24  * BEGIN of ufdt_node methods
     25  */
     26 
     27 /*
     28  * Allocates spaces for new ufdt_node who represents a fdt node at fdt_tag_ptr.
     29  * In order to get name pointer, it's necessary to give the pointer to the
     30  * entire fdt it belongs to.
     31  *
     32  *
     33  * @return: a pointer to the newly created ufdt_node or
     34  *          NULL if dto_malloc failed
     35  */
     36 struct ufdt_node *ufdt_node_construct(void *fdtp, fdt32_t *fdt_tag_ptr,
     37                                       struct ufdt_node_pool *pool);
     38 
     39 /*
     40  * Frees all nodes in the subtree rooted at *node.
     41  */
     42 void ufdt_node_destruct(struct ufdt_node *node, struct ufdt_node_pool *pool);
     43 
     44 /*
     45  * Adds the child as a subnode of the parent.
     46  * It's been done by add entries in parent->prop_list or node_list depending on
     47  * the tag type of child.
     48  *
     49  * @return: 0 if success
     50  *          < 0 otherwise
     51  *
     52  * @Time: O(1) w.h.p.
     53  */
     54 int ufdt_node_add_child(struct ufdt_node *parent, struct ufdt_node *child);
     55 
     56 /* BEGIN of FDT_PROP related functions .*/
     57 
     58 /*
     59  * Gets pointer to FDT_PROP subnode of node with name equals to name[0..len-1]
     60  *
     61  * @return: a pointer to the subnode or
     62  *          NULL if no such subnode.
     63  *
     64  * @Time: O(len = length of name) w.h.p.
     65  */
     66 struct ufdt_node *ufdt_node_get_property_by_name_len(
     67     const struct ufdt_node *node, const char *name, int len);
     68 struct ufdt_node *ufdt_node_get_property_by_name(const struct ufdt_node *node,
     69                                                  const char *name);
     70 
     71 /*
     72  * Gets the pointer to the FDT_PROP node's data in the corresponding fdt.
     73  * Also writes the length of such data to *out_len if out_len is not NULL.
     74  *
     75  * @return: a pointer to some data located in fdt or
     76  *          NULL if *node is not a FDT_PROP
     77  */
     78 char *ufdt_node_get_fdt_prop_data(const struct ufdt_node *node, int *out_len);
     79 
     80 /*
     81  * Gets pointer to FDT_PROP node's data in fdt with name equals to
     82  * name[0..len-1], which is a subnode of *node.
     83  * It's actually a composition of ufdt_node_get_property_by_name and
     84  * ufdt_node_get_fdt_prop_data
     85  *
     86  * @return: a pointer to some data located in fdt or
     87  *          NULL if no such subnode.
     88  *
     89  * @Time: O(len = length of name) w.h.p.
     90  */
     91 char *ufdt_node_get_fdt_prop_data_by_name_len(const struct ufdt_node *node,
     92                                               const char *name, int len,
     93                                               int *out_len);
     94 char *ufdt_node_get_fdt_prop_data_by_name(const struct ufdt_node *node,
     95                                           const char *name, int *out_len);
     96 
     97 /* END of FDT_PROP related functions .*/
     98 
     99 /*
    100  * Gets pointer to FDT_BEGIN_NODE subnode of node with name equals to
    101  * name[0..len-1].
    102  *
    103  * @return: a pointer to the subnode or
    104  *          NULL if no such subnode.
    105  *
    106  * @Time: O(len = length of name) w.h.p.
    107  */
    108 
    109 struct ufdt_node *ufdt_node_get_subnode_by_name_len(const struct ufdt_node *node,
    110                                                     const char *name, int len);
    111 struct ufdt_node *ufdt_node_get_subnode_by_name(const struct ufdt_node *node,
    112                                                 const char *name);
    113 
    114 /*
    115  * Gets the pointer to FDT_NODE node whose relative path to *node is
    116  * path[0..len-1].
    117  * Note that the relative path doesn't support parent node like:
    118  * "../path/to/node".
    119  *
    120  * @return: a pointer to the node or
    121  *          NULL if no such node.
    122  *
    123  * @Time: O(len = length of path) w.h.p.
    124  */
    125 struct ufdt_node *ufdt_node_get_node_by_path_len(const struct ufdt_node *node,
    126                                                  const char *path, int len);
    127 struct ufdt_node *ufdt_node_get_node_by_path(const struct ufdt_node *node,
    128                                              const char *path);
    129 
    130 /*
    131  * Gets the phandle value of the node if it has.
    132  *
    133  * @return: phandle value of that node or
    134  *          0 if *node is not FDT_NODE or there's no "phandle"/"linux,phandle"
    135  *          property.
    136  *
    137  * @Time: O(1) w.h.p.
    138  */
    139 uint32_t ufdt_node_get_phandle(const struct ufdt_node *node);
    140 
    141 /*
    142  * END of ufdt_node methods
    143  */
    144 
    145 /*
    146  * BEGIN of ufdt methods.
    147  */
    148 
    149 /*
    150  * Constructs a ufdt whose base fdt is fdtp.
    151  * Note that this function doesn't construct the entire tree.
    152  * To get the whole tree please call `ufdt_from_fdt(fdtp, fdt_size)`
    153  *
    154  * @return: an empty ufdt with base fdtp = fdtp
    155  */
    156 struct ufdt *ufdt_construct(void *fdtp, struct ufdt_node_pool *pool);
    157 
    158 /*
    159  * Frees the space occupied by the ufdt, including all ufdt_nodes
    160  * with ufdt_static_phandle_table.
    161  */
    162 void ufdt_destruct(struct ufdt *tree, struct ufdt_node_pool *pool);
    163 
    164 /*
    165  * Add a fdt into this ufdt.
    166  * Note that this function just add the given fdtp into this ufdt,
    167  * and doesn't create any node.
    168  *
    169  * @return: 0 if success.
    170  */
    171 int ufdt_add_fdt(struct ufdt *tree, void *fdtp);
    172 
    173 /*
    174  * Calculate the offset in the string tables of the given string.
    175  * All string tables will be concatenated in reversed order.
    176  *
    177  * @return: The offset is a negative number, base on the end position of
    178  *          all concatenated string tables
    179  *          Return 0 if not in any string table.
    180  */
    181 int ufdt_get_string_off(const struct ufdt *tree, const char *s);
    182 
    183 /*
    184  * Gets the pointer to the ufdt_node in tree with phandle = phandle.
    185  * The function do a binary search in tree->phandle_table.
    186  *
    187  * @return: a pointer to the target ufdt_node
    188  *          NULL if no ufdt_node has phandle = phandle
    189  *
    190  * @Time: O(log(# of nodes in tree)) = O(log(size of underlying fdt))
    191  */
    192 struct ufdt_node *ufdt_get_node_by_phandle(struct ufdt *tree, uint32_t phandle);
    193 
    194 /*
    195  * Gets the pointer to the ufdt_node in tree with absolute path =
    196  * path[0..len-1].
    197  * Absolute path has form "/path/to/node" or "some_alias/to/node".
    198  * In later example, some_alias is a property in "/aliases" with data is a path
    199  * to some node X. Then the funcion will return node with relative
    200  * path = "to/node" w.r.t. X.
    201  *
    202  * @return: a pointer to the target ufdt_node or
    203  *          NULL if such dnt doesn't exist.
    204  *
    205  * @Time: O(len = length of path) w.h.p.
    206  */
    207 struct ufdt_node *ufdt_get_node_by_path_len(struct ufdt *tree, const char *path,
    208                                             int len);
    209 struct ufdt_node *ufdt_get_node_by_path(struct ufdt *tree, const char *path);
    210 
    211 /*
    212  * Determines whether node->name equals to name[0..len-1]
    213  *
    214  * @return: true if they're equal.
    215  *          false otherwise
    216  */
    217 bool ufdt_node_name_eq(const struct ufdt_node *node, const char *name, int len);
    218 
    219 /*
    220  * Merges tree_b into tree_a with tree_b has all nodes except root disappeared.
    221  * Overwrite property in tree_a if there's one with same name in tree_b.
    222  * Otherwise add the property to tree_a.
    223  * For subnodes with the same name, recursively run this function.
    224  *
    225  * Ex:
    226  * tree_a : ta {
    227  *  b = "b";
    228  *  c = "c";
    229  *  d {
    230  *    e = "g";
    231  *  };
    232  * };
    233  *
    234  * tree_b : tb {
    235  *  c = "C";
    236  *  g = "G";
    237  *  d {
    238  *    da = "dad";
    239  *  };
    240  *  h {
    241  *    hh = "HH";
    242  *  };
    243  * };
    244  *
    245  * The resulting trees will be:
    246  *
    247  * tree_a : ta {
    248  *  b = "b";
    249  *  c = "C";
    250  *  g = "G";
    251  *  d {
    252  *    da = "dad";
    253  *    e = "g";
    254  *  };
    255  *  h {
    256  *    hh = "HH";
    257  *  };
    258  * };
    259  *
    260  * tree_b : tb {
    261  * };
    262  *
    263  *
    264  * @return: 0 if merge success
    265  *          < 0 otherwise
    266  *
    267  * @Time: O(# of nodes in tree_b + total length of all names in tree_b) w.h.p.
    268  */
    269 int ufdt_node_merge_into(struct ufdt_node *node_a, struct ufdt_node *node_b,
    270                          struct ufdt_node_pool *pool);
    271 
    272 /*
    273  * END of ufdt methods.
    274  */
    275 
    276 /*
    277  * BEGIN of ufdt output functions
    278  */
    279 
    280 /*
    281  * Builds the ufdt for FDT pointed by fdtp.
    282  *
    283  * @return: the ufdt T representing fdtp or
    284  *          T with T.fdtp == NULL if fdtp is unvalid.
    285  *
    286  * @Time: O(fdt_size + nlogn) where n = # of nodes in fdt.
    287  */
    288 struct ufdt *ufdt_from_fdt(void *fdtp, size_t fdt_size,
    289                            struct ufdt_node_pool *pool);
    290 
    291 /*
    292  * Sequentially dumps the whole ufdt to FDT buffer fdtp with buffer size
    293  * buf_size.
    294  *
    295  * Basically using functions provided by libfdt/fdt_sw.c.
    296  *
    297  * @return: 0 if successfully dump or
    298  *          < 0 otherwise
    299  *
    300  * @Time: O(total length of all names + # of nodes in tree)
    301  */
    302 int ufdt_to_fdt(const struct ufdt *tree, void *buf, int buf_size);
    303 
    304 /*
    305  * prints the entire subtree rooted at *node in form:
    306  * NODE :[node name]:
    307  *   PROP :[prop name]:
    308  *   ...
    309  *   NODE :[subnode1 name]:
    310  *     ...
    311  *   NODE :[subnode1 name]:
    312  *     ...
    313  *   ...
    314  * There're (depth * TAB_SIZE) spaces in front of each line.
    315  */
    316 void ufdt_node_print(const struct ufdt_node *node, int depth);
    317 
    318 /*
    319  * It's just ufdt_node_print(tree->root, 0).
    320  */
    321 void ufdt_print(struct ufdt *tree);
    322 
    323 /*
    324  * END of ufdt output functions
    325  */
    326 
    327 #endif /* LIBUFDT_H */
    328