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 dtn_bind_object(struct dtn* node, morph_t* mobj)
449 node->base.binded_obj = changeling_ref(mobj);
453 //////////////////////////////////////
454 /// DT Methods: Specifier Map
455 //////////////////////////////////////
458 struct dtspec_create_ops
460 int (*child_keysz)(struct dtn*);
461 int (*parent_keysz)(struct dtn*);
462 struct dtp_val* (*get_mask)(struct dtn*);
463 struct dtp_val* (*get_passthru)(struct dtn*);
467 dtspec_create(struct dtn* node, struct dtp_val* map,
468 const struct dtspec_create_ops* ops);
470 struct dtspec_mapent*
471 dtspec_lookup(struct dtspec_map*, struct dtspec_key*);
474 dtspec_applymask(struct dtspec_map*, struct dtspec_key*);
477 dtspec_free(struct dtspec_map*);
480 dtspec_cpykey(struct dtspec_key* dest, struct dtspec_key* src);
483 dtspec_freekey(struct dtspec_key* key);
486 dtspec_nullkey(struct dtspec_key* key)
488 return !key || !key->size;
492 //////////////////////////////////////
493 /// DT Methods: Node query
494 //////////////////////////////////////
497 dt_begin_find_byname(struct dtn_iter* iter,
498 struct dtn* node, const char* name);
501 dt_begin_find(struct dtn_iter* iter, struct dtn* node,
502 node_predicate_t pred, void* closure);
505 dt_end_find(struct dtn_iter* iter)
507 // currently do nothing, keep only for semantic
511 dt_find_next(struct dtn_iter* iter,
512 struct dtn_base** matched);
515 dt_found_any(struct dtn_iter* iter)
517 return !!iter->matched;
524 dtp_u32(struct dtp_val* val)
526 return val->ref->u32_val;
530 dtp_u64(struct dtp_val* val)
532 return val->ref->u64_val;
536 dtp_speckey(struct dtspec_key* key, struct dtp_val* prop)
538 key->size = prop->size / sizeof(u32_t);
539 key->val = prop->encoded;
543 //////////////////////////////////////
544 /// DT Prop Extractor
545 //////////////////////////////////////
560 enum dtprop_types type;
563 typedef struct dtprop_def dt_proplet[];
573 union dtp_baseval* cval;
576 struct dtprop_def* archetype;
581 const struct dtprop_def* proplet;
589 #define dtprop_u32 (struct dtprop_def){ 1, 0, DTP_U32 }
590 #define dtprop_u64 (struct dtprop_def){ 2, 0, DTP_U64 }
591 #define dtprop_handle (struct dtprop_def){ 1, 0, DTP_PHANDLE }
592 #define dtprop_compx(cell) (struct dtprop_def){ cell, 0, DTP_COMPX }
593 #define dtprop_end (struct dtprop_def){ 0, 0, DTP_END }
594 #define dtprop_(type, cell) (struct dtprop_def){ cell, 0, type }
596 #define dtprop_reglike(base) \
599 dtprop_compx((base)->addr_c), \
600 dtprop_compx((base)->sz_c), \
606 #define dtprop_rangelike(node) \
609 dtprop_compx(base->addr_c), \
610 dtprop_compx(base->parent->addr_c), \
611 dtprop_compx(base->sz_c), \
617 #define dtprop_strlst_foreach(pos, prop) \
618 for (pos = (prop)->str_lst; \
619 pos <= &(prop)->str_lst[(prop)->size - 1]; \
620 pos = &pos[strlen(pos) + 1])
623 dtpx_compile_proplet(struct dtprop_def* proplet);
626 dtpx_prepare_with(struct dtpropx* propx, struct dtp_val* prop,
627 struct dtprop_def* proplet);
629 #define dtproplet_compile(proplet) \
630 dtpx_compile_proplet(proplet, \
631 sizeof(proplet) / sizeof(struct dtprop_def))
634 dtpx_goto_row(struct dtpropx*, int row);
637 dtpx_next_row(struct dtpropx*);
640 dtpx_extract_at(struct dtpropx*, struct dtprop_xval*, int col);
643 dtpx_extract_loc(struct dtpropx*, struct dtprop_xval*,
647 dtpx_extract_row(struct dtpropx*, struct dtprop_xval*, int len);
650 dtpx_xvalu32(struct dtprop_xval* val){
651 return val->archetype->type == DTP_COMPX ?
652 val->cval->u32_val : val->u32;
656 dtpx_xvalu64(struct dtprop_xval* val){
657 return val->archetype->type == DTP_COMPX ?
658 val->cval->u64_val : val->u64;
662 //////////////////////////////////////
664 //////////////////////////////////////
667 dtpi_init(struct dtpropi* dtpi, struct dtp_val* val)
669 *dtpi = (struct dtpropi) {
676 dtpi_init_empty(struct dtpropi* dtpi)
678 *dtpi = (struct dtpropi) {
685 dtpi_is_empty(struct dtpropi* dtpi)
687 return !dtpi->prop.size;
691 dtpi_has_next(struct dtpropi* dtpi)
693 return dtpi->loc < dtpi->prop.size / sizeof(u32_t);
697 dtpi_next_integer(struct dtpropi* dtpi, int int_cells)
699 union dtp_baseval* val;
700 off_t loc = dtpi->loc;
701 dtpi->loc += int_cells;
702 val = (union dtp_baseval*)&dtpi->prop.encoded[loc];
704 return int_cells == 1 ? val->u32_val : val->u64_val;
708 dtpi_next_u64(struct dtpropi* dtpi)
710 return dtpi_next_integer(dtpi, 2);
714 dtpi_next_u32(struct dtpropi* dtpi)
716 return (u32_t)dtpi_next_integer(dtpi, 1);
719 static inline struct dtn*
720 dtpi_next_hnd(struct dtpropi* dtpi)
723 phandle = dtpi_next_u32(dtpi);
724 return dt_resolve_phandle(phandle);
728 dtpi_next_val(struct dtpropi* dtpi, struct dtp_val* val, int cells)
730 if (!dtpi_has_next(dtpi)) {
734 off_t loc = dtpi->loc;
735 dtp_val_set(val, &dtpi->prop.encoded[loc], cells);
742 #endif /* __LUNAIX_DEVTREE_H */