[Pdbg] [RFC 11/12] libpdbg: Implement logic to link backends with each target

Alistair Popple alistair at popple.id.au
Tue Aug 6 11:37:22 AEST 2019


Signed-off-by: Alistair Popple <alistair at popple.id.au>
---
 libpdbg/device.c | 37 +++++++++++++++++++++++++------------
 libpdbg/target.c |  7 ++++++-
 2 files changed, 31 insertions(+), 13 deletions(-)

diff --git a/libpdbg/device.c b/libpdbg/device.c
index 428d946..720a81b 100644
--- a/libpdbg/device.c
+++ b/libpdbg/device.c
@@ -686,27 +686,40 @@ static struct pdbg_target *pdbg_get_system_target(struct pdbg_target *backend_ta
 static void pdbg_link_backend_targets(struct pdbg_target *backend_target)
 {
 	struct pdbg_target *system_target, *child;
+	char *target_path;
+
+	/* Recursively link all child targets */
+	pdbg_for_each_child_target(backend_target, child)
+		pdbg_link_backend_targets(child);
 
 	system_target = pdbg_get_system_target(backend_target);
-	if (system_target) {
+	target_path = pdbg_target_property(backend_target, "target", NULL);
+	if (target_path)
+		backend_target = pdbg_target_from_path(pdbg_dt_root, target_path);
+
+	if (system_target && backend_target) {
 		PR_DEBUG("Linking backend target %s to system target %s\n",
 			 pdbg_target_path(backend_target), pdbg_target_path(system_target));
 
-		/* The backend class must match the system class */
-		assert(!strcmp(pdbg_target_class_name(backend_target),
-			       pdbg_target_class_name(system_target)));
+		/* If the backend target actually implements the
+		 * access methods (as indicated by the presence of a
+		 * compatible property) make sure it matches the
+		 * class. */
+		if (backend_target->compatible) {
+			assert(get_target_class(backend_target) == get_target_class(system_target));
+		} else {
+			assert(system_target->class);
+			backend_target->class = system_target->class;
+		}
 		system_target->backend = backend_target;
 
-		/* A backend target shoudl always use it's own implementation for access */
+		/* A backend target should always use it's own implementation for access */
 		backend_target->backend = backend_target;
-	} else {
-		PR_INFO("Unable to match backend at %s to system target %s",
-			pdbg_target_path(backend_target), pdbg_target_path(system_target));
+	} else if (system_target) {
+		PR_INFO("Unable to find backend for %s at %s\n", pdbg_target_path(system_target),
+			target_path);
+		system_target->status = PDBG_TARGET_NONEXISTENT;
 	}
-
-	/* Recursively link all child targets as well */
-	pdbg_for_each_child_target(backend_target, child)
-		pdbg_link_backend_targets(child);
 }
 
 void pdbg_backend_init(void *fdt)
diff --git a/libpdbg/target.c b/libpdbg/target.c
index d6604c2..5cbddac 100644
--- a/libpdbg/target.c
+++ b/libpdbg/target.c
@@ -338,6 +338,7 @@ struct pdbg_target_class *get_target_class(struct pdbg_target *target)
 {
 	struct pdbg_target_class *target_class;
 
+	assert(target->class);
 	if ((target_class = find_target_class(target->class)))
 		return target_class;
 
@@ -369,7 +370,11 @@ enum pdbg_target_status pdbg_target_probe(struct pdbg_target *target)
 		 * it's status won't have changed */
 		   return status;
 
-	parent = target->parent;
+	if (target->backend)
+		parent = target->backend->parent;
+	else
+		parent = target->parent;
+
 	if (parent) {
 		/* Recurse up the tree to probe and set parent target status */
 		pdbg_target_probe(parent);
-- 
2.20.1



More information about the Pdbg mailing list