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>
10 #define le(v) ((((v) >> 24) & 0x000000ff) |\
11 (((v) << 8) & 0x00ff0000) |\
12 (((v) >> 8) & 0x0000ff00) |\
13 (((v) << 24) & 0xff000000))
15 #define le64(v) (((u64_t)le(v & 0xffffffff) << 32) | le(v >> 32))
17 #define be(v) ((((v) << 24) & 0x000000ff) |\
18 (((v) >> 8) & 0x00ff0000) |\
19 (((v) << 8) & 0x0000ff00) |\
20 (((v) >> 24) & 0xff000000))
22 #define FDT_MAGIC be(0xd00dfeed)
23 #define FDT_NOD_BEGIN be(0x00000001)
24 #define FDT_NOD_END be(0x00000002)
25 #define FDT_PROP be(0x00000003)
26 #define FDT_NOP be(0x00000004)
27 #define FDT_END be(0x00000009)
30 #define STATUS_DISABLE 1
35 typedef unsigned int* dt_enc_t;
36 typedef unsigned int dt_phnd_t;
38 #define PHND_NULL ((dt_phnd_t)-1)
47 u32_t last_comp_version;
48 u32_t boot_cpuid_phys;
49 u32_t size_dt_strings;
53 struct fdt_memrsvd_ent
66 struct fdt_token token;
72 struct fdt_token token;
103 struct hlist_node ht;
105 struct dt_prop_val val;
112 unsigned char addr_c;
114 unsigned char intr_c;
115 unsigned char status;
122 bool dma_coherent : 1;
123 bool dma_ncoherent : 1;
124 bool intr_controll : 1;
125 unsigned int other : 29;
130 struct dt_node_base *parent;
131 struct llist_header children;
132 struct llist_header siblings;
133 struct llist_header nodes;
134 struct hlist_node phnd_link;
138 struct dt_prop_val compat;
143 struct hbucket other_props[0];
144 struct hbucket _op_bucket[8];
150 struct dt_node_base base;
161 struct dt_intr_node *parent;
162 dt_phnd_t parent_hnd;
168 struct dt_prop_val arr;
169 struct llist_header values;
173 struct dt_prop_val intr_map;
174 struct dt_prop_val intr_map_mask;
176 #define DT_NODE(intr_node) \
177 (container_of(intr_node, struct dt_node, intr))
182 struct dt_node_base base;
183 struct dt_intr_node intr;
185 struct dt_prop_val reg;
186 struct dt_prop_val vreg;
188 struct dt_prop_val ranges;
189 struct dt_prop_val dma_ranges;
195 struct dt_intr_node *master;
197 struct llist_header props;
198 struct dt_prop_val val;
203 struct dt_prop_val *prop;
204 struct dt_node_base *node;
206 dt_enc_t prop_loc_next;
214 struct fdt_header* fdt;
217 struct llist_header nodes;
218 struct dt_root *root;
219 struct hbucket phnds_table[16];
220 const char *str_block;
226 struct fdt_token *pos;
227 struct fdt_prop *prop;
228 struct fdt_node_head *node_head;
231 const char* str_block;
235 struct fdt_memrsvd_iter
237 struct fdt_memrsvd_ent *block;
242 struct dt_node_base* head;
243 struct dt_node_base* matched;
247 #define dtnode_child_foreach(node_base, pos, n) \
248 llist_for_each(pos, n, &(node_base)->children, siblings)
250 #define fdt_prop(tok) ((tok)->token == FDT_PROP)
251 #define fdt_node(tok) ((tok)->token == FDT_NOD_BEGIN)
252 #define fdt_node_end(tok) ((tok)->token == FDT_NOD_END)
253 #define fdt_nope(tok) ((tok)->token == FDT_NOP)
256 fdt_itbegin(struct fdt_iter* fdti, struct fdt_header* fdt_hdr);
259 fdt_itend(struct fdt_iter* fdti);
262 fdt_itnext(struct fdt_iter* fdti);
265 fdt_itnext_at(struct fdt_iter* fdti, int level);
268 fdt_memrsvd_itbegin(struct fdt_memrsvd_iter* rsvdi,
269 struct fdt_header* fdt_hdr);
272 fdt_memrsvd_itnext(struct fdt_memrsvd_iter* rsvdi);
275 fdt_memrsvd_itend(struct fdt_memrsvd_iter* rsvdi);
279 dt_load(ptr_t dtb_dropoff);
282 dt_resolve_phandle(dt_phnd_t phandle);
285 dt_getprop(struct dt_node* node, const char* name);
288 dt_begin_find(struct dt_node_iter* iter,
289 struct dt_node* node, const char* name);
292 dt_find_next(struct dt_node_iter* iter,
293 struct dt_node_base** matched);
296 dt_found_any(struct dt_node_iter* iter)
298 return !!iter->matched;
303 fdtit_prop_key(struct fdt_iter* fdti)
305 return &fdti->str_block[fdti->prop->nameoff];
309 dt_decode(struct dt_prop_iter* dtpi, struct dt_node_base* node,
310 struct dt_prop_val* val, unsigned int ent_sz)
312 *dtpi = (struct dt_prop_iter) {
315 .prop_loc = val->encoded,
316 .prop_loc_next = val->encoded,
321 #define dt_decode_reg(dtpi, node, field) \
322 dt_decode(dtpi, &(node)->base, &(node)->field, \
323 (node)->base.sz_c + (node)->base.addr_c);
325 #define dt_decode_range(dtpi, node, field) \
326 dt_decode(dtpi, &(node)->base, &(node)->field, \
327 (node)->base.sz_c * 2 + (node)->base.addr_c);
330 dt_decode_intrmap(struct dt_prop_iter* dtpi,
331 struct dt_intr_node* intr_node)
334 struct dt_node* node;
335 struct dt_node_base* base;
337 node = DT_NODE(intr_node);
339 size = (base->addr_c + base->intr_c) * 2 + 1;
341 dt_decode(dtpi, base, &intr_node->intr_map, size);
344 #define dtprop_off(dtpi) \
346 __ptr(dtpi->prop_loc_next) - __ptr(dtpi->prop->encoded) \
349 #define dtprop_extract(dtpi, off) \
350 ( (dt_enc_t) (&(dtpi)->prop_loc[(off)]) )
353 dtprop_next_n(struct dt_prop_iter* dtpi, int n)
357 dtpi->prop_loc = dtpi->prop_loc_next;
358 dtpi->prop_loc_next += n;
360 off = dtprop_off(dtpi);
361 return off >= dtpi->prop->size;
365 dtprop_prev_n(struct dt_prop_iter* dtpi, int n)
369 off = dtprop_off(dtpi);
370 if (!off || off > dtpi->prop->size) {
374 dtpi->prop_loc = dtpi->prop_loc_next;
375 dtpi->prop_loc_next -= n;
381 dtprop_next(struct dt_prop_iter* dtpi)
383 return dtprop_next_n(dtpi, dtpi->ent_sz);
387 dtprop_prev(struct dt_prop_iter* dtpi)
389 return dtprop_prev_n(dtpi, dtpi->ent_sz);
392 static inline unsigned int
393 dtprop_to_u32(dt_enc_t enc_val)
398 #define dtprop_to_phnd(enc_val) \
399 (dt_phnd_t)dtprop_to_u32(enc_val)
402 dtprop_to_u64(dt_enc_t enc_val)
404 return le64(*(u64_t*)enc_val);
407 static inline dt_enc_t
408 dtprop_reg_addr(struct dt_prop_iter* dtpi)
410 return dtprop_extract(dtpi, 0);
414 dtprop_reg_nextaddr(struct dt_prop_iter* dtpi)
418 t = (ptr_t)dtprop_to_u64(dtprop_reg_addr(dtpi));
424 static inline dt_enc_t
425 dtprop_reg_len(struct dt_prop_iter* dtpi)
427 return dtprop_extract(dtpi, dtpi->node->addr_c);
431 dtprop_reg_nextlen(struct dt_prop_iter* dtpi)
435 t = (size_t)dtprop_to_u64(dtprop_reg_len(dtpi));
441 static inline dt_enc_t
442 dtprop_range_childbus(struct dt_prop_iter* dtpi)
444 return dtprop_extract(dtpi, 0);
447 static inline dt_enc_t
448 dtprop_range_parentbus(struct dt_prop_iter* dtpi)
450 return dtprop_extract(dtpi, dtpi->node->addr_c);
453 static inline dt_enc_t
454 dtprop_range_len(struct dt_prop_iter* dtpi)
456 return dtprop_extract(dtpi, dtpi->node->addr_c * 2);
459 static inline dt_enc_t
460 dtprop_intr_cuaddr(struct dt_prop_iter* dtpi)
462 return dtprop_extract(dtpi, 0);
465 static inline dt_enc_t
466 dtprop_intr_cispec(struct dt_prop_iter* dtpi)
468 return dtprop_extract(dtpi, dtpi->node->addr_c);
471 static inline struct dt_intr_node*
472 dtprop_intr_parent(struct dt_prop_iter* dtpi)
475 struct dt_node* node;
478 off = dtpi->node->addr_c + dtpi->node->intr_c;
479 enc_val = dtprop_extract(dtpi, off);
480 node = dt_resolve_phandle(dtprop_to_phnd(enc_val));
485 static inline dt_enc_t
486 dtprop_intr_puaddr(struct dt_prop_iter* dtpi)
490 off = dtpi->node->addr_c + dtpi->node->intr_c + 1;
491 return dtprop_extract(dtpi, off);
494 static inline dt_enc_t
495 dtprop_intr_pispec(struct dt_prop_iter* dtpi)
499 off = dtpi->node->addr_c * 2 + dtpi->node->intr_c + 1;
500 return dtprop_extract(dtpi, off);
503 #endif /* __LUNAIX_DEVTREE_H */