summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorCyril Bur <cyrilbur@gmail.com>2018-04-12 16:01:53 +1000
committerAlistair Popple <alistair@popple.id.au>2018-04-24 13:01:20 +1000
commite227bee0be86ccd2fe10887c8406d30effd7127a (patch)
tree7b5b1b68ea1143a8d82ed1426666c7de6c485b0c
parent808854c5adc2a058e2f317cde54fab69eecc5429 (diff)
downloadpdbg-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.c22
-rw-r--r--libpdbg/cfam.c12
-rw-r--r--libpdbg/device.c202
-rw-r--r--libpdbg/device.h104
-rw-r--r--libpdbg/host.c5
-rw-r--r--libpdbg/htm.c12
-rw-r--r--libpdbg/i2c.c4
-rw-r--r--libpdbg/libpdbg.c44
-rw-r--r--libpdbg/p8chip.c20
-rw-r--r--libpdbg/p9chip.c14
-rw-r--r--libpdbg/target.c108
-rw-r--r--libpdbg/target.h9
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
OpenPOWER on IntegriCloud