1 #ifndef __LUNAIX_DEVTREE_H
2 #define __LUNAIX_DEVTREE_H
4 #ifdef CONFIG_USE_DEVICETREE
5 #include <lunaix/types.h>
6 #include <lunaix/ds/llist.h>
7 #include <lunaix/ds/hstr.h>
8 #include <lunaix/ds/hashtable.h>
9 #include <lunaix/changeling.h>
11 #include <klibc/string.h>
13 #define FDT_MAGIC 0xd00dfeedU
14 #define FDT_NOD_BEGIN 0x00000001U
15 #define FDT_NOD_END 0x00000002U
16 #define FDT_PROP 0x00000003U
17 #define FDT_NOP 0x00000004U
18 #define FDT_END 0x00000009U
21 #define STATUS_DISABLE 1
25 #define PHND_NULL ((dt_phnd_t)-1)
27 /////////////////////////////////
29 /////////////////////////////////
31 typedef unsigned int* dt_enc_t;
32 typedef unsigned int dt_phnd_t;
36 typedef bool (*node_predicate_t)(struct dtn_iter*, struct dtn_base*);
53 union dtp_baseval* ref;
68 /////////////////////////////////
70 /////////////////////////////////
79 u32_t last_comp_version;
80 u32_t boot_cpuid_phys;
81 u32_t size_dt_strings;
85 struct fdt_memrsvd_ent
95 } _be compact align(4);
99 struct fdt_token token;
107 } _be compact align(4);
112 struct fdt_token *token;
113 struct fdt_prop *prop;
114 struct fdt_memrsvd_ent *rsvd_ent;
117 struct fdt_token token;
122 typedef struct fdt_loc fdt_loc_t;
140 FDT_MEM_RSVD_DYNAMIC,
144 struct fdt_rsvdmem_attrs
158 struct dt_memory_node
162 enum fdt_mem_type type;
164 struct fdt_rsvdmem_attrs dyn_alloc_attr;
176 struct fdt_header* header;
182 const char* str_block;
183 ptr_t str_block_base;
188 struct fdt_rsvd_mem* plat_rsvd;
189 ptr_t plat_rsvd_base;
198 struct dtpropi regit;
202 enum fdt_mem_type node_type;
204 struct fdt_rsvdmem_attrs node_attr;
207 struct fdt_memrsvd_iter
209 struct fdt_memrsvd_ent *block;
213 /////////////////////////////////
215 /////////////////////////////////
219 struct hlist_node ht;
227 struct hbucket other_props[0];
228 struct hbucket _op_bucket[8];
238 unsigned char addr_c;
240 unsigned char intr_c;
241 unsigned char status;
248 bool dma_coherent : 1;
249 bool dma_ncoherent : 1;
250 bool intr_controll : 1;
255 struct dtn_base *parent;
256 struct llist_header nodes;
258 struct dtp_val compat;
261 struct dtp_table *props;
269 union dtp_baseval *bval;
277 struct llist_header ents;
278 const struct dtspec_key child_spec;
281 const struct dtspec_key parent_spec;
286 const struct dtspec_key mask;
287 const struct dtspec_key pass_thru;
289 struct llist_header ents;
296 struct llist_header ispecs;
304 dt_phnd_t parent_hnd;
316 struct dtp_val raw_ispecs;
317 struct llist_header ext_ispecs;
322 struct dtspec_map* map;
329 struct dtn_base base;
332 struct dtn_intr intr;
336 struct dtp_val ranges;
337 struct dtp_val dma_ranges;
339 #define dt_parent(node) ((node)->base.parent)
340 #define dt_morpher morphable_attrs(dtn, mobj)
341 #define dt_mobj(node) (&(node)->mobj)
342 #define dt_name(node) morpher_name(dt_mobj(node))
343 #define dtn_from(base_node) \
344 (container_of(base_node, struct dtn, base))
348 struct dtn_base* head;
349 struct dtn_base* matched;
351 node_predicate_t pred;
358 struct llist_header nodes;
360 struct hbucket phnds_table[16];
361 const char *str_block;
365 /////////////////////////////////
367 /////////////////////////////////
369 #define fdt_prop(tok) ((tok)->token == FDT_PROP)
370 #define fdt_node(tok) ((tok)->token == FDT_NOD_BEGIN)
371 #define fdt_nope(tok) ((tok)->token == FDT_NOP)
372 #define fdt_eof(tok) ((tok)->token == FDT_END)
373 #define fdt_node_end(tok) \
374 ((tok)->token == FDT_NOD_END || (tok)->token == FDT_END)
377 fdt_load(struct fdt_blob* fdt, ptr_t base);
380 fdt_next_token(fdt_loc_t loc, int* depth);
383 fdt_next_sibling(fdt_loc_t loc, fdt_loc_t* loc_out);
386 fdt_next_boot_rsvdmem(struct fdt_blob*, fdt_loc_t*, struct dt_memory_node*);
389 fdt_descend_into(fdt_loc_t loc);
391 static inline fdt_loc_t
392 fdt_ascend_from(fdt_loc_t loc)
394 while (fdt_next_sibling(loc, &loc));
401 fdt_memscan_begin(struct fdt_memscan*, const struct fdt_blob*);
404 fdt_memscan_nextnode(struct fdt_memscan*, struct fdt_blob*);
407 fdt_memscan_nextrange(struct fdt_memscan*, struct dt_memory_node*);
410 fdt_find_prop(const struct fdt_blob*, fdt_loc_t,
411 const char*, struct dtp_val*);
414 fdt_prop_key(struct fdt_blob* fdt, fdt_loc_t loc)
416 return &fdt->str_block[loc.prop->nameoff];
420 /////////////////////////////////
421 /// DT General Methods
422 /////////////////////////////////
425 dt_load(ptr_t dtb_dropoff);
428 dt_resolve_phandle(dt_phnd_t phandle);
431 dt_getprop(struct dtn_base* base, const char* name);
434 dt_resolve_interrupt_map(struct dtn* node);
437 dt_interrupt_at(struct dtn* node, int idx, struct dtp_val* int_spec);
440 dtp_val_set(struct dtp_val* val, dt_enc_t raw, unsigned cells)
443 val->size = cells * sizeof(u32_t);
447 //////////////////////////////////////
448 /// DT Methods: Specifier Map
449 //////////////////////////////////////
452 struct dtspec_create_ops
454 int (*child_keysz)(struct dtn*);
455 int (*parent_keysz)(struct dtn*);
456 struct dtp_val* (*get_mask)(struct dtn*);
457 struct dtp_val* (*get_passthru)(struct dtn*);
461 dtspec_create(struct dtn* node, struct dtp_val* map,
462 const struct dtspec_create_ops* ops);
464 struct dtspec_mapent*
465 dtspec_lookup(struct dtspec_map*, struct dtspec_key*);
468 dtspec_applymask(struct dtspec_map*, struct dtspec_key*);
471 dtspec_free(struct dtspec_map*);
474 dtspec_cpykey(struct dtspec_key* dest, struct dtspec_key* src);
477 dtspec_freekey(struct dtspec_key* key);
480 dtspec_nullkey(struct dtspec_key* key)
482 return !key || !key->size;
486 //////////////////////////////////////
487 /// DT Methods: Node query
488 //////////////////////////////////////
491 dt_begin_find_byname(struct dtn_iter* iter,
492 struct dtn* node, const char* name);
495 dt_begin_find(struct dtn_iter* iter, struct dtn* node,
496 node_predicate_t pred, void* closure);
499 dt_end_find(struct dtn_iter* iter)
501 // currently do nothing, keep only for semantic
505 dt_find_next(struct dtn_iter* iter,
506 struct dtn_base** matched);
509 dt_found_any(struct dtn_iter* iter)
511 return !!iter->matched;
518 dtp_u32(struct dtp_val* val)
520 return val->ref->u32_val;
524 dtp_u64(struct dtp_val* val)
526 return val->ref->u64_val;
530 dtp_speckey(struct dtspec_key* key, struct dtp_val* prop)
532 key->size = prop->size / sizeof(u32_t);
533 key->val = prop->encoded;
537 //////////////////////////////////////
538 /// DT Prop Extractor
539 //////////////////////////////////////
554 enum dtprop_types type;
557 typedef struct dtprop_def dt_proplet[];
567 union dtp_baseval* cval;
570 struct dtprop_def* archetype;
575 const struct dtprop_def* proplet;
583 #define dtprop_u32 (struct dtprop_def){ 1, 0, DTP_U32 }
584 #define dtprop_u64 (struct dtprop_def){ 2, 0, DTP_U64 }
585 #define dtprop_handle (struct dtprop_def){ 1, 0, DTP_PHANDLE }
586 #define dtprop_compx(cell) (struct dtprop_def){ cell, 0, DTP_COMPX }
587 #define dtprop_end (struct dtprop_def){ 0, 0, DTP_END }
588 #define dtprop_(type, cell) (struct dtprop_def){ cell, 0, type }
590 #define dtprop_reglike(base) \
593 dtprop_compx(base->addr_c), \
594 dtprop_compx(base->sz_c), \
600 #define dtprop_rangelike(node) \
603 dtprop_compx(base->addr_c), \
604 dtprop_compx(base->parent->addr_c), \
605 dtprop_compx(base->sz_c), \
611 #define dtprop_strlst_foreach(pos, prop) \
612 for (pos = (prop)->str_lst; \
613 pos <= &(prop)->str_lst[(prop)->size - 1]; \
614 pos = &pos[strlen(pos) + 1])
617 dtpx_compile_proplet(struct dtprop_def* proplet);
620 dtpx_prepare_with(struct dtpropx* propx, struct dtp_val* prop,
621 struct dtprop_def* proplet);
623 #define dtproplet_compile(proplet) \
624 dtpx_compile_proplet(proplet, \
625 sizeof(proplet) / sizeof(struct dtprop_def))
628 dtpx_goto_row(struct dtpropx*, int row);
631 dtpx_next_row(struct dtpropx*);
634 dtpx_extract_at(struct dtpropx*, struct dtprop_xval*, int col);
637 dtpx_extract_loc(struct dtpropx*, struct dtprop_xval*,
641 dtpx_extract_row(struct dtpropx*, struct dtprop_xval*, int len);
644 dtpx_xvalu32(struct dtprop_xval* val){
645 return val->archetype->type == DTP_COMPX ?
646 val->cval->u32_val : val->u32;
650 dtpx_xvalu64(struct dtprop_xval* val){
651 return val->archetype->type == DTP_COMPX ?
652 val->cval->u64_val : val->u64;
656 //////////////////////////////////////
658 //////////////////////////////////////
661 dtpi_init(struct dtpropi* dtpi, struct dtp_val* val)
663 *dtpi = (struct dtpropi) {
670 dtpi_init_empty(struct dtpropi* dtpi)
672 *dtpi = (struct dtpropi) {
679 dtpi_is_empty(struct dtpropi* dtpi)
681 return !dtpi->prop.size;
685 dtpi_has_next(struct dtpropi* dtpi)
687 return dtpi->loc < dtpi->prop.size / sizeof(u32_t);
691 dtpi_next_u32(struct dtpropi* dtpi)
693 union dtp_baseval* val;
694 val = (union dtp_baseval*)&dtpi->prop.encoded[dtpi->loc++];
699 dtpi_next_u64(struct dtpropi* dtpi)
701 union dtp_baseval* val;
702 off_t loc = dtpi->loc;
704 val = (union dtp_baseval*)&dtpi->prop.encoded[loc];
709 static inline struct dtn*
710 dtpi_next_hnd(struct dtpropi* dtpi)
713 phandle = dtpi_next_u32(dtpi);
714 return dt_resolve_phandle(phandle);
718 dtpi_next_val(struct dtpropi* dtpi, struct dtp_val* val, int cells)
720 if (!dtpi_has_next(dtpi)) {
724 off_t loc = dtpi->loc;
725 dtp_val_set(val, &dtpi->prop.encoded[loc], cells);
732 #endif /* __LUNAIX_DEVTREE_H */