devtree: fix addr/size cells should use parent's
[lunaix-os.git] / lunaix-os / includes / hal / devtree.h
index 3a92116eeb4fc744be07297c6b0664b49591b3cb..088e66f115d930d26b1e6d3853ec39aa19be2916 100644 (file)
@@ -34,6 +34,8 @@
 
 typedef unsigned int* dt_enc_t;
 typedef unsigned int  dt_phnd_t;
+typedef bool (*node_predicate_t)(struct dt_node_iter*, struct dt_node*);
+
 
 #define PHND_NULL    ((dt_phnd_t)-1)
 
@@ -122,7 +124,7 @@ struct dt_node_base
             bool dma_coherent  : 1;
             bool dma_ncoherent : 1;
             bool intr_controll : 1;
-            unsigned int other : 29;
+            bool intr_neuxs    : 1;
         };
         unsigned int    flags;
     };
@@ -143,6 +145,8 @@ struct dt_node_base
         struct hbucket    other_props[0];
         struct hbucket    _op_bucket[8];
     };
+
+    void* obj;
 };
 
 struct dt_root
@@ -155,6 +159,33 @@ struct dt_root
 
 struct dt_intr_prop;
 
+struct dt_intr_mapkey
+{
+    unsigned int* val;
+    unsigned int  size;
+};
+
+struct dt_intr_mapent
+{
+    struct llist_header ents;
+
+    struct dt_intr_mapkey key;
+
+    struct dt_node_base* parent;
+    struct dt_prop_val parent_props;
+};
+
+struct dt_intr_map 
+{
+    struct dt_prop_val       raw;
+    struct dt_prop_val       raw_mask;
+
+    struct dt_intr_mapkey    key_mask;
+    struct llist_header      mapent;
+
+    bool resolved;
+};
+
 struct dt_intr_node
 {
     union {
@@ -164,18 +195,20 @@ struct dt_intr_node
 
     struct {
         bool extended;
+        bool valid;
         union {
             struct dt_prop_val   arr;
             struct llist_header  values; 
         };
     } intr;
 
-    struct dt_prop_val       intr_map;
-    struct dt_prop_val       intr_map_mask;
+    struct dt_intr_map* map;
 };
-#define DT_NODE(intr_node) \
+#define INTR_TO_DTNODE(intr_node) \
         (container_of(intr_node, struct dt_node, intr))
 
+#define BASE_TO_DTNODE(base_node) \
+        (container_of(base_node, struct dt_node, base))
 
 struct dt_node
 {
@@ -241,11 +274,15 @@ struct dt_node_iter
 {
     struct dt_node_base* head;
     struct dt_node_base* matched;
-    const char *name;
+    void* closure;
+    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)
@@ -274,6 +311,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);
@@ -282,11 +329,44 @@ struct dt_node*
 dt_resolve_phandle(dt_phnd_t phandle);
 
 struct dt_prop_val*
-dt_getprop(struct dt_node* node, const char* name);
+dt_getprop(struct dt_node_base* base, const char* name);
+
+struct dt_prop_val*
+dt_resolve_interrupt(struct dt_node* node);
 
 void
-dt_begin_find(struct dt_node_iter* iter, 
-              struct dt_node* node, const char* name);
+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);
+
+void
+dt_begin_find(struct dt_node_iter* iter, struct dt_node* node, 
+              node_predicate_t pred, void* closure);
+
+static inline void
+dt_end_find(struct dt_node_iter* iter)
+{
+    // currently do nothing, keep only for semantic
+}
 
 bool
 dt_find_next(struct dt_node_iter* iter,
@@ -299,12 +379,30 @@ dt_found_any(struct dt_node_iter* iter)
 }
 
 
-static inline char*
-fdtit_prop_key(struct fdt_iter* fdti)
+/****
+ * DT Main Functions: Node-binding
+ ****/
+
+static inline void
+dt_bind_object(struct dt_node_base* base, void* obj)
 {
-    return &fdti->str_block[fdti->prop->nameoff];
+    base->obj = obj;
+}
+
+static inline bool
+dt_has_binding(struct dt_node_base* base) 
+{
+    return base->obj != NULL;
 }
 
+#define dt_binding_of(node_base, type)  \
+    ((type)(node_base)->obj)
+
+
+/****
+ * DT Main Functions: Prop decoders
+ ****/
+
 static inline void
 dt_decode(struct dt_prop_iter* dtpi, struct dt_node_base* node, 
                 struct dt_prop_val* val, unsigned int ent_sz)
@@ -319,27 +417,17 @@ 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_decode(dtpi, &(node)->base, &(node)->field, \
+                        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_decode(dtpi, &(node)->base, &(node)->field, \
+                        dt_size_cells(&(node)->base) * 2 \
+                            + dt_addr_cells(&(node)->base))
 
-static inline void
-dt_decode_intrmap(struct dt_prop_iter* dtpi, 
-                  struct dt_intr_node* intr_node)
-{
-    unsigned int size;
-    struct dt_node* node;
-    struct dt_node_base* base;
-    
-    node = DT_NODE(intr_node);
-    base = &node->base;
-    size = (base->addr_c + base->intr_c) * 2 + 1;
-
-    dt_decode(dtpi, base, &intr_node->intr_map, size);
-}
+#define dt_decode_simple(dtpi, prop) \
+            dt_decode(dtpi, NULL, prop, 1);
 
 #define dtprop_off(dtpi) \
             (unsigned int)(\
@@ -404,78 +492,68 @@ dtprop_to_u64(dt_enc_t enc_val)
     return le64(*(u64_t*)enc_val);
 }
 
-static inline dt_enc_t
-dtprop_reg_addr(struct dt_prop_iter* dtpi)
+static inline u32_t
+dtprop_u32_at(struct dt_prop_iter* dtpi, int index)
 {
-    return dtprop_extract(dtpi, 0);
+    return dtprop_to_u32(dtprop_extract(dtpi, index));
 }
 
-static inline dt_enc_t
-dtprop_reg_len(struct dt_prop_iter* dtpi)
+static inline u32_t
+dtprop_u64_at(struct dt_prop_iter* dtpi, int index)
 {
-    return dtprop_extract(dtpi, dtpi->node->addr_c);
+    return dtprop_to_u64(dtprop_extract(dtpi, index));
 }
 
 static inline dt_enc_t
-dtprop_range_childbus(struct dt_prop_iter* dtpi)
+dtprop_reg_addr(struct dt_prop_iter* dtpi)
 {
     return dtprop_extract(dtpi, 0);
 }
 
-static inline dt_enc_t
-dtprop_range_parentbus(struct dt_prop_iter* dtpi)
+static inline ptr_t
+dtprop_reg_nextaddr(struct dt_prop_iter* dtpi)
 {
-    return dtprop_extract(dtpi, dtpi->node->addr_c);
-}
+    ptr_t t;
 
-static inline dt_enc_t
-dtprop_range_len(struct dt_prop_iter* dtpi)
-{
-    return dtprop_extract(dtpi, dtpi->node->addr_c * 2);
-}
+    t = (ptr_t)dtprop_to_u64(dtprop_reg_addr(dtpi));
+    dtprop_next_n(dtpi, dt_addr_cells(dtpi->node));
 
-static inline dt_enc_t
-dtprop_intr_cuaddr(struct dt_prop_iter* dtpi)
-{
-    return dtprop_extract(dtpi, 0);
+    return t;
 }
 
 static inline dt_enc_t
-dtprop_intr_cispec(struct dt_prop_iter* dtpi)
+dtprop_reg_len(struct dt_prop_iter* dtpi)
 {
     return dtprop_extract(dtpi, dtpi->node->addr_c);
 }
 
-static inline struct dt_intr_node*
-dtprop_intr_parent(struct dt_prop_iter* dtpi)
+static inline size_t
+dtprop_reg_nextlen(struct dt_prop_iter* dtpi)
 {
-    unsigned off;
-    struct dt_node* node;
-    dt_enc_t enc_val;
+    size_t t;
 
-    off = dtpi->node->addr_c + dtpi->node->intr_c;
-    enc_val = dtprop_extract(dtpi, off);
-    node = dt_resolve_phandle(dtprop_to_phnd(enc_val));
-    
-    return &node->intr;
+    t = (size_t)dtprop_to_u64(dtprop_reg_len(dtpi));
+    dtprop_next_n(dtpi, dt_size_cells(dtpi->node));
+
+    return t;
 }
 
 static inline dt_enc_t
-dtprop_intr_puaddr(struct dt_prop_iter* dtpi)
+dtprop_range_childbus(struct dt_prop_iter* dtpi)
 {
-    unsigned off;
-
-    off = dtpi->node->addr_c + dtpi->node->intr_c + 1;
-    return dtprop_extract(dtpi, off);
+    return dtprop_extract(dtpi, 0);
 }
 
 static inline dt_enc_t
-dtprop_intr_pispec(struct dt_prop_iter* dtpi)
+dtprop_range_parentbus(struct dt_prop_iter* dtpi)
 {
-    unsigned off;
+    return dtprop_extract(dtpi, dt_addr_cells(dtpi->node));
+}
 
-    off = dtpi->node->addr_c * 2 + dtpi->node->intr_c + 1;
-    return dtprop_extract(dtpi, off);
+static inline dt_enc_t
+dtprop_range_len(struct dt_prop_iter* dtpi)
+{
+    return dtprop_extract(dtpi, dt_addr_cells(dtpi->node) * 2);
 }
 
 #endif /* __LUNAIX_DEVTREE_H */