1 #ifndef __LUNAIX_DEVTREE_H
2 #define __LUNAIX_DEVTREE_H
4 #include <lunaix/types.h>
5 #include <lunaix/ds/llist.h>
6 #include <lunaix/ds/hstr.h>
7 #include <lunaix/ds/hashtable.h>
8 #include <lunaix/boot_generic.h>
10 #define le(v) ((((v) >> 24) & 0x000000ff) |\
11 (((v) << 8) & 0x00ff0000) |\
12 (((v) >> 8) & 0x0000ff00) |\
13 (((v) << 24) & 0xff000000))
15 #define le64(v) (((u64_t)le(v & 0xffffffff) << 32) | le(v >> 32))
17 #define be(v) ((((v) << 24) & 0x000000ff) |\
18 (((v) >> 8) & 0x00ff0000) |\
19 (((v) << 8) & 0x0000ff00) |\
20 (((v) >> 24) & 0xff000000))
22 #define FDT_MAGIC be(0xd00dfeed)
23 #define FDT_NOD_BEGIN be(0x00000001)
24 #define FDT_NOD_END be(0x00000002)
25 #define FDT_PROP be(0x00000003)
26 #define FDT_NOP be(0x00000004)
27 #define FDT_END be(0x00000009)
30 #define STATUS_DISABLE 1
35 typedef unsigned int* dt_enc_t;
36 typedef unsigned int dt_phnd_t;
37 typedef bool (*node_predicate_t)(struct dt_node_iter*, struct dt_node*);
40 #define PHND_NULL ((dt_phnd_t)-1)
49 u32_t last_comp_version;
50 u32_t boot_cpuid_phys;
51 u32_t size_dt_strings;
55 struct fdt_memrsvd_ent
68 struct fdt_token token;
74 struct fdt_token token;
105 struct hlist_node ht;
107 struct dt_prop_val val;
114 unsigned char addr_c;
116 unsigned char intr_c;
117 unsigned char status;
124 bool dma_coherent : 1;
125 bool dma_ncoherent : 1;
126 bool intr_controll : 1;
132 struct dt_node_base *parent;
133 struct llist_header children;
134 struct llist_header siblings;
135 struct llist_header nodes;
136 struct hlist_node phnd_link;
140 struct dt_prop_val compat;
145 struct hbucket other_props[0];
146 struct hbucket _op_bucket[8];
154 struct dt_node_base base;
162 struct dt_intr_mapkey
168 struct dt_intr_mapent
170 struct llist_header ents;
172 struct dt_intr_mapkey key;
174 struct dt_node_base* parent;
175 struct dt_prop_val parent_props;
180 struct dt_prop_val raw;
181 struct dt_prop_val raw_mask;
183 struct dt_intr_mapkey key_mask;
184 struct llist_header mapent;
192 struct dt_intr_node *parent;
193 dt_phnd_t parent_hnd;
200 struct dt_prop_val arr;
201 struct llist_header values;
205 struct dt_intr_map* map;
207 #define INTR_TO_DTNODE(intr_node) \
208 (container_of(intr_node, struct dt_node, intr))
210 #define BASE_TO_DTNODE(base_node) \
211 (container_of(base_node, struct dt_node, base))
215 struct dt_node_base base;
216 struct dt_intr_node intr;
218 struct dt_prop_val reg;
219 struct dt_prop_val vreg;
221 struct dt_prop_val ranges;
222 struct dt_prop_val dma_ranges;
228 struct dt_intr_node *master;
230 struct llist_header props;
231 struct dt_prop_val val;
236 struct dt_prop_val *prop;
237 struct dt_node_base *node;
239 dt_enc_t prop_loc_next;
247 struct fdt_header* fdt;
250 struct llist_header nodes;
251 struct dt_root *root;
252 struct hbucket phnds_table[16];
253 const char *str_block;
259 struct fdt_token *pos;
260 struct fdt_prop *prop;
261 struct fdt_node_head *node_head;
264 const char* str_block;
268 struct fdt_memrsvd_iter
270 struct fdt_memrsvd_ent *block;
275 struct dt_node_base* head;
276 struct dt_node_base* matched;
278 node_predicate_t pred;
287 #define fdt_prop(tok) ((tok)->token == FDT_PROP)
288 #define fdt_node(tok) ((tok)->token == FDT_NOD_BEGIN)
289 #define fdt_node_end(tok) ((tok)->token == FDT_NOD_END)
290 #define fdt_nope(tok) ((tok)->token == FDT_NOP)
293 fdt_itbegin(struct fdt_iter* fdti, struct fdt_header* fdt_hdr);
296 fdt_itend(struct fdt_iter* fdti);
299 fdt_itnext(struct fdt_iter* fdti);
302 fdt_itnext_at(struct fdt_iter* fdti, int level);
305 fdt_memrsvd_itbegin(struct fdt_memrsvd_iter* rsvdi,
306 struct fdt_header* fdt_hdr);
309 fdt_memrsvd_itnext(struct fdt_memrsvd_iter* rsvdi);
312 fdt_memrsvd_itend(struct fdt_memrsvd_iter* rsvdi);
315 fdtit_prop_key(struct fdt_iter* fdti)
317 return &fdti->str_block[fdti->prop->nameoff];
322 * DT Main Functions: General
326 dt_load(ptr_t dtb_dropoff);
329 dt_resolve_phandle(dt_phnd_t phandle);
332 dt_getprop(struct dt_node_base* base, const char* name);
335 dt_resolve_interrupt(struct dt_node* node);
338 dt_resolve_interrupt_map(struct dt_node* node);
340 static inline unsigned int
341 dt_addr_cells(struct dt_node_base* base)
343 return base->parent ? base->parent->addr_c : base->addr_c;
346 static inline unsigned int
347 dt_size_cells(struct dt_node_base* base)
349 return base->parent ? base->parent->sz_c : base->sz_c;
354 * DT Main Functions: Node-finder
358 dt_begin_find_byname(struct dt_node_iter* iter,
359 struct dt_node* node, const char* name);
362 dt_begin_find(struct dt_node_iter* iter, struct dt_node* node,
363 node_predicate_t pred, void* closure);
366 dt_end_find(struct dt_node_iter* iter)
368 // currently do nothing, keep only for semantic
372 dt_find_next(struct dt_node_iter* iter,
373 struct dt_node_base** matched);
376 dt_found_any(struct dt_node_iter* iter)
378 return !!iter->matched;
383 * DT Main Functions: Node-binding
387 dt_bind_object(struct dt_node_base* base, void* obj)
393 dt_has_binding(struct dt_node_base* base)
395 return base->obj != NULL;
398 #define dt_binding_of(node_base, type) \
399 ((type)(node_base)->obj)
403 * DT Main Functions: Prop decoders
407 dt_decode(struct dt_prop_iter* dtpi, struct dt_node_base* node,
408 struct dt_prop_val* val, unsigned int ent_sz)
410 *dtpi = (struct dt_prop_iter) {
413 .prop_loc = val->encoded,
414 .prop_loc_next = val->encoded,
419 #define dt_decode_reg(dtpi, node, field) \
420 dt_decode(dtpi, &(node)->base, &(node)->field, \
421 dt_size_cells(&(node)->base) \
422 + dt_addr_cells(&(node)->base))
424 #define dt_decode_range(dtpi, node, field) \
425 dt_decode(dtpi, &(node)->base, &(node)->field, \
426 dt_size_cells(&(node)->base) * 2 \
427 + dt_addr_cells(&(node)->base))
429 #define dt_decode_simple(dtpi, prop) \
430 dt_decode(dtpi, NULL, prop, 1);
432 #define dtprop_off(dtpi) \
434 __ptr(dtpi->prop_loc_next) - __ptr(dtpi->prop->encoded) \
437 #define dtprop_extract(dtpi, off) \
438 ( (dt_enc_t) (&(dtpi)->prop_loc[(off)]) )
441 dtprop_next_n(struct dt_prop_iter* dtpi, int n)
445 dtpi->prop_loc = dtpi->prop_loc_next;
446 dtpi->prop_loc_next += n;
448 off = dtprop_off(dtpi);
449 return off >= dtpi->prop->size;
453 dtprop_prev_n(struct dt_prop_iter* dtpi, int n)
457 off = dtprop_off(dtpi);
458 if (!off || off > dtpi->prop->size) {
462 dtpi->prop_loc = dtpi->prop_loc_next;
463 dtpi->prop_loc_next -= n;
469 dtprop_next(struct dt_prop_iter* dtpi)
471 return dtprop_next_n(dtpi, dtpi->ent_sz);
475 dtprop_prev(struct dt_prop_iter* dtpi)
477 return dtprop_prev_n(dtpi, dtpi->ent_sz);
480 static inline unsigned int
481 dtprop_to_u32(dt_enc_t enc_val)
486 #define dtprop_to_phnd(enc_val) \
487 (dt_phnd_t)dtprop_to_u32(enc_val)
490 dtprop_to_u64(dt_enc_t enc_val)
492 return le64(*(u64_t*)enc_val);
496 dtprop_u32_at(struct dt_prop_iter* dtpi, int index)
498 return dtprop_to_u32(dtprop_extract(dtpi, index));
502 dtprop_u64_at(struct dt_prop_iter* dtpi, int index)
504 return dtprop_to_u64(dtprop_extract(dtpi, index));
507 static inline dt_enc_t
508 dtprop_reg_addr(struct dt_prop_iter* dtpi)
510 return dtprop_extract(dtpi, 0);
514 dtprop_reg_nextaddr(struct dt_prop_iter* dtpi)
518 t = (ptr_t)dtprop_to_u64(dtprop_reg_addr(dtpi));
519 dtprop_next_n(dtpi, dt_addr_cells(dtpi->node));
524 static inline dt_enc_t
525 dtprop_reg_len(struct dt_prop_iter* dtpi)
527 return dtprop_extract(dtpi, dtpi->node->addr_c);
531 dtprop_reg_nextlen(struct dt_prop_iter* dtpi)
535 t = (size_t)dtprop_to_u64(dtprop_reg_len(dtpi));
536 dtprop_next_n(dtpi, dt_size_cells(dtpi->node));
541 static inline dt_enc_t
542 dtprop_range_childbus(struct dt_prop_iter* dtpi)
544 return dtprop_extract(dtpi, 0);
547 static inline dt_enc_t
548 dtprop_range_parentbus(struct dt_prop_iter* dtpi)
550 return dtprop_extract(dtpi, dt_addr_cells(dtpi->node));
553 static inline dt_enc_t
554 dtprop_range_len(struct dt_prop_iter* dtpi)
556 return dtprop_extract(dtpi, dt_addr_cells(dtpi->node) * 2);
559 #endif /* __LUNAIX_DEVTREE_H */