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>
9 #include <lunaix/changeling.h>
11 #include <klibc/string.h>
13 #define le(v) ((((v) >> 24) & 0x000000ff) |\
14 (((v) << 8) & 0x00ff0000) |\
15 (((v) >> 8) & 0x0000ff00) |\
16 (((v) << 24) & 0xff000000))
18 #define le64(v) (((u64_t)le(v & 0xffffffff) << 32) | le(v >> 32))
20 #define be(v) ((((v) << 24) & 0x000000ff) |\
21 (((v) >> 8) & 0x00ff0000) |\
22 (((v) << 8) & 0x0000ff00) |\
23 (((v) >> 24) & 0xff000000))
25 #define FDT_MAGIC be(0xd00dfeed)
26 #define FDT_NOD_BEGIN be(0x00000001)
27 #define FDT_NOD_END be(0x00000002)
28 #define FDT_PROP be(0x00000003)
29 #define FDT_NOP be(0x00000004)
30 #define FDT_END be(0x00000009)
33 #define STATUS_DISABLE 1
38 typedef unsigned int* dt_enc_t;
39 typedef unsigned int dt_phnd_t;
43 typedef bool (*node_predicate_t)(struct dt_node_iter*, struct dt_node_base*);
46 #define PHND_NULL ((dt_phnd_t)-1)
55 u32_t last_comp_version;
56 u32_t boot_cpuid_phys;
57 u32_t size_dt_strings;
61 struct fdt_memrsvd_ent
74 struct fdt_token token;
80 struct fdt_token token;
111 struct hlist_node ht;
113 struct dt_prop_val val;
119 struct hbucket other_props[0];
120 struct hbucket _op_bucket[8];
130 unsigned char addr_c;
132 unsigned char intr_c;
133 unsigned char status;
140 bool dma_coherent : 1;
141 bool dma_ncoherent : 1;
142 bool intr_controll : 1;
148 struct dt_node_base *parent;
149 struct llist_header nodes;
151 struct dt_prop_val compat;
154 struct dt_prop_table* props;
162 struct dt_node_base base;
170 struct dt_intr_mapkey
176 struct dt_intr_mapent
178 struct llist_header ents;
180 struct dt_intr_mapkey key;
182 struct dt_node_base* parent;
183 struct dt_prop_val parent_props;
188 struct dt_prop_val raw;
189 struct dt_prop_val raw_mask;
191 struct dt_intr_mapkey key_mask;
192 struct llist_header mapent;
200 struct dt_intr_node *parent;
201 dt_phnd_t parent_hnd;
208 struct dt_prop_val arr;
209 struct llist_header values;
213 struct dt_intr_map* map;
215 #define INTR_TO_DTNODE(intr_node) \
216 (container_of(intr_node, struct dt_node, intr))
218 #define BASE_TO_DTNODE(base_node) \
219 (container_of(base_node, struct dt_node, base))
225 struct dt_node_base base;
228 struct dt_intr_node intr;
230 struct dt_prop_val reg;
231 struct dt_prop_val vreg;
233 struct dt_prop_val ranges;
234 struct dt_prop_val dma_ranges;
236 #define dt_parent(node) ((node)->base.parent)
237 #define dt_morpher morphable_attrs(dt_node, mobj)
238 #define dt_mobj(node) (&(node)->mobj)
242 struct dt_intr_node *master;
244 struct llist_header props;
245 struct dt_prop_val val;
250 struct dt_prop_val *prop;
251 struct dt_node_base *node;
253 dt_enc_t prop_loc_next;
261 struct fdt_header* fdt;
264 struct llist_header nodes;
265 struct dt_root *root;
266 struct hbucket phnds_table[16];
267 const char *str_block;
273 struct fdt_token *pos;
274 struct fdt_prop *prop;
275 struct fdt_node_head *node_head;
278 const char* str_block;
282 struct fdt_memrsvd_iter
284 struct fdt_memrsvd_ent *block;
289 struct dt_node_base* head;
290 struct dt_node_base* matched;
292 node_predicate_t pred;
301 #define fdt_prop(tok) ((tok)->token == FDT_PROP)
302 #define fdt_node(tok) ((tok)->token == FDT_NOD_BEGIN)
303 #define fdt_node_end(tok) ((tok)->token == FDT_NOD_END)
304 #define fdt_nope(tok) ((tok)->token == FDT_NOP)
307 fdt_itbegin(struct fdt_iter* fdti, struct fdt_header* fdt_hdr);
310 fdt_itend(struct fdt_iter* fdti);
313 fdt_itnext(struct fdt_iter* fdti);
316 fdt_itnext_at(struct fdt_iter* fdti, int level);
319 fdt_memrsvd_itbegin(struct fdt_memrsvd_iter* rsvdi,
320 struct fdt_header* fdt_hdr);
323 fdt_memrsvd_itnext(struct fdt_memrsvd_iter* rsvdi);
326 fdt_memrsvd_itend(struct fdt_memrsvd_iter* rsvdi);
329 fdtit_prop_key(struct fdt_iter* fdti)
331 return &fdti->str_block[fdti->prop->nameoff];
336 * DT Main Functions: General
340 dt_load(ptr_t dtb_dropoff);
343 dt_resolve_phandle(dt_phnd_t phandle);
346 dt_getprop(struct dt_node_base* base, const char* name);
349 dt_resolve_interrupt(struct dt_node* node);
352 dt_resolve_interrupt_map(struct dt_node* node);
354 static inline unsigned int
355 dt_addr_cells(struct dt_node_base* base)
357 return base->parent ? base->parent->addr_c : base->addr_c;
360 static inline unsigned int
361 dt_size_cells(struct dt_node_base* base)
363 return base->parent ? base->parent->sz_c : base->sz_c;
368 * DT Main Functions: Node-finder
372 dt_begin_find_byname(struct dt_node_iter* iter,
373 struct dt_node* node, const char* name);
376 dt_begin_find(struct dt_node_iter* iter, struct dt_node* node,
377 node_predicate_t pred, void* closure);
380 dt_end_find(struct dt_node_iter* iter)
382 // currently do nothing, keep only for semantic
386 dt_find_next(struct dt_node_iter* iter,
387 struct dt_node_base** matched);
390 dt_found_any(struct dt_node_iter* iter)
392 return !!iter->matched;
400 * DT Main Functions: Node-binding
404 dt_bind_object(struct dt_node_base* base, void* obj)
410 dt_has_binding(struct dt_node_base* base)
412 return base->obj != NULL;
415 #define dt_binding_of(node_base, type) \
416 ((type)(node_base)->obj)
420 * DT Main Functions: Prop decoders
424 dt_decode(struct dt_prop_iter* dtpi, struct dt_node_base* node,
425 struct dt_prop_val* val, unsigned int ent_sz)
427 *dtpi = (struct dt_prop_iter) {
430 .prop_loc = val->encoded,
431 .prop_loc_next = val->encoded,
436 #define dt_decode_reg(dtpi, node, field) \
437 dt_decode(dtpi, &(node)->base, &(node)->field, \
438 dt_size_cells(&(node)->base) \
439 + dt_addr_cells(&(node)->base))
441 #define dt_decode_range(dtpi, node, field) \
442 dt_decode(dtpi, &(node)->base, &(node)->field, \
443 dt_size_cells(&(node)->base) * 2 \
444 + dt_addr_cells(&(node)->base))
446 #define dt_decode_simple(dtpi, prop) \
447 dt_decode(dtpi, NULL, prop, 1);
449 #define dtprop_off(dtpi) \
451 __ptr(dtpi->prop_loc_next) - __ptr(dtpi->prop->encoded) \
454 #define dtprop_extract(dtpi, off) \
455 ( (dt_enc_t) (&(dtpi)->prop_loc[(off)]) )
457 #define dtprop_strlst_foreach(pos, prop) \
458 for (pos = (prop)->str_lst; \
459 pos <= &(prop)->str_lst[(prop)->size]; \
460 pos = &pos[strlen(pos) + 1])
463 dtprop_next_n(struct dt_prop_iter* dtpi, int n)
467 dtpi->prop_loc = dtpi->prop_loc_next;
468 dtpi->prop_loc_next += n;
470 off = dtprop_off(dtpi);
471 return off >= dtpi->prop->size;
475 dtprop_prev_n(struct dt_prop_iter* dtpi, int n)
479 off = dtprop_off(dtpi);
480 if (!off || off > dtpi->prop->size) {
484 dtpi->prop_loc = dtpi->prop_loc_next;
485 dtpi->prop_loc_next -= n;
491 dtprop_next(struct dt_prop_iter* dtpi)
493 return dtprop_next_n(dtpi, dtpi->ent_sz);
497 dtprop_prev(struct dt_prop_iter* dtpi)
499 return dtprop_prev_n(dtpi, dtpi->ent_sz);
502 static inline unsigned int
503 dtprop_to_u32(dt_enc_t enc_val)
508 #define dtprop_to_phnd(enc_val) \
509 (dt_phnd_t)dtprop_to_u32(enc_val)
512 dtprop_to_u64(dt_enc_t enc_val)
514 return le64(*(u64_t*)enc_val);
518 dtprop_u32_at(struct dt_prop_iter* dtpi, int index)
520 return dtprop_to_u32(dtprop_extract(dtpi, index));
524 dtprop_u64_at(struct dt_prop_iter* dtpi, int index)
526 return dtprop_to_u64(dtprop_extract(dtpi, index));
529 static inline dt_enc_t
530 dtprop_reg_addr(struct dt_prop_iter* dtpi)
532 return dtprop_extract(dtpi, 0);
536 dtprop_reg_nextaddr(struct dt_prop_iter* dtpi)
540 t = (ptr_t)dtprop_to_u64(dtprop_reg_addr(dtpi));
541 dtprop_next_n(dtpi, dt_addr_cells(dtpi->node));
546 static inline dt_enc_t
547 dtprop_reg_len(struct dt_prop_iter* dtpi)
549 return dtprop_extract(dtpi, dtpi->node->addr_c);
553 dtprop_reg_nextlen(struct dt_prop_iter* dtpi)
557 t = (size_t)dtprop_to_u64(dtprop_reg_len(dtpi));
558 dtprop_next_n(dtpi, dt_size_cells(dtpi->node));
563 static inline dt_enc_t
564 dtprop_range_childbus(struct dt_prop_iter* dtpi)
566 return dtprop_extract(dtpi, 0);
569 static inline dt_enc_t
570 dtprop_range_parentbus(struct dt_prop_iter* dtpi)
572 return dtprop_extract(dtpi, dt_addr_cells(dtpi->node));
575 static inline dt_enc_t
576 dtprop_range_len(struct dt_prop_iter* dtpi)
578 return dtprop_extract(dtpi, dt_addr_cells(dtpi->node) * 2);
581 #endif /* __LUNAIX_DEVTREE_H */