[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