X-Git-Url: https://scm.lunaixsky.com/lunaix-os.git/blobdiff_plain/99f2ed669601a61f4f0210e0b481ff877cd9bea7..35a7d633d3f16c1e0539af6ca5d8e7482926cd93:/lunaix-os/hal/devtree/dt.c diff --git a/lunaix-os/hal/devtree/dt.c b/lunaix-os/hal/devtree/dt.c index 72c443c..f1d6860 100644 --- a/lunaix-os/hal/devtree/dt.c +++ b/lunaix-os/hal/devtree/dt.c @@ -1,12 +1,12 @@ #include #include - -#include +#include #include "devtree.h" LOG_MODULE("dtb") +static morph_t* devtree_obj_root; static struct dt_context dtctx; void @@ -126,39 +126,6 @@ fdt_memrsvd_itend(struct fdt_memrsvd_iter* rsvdi) rsvdi->block = NULL; } -static inline bool -propeq(struct fdt_iter* it, const char* key) -{ - return streq(fdtit_prop_key(it), key); -} - -static inline void -__mkprop_val32(struct fdt_iter* it, struct dt_prop_val* val) -{ - val->u32_val = le(*(u32_t*)&it->prop[1]); - val->size = le(it->prop->len); -} - -static inline void -__mkprop_val64(struct fdt_iter* it, struct dt_prop_val* val) -{ - val->u64_val = le64(*(u64_t*)&it->prop[1]); - val->size = le(it->prop->len); -} - -static inline void -__mkprop_ptr(struct fdt_iter* it, struct dt_prop_val* val) -{ - val->ptr_val = __ptr(&it->prop[1]); - val->size = le(it->prop->len); -} - -static inline u32_t -__prop_getu32(struct fdt_iter* it) -{ - return le(*(u32_t*)&it->prop[1]); -} - static bool __parse_stdbase_prop(struct fdt_iter* it, struct dt_node_base* node) { @@ -169,15 +136,9 @@ __parse_stdbase_prop(struct fdt_iter* it, struct dt_node_base* node) if (propeq(it, "compatible")) { __mkprop_ptr(it, &node->compat); } - - else if (propeq(it, "model")) { - node->model = (const char*)&prop[1]; - } else if (propeq(it, "phandle")) { node->phandle = __prop_getu32(it); - hashtable_hash_in(dtctx.phnds_table, - &node->phnd_link, node->phandle); } else if (propeq(it, "#address-cells")) { @@ -263,6 +224,25 @@ __parse_stdflags(struct fdt_iter* it, struct dt_node_base* node) return true; } +static inline void +__dt_node_set_name(struct dt_node_base* node, const char* name) +{ + changeling_setname(&node->mobj, name); +} + +static inline void +__init_prop_table(struct dt_node_base* node) +{ + struct dt_prop_table* propt; + + propt = valloc(sizeof(*propt)); + hashtable_init(propt->_op_bucket); +} + +#define prop_table_add(node, prop) \ + hashtable_hash_in( (node)->props->_op_bucket, \ + &(prop)->ht, (prop)->key.hash); + static void __parse_other_prop(struct fdt_iter* it, struct dt_node_base* node) { @@ -277,9 +257,8 @@ __parse_other_prop(struct fdt_iter* it, struct dt_node_base* node) __mkprop_ptr(it, &prop->val); hstr_rehash(&prop->key, HSTR_FULL_HASH); - hash = prop->key.hash; - hashtable_hash_in(node->_op_bucket, &prop->ht, hash); + prop_table_add(node, prop); } static void @@ -297,7 +276,7 @@ __fill_node(struct fdt_iter* it, struct dt_node* node) return; } - if (__parse_stdintr_prop(it, &node->intr)) { + if (parse_stdintr_prop(it, &node->intr)) { return; } @@ -332,11 +311,16 @@ __fill_root(struct fdt_iter* it, struct dt_root* node) static inline void __init_node(struct dt_node_base* node) { - hashtable_init(node->_op_bucket); - llist_init_head(&node->children); + morph_t* parent; - if (node->parent) + parent = devtree_obj_root; + if (node->parent) { + parent = node->mobj.parent; node->_std = node->parent->_std; + } + + __init_prop_table(node); + changeling_morph_anon(parent, node->mobj, dt_morpher); } static inline void @@ -488,12 +472,11 @@ dt_load(ptr_t dtb_dropoff) node->parent = prev; __init_node_regular((struct dt_node*)node); - llist_append(&prev->children, &node->siblings); llist_append(&dtctx.nodes, &node->nodes); } - node->name = (const char*)&it.pos[1]; + __dt_node_set_name(node, (const char*)&it.pos[1]); } if (unlikely(is_root_level)) { @@ -520,7 +503,7 @@ struct dt_node* dt_resolve_phandle(dt_phnd_t phandle) { struct dt_node_base *pos, *n; - hashtable_hash_foreach(dtctx.phnds_table, phandle, pos, n, phnd_link) + llist_for_each(pos, n, &dtctx.nodes, nodes) { if (pos->phandle == phandle) { return (struct dt_node*)pos; @@ -534,7 +517,7 @@ static bool __byname_predicate(struct dt_node_iter* iter, struct dt_node_base* node) { int i = 0; - const char* be_matched = node->name; + const char* be_matched = HSTR_VAL(node->mobj.name); const char* name = (const char*)iter->closure; while (be_matched[i] && name[i]) @@ -567,11 +550,13 @@ dt_begin_find(struct dt_node_iter* iter, struct dt_node* node, iter->closure = closure; iter->pred = pred; - struct dt_node_base *pos, *n; - llist_for_each(pos, n, &node->base.children, siblings) + morph_t *pos, *n; + struct dt_node_base* base; + changeling_for_each(pos, n, &node->mobj) { - if (pred(iter, pos)) { - iter->matched = pos; + base = &changeling_reveal(pos, dt_morpher)->base; + if (pred(iter, base)) { + iter->matched = base; break; } } @@ -585,21 +570,23 @@ dt_find_next(struct dt_node_iter* iter, return false; } - struct dt_node_base *pos, *head; + struct dt_node *node; + morph_t *pos, *head; - head = iter->head; - pos = iter->matched; - *matched = pos; + head = dt_mobj(iter->head); + pos = dt_mobj(iter->matched); + *matched = iter->matched; - while (&pos->siblings != &head->children) + while (&pos->sibs != &head->subs) { - pos = list_next(pos, struct dt_node_base, siblings); + pos = list_next(pos, morph_t, sibs); + node = changeling_reveal(pos, dt_morpher); - if (!iter->pred(iter, pos)) { + if (!iter->pred(iter, &node->base)) { continue; } - iter->matched = pos; + iter->matched = &node->base; return true; } @@ -617,7 +604,7 @@ dt_getprop(struct dt_node_base* base, const char* name) hstr_rehash(&hashed_name, HSTR_FULL_HASH); hash = hashed_name.hash; - hashtable_hash_foreach(base->_op_bucket, hash, pos, n, ht) + hashtable_hash_foreach(base->props->_op_bucket, hash, pos, n, ht) { if (HSTR_EQ(&pos->key, &hashed_name)) { return &pos->val; @@ -625,4 +612,17 @@ dt_getprop(struct dt_node_base* base, const char* name) } return NULL; -} \ No newline at end of file +} + +struct dt_context* +dt_main_context() +{ + return &dtctx; +} + +static void +__init_devtree() +{ + devtree_obj_root = changeling_spawn(NULL, NULL); +} +owloysius_fetch_init(__init_devtree, on_sysconf); \ No newline at end of file