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 //////////////////////////////////////
447 /// DT Methods: Specifier Map
448 //////////////////////////////////////
451 struct dtspec_create_ops
453 int (*child_keysz)(struct dtn*);
454 int (*parent_keysz)(struct dtn*);
455 struct dtp_val* (*get_mask)(struct dtn*);
456 struct dtp_val* (*get_passthru)(struct dtn*);
460 dtspec_create(struct dtn* node, struct dtp_val* map,
461 const struct dtspec_create_ops* ops);
463 struct dtspec_mapent*
464 dtspec_lookup(struct dtspec_map*, struct dtspec_key*);
467 dtspec_applymask(struct dtspec_map*, struct dtspec_key*);
470 dtspec_free(struct dtspec_map*);
473 dtspec_cpykey(struct dtspec_key* dest, struct dtspec_key* src);
476 dtspec_freekey(struct dtspec_key* key);
479 dtspec_nullkey(struct dtspec_key* key)
481 return !key || !key->size;
485 //////////////////////////////////////
486 /// DT Methods: Node query
487 //////////////////////////////////////
490 dt_begin_find_byname(struct dtn_iter* iter,
491 struct dtn* node, const char* name);
494 dt_begin_find(struct dtn_iter* iter, struct dtn* node,
495 node_predicate_t pred, void* closure);
498 dt_end_find(struct dtn_iter* iter)
500 // currently do nothing, keep only for semantic
504 dt_find_next(struct dtn_iter* iter,
505 struct dtn_base** matched);
508 dt_found_any(struct dtn_iter* iter)
510 return !!iter->matched;
517 dtp_u32(struct dtp_val* val)
519 return val->ref->u32_val;
523 dtp_u64(struct dtp_val* val)
525 return val->ref->u64_val;
529 dtp_speckey(struct dtspec_key* key, struct dtp_val* prop)
531 key->size = prop->size / sizeof(u32_t);
532 key->val = prop->encoded;
536 //////////////////////////////////////
537 /// DT Prop Extractor
538 //////////////////////////////////////
553 enum dtprop_types type;
556 typedef struct dtprop_def dt_proplet[];
566 union dtp_baseval* cval;
569 struct dtprop_def* archetype;
574 const struct dtprop_def* proplet;
582 #define dtprop_u32 (struct dtprop_def){ 1, 0, DTP_U32 }
583 #define dtprop_u64 (struct dtprop_def){ 2, 0, DTP_U64 }
584 #define dtprop_handle (struct dtprop_def){ 1, 0, DTP_PHANDLE }
585 #define dtprop_compx(cell) (struct dtprop_def){ cell, 0, DTP_COMPX }
586 #define dtprop_end (struct dtprop_def){ 0, 0, DTP_END }
587 #define dtprop_(type, cell) (struct dtprop_def){ cell, 0, type }
589 #define dtprop_reglike(base) \
592 dtprop_compx(base->addr_c), \
593 dtprop_compx(base->sz_c), \
599 #define dtprop_rangelike(node) \
602 dtprop_compx(base->addr_c), \
603 dtprop_compx(base->parent->addr_c), \
604 dtprop_compx(base->sz_c), \
610 #define dtprop_strlst_foreach(pos, prop) \
611 for (pos = (prop)->str_lst; \
612 pos <= &(prop)->str_lst[(prop)->size - 1]; \
613 pos = &pos[strlen(pos) + 1])
616 dtpx_compile_proplet(struct dtprop_def* proplet);
619 dtpx_prepare_with(struct dtpropx* propx, struct dtp_val* prop,
620 struct dtprop_def* proplet);
622 #define dtproplet_compile(proplet) \
623 dtpx_compile_proplet(proplet, \
624 sizeof(proplet) / sizeof(struct dtprop_def))
627 dtpx_goto_row(struct dtpropx*, int row);
630 dtpx_next_row(struct dtpropx*);
633 dtpx_extract_at(struct dtpropx*, struct dtprop_xval*, int col);
636 dtpx_extract_loc(struct dtpropx*, struct dtprop_xval*,
640 dtpx_extract_row(struct dtpropx*, struct dtprop_xval*, int len);
643 dtpx_xvalu32(struct dtprop_xval* val){
644 return val->archetype->type == DTP_COMPX ?
645 val->cval->u32_val : val->u32;
649 dtpx_xvalu64(struct dtprop_xval* val){
650 return val->archetype->type == DTP_COMPX ?
651 val->cval->u64_val : val->u64;
655 //////////////////////////////////////
657 //////////////////////////////////////
660 dtpi_init(struct dtpropi* dtpi, struct dtp_val* val)
662 *dtpi = (struct dtpropi) {
669 dtpi_init_empty(struct dtpropi* dtpi)
671 *dtpi = (struct dtpropi) {
678 dtpi_is_empty(struct dtpropi* dtpi)
680 return !dtpi->prop.size;
684 dtpi_has_next(struct dtpropi* dtpi)
686 return dtpi->loc < dtpi->prop.size / sizeof(u32_t);
690 dtpi_next_u32(struct dtpropi* dtpi)
692 union dtp_baseval* val;
693 val = (union dtp_baseval*)&dtpi->prop.encoded[dtpi->loc++];
698 dtpi_next_u64(struct dtpropi* dtpi)
700 union dtp_baseval* val;
701 off_t loc = dtpi->loc;
703 val = (union dtp_baseval*)&dtpi->prop.encoded[loc];
708 static inline struct dtn*
709 dtpi_next_hnd(struct dtpropi* dtpi)
712 phandle = dtpi_next_u32(dtpi);
713 return dt_resolve_phandle(phandle);
717 dtpi_next_val(struct dtpropi* dtpi, struct dtp_val* val, int cells)
719 if (!dtpi_has_next(dtpi)) {
723 off_t loc = dtpi->loc;
724 dtp_val_set(val, &dtpi->prop.encoded[loc], cells);
730 #endif /* __LUNAIX_DEVTREE_H */