[Pdbg] [PATCH v4 14/30] libpdbg: Parent retrieval should handle virtual nodes correctly

Alistair Popple alistair at popple.id.au
Wed Oct 9 15:06:04 AEDT 2019


Reviewed-by: Alistair Popple <alistair at popple.id.au>

On Thursday, 3 October 2019 2:18:53 PM AEDT Amitay Isaacs wrote:
> 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 | 46 ++++++++++++++++++++++++++++++++++++++++------
>  libpdbg/libpdbg.h | 10 +++++-----
>  libpdbg/target.c  |  2 +-
>  libpdbg/target.h  |  1 +
>  src/thread.c      |  4 ++--
>  5 files changed, 49 insertions(+), 14 deletions(-)
> 
> diff --git a/libpdbg/libpdbg.c b/libpdbg/libpdbg.c
> index 158c63e..7e72024 100644
> --- a/libpdbg/libpdbg.c
> +++ b/libpdbg/libpdbg.c
> @@ -6,7 +6,36 @@
>  
>  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 *get_parent(struct pdbg_target *target, bool system)
> +{
> +	struct pdbg_target *parent;
> +
> +	if (!target)
> +		return NULL;
> +
> +	/*
> +	 * To find a parent in the system tree:
> +	 *   - If a target is real, map it to possible virtual target
> +	 *   - Calculate the parent
> +	 *   - If the parent is virtual, map it to real target
> +	 *
> +	 * To find a parent in the backend tree:
> +	 *   - Target will be real or virtual without mapped real node
> +	 *   - Calculate the parent
> +	 *   - If the parent is virtual, map it to real target
> +	 */
> +	if (system)
> +		target = target_to_virtual(target);
> +
> +	parent = target->parent;
> +
> +	if (!parent)
> +		return NULL;
> +
> +	return target_to_real(parent);
> +}
> +
> +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 +62,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 {
> @@ -160,7 +189,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;
> @@ -174,10 +203,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 = 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;
>  
> -	for (parent = target->parent; parent && parent->parent; parent = parent->parent) {
> -		if (!strcmp(class, pdbg_target_class_name(parent)))
> +		if (!strcmp(class, tclass))
>  			return parent;
>  	}
>  
> diff --git a/libpdbg/libpdbg.h b/libpdbg/libpdbg.h
> index 4eec123..ca4f951 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 f3d4db8..a68cb6c 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. */
> diff --git a/libpdbg/target.h b/libpdbg/target.h
> index 8148f83..a8b0d3d 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_class *find_target_class(const char *name);
>  struct pdbg_target_class *require_target_class(const char *name);
>  struct pdbg_target_class *get_target_class(struct pdbg_target *target);
> 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)
> 






More information about the Pdbg mailing list