[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