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/changeling.h>
10 #include <klibc/string.h>
12 #define FDT_MAGIC 0xd00dfeedU
13 #define FDT_NOD_BEGIN 0x00000001U
14 #define FDT_NOD_END 0x00000002U
15 #define FDT_PROP 0x00000003U
16 #define FDT_NOP 0x00000004U
17 #define FDT_END 0x00000009U
20 #define STATUS_DISABLE 1
24 #define PHND_NULL ((dt_phnd_t)-1)
26 /////////////////////////////////
28 /////////////////////////////////
30 typedef unsigned int* dt_enc_t;
31 typedef unsigned int dt_phnd_t;
35 typedef bool (*node_predicate_t)(struct dtn_iter*, struct dtn_base*);
56 union dtp_baseval* ref;
67 /////////////////////////////////
69 /////////////////////////////////
78 u32_t last_comp_version;
79 u32_t boot_cpuid_phys;
80 u32_t size_dt_strings;
84 struct fdt_memrsvd_ent
94 } _be compact align(4);
98 struct fdt_token token;
106 } _be compact align(4);
111 struct fdt_token *token;
112 struct fdt_prop *prop;
113 struct fdt_memrsvd_ent *rsvd_ent;
116 struct fdt_token token;
121 typedef struct fdt_loc fdt_loc_t;
139 FDT_MEM_RSVD_DYNAMIC,
143 struct fdt_rsvdmem_attrs
157 struct dt_memory_node
161 enum fdt_mem_type type;
163 struct fdt_rsvdmem_attrs dyn_alloc_attr;
175 struct fdt_header* header;
181 const char* str_block;
182 ptr_t str_block_base;
187 struct fdt_rsvd_mem* plat_rsvd;
188 ptr_t plat_rsvd_base;
197 struct dtpropi regit;
201 enum fdt_mem_type node_type;
203 struct fdt_rsvdmem_attrs node_attr;
206 struct fdt_memrsvd_iter
208 struct fdt_memrsvd_ent *block;
212 /////////////////////////////////
214 /////////////////////////////////
218 struct hlist_node ht;
226 struct hbucket other_props[0];
227 struct hbucket _op_bucket[8];
237 unsigned char addr_c;
239 unsigned char intr_c;
240 unsigned char status;
247 bool dma_coherent : 1;
248 bool dma_ncoherent : 1;
249 bool intr_controll : 1;
254 struct dtn_base *parent;
255 struct llist_header nodes;
257 struct dtp_val compat;
260 struct dtp_table *props;
268 union dtp_baseval *bval;
276 struct llist_header ents;
277 const struct dtspec_key child_spec;
280 const struct dtspec_key parent_spec;
285 const struct dtspec_key mask;
286 const struct dtspec_key pass_thru;
288 struct llist_header ents;
295 struct llist_header ispecs;
303 dt_phnd_t parent_hnd;
315 struct dtp_val raw_ispecs;
316 struct llist_header ext_ispecs;
321 struct dtspec_map* map;
328 struct dtn_base base;
331 struct dtn_intr intr;
335 struct dtp_val ranges;
336 struct dtp_val dma_ranges;
338 #define dt_parent(node) ((node)->base.parent)
339 #define dt_morpher morphable_attrs(dtn, mobj)
340 #define dt_mobj(node) (&(node)->mobj)
341 #define dt_name(node) morpher_name(dt_mobj(node))
342 #define dtn_from(base_node) \
343 (container_of(base_node, struct dtn, base))
347 struct dtn_base* head;
348 struct dtn_base* matched;
350 node_predicate_t pred;
357 struct llist_header nodes;
359 struct hbucket phnds_table[16];
360 const char *str_block;
364 /////////////////////////////////
366 /////////////////////////////////
368 #define fdt_prop(tok) ((tok)->token == FDT_PROP)
369 #define fdt_node(tok) ((tok)->token == FDT_NOD_BEGIN)
370 #define fdt_nope(tok) ((tok)->token == FDT_NOP)
371 #define fdt_eof(tok) ((tok)->token == FDT_END)
372 #define fdt_node_end(tok) \
373 ((tok)->token == FDT_NOD_END || (tok)->token == FDT_END)
376 fdt_load(struct fdt_blob* fdt, ptr_t base);
379 fdt_next_token(fdt_loc_t loc, int* depth);
382 fdt_next_sibling(fdt_loc_t loc, fdt_loc_t* loc_out);
385 fdt_next_boot_rsvdmem(struct fdt_blob*, fdt_loc_t*, struct dt_memory_node*);
388 fdt_descend_into(fdt_loc_t loc);
390 static inline fdt_loc_t
391 fdt_ascend_from(fdt_loc_t loc)
393 while (fdt_next_sibling(loc, &loc));
400 fdt_memscan_begin(struct fdt_memscan*, const struct fdt_blob*);
403 fdt_memscan_nextnode(struct fdt_memscan*, struct fdt_blob*);
406 fdt_memscan_nextrange(struct fdt_memscan*, struct dt_memory_node*);
409 fdt_find_prop(const struct fdt_blob*, fdt_loc_t,
410 const char*, struct dtp_val*);
413 fdt_prop_key(struct fdt_blob* fdt, fdt_loc_t loc)
415 return &fdt->str_block[loc.prop->nameoff];
419 /////////////////////////////////
420 /// DT General Methods
421 /////////////////////////////////
424 dt_load(ptr_t dtb_dropoff);
427 dt_resolve_phandle(dt_phnd_t phandle);
430 dt_getprop(struct dtn_base* base, const char* name);
433 dt_resolve_interrupt_map(struct dtn* node);
436 dt_interrupt_at(struct dtn* node, int idx, struct dtp_val* int_spec);
439 dtp_val_set(struct dtp_val* val, dt_enc_t raw, unsigned cells)
442 val->size = cells * sizeof(u32_t);
446 dtn_bind_object(struct dtn* node, morph_t* mobj)
448 node->base.binded_obj = changeling_ref(mobj);
452 //////////////////////////////////////
453 /// DT Methods: Specifier Map
454 //////////////////////////////////////
457 struct dtspec_create_ops
459 int (*child_keysz)(struct dtn*);
460 int (*parent_keysz)(struct dtn*);
461 struct dtp_val* (*get_mask)(struct dtn*);
462 struct dtp_val* (*get_passthru)(struct dtn*);
466 dtspec_create(struct dtn* node, struct dtp_val* map,
467 const struct dtspec_create_ops* ops);
469 struct dtspec_mapent*
470 dtspec_lookup(struct dtspec_map*, struct dtspec_key*);
473 dtspec_applymask(struct dtspec_map*, struct dtspec_key*);
476 dtspec_free(struct dtspec_map*);
479 dtspec_cpykey(struct dtspec_key* dest, struct dtspec_key* src);
482 dtspec_freekey(struct dtspec_key* key);
485 dtspec_nullkey(struct dtspec_key* key)
487 return !key || !key->size;
491 //////////////////////////////////////
492 /// DT Methods: Node query
493 //////////////////////////////////////
496 dt_begin_find_byname(struct dtn_iter* iter,
497 struct dtn* node, const char* name);
500 dt_begin_find(struct dtn_iter* iter, struct dtn* node,
501 node_predicate_t pred, void* closure);
504 dt_end_find(struct dtn_iter* iter)
506 // currently do nothing, keep only for semantic
510 dt_find_next(struct dtn_iter* iter,
511 struct dtn_base** matched);
514 dt_found_any(struct dtn_iter* iter)
516 return !!iter->matched;
523 dtp_u32(struct dtp_val* val)
525 return val->ref->u32_val;
529 dtp_u64(struct dtp_val* val)
531 return val->ref->u64_val;
535 dtp_speckey(struct dtspec_key* key, struct dtp_val* prop)
537 key->size = prop->size / sizeof(u32_t);
538 key->val = prop->encoded;
542 //////////////////////////////////////
543 /// DT Prop Extractor
544 //////////////////////////////////////
559 enum dtprop_types type;
562 typedef struct dtprop_def dt_proplet[];
572 union dtp_baseval* cval;
575 struct dtprop_def* archetype;
580 const struct dtprop_def* proplet;
588 #define dtprop_u32 (struct dtprop_def){ 1, 0, DTP_U32 }
589 #define dtprop_u64 (struct dtprop_def){ 2, 0, DTP_U64 }
590 #define dtprop_handle (struct dtprop_def){ 1, 0, DTP_PHANDLE }
591 #define dtprop_compx(cell) (struct dtprop_def){ cell, 0, DTP_COMPX }
592 #define dtprop_end (struct dtprop_def){ 0, 0, DTP_END }
593 #define dtprop_(type, cell) (struct dtprop_def){ cell, 0, type }
595 #define dtprop_reglike(base) \
598 dtprop_compx((base)->addr_c), \
599 dtprop_compx((base)->sz_c), \
605 #define dtprop_rangelike(node) \
608 dtprop_compx(base->addr_c), \
609 dtprop_compx(base->parent->addr_c), \
610 dtprop_compx(base->sz_c), \
616 #define dtprop_strlst_foreach(pos, prop) \
617 for (pos = (prop)->str_lst; \
618 pos <= &(prop)->str_lst[(prop)->size - 1]; \
619 pos = &pos[strlen(pos) + 1])
622 dtpx_compile_proplet(struct dtprop_def* proplet);
625 dtpx_prepare_with(struct dtpropx* propx, struct dtp_val* prop,
626 struct dtprop_def* proplet);
628 #define dtproplet_compile(proplet) \
629 dtpx_compile_proplet(proplet, \
630 sizeof(proplet) / sizeof(struct dtprop_def))
633 dtpx_goto_row(struct dtpropx*, int row);
636 dtpx_next_row(struct dtpropx*);
639 dtpx_extract_at(struct dtpropx*, struct dtprop_xval*, int col);
642 dtpx_extract_loc(struct dtpropx*, struct dtprop_xval*,
646 dtpx_extract_row(struct dtpropx*, struct dtprop_xval*, int len);
649 dtpx_xvalu32(struct dtprop_xval* val){
650 return val->archetype->type == DTP_COMPX ?
651 val->cval->u32_val : val->u32;
655 dtpx_xvalu64(struct dtprop_xval* val){
656 return val->archetype->type == DTP_COMPX ?
657 val->cval->u64_val : val->u64;
661 //////////////////////////////////////
663 //////////////////////////////////////
666 dtpi_init(struct dtpropi* dtpi, struct dtp_val* val)
668 *dtpi = (struct dtpropi) {
675 dtpi_init_empty(struct dtpropi* dtpi)
677 *dtpi = (struct dtpropi) {
684 dtpi_is_empty(struct dtpropi* dtpi)
686 return !dtpi->prop.size;
690 dtpi_has_next(struct dtpropi* dtpi)
692 return dtpi->loc < dtpi->prop.size / sizeof(u32_t);
696 dtpi_next_u32(struct dtpropi* dtpi)
698 union dtp_baseval* val;
699 val = (union dtp_baseval*)&dtpi->prop.encoded[dtpi->loc++];
704 dtpi_next_u64(struct dtpropi* dtpi)
706 union dtp_baseval* val;
707 off_t loc = dtpi->loc;
709 val = (union dtp_baseval*)&dtpi->prop.encoded[loc];
714 static inline struct dtn*
715 dtpi_next_hnd(struct dtpropi* dtpi)
718 phandle = dtpi_next_u32(dtpi);
719 return dt_resolve_phandle(phandle);
723 dtpi_next_val(struct dtpropi* dtpi, struct dtp_val* val, int cells)
725 if (!dtpi_has_next(dtpi)) {
729 off_t loc = dtpi->loc;
730 dtp_val_set(val, &dtpi->prop.encoded[loc], cells);
736 #endif /* __LUNAIX_DEVTREE_H */