diff options
author | Cyril Bur <cyrilbur@gmail.com> | 2018-04-12 16:01:53 +1000 |
---|---|---|
committer | Alistair Popple <alistair@popple.id.au> | 2018-04-24 13:01:20 +1000 |
commit | e227bee0be86ccd2fe10887c8406d30effd7127a (patch) | |
tree | 7b5b1b68ea1143a8d82ed1426666c7de6c485b0c | |
parent | 808854c5adc2a058e2f317cde54fab69eecc5429 (diff) | |
download | pdbg-e227bee0be86ccd2fe10887c8406d30effd7127a.tar.gz pdbg-e227bee0be86ccd2fe10887c8406d30effd7127a.zip |
libpdbg: Move struct dt_node into struct pdbg_target
Currently we have this terrible mess of dt_nodes pointing to targets
and targets pointing to dt_nodes. This has been the cause of bugs due
to folling NULL pointers from a target expecting a node and vice versa.
Consolidating these structs means that there must be a node for a
target.
Signed-off-by: Cyril Bur <cyrilbur@gmail.com>
-rw-r--r-- | libpdbg/bmcfsi.c | 22 | ||||
-rw-r--r-- | libpdbg/cfam.c | 12 | ||||
-rw-r--r-- | libpdbg/device.c | 202 | ||||
-rw-r--r-- | libpdbg/device.h | 104 | ||||
-rw-r--r-- | libpdbg/host.c | 5 | ||||
-rw-r--r-- | libpdbg/htm.c | 12 | ||||
-rw-r--r-- | libpdbg/i2c.c | 4 | ||||
-rw-r--r-- | libpdbg/libpdbg.c | 44 | ||||
-rw-r--r-- | libpdbg/p8chip.c | 20 | ||||
-rw-r--r-- | libpdbg/p9chip.c | 14 | ||||
-rw-r--r-- | libpdbg/target.c | 108 | ||||
-rw-r--r-- | libpdbg/target.h | 9 |
12 files changed, 279 insertions, 277 deletions
diff --git a/libpdbg/bmcfsi.c b/libpdbg/bmcfsi.c index c8597a4..62b96c9 100644 --- a/libpdbg/bmcfsi.c +++ b/libpdbg/bmcfsi.c @@ -458,17 +458,17 @@ int bmcfsi_probe(struct pdbg_target *target) } if (!gpio_reg) { - gpio_pins[GPIO_FSI_CLK].offset = dt_prop_get_u32_index(target->dn, "fsi_clk", 0); - gpio_pins[GPIO_FSI_CLK].bit = dt_prop_get_u32_index(target->dn, "fsi_clk", 1); - gpio_pins[GPIO_FSI_DAT].offset = dt_prop_get_u32_index(target->dn, "fsi_dat", 0); - gpio_pins[GPIO_FSI_DAT].bit = dt_prop_get_u32_index(target->dn, "fsi_dat", 1); - gpio_pins[GPIO_FSI_DAT_EN].offset = dt_prop_get_u32_index(target->dn, "fsi_dat_en", 0); - gpio_pins[GPIO_FSI_DAT_EN].bit = dt_prop_get_u32_index(target->dn, "fsi_dat_en", 1); - gpio_pins[GPIO_FSI_ENABLE].offset = dt_prop_get_u32_index(target->dn, "fsi_enable", 0); - gpio_pins[GPIO_FSI_ENABLE].bit = dt_prop_get_u32_index(target->dn, "fsi_enable", 1); - gpio_pins[GPIO_CRONUS_SEL].offset = dt_prop_get_u32_index(target->dn, "cronus_sel", 0); - gpio_pins[GPIO_CRONUS_SEL].bit = dt_prop_get_u32_index(target->dn, "cronus_sel", 1); - clock_delay = dt_prop_get_u32(target->dn, "clock_delay"); + gpio_pins[GPIO_FSI_CLK].offset = dt_prop_get_u32_index(target, "fsi_clk", 0); + gpio_pins[GPIO_FSI_CLK].bit = dt_prop_get_u32_index(target, "fsi_clk", 1); + gpio_pins[GPIO_FSI_DAT].offset = dt_prop_get_u32_index(target, "fsi_dat", 0); + gpio_pins[GPIO_FSI_DAT].bit = dt_prop_get_u32_index(target, "fsi_dat", 1); + gpio_pins[GPIO_FSI_DAT_EN].offset = dt_prop_get_u32_index(target, "fsi_dat_en", 0); + gpio_pins[GPIO_FSI_DAT_EN].bit = dt_prop_get_u32_index(target, "fsi_dat_en", 1); + gpio_pins[GPIO_FSI_ENABLE].offset = dt_prop_get_u32_index(target, "fsi_enable", 0); + gpio_pins[GPIO_FSI_ENABLE].bit = dt_prop_get_u32_index(target, "fsi_enable", 1); + gpio_pins[GPIO_CRONUS_SEL].offset = dt_prop_get_u32_index(target, "cronus_sel", 0); + gpio_pins[GPIO_CRONUS_SEL].bit = dt_prop_get_u32_index(target, "cronus_sel", 1); + clock_delay = dt_prop_get_u32(target, "clock_delay"); /* We only have to do this init once per backend */ gpio_reg = mmap(NULL, getpagesize(), diff --git a/libpdbg/cfam.c b/libpdbg/cfam.c index cf0017f..50a7381 100644 --- a/libpdbg/cfam.c +++ b/libpdbg/cfam.c @@ -296,18 +296,18 @@ DECLARE_HW_UNIT(p8_opb_hmfsi); static int cfam_hmfsi_read(struct fsi *fsi, uint32_t addr, uint32_t *data) { - struct pdbg_target *parent_fsi = fsi->target.dn->parent->target; + struct pdbg_target *parent_fsi = fsi->target.parent; - addr += dt_get_address(fsi->target.dn, 0, NULL); + addr += dt_get_address(&fsi->target, 0, NULL); return fsi_read(parent_fsi, addr, data); } static int cfam_hmfsi_write(struct fsi *fsi, uint32_t addr, uint32_t data) { - struct pdbg_target *parent_fsi = fsi->target.dn->parent->target; + struct pdbg_target *parent_fsi = fsi->target.parent; - addr += dt_get_address(fsi->target.dn, 0, NULL); + addr += dt_get_address(&fsi->target, 0, NULL); return fsi_write(parent_fsi, addr, data); } @@ -315,12 +315,12 @@ static int cfam_hmfsi_write(struct fsi *fsi, uint32_t addr, uint32_t data) static int cfam_hmfsi_probe(struct pdbg_target *target) { struct fsi *fsi = target_to_fsi(target); - struct pdbg_target *fsi_parent = target->dn->parent->target; + struct pdbg_target *fsi_parent = target->parent; uint32_t value, port; int rc; /* Enable the port in the upstream control register */ - port = dt_prop_get_u32(target->dn, "port"); + port = dt_prop_get_u32(target, "port"); fsi_read(fsi_parent, 0x3404, &value); value |= 1 << (31 - port); if ((rc = fsi_write(fsi_parent, 0x3404, value))) { diff --git a/libpdbg/device.c b/libpdbg/device.c index 3fefb11..6c1c29b 100644 --- a/libpdbg/device.c +++ b/libpdbg/device.c @@ -18,6 +18,7 @@ #include <stdio.h> #include <stdlib.h> #include <stdarg.h> +#include "target.h" #include <libfdt/libfdt.h> #include <libfdt/libfdt_internal.h> #include <ccan/str/str.h> @@ -33,8 +34,8 @@ /* Used to give unique handles. */ u32 last_phandle = 0; -struct dt_node *dt_root; -struct dt_node *dt_chosen; +struct pdbg_target *dt_root; +struct pdbg_target *dt_chosen; static const char *take_name(const char *name) { @@ -51,15 +52,55 @@ static void free_name(const char *name) free((char *)name); } -static struct dt_node *new_node(const char *name) +static struct pdbg_target *new_node(const char *name, const void *fdt, int node_offset) { - struct dt_node *node = malloc(sizeof *node); + struct hw_unit_info *hw_info = NULL; + const struct fdt_property *prop; + struct pdbg_target *node; + size_t size = sizeof(*node); + + if (fdt) { + prop = fdt_get_property(fdt, node_offset, "compatible", NULL); + if (prop) { + int i, prop_len = fdt32_to_cpu(prop->len); + + /* + * If I understand correctly, the property we have + * here can be a stringlist with a few compatible + * strings + */ + i = 0; + while (i < prop_len) { + hw_info = find_compatible_target(&prop->data[i]); + if (hw_info) { + size = hw_info->size; + break; + } + + i += strlen(&prop->data[i]) + 1; + } + } + } + + node = calloc(1, size); if (!node) { prerror("Failed to allocate node\n"); abort(); } - node->name = take_name(name); + if (hw_info) { + struct pdbg_target_class *target_class; + + /* hw_info->hw_unit points to a per-target struct type. This + * works because the first member in the per-target struct is + * guaranteed to be the struct pdbg_target (see the comment + * above DECLARE_HW_UNIT). */ + memcpy(node, hw_info->hw_unit, size); + target_class = get_target_class(node->class); + list_add(&target_class->targets, &node->class_link); + } + + node->dn_name = take_name(name); node->parent = NULL; list_head_init(&node->properties); list_head_init(&node->children); @@ -68,14 +109,14 @@ static struct dt_node *new_node(const char *name) return node; } -struct dt_node *dt_new_root(const char *name) +struct pdbg_target *dt_new_root(const char *name, const void *fdt, int offset) { - return new_node(name); + return new_node(name, fdt, offset); } -static const char *get_unitname(const struct dt_node *node) +static const char *get_unitname(const struct pdbg_target *node) { - const char *c = strchr(node->name, '@'); + const char *c = strchr(node->dn_name, '@'); if (!c) return NULL; @@ -83,15 +124,15 @@ static const char *get_unitname(const struct dt_node *node) return c + 1; } -int dt_cmp_subnodes(const struct dt_node *a, const struct dt_node *b) +int dt_cmp_subnodes(const struct pdbg_target *a, const struct pdbg_target *b) { const char *a_unit = get_unitname(a); const char *b_unit = get_unitname(b); - ptrdiff_t basenamelen = a_unit - a->name; + ptrdiff_t basenamelen = a_unit - a->dn_name; /* sort hex unit addresses by number */ - if (a_unit && b_unit && !strncmp(a->name, b->name, basenamelen)) { + if (a_unit && b_unit && !strncmp(a->dn_name, b->dn_name, basenamelen)) { unsigned long long a_num, b_num; char *a_end, *b_end; @@ -103,12 +144,12 @@ int dt_cmp_subnodes(const struct dt_node *a, const struct dt_node *b) return (a_num > b_num) - (a_num < b_num); } - return strcmp(a->name, b->name); + return strcmp(a->dn_name, b->dn_name); } -bool dt_attach_root(struct dt_node *parent, struct dt_node *root) +bool dt_attach_root(struct pdbg_target *parent, struct pdbg_target *root) { - struct dt_node *node; + struct pdbg_target *node; assert(!root->parent); @@ -125,7 +166,7 @@ bool dt_attach_root(struct dt_node *parent, struct dt_node *root) /* Look for duplicates */ if (cmp == 0) { prerror("DT: %s failed, duplicate %s\n", - __func__, root->name); + __func__, root->dn_name); return false; } @@ -141,19 +182,19 @@ bool dt_attach_root(struct dt_node *parent, struct dt_node *root) return true; } -static inline void dt_destroy(struct dt_node *dn) +static inline void dt_destroy(struct pdbg_target *dn) { if (!dn) return; - free_name(dn->name); + free_name(dn->dn_name); free(dn); } -char *dt_get_path(const struct dt_node *node) +char *dt_get_path(const struct pdbg_target *node) { unsigned int len = 0; - const struct dt_node *n; + const struct pdbg_target *n; char *path, *p; /* Dealing with NULL is for test/debug purposes */ @@ -161,7 +202,7 @@ char *dt_get_path(const struct dt_node *node) return strdup("<NULL>"); for (n = node; n; n = n->parent) { - len += strlen(n->name); + len += strlen(n->dn_name); if (n->parent || n == node) len++; } @@ -169,9 +210,9 @@ char *dt_get_path(const struct dt_node *node) assert(path); p = path + len; for (n = node; n; n = n->parent) { - len = strlen(n->name); + len = strlen(n->dn_name); p -= len; - memcpy(p, n->name, len); + memcpy(p, n->dn_name, len); if (n->parent || n == node) *(--p) = '/'; } @@ -212,9 +253,9 @@ static const char *__dt_path_split(const char *p, return sl; } -struct dt_node *dt_find_by_path(struct dt_node *root, const char *path) +struct pdbg_target *dt_find_by_path(struct pdbg_target *root, const char *path) { - struct dt_node *n; + struct pdbg_target *n; const char *pn, *pa = NULL, *p = path, *nn = NULL, *na = NULL; unsigned int pnl, pal, nnl, nal; bool match; @@ -230,7 +271,7 @@ struct dt_node *dt_find_by_path(struct dt_node *root, const char *path) match = false; list_for_each(&root->children, n, list) { match = true; - __dt_path_split(n->name, &nn, &nnl, &na, &nal); + __dt_path_split(n->dn_name, &nn, &nnl, &na, &nal); if (pnl && (pnl != nnl || strncmp(pn, nn, pnl))) match = false; if (pal && (pal != nal || strncmp(pa, na, pal))) @@ -248,12 +289,12 @@ struct dt_node *dt_find_by_path(struct dt_node *root, const char *path) return root; } -struct dt_node *dt_find_by_name(struct dt_node *root, const char *name) +struct pdbg_target *dt_find_by_name(struct pdbg_target *root, const char *name) { - struct dt_node *child, *match; + struct pdbg_target *child, *match; list_for_each(&root->children, child, list) { - if (!strcmp(child->name, name)) + if (!strcmp(child->dn_name, name)) return child; match = dt_find_by_name(child, name); @@ -264,7 +305,7 @@ struct dt_node *dt_find_by_name(struct dt_node *root, const char *name) return NULL; } -static struct dt_property *new_property(struct dt_node *node, +static struct dt_property *new_property(struct pdbg_target *node, const char *name, size_t size) { struct dt_property *p = malloc(sizeof(*p) + size); @@ -292,7 +333,7 @@ static struct dt_property *new_property(struct dt_node *node, return p; } -struct dt_property *dt_add_property(struct dt_node *node, +struct dt_property *dt_add_property(struct pdbg_target *node, const char *name, const void *val, size_t size) { @@ -328,14 +369,14 @@ void dt_resize_property(struct dt_property **prop, size_t len) (*prop)->list.prev->next = &(*prop)->list; } -struct dt_property *dt_add_property_string(struct dt_node *node, +struct dt_property *dt_add_property_string(struct pdbg_target *node, const char *name, const char *value) { return dt_add_property(node, name, value, strlen(value)+1); } -struct dt_property *dt_add_property_nstr(struct dt_node *node, +struct dt_property *dt_add_property_nstr(struct pdbg_target *node, const char *name, const char *value, unsigned int vlen) { @@ -352,7 +393,7 @@ struct dt_property *dt_add_property_nstr(struct dt_node *node, return p; } -struct dt_property *__dt_add_property_cells(struct dt_node *node, +struct dt_property *__dt_add_property_cells(struct pdbg_target *node, const char *name, int count, ...) { @@ -370,7 +411,7 @@ struct dt_property *__dt_add_property_cells(struct dt_node *node, return p; } -struct dt_property *__dt_add_property_u64s(struct dt_node *node, +struct dt_property *__dt_add_property_u64s(struct pdbg_target *node, const char *name, int count, ...) { @@ -388,7 +429,7 @@ struct dt_property *__dt_add_property_u64s(struct dt_node *node, return p; } -struct dt_property *__dt_add_property_strings(struct dt_node *node, +struct dt_property *__dt_add_property_strings(struct pdbg_target *node, const char *name, int count, ...) { @@ -422,7 +463,7 @@ struct dt_property *__dt_add_property_strings(struct dt_node *node, return p; } -void dt_del_property(struct dt_node *node, struct dt_property *prop) +void dt_del_property(struct pdbg_target *node, struct dt_property *prop) { list_del_from(&node->properties, &prop->list); free_name(prop->name); @@ -437,14 +478,14 @@ u32 dt_property_get_cell(const struct dt_property *prop, u32 index) } /* First child of this node. */ -struct dt_node *dt_first(const struct dt_node *root) +struct pdbg_target *dt_first(const struct pdbg_target *root) { - return list_top(&root->children, struct dt_node, list); + return list_top(&root->children, struct pdbg_target, list); } /* Return next node, or NULL. */ -struct dt_node *dt_next(const struct dt_node *root, - const struct dt_node *prev) +struct pdbg_target *dt_next(const struct pdbg_target *root, + const struct pdbg_target *prev) { /* Children? */ if (!list_empty(&prev->children)) @@ -453,7 +494,7 @@ struct dt_node *dt_next(const struct dt_node *root, do { /* More siblings? */ if (prev->list.next != &prev->parent->children.n) - return list_entry(prev->list.next, struct dt_node,list); + return list_entry(prev->list.next, struct pdbg_target,list); /* No more siblings, move up to parent. */ prev = prev->parent; @@ -462,7 +503,7 @@ struct dt_node *dt_next(const struct dt_node *root, return NULL; } -struct dt_property *__dt_find_property(struct dt_node *node, const char *name) +struct dt_property *__dt_find_property(struct pdbg_target *node, const char *name) { struct dt_property *i; @@ -472,7 +513,7 @@ struct dt_property *__dt_find_property(struct dt_node *node, const char *name) return NULL; } -struct dt_property *dt_find_property(const struct dt_node *node, +struct dt_property *dt_find_property(const struct pdbg_target *node, const char *name) { struct dt_property *i; @@ -483,7 +524,7 @@ struct dt_property *dt_find_property(const struct dt_node *node, return NULL; } -void dt_check_del_prop(struct dt_node *node, const char *name) +void dt_check_del_prop(struct pdbg_target *node, const char *name) { struct dt_property *p; @@ -491,7 +532,7 @@ void dt_check_del_prop(struct dt_node *node, const char *name) if (p) dt_del_property(node, p); } -const struct dt_property *dt_require_property(const struct dt_node *node, +const struct dt_property *dt_require_property(const struct pdbg_target *node, const char *name, int wanted_len) { const struct dt_property *p = dt_find_property(node, name); @@ -516,7 +557,7 @@ const struct dt_property *dt_require_property(const struct dt_node *node, return p; } -bool dt_has_node_property(const struct dt_node *node, +bool dt_has_node_property(const struct pdbg_target *node, const char *name, const char *val) { const struct dt_property *p = dt_find_property(node, name); @@ -546,18 +587,18 @@ bool dt_prop_find_string(const struct dt_property *p, const char *s) return false; } -bool dt_node_is_compatible(const struct dt_node *node, const char *compat) +bool dt_node_is_compatible(const struct pdbg_target *node, const char *compat) { const struct dt_property *p = dt_find_property(node, "compatible"); return dt_prop_find_string(p, compat); } -struct dt_node *dt_find_compatible_node(struct dt_node *root, - struct dt_node *prev, +struct pdbg_target *dt_find_compatible_node(struct pdbg_target *root, + struct pdbg_target *prev, const char *compat) { - struct dt_node *node; + struct pdbg_target *node; node = prev ? dt_next(root, prev) : root; for (; node; node = dt_next(root, node)) @@ -566,7 +607,7 @@ struct dt_node *dt_find_compatible_node(struct dt_node *root, return NULL; } -u64 dt_prop_get_u64(const struct dt_node *node, const char *prop) +u64 dt_prop_get_u64(const struct pdbg_target *node, const char *prop) { const struct dt_property *p = dt_require_property(node, prop, 8); @@ -574,7 +615,7 @@ u64 dt_prop_get_u64(const struct dt_node *node, const char *prop) | dt_property_get_cell(p, 1); } -u64 dt_prop_get_u64_def(const struct dt_node *node, const char *prop, u64 def) +u64 dt_prop_get_u64_def(const struct pdbg_target *node, const char *prop, u64 def) { const struct dt_property *p = dt_find_property(node, prop); @@ -585,14 +626,14 @@ u64 dt_prop_get_u64_def(const struct dt_node *node, const char *prop, u64 def) | dt_property_get_cell(p, 1); } -u32 dt_prop_get_u32(const struct dt_node *node, const char *prop) +u32 dt_prop_get_u32(const struct pdbg_target *node, const char *prop) { const struct dt_property *p = dt_require_property(node, prop, 4); return dt_property_get_cell(p, 0); } -u32 dt_prop_get_u32_def(const struct dt_node *node, const char *prop, u32 def) +u32 dt_prop_get_u32_def(const struct pdbg_target *node, const char *prop, u32 def) { const struct dt_property *p = dt_find_property(node, prop); @@ -602,21 +643,21 @@ u32 dt_prop_get_u32_def(const struct dt_node *node, const char *prop, u32 def) return dt_property_get_cell(p, 0); } -u32 dt_prop_get_u32_index(const struct dt_node *node, const char *prop, u32 index) +u32 dt_prop_get_u32_index(const struct pdbg_target *node, const char *prop, u32 index) { const struct dt_property *p = dt_require_property(node, prop, -1); return dt_property_get_cell(p, index); } -const void *dt_prop_get(const struct dt_node *node, const char *prop) +const void *dt_prop_get(const struct pdbg_target *node, const char *prop) { const struct dt_property *p = dt_require_property(node, prop, -1); return p->prop; } -const void *dt_prop_get_def(const struct dt_node *node, const char *prop, +const void *dt_prop_get_def(const struct pdbg_target *node, const char *prop, void *def) { const struct dt_property *p = dt_find_property(node, prop); @@ -624,7 +665,7 @@ const void *dt_prop_get_def(const struct dt_node *node, const char *prop, return p ? p->prop : def; } -const void *dt_prop_get_def_size(const struct dt_node *node, const char *prop, +const void *dt_prop_get_def_size(const struct pdbg_target *node, const char *prop, void *def, size_t *len) { const struct dt_property *p = dt_find_property(node, prop); @@ -635,14 +676,14 @@ const void *dt_prop_get_def_size(const struct dt_node *node, const char *prop, return p ? p->prop : def; } -u32 dt_prop_get_cell(const struct dt_node *node, const char *prop, u32 cell) +u32 dt_prop_get_cell(const struct pdbg_target *node, const char *prop, u32 cell) { const struct dt_property *p = dt_require_property(node, prop, -1); return dt_property_get_cell(p, cell); } -u32 dt_prop_get_cell_def(const struct dt_node *node, const char *prop, +u32 dt_prop_get_cell_def(const struct pdbg_target *node, const char *prop, u32 cell, u32 def) { const struct dt_property *p = dt_find_property(node, prop); @@ -653,12 +694,12 @@ u32 dt_prop_get_cell_def(const struct dt_node *node, const char *prop, return dt_property_get_cell(p, cell); } -void dt_free(struct dt_node *node) +void dt_free(struct pdbg_target *node) { - struct dt_node *child; + struct pdbg_target *child; struct dt_property *p; - while ((child = list_top(&node->children, struct dt_node, list))) + while ((child = list_top(&node->children, struct pdbg_target, list))) dt_free(child); while ((p = list_pop(&node->properties, struct dt_property, list))) { @@ -671,13 +712,14 @@ void dt_free(struct dt_node *node) dt_destroy(node); } -int dt_expand_node(struct dt_node *node, const void *fdt, int fdt_node) +int dt_expand_node(struct pdbg_target *node, const void *fdt, int fdt_node) { const struct fdt_property *prop; int offset, nextoffset, err; - struct dt_node *child; + struct pdbg_target *child; const char *name; uint32_t tag; + uint32_t data; if (((err = fdt_check_header(fdt)) != 0) || (fdt_node < 0) || (fdt_node % FDT_TAGSIZE) @@ -695,12 +737,16 @@ int dt_expand_node(struct dt_node *node, const void *fdt, int fdt_node) case FDT_PROP: prop = fdt_offset_ptr(fdt, offset, 0); name = fdt_string(fdt, fdt32_to_cpu(prop->nameoff)); + if (strcmp("index", name) == 0) { + memcpy(&data, prop->data, sizeof(data)); + node->index = fdt32_to_cpu(data); + } dt_add_property(node, name, prop->data, fdt32_to_cpu(prop->len)); break; case FDT_BEGIN_NODE: name = fdt_get_name(fdt, offset, NULL); - child = dt_new_root(name); + child = dt_new_root(name, fdt, offset); assert(child); nextoffset = dt_expand_node(child, fdt, offset); @@ -737,21 +783,21 @@ u64 dt_get_number(const void *pdata, unsigned int cells) return ret; } -u32 dt_n_address_cells(const struct dt_node *node) +u32 dt_n_address_cells(const struct pdbg_target *node) { if (!node->parent) return 0; return dt_prop_get_u32_def(node->parent, "#address-cells", 2); } -u32 dt_n_size_cells(const struct dt_node *node) +u32 dt_n_size_cells(const struct pdbg_target *node) { if (!node->parent) return 0; return dt_prop_get_u32_def(node->parent, "#size-cells", 1); } -u64 dt_get_address(const struct dt_node *node, unsigned int index, +u64 dt_get_address(const struct pdbg_target *node, unsigned int index, u64 *out_size) { const struct dt_property *p; @@ -768,7 +814,7 @@ u64 dt_get_address(const struct dt_node *node, unsigned int index, return dt_get_number(p->prop + pos, na); } -static u32 __dt_get_chip_id(const struct dt_node *node) +static u32 __dt_get_chip_id(const struct pdbg_target *node) { const struct dt_property *prop; @@ -780,19 +826,19 @@ static u32 __dt_get_chip_id(const struct dt_node *node) return 0xffffffff; } -u32 dt_get_chip_id(const struct dt_node *node) +u32 dt_get_chip_id(const struct pdbg_target *node) { u32 id = __dt_get_chip_id(node); assert(id != 0xffffffff); return id; } -struct dt_node *dt_find_compatible_node_on_chip(struct dt_node *root, - struct dt_node *prev, +struct pdbg_target *dt_find_compatible_node_on_chip(struct pdbg_target *root, + struct pdbg_target *prev, const char *compat, uint32_t chip_id) { - struct dt_node *node; + struct pdbg_target *node; node = prev ? dt_next(root, prev) : root; for (; node; node = dt_next(root, node)) { @@ -804,7 +850,7 @@ struct dt_node *dt_find_compatible_node_on_chip(struct dt_node *root, return NULL; } -unsigned int dt_count_addresses(const struct dt_node *node) +unsigned int dt_count_addresses(const struct pdbg_target *node) { const struct dt_property *p; u32 na = dt_n_address_cells(node); @@ -820,14 +866,14 @@ unsigned int dt_count_addresses(const struct dt_node *node) return p->len / n; } -u64 dt_translate_address(const struct dt_node *node, unsigned int index, +u64 dt_translate_address(const struct pdbg_target *node, unsigned int index, u64 *out_size) { /* XXX TODO */ return dt_get_address(node, index, out_size); } -bool dt_node_is_enabled(struct dt_node *node) +bool dt_node_is_enabled(struct pdbg_target *node) { const struct dt_property *p = dt_find_property(node, "status"); diff --git a/libpdbg/device.h b/libpdbg/device.h index bb0b3fa..05d6c12 100644 --- a/libpdbg/device.h +++ b/libpdbg/device.h @@ -38,38 +38,28 @@ struct dt_property { char prop[/* len */]; }; -struct dt_node { - const char *name; - struct list_node list; - struct list_head properties; - struct list_head children; - struct dt_node *parent; - u32 phandle; - struct pdbg_target *target; -}; - /* This is shared with device_tree.c .. make it static when * the latter is gone (hopefully soon) */ extern u32 last_phandle; -extern struct dt_node *dt_root; -extern struct dt_node *dt_chosen; +extern struct pdbg_target *dt_root; +extern struct pdbg_target *dt_chosen; /* Create a root node: ie. a parentless one. */ -struct dt_node *dt_new_root(const char *name); +struct pdbg_target *dt_new_root(const char *name, const void *fdt, int offset); /* Graft a root node into this tree. */ -bool dt_attach_root(struct dt_node *parent, struct dt_node *root); +bool dt_attach_root(struct pdbg_target *parent, struct pdbg_target *root); /* Add a property node, various forms. */ -struct dt_property *dt_add_property(struct dt_node *node, +struct dt_property *dt_add_property(struct pdbg_target *node, const char *name, const void *val, size_t size); -struct dt_property *dt_add_property_string(struct dt_node *node, +struct dt_property *dt_add_property_string(struct pdbg_target *node, const char *name, const char *value); -struct dt_property *dt_add_property_nstr(struct dt_node *node, +struct dt_property *dt_add_property_nstr(struct pdbg_target *node, const char *name, const char *value, unsigned int vlen); @@ -79,7 +69,7 @@ struct dt_property *dt_add_property_nstr(struct dt_node *node, sizeof((const char *[]) { __VA_ARGS__ })/sizeof(const char *), \ __VA_ARGS__) -struct dt_property *__dt_add_property_strings(struct dt_node *node, +struct dt_property *__dt_add_property_strings(struct pdbg_target *node, const char *name, int count, ...); @@ -89,7 +79,7 @@ struct dt_property *__dt_add_property_strings(struct dt_node *node, sizeof((u32[]) { __VA_ARGS__ })/sizeof(u32), \ __VA_ARGS__) -struct dt_property *__dt_add_property_cells(struct dt_node *node, +struct dt_property *__dt_add_property_cells(struct pdbg_target *node, const char *name, int count, ...); @@ -98,19 +88,19 @@ struct dt_property *__dt_add_property_cells(struct dt_node *node, sizeof((u64[]) { __VA_ARGS__ })/sizeof(u64), \ __VA_ARGS__) -struct dt_property *__dt_add_property_u64s(struct dt_node *node, +struct dt_property *__dt_add_property_u64s(struct pdbg_target *node, const char *name, int count, ...); -static inline struct dt_property *dt_add_property_u64(struct dt_node *node, +static inline struct dt_property *dt_add_property_u64(struct pdbg_target *node, const char *name, u64 val) { return dt_add_property_cells(node, name, (u32)(val >> 32), (u32)val); } -void dt_del_property(struct dt_node *node, struct dt_property *prop); +void dt_del_property(struct pdbg_target *node, struct dt_property *prop); -void dt_check_del_prop(struct dt_node *node, const char *name); +void dt_check_del_prop(struct pdbg_target *node, const char *name); /* Warning: moves *prop! */ void dt_resize_property(struct dt_property **prop, size_t len); @@ -118,10 +108,10 @@ void dt_resize_property(struct dt_property **prop, size_t len); u32 dt_property_get_cell(const struct dt_property *prop, u32 index); /* First child of this node. */ -struct dt_node *dt_first(const struct dt_node *root); +struct pdbg_target *dt_first(const struct pdbg_target *root); /* Return next node, or NULL. */ -struct dt_node *dt_next(const struct dt_node *root, const struct dt_node *prev); +struct pdbg_target *dt_next(const struct pdbg_target *root, const struct pdbg_target *prev); /* Iterate nodes */ #define dt_for_each_node(root, node) \ @@ -134,19 +124,19 @@ struct dt_node *dt_next(const struct dt_node *root, const struct dt_node *prev); bool dt_prop_find_string(const struct dt_property *p, const char *s); /* Check a compatible property */ -bool dt_node_is_compatible(const struct dt_node *node, const char *compat); +bool dt_node_is_compatible(const struct pdbg_target *node, const char *compat); /* Find a node based on compatible property */ -struct dt_node *dt_find_compatible_node(struct dt_node *root, - struct dt_node *prev, +struct pdbg_target *dt_find_compatible_node(struct pdbg_target *root, + struct pdbg_target *prev, const char *compat); #define dt_for_each_compatible(root, node, compat) \ for (node = NULL; \ (node = dt_find_compatible_node(root, node, compat)) != NULL;) -struct dt_node *dt_find_compatible_node_on_chip(struct dt_node *root, - struct dt_node *prev, +struct pdbg_target *dt_find_compatible_node_on_chip(struct pdbg_target *root, + struct pdbg_target *prev, const char *compat, uint32_t chip_id); @@ -155,71 +145,71 @@ struct dt_node *dt_find_compatible_node_on_chip(struct dt_node *root, (node = dt_find_compatible_node_on_chip(root, node,\ compat, chip_id)) != NULL;) /* Check status property */ -bool dt_node_is_enabled(struct dt_node *node); +bool dt_node_is_enabled(struct pdbg_target *node); /* Build the full path for a node. Return a new block of memory, caller * shall free() it */ -char *dt_get_path(const struct dt_node *node); +char *dt_get_path(const struct pdbg_target *node); /* Find a node by path */ -struct dt_node *dt_find_by_path(struct dt_node *root, const char *path); +struct pdbg_target *dt_find_by_path(struct pdbg_target *root, const char *path); /* Find a child node by name */ -struct dt_node *dt_find_by_name(struct dt_node *root, const char *name); +struct pdbg_target *dt_find_by_name(struct pdbg_target *root, const char *name); /* Find a property by name. */ -struct dt_property *dt_find_property(const struct dt_node *node,\ +struct dt_property *dt_find_property(const struct pdbg_target *node,\ const char *name); -const struct dt_property *dt_require_property(const struct dt_node *node, +const struct dt_property *dt_require_property(const struct pdbg_target *node, const char *name, int wanted_len); /* non-const variant */ -struct dt_property *__dt_find_property(struct dt_node *node, const char *name); +struct dt_property *__dt_find_property(struct pdbg_target *node, const char *name); /* Find a property by name, check if it's the same as val. */ -bool dt_has_node_property(const struct dt_node *node, +bool dt_has_node_property(const struct pdbg_target *node, const char *name, const char *val); /* Free a node (and any children). */ -void dt_free(struct dt_node *node); +void dt_free(struct pdbg_target *node); /* Parse an initial fdt */ void dt_expand(const void *fdt); -int dt_expand_node(struct dt_node *node, const void *fdt, int fdt_node) __warn_unused_result; +int dt_expand_node(struct pdbg_target *node, const void *fdt, int fdt_node) __warn_unused_result; /* Simplified accessors */ -u64 dt_prop_get_u64(const struct dt_node *node, const char *prop); -u64 dt_prop_get_u64_def(const struct dt_node *node, const char *prop, u64 def); -u32 dt_prop_get_u32(const struct dt_node *node, const char *prop); -u32 dt_prop_get_u32_def(const struct dt_node *node, const char *prop, u32 def); -u32 dt_prop_get_u32_index(const struct dt_node *node, const char *prop, u32 index); -const void *dt_prop_get(const struct dt_node *node, const char *prop); -const void *dt_prop_get_def(const struct dt_node *node, const char *prop, +u64 dt_prop_get_u64(const struct pdbg_target *node, const char *prop); +u64 dt_prop_get_u64_def(const struct pdbg_target *node, const char *prop, u64 def); +u32 dt_prop_get_u32(const struct pdbg_target *node, const char *prop); +u32 dt_prop_get_u32_def(const struct pdbg_target *node, const char *prop, u32 def); +u32 dt_prop_get_u32_index(const struct pdbg_target *node, const char *prop, u32 index); +const void *dt_prop_get(const struct pdbg_target *node, const char *prop); +const void *dt_prop_get_def(const struct pdbg_target *node, const char *prop, void *def); -const void *dt_prop_get_def_size(const struct dt_node *node, const char *prop, +const void *dt_prop_get_def_size(const struct pdbg_target *node, const char *prop, void *def, size_t *len); -u32 dt_prop_get_cell(const struct dt_node *node, const char *prop, u32 cell); -u32 dt_prop_get_cell_def(const struct dt_node *node, const char *prop, u32 cell, u32 def); +u32 dt_prop_get_cell(const struct pdbg_target *node, const char *prop, u32 cell); +u32 dt_prop_get_cell_def(const struct pdbg_target *node, const char *prop, u32 cell, u32 def); /* Parsing helpers */ -u32 dt_n_address_cells(const struct dt_node *node); -u32 dt_n_size_cells(const struct dt_node *node); +u32 dt_n_address_cells(const struct pdbg_target *node); +u32 dt_n_size_cells(const struct pdbg_target *node); u64 dt_get_number(const void *pdata, unsigned int cells); /* Find an chip-id property in this node; if not found, walk up the parent * nodes. Returns -1 if no chip-id property exists. */ -u32 dt_get_chip_id(const struct dt_node *node); +u32 dt_get_chip_id(const struct pdbg_target *node); /* Address accessors ("reg" properties parsing). No translation, * only support "simple" address forms (1 or 2 cells). Asserts * if address doesn't exist */ -u64 dt_get_address(const struct dt_node *node, unsigned int index, +u64 dt_get_address(const struct pdbg_target *node, unsigned int index, u64 *out_size); /* Count "reg" property entries */ -unsigned int dt_count_addresses(const struct dt_node *node); +unsigned int dt_count_addresses(const struct pdbg_target *node); /* Address translation * @@ -227,12 +217,12 @@ unsigned int dt_count_addresses(const struct dt_node *node); * handle complex address formats with address space indicators * nor will it handle "ranges" translations yet... (XX TODO) */ -u64 dt_translate_address(const struct dt_node *node, unsigned int index, +u64 dt_translate_address(const struct pdbg_target *node, unsigned int index, u64 *out_size); /* compare function used to sort child nodes by name when added to the * tree. This is mainly here for testing. */ -int dt_cmp_subnodes(const struct dt_node *a, const struct dt_node *b); +int dt_cmp_subnodes(const struct pdbg_target *a, const struct pdbg_target *b); #endif /* __DEVICE_H */ diff --git a/libpdbg/host.c b/libpdbg/host.c index 0c5e07b..f43b355 100644 --- a/libpdbg/host.c +++ b/libpdbg/host.c @@ -91,7 +91,10 @@ static int host_pib_probe(struct pdbg_target *target) if (!fd) return -1; - chip_id = dt_prop_get_u32(target->dn, "chip-id"); + chip_id = dt_get_chip_id(target); + if (chip_id == -1) + goto out; + if (asprintf(&access_fn, "%s/%08d/access", XSCOM_BASE_PATH, chip_id) < 0) goto out; diff --git a/libpdbg/htm.c b/libpdbg/htm.c index 4c1ee01..cf91f12 100644 --- a/libpdbg/htm.c +++ b/libpdbg/htm.c @@ -492,7 +492,7 @@ static int configure_nhtm(struct htm *htm) NHTM_TTYPE_SIZE_MASK ))) /* no pattern matching */ return -1; - if (dt_node_is_compatible(htm->target.dn, "ibm,power9-nhtm")) { + if (dt_node_is_compatible(&htm->target, "ibm,power9-nhtm")) { if (HTM_ERR(pib_read(&htm->target, NHTM_FLEX_MUX, &val))) return -1; @@ -532,7 +532,7 @@ static int do_htm_start(struct htm *htm) /* * Instead of the HTM_TRIG_START, this is where you might want * to call do_adu_magic() - * for_each_child_target("adu", htm->target.dn->parent->target, do_adu_magic, NULL, NULL); + * for_each_child_target("adu", &htm->target.parent, do_adu_magic, NULL, NULL); * see what I mean? */ @@ -544,7 +544,7 @@ static char *get_debugfs_file(struct htm *htm, const char *file) uint32_t chip_id; char *filename; - chip_id = dt_get_chip_id(htm->target.dn); + chip_id = dt_get_chip_id(&htm->target); if (chip_id == -1) { PR_ERROR("Couldn't find a chip id\n"); return NULL; @@ -751,7 +751,7 @@ static int do_htm_status(struct htm *htm) uint64_t val, total; int i, regs = 9; - if (dt_node_is_compatible(htm->target.dn, "ibm,power9-nhtm")) + if (dt_node_is_compatible(&htm->target, "ibm,power9-nhtm")) regs++; PR_DEBUG("HTM register dump:\n"); @@ -844,7 +844,7 @@ static int do_htm_dump(struct htm *htm, uint64_t size, const char *basename) return -1; } - chip_id = dt_get_chip_id(htm->target.dn); + chip_id = dt_get_chip_id(&htm->target); if (chip_id == -1) return -1; @@ -925,7 +925,7 @@ static int nhtm_probe(struct pdbg_target *target) if (!is_debugfs_memtrace_ok() || !is_debugfs_scom_ok()) return -1; - if (dt_node_is_compatible(target->dn, "ibm,power9-nhtm")) { + if (dt_node_is_compatible(target, "ibm,power9-nhtm")) { pib_read(target, NHTM_FLEX_MUX, &val); if (GETFIELD(NHTM_FLEX_MUX_MASK, val) != NHTM_FLEX_DEFAULT) { PR_DEBUG("FLEX_MUX not default\n"); diff --git a/libpdbg/i2c.c b/libpdbg/i2c.c index 62fc1d3..df5ac86 100644 --- a/libpdbg/i2c.c +++ b/libpdbg/i2c.c @@ -129,8 +129,8 @@ int i2c_target_probe(struct pdbg_target *target) const char *bus; int addr; - bus = dt_prop_get_def(pib->target.dn, "bus", "/dev/i2c4"); - addr = dt_get_address(pib->target.dn, 0, NULL); + bus = dt_prop_get_def(&pib->target, "bus", "/dev/i2c4"); + addr = dt_get_address(&pib->target, 0, NULL); assert(addr); i2c_data = malloc(sizeof(*i2c_data)); diff --git a/libpdbg/libpdbg.c b/libpdbg/libpdbg.c index 6194048..86f3dc4 100644 --- a/libpdbg/libpdbg.c +++ b/libpdbg/libpdbg.c @@ -31,7 +31,7 @@ retry: return next; else { /* Check if this target is a child of the given parent */ - for (tmp = next; tmp && next->dn->parent && tmp != parent; tmp = tmp->dn->parent->target) {} + for (tmp = next; tmp && next->parent && tmp != parent; tmp = tmp->parent) {} if (tmp == parent) return next; else { @@ -43,23 +43,23 @@ retry: struct pdbg_target *__pdbg_next_child_target(struct pdbg_target *parent, struct pdbg_target *last) { - if (!parent || list_empty(&parent->dn->children)) + if (!parent || list_empty(&parent->children)) return NULL; if (!last) - return list_top(&parent->dn->children, struct dt_node, list)->target; + return list_top(&parent->children, struct pdbg_target, list); - if (last->dn->list.next == &parent->dn->children.n) + if (last->list.next == &parent->children.n) return NULL; - return list_entry(last->dn->list.next, struct dt_node, list)->target; + return list_entry(last->list.next, struct pdbg_target, list); } enum pdbg_target_status pdbg_target_status(struct pdbg_target *target) { struct dt_property *p; - p = dt_find_property(target->dn, "status"); + p = dt_find_property(target, "status"); if (!p) return PDBG_TARGET_ENABLED; @@ -81,35 +81,35 @@ void pdbg_enable_target(struct pdbg_target *target) if (status == PDBG_TARGET_ENABLED) return; - p = dt_find_property(target->dn, "status"); - dt_del_property(target->dn, p); + p = dt_find_property(target, "status"); + dt_del_property(target, p); } void pdbg_disable_target(struct pdbg_target *target) { struct dt_property *p; - p = dt_find_property(target->dn, "status"); + p = dt_find_property(target, "status"); if (p) /* We don't override hard-coded device tree * status. This is needed to avoid disabling that * backend. */ return; - dt_add_property_string(target->dn, "status", "disabled"); + dt_add_property_string(target, "status", "disabled"); } /* Searches up the tree and returns the first valid index found */ uint32_t pdbg_target_index(struct pdbg_target *target) { - struct dt_node *dn; + struct pdbg_target *dn; - for (dn = target->dn; dn && dn->target->index == -1; dn = dn->parent); + for (dn = target; dn && dn->index == -1; dn = dn->parent); if (!dn) return -1; else - return dn->target->index; + return dn->index; } /* Searched up the tree for the first target of the right class and returns its index */ @@ -117,7 +117,7 @@ uint32_t pdbg_parent_index(struct pdbg_target *target, char *class) { struct pdbg_target *tmp; - for (tmp = target; tmp && tmp->dn->parent; tmp = tmp->dn->parent->target) { + for (tmp = target; tmp && tmp->parent; tmp = tmp->parent) { if (!strcmp(class, pdbg_target_class_name(tmp))) return pdbg_target_index(tmp); } @@ -139,7 +139,7 @@ void pdbg_set_target_property(struct pdbg_target *target, const char *name, cons { struct dt_property *p; - if ((p = dt_find_property(target->dn, name))) { + if ((p = dt_find_property(target, name))) { if (size > p->len) { dt_resize_property(&p, size); p->len = size; @@ -147,7 +147,7 @@ void pdbg_set_target_property(struct pdbg_target *target, const char *name, cons memcpy(p->prop, val, size); } else { - dt_add_property(target->dn, name, val, size); + dt_add_property(target, name, val, size); } } @@ -155,7 +155,7 @@ void *pdbg_get_target_property(struct pdbg_target *target, const char *name, siz { struct dt_property *p; - p = dt_find_property(target->dn, name); + p = dt_find_property(target, name); if (p) { if (size) *size = p->len; @@ -168,7 +168,7 @@ void *pdbg_get_target_property(struct pdbg_target *target, const char *name, siz uint64_t pdbg_get_address(struct pdbg_target *target, uint64_t *size) { - return dt_get_address(target->dn, 0, size); + return dt_get_address(target, 0, size); } /* Difference from below is that it doesn't search up the tree for the given @@ -178,7 +178,7 @@ static int pdbg_get_target_u64_property(struct pdbg_target *target, const char * { struct dt_property *p; - p = dt_find_property(target->dn, name); + p = dt_find_property(target, name); if (!p) return -1; @@ -188,10 +188,10 @@ static int pdbg_get_target_u64_property(struct pdbg_target *target, const char * int pdbg_get_u64_property(struct pdbg_target *target, const char *name, uint64_t *val) { - struct dt_node *dn; + struct pdbg_target *dn; - for (dn = target->dn; dn; dn = dn->parent) { - if (!pdbg_get_target_u64_property(dn->target, name, val)) + for (dn = target; dn; dn = dn->parent) { + if (!pdbg_get_target_u64_property(dn, name, val)) return 0; } diff --git a/libpdbg/p8chip.c b/libpdbg/p8chip.c index 3d3795f..d68a521 100644 --- a/libpdbg/p8chip.c +++ b/libpdbg/p8chip.c @@ -87,7 +87,7 @@ static int assert_special_wakeup(struct core *chip) if (i++ > SPECIAL_WKUP_TIMEOUT) { PR_ERROR("Timeout waiting for special wakeup on %s@0x%08" PRIx64 "\n", chip->target.name, - dt_get_address(chip->target.dn, 0, NULL)); + dt_get_address(&chip->target, 0, NULL)); return -1; } } while (!(gp0 & SPECIAL_WKUP_DONE)); @@ -163,7 +163,7 @@ static int p8_thread_stop(struct thread *thread) { int i = 0; uint64_t val; - struct core *chip = target_to_core(thread->target.dn->parent->target); + struct core *chip = target_to_core(thread->target.parent); do { /* Quiese active thread */ @@ -201,7 +201,7 @@ static int p8_thread_stop(struct thread *thread) static int p8_thread_start(struct thread *thread) { uint64_t val; - struct core *chip = target_to_core(thread->target.dn->parent->target); + struct core *chip = target_to_core(thread->target.parent); /* Activate thread */ CHECK_ERR(pib_write(&thread->target, DIRECT_CONTROLS_REG, DIRECT_CONTROL_SP_START)); @@ -217,15 +217,15 @@ static int p8_thread_start(struct thread *thread) static int p8_ram_setup(struct thread *thread) { - struct dt_node *dn; - struct core *chip = target_to_core(thread->target.dn->parent->target); + struct pdbg_target *target; + struct core *chip = target_to_core(thread->target.parent); uint64_t ram_mode, val; /* We can only ram a thread if all the threads on the core/chip are * quiesced */ - dt_for_each_compatible(chip->target.dn, dn, "ibm,power8-thread") { + dt_for_each_compatible(&chip->target, target, "ibm,power8-thread") { struct thread *tmp; - tmp = target_to_thread(dn->target); + tmp = target_to_thread(target); if (!(get_thread_status(tmp) & THREAD_STATUS_QUIESCE)) return 1; } @@ -250,7 +250,7 @@ static int p8_ram_setup(struct thread *thread) static int p8_ram_instruction(struct thread *thread, uint64_t opcode, uint64_t *scratch) { - struct core *chip = target_to_core(thread->target.dn->parent->target); + struct core *chip = target_to_core(thread->target.parent); uint64_t val; CHECK_ERR(pib_write(&chip->target, SCR0_REG, *scratch)); @@ -282,7 +282,7 @@ static int p8_ram_instruction(struct thread *thread, uint64_t opcode, uint64_t * static int p8_ram_destroy(struct thread *thread) { - struct core *chip = target_to_core(thread->target.dn->parent->target); + struct core *chip = target_to_core(thread->target.parent); uint64_t ram_mode; /* Disable RAM mode */ @@ -300,7 +300,7 @@ static int p8_thread_probe(struct pdbg_target *target) { struct thread *thread = target_to_thread(target); - thread->id = (dt_get_address(target->dn, 0, NULL) >> 4) & 0xf; + thread->id = (dt_get_address(target, 0, NULL) >> 4) & 0xf; thread->status = get_thread_status(thread); return 0; diff --git a/libpdbg/p9chip.c b/libpdbg/p9chip.c index 8f7a86c..41f694e 100644 --- a/libpdbg/p9chip.c +++ b/libpdbg/p9chip.c @@ -74,7 +74,7 @@ static int p9_thread_probe(struct pdbg_target *target) { struct thread *thread = target_to_thread(target); - thread->id = dt_prop_get_u32(target->dn, "tid"); + thread->id = dt_prop_get_u32(target, "tid"); thread->status = p9_get_thread_status(thread); return 0; @@ -125,18 +125,18 @@ static int p9_thread_sreset(struct thread *thread) static int p9_ram_setup(struct thread *thread) { - struct dt_node *dn; - struct core *chip = target_to_core(thread->target.dn->parent->target); + struct pdbg_target *target; + struct core *chip = target_to_core(thread->target.parent); /* We can only ram a thread if all the threads on the core/chip are * quiesced */ - dt_for_each_compatible(chip->target.dn, dn, "ibm,power9-thread") { + dt_for_each_compatible(&chip->target, target, "ibm,power9-thread") { struct thread *tmp; /* If this thread wasn't enabled it may not yet have been probed so do that now. This will also update the thread status */ - p9_thread_probe(dn->target); - tmp = target_to_thread(dn->target); + p9_thread_probe(target); + tmp = target_to_thread(target); if (tmp->status != (THREAD_STATUS_QUIESCE | THREAD_STATUS_ACTIVE)) return 1; } @@ -233,7 +233,7 @@ static int p9_core_probe(struct pdbg_target *target) if (i++ > SPECIAL_WKUP_TIMEOUT) { PR_ERROR("Timeout waiting for special wakeup on %s@0x%08" PRIx64 "\n", target->name, - dt_get_address(target->dn, 0, NULL)); + dt_get_address(target, 0, NULL)); break; } } while (!(value & SPECIAL_WKUP_DONE)); diff --git a/libpdbg/target.c b/libpdbg/target.c index 07159d2..984dcd2 100644 --- a/libpdbg/target.c +++ b/libpdbg/target.c @@ -17,22 +17,21 @@ struct list_head target_classes = LIST_HEAD_INIT(target_classes); /* Work out the address to access based on the current target and * final class name */ -static struct dt_node *get_class_target_addr(struct dt_node *dn, const char *name, uint64_t *addr) +static struct pdbg_target *get_class_target_addr(struct pdbg_target *target, const char *name, uint64_t *addr) { /* Check class */ - while (strcmp(dn->target->class, name)) { + while (strcmp(target->class, name)) { /* Keep walking the tree translating addresses */ - *addr += dt_get_address(dn, 0, NULL); - dn = dn->parent; + *addr += dt_get_address(target, 0, NULL); + target = target->parent; /* The should always be a parent. If there isn't it * means we traversed up the whole device tree and * didn't find a parent matching the given class. */ - assert(dn); - assert(dn->target); + assert(target); } - return dn; + return target; } /* The indirect access code was largely stolen from hw/xscom.c in skiboot */ @@ -115,11 +114,9 @@ static int pib_indirect_write(struct pib *pib, uint64_t addr, uint64_t data) int pib_read(struct pdbg_target *pib_dt, uint64_t addr, uint64_t *data) { struct pib *pib; - struct dt_node *dn = pib_dt->dn; int rc; - dn = get_class_target_addr(dn, "pib", &addr); - pib_dt = dn->target; + pib_dt = get_class_target_addr(pib_dt, "pib", &addr); pib = target_to_pib(pib_dt); if (addr & PPC_BIT(0)) rc = pib_indirect_read(pib, addr, data); @@ -131,11 +128,9 @@ int pib_read(struct pdbg_target *pib_dt, uint64_t addr, uint64_t *data) int pib_write(struct pdbg_target *pib_dt, uint64_t addr, uint64_t data) { struct pib *pib; - struct dt_node *dn = pib_dt->dn; int rc; - dn = get_class_target_addr(dn, "pib", &addr); - pib_dt = dn->target; + pib_dt = get_class_target_addr(pib_dt, "pib", &addr); pib = target_to_pib(pib_dt); if (addr & PPC_BIT(0)) rc = pib_indirect_write(pib, addr, data); @@ -147,11 +142,9 @@ int pib_write(struct pdbg_target *pib_dt, uint64_t addr, uint64_t data) int opb_read(struct pdbg_target *opb_dt, uint32_t addr, uint32_t *data) { struct opb *opb; - struct dt_node *dn = opb_dt->dn; uint64_t addr64 = addr; - dn = get_class_target_addr(dn, "opb", &addr64); - opb_dt = dn->target; + opb_dt = get_class_target_addr(opb_dt, "opb", &addr64); opb = target_to_opb(opb_dt); return opb->read(opb, addr64, data); } @@ -159,11 +152,9 @@ int opb_read(struct pdbg_target *opb_dt, uint32_t addr, uint32_t *data) int opb_write(struct pdbg_target *opb_dt, uint32_t addr, uint32_t data) { struct opb *opb; - struct dt_node *dn = opb_dt->dn; uint64_t addr64 = addr; - dn = get_class_target_addr(dn, "opb", &addr64); - opb_dt = dn->target; + opb_dt = get_class_target_addr(opb_dt, "opb", &addr64); opb = target_to_opb(opb_dt); return opb->write(opb, addr64, data); @@ -172,11 +163,9 @@ int opb_write(struct pdbg_target *opb_dt, uint32_t addr, uint32_t data) int fsi_read(struct pdbg_target *fsi_dt, uint32_t addr, uint32_t *data) { struct fsi *fsi; - struct dt_node *dn = fsi_dt->dn; uint64_t addr64 = addr; - dn = get_class_target_addr(dn, "fsi", &addr64); - fsi_dt = dn->target; + fsi_dt = get_class_target_addr(fsi_dt, "fsi", &addr64); fsi = target_to_fsi(fsi_dt); return fsi->read(fsi, addr64, data); } @@ -184,11 +173,9 @@ int fsi_read(struct pdbg_target *fsi_dt, uint32_t addr, uint32_t *data) int fsi_write(struct pdbg_target *fsi_dt, uint32_t addr, uint32_t data) { struct fsi *fsi; - struct dt_node *dn = fsi_dt->dn; uint64_t addr64 = addr; - dn = get_class_target_addr(dn, "fsi", &addr64); - fsi_dt = dn->target; + fsi_dt = get_class_target_addr(fsi_dt, "fsi", &addr64); fsi = target_to_fsi(fsi_dt); return fsi->write(fsi, addr64, data); @@ -196,10 +183,8 @@ int fsi_write(struct pdbg_target *fsi_dt, uint32_t addr, uint32_t data) struct pdbg_target *require_target_parent(struct pdbg_target *target) { - struct dt_node *dn; - - assert((dn = target->dn)); - return dn->parent->target; + assert(target->parent); + return target->parent; } /* Finds the given class. Returns NULL if not found. */ @@ -229,7 +214,7 @@ struct pdbg_target_class *require_target_class(const char *name) } /* Returns the existing class or allocates space for a new one */ -static struct pdbg_target_class *get_target_class(const char *name) +struct pdbg_target_class *get_target_class(const char *name) { struct pdbg_target_class *target_class; @@ -264,73 +249,44 @@ struct hw_unit_info *find_compatible_target(const char *compat) void pdbg_targets_init(void *fdt) { - struct dt_node *dn; - const struct dt_property *p; - struct pdbg_target_class *target_class; - struct hw_unit_info *hw_unit_info; - struct pdbg_target *new_target; - uint32_t index; - - dt_root = dt_new_root(""); + dt_root = dt_new_root("", NULL, 0); dt_expand(fdt); - - /* Now we need to walk the device-tree, assign struct pdbg_targets - * to each of the nodes and add them to the appropriate target - * classes */ - dt_for_each_node(dt_root, dn) { - p = dt_require_property(dn, "compatible", -1); - hw_unit_info = find_compatible_target(p->prop); - if (hw_unit_info) { - /* We need to allocate a new target */ - new_target = malloc(hw_unit_info->size); - assert(new_target); - memcpy(new_target, hw_unit_info->hw_unit, hw_unit_info->size); - new_target->dn = dn; - dn->target = new_target; - index = dt_prop_get_u32_def(dn, "index", -1); - dn->target->index = index; - target_class = get_target_class(new_target->class); - list_add(&target_class->targets, &new_target->class_link); - PR_DEBUG("Found target %s for %s\n", new_target->name, dn->name); - } else - PR_DEBUG("No target found for %s\n", dn->name); - } } /* Disable a node and all it's children */ -static void disable_node(struct dt_node *dn) +static void disable_node(struct pdbg_target *target) { - struct dt_node *next; + struct pdbg_target *t; struct dt_property *p; - p = dt_find_property(dn, "status"); + p = dt_find_property(target, "status"); if (p) - dt_del_property(dn, p); + dt_del_property(target, p); - dt_add_property_string(dn, "status", "disabled"); - dt_for_each_child(dn, next) - disable_node(next); + dt_add_property_string(target, "status", "disabled"); + dt_for_each_child(target, t) + disable_node(t); } -static void _target_probe(struct dt_node *dn) +static void _target_probe(struct pdbg_target *target) { int rc = 0; struct dt_property *p; - PR_DEBUG("Probe %s - ", dn->name); - if (!dn->target) { + PR_DEBUG("Probe %s - ", target->dn_name); + if (!target->class) { PR_DEBUG("target not found\n"); return; } - p = dt_find_property(dn, "status"); - if ((p && !strcmp(p->prop, "disabled")) || (dn->target->probe && (rc = dn->target->probe(dn->target)))) { + p = dt_find_property(target, "status"); + if ((p && !strcmp(p->prop, "disabled")) || (target->probe && (rc = target->probe(target)))) { if (rc) PR_DEBUG("not found\n"); else PR_DEBUG("disabled\n"); - disable_node(dn); + disable_node(target); } else { PR_DEBUG("success\n"); } @@ -340,10 +296,10 @@ static void _target_probe(struct dt_node *dn) * exist but don't */ void pdbg_target_probe(void) { - struct dt_node *dn; + struct pdbg_target *target; - dt_for_each_node(dt_root, dn) - _target_probe(dn); + dt_for_each_node(dt_root, target) + _target_probe(target); } bool pdbg_target_is_class(struct pdbg_target *target, const char *class) diff --git a/libpdbg/target.h b/libpdbg/target.h index 2bc7dba..e7f793c 100644 --- a/libpdbg/target.h +++ b/libpdbg/target.h @@ -45,13 +45,19 @@ struct pdbg_target { char *class; int (*probe)(struct pdbg_target *target); int index; - struct dt_node *dn; + const char *dn_name; + struct list_node list; + struct list_head properties; + struct list_head children; + struct pdbg_target *parent; + u32 phandle; struct list_node class_link; }; struct pdbg_target *require_target_parent(struct pdbg_target *target); struct pdbg_target_class *find_target_class(const char *name); struct pdbg_target_class *require_target_class(const char *name); +struct pdbg_target_class *get_target_class(const char *name); bool pdbg_target_is_class(struct pdbg_target *target, const char *class); extern struct list_head empty_list; @@ -62,6 +68,7 @@ struct hw_unit_info { void *hw_unit; size_t size; }; +struct hw_unit_info *find_compatible_target(const char *compat); /* We can't pack the structs themselves directly into a special * section because there doesn't seem to be any standard way of doing |