aboutsummaryrefslogtreecommitdiff
path: root/modules/devices
diff options
context:
space:
mode:
Diffstat (limited to 'modules/devices')
-rw-r--r--modules/devices/devicetree.c4
-rw-r--r--modules/devices/devicetree/dt_util.c83
2 files changed, 87 insertions, 0 deletions
diff --git a/modules/devices/devicetree.c b/modules/devices/devicetree.c
index fdc13644..778e3693 100644
--- a/modules/devices/devicetree.c
+++ b/modules/devices/devicetree.c
@@ -241,12 +241,16 @@ void __scan_dtree()
{
dt = dtr_new(NULL);
gchar *summary = get_summary();
+ gchar *maps = dtr_maps_info(dt);
dtree_info = g_strdup("[Device Tree]\n");
mi_add("Summary", summary);
+ mi_add("Maps", maps);
add_keys("/");
//printf("%s\n", dtree_info);
+ g_free(summary);
+ g_free(maps);
dtr_free(dt);
}
diff --git a/modules/devices/devicetree/dt_util.c b/modules/devices/devicetree/dt_util.c
index 684b2f89..de2d1e37 100644
--- a/modules/devices/devicetree/dt_util.c
+++ b/modules/devices/devicetree/dt_util.c
@@ -107,6 +107,43 @@ void dtr_map_free(dtr_map *map) {
}
}
+/* simple sort for maps
+ * sv: 1 = sort by v, 0 = sort by label */
+void dtr_map_sort(dtr_map *map, int sv)
+{
+ int done = 0, cmp;
+ dtr_map *this, *next, *top, *next_top;
+ uint32_t tmp_v;
+ char *tmp_l, *tmp_p;
+ if (map == NULL) return;
+ do {
+ this = map;
+ next_top = NULL;
+ while(this != NULL) {
+ next = this->next;
+ if (this == top)
+ break;
+ if (next == NULL)
+ break;
+ if (sv)
+ cmp = (this->v > next->v) ? 1 : 0;
+ else
+ cmp = strcmp(this->label, next->label);
+ if (cmp > 0) {
+ tmp_v = this->v; this->v = next->v; next->v = tmp_v;
+ tmp_l = this->label; this->label = next->label; next->label = tmp_l;
+ tmp_p = this->path; this->path = next->path; next->path = tmp_p;
+ next_top = this;
+ }
+ this = next;
+ }
+ if (next_top == NULL)
+ done = 1;
+ else
+ top = next_top;
+ } while (!done);
+}
+
const char *dtr_phandle_lookup(dtr *s, uint32_t v) {
dtr_map *phi = s->phandles;
/* 0 and 0xffffffff are invalid phandle values */
@@ -569,6 +606,7 @@ void _dtr_read_aliases(dtr *s) {
g_dir_close(dir);
g_free(dir_path);
dtr_obj_free(anode);
+ dtr_map_sort(s->aliases, 0);
}
void _dtr_read_symbols(dtr *s) {
@@ -597,6 +635,7 @@ void _dtr_read_symbols(dtr *s) {
g_dir_close(dir);
g_free(dir_path);
dtr_obj_free(anode);
+ dtr_map_sort(s->symbols, 0);
}
/* TODO: rewrite */
@@ -636,6 +675,50 @@ void _dtr_map_phandles(dtr *s, char *np) {
}
g_dir_close(dir);
dtr_obj_free(prop);
+ dtr_map_sort(s->phandles, 1);
+}
+
+/*
+ * Maybe these should move to devicetree.c, but would have to expose
+ * struct internals.
+ */
+
+/* kvl: 0 = key is label, 1 = key is v */
+char *dtr_map_info_section(dtr *s, dtr_map *map, char *title, int kvl) {
+ gchar *tmp, *ret;
+ const gchar *sym;
+ ret = g_strdup_printf("[%s]\n", _(title));
+ dtr_map *it = map;
+ while(it != NULL) {
+ if (kvl) {
+ sym = dtr_symbol_lookup_by_path(s, it->path);
+ if (sym != NULL)
+ tmp = g_strdup_printf("%s0x%x (%s)=%s\n", ret,
+ it->v, sym, it->path);
+ else
+ tmp = g_strdup_printf("%s0x%x=%s\n", ret,
+ it->v, it->path);
+ } else
+ tmp = g_strdup_printf("%s%s=%s\n", ret,
+ it->label, it->path);
+ g_free(ret);
+ ret = tmp;
+ it = it->next;
+ }
+
+ return ret;
}
+char *dtr_maps_info(dtr *s) {
+ gchar *ph_map, *al_map, *sy_map, *ret;
+
+ ph_map = dtr_map_info_section(s, s->phandles, _("phandle Map"), 1);
+ al_map = dtr_map_info_section(s, s->aliases, _("Alias Map"), 0);
+ sy_map = dtr_map_info_section(s, s->symbols, _("Symbol Map"), 0);
+ ret = g_strdup_printf("%s%s%s", ph_map, sy_map, al_map);
+ g_free(ph_map);
+ g_free(al_map);
+ g_free(sy_map);
+ return ret;
+}