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)
bool dma_coherent : 1;
bool dma_ncoherent : 1;
bool intr_controll : 1;
- unsigned int other : 29;
+ bool intr_neuxs : 1;
};
unsigned int flags;
};
struct hbucket other_props[0];
struct hbucket _op_bucket[8];
};
+
+ void* obj;
};
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 {
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
{
{
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)
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);
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,
}
-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)
}
#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)(\
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 */