소스 검색

Merge pull request #4 from linzhenxing-bit/main

添加dtb相关接口
Bernard Xiong 3 년 전
부모
커밋
f3a3fe7c69
16개의 변경된 파일2120개의 추가작업 그리고 404개의 파일을 삭제
  1. 2 2
      examples/fdt_dump.c
  2. 17 17
      examples/fdt_test.c
  3. 17 0
      inc/dtb_head.h
  4. 379 0
      inc/dtb_node.h
  5. 0 124
      inc/fdt.h
  6. 1 1
      src/SConscript
  7. 658 0
      src/dtb_access.c
  8. 64 0
      src/dtb_addr.c
  9. 546 0
      src/dtb_base.c
  10. 202 218
      src/dtb_get.c
  11. 42 0
      src/dtb_head.c
  12. 33 21
      src/dtb_load.c
  13. 33 21
      src/dtb_set.c
  14. 101 0
      src/libfdt/fdt_addresses.c
  15. 24 0
      src/libfdt/libfdt.h
  16. 1 0
      src/libfdt/libfdt_env.h

+ 2 - 2
examples/fdt_dump.c

@@ -1,5 +1,5 @@
 #include <rtthread.h>
-#include <fdt.h>
+#include <dtb_node.h>
 
 int fdt_dump(int argc, char** argv)
 {
@@ -10,7 +10,7 @@ int fdt_dump(int argc, char** argv)
         struct dtb_node *dtb_node_list = fdt_get_dtb_list(fdt);
         if (dtb_node_list != RT_NULL)
         {
-            fdt_get_dts_dump(dtb_node_list);
+            dtb_node_get_dts_dump(dtb_node_list);
         }
         /* dtb_node_list will free on here */
         fdt_free_dtb_list(dtb_node_list);

+ 17 - 17
examples/fdt_test.c

@@ -1,18 +1,18 @@
 #include <rtthread.h>
-#include <fdt.h>
+#include <fdt_node.h>
 
 int fdt_test()
 {
     void *fdt;
 
-    if ((fdt = fdt_load_from_fs("vexpress-v2p-ca9.dtb")) != RT_NULL)
+    if ((fdt = dtb_node_load_from_fs("vexpress-v2p-ca9.dtb")) != RT_NULL)
     {
-        struct dtb_node *dtb_node_list =  fdt_get_dtb_list(fdt);
+        struct dtb_node *dtb_node_list =  dtb_node_get_dtb_list(fdt);
         if (dtb_node_list != RT_NULL)
         {
-            struct dtb_node *serial0 = fdt_get_dtb_node_by_path(dtb_node_list, "/smb@4000000/motherboard/iofpga@7,00000000/uart@9000");
-            struct dtb_node *cpu = fdt_get_dtb_node_by_path(dtb_node_list, "/cpus");
-            struct dtb_node *user1 = fdt_get_dtb_node_by_path(dtb_node_list, "/smb@4000000/motherboard/leds/user1");
+            struct dtb_node *serial0 = dtb_node_get_dtb_node_by_path(dtb_node_list, "/smb@4000000/motherboard/iofpga@7,00000000/uart@9000");
+            struct dtb_node *cpu = dtb_node_get_dtb_node_by_path(dtb_node_list, "/cpus");
+            struct dtb_node *user1 = dtb_node_get_dtb_node_by_path(dtb_node_list, "/smb@4000000/motherboard/leds/user1");
 
             if (serial0 != RT_NULL)
             {
@@ -54,32 +54,32 @@ int fdt_test()
             {
                 struct dtb_node *user = user1;
 
-                rt_kprintf("\nname = %s, lable = %s\n", user1->name, fdt_get_dtb_node_property(user1, "label", RT_NULL));
+                rt_kprintf("\nname = %s, lable = %s\n", user1->name, dtb_node_get_dtb_node_property(user1, "label", RT_NULL));
 
                 for_each_node_sibling(user)
                 {
-                    rt_kprintf("name = %s, lable = %s\n", user->name, fdt_get_dtb_node_property(user, "label", RT_NULL));
+                    rt_kprintf("name = %s, lable = %s\n", user->name, dtb_node_get_dtb_node_property(user, "label", RT_NULL));
                 }
             }
         }
-        fdt_free_dtb_list(dtb_node_list);
+        dtb_node_free_dtb_list(dtb_node_list);
     }
 
-    if ((fdt = fdt_load_from_fs("bcm2711-rpi-4-b.dtb")) != RT_NULL)
+    if ((fdt = dtb_node_load_from_fs("bcm2711-rpi-4-b.dtb")) != RT_NULL)
     {
-        struct dtb_node *dtb_node_list =  fdt_get_dtb_list(fdt);
+        struct dtb_node *dtb_node_list =  dtb_node_get_dtb_list(fdt);
         if (dtb_node_list != RT_NULL)
         {
             struct dtb_node *bt_pins;
             int memreserve_size;
             struct dtb_memreserve *memreserve;
 
-            bt_pins = fdt_get_dtb_node_by_name_DFS(dtb_node_list, "bt_pins");
-            bt_pins = fdt_get_dtb_node_by_name_BFS(dtb_node_list, bt_pins->name);
-            bt_pins = fdt_get_dtb_node_by_phandle_DFS(dtb_node_list, bt_pins->handle);
-            bt_pins = fdt_get_dtb_node_by_phandle_BFS(dtb_node_list, bt_pins->handle);
+            bt_pins = dtb_node_get_dtb_node_by_name_DFS(dtb_node_list, "bt_pins");
+            bt_pins = dtb_node_get_dtb_node_by_name_BFS(dtb_node_list, bt_pins->name);
+            bt_pins = dtb_node_get_dtb_node_by_phandle_DFS(dtb_node_list, bt_pins->handle);
+            bt_pins = dtb_node_get_dtb_node_by_phandle_BFS(dtb_node_list, bt_pins->handle);
 
-            memreserve = fdt_get_dtb_memreserve(bt_pins, &memreserve_size);
+            memreserve = dtb_node_get_dtb_memreserve(bt_pins, &memreserve_size);
             if (memreserve_size > 0)
             {
                 int i;
@@ -115,7 +115,7 @@ int fdt_test()
                 rt_kputs("\b]\n");
             }
         }
-        fdt_free_dtb_list(dtb_node_list);
+        dtb_node_free_dtb_list(dtb_node_list);
     }
     return 0;
 }

+ 17 - 0
inc/dtb_head.h

@@ -0,0 +1,17 @@
+/*
+ * Copyright (c) 2006-2021, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+#ifndef _RT_DTB_HEAD_H
+#define _RT_DTB_HEAD_H
+#include <stdio.h>
+#include <string.h>
+#include <stdbool.h>
+#include <stdlib.h>
+
+void *get_fdt_blob(void);
+struct dtb_node *get_dtb_node_head(void);
+bool dtb_node_active(void);
+int device_tree_setup(void *mem_addr);
+#endif

+ 379 - 0
inc/dtb_node.h

@@ -0,0 +1,379 @@
+/*
+ * Copyright (c) 2006-2021, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+#ifndef _DTB_NODE_H__
+#define _DTB_NODE_H__
+
+#include "libfdt_env.h"
+#include "dtb_head.h"
+#include <stdio.h>
+#include <string.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <sys/types.h>
+
+//#define RT_DTB_DEBUG
+#ifdef RT_DTB_DEBUG
+#define debug(fmt, args...) printf(fmt, ##args)
+#else
+#define debug(fmt, args...)
+#endif
+
+#define ERR_PTR(err)    ((void *)((long)(err)))
+#define PTR_ERR(ptr)    ((long)(ptr))
+#define IS_ERR(ptr)     ((unsigned long)(ptr) > (unsigned long)(-1000))
+
+#define DEV_ROOT_NODE_ADDR_CELLS_DEFAULT 2
+#define DEV_ROOT_NODE_SIZE_CELLS_DEFAULT 1
+/* will be optimized to only u64 or u32 by gcc */
+#define IN_64BITS_MODE (sizeof(void *) == 8)
+
+#define FDT_ROOT_ADDR_CELLS_DEFAULT 1
+#define FDT_ROOT_SIZE_CELLS_DEFAULT 1
+
+#define FDT_DTB_ALL_NODES_PATH_SIZE (32 * 1024)
+#define FDT_DTB_PAD_SIZE 1024
+
+#define FDT_RET_NO_MEMORY 2
+#define FDT_RET_NO_LOADED 1
+#define FDT_RET_GET_OK 0
+#define FDT_RET_GET_EMPTY (-1)
+
+typedef uint32_t phandle;
+
+struct dtb_memreserve
+{
+    uintptr_t address;
+    size_t size;
+};
+
+struct dtb_header
+{
+    char root, zero; /* "/" */
+    struct dtb_memreserve *memreserve;
+    size_t memreserve_sz;
+};
+
+struct dtb_property
+{
+    const char *name;
+    int size;
+    void *value;
+
+    struct dtb_property *next;
+};
+
+struct dtb_node
+{
+    union
+    {
+        const char *name;
+        const struct dtb_header *header;
+    };
+    const char *path;
+    phandle handle;
+
+    struct dtb_property *properties;
+    struct dtb_node *parent;
+    struct dtb_node *child;
+    struct dtb_node *sibling;
+};
+
+#define FDT_MAX_PHANDLE_ARGS 16
+
+/**
+ * struct dtb_node_phandle_args - structure to hold phandle and arguments
+ *
+ * This is used when decoding a phandle in a device tree property. Typically
+ * these look like this:
+ *
+ * wibble {
+ *    phandle = <5>;
+ * };
+ *
+ * ...
+ * some-prop = <&wibble 1 2 3>
+ *
+ * Here &node is the phandle of the node 'wibble', i.e. 5. There are three
+ * arguments: 1, 2, 3.
+ *
+ * So when decoding the phandle in some-prop, np will point to wibble,
+ * args_count will be 3 and the three arguments will be in args.
+ *
+ * @np: Node that the phandle refers to
+ * @args_count: Number of arguments
+ * @args: Argument values
+ */
+struct fdt_phandle_args
+{
+    struct dtb_node *np;
+    int args_count;
+    uint32_t args[FDT_MAX_PHANDLE_ARGS];
+};
+
+/*
+ * A single signal can be specified via a range of minimal and maximal values
+ * with a typical value, that lies somewhere inbetween.
+ */
+struct timing_entry
+{
+    uint32_t min;
+    uint32_t typ;
+    uint32_t max;
+};
+
+void *dtb_node_load_from_fs(char *dtb_filename);
+void *dtb_node_load_from_memory(void *dtb_ptr, bool is_clone);
+
+size_t dtb_node_set_linux_cmdline(void *fdt, char *cmdline);
+size_t dtb_node_set_linux_initrd(void *fdt, uint64_t initrd_addr, size_t initrd_size);
+
+size_t dtb_node_set_dtb_property(void *fdt, char *pathname, char *property_name, uint32_t *cells, size_t cells_size);
+size_t dtb_node_add_dtb_memreserve(void *fdt, uint64_t address, uint64_t size);
+size_t dtb_node_del_dtb_memreserve(void *fdt, uint64_t address);
+
+int dtb_node_get_exec_status();
+struct dtb_node *dtb_node_get_dtb_list(void *fdt);
+void dtb_node_free_dtb_list(struct dtb_node *dtb_node_head);
+void dtb_node_get_dts_dump(struct dtb_node *dtb_node_head);
+void dtb_node_get_enum_dtb_node(struct dtb_node *dtb_node_head, void(callback(struct dtb_node *dtb_node)));
+
+struct dtb_node *dtb_node_get_dtb_node_by_name_DFS(struct dtb_node *dtb_node, const char *nodename);
+struct dtb_node *dtb_node_get_dtb_node_by_name_BFS(struct dtb_node *dtb_node, const char *nodename);
+struct dtb_node *dtb_node_get_dtb_node_by_path(struct dtb_node *dtb_node, const char *pathname);
+struct dtb_node *dtb_node_get_dtb_node_by_phandle_DFS(struct dtb_node *dtb_node, phandle handle);
+struct dtb_node *dtb_node_get_dtb_node_by_phandle_BFS(struct dtb_node *dtb_node, phandle handle);
+void dtb_node_get_dtb_node_cells(struct dtb_node *dtb_node, int *addr_cells, int *size_cells);
+struct dtb_memreserve *dtb_node_get_dtb_memreserve(struct dtb_node *dtb_node, int *memreserve_size);
+uint8_t dtb_node_get_dtb_byte_value(void *value);
+
+char *dtb_node_get_dtb_string_list_value(void *value, int size, int index);
+char *dtb_node_get_dtb_string_list_value_next(void *value, void *end);
+uint32_t dtb_node_get_dtb_cell_value(void *value);
+
+bool dtb_node_get_dtb_node_status(const struct dtb_node *dtb_node);
+bool dtb_node_get_dtb_node_compatible_match(const struct dtb_node *dtb_node, const char *compatibles);
+
+/*dtb_node_access.c */
+int dtb_node_read_u32(const struct dtb_node *dn, const char *propname, uint32_t *outp);
+uint32_t dtb_node_read_u32_default(const struct dtb_node *node, const char *propname, uint32_t def);
+int dtb_node_read_u32_index(const struct dtb_node *node, const char *propname, int index,
+                           uint32_t *outp);
+uint32_t dtb_node_read_u32_index_default(const struct dtb_node *node, const char *propname, int index,
+                                        uint32_t def);
+int dtb_node_read_u32_array(const struct dtb_node *dn, const char *propname,
+                       uint32_t *out_values, size_t sz);
+int dtb_node_read_u32_index(const struct dtb_node *dn, const char *propname,
+                       int index, uint32_t *outp);
+int dtb_node_read_s32_default(const struct dtb_node *node, const char *propname, int32_t def);
+int dtb_node_read_u64(const struct dtb_node *dn, const char *propname, uint64_t *outp);
+uint64_t dtb_node_read_u64_default(const struct dtb_node *node, const char *propname, uint64_t def);
+
+int dtb_node_n_addr_cells(const struct dtb_node *dn);
+int dtb_node_n_size_cells(const struct dtb_node *dn);
+int dtb_node_simple_addr_cells(const struct dtb_node *np);
+int dtb_node_simple_size_cells(const struct dtb_node *np);
+
+struct dtb_node *dtb_node_find_all_nodes(const struct dtb_node *prev);
+struct dtb_node *dtb_node_find_node_by_phandle(phandle handle);
+struct dtb_node *dtb_node_find_compatible_node(struct dtb_node *from, const char *compatible);
+void *dtb_node_get_dtb_node_property_value(const struct dtb_node *dtb_node, const char *property_name, int *property_size);
+struct dtb_property *dtb_node_get_dtb_node_property(const struct dtb_node *dtb_node, const char *property_name, int *property_size);
+const struct dtb_node *dtb_node_find_node_by_prop_value(struct dtb_node *from, const char *propname, const void *propval, int proplen);
+struct dtb_node *dtb_node_find_node_opts_by_path(const char *path,
+                                            const char **opts);
+
+static inline struct dtb_node *dtb_node_find_node_by_path(const char *path)
+{
+    return dtb_node_find_node_opts_by_path(path, NULL);
+}
+
+bool dtb_node_device_is_available(const struct dtb_node *device);
+struct dtb_node *dtb_node_get_parent(const struct dtb_node *node);
+int dtb_node_property_match_string(const struct dtb_node *dn, const char *propname,
+                              const char *string);
+int dtb_node_property_read_string_helper(const struct dtb_node *dn,
+                                    const char *propname, const char **out_strs,
+                                    size_t sz, int skip);
+/**
+ * of_property_read_string_index() - Find and read a string from a multiple
+ * strings property.
+ * @np:		device node from which the property value is to be read.
+ * @propname:	name of the property to be searched.
+ * @index:	index of the string in the list of strings
+ * @out_string:	pointer to null terminated return string, modified only if
+ *		return value is 0.
+ *
+ * Search for a property in a device tree node and retrieve a null
+ * terminated string value (pointer to data, not a copy) in the list of strings
+ * contained in that property.
+ * Returns 0 on success, -EINVAL if the property does not exist, -ENODATA if
+ * property does not have a value, and -EILSEQ if the string is not
+ * null-terminated within the length of the property data.
+ *
+ * The out_string pointer is modified only if a valid string can be decoded.
+ */
+static inline int dtb_node_property_read_string_index(const struct dtb_node *dn,
+                                                 const char *propname,
+                                                 int index, const char **output)
+{
+    int rc = dtb_node_property_read_string_helper(dn, propname, output, 1, index);
+    return rc < 0 ? rc : 0;
+}
+
+/**
+ * of_property_count_strings() - Find and return the number of strings from a
+ * multiple strings property.
+ * @np:		device node from which the property value is to be read.
+ * @propname:	name of the property to be searched.
+ *
+ * Search for a property in a device tree node and retrieve the number of null
+ * terminated string contain in it. Returns the number of strings on
+ * success, -EINVAL if the property does not exist, -ENODATA if property
+ * does not have a value, and -EILSEQ if the string is not null-terminated
+ * within the length of the property data.
+ */
+static inline int dtb_node_property_count_strings(const struct dtb_node *dn,
+                                             const char *propname)
+{
+    return dtb_node_property_read_string_helper(dn, propname, NULL, 0, 0);
+}
+
+struct dtb_node *dtb_node_parse_phandle(const struct dtb_node *dn,
+                                   const char *phandle_name, int index);
+int dtb_node_parse_phandle_with_args(const struct dtb_node *dn,
+                                const char *list_name, const char *cells_name,
+                                int index, struct fdt_phandle_args *out_args);
+int dtb_node_count_phandle_with_args(const struct dtb_node *dn,
+                                const char *list_name, const char *cells_name);
+
+/* dtb_node_addr.c */
+const uint32_t *dtb_node_get_address(const struct dtb_node *dev, int index,
+                                uint64_t *size, unsigned int *flags);
+
+#define dtb_node_string_list(string, ...) ((char *[]){string, ##__VA_ARGS__, NULL})
+
+#define for_each_property_string(node_ptr, property_name, str, size)            \
+    for (str = dtb_node_get_dtb_node_property_value(node_ptr, property_name, &size), \
+        size += (typeof(size))(size_t)str;                                      \
+         str && *str;                                                           \
+         str = dtb_node_get_dtb_string_list_value_next((void *)str, (void *)(size_t)size))
+
+#define for_each_property_cell(node_ptr, property_name, value, list, size)       \
+    for (list = dtb_node_get_dtb_node_property_value(node_ptr, property_name, &size), \
+        value = dtb_node_get_dtb_cell_value(list),                                    \
+        size /= sizeof(uint32_t);                                                \
+         size > 0;                                                               \
+         value = dtb_node_get_dtb_cell_value(++list), --size)
+
+#define for_each_property_byte(node_ptr, property_name, value, list, size)       \
+    for (list = dtb_node_get_dtb_node_property_value(node_ptr, property_name, &size), \
+        value = dtb_node_get_dtb_byte_value(list);                                    \
+         size > 0;                                                               \
+         value = dtb_node_get_dtb_byte_value(++list), --size)
+
+#define for_each_node_child(node_ptr)                    \
+    for (node_ptr = (node_ptr ? node_ptr->child : NULL); \
+         node_ptr != NULL;                               \
+         node_ptr = node_ptr->sibling)
+
+#define for_each_node_sibling(node_ptr)                    \
+    for (node_ptr = (node_ptr ? node_ptr->sibling : NULL); \
+         node_ptr != NULL;                                 \
+         node_ptr = node_ptr->sibling)
+
+#define for_each_of_allnodes_from(from, dn) \
+    for (dn = dtb_node_find_all_nodes(from); dn; dn = dtb_node_find_all_nodes(dn))
+
+#define for_each_of_allnodes(dn) for_each_of_allnodes_from(NULL, dn)
+
+#define dtb_node_get(x) (x)
+static inline void dtb_node_put(const struct dtb_node *np)
+{
+}
+
+/* Helper to read a big number; size is in cells (not bytes) */
+static inline uint64_t dtb_node_read_number(const uint32_t *cell, int size)
+{
+    uint64_t r = 0;
+    while (size--)
+        r = (r << 32) | fdt32_to_cpu(*(cell++));
+    return r;
+}
+
+/**
+ * ofnode_valid() - check if an ofnode is valid
+ *
+ * @return true if the reference contains a valid ofnode, false if it is NULL
+ */
+static inline bool dtb_node_valid(const struct dtb_node *node)
+{
+    if (dtb_node_active())
+        return node != NULL;
+    return false;
+}
+
+/*dtb_base.c */
+bool dtb_node_read_bool(const struct dtb_node *node, const char *propname);
+const void *dtb_node_read_prop(const struct dtb_node *node, const char *propname, int *sizep);
+const char *dtb_node_read_string(const struct dtb_node *node, const char *propname);
+const struct dtb_node *dtb_node_find_subnode(const struct dtb_node *node, const char *subnode_name);
+int dtb_node_read_u32_array(const struct dtb_node *node, const char *propname,
+                           uint32_t *out_values, size_t sz);
+struct dtb_node *dtb_node_first_subnode(const struct dtb_node *node);
+struct dtb_node *dtb_node_next_subnode(const struct dtb_node *node);
+struct dtb_node *dtb_node_get_parent(const struct dtb_node *node);
+const char *dtb_node_get_name(const struct dtb_node *node);
+struct dtb_node *dtb_node_get_by_phandle(uint phandle);
+int dtb_node_read_size(const struct dtb_node *node, const char *propname);
+size_t dtb_node_get_addr_index(const struct dtb_node *node, int index);
+size_t dtb_node_get_addr(const struct dtb_node *node);
+int dtb_node_stringlist_search(const struct dtb_node *node, const char *property,
+                              const char *string);
+int dtb_node_read_string_index(const struct dtb_node *node, const char *property, int index,
+                              const char **outp);
+int dtb_node_read_string_count(const struct dtb_node *node, const char *property);
+struct dtb_node *dtb_node_path(const char *path);
+const char *dtb_node_get_chosen_prop(const char *name);
+struct dtb_node *dtb_node_get_chosen_node(const char *name);
+const void *dtb_node_get_property(const struct dtb_node *node, const char *propname, int *lenp);
+bool dtb_node_is_available(const struct dtb_node *node);
+size_t dtb_node_get_addr_size(const struct dtb_node *node, const char *property,
+                             size_t *sizep);
+const uint8_t *dtb_node_read_u8_array_ptr(const struct dtb_node *node, const char *propname, size_t sz);
+int dtb_node_find_all_active_compatible_node(const struct dtb_node *from, const char *compatible, struct dtb_node **node_table, int max_num, int *node_num);
+int dtb_node_write_prop(const struct dtb_node *node, const char *propname, int len,
+                       const void *value);
+int dtb_node_write_string(const struct dtb_node *node, const char *propname, const char *value);
+int dtb_node_set_enabled(const struct dtb_node *node, bool value);
+int dtb_node_irq_get(struct dtb_node *dev, int index);
+int dtb_node_irq_get_byname(struct dtb_node *dev, const char *name);
+int dtb_node_irq_count(struct dtb_node *dev);
+/**
+ * dtb_node_for_each_subnode() - iterate over all subnodes of a parent
+ *
+ * @node:       child node (ofnode, lvalue)
+ * @parent:     parent node (ofnode)
+ *
+ * This is a wrapper around a for loop and is used like so:
+ *
+ * ofnode node;
+ *
+ * dtb_node_for_each_subnode(node, parent) {
+ *      Use node
+ *       ...
+ * }
+ *
+ * Note that this is implemented as a macro and @node is used as
+ * iterator in the loop. The parent variable can be a constant or even a
+ * literal.
+ */
+#define dtb_node_for_each_subnode(node, parent) \
+    for (node = dtb_node_first_subnode(parent); \
+         dtb_node_valid(node);                  \
+         node = dtb_node_next_subnode(node))
+
+#endif /* RT_FDT_H__ */

+ 0 - 124
inc/fdt.h

@@ -1,124 +0,0 @@
-#ifndef _RT_FDT_H
-#define _RT_FDT_H
-
-#include <rtthread.h>
-
-/* will be optimized to only u64 or u32 by gcc */
-#define IN_64BITS_MODE  (sizeof(void *) == 8)
-
-#define FDT_ROOT_ADDR_CELLS_DEFAULT 1
-#define FDT_ROOT_SIZE_CELLS_DEFAULT 1
-
-#define FDT_DTB_ALL_NODES_PATH_SIZE (32 * 1024)
-#define FDT_DTB_PAD_SIZE            1024
-
-#define FDT_RET_NO_MEMORY   2
-#define FDT_RET_NO_LOADED   1
-#define FDT_RET_GET_OK      0
-#define FDT_RET_GET_EMPTY   (-1)
-
-typedef rt_uint32_t phandle;
-
-struct dtb_memreserve
-{
-    rt_uint64_t address;
-    rt_uint64_t size;
-};
-
-struct dtb_header
-{
-    char root, zero;        /* "/" */
-    struct dtb_memreserve *memreserve;
-    rt_size_t memreserve_sz;
-};
-
-struct dtb_property
-{
-    const char *name;
-    int size;
-    void *value;
-
-    struct dtb_property *next;
-};
-
-struct dtb_node
-{
-    union
-    {
-        const char *name;
-        const struct dtb_header *header;
-    };
-    const char *path;
-    phandle handle;
-
-    struct dtb_property *properties;
-    struct dtb_node *parent;
-    struct dtb_node *child;
-    struct dtb_node *sibling;
-};
-
-void *fdt_load_from_fs(char *dtb_filename);
-void *fdt_load_from_memory(void *dtb_ptr, rt_bool_t is_clone);
-
-rt_size_t fdt_set_linux_cmdline(void *fdt, char *cmdline);
-rt_size_t fdt_set_linux_initrd(void *fdt, rt_uint64_t initrd_addr, rt_size_t initrd_size);
-
-rt_size_t fdt_set_dtb_property(void *fdt, char *pathname, char *property_name, rt_uint32_t *cells, rt_size_t cells_size);
-rt_size_t fdt_add_dtb_memreserve(void *fdt, rt_uint64_t address, rt_uint64_t size);
-rt_size_t fdt_del_dtb_memreserve(void *fdt, rt_uint64_t address);
-
-rt_err_t fdt_get_exec_status();
-struct dtb_node *fdt_get_dtb_list(void *fdt);
-void fdt_free_dtb_list(struct dtb_node *dtb_node_head);
-void fdt_get_dts_dump(struct dtb_node *dtb_node_head);
-void fdt_get_enum_dtb_node(struct dtb_node *dtb_node_head, void (callback(struct dtb_node *dtb_node)));
-
-struct dtb_node *fdt_get_dtb_node_by_name_DFS(struct dtb_node *dtb_node, const char *nodename);
-struct dtb_node *fdt_get_dtb_node_by_name_BFS(struct dtb_node *dtb_node, const char *nodename);
-struct dtb_node *fdt_get_dtb_node_by_path(struct dtb_node *dtb_node, const char *pathname);
-struct dtb_node *fdt_get_dtb_node_by_phandle_DFS(struct dtb_node *dtb_node, phandle handle);
-struct dtb_node *fdt_get_dtb_node_by_phandle_BFS(struct dtb_node *dtb_node, phandle handle);
-void fdt_get_dtb_node_cells(struct dtb_node *dtb_node, int *addr_cells, int *size_cells);
-void *fdt_get_dtb_node_property(struct dtb_node *dtb_node, const char *property_name, rt_size_t *property_size);
-struct dtb_memreserve *fdt_get_dtb_memreserve(struct dtb_node *dtb_node, int *memreserve_size);
-rt_uint8_t fdt_get_dtb_byte_value(void *value);
-
-char *fdt_get_dtb_string_list_value(void *value, int size, int index);
-char *fdt_get_dtb_string_list_value_next(void *value, void *end);
-rt_uint32_t fdt_get_dtb_cell_value(void *value);
-
-rt_bool_t fdt_get_dtb_node_status(struct dtb_node *dtb_node);
-rt_bool_t fdt_get_dtb_node_compatible_match(struct dtb_node *dtb_node, char **compatibles);
-
-#define fdt_string_list(string, ...) ((char *[]){string, ##__VA_ARGS__, RT_NULL})
-
-#define for_each_property_string(node_ptr, property_name, str, size)        \
-    for (str = fdt_get_dtb_node_property(node_ptr, property_name, &size),   \
-        size += (typeof(size))(rt_ubase_t)str;                              \
-        str && *str;                                                        \
-        str = fdt_get_dtb_string_list_value_next((void *)str, (void *)(rt_ubase_t)size))
-
-#define for_each_property_cell(node_ptr, property_name, value, list, size)  \
-    for (list = fdt_get_dtb_node_property(node_ptr, property_name, &size),  \
-        value = fdt_get_dtb_cell_value(list),                               \
-        size /= sizeof(rt_uint32_t);                                        \
-        size > 0;                                                           \
-        value = fdt_get_dtb_cell_value(++list), --size)
-
-#define for_each_property_byte(node_ptr, property_name, value, list, size)  \
-    for (list = fdt_get_dtb_node_property(node_ptr, property_name, &size),  \
-        value = fdt_get_dtb_byte_value(list);                               \
-        size > 0;                                                           \
-        value = fdt_get_dtb_byte_value(++list), --size)
-
-#define for_each_node_child(node_ptr)                           \
-    for (node_ptr = (node_ptr ? node_ptr->child : RT_NULL);     \
-        node_ptr != RT_NULL;                                    \
-        node_ptr = node_ptr->sibling)
-
-#define for_each_node_sibling(node_ptr)                         \
-    for (node_ptr = (node_ptr ? node_ptr->sibling : RT_NULL);   \
-        node_ptr != RT_NULL;                                    \
-        node_ptr = node_ptr->sibling)
-
-#endif /* _RT_FDT_H */

+ 1 - 1
src/SConscript

@@ -3,7 +3,7 @@ from building import *
 cwd     = GetCurrentDir()
 src     = Glob('*.c')
 list    = os.listdir(cwd)
-CPPPATH = [cwd + '/../inc']
+CPPPATH = [cwd + '/../inc' , cwd + '/libfdt']
 objs    = []
 
 group = DefineGroup('FDT', src, depend = ['PKG_USING_FDT'], CPPPATH = CPPPATH)

+ 658 - 0
src/dtb_access.c

@@ -0,0 +1,658 @@
+/*
+ * Copyright (c) 2006-2022, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+#define _GNU_SOURCE
+
+#include "libfdt/libfdt.h"
+#include "dtb_node.h"
+#include "dtb_head.h"
+
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <assert.h>
+
+/* "/aliaes" node */
+static struct dtb_node *fdt_aliases;
+
+/**
+ * of_find_property_value_of_size() - find property of given size
+ *
+ * Search for a property in a device node and validate the requested size.
+ *
+ * @np:     device node from which the property value is to be read.
+ * @propname:   name of the property to be searched.
+ * @len:    requested length of property value
+ *
+ * @return the property value on success, -EINVAL if the property does not
+ * exist, -ENODATA if property does not have a value, and -EOVERFLOW if the
+ * property data isn't large enough.
+ */
+static void *dtb_node_find_property_value_of_size(const struct dtb_node *dn,
+                                             const char *propname, uint32_t len)
+{
+    struct dtb_property *prop = dtb_node_get_dtb_node_property(dn, propname, NULL);
+
+    if (!prop)
+        return ERR_PTR(-EINVAL);
+    if (!prop->value)
+        return ERR_PTR(-ENODATA);
+    if (len > prop->size)
+        return ERR_PTR(-EOVERFLOW);
+    return prop->value;
+}
+
+int dtb_node_read_u32(const struct dtb_node *dn, const char *propname, uint32_t *outp)
+{
+    const uint32_t *val;
+
+    debug("%s: %s: \n", __func__, propname);
+    if (!dn)
+        return -EINVAL;
+    val = dtb_node_find_property_value_of_size(dn, propname, sizeof(*outp));
+    if (IS_ERR(val))
+    {
+        debug("(not found)\n");
+        return PTR_ERR(val);
+    }
+
+    *outp = fdt32_to_cpu(*val);
+    debug("%#x (%d)\n", *outp, *outp);
+
+    return 0;
+}
+
+uint32_t dtb_node_read_u32_default(const struct dtb_node *node, const char *propname, uint32_t def)
+{
+    dtb_node_read_u32(node, propname, &def);
+
+    return def;
+}
+
+int dtb_node_read_u32_array(const struct dtb_node *dn, const char *propname,
+                       uint32_t *out_values, size_t sz)
+{
+    const uint32_t *val;
+
+    debug("%s: %s: ", __func__, propname);
+    val = dtb_node_find_property_value_of_size(dn, propname,
+                                          sz * sizeof(*out_values));
+
+    if (IS_ERR(val))
+        return PTR_ERR(val);
+
+    debug("size %zd, val:%d\n", sz, *val);
+    while (sz--)
+        *out_values++ = fdt32_to_cpu(*val++);
+
+    return 0;
+}
+
+uint32_t dtb_node_read_u32_index_default(const struct dtb_node *node, const char *propname, int index,
+                  uint32_t def)
+{
+    assert(dtb_node_valid(node));
+    dtb_node_read_u32_index(node, propname, index, &def);
+
+    return def;
+}
+
+int dtb_node_read_s32_default(const struct dtb_node *node, const char *propname, int32_t def)
+{
+    assert(dtb_node_valid(node));
+    dtb_node_read_u32(node, propname, (uint32_t *)&def);
+
+    return def;
+}
+
+int dtb_node_read_u32_index(const struct dtb_node *dn, const char *propname,
+                       int index, uint32_t *outp)
+{
+    const uint32_t *val;
+
+    debug("%s: %s: ", __func__, propname);
+    if (!dn)
+        return -EINVAL;
+
+    val = dtb_node_find_property_value_of_size(dn, propname,
+                                          sizeof(*outp) * (index + 1));
+    if (IS_ERR(val))
+    {
+        debug("(not found)\n");
+        return PTR_ERR(val);
+    }
+
+    *outp = fdt32_to_cpu(val[index]);
+    debug("%#x (%d)\n", *outp, *outp);
+
+    return 0;
+}
+
+int dtb_node_read_u64(const struct dtb_node *dn, const char *propname, uint64_t *outp)
+{
+    const uint64_t *val;
+
+    debug("%s: %s: ", __func__, propname);
+    if (!dn)
+        return -EINVAL;
+    val = dtb_node_find_property_value_of_size(dn, propname, sizeof(*outp));
+    if (IS_ERR(val))
+    {
+        debug("(not found)\n");
+        return PTR_ERR(val);
+    }
+
+    *outp = fdt64_to_cpu(*val);
+    debug("%#llx (%lld)\n", (unsigned long long)*outp,
+          (unsigned long long)*outp);
+
+    return 0;
+}
+
+uint64_t dtb_node_read_u64_default(const struct dtb_node *node, const char *propname, uint64_t def)
+{
+    assert(dtb_node_valid(node));
+    dtb_node_read_u64(node, propname, &def);
+
+    return def;
+}
+
+int dtb_node_n_addr_cells(const struct dtb_node *dn)
+{
+    const uint32_t *ip;
+
+    do
+    {
+        if (dn->parent)
+            dn = dn->parent;
+        ip = dtb_node_get_dtb_node_property_value(dn, "#address-cells", NULL);
+        if (ip)
+            return fdt32_to_cpu(*ip);
+    } while (dn->parent);
+
+    /* No #address-cells property for the root node */
+    return DEV_ROOT_NODE_ADDR_CELLS_DEFAULT;
+}
+
+int dtb_node_n_size_cells(const struct dtb_node *dn)
+{
+    const uint32_t *ip;
+
+    do
+    {
+        if (dn->parent)
+            dn = dn->parent;
+        ip = dtb_node_get_dtb_node_property_value(dn, "#size-cells", NULL);
+        if (ip)
+            return fdt32_to_cpu(*ip);
+    } while (dn->parent);
+
+    /* No #size-cells property for the root node */
+    return DEV_ROOT_NODE_SIZE_CELLS_DEFAULT;
+}
+
+int dtb_node_simple_addr_cells(const struct dtb_node *dn)
+{
+    const uint32_t *ip;
+
+    ip = dtb_node_get_dtb_node_property_value(dn, "#address-cells", NULL);
+    if (ip)
+        return fdt32_to_cpu(*ip);
+
+    /* Return a default of 2 to match fdt_address_cells()*/
+    return 2;
+}
+
+int dtb_node_simple_size_cells(const struct dtb_node *dn)
+{
+    const uint32_t *ip;
+
+    ip = dtb_node_get_dtb_node_property_value(dn, "#size-cells", NULL);
+    if (ip)
+        return fdt32_to_cpu(*ip);
+
+    /* Return a default of 2 to match fdt_size_cells()*/
+    return 2;
+}
+
+struct dtb_property *dtb_node_get_dtb_node_property(const struct dtb_node *dtb_node, const char *property_name, int *property_size)
+{
+    struct dtb_property *dtb_property = NULL;
+
+    if (dtb_node != NULL && property_name != NULL)
+    {
+        dtb_property = dtb_node->properties;
+
+        while (dtb_property != NULL)
+        {
+            if (!strcmp(dtb_property->name, property_name))
+            {
+                if (property_size != NULL)
+                {
+                    *property_size = dtb_property->size;
+                }
+                return dtb_property;
+            }
+            dtb_property = dtb_property->next;
+        }
+    }
+
+    return dtb_property;
+}
+
+#define for_each_property_of_node(dn, pp) \
+    for (pp = dn->properties; pp != NULL; pp = pp->next)
+
+struct dtb_node *dtb_node_find_node_opts_by_path(const char *path,
+                                            const char **opts)
+{
+    struct dtb_node *np = NULL;
+    struct dtb_property *pp;
+    const char *separator = strchr(path, ':');
+
+    if (opts)
+        *opts = separator ? separator + 1 : NULL;
+
+    if (strcmp(path, "/") == 0)
+        return dtb_node_get(get_dtb_node_head());
+
+    /* The path could begin with an alias */
+    if (*path != '/')
+    {
+        int len;
+        const char *p = separator;
+
+        if (!p)
+            p = strchrnul(path, '/');
+        len = p - path;
+
+        /* of_aliases must not be NULL */
+        if (!fdt_aliases)
+            return NULL;
+
+        for_each_property_of_node(fdt_aliases, pp)
+        {
+            if (strlen(pp->name) == len && !strncmp(pp->name, path,
+                                                    len))
+            {
+                np = dtb_node_find_node_by_path(pp->value);
+                break;
+            }
+        }
+        if (!np)
+            return NULL;
+        path = p;
+    }
+
+    /* Step down the tree matching path components */
+    if (!np)
+        np = dtb_node_get(get_dtb_node_head());
+    while (np && *path == '/')
+    {
+        struct dtb_node *tmp = np;
+
+        path++; /* Increment past '/' delimiter */
+        np = dtb_node_get_dtb_node_by_path(np, path);
+        dtb_node_put(tmp);
+        path = strchrnul(path, '/');
+        if (separator && separator < path)
+            break;
+    }
+
+    return np;
+}
+
+struct dtb_node *dtb_node_find_compatible_node(struct dtb_node *from, const char *compatible)
+{
+    struct dtb_node *dn;
+
+    for_each_of_allnodes_from(from, dn)
+    {
+        if (dtb_node_get_dtb_node_compatible_match(dn, compatible) &&
+            dtb_node_get(dn))
+            break;
+    }
+    dtb_node_put(from);
+
+    return dn;
+}
+
+void *dtb_node_get_dtb_node_property_value(const struct dtb_node *dtb_node, const char *property_name, int *property_size)
+{
+    struct dtb_property *dtb_property = dtb_node_get_dtb_node_property(dtb_node, property_name, NULL);
+
+    if (!dtb_property || !dtb_property->value || !dtb_property->size)
+    {
+        return NULL;
+    }
+
+    if (property_size != NULL)
+    {
+        *property_size = dtb_property->size;        
+    }
+
+    return dtb_property->value;
+}
+
+const struct dtb_node *dtb_node_find_node_by_prop_value(struct dtb_node *from,
+                                                   const char *propname,
+                                                   const void *propval, int proplen)
+{
+    struct dtb_node *np;
+    void *value;
+    for_each_of_allnodes_from(from, np)
+    {
+        value = dtb_node_get_dtb_node_property_value(np, propname, &proplen);
+        if (!memcmp(value, propval, proplen) && dtb_node_get(np))
+            break;
+    }
+    dtb_node_put(from);
+
+    return np;
+}
+
+struct dtb_node *dtb_node_find_all_nodes(const struct dtb_node *prev)
+{
+    const struct dtb_node *dn;
+
+    if (!prev)
+    {
+        dn = get_dtb_node_head();
+    }
+    else if (prev->child)
+    {
+        dn = prev->child;
+    }
+    else
+    {
+        /*
+         * Walk back up looking for a sibling, or the end of the
+         * structure
+         */
+        dn = prev;
+        while (dn->parent && !dn->sibling)
+            dn = dn->parent;
+        dn = dn->sibling; /* Might be null at the end of the tree */
+    }
+
+    return (struct dtb_node *)dn;
+}
+
+bool dtb_node_device_is_available(const struct dtb_node *device)
+{
+    const char *status;
+    int statlen;
+
+    if (!device)
+        return false;
+
+    status = dtb_node_get_dtb_node_property_value(device, "status", &statlen);
+    if (status == NULL)
+        return true;
+
+    if (statlen > 0)
+    {
+        if (!strcmp(status, "okay"))
+            return true;
+    }
+
+    return false;
+}
+
+struct dtb_node *dtb_node_get_parent(const struct dtb_node *node)
+{
+    const struct dtb_node *dn;
+
+    if (!node)
+        return NULL;
+
+    dn = dtb_node_get(node->parent);
+
+    return (struct dtb_node *)dn;
+}
+
+struct dtb_node *dtb_node_find_node_by_phandle(phandle handle)
+{
+    struct dtb_node *dn;
+
+    if (!handle)
+        return NULL;
+
+    for_each_of_allnodes(dn) if (dn->handle == handle) break;
+    (void)dtb_node_get(dn);
+
+    return dn;
+}
+
+int dtb_node_property_match_string(const struct dtb_node *dn, const char *propname,
+                              const char *string)
+{
+    const struct dtb_property *prop = dtb_node_get_dtb_node_property(dn, propname, NULL);
+    size_t l;
+    int i;
+    const char *p, *end;
+
+    if (!prop)
+        return -EINVAL;
+    if (!prop->value)
+        return -ENODATA;
+
+    p = prop->value;
+    end = p + prop->size;
+
+    for (i = 0; p < end; i++, p += l)
+    {
+        l = strnlen(p, end - p) + 1;
+        if (p + l > end)
+            return -EILSEQ;
+        debug("comparing %s with %s\n", string, p);
+        if (strcmp(string, p) == 0)
+            return i; /* Found it; return index */
+    }
+    return -ENODATA;
+}
+
+/**
+ * of_property_read_string_helper() - Utility helper for parsing string properties
+ * @np:		device node from which the property value is to be read.
+ * @propname:	name of the property to be searched.
+ * @out_strs:	output array of string pointers.
+ * @sz:		number of array elements to read.
+ * @skip:	Number of strings to skip over at beginning of list.
+ *
+ * Don't call this function directly. It is a utility helper for the
+ * of_property_read_string*() family of functions.
+ */
+int dtb_node_property_read_string_helper(const struct dtb_node *dn,
+                                    const char *propname, const char **out_strs,
+                                    size_t sz, int skip)
+{
+    const struct dtb_property *prop = dtb_node_get_dtb_node_property(dn, propname, NULL);
+    int l = 0, i = 0;
+    const char *p, *end;
+
+    if (!prop)
+        return -EINVAL;
+    if (!prop->value)
+        return -ENODATA;
+    p = prop->value;
+    end = p + prop->size;
+
+    for (i = 0; p < end && (!out_strs || i < skip + sz); i++, p += l)
+    {
+        l = strnlen(p, end - p) + 1;
+        if (p + l > end)
+            return -EILSEQ;
+        if (out_strs && i >= skip)
+            *out_strs++ = p;
+    }
+    i -= skip;
+    return i <= 0 ? -ENODATA : i;
+}
+
+static int __dtb_node_parse_phandle_with_args(const struct dtb_node *dn,
+                                         const char *list_name,
+                                         const char *cells_name,
+                                         int cell_count, int index,
+                                         struct fdt_phandle_args *out_args)
+{
+    const uint32_t *list, *list_end;
+    int rc = 0, cur_index = 0;
+    uint32_t count = 0;
+    struct dtb_node *node = NULL;
+    phandle phandle;
+    int size;
+
+    /* Retrieve the phandle list property */
+    list = dtb_node_get_dtb_node_property_value(dn, list_name, &size);
+    if (!list)
+        return -ENOENT;
+    list_end = list + size / sizeof(*list);
+
+    /* Loop over the phandles until all the requested entry is found */
+    while (list < list_end)
+    {
+        rc = -EINVAL;
+        count = 0;
+
+        /*
+         * If phandle is 0, then it is an empty entry with no
+         * arguments.  Skip forward to the next entry.
+         */
+        phandle = fdt32_to_cpu(*(list++));
+        if (phandle)
+        {
+            /*
+             * Find the provider node and parse the #*-cells
+             * property to determine the argument length.
+             *
+             * This is not needed if the cell count is hard-coded
+             * (i.e. cells_name not set, but cell_count is set),
+             * except when we're going to return the found node
+             * below.
+             */
+            if (cells_name || cur_index == index)
+            {
+                node = dtb_node_find_node_by_phandle(phandle);
+                if (!node)
+                {
+                    debug("%s: could not find phandle\n",
+                          dn->path);
+                    goto err;
+                }
+            }
+
+            if (cells_name)
+            {
+                if (dtb_node_read_u32(node, cells_name, &count))
+                {
+                    debug("%s: could not get %s for %s\n",
+                          dn->path, cells_name,
+                          node->path);
+                    goto err;
+                }
+            }
+            else
+            {
+                count = cell_count;
+            }
+
+            /*
+             * Make sure that the arguments actually fit in the
+             * remaining property data length
+             */
+            if (list + count > list_end)
+            {
+                debug("%s: arguments longer than property\n",
+                      dn->path);
+                goto err;
+            }
+        }
+
+        /*
+         * All of the error cases above bail out of the loop, so at
+         * this point, the parsing is successful. If the requested
+         * index matches, then fill the out_args structure and return,
+         * or return -ENOENT for an empty entry.
+         */
+        rc = -ENOENT;
+        if (cur_index == index)
+        {
+            if (!phandle)
+                goto err;
+
+            if (out_args)
+            {
+                int i;
+                if (count > FDT_MAX_PHANDLE_ARGS)
+                    count = FDT_MAX_PHANDLE_ARGS;
+                out_args->np = node;
+                out_args->args_count = count;
+                for (i = 0; i < count; i++)
+                    out_args->args[i] =
+                        fdt32_to_cpu(*(list++));
+            }
+            else
+            {
+                dtb_node_put(node);
+            }
+
+            /* Found it! return success */
+            return 0;
+        }
+
+        dtb_node_put(node);
+        node = NULL;
+        list += count;
+        cur_index++;
+    }
+
+    /*
+     * Unlock node before returning result; will be one of:
+     * -ENOENT : index is for empty phandle
+     * -EINVAL : parsing error on data
+     * [1..n]  : Number of phandle (count mode; when index = -1)
+     */
+    rc = index < 0 ? cur_index : -ENOENT;
+err:
+    if (node)
+        dtb_node_put(node);
+    return rc;
+}
+
+struct dtb_node *dtb_node_parse_phandle(const struct dtb_node *dn,
+                                   const char *phandle_name, int index)
+{
+    struct fdt_phandle_args args;
+
+    if (index < 0)
+        return NULL;
+
+    if (__dtb_node_parse_phandle_with_args(dn, phandle_name, NULL, 0, index,
+                                      &args))
+        return NULL;
+
+    return args.np;
+}
+
+int dtb_node_parse_phandle_with_args(const struct dtb_node *dn,
+                                const char *list_name, const char *cells_name,
+                                int index, struct fdt_phandle_args *out_args)
+{
+    if (index < 0)
+        return -EINVAL;
+
+    return __dtb_node_parse_phandle_with_args(dn, list_name, cells_name, 0,
+                                         index, out_args);
+}
+
+int dtb_node_count_phandle_with_args(const struct dtb_node *dn,
+                                const char *list_name, const char *cells_name)
+{
+    return __dtb_node_parse_phandle_with_args(dn, list_name, cells_name, 0,
+                                         -1, NULL);
+}

+ 64 - 0
src/dtb_addr.c

@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2006-2022, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+#include "libfdt/libfdt.h"
+#include "dtb_node.h"
+#include "dtb_head.h"
+
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdbool.h>
+#include <stdlib.h>
+
+/* Max address size we deal with */
+#define FDT_MAX_ADDR_CELLS	4
+#define FDT_CHECK_ADDR_COUNT(na)	((na) > 0 && (na) <= FDT_MAX_ADDR_CELLS)
+#define FDT_CHECK_COUNTS(na, ns)	(FDT_CHECK_ADDR_COUNT(na) && (ns) > 0)
+
+static void dtb_node_default_count_cells(const struct dtb_node *dn,
+				       int *addrc, int *sizec)
+{
+	if (addrc)
+		*addrc = dtb_node_n_addr_cells(dn);
+	if (sizec)
+		*sizec = dtb_node_n_size_cells(dn);
+}
+
+const uint32_t *dtb_node_get_address(const struct dtb_node *dev, int index,
+			     uint64_t *size, unsigned int *flags)
+{
+	const uint32_t *prop;
+	int psize;
+	struct dtb_node *parent;
+	int onesize, i, na, ns;
+
+	/* Get parent */
+	parent = dtb_node_get_parent(dev);
+	if (parent == NULL)
+		return NULL;
+
+	dtb_node_default_count_cells(dev, &na, &ns);
+	if (!FDT_CHECK_ADDR_COUNT(na))
+		return NULL;
+
+	/* Get "reg" or "assigned-addresses" property */
+	prop = dtb_node_get_dtb_node_property_value(dev, "reg", &psize);
+	if (prop == NULL)
+		return NULL;
+	psize /= 4;
+
+	onesize = na + ns;
+	for (i = 0; psize >= onesize; psize -= onesize, prop += onesize, i++)
+		if (i == index)
+		{
+			if (size)
+				*size = dtb_node_read_number(prop + na, ns);
+			if (flags)
+				*flags = 0x200;
+			return prop;
+		}
+	return NULL;
+}

+ 546 - 0
src/dtb_base.c

@@ -0,0 +1,546 @@
+/*
+ * Copyright (c) 2006-2022, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+#include "dtb_node.h"
+#include "libfdt.h"
+#include "libfdt_env.h"
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <ctype.h>
+
+static const char *_parse_integer_fixup_radix(const char *s, unsigned int *base)
+{
+    if (*base == 0)
+    {
+        if (s[0] == '0')
+        {
+            if (tolower(s[1]) == 'x' && isxdigit(s[2]))
+                *base = 16;
+            else
+                *base = 8;
+        }
+        else
+            *base = 10;
+    }
+    if (*base == 16 && s[0] == '0' && tolower(s[1]) == 'x')
+        s += 2;
+    return s;
+}
+
+unsigned long simple_strtoul(const char *cp, char **endp,
+                unsigned int base)
+{
+    unsigned long result = 0;
+    unsigned long value;
+
+    cp = _parse_integer_fixup_radix(cp, &base);
+
+    while (isxdigit(*cp) && (value = isdigit(*cp) ? *cp-'0' : (islower(*cp)
+        ? toupper(*cp) : *cp)-'A'+10) < base)
+    {
+        result = result*base + value;
+        cp++;
+    }
+
+    if (endp)
+        *endp = (char *)cp;
+
+    return result;
+}
+
+int strict_strtoul(const char *cp, unsigned int base, unsigned long *res)
+{
+    char *tail;
+    unsigned long val;
+    size_t len;
+
+    *res = 0;
+    len = strlen(cp);
+    if (len == 0)
+        return -EINVAL;
+
+    val = simple_strtoul(cp, &tail, base);
+    if (tail == cp)
+        return -EINVAL;
+
+    if ((*tail == '\0') ||
+        ((len == (size_t)(tail - cp) + 1) && (*tail == '\n')))
+    {
+        *res = val;
+        return 0;
+    }
+
+    return -EINVAL;
+}
+
+long simple_strtol(const char *cp, char **endp, unsigned int base)
+{
+    if (*cp == '-')
+        return -simple_strtoul(cp + 1, endp, base);
+
+    return simple_strtoul(cp, endp, base);
+}
+
+bool dtb_node_read_bool(const struct dtb_node *node, const char *propname)
+{
+    const void *prop;
+
+    assert(dtb_node_valid(node));
+    debug("%s: %s: ", __func__, propname);
+
+    prop = dtb_node_get_property(node, propname, NULL);
+
+    debug("%s\n", prop ? "true" : "false");
+
+    return prop ? true : false;
+}
+
+const void *dtb_node_read_prop(const struct dtb_node *node, const char *propname, int *sizep)
+{
+    const char *val = NULL;
+    int len;
+
+    assert(dtb_node_valid(node));
+    debug("%s: %s: ", __func__, propname);
+
+    struct dtb_property *prop = dtb_node_get_dtb_node_property(node, propname, &len);
+
+    if (prop)
+    {
+        val = prop->value;
+        len = prop->size;
+    }
+
+    if (!val)
+    {
+        debug("<not found>\n");
+        if (sizep)
+            *sizep = -FDT_ERR_NOTFOUND;
+        return NULL;
+    }
+    if (sizep)
+        *sizep = len;
+
+    return val;
+}
+
+const char *dtb_node_read_string(const struct dtb_node *node, const char *propname)
+{
+    const char *str;
+    int len;
+
+    str = dtb_node_read_prop(node, propname, &len);
+    if (!str)
+        return NULL;
+
+    if (strnlen(str, len) >= len)
+    {
+        debug("<invalid>\n");
+        return NULL;
+    }
+    debug("%s\n", str);
+
+    return str;
+}
+
+const struct dtb_node *dtb_node_find_subnode(const struct dtb_node *node, const char *subnode_name)
+{
+    const struct dtb_node *subnode;
+
+    assert(dtb_node_valid(node));
+    debug("%s: %s: ", __func__, subnode_name);
+
+    for (node = node->child; node; node = node->sibling)
+    {
+        if (!strcmp(subnode_name, node->name))
+            break;
+    }
+    subnode = node;
+
+    debug("%s\n", dtb_node_valid(subnode) ?\
+          dtb_node_get_name(subnode) : "<none>");
+
+    return subnode;
+}
+
+struct dtb_node *dtb_node_first_subnode(const struct dtb_node *node)
+{
+    assert(dtb_node_valid(node));
+
+    return node->child;
+}
+
+struct dtb_node *dtb_node_next_subnode(const struct dtb_node *node)
+{
+    assert(dtb_node_valid(node));
+
+    return node->sibling;
+}
+
+const char *dtb_node_get_name(const struct dtb_node *node)
+{
+    if (!dtb_node_valid(node))
+    {
+        debug("%s node not valid\n", __func__);
+        return NULL;
+    }
+
+    return strrchr(node->path, '/') + 1;
+
+}
+
+struct dtb_node *dtb_node_get_by_phandle(uint phandle)
+{
+    if (dtb_node_active())
+        return dtb_node_find_node_by_phandle(phandle);
+    return NULL;
+}
+
+int dtb_node_read_size(const struct dtb_node *node, const char *propname)
+{
+    struct dtb_property *prop = dtb_node_get_dtb_node_property( node, propname, NULL);
+
+    if (prop)
+        return prop->size;
+
+    return -EINVAL;
+}
+
+size_t dtb_node_get_addr_index(const struct dtb_node *node, int index)
+{
+    int na;
+    size_t size;
+
+    const uint32_t *prop_val;
+    uint flags;
+
+    prop_val = dtb_node_get_address(node, index,
+                    (uint64_t *)&size, &flags);
+    if (!prop_val)
+        return -1;
+
+    na = dtb_node_n_addr_cells(node);
+
+    return dtb_node_read_number(prop_val, na);
+}
+
+size_t dtb_node_get_addr(const struct dtb_node *node)
+{
+    return dtb_node_get_addr_index(node, 0);
+}
+
+int dtb_node_stringlist_search(const struct dtb_node *node, const char *property,
+                 const char *string)
+{
+    return dtb_node_property_match_string(node, property, string);
+}
+
+int dtb_node_read_string_index(const struct dtb_node *node, const char *property, int index,
+                 const char **outp)
+{
+    return dtb_node_property_read_string_index(node, property, index, outp);
+}
+
+int dtb_node_read_string_count(const struct dtb_node *node, const char *property)
+{
+    return dtb_node_property_count_strings(node, property);
+}
+
+struct dtb_node *dtb_node_path(const char *path)
+{
+    if (dtb_node_active())
+        return dtb_node_find_node_by_path(path);
+    return NULL;
+}
+
+const char *dtb_node_get_chosen_prop(const char *name)
+{
+    const struct dtb_node *chosen_node;
+
+    chosen_node = (const struct dtb_node *)dtb_node_path("/chosen");
+
+    return dtb_node_read_string(chosen_node, name);
+}
+
+struct dtb_node *dtb_node_get_chosen_node(const char *name)
+{
+    const char *prop;
+
+    prop = dtb_node_get_chosen_prop(name);
+    if (!prop)
+        return NULL;
+
+    return dtb_node_path(prop);
+}
+
+const void *dtb_node_get_property(const struct dtb_node *node, const char *propname, int *lenp)
+{
+    return dtb_node_get_dtb_node_property_value(node, propname, lenp);
+}
+
+bool dtb_node_is_available(const struct dtb_node *node)
+{
+    return dtb_node_device_is_available(node);
+}
+
+size_t dtb_node_get_addr_size(const struct dtb_node *node, const char *property,
+                size_t *sizep)
+{
+    int na, ns;
+    int psize;
+    const uint32_t *prop = dtb_node_get_dtb_node_property_value(node, property, &psize);
+
+    if (!prop)
+        return -1;
+    na = dtb_node_n_addr_cells(node);
+    ns = dtb_node_n_size_cells(node);
+    *sizep = dtb_node_read_number(prop + na, ns);
+
+    return dtb_node_read_number(prop, na);
+}
+
+const uint8_t *dtb_node_read_u8_array_ptr(const struct dtb_node *node, const char *propname,
+                    size_t sz)
+{
+    int psize;
+    const uint32_t *prop = dtb_node_get_dtb_node_property_value(node, propname, &psize);
+
+    if (!prop || sz != psize)
+        return NULL;
+    return (uint8_t *)prop;
+}
+
+int dtb_node_find_all_active_compatible_node(const struct dtb_node *from, const char *compatible, struct dtb_node **node_table, int max_num, int *node_num)
+{
+    const struct dtb_node *dn;
+    int num = 0;
+    for_each_of_allnodes_from(from, dn)
+    {
+        if (dtb_node_get_dtb_node_compatible_match(dn, compatible) &&
+            dtb_node_get(dn))
+        {
+            if (!dtb_node_device_is_available(dn))
+            {
+                continue;
+            }
+            num++;
+            if (num > max_num)
+            {
+                return -ETOOMANYREFS;
+            }
+            *node_table = (struct dtb_node *)dn;
+            node_table++;
+        }
+    }
+    *node_num = num;
+    dtb_node_put(from);
+
+    return 0;
+}
+
+int dtb_node_write_prop(const struct dtb_node *node, const char *propname, int len,
+              const void *value)
+{
+    struct dtb_property *pp;
+    struct dtb_property *pp_last = NULL;
+    struct dtb_property *new;
+
+    if (!dtb_node_active())
+        return -ENOSYS;
+
+    if (!node)
+        return -EINVAL;
+
+    for (pp = node->properties; pp; pp = pp->next)
+    {
+        if (strcmp(pp->name, propname) == 0)
+        {
+            /* Property exists -> change value */
+            pp->value = (void *)value;
+            pp->size = len;
+            return 0;
+        }
+        pp_last = pp;
+    }
+
+    if (!pp_last)
+        return -ENOENT;
+
+    /* Property does not exist -> append new property */
+    new = malloc(sizeof(struct dtb_property));
+    if (!new)
+        return -ENOMEM;
+
+    new->name = strdup(propname);
+    if (!new->name)
+    {
+        free(new);
+        return -ENOMEM;
+    }
+
+    new->value = (void *)value;
+    new->size = len;
+    new->next = NULL;
+
+    pp_last->next = new;
+
+    return 0;
+}
+
+int dtb_node_write_string(const struct dtb_node *node, const char *propname, const char *value)
+{
+    if (!dtb_node_active())
+        return -ENOSYS;
+
+    assert(dtb_node_valid(node));
+
+    debug("%s: %s = %s", __func__, propname, value);
+
+    return dtb_node_write_prop(node, propname, strlen(value) + 1, value);
+}
+
+int dtb_node_set_enabled(const struct dtb_node *node, bool value)
+{
+    if (!dtb_node_active())
+        return -ENOSYS;
+
+    assert(dtb_node_valid(node));
+
+    if (value)
+        return dtb_node_write_string(node, "status", "okay");
+    else
+        return dtb_node_write_string(node, "status", "disable");
+}
+
+/**
+ * dtb_node_irq_find_parent - Given a device node, find its interrupt parent node
+ * @child: pointer to device node
+ *
+ * Returns a pointer to the interrupt parent node, or NULL if the interrupt
+ * parent could not be determined.
+ */
+static struct dtb_node *dtb_node_irq_find_parent(struct dtb_node *child)
+{
+	struct dtb_node *p;
+	phandle parent;
+
+	if (!dtb_node_get(child))
+		return NULL;
+	do
+    {
+		if (dtb_node_read_u32_array(child, "interrupt-parent", &parent, 1))
+        {
+			p = dtb_node_get_parent(child);
+		}
+        else
+        {
+			p = dtb_node_get_by_phandle(parent);         
+		}
+		dtb_node_put(child);
+		child = p;
+	} while (p && dtb_node_get_property(p, "#interrupt-cells", NULL) == NULL);
+
+	return p;
+}
+
+int dtb_node_irq_get(struct dtb_node *dev, int index)
+{
+	int rc = 0;
+	struct fdt_phandle_args out_irq;
+    struct dtb_node *p;
+	uint32_t intsize;
+	int res, i;
+
+	p = dtb_node_irq_find_parent(dev);
+	if (p == NULL)
+		return -EINVAL;
+	/* Get size of interrupt specifier */
+	if (dtb_node_read_u32_array(p, "#interrupt-cells", &intsize, 1))
+    {
+		res = -EINVAL;
+		goto out;
+	}
+
+	debug(" path:%s, parent=%pOF, intsize=%d\n", p->path,p, intsize);
+    
+	/* Copy intspec into irq structure */
+	out_irq.np = p;
+	out_irq.args_count = intsize;
+	for (i = 0; i < intsize; i++)
+    {
+		res = dtb_node_read_u32_index(dev, "interrupts",
+						 (index * 3 + i),
+						 out_irq.args + i);
+		if (res)
+			goto out;
+	}
+    rc = out_irq.args[1];
+ out:
+	dtb_node_put(p);
+	return rc;
+
+}
+
+/**
+ * dtb_node_irq_get_byname - Decode a node's IRQ and return it as a Linux IRQ number
+ * @dev: pointer to device tree node
+ * @name: IRQ name
+ *
+ * Returns Linux IRQ number on success, or 0 on the IRQ mapping failure, or
+ * -EPROBE_DEFER if the IRQ domain is not yet created, or error code in case
+ * of any other failure.
+ */
+int dtb_node_irq_get_byname(struct dtb_node *dev, const char *name)
+{
+	int index;
+
+	if (!name)
+		return -EINVAL;
+
+	index = dtb_node_stringlist_search(dev, "interrupt-names", name);
+	if (index < 0)
+		return index;
+
+	return dtb_node_irq_get(dev, index);
+}
+
+/**
+ * dtb_node_irq_count - Count the number of IRQs a node uses
+ * @dev: pointer to device tree node
+ */
+int dtb_node_irq_count(struct dtb_node *device)
+{
+    struct dtb_node *p;
+	uint32_t intsize;
+	int nr = 0, res = 0;
+
+	p = dtb_node_irq_find_parent(device);
+	if (p == NULL)
+		return -EINVAL;
+
+	/* Get size of interrupt specifier */
+	if (dtb_node_read_u32_array(p, "#interrupt-cells", &intsize, 1))
+    {
+		res = -EINVAL;
+		goto out;
+	}
+
+	debug(" path:%s, parent=%pOF, intsize=%d\n", p->path,p, intsize);
+
+    res = dtb_node_read_size(device, "interrupts");
+    if (res < 0)
+    {
+        goto out;
+    }
+    nr = res / (intsize * 4);
+ out:
+	dtb_node_put(p);
+
+	return nr;
+}

+ 202 - 218
src/fdt_get.c → src/dtb_get.c

@@ -1,25 +1,39 @@
+/*
+ * Copyright (c) 2006-2022, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
 #include "libfdt/libfdt.h"
-#include "fdt.h"
+#include "dtb_node.h"
+#include "dtb_head.h"
+
+#include <stdio.h>
+#include <string.h>
+#include <stdbool.h>
+#include <stdlib.h>
+
+#define RT_TRUE     true
+#define RT_FALSE    false
 
 static struct
 {
     const char *ptr;
     const char *end;
     char *cur;
-} paths_buf = {RT_NULL, RT_NULL};
+} paths_buf = {NULL, NULL};
 static void *current_fdt;
 
-rt_err_t fdt_exec_status = FDT_RET_GET_OK;
+int fdt_exec_status = FDT_RET_GET_OK;
 
-rt_err_t fdt_get_exec_status()
+int dtb_node_get_exec_status()
 {
     return fdt_exec_status;
 }
 
-static rt_err_t _fdt_get_dtb_properties_list(struct dtb_property *dtb_property, rt_off_t node_off)
+static int _dtb_node_get_dtb_properties_list(struct dtb_property *dtb_property, off_t node_off)
 {
     /* caller alrealy checked current_fdt */
-    rt_off_t property_off = fdt_first_property_offset(current_fdt, node_off);
+    off_t property_off = fdt_first_property_offset(current_fdt, node_off);
     struct fdt_property *fdt_property;
 
     if (property_off < 0)
@@ -30,7 +44,7 @@ static rt_err_t _fdt_get_dtb_properties_list(struct dtb_property *dtb_property,
     for (;;)
     {
         fdt_property = (struct fdt_property *)fdt_get_property_by_offset(current_fdt, property_off, &dtb_property->size);
-        if (fdt_property != RT_NULL)
+        if (fdt_property != NULL)
         {
             dtb_property->name = fdt_string(current_fdt, fdt32_to_cpu(fdt_property->nameoff));
             dtb_property->value = fdt_property->data;
@@ -40,8 +54,8 @@ static rt_err_t _fdt_get_dtb_properties_list(struct dtb_property *dtb_property,
         property_off = fdt_next_property_offset(current_fdt, property_off);
         if (property_off >= 0)
         {
-            dtb_property->next = (struct dtb_property *)rt_malloc(sizeof(struct dtb_property));
-            if (dtb_property->next == RT_NULL)
+            dtb_property->next = (struct dtb_property *)malloc(sizeof(struct dtb_property));
+            if (dtb_property->next == NULL)
             {
                 return FDT_RET_NO_MEMORY;
             }
@@ -49,7 +63,7 @@ static rt_err_t _fdt_get_dtb_properties_list(struct dtb_property *dtb_property,
         }
         else
         {
-            dtb_property->next = RT_NULL;
+            dtb_property->next = NULL;
             break;
         }
     }
@@ -57,17 +71,17 @@ static rt_err_t _fdt_get_dtb_properties_list(struct dtb_property *dtb_property,
     return FDT_RET_GET_OK;
 }
 
-static rt_err_t _fdt_get_dtb_nodes_list(struct dtb_node *dtb_node_head, struct dtb_node *dtb_node, const char *pathname)
+static int _dtb_node_get_dtb_nodes_list(struct dtb_node *dtb_node_head, struct dtb_node *dtb_node, const char *pathname)
 {
-    rt_off_t root_off;
-    rt_off_t node_off;
+    off_t root_off;
+    off_t node_off;
     int pathname_sz;
     int node_name_sz;
 
     /* caller alrealy checked current_fdt */
     if ((root_off = fdt_path_offset(current_fdt, pathname)) >= 0)
     {
-        pathname_sz = rt_strlen(pathname);
+        pathname_sz = strlen(pathname);
         node_off = fdt_first_subnode(current_fdt, root_off);
 
         if (node_off < 0)
@@ -78,52 +92,52 @@ static rt_err_t _fdt_get_dtb_nodes_list(struct dtb_node *dtb_node_head, struct d
         for (;;)
         {
             dtb_node->parent = dtb_node_head;
-            dtb_node->sibling = RT_NULL;
+            dtb_node->sibling = NULL;
             dtb_node->name = fdt_get_name(current_fdt, node_off, &node_name_sz);
 
             /* parent_path + name + '/' + '\0' */
             if (paths_buf.cur + pathname_sz + node_name_sz + 2 < paths_buf.end)
             {
                 dtb_node->path = (const char *)paths_buf.cur;
-                rt_strncpy(paths_buf.cur, pathname, pathname_sz);
+                strncpy(paths_buf.cur, pathname, pathname_sz);
                 paths_buf.cur += pathname_sz;
-                rt_strncpy(paths_buf.cur, (char *)dtb_node->name, node_name_sz);
+                strncpy(paths_buf.cur, (char *)dtb_node->name, node_name_sz);
                 paths_buf.cur += node_name_sz;
                 *paths_buf.cur++ = '/';
                 *paths_buf.cur++ = '\0';
             }
             else
             {
-                dtb_node->path = RT_NULL;
-                rt_kprintf("\033[31m\rERROR: `FDT_DTB_ALL_NODES_PATH_SIZE' = %d bytes is configured too low.\033[0m\n", FDT_DTB_ALL_NODES_PATH_SIZE);
+                dtb_node->path = NULL;
+                printf("\033[31m\rERROR: `FDT_DTB_ALL_NODES_PATH_SIZE' = %d bytes is configured too low.\033[0m\n", FDT_DTB_ALL_NODES_PATH_SIZE);
                 return FDT_RET_NO_MEMORY;
             }
 
             dtb_node->handle = fdt_get_phandle(current_fdt, node_off);
-            dtb_node->properties = (struct dtb_property *)rt_malloc(sizeof(struct dtb_property));
-            dtb_node->child = (struct dtb_node *)rt_malloc(sizeof(struct dtb_node));
+            dtb_node->properties = (struct dtb_property *)malloc(sizeof(struct dtb_property));
+            dtb_node->child = (struct dtb_node *)malloc(sizeof(struct dtb_node));
 
-            if (dtb_node->properties == RT_NULL || dtb_node->child == RT_NULL)
+            if (dtb_node->properties == NULL || dtb_node->child == NULL)
             {
                 return FDT_RET_NO_MEMORY;
             }
 
-            fdt_exec_status = _fdt_get_dtb_properties_list(dtb_node->properties, node_off);
+            fdt_exec_status = _dtb_node_get_dtb_properties_list(dtb_node->properties, node_off);
             if (fdt_exec_status == FDT_RET_GET_EMPTY)
             {
-                rt_free(dtb_node->properties);
-                dtb_node->properties = RT_NULL;
+                free(dtb_node->properties);
+                dtb_node->properties = NULL;
             }
             else if (fdt_exec_status != FDT_RET_GET_OK)
             {
                 return fdt_exec_status;
             }
 
-            fdt_exec_status = _fdt_get_dtb_nodes_list(dtb_node, dtb_node->child, dtb_node->path);
+            fdt_exec_status = _dtb_node_get_dtb_nodes_list(dtb_node, dtb_node->child, dtb_node->path);
             if (fdt_exec_status == FDT_RET_GET_EMPTY)
             {
-                rt_free(dtb_node->child);
-                dtb_node->child = RT_NULL;
+                free(dtb_node->child);
+                dtb_node->child = NULL;
             }
             else if (fdt_exec_status != FDT_RET_GET_OK)
             {
@@ -133,8 +147,8 @@ static rt_err_t _fdt_get_dtb_nodes_list(struct dtb_node *dtb_node_head, struct d
             node_off = fdt_next_subnode(current_fdt, node_off);
             if (node_off >= 0)
             {
-                dtb_node->sibling = (struct dtb_node *)rt_malloc(sizeof(struct dtb_node));
-                if (dtb_node->sibling == RT_NULL)
+                dtb_node->sibling = (struct dtb_node *)malloc(sizeof(struct dtb_node));
+                if (dtb_node->sibling == NULL)
                 {
                     return FDT_RET_NO_MEMORY;
                 }
@@ -150,12 +164,12 @@ static rt_err_t _fdt_get_dtb_nodes_list(struct dtb_node *dtb_node_head, struct d
     return FDT_RET_GET_OK;
 }
 
-struct dtb_node *fdt_get_dtb_list(void *fdt)
+struct dtb_node *dtb_node_get_dtb_list(void *fdt)
 {
     int root_off;
-    struct dtb_node *dtb_node_head = RT_NULL;
+    struct dtb_node *dtb_node_head = NULL;
 
-    if (fdt == RT_NULL)
+    if (fdt == NULL)
     {
         fdt_exec_status = FDT_RET_NO_LOADED;
         goto fail;
@@ -163,16 +177,16 @@ struct dtb_node *fdt_get_dtb_list(void *fdt)
 
     current_fdt = fdt;
 
-    if ((dtb_node_head = (struct dtb_node *)rt_malloc(sizeof(struct dtb_node))) == RT_NULL)
+    if ((dtb_node_head = (struct dtb_node *)malloc(sizeof(struct dtb_node))) == NULL)
     {
         fdt_exec_status = FDT_RET_NO_MEMORY;
         goto fail;
     }
 
-    if (paths_buf.ptr == RT_NULL)
+    if (paths_buf.ptr == NULL)
     {
-        paths_buf.ptr = rt_malloc(FDT_DTB_ALL_NODES_PATH_SIZE);
-        if (paths_buf.ptr == RT_NULL)
+        paths_buf.ptr = malloc(FDT_DTB_ALL_NODES_PATH_SIZE);
+        if (paths_buf.ptr == NULL)
         {
             fdt_exec_status = FDT_RET_NO_MEMORY;
             goto fail;
@@ -183,7 +197,7 @@ struct dtb_node *fdt_get_dtb_list(void *fdt)
 
     root_off = fdt_path_offset(fdt, "/");
 
-    if ((dtb_node_head->header = rt_malloc(sizeof(struct dtb_header))) == RT_NULL)
+    if ((dtb_node_head->header = malloc(sizeof(struct dtb_header))) == NULL)
     {
         fdt_exec_status = FDT_RET_NO_MEMORY;
         goto fail;
@@ -198,11 +212,11 @@ struct dtb_node *fdt_get_dtb_list(void *fdt)
         {
             int i;
             int memreserve_sz = dtb_node_head->header->memreserve_sz;
-            rt_uint32_t off_mem_rsvmap = fdt_off_mem_rsvmap(fdt);
+            uint32_t off_mem_rsvmap = fdt_off_mem_rsvmap(fdt);
             struct fdt_reserve_entry *rsvmap = (struct fdt_reserve_entry *)((char *)fdt + off_mem_rsvmap);
 
-            ((struct dtb_header *)dtb_node_head->header)->memreserve = rt_malloc(sizeof(struct dtb_memreserve) * memreserve_sz);
-            if (dtb_node_head->header->memreserve == RT_NULL)
+            ((struct dtb_header *)dtb_node_head->header)->memreserve = malloc(sizeof(struct dtb_memreserve) * memreserve_sz);
+            if (dtb_node_head->header->memreserve == NULL)
             {
                 fdt_exec_status = FDT_RET_NO_MEMORY;
                 goto fail;
@@ -215,112 +229,113 @@ struct dtb_node *fdt_get_dtb_list(void *fdt)
         }
         else
         {
-            ((struct dtb_header *)dtb_node_head->header)->memreserve = RT_NULL;
+            ((struct dtb_header *)dtb_node_head->header)->memreserve = NULL;
         }
     }
 
     dtb_node_head->path = paths_buf.ptr;
     *paths_buf.cur++ = '/';
     *paths_buf.cur++ = '\0';
-    dtb_node_head->parent = RT_NULL;
-    dtb_node_head->sibling = RT_NULL;
+    dtb_node_head->parent = NULL;
+    dtb_node_head->sibling = NULL;
 
     dtb_node_head->handle = fdt_get_phandle(fdt, root_off);
-    dtb_node_head->properties = (struct dtb_property *)rt_malloc(sizeof(struct dtb_property));
-    dtb_node_head->child = (struct dtb_node *)rt_malloc(sizeof(struct dtb_node));
+    dtb_node_head->properties = (struct dtb_property *)malloc(sizeof(struct dtb_property));
+    dtb_node_head->child = (struct dtb_node *)malloc(sizeof(struct dtb_node));
 
-    if (dtb_node_head->properties == RT_NULL || dtb_node_head->child == RT_NULL)
+    if (dtb_node_head->properties == NULL || dtb_node_head->child == NULL)
     {
         fdt_exec_status = FDT_RET_NO_MEMORY;
         goto fail;
     }
 
-    if ((fdt_exec_status = _fdt_get_dtb_properties_list(dtb_node_head->properties, root_off)) != FDT_RET_GET_OK)
+    if ((fdt_exec_status = _dtb_node_get_dtb_properties_list(dtb_node_head->properties, root_off)) != FDT_RET_GET_OK)
     {
         goto fail;
     }
 
-    if ((fdt_exec_status = _fdt_get_dtb_nodes_list(dtb_node_head, dtb_node_head->child, dtb_node_head->path)) != FDT_RET_GET_OK)
+    if ((fdt_exec_status = _dtb_node_get_dtb_nodes_list(dtb_node_head, dtb_node_head->child, dtb_node_head->path)) != FDT_RET_GET_OK)
     {
         goto fail;
     }
 
     /* paths_buf.ptr addr save in the dtb_node_head's path */
-    paths_buf.ptr = RT_NULL;
-    paths_buf.cur = RT_NULL;
+    paths_buf.ptr = NULL;
+    paths_buf.cur = NULL;
 
     return dtb_node_head;
 
 fail:
-    if (dtb_node_head != RT_NULL)
+    if (dtb_node_head != NULL)
     {
-        fdt_free_dtb_list(dtb_node_head);
+        dtb_node_free_dtb_list(dtb_node_head);
     }
 
-    return RT_NULL;
+    return NULL;
 }
 
-static void _fdt_free_dtb_node(struct dtb_node *dtb_node)
+static void _dtb_node_free_dtb_node(struct dtb_node *dtb_node)
 {
     struct dtb_node *dtb_node_last;
     struct dtb_property *dtb_property;
     struct dtb_property *dtb_property_last;
 
-    while (dtb_node != RT_NULL)
+    while (dtb_node != NULL)
     {
         dtb_property = dtb_node->properties;
-        while (dtb_property != RT_NULL)
+        while (dtb_property != NULL)
         {
             dtb_property_last = dtb_property;
             dtb_property = dtb_property->next;
-            rt_free(dtb_property_last);
+            free(dtb_property_last);
         }
 
-        _fdt_free_dtb_node(dtb_node->child);
+        _dtb_node_free_dtb_node(dtb_node->child);
 
         dtb_node_last = dtb_node;
         dtb_node = dtb_node->sibling;
-        rt_free(dtb_node_last);
+        free(dtb_node_last);
     }
 }
 
-void fdt_free_dtb_list(struct dtb_node *dtb_node_head)
+void dtb_node_free_dtb_list(struct dtb_node *dtb_node_head)
 {
-    if (dtb_node_head == RT_NULL)
+    if (dtb_node_head == NULL)
     {
         return;
     }
 
     /* only root node can free all path buffer */
-    if (dtb_node_head->parent == RT_NULL || (dtb_node_head->path != RT_NULL && !rt_strcmp(dtb_node_head->path, "/")))
+    if (dtb_node_head->parent == NULL || (dtb_node_head->path != NULL && !strcmp(dtb_node_head->path, "/")))
     {
-        if (dtb_node_head->path != RT_NULL)
+        if (dtb_node_head->path != NULL)
         {
-            rt_free((void *)dtb_node_head->path);
+            free((void *)dtb_node_head->path);
         }
-        if (dtb_node_head->header != RT_NULL)
+        if (dtb_node_head->header != NULL)
         {
-            if (dtb_node_head->header->memreserve != RT_NULL)
+            if (dtb_node_head->header->memreserve != NULL)
             {
-                rt_free((void *)dtb_node_head->header->memreserve);
+                free((void *)dtb_node_head->header->memreserve);
             }
-            rt_free((void *)dtb_node_head->header);
+            free((void *)dtb_node_head->header);
         }
     }
 
-    _fdt_free_dtb_node(dtb_node_head);
+    _dtb_node_free_dtb_node(dtb_node_head);
 }
 
-static void _fdt_printf_depth(int depth)
+static void _dtb_node_printf_depth(int depth)
 {
     int i = depth;
     while (i --> 0)
     {
-        rt_kputs("\t");
+        puts("\t");
     }
 }
 
-static rt_bool_t _fdt_test_string_list(const void *value, int size)
+//static bool _dtb_node_test_string_list(const void *value, int size)
+bool _dtb_node_test_string_list(const void *value, int size)
 {
     const char *str = value;
     const char *str_start, *str_end;
@@ -361,43 +376,43 @@ static rt_bool_t _fdt_test_string_list(const void *value, int size)
     return RT_TRUE;
 }
 
-static void _fdt_printf_dtb_node_info(struct dtb_node *dtb_node)
+static void _dtb_node_printf_dtb_node_info(struct dtb_node *dtb_node)
 {
     static int depth = 0;
     struct dtb_property *dtb_property;
 
-    while (dtb_node != RT_NULL)
+    while (dtb_node != NULL)
     {
-        rt_kputs("\n");
-        _fdt_printf_depth(depth);
-        rt_kputs(dtb_node->name);
-        rt_kputs(" {\n");
+        puts("\n");
+        _dtb_node_printf_depth(depth);
+        puts(dtb_node->name);
+        puts(" {\n");
         ++depth;
 
         dtb_property = dtb_node->properties;
-        while (dtb_property != RT_NULL)
+        while (dtb_property != NULL)
         {
-            _fdt_printf_depth(depth);
+            _dtb_node_printf_depth(depth);
 
-            rt_kputs(dtb_property->name);
+            puts(dtb_property->name);
 
             if (dtb_property->size > 0)
             {
                 int size = dtb_property->size;
                 char *value = dtb_property->value;
 
-                rt_kputs(" = ");
-                if (_fdt_test_string_list(value, size) == RT_TRUE)
+                puts(" = ");
+                if (_dtb_node_test_string_list(value, size) == RT_TRUE)
                 {
                     /* print string list */
                     char *str = value;
                     do
                     {
-                        rt_kprintf("\"%s\"", str);
-                        str += rt_strlen(str) + 1;
-                        rt_kputs(", ");
+                        printf("\"%s\"", str);
+                        str += strlen(str) + 1;
+                        puts(", ");
                     } while (str < value + size);
-                    rt_kputs("\b\b");
+                    puts("\b\b");
                 }
                 else if ((size % 4) == 0)
                 {
@@ -405,116 +420,108 @@ static void _fdt_printf_dtb_node_info(struct dtb_node *dtb_node)
                     int i;
                     fdt32_t *cell = (fdt32_t *)value;
 
-                    rt_kputs("<");
+                    puts("<");
                     for (i = 0, size /= 4; i < size; ++i)
                     {
-                        rt_kprintf("0x%x ", fdt32_to_cpu(cell[i]));
+                        printf("0x%x ", fdt32_to_cpu(cell[i]));
                     }
-                    rt_kputs("\b>");
+                    puts("\b>");
                 }
                 else
                 {
                     /* print bytes array */
                     int i;
-                    rt_uint8_t *byte = (rt_uint8_t *)value;
+                    uint8_t *byte = (uint8_t *)value;
 
-                    rt_kputs("[");
+                    puts("[");
                     for (i = 0; i < size; ++i)
                     {
-                       rt_kprintf("%02x ", *byte++);
+                       printf("%02x ", *byte++);
                     }
-                    rt_kputs("\b]");
+                    puts("\b]");
                 }
             }
-            rt_kputs(";\n");
+            puts(";\n");
             dtb_property = dtb_property->next;
         }
 
-        _fdt_printf_dtb_node_info(dtb_node->child);
+        _dtb_node_printf_dtb_node_info(dtb_node->child);
         dtb_node = dtb_node->sibling;
 
         --depth;
-        _fdt_printf_depth(depth);
-        rt_kputs("};\n");
+        _dtb_node_printf_depth(depth);
+        puts("};\n");
     }
 }
 
-void fdt_get_dts_dump(struct dtb_node *dtb_node_head)
+void dtb_node_get_dts_dump(struct dtb_node *dtb_node_head)
 {
-    if (dtb_node_head != RT_NULL)
+    if (dtb_node_head != NULL)
     {
         int i = dtb_node_head->header->memreserve_sz;
 
-        rt_kputs("/dts-v1/;\n");
-
+        puts("/dts-v1/;\n");
         while (i --> 0)
         {
-            if (IN_64BITS_MODE)
-            {
-                rt_kprintf("\n/memreserve/\t0x%016x 0x%016x;", dtb_node_head->header->memreserve[i].address, dtb_node_head->header->memreserve[i].size);
-            }
-            else
-            {
-                rt_kprintf("\n/memreserve/\t0x%08x%08x 0x%08x%08x;", dtb_node_head->header->memreserve[i].address, dtb_node_head->header->memreserve[i].size);
-            }
+            printf("\n/memreserve/\t0x%lx 0x%zx;", dtb_node_head->header->memreserve[i].address, dtb_node_head->header->memreserve[i].size);
         }
 
-        _fdt_printf_dtb_node_info(dtb_node_head);
+        _dtb_node_printf_dtb_node_info(dtb_node_head);
     }
 }
 
-static void _fdt_get_enum_dtb_node(struct dtb_node *dtb_node, void (callback(struct dtb_node *dtb_node)))
+static void _dtb_node_get_enum_dtb_node(struct dtb_node *dtb_node, void (callback(struct dtb_node *dtb_node)))
 {
-    while (dtb_node != RT_NULL)
+    while (dtb_node != NULL)
     {
         callback(dtb_node);
-        _fdt_get_enum_dtb_node(dtb_node->child, callback);
+        _dtb_node_get_enum_dtb_node(dtb_node->child, callback);
         dtb_node = dtb_node->sibling;
     }
 }
 
-void fdt_get_enum_dtb_node(struct dtb_node *dtb_node_head, void (callback(struct dtb_node *dtb_node)))
+void dtb_node_get_enum_dtb_node(struct dtb_node *dtb_node_head, void (callback(struct dtb_node *dtb_node)))
 {
-    if (dtb_node_head == RT_NULL || callback == RT_NULL)
+    if (dtb_node_head == NULL || callback == NULL)
     {
         return;
     }
 
-    _fdt_get_enum_dtb_node(dtb_node_head, callback);
+    _dtb_node_get_enum_dtb_node(dtb_node_head, callback);
 }
 
-struct dtb_node *fdt_get_dtb_node_by_name_DFS(struct dtb_node *dtb_node, const char *nodename)
+struct dtb_node *dtb_node_get_dtb_node_by_name_DFS(struct dtb_node *dtb_node, const char *nodename)
 {
     struct dtb_node *dtb_node_child;
 
-    while (dtb_node != RT_NULL)
+    while (dtb_node != NULL)
     {
-        if (!rt_strcmp(nodename, dtb_node->name))
+        if (!strcmp(nodename, dtb_node->name))
         {
             return dtb_node;
         }
 
-        dtb_node_child = fdt_get_dtb_node_by_name_DFS(dtb_node->child, nodename);
+        dtb_node_child = dtb_node_get_dtb_node_by_name_DFS(dtb_node->child, nodename);
 
-        if (dtb_node_child != RT_NULL)
+        if (dtb_node_child != NULL)
         {
             return dtb_node_child;
         }
         dtb_node = dtb_node->sibling;
     }
 
-    return RT_NULL;
+    return NULL;
 }
 
-struct dtb_node *fdt_get_dtb_node_by_name_BFS(struct dtb_node *dtb_node, const char *nodename)
+struct dtb_node *dtb_node_get_dtb_node_by_name_BFS(struct dtb_node *dtb_node, const char *nodename)
 {
-    if (dtb_node != RT_NULL)
+    if (dtb_node != NULL)
     {
         struct dtb_node *dtb_node_child, *dtb_node_head = dtb_node;
 
-        while (dtb_node != RT_NULL)
+        while (dtb_node != NULL)
         {
-            if (!rt_strcmp(nodename, dtb_node->name))
+            if (!strcmp(nodename, dtb_node->name))
             {
                 return dtb_node;
             }
@@ -523,11 +530,11 @@ struct dtb_node *fdt_get_dtb_node_by_name_BFS(struct dtb_node *dtb_node, const c
 
         dtb_node = dtb_node_head;
 
-        while (dtb_node != RT_NULL)
+        while (dtb_node != NULL)
         {
-            dtb_node_child = fdt_get_dtb_node_by_name_BFS(dtb_node->child, nodename);
+            dtb_node_child = dtb_node_get_dtb_node_by_name_BFS(dtb_node->child, nodename);
 
-            if (dtb_node_child != RT_NULL)
+            if (dtb_node_child != NULL)
             {
                 return dtb_node_child;
             }
@@ -535,19 +542,19 @@ struct dtb_node *fdt_get_dtb_node_by_name_BFS(struct dtb_node *dtb_node, const c
         }
     }
 
-    return RT_NULL;
+    return NULL;
 }
 
-struct dtb_node *fdt_get_dtb_node_by_path(struct dtb_node *dtb_node, const char *pathname)
+struct dtb_node *dtb_node_get_dtb_node_by_path(struct dtb_node *dtb_node, const char *pathname)
 {
     int i = 0;
     char *node_name;
     char *pathname_clone;
     int pathname_sz;
 
-    if (pathname == RT_NULL || dtb_node == RT_NULL)
+    if (pathname == NULL || dtb_node == NULL)
     {
-        return RT_NULL;
+        return NULL;
     }
 
     /* skip '/' */
@@ -557,18 +564,18 @@ struct dtb_node *fdt_get_dtb_node_by_path(struct dtb_node *dtb_node, const char
     }
 
     /* root not have sibling, so skip */
-    if (dtb_node->parent == RT_NULL || !rt_strcmp(dtb_node->path, "/"))
+    if (dtb_node->parent == NULL || !strcmp(dtb_node->path, "/"))
     {
         dtb_node = dtb_node->child;
     }
 
-    pathname_sz = rt_strlen(pathname) + 1;
-    pathname_clone = rt_malloc(pathname_sz);
-    if (pathname_clone == RT_NULL)
+    pathname_sz = strlen(pathname) + 1;
+    pathname_clone = malloc(pathname_sz);
+    if (pathname_clone == NULL)
     {
-        return RT_NULL;
+        return NULL;
     }
-    rt_strncpy(pathname_clone, pathname, pathname_sz);
+    strncpy(pathname_clone, pathname, pathname_sz);
     node_name = pathname_clone;
 
     while (pathname_clone[i])
@@ -578,18 +585,18 @@ struct dtb_node *fdt_get_dtb_node_by_path(struct dtb_node *dtb_node, const char
             /* set an end of name that can used to strcmp */
             pathname_clone[i] = '\0';
 
-            while (dtb_node != RT_NULL)
+            while (dtb_node != NULL)
             {
-                if (!rt_strcmp(dtb_node->name, node_name))
+                if (!strcmp(dtb_node->name, node_name))
                 {
                     break;
                 }
                 dtb_node = dtb_node->sibling;
             }
-            if (dtb_node == RT_NULL)
+            if (dtb_node == NULL)
             {
-                rt_free(pathname_clone);
-                return RT_NULL;
+                free(pathname_clone);
+                return NULL;
             }
             dtb_node = dtb_node->child;
             node_name = &pathname_clone[i + 1];
@@ -603,50 +610,50 @@ struct dtb_node *fdt_get_dtb_node_by_path(struct dtb_node *dtb_node, const char
      *      (&pathname_clone[i] - node_name) is the node_name's length
      */
     node_name = &((char *)pathname)[(pathname_sz - 1) - (&pathname_clone[i] - node_name)];
-    rt_free(pathname_clone);
+    free(pathname_clone);
 
-    while (dtb_node != RT_NULL)
+    while (dtb_node != NULL)
     {
-        if (!rt_strcmp(dtb_node->name, node_name))
+        if (!strcmp(dtb_node->name, node_name))
         {
             return dtb_node;
         }
         dtb_node = dtb_node->sibling;
     }
 
-    return RT_NULL;
+    return NULL;
 }
 
-struct dtb_node *fdt_get_dtb_node_by_phandle_DFS(struct dtb_node *dtb_node, phandle handle)
+struct dtb_node *dtb_node_get_dtb_node_by_phandle_DFS(struct dtb_node *dtb_node, phandle handle)
 {
     struct dtb_node *dtb_node_child;
 
-    while (dtb_node != RT_NULL)
+    while (dtb_node != NULL)
     {
         if (dtb_node->handle == handle)
         {
             return dtb_node;
         }
 
-        dtb_node_child = fdt_get_dtb_node_by_phandle_DFS(dtb_node->child, handle);
+        dtb_node_child = dtb_node_get_dtb_node_by_phandle_DFS(dtb_node->child, handle);
 
-        if (dtb_node_child != RT_NULL)
+        if (dtb_node_child != NULL)
         {
             return dtb_node_child;
         }
         dtb_node = dtb_node->sibling;
     }
 
-    return RT_NULL;
+    return NULL;
 }
 
-struct dtb_node *fdt_get_dtb_node_by_phandle_BFS(struct dtb_node *dtb_node, phandle handle)
+struct dtb_node *dtb_node_get_dtb_node_by_phandle_BFS(struct dtb_node *dtb_node, phandle handle)
 {
-    if (dtb_node != RT_NULL)
+    if (dtb_node != NULL)
     {
         struct dtb_node *dtb_node_child, *dtb_node_head = dtb_node;
 
-        while (dtb_node != RT_NULL)
+        while (dtb_node != NULL)
         {
             if (dtb_node->handle == handle)
             {
@@ -657,11 +664,11 @@ struct dtb_node *fdt_get_dtb_node_by_phandle_BFS(struct dtb_node *dtb_node, phan
 
         dtb_node = dtb_node_head;
 
-        while (dtb_node != RT_NULL)
+        while (dtb_node != NULL)
         {
-            dtb_node_child = fdt_get_dtb_node_by_phandle_BFS(dtb_node->child, handle);
+            dtb_node_child = dtb_node_get_dtb_node_by_phandle_BFS(dtb_node->child, handle);
 
-            if (dtb_node_child != RT_NULL)
+            if (dtb_node_child != NULL)
             {
                 return dtb_node_child;
             }
@@ -669,28 +676,28 @@ struct dtb_node *fdt_get_dtb_node_by_phandle_BFS(struct dtb_node *dtb_node, phan
         }
     }
 
-    return RT_NULL;
+    return NULL;
 }
 
-void fdt_get_dtb_node_cells(struct dtb_node *dtb_node, int *addr_cells, int *size_cells)
+void dtb_node_get_dtb_node_cells(struct dtb_node *dtb_node, int *addr_cells, int *size_cells)
 {
-    if (dtb_node != RT_NULL && addr_cells != RT_NULL && size_cells != RT_NULL)
+    if (dtb_node != NULL && addr_cells != NULL && size_cells != NULL)
     {
         struct dtb_property *dtb_property;
         *addr_cells = -1;
         *size_cells = -1;
 
         /* if couldn't found, check parent */
-        while ((dtb_node = dtb_node->parent) != RT_NULL)
+        while ((dtb_node = dtb_node->parent) != NULL)
         {
             dtb_property = dtb_node->properties;
-            while (dtb_property != RT_NULL)
+            while (dtb_property != NULL)
             {
-                if (!rt_strcmp(dtb_property->name, "#address-cells"))
+                if (!strcmp(dtb_property->name, "#address-cells"))
                 {
                     *addr_cells = fdt32_to_cpu(*(int *)dtb_property->value);
                 }
-                else if (!rt_strcmp(dtb_property->name, "#size-cells"))
+                else if (!strcmp(dtb_property->name, "#size-cells"))
                 {
                     *size_cells = fdt32_to_cpu(*(int *)dtb_property->value);
                 }
@@ -713,38 +720,15 @@ void fdt_get_dtb_node_cells(struct dtb_node *dtb_node, int *addr_cells, int *siz
     }
 }
 
-void *fdt_get_dtb_node_property(struct dtb_node *dtb_node, const char *property_name, rt_size_t *property_size)
+struct dtb_memreserve *dtb_node_get_dtb_memreserve(struct dtb_node *dtb_node, int *memreserve_size)
 {
-    if (dtb_node != RT_NULL && property_name != RT_NULL)
-    {
-        struct dtb_property *dtb_property = dtb_node->properties;
-
-        while (dtb_property != RT_NULL)
-        {
-            if (!rt_strcmp(dtb_property->name, property_name))
-            {
-                if (property_size != RT_NULL)
-                {
-                    *property_size = dtb_property->size;
-                }
-                return dtb_property->value;
-            }
-            dtb_property = dtb_property->next;
-        }
-    }
-
-    return RT_NULL;
-}
-
-struct dtb_memreserve *fdt_get_dtb_memreserve(struct dtb_node *dtb_node, int *memreserve_size)
-{
-    if (dtb_node != RT_NULL && memreserve_size != RT_NULL)
+    if (dtb_node != NULL && memreserve_size != NULL)
     {
         struct dtb_node *dtb_node_root = dtb_node;
 
-        while (dtb_node_root != RT_NULL)
+        while (dtb_node_root != NULL)
         {
-            if (!rt_strcmp(dtb_node_root->path, "/"))
+            if (!strcmp(dtb_node_root->path, "/"))
             {
                 break;
             }
@@ -755,17 +739,17 @@ struct dtb_memreserve *fdt_get_dtb_memreserve(struct dtb_node *dtb_node, int *me
 
         return dtb_node_root->header->memreserve;
     }
-    return RT_NULL;
+    return NULL;
 }
 
-rt_bool_t fdt_get_dtb_node_status(struct dtb_node *dtb_node)
+bool dtb_node_get_dtb_node_status(const struct dtb_node *dtb_node)
 {
-    if (dtb_node != RT_NULL)
+    if (dtb_node != NULL)
     {
-        char *status = fdt_get_dtb_node_property(dtb_node, "status", RT_NULL);
-        if (status != RT_NULL)
+        char *status = dtb_node_get_dtb_node_property_value(dtb_node, "status", NULL);
+        if (status != NULL)
         {
-            return (!rt_strcmp(status, "okay") || !rt_strcmp(status, "ok")) ? RT_TRUE : RT_FALSE;
+            return (!strcmp(status, "okay") || !strcmp(status, "ok")) ? RT_TRUE : RT_FALSE;
         }
 
         return RT_TRUE;
@@ -774,34 +758,34 @@ rt_bool_t fdt_get_dtb_node_status(struct dtb_node *dtb_node)
     return RT_FALSE;
 }
 
-rt_bool_t fdt_get_dtb_node_compatible_match(struct dtb_node *dtb_node, char **compatibles)
+bool dtb_node_get_dtb_node_compatible_match(const struct dtb_node *dtb_node, const char *compatibles)
 {
-    if (dtb_node != RT_NULL)
+    if (dtb_node != NULL)
     {
-        while (*compatibles != RT_NULL)
+        if (compatibles != NULL)
         {
             char *str_ptr;
-            rt_size_t prop_sz;
+            int prop_sz;
+
             for_each_property_string(dtb_node, "compatible", str_ptr, prop_sz)
             {
-                if (!rt_strcmp(*compatibles, str_ptr))
+                if (!strcmp(compatibles, str_ptr))
                 {
                     return RT_TRUE;
                 }
             }
-            ++compatibles;
         }
     }
 
     return RT_FALSE;
 }
 
-char *fdt_get_dtb_string_list_value(void *value, int size, int index)
+char *dtb_node_get_dtb_string_list_value(void *value, int size, int index)
 {
     int i = 0;
     char *str = value;
 
-    if (str != RT_NULL)
+    if (str != NULL)
     {
         do
         {
@@ -809,35 +793,35 @@ char *fdt_get_dtb_string_list_value(void *value, int size, int index)
             {
                 return str;
             }
-            str += rt_strlen(str) + 1;
+            str += strlen(str) + 1;
         } while (str < (char *)value + size);
     }
 
-    return RT_NULL;
+    return NULL;
 }
 
-char *fdt_get_dtb_string_list_value_next(void *value, void *end)
+char *dtb_node_get_dtb_string_list_value_next(void *value, void *end)
 {
     char *str = value;
 
-    if (str != RT_NULL)
+    if (str != NULL)
     {
-        str += rt_strlen(str) + 1;
+        str += strlen(str) + 1;
         if (str < (char *)end)
         {
             return str;
         }
     }
 
-    return RT_NULL;
+    return NULL;
 }
 
-rt_uint32_t fdt_get_dtb_cell_value(void *value)
+uint32_t dtb_node_get_dtb_cell_value(void *value)
 {
     return fdt32_to_cpu(*(fdt32_t *)value);
 }
 
-rt_uint8_t fdt_get_dtb_byte_value(void *value)
+uint8_t dtb_node_get_dtb_byte_value(void *value)
 {
-    return *(rt_uint8_t *)value;
+    return *(uint8_t *)value;
 }

+ 42 - 0
src/dtb_head.c

@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2006-2022, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+#include "dtb_node.h"
+#include "dtb_head.h"
+
+static void *fdt = NULL;
+static struct dtb_node *dtb_node_list = NULL;
+void *get_fdt_blob(void)
+{
+    return fdt;
+}
+
+struct dtb_node *get_dtb_node_head(void)
+{
+    return dtb_node_list;
+}
+
+bool dtb_node_active(void)
+{
+    return dtb_node_list != NULL;
+}
+
+int device_tree_setup(void *mem_addr)
+{
+    if(mem_addr)
+    {
+        if ((fdt = dtb_node_load_from_memory(mem_addr,1)) != NULL)
+        {
+            dtb_node_list = dtb_node_get_dtb_list(fdt);
+            if (dtb_node_list != NULL)
+            {
+                return -1;
+            }
+        }
+        return 0;
+    }
+
+    return -1;
+}

+ 33 - 21
src/fdt_load.c → src/dtb_load.c

@@ -1,24 +1,36 @@
-#include <rthw.h>
+/*
+ * Copyright (c) 2006-2022, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
 #include <unistd.h>
 #include <fcntl.h>
 
 #include "libfdt/libfdt.h"
-#include "fdt.h"
+#include "dtb_node.h"
 
-extern rt_err_t fdt_exec_status;
+#include <stdio.h>
+#include <string.h>
+#include <stdbool.h>
+#include <stdlib.h>
 
-rt_inline rt_bool_t fdt_check(void *fdt)
+#define RT_TRUE     true
+#define RT_FALSE    false
+
+extern int fdt_exec_status;
+
+bool dtb_node_check(void *fdt)
 {
     return fdt_check_header(fdt) == 0 ? RT_TRUE : RT_FALSE;
 }
 
-void *fdt_load_from_fs(char *dtb_filename)
+void *dtb_node_load_from_fs(char *dtb_filename)
 {
-    void *fdt = RT_NULL;
-    rt_size_t dtb_sz;
+    void *fdt = NULL;
+    size_t dtb_sz;
     int fd = -1;
 
-    if (dtb_filename == RT_NULL)
+    if (dtb_filename == NULL)
     {
         fdt_exec_status = FDT_RET_GET_EMPTY;
         goto end;
@@ -28,7 +40,7 @@ void *fdt_load_from_fs(char *dtb_filename)
 
     if (fd == -1)
     {
-        rt_kprintf("File `%s' not found.\n", dtb_filename);
+        printf("File `%s' not found.\n", dtb_filename);
         fdt_exec_status = FDT_RET_GET_EMPTY;
         goto end;
     }
@@ -37,18 +49,18 @@ void *fdt_load_from_fs(char *dtb_filename)
 
     if (dtb_sz > 0)
     {
-        if ((fdt = (struct fdt_header *)rt_malloc(sizeof(rt_uint8_t) * dtb_sz)) == RT_NULL)
+        if ((fdt = (struct fdt_header *)malloc(sizeof(uint8_t) * dtb_sz)) == NULL)
         {
             fdt_exec_status = FDT_RET_NO_MEMORY;
             goto end;
         }
 
         lseek(fd, 0, SEEK_SET);
-        read(fd, fdt, sizeof(rt_uint8_t) * dtb_sz);
+        read(fd, fdt, sizeof(uint8_t) * dtb_sz);
 
-        if (fdt_check(fdt) == RT_FALSE)
+        if (dtb_node_check(fdt) == RT_FALSE)
         {
-            rt_free(fdt);
+            free(fdt);
         }
     }
 
@@ -61,31 +73,31 @@ end:
     return fdt;
 }
 
-void *fdt_load_from_memory(void *dtb_ptr, rt_bool_t is_clone)
+void *dtb_node_load_from_memory(void *dtb_ptr, bool is_clone)
 {
-    void *fdt = RT_NULL;
+    void *fdt = NULL;
 
-    if (dtb_ptr == RT_NULL)
+    if (dtb_ptr == NULL)
     {
         fdt_exec_status = FDT_RET_GET_EMPTY;
         goto end;
     }
 
-    if (fdt_check(dtb_ptr) == RT_FALSE)
+    if (dtb_node_check(dtb_ptr) == RT_FALSE)
     {
         fdt_exec_status = FDT_RET_GET_EMPTY;
-        fdt = RT_NULL;
+        fdt = NULL;
         goto end;
     }
 
     if (is_clone)
     {
-        rt_size_t dtb_sz = fdt_totalsize(dtb_ptr);
+        size_t dtb_sz = fdt_totalsize(dtb_ptr);
         if (dtb_sz > 0)
         {
-            if ((fdt = rt_malloc(dtb_sz)) != RT_NULL)
+            if ((fdt = malloc(dtb_sz)) != NULL)
             {
-                rt_memcpy(fdt, dtb_ptr, dtb_sz);
+                memcpy(fdt, dtb_ptr, dtb_sz);
             }
             else
             {

+ 33 - 21
src/fdt_set.c → src/dtb_set.c

@@ -1,9 +1,21 @@
+/*
+ * Copyright (c) 2006-2022, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
 #include "libfdt/libfdt.h"
-#include "fdt.h"
+#include "dtb_node.h"
 
-static rt_off_t fdt_find_and_add_subnode(void *fdt, char* name)
+#include <string.h>
+#include <stdbool.h>
+#include <stdlib.h>
+
+#define RT_TRUE     true
+#define RT_FALSE    false
+
+static off_t dtb_node_find_and_add_subnode(void *fdt, char* name)
 {
-    rt_off_t chosen_offset = 0;
+    off_t chosen_offset = 0;
 
     chosen_offset = fdt_subnode_offset(fdt, 0, name);
 
@@ -15,18 +27,18 @@ static rt_off_t fdt_find_and_add_subnode(void *fdt, char* name)
     return chosen_offset;
 }
 
-rt_size_t fdt_set_linux_cmdline(void *fdt, char *cmdline)
+size_t dtb_node_set_linux_cmdline(void *fdt, char *cmdline)
 {
-    rt_off_t chosen_offset;
-    rt_size_t cmdline_size;
+    off_t chosen_offset;
+    size_t cmdline_size;
 
-    if (cmdline == RT_NULL || fdt == RT_NULL)
+    if (cmdline == NULL || fdt == NULL)
     {
         goto end;
     }
 
-    chosen_offset = fdt_find_and_add_subnode(fdt, "chosen");
-    cmdline_size = rt_strlen(cmdline);
+    chosen_offset = dtb_node_find_and_add_subnode(fdt, "chosen");
+    cmdline_size = strlen(cmdline);
 
     /* install bootargs */
     if (chosen_offset >= 0 || chosen_offset == -FDT_ERR_EXISTS)
@@ -42,18 +54,18 @@ end:
     return fdt_totalsize(fdt);
 }
 
-rt_size_t fdt_set_linux_initrd(void *fdt, rt_uint64_t initrd_addr, rt_size_t initrd_size)
+size_t dtb_node_set_linux_initrd(void *fdt, uint64_t initrd_addr, size_t initrd_size)
 {
-    rt_uint64_t addr, size_ptr;
-    rt_off_t chosen_offset;
+    uint64_t addr, size_ptr;
+    off_t chosen_offset;
     int i;
 
-    if (fdt == RT_NULL)
+    if (fdt == NULL)
     {
         goto end;
     }
 
-    chosen_offset = fdt_find_and_add_subnode(fdt, "chosen");
+    chosen_offset = dtb_node_find_and_add_subnode(fdt, "chosen");
 
     /* update the entry */
     for (i = fdt_num_mem_rsv(fdt) - 1; i >= 0; --i)
@@ -98,11 +110,11 @@ end:
     return fdt_totalsize(fdt);
 }
 
-rt_size_t fdt_set_dtb_property(void *fdt, char *pathname, char *property_name, rt_uint32_t *cells, rt_size_t cells_size)
+size_t dtb_node_set_dtb_property(void *fdt, char *pathname, char *property_name, uint32_t *cells, size_t cells_size)
 {
     int node_off;
 
-    if (fdt == RT_NULL)
+    if (fdt == NULL)
     {
         goto end;
     }
@@ -118,9 +130,9 @@ end:
     return fdt_totalsize(fdt);
 }
 
-rt_size_t fdt_add_dtb_memreserve(void *fdt, rt_uint64_t address, rt_uint64_t size)
+size_t dtb_node_add_dtb_memreserve(void *fdt, uint64_t address, uint64_t size)
 {
-    if (fdt == RT_NULL)
+    if (fdt == NULL)
     {
         goto end;
     }
@@ -131,14 +143,14 @@ end:
     return fdt_totalsize(fdt);
 }
 
-rt_size_t fdt_del_dtb_memreserve(void *fdt, rt_uint64_t address)
+size_t dtb_node_del_dtb_memreserve(void *fdt, uint64_t address)
 {
     int i;
     int num_mem_rsvmap;
-    rt_uint32_t off_mem_rsvmap;
+    uint32_t off_mem_rsvmap;
     struct fdt_reserve_entry *rsvmap;
 
-    if (fdt == RT_NULL)
+    if (fdt == NULL)
     {
         goto end;
     }

+ 101 - 0
src/libfdt/fdt_addresses.c

@@ -0,0 +1,101 @@
+// SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause)
+/*
+ * libfdt - Flat Device Tree manipulation
+ * Copyright (C) 2014 David Gibson <david@gibson.dropbear.id.au>
+ * Copyright (C) 2018 embedded brains GmbH
+ */
+#include "libfdt_env.h"
+
+#include <fdt.h>
+#include <libfdt.h>
+
+#include "libfdt_internal.h"
+
+static int fdt_cells(const void *fdt, int nodeoffset, const char *name)
+{
+    const fdt32_t *c;
+    uint32_t val;
+    int len;
+
+    c = fdt_getprop(fdt, nodeoffset, name, &len);
+    if (!c)
+        return len;
+
+    if (len != sizeof(*c))
+        return -FDT_ERR_BADNCELLS;
+
+    val = fdt32_to_cpu(*c);
+    if (val > FDT_MAX_NCELLS)
+        return -FDT_ERR_BADNCELLS;
+
+    return (int)val;
+}
+
+int fdt_address_cells(const void *fdt, int nodeoffset)
+{
+    int val;
+
+    val = fdt_cells(fdt, nodeoffset, "#address-cells");
+    if (val == 0)
+        return -FDT_ERR_BADNCELLS;
+    if (val == -FDT_ERR_NOTFOUND)
+        return 2;
+    return val;
+}
+
+int fdt_size_cells(const void *fdt, int nodeoffset)
+{
+    int val;
+
+    val = fdt_cells(fdt, nodeoffset, "#size-cells");
+    if (val == -FDT_ERR_NOTFOUND)
+        return 1;
+    return val;
+}
+
+/* This function assumes that [address|size]_cells is 1 or 2 */
+int fdt_appendprop_addrrange(void *fdt, int parent, int nodeoffset,
+                 const char *name, uint64_t addr, uint64_t size)
+{
+    int addr_cells, size_cells, ret;
+    uint8_t data[sizeof(fdt64_t) * 2], *prop;
+
+    ret = fdt_address_cells(fdt, parent);
+    if (ret < 0)
+        return ret;
+    addr_cells = ret;
+
+    ret = fdt_size_cells(fdt, parent);
+    if (ret < 0)
+        return ret;
+    size_cells = ret;
+
+    /* check validity of address */
+    prop = data;
+    if (addr_cells == 1) {
+        if ((addr > UINT32_MAX) || ((UINT32_MAX + 1 - addr) < size))
+            return -FDT_ERR_BADVALUE;
+
+        fdt32_st(prop, (uint32_t)addr);
+    } else if (addr_cells == 2) {
+        fdt64_st(prop, addr);
+    } else {
+        return -FDT_ERR_BADNCELLS;
+    }
+
+    /* check validity of size */
+    prop += addr_cells * sizeof(fdt32_t);
+    if (size_cells == 1) {
+        if (size > UINT32_MAX)
+            return -FDT_ERR_BADVALUE;
+
+        fdt32_st(prop, (uint32_t)size);
+    } else if (size_cells == 2) {
+        fdt64_st(prop, size);
+    } else {
+        return -FDT_ERR_BADNCELLS;
+    }
+
+    return fdt_appendprop(fdt, nodeoffset, name, data,
+                  (addr_cells + size_cells) * sizeof(fdt32_t));
+}

+ 24 - 0
src/libfdt/libfdt.h

@@ -153,6 +153,30 @@ static inline void *fdt_offset_ptr_w(void *fdt, int offset, int checklen)
 
 uint32_t fdt_next_tag(const void *fdt, int offset, int *nextoffset);
 
+static inline void fdt32_st(void *property, uint32_t value)
+{
+    uint8_t *bp = (uint8_t *)property;
+
+    bp[0] = value >> 24;
+    bp[1] = (value >> 16) & 0xff;
+    bp[2] = (value >> 8) & 0xff;
+    bp[3] = value & 0xff;
+}
+
+static inline void fdt64_st(void *property, uint64_t value)
+{
+    uint8_t *bp = (uint8_t *)property;
+
+    bp[0] = value >> 56;
+    bp[1] = (value >> 48) & 0xff;
+    bp[2] = (value >> 40) & 0xff;
+    bp[3] = (value >> 32) & 0xff;
+    bp[4] = (value >> 24) & 0xff;
+    bp[5] = (value >> 16) & 0xff;
+    bp[6] = (value >> 8) & 0xff;
+    bp[7] = value & 0xff;
+}
+
 /**********************************************************************/
 /* Traversal functions                                                */
 /**********************************************************************/

+ 1 - 0
src/libfdt/libfdt_env.h

@@ -68,6 +68,7 @@
 typedef uint16_t FDT_BITWISE fdt16_t;
 typedef uint32_t FDT_BITWISE fdt32_t;
 typedef uint64_t FDT_BITWISE fdt64_t;
+typedef uint64_t unaligned_fdt64_t __attribute__((aligned(4)));
 
 #define EXTRACT_BYTE(x, n)	((unsigned long long)((uint8_t *)&x)[n])
 #define CPU_TO_FDT16(x) ((EXTRACT_BYTE(x, 0) << 8) | EXTRACT_BYTE(x, 1))