diff mbox series

[v2,04/16] libpdbg: Add indirect address translation via callback

Message ID 20181107053943.4307-5-alistair@popple.id.au
State Superseded
Headers show
Series Cleanup old code | expand

Checks

Context Check Description
snowpatch_ozlabs/apply_patch success master/apply_patch Successfully applied
snowpatch_ozlabs/build-multiarch success Test build-multiarch on branch master

Commit Message

Alistair Popple Nov. 7, 2018, 5:39 a.m. UTC
Some hardware targets have more complicated addressing schemes than a
simple base address + offset. It may be possible to determine a
device-tree representation for these schemes but for the moment it is
more straight forward to define a callback to do the translation.

Signed-off-by: Alistair Popple <alistair@popple.id.au>
---
 libpdbg/target.c | 7 ++++++-
 libpdbg/target.h | 7 +++++++
 2 files changed, 13 insertions(+), 1 deletion(-)

Comments

Amitay Isaacs Nov. 7, 2018, 6:02 a.m. UTC | #1
Reviewed-by: Amitay Isaacs <amitay@ozlabs.org>

On Wed, 2018-11-07 at 16:39 +1100, Alistair Popple wrote:
> Some hardware targets have more complicated addressing schemes than a
> simple base address + offset. It may be possible to determine a
> device-tree representation for these schemes but for the moment it is
> more straight forward to define a callback to do the translation.
> 
> Signed-off-by: Alistair Popple <alistair@popple.id.au>
> ---
>  libpdbg/target.c | 7 ++++++-
>  libpdbg/target.h | 7 +++++++
>  2 files changed, 13 insertions(+), 1 deletion(-)
> 
> diff --git a/libpdbg/target.c b/libpdbg/target.c
> index 975ecec..7468863 100644
> --- a/libpdbg/target.c
> +++ b/libpdbg/target.c
> @@ -20,8 +20,13 @@ static struct pdbg_target
> *get_class_target_addr(struct pdbg_target *target, con
>  {
>  	/* Check class */
>  	while (strcmp(target->class, name)) {
> +
> +		if (target->translate)
> +			*addr = target->translate(target, *addr);
> +		else
> +			*addr += dt_get_address(target, 0, NULL);
> +
>  		/* Keep walking the tree translating addresses */
> -		*addr += dt_get_address(target, 0, NULL);
>  		target = target->parent;
>  
>  		/* The root node doesn't have an address space so it's
> diff --git a/libpdbg/target.h b/libpdbg/target.h
> index d1a6aec..289c1ee 100644
> --- a/libpdbg/target.h
> +++ b/libpdbg/target.h
> @@ -38,6 +38,7 @@ struct pdbg_target {
>  	char *class;
>  	int (*probe)(struct pdbg_target *target);
>  	void (*release)(struct pdbg_target *target);
> +	uint64_t (*translate)(struct pdbg_target *target, uint64_t
> addr);
>  	int index;
>  	enum pdbg_target_status status;
>  	const char *dn_name;
> @@ -57,6 +58,12 @@ struct pdbg_target_class
> *require_target_class(const char *name);
>  struct pdbg_target_class *get_target_class(const char *name);
>  bool pdbg_target_is_class(struct pdbg_target *target, const char
> *class);
>  
> +/* This works and should be safe because struct pdbg_target is
> guaranteed to be
> + * the first member of the specialised type (see the DECLARE_HW_UNIT
> definition
> + * below). I'm not sure how sane it is though. Probably not very but
> it does
> + * remove a bunch of tedious container_of() typing */
> +#define translate_cast(x) (uint64_t (*)(struct pdbg_target *,
> uint64_t)) (x)
> +
>  extern struct list_head empty_list;
>  extern struct list_head target_classes;
>  
> -- 
> 2.11.0
> 

Amitay.
diff mbox series

Patch

diff --git a/libpdbg/target.c b/libpdbg/target.c
index 975ecec..7468863 100644
--- a/libpdbg/target.c
+++ b/libpdbg/target.c
@@ -20,8 +20,13 @@  static struct pdbg_target *get_class_target_addr(struct pdbg_target *target, con
 {
 	/* Check class */
 	while (strcmp(target->class, name)) {
+
+		if (target->translate)
+			*addr = target->translate(target, *addr);
+		else
+			*addr += dt_get_address(target, 0, NULL);
+
 		/* Keep walking the tree translating addresses */
-		*addr += dt_get_address(target, 0, NULL);
 		target = target->parent;
 
 		/* The root node doesn't have an address space so it's
diff --git a/libpdbg/target.h b/libpdbg/target.h
index d1a6aec..289c1ee 100644
--- a/libpdbg/target.h
+++ b/libpdbg/target.h
@@ -38,6 +38,7 @@  struct pdbg_target {
 	char *class;
 	int (*probe)(struct pdbg_target *target);
 	void (*release)(struct pdbg_target *target);
+	uint64_t (*translate)(struct pdbg_target *target, uint64_t addr);
 	int index;
 	enum pdbg_target_status status;
 	const char *dn_name;
@@ -57,6 +58,12 @@  struct pdbg_target_class *require_target_class(const char *name);
 struct pdbg_target_class *get_target_class(const char *name);
 bool pdbg_target_is_class(struct pdbg_target *target, const char *class);
 
+/* This works and should be safe because struct pdbg_target is guaranteed to be
+ * the first member of the specialised type (see the DECLARE_HW_UNIT definition
+ * below). I'm not sure how sane it is though. Probably not very but it does
+ * remove a bunch of tedious container_of() typing */
+#define translate_cast(x) (uint64_t (*)(struct pdbg_target *, uint64_t)) (x)
+
 extern struct list_head empty_list;
 extern struct list_head target_classes;