Merge remote-tracking branch 'origin/master' into isa/arm64
[lunaix-os.git] / lunaix-os / includes / hal / devtree.h
index 5203d1aa7706d143bdb3197660f7595ce3bbc487..45e80ce0a448b6f439d53d8233a7b9d8f4671d60 100644 (file)
@@ -6,6 +6,9 @@
 #include <lunaix/ds/hstr.h>
 #include <lunaix/ds/hashtable.h>
 #include <lunaix/boot_generic.h>
+#include <lunaix/changeling.h>
+
+#include <klibc/string.h>
 
 #define le(v) ((((v) >> 24) & 0x000000ff)  |\
                (((v) << 8)  & 0x00ff0000)  |\
@@ -37,6 +40,11 @@ typedef unsigned int  dt_phnd_t;
 typedef bool (*node_predicate_t)(struct dt_node_iter*, struct dt_node*);
 
 
+struct dt_node_base;
+struct dt_node_iter;
+typedef bool (*node_predicate_t)(struct dt_node_iter*, struct dt_node_base*);
+
+
 #define PHND_NULL    ((dt_phnd_t)-1)
 
 struct fdt_header {
@@ -83,7 +91,7 @@ struct dt_prop_val
         {
             union {
                 const char*  str_val;
-                const char** str_lst;
+                const char*  str_lst;
             };
             ptr_t        ptr_val;
             
@@ -107,8 +115,18 @@ struct dt_prop
     struct dt_prop_val  val;
 };
 
+struct dt_prop_table
+{
+    union {
+        struct hbucket    other_props[0];
+        struct hbucket    _op_bucket[8];
+    };
+};
+
 struct dt_node_base
 {
+    morph_t mobj;
+
     union {
         struct {
             unsigned char addr_c;
@@ -125,29 +143,20 @@ struct dt_node_base
             bool dma_ncoherent : 1;
             bool intr_controll : 1;
             bool intr_neuxs    : 1;
-            unsigned int other : 29;
         };
         unsigned int    flags;
     };
 
     struct dt_node_base  *parent;
-    struct llist_header   children;
-    struct llist_header   siblings;
     struct llist_header   nodes;
-    struct hlist_node     phnd_link;
-
-    const char*           name;
 
     struct dt_prop_val    compat;
-    const char*           model;
     dt_phnd_t             phandle;
 
-    union {
-        struct hbucket    other_props[0];
-        struct hbucket    _op_bucket[8];
-    };
+    struct dt_prop_table* props;
 
     void* obj;
+    morph_t* binded_dev;
 };
 
 struct dt_root
@@ -213,7 +222,11 @@ struct dt_intr_node
 
 struct dt_node
 {
-    struct dt_node_base base;
+    union {
+        morph_t mobj;
+        struct dt_node_base base;
+    };
+    
     struct dt_intr_node intr;
     
     struct dt_prop_val  reg;
@@ -222,7 +235,9 @@ struct dt_node
     struct dt_prop_val  ranges;
     struct dt_prop_val  dma_ranges;
 };
-
+#define dt_parent(node) ((node)->base.parent)
+#define dt_morpher       morphable_attrs(dt_node, mobj)
+#define dt_mobj(node)   (&(node)->mobj)
 
 struct dt_intr_prop
 {
@@ -279,8 +294,11 @@ struct dt_node_iter
     node_predicate_t pred;
 };
 
-#define dtnode_child_foreach(node_base, pos, n)  \
-        llist_for_each(pos, n, &(node_base)->children, siblings)
+
+
+/****
+ * FDT Related
+ ****/
 
 #define fdt_prop(tok) ((tok)->token == FDT_PROP)
 #define fdt_node(tok) ((tok)->token == FDT_NOD_BEGIN)
@@ -309,6 +327,16 @@ fdt_memrsvd_itnext(struct fdt_memrsvd_iter* rsvdi);
 void
 fdt_memrsvd_itend(struct fdt_memrsvd_iter* rsvdi);
 
+static inline char*
+fdtit_prop_key(struct fdt_iter* fdti)
+{
+    return &fdti->str_block[fdti->prop->nameoff];
+}
+
+
+/****
+ * DT Main Functions: General
+ ****/
 
 bool
 dt_load(ptr_t dtb_dropoff);
@@ -319,6 +347,29 @@ dt_resolve_phandle(dt_phnd_t phandle);
 struct dt_prop_val*
 dt_getprop(struct dt_node_base* base, const char* name);
 
+struct dt_prop_val*
+dt_resolve_interrupt(struct dt_node* node);
+
+void
+dt_resolve_interrupt_map(struct dt_node* node);
+
+static inline unsigned int
+dt_addr_cells(struct dt_node_base* base)
+{
+    return base->parent ? base->parent->addr_c : base->addr_c;
+}
+
+static inline unsigned int
+dt_size_cells(struct dt_node_base* base)
+{
+    return base->parent ? base->parent->sz_c : base->sz_c;
+}
+
+
+/****
+ * DT Main Functions: Node-finder
+ ****/
+
 void
 dt_begin_find_byname(struct dt_node_iter* iter, 
                      struct dt_node* node, const char* name);
@@ -327,12 +378,6 @@ void
 dt_begin_find(struct dt_node_iter* iter, struct dt_node* node, 
               node_predicate_t pred, void* closure);
 
-struct dt_prop_val*
-resolve_interrupt(struct dt_node* node);
-
-void
-resolve_interrupt_map(struct dt_node* node);
-
 static inline void
 dt_end_find(struct dt_node_iter* iter)
 {
@@ -349,6 +394,12 @@ dt_found_any(struct dt_node_iter* iter)
     return !!iter->matched;
 }
 
+struct dt_context*
+dt_main_context();
+
+/****
+ * DT Main Functions: Node-binding
+ ****/
 
 static inline void
 dt_bind_object(struct dt_node_base* base, void* obj)
@@ -365,11 +416,10 @@ dt_has_binding(struct dt_node_base* base)
 #define dt_binding_of(node_base, type)  \
     ((type)(node_base)->obj)
 
-static inline char*
-fdtit_prop_key(struct fdt_iter* fdti)
-{
-    return &fdti->str_block[fdti->prop->nameoff];
-}
+
+/****
+ * DT Main Functions: Prop decoders
+ ****/
 
 static inline void
 dt_decode(struct dt_prop_iter* dtpi, struct dt_node_base* node, 
@@ -386,11 +436,16 @@ dt_decode(struct dt_prop_iter* dtpi, struct dt_node_base* node,
 
 #define dt_decode_reg(dtpi, node, field) \
             dt_decode(dtpi, &(node)->base, &(node)->field, \
-                            (node)->base.sz_c + (node)->base.addr_c);
+                        dt_size_cells(&(node)->base) \
+                            + dt_addr_cells(&(node)->base))
 
 #define dt_decode_range(dtpi, node, field) \
             dt_decode(dtpi, &(node)->base, &(node)->field, \
-                            (node)->base.sz_c * 2 + (node)->base.addr_c);
+                        dt_size_cells(&(node)->base) * 2 \
+                            + dt_addr_cells(&(node)->base))
+
+#define dt_decode_simple(dtpi, prop) \
+            dt_decode(dtpi, NULL, prop, 1);
 
 #define dtprop_off(dtpi) \
             (unsigned int)(\
@@ -400,6 +455,11 @@ dt_decode(struct dt_prop_iter* dtpi, struct dt_node_base* node,
 #define dtprop_extract(dtpi, off) \
             ( (dt_enc_t) (&(dtpi)->prop_loc[(off)]) )
 
+#define dtprop_strlst_foreach(pos, prop)    \
+        for (pos = (prop)->str_lst; \
+             pos <= &(prop)->str_lst[(prop)->size]; \
+             pos = &pos[strlen(pos) + 1])
+
 static inline bool
 dtprop_next_n(struct dt_prop_iter* dtpi, int n)
 {
@@ -479,7 +539,7 @@ dtprop_reg_nextaddr(struct dt_prop_iter* dtpi)
     ptr_t t;
 
     t = (ptr_t)dtprop_to_u64(dtprop_reg_addr(dtpi));
-    dtprop_next(dtpi);
+    dtprop_next_n(dtpi, dt_addr_cells(dtpi->node));
 
     return t;
 }
@@ -496,7 +556,7 @@ dtprop_reg_nextlen(struct dt_prop_iter* dtpi)
     size_t t;
 
     t = (size_t)dtprop_to_u64(dtprop_reg_len(dtpi));
-    dtprop_next(dtpi);
+    dtprop_next_n(dtpi, dt_size_cells(dtpi->node));
 
     return t;
 }
@@ -510,13 +570,13 @@ dtprop_range_childbus(struct dt_prop_iter* dtpi)
 static inline dt_enc_t
 dtprop_range_parentbus(struct dt_prop_iter* dtpi)
 {
-    return dtprop_extract(dtpi, dtpi->node->addr_c);
+    return dtprop_extract(dtpi, dt_addr_cells(dtpi->node));
 }
 
 static inline dt_enc_t
 dtprop_range_len(struct dt_prop_iter* dtpi)
 {
-    return dtprop_extract(dtpi, dtpi->node->addr_c * 2);
+    return dtprop_extract(dtpi, dt_addr_cells(dtpi->node) * 2);
 }
 
 #endif /* __LUNAIX_DEVTREE_H */