[Pdbg] [PATCH v2 09/22] libpdbg: Parent retrieval should handle virtual nodes correctly
Amitay Isaacs
amitay at ozlabs.org
Fri Sep 20 15:16:38 AEST 2019
When traversing system device tree view (system == true), parent of a
node can be a virtual node.
When traversing backend device tree, parent of a node will not be a
virtual node unless it's part of the backend device tree itself.
Signed-off-by: Amitay Isaacs <amitay at ozlabs.org>
---
libpdbg/libpdbg.c | 17 +++++++++++------
libpdbg/libpdbg.h | 10 +++++-----
libpdbg/target.c | 27 ++++++++++++++++++++++++++-
libpdbg/target.h | 1 +
src/thread.c | 4 ++--
5 files changed, 45 insertions(+), 14 deletions(-)
diff --git a/libpdbg/libpdbg.c b/libpdbg/libpdbg.c
index 7029647..db0a564 100644
--- a/libpdbg/libpdbg.c
+++ b/libpdbg/libpdbg.c
@@ -6,7 +6,7 @@
static pdbg_progress_tick_t progress_tick;
-struct pdbg_target *__pdbg_next_target(const char *class, struct pdbg_target *parent, struct pdbg_target *last)
+struct pdbg_target *__pdbg_next_target(const char *class, struct pdbg_target *parent, struct pdbg_target *last, bool system)
{
struct pdbg_target *next, *tmp;
struct pdbg_target_class *target_class;
@@ -33,7 +33,7 @@ retry:
return next;
else {
/* Check if this target is a child of the given parent */
- for (tmp = next; tmp && next->parent && tmp != parent; tmp = tmp->parent) {}
+ for (tmp = next; tmp && get_parent(tmp, system) && tmp != parent; tmp = get_parent(tmp, system)) {}
if (tmp == parent)
return next;
else {
@@ -116,7 +116,7 @@ uint32_t pdbg_target_index(struct pdbg_target *target)
{
struct pdbg_target *dn;
- for (dn = target; dn && dn->index == -1; dn = dn->parent);
+ for (dn = target; dn && dn->index == -1; dn = get_parent(dn, true));
if (!dn)
return -1;
@@ -130,10 +130,15 @@ struct pdbg_target *pdbg_target_parent(const char *class, struct pdbg_target *ta
struct pdbg_target *parent;
if (!class)
- return target->parent;
+ return get_parent(target, true);
- for (parent = target->parent; parent && parent->parent; parent = parent->parent) {
- if (!strcmp(class, pdbg_target_class_name(parent)))
+ for (parent = get_parent(target, true); parent && get_parent(parent, true); parent = get_parent(parent, true)) {
+ const char *tclass = pdbg_target_class_name(parent);
+
+ if (!tclass)
+ continue;
+
+ if (!strcmp(class, tclass))
return parent;
}
diff --git a/libpdbg/libpdbg.h b/libpdbg/libpdbg.h
index 2ae29cc..de3fc17 100644
--- a/libpdbg/libpdbg.h
+++ b/libpdbg/libpdbg.h
@@ -19,7 +19,7 @@ struct pdbg_target_class;
struct pdbg_target *__pdbg_next_compatible_node(struct pdbg_target *root,
struct pdbg_target *prev,
const char *compat);
-struct pdbg_target *__pdbg_next_target(const char *klass, struct pdbg_target *parent, struct pdbg_target *last);
+struct pdbg_target *__pdbg_next_target(const char *klass, struct pdbg_target *parent, struct pdbg_target *last, bool system);
struct pdbg_target *__pdbg_next_child_target(struct pdbg_target *parent, struct pdbg_target *last, bool system);
/*
@@ -61,14 +61,14 @@ enum pdbg_backend { PDBG_DEFAULT_BACKEND = 0, PDBG_BACKEND_FSI, PDBG_BACKEND_I2C
(target = __pdbg_next_compatible_node(parent, target, compat)) != NULL;)
#define pdbg_for_each_target(class, parent, target) \
- for (target = __pdbg_next_target(class, parent, NULL); \
+ for (target = __pdbg_next_target(class, parent, NULL, true); \
target; \
- target = __pdbg_next_target(class, parent, target))
+ target = __pdbg_next_target(class, parent, target, true))
#define pdbg_for_each_class_target(class, target) \
- for (target = __pdbg_next_target(class, NULL, NULL); \
+ for (target = __pdbg_next_target(class, NULL, NULL, true); \
target; \
- target = __pdbg_next_target(class, NULL, target))
+ target = __pdbg_next_target(class, NULL, target, true))
#define pdbg_for_each_child_target(parent, target) \
for (target = __pdbg_next_child_target(parent, NULL, true); \
diff --git a/libpdbg/target.c b/libpdbg/target.c
index da24ba0..667e55d 100644
--- a/libpdbg/target.c
+++ b/libpdbg/target.c
@@ -27,7 +27,7 @@ static struct pdbg_target *get_class_target_addr(struct pdbg_target *target, con
*addr += pdbg_target_address(target, NULL);
/* Keep walking the tree translating addresses */
- target = target->parent;
+ target = get_parent(target, false);
/* The root node doesn't have an address space so it's
* an error in the device tree if we hit this. */
@@ -312,6 +312,31 @@ uint32_t sbe_ffdc_get(struct pdbg_target *target, const uint8_t **ffdc, uint32_t
return sbefifo->ffdc_get(sbefifo, ffdc, ffdc_len);
}
+struct pdbg_target *get_parent(struct pdbg_target *target, bool system)
+{
+ struct pdbg_target *parent;
+
+ if (!target)
+ return NULL;
+
+ if (system) {
+ if (target->compatible && target->vnode)
+ target = target->vnode;
+ } else {
+ if (!target->compatible && target->vnode)
+ target = target->vnode;
+ }
+
+ parent = target->parent;
+ if (!parent || !parent->vnode)
+ return parent;
+
+ if (parent->compatible)
+ return parent;
+
+ return parent->vnode;
+}
+
struct pdbg_target *require_target_parent(struct pdbg_target *target)
{
assert(target->parent);
diff --git a/libpdbg/target.h b/libpdbg/target.h
index 7e08ac3..7419ce5 100644
--- a/libpdbg/target.h
+++ b/libpdbg/target.h
@@ -53,6 +53,7 @@ struct pdbg_target {
struct pdbg_target *vnode;
};
+struct pdbg_target *get_parent(struct pdbg_target *target, bool system);
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);
diff --git a/src/thread.c b/src/thread.c
index 663f290..8ddf4ae 100644
--- a/src/thread.c
+++ b/src/thread.c
@@ -277,10 +277,10 @@ static int thread_status_print(void)
assert(path_target_add(pib));
}
- pib = __pdbg_next_target("pib", pdbg_target_root(), NULL);
+ pib = __pdbg_next_target("pib", pdbg_target_root(), NULL, true);
assert(pib);
- core = __pdbg_next_target("core", pib, NULL);
+ core = __pdbg_next_target("core", pib, NULL, true);
assert(core);
pdbg_for_each_target("thread", core, thread)
--
2.21.0
More information about the Pdbg
mailing list