[Pdbg] [PATCH v2 09/22] libpdbg: Parent retrieval should handle virtual nodes correctly
Amitay Isaacs
amitay at ozlabs.org
Mon Sep 23 18:11:44 AEST 2019
On Mon, 2019-09-23 at 13:23 +1000, Alistair Popple wrote:
> On Friday, 20 September 2019 3:16:38 PM AEST 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 | 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;
>
> Do we need to add any filtering with something like
> pdbg_next_target_match()
> here? Or are we ok returning everything for a particular target
> class
> regardless of which tree it falls under?
We do need a mapping. But turns out the mapping for child and mapping
for parent is slightly different. Figured that out after refactoring
it as common code. :-(
>
> > 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;
> > + }
>
> Still not sure I completely follow the reasoning behind this logic so
> it would
> be good if we could get some comments describing the
> rules/assumptions for
> each node type.
I will add comments to get_parent() to explain how the mapping is done.
>
> - Alistair
>
> > + 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)
> >
>
>
>
Amitay.
--
The man with imagination is never alone.
More information about the Pdbg
mailing list