diff options
author | Alistair Popple <alistair@popple.id.au> | 2017-12-04 13:15:16 +1100 |
---|---|---|
committer | Alistair Popple <alistair@popple.id.au> | 2017-12-08 11:22:09 +1100 |
commit | 5f815d7a742eaebe01d44251db833b8051f393aa (patch) | |
tree | 0c23107ede525f761ebbcb2b17a8bb99188f12a2 | |
parent | 07aa13ea742ee447d7b5d5c295116510f2918119 (diff) | |
download | pdbg-5f815d7a742eaebe01d44251db833b8051f393aa.tar.gz pdbg-5f815d7a742eaebe01d44251db833b8051f393aa.zip |
Refactor for an exportable API
The existing API between libpdbg and pdbg was poorly defined. Other
programs are beginning to utilise libpdbg so a more strictly defined API
would be beneficial. This patch introduces a new header (libpdbg.h) which
includes the definition of a public API for libpdbg and updates pdbg to
only depend on this.
Signed-off-by: Alistair Popple <alistair@popple.id.au>
-rw-r--r-- | Makefile.am | 1 | ||||
-rw-r--r-- | libpdbg/chip.c | 29 | ||||
-rw-r--r-- | libpdbg/libpdbg.c | 196 | ||||
-rw-r--r-- | libpdbg/libpdbg.h | 89 | ||||
-rw-r--r-- | libpdbg/operations.h | 24 | ||||
-rw-r--r-- | libpdbg/p8chip.c | 2 | ||||
-rw-r--r-- | libpdbg/target.c | 4 | ||||
-rw-r--r-- | libpdbg/target.h | 11 | ||||
-rw-r--r-- | src/main.c | 309 |
9 files changed, 442 insertions, 223 deletions
diff --git a/Makefile.am b/Makefile.am index 9d34bff..4239a29 100644 --- a/Makefile.am +++ b/Makefile.am @@ -36,6 +36,7 @@ libfdt_la_SOURCES = \ libfdt/fdt_overlay.c libpdbg_la_SOURCES = \ + libpdbg/libpdbg.c \ libpdbg/host.c \ libpdbg/kernel.c \ libpdbg/fake.c \ diff --git a/libpdbg/chip.c b/libpdbg/chip.c index 03dcdc7..06ea4e9 100644 --- a/libpdbg/chip.c +++ b/libpdbg/chip.c @@ -80,8 +80,12 @@ static uint64_t ld(uint64_t rt, uint64_t ds, uint64_t ra) return LD_OPCODE | (rt << 21) | (ra << 16) | (ds << 2); } -uint64_t thread_status(struct thread *thread) +uint64_t thread_status(struct pdbg_target *target) { + struct thread *thread; + + assert(!strcmp(target->class, "thread")); + thread = target_to_thread(target); return thread->status; } @@ -132,13 +136,16 @@ int ram_sreset_thread(struct pdbg_target *thread_target) * data. Note that only register r0 is saved and restored so opcodes * must not touch other registers. */ -static int ram_instructions(struct thread *thread, uint64_t *opcodes, +static int ram_instructions(struct pdbg_target *thread_target, uint64_t *opcodes, uint64_t *results, int len, unsigned int lpar) { uint64_t opcode = 0, r0 = 0, r1 = 0, scratch = 0; int i; int exception = 0; + struct thread *thread; + assert(!strcmp(thread_target->class, "thread")); + thread = target_to_thread(thread_target); CHECK_ERR(thread->ram_setup(thread)); /* RAM instructions */ @@ -179,7 +186,7 @@ static int ram_instructions(struct thread *thread, uint64_t *opcodes, /* * Get gpr value. Chip must be stopped. */ -int ram_getgpr(struct thread *thread, int gpr, uint64_t *value) +int ram_getgpr(struct pdbg_target *thread, int gpr, uint64_t *value) { uint64_t opcodes[] = {mtspr(277, gpr)}; uint64_t results[] = {0}; @@ -189,7 +196,7 @@ int ram_getgpr(struct thread *thread, int gpr, uint64_t *value) return 0; } -int ram_putgpr(struct thread *thread, int gpr, uint64_t value) +int ram_putgpr(struct pdbg_target *thread, int gpr, uint64_t value) { uint64_t opcodes[] = {mfspr(gpr, 277)}; uint64_t results[] = {value}; @@ -199,7 +206,7 @@ int ram_putgpr(struct thread *thread, int gpr, uint64_t value) return 0; } -int ram_getnia(struct thread *thread, uint64_t *value) +int ram_getnia(struct pdbg_target *thread, uint64_t *value) { uint64_t opcodes[] = {mfnia(0), mtspr(277, 0)}; uint64_t results[] = {0, 0}; @@ -209,7 +216,7 @@ int ram_getnia(struct thread *thread, uint64_t *value) return 0; } -int ram_putnia(struct thread *thread, uint64_t value) +int ram_putnia(struct pdbg_target *thread, uint64_t value) { uint64_t opcodes[] = {mfspr(0, 277), mtnia(0)}; uint64_t results[] = {value, 0}; @@ -218,7 +225,7 @@ int ram_putnia(struct thread *thread, uint64_t value) return 0; } -int ram_getspr(struct thread *thread, int spr, uint64_t *value) +int ram_getspr(struct pdbg_target *thread, int spr, uint64_t *value) { uint64_t opcodes[] = {mfspr(0, spr), mtspr(277, 0)}; uint64_t results[] = {0, 0}; @@ -228,7 +235,7 @@ int ram_getspr(struct thread *thread, int spr, uint64_t *value) return 0; } -int ram_putspr(struct thread *thread, int spr, uint64_t value) +int ram_putspr(struct pdbg_target *thread, int spr, uint64_t value) { uint64_t opcodes[] = {mfspr(0, 277), mtspr(spr, 0)}; uint64_t results[] = {value, 0}; @@ -237,7 +244,7 @@ int ram_putspr(struct thread *thread, int spr, uint64_t value) return 0; } -int ram_getmsr(struct thread *thread, uint64_t *value) +int ram_getmsr(struct pdbg_target *thread, uint64_t *value) { uint64_t opcodes[] = {mfmsr(0), mtspr(277, 0)}; uint64_t results[] = {0, 0}; @@ -247,7 +254,7 @@ int ram_getmsr(struct thread *thread, uint64_t *value) return 0; } -int ram_putmsr(struct thread *thread, uint64_t value) +int ram_putmsr(struct pdbg_target *thread, uint64_t value) { uint64_t opcodes[] = {mfspr(0, 277), mtmsr(0)}; uint64_t results[] = {value, 0}; @@ -256,7 +263,7 @@ int ram_putmsr(struct thread *thread, uint64_t value) return 0; } -int ram_getmem(struct thread *thread, uint64_t addr, uint64_t *value) +int ram_getmem(struct pdbg_target *thread, uint64_t addr, uint64_t *value) { uint64_t opcodes[] = {mfspr(0, 277), mfspr(1, 277), ld(0, 0, 1), mtspr(277, 0)}; uint64_t results[] = {0xdeaddeaddeaddead, addr, 0, 0}; diff --git a/libpdbg/libpdbg.c b/libpdbg/libpdbg.c new file mode 100644 index 0000000..a971125 --- /dev/null +++ b/libpdbg/libpdbg.c @@ -0,0 +1,196 @@ +#include <string.h> + +#include "target.h" +#include "device.h" +#include "libpdbg.h" + +struct pdbg_target *__pdbg_next_target(const char *class, struct pdbg_target *parent, struct pdbg_target *last) +{ + struct pdbg_target *next, *tmp; + struct pdbg_target_class *target_class; + + if (class && !find_target_class(class)) + return NULL; + + target_class = require_target_class(class); + +retry: + /* No more targets left to check in this class */ + if ((last && last->class_link.next == &target_class->targets.n) || + list_empty(&target_class->targets)) + return NULL; + + if (last) + next = list_entry(last->class_link.next, struct pdbg_target, class_link); + else + if (!(next = list_top(&target_class->targets, struct pdbg_target, class_link))) + return NULL; + + if (!parent) + /* Parent is null, no need to check if this is a child */ + return next; + else { + /* Check if this target is a child of the given parent */ + for (tmp = next; tmp && next->dn->parent && tmp != parent; tmp = tmp->dn->parent->target) {} + if (tmp == parent) + return next; + else { + last = next; + goto retry; + } + } +} + +struct pdbg_target *__pdbg_next_child_target(struct pdbg_target *parent, struct pdbg_target *last) +{ + if (!parent || list_empty(&parent->dn->children)) + return NULL; + + if (!last) + return list_top(&parent->dn->children, struct dt_node, list)->target; + + if (last->dn->list.next == &parent->dn->children.n) + return NULL; + + return list_entry(last->dn->list.next, struct dt_node, list)->target; +} + +enum pdbg_target_status pdbg_target_status(struct pdbg_target *target) +{ + struct dt_property *p; + + p = dt_find_property(target->dn, "status"); + if (!p) + return PDBG_TARGET_ENABLED; + + if (!strcmp(p->prop, "enabled")) + return PDBG_TARGET_ENABLED; + else if (!strcmp(p->prop, "disabled")) + return PDBG_TARGET_DISABLED; + else if (!strcmp(p->prop, "hidden")) + return PDBG_TARGET_HIDDEN; + else + assert(0); +} + +void pdbg_enable_target(struct pdbg_target *target) +{ + struct dt_property *p; + enum pdbg_target_status status = pdbg_target_status(target); + + if (status == PDBG_TARGET_ENABLED) + return; + + p = dt_find_property(target->dn, "status"); + dt_del_property(target->dn, p); +} + +void pdbg_disable_target(struct pdbg_target *target) +{ + struct dt_property *p; + + p = dt_find_property(target->dn, "status"); + if (p) + /* We don't override hard-coded device tree + * status. This is needed to avoid disabling that + * backend. */ + return; + + dt_add_property_string(target->dn, "status", "disabled"); +} + +/* Searches up the tree and returns the first valid index found */ +uint32_t pdbg_target_index(struct pdbg_target *target) +{ + uint32_t index; + struct dt_node *dn = target->dn; + + for (index = dn->target->index; index == -1; dn = dn->parent); + return index; +} + +/* Searched up the tree for the first target of the right class and returns its index */ +uint32_t pdbg_parent_index(struct pdbg_target *target, char *class) +{ + struct pdbg_target *tmp; + + for (tmp = target; tmp && tmp->dn->parent; tmp = tmp->dn->parent->target) { + if (!strcmp(class, pdbg_target_class_name(tmp))) + return pdbg_target_index(tmp); + } + + return -1; +} + +char *pdbg_target_class_name(struct pdbg_target *target) +{ + return target->class; +} + +char *pdbg_target_name(struct pdbg_target *target) +{ + return target->name; +} + +void pdbg_set_target_property(struct pdbg_target *target, const char *name, const void *val, size_t size) +{ + struct dt_property *p; + + if ((p = dt_find_property(target->dn, name))) { + if (size > p->len) { + dt_resize_property(&p, size); + p->len = size; + } + + memcpy(p->prop, val, size); + } else { + dt_add_property(target->dn, name, val, size); + } +} + +void *pdbg_get_target_property(struct pdbg_target *target, const char *name, size_t *size) +{ + struct dt_property *p; + + p = dt_find_property(target->dn, name); + if (p) { + if (size) + *size = p->len; + return p->prop; + } else if (size) + *size = 0; + + return NULL; +} + +uint64_t pdbg_get_address(struct pdbg_target *target, uint64_t *size) +{ + return dt_get_address(target->dn, 0, size); +} + +/* Difference from below is that it doesn't search up the tree for the given + * property. As nothing uses this yet we don't export it for use, but we may in + * future */ +static int pdbg_get_target_u64_property(struct pdbg_target *target, const char *name, uint64_t *val) +{ + struct dt_property *p; + + p = dt_find_property(target->dn, name); + if (!p) + return -1; + + *val = dt_get_number(p->prop, 2); + return 0; +} + +int pdbg_get_u64_property(struct pdbg_target *target, const char *name, uint64_t *val) +{ + struct dt_node *dn; + + for (dn = target->dn; dn; dn = dn->parent) { + if (!pdbg_get_target_u64_property(dn->target, name, val)) + return 0; + } + + return -1; +} diff --git a/libpdbg/libpdbg.h b/libpdbg/libpdbg.h new file mode 100644 index 0000000..8c57193 --- /dev/null +++ b/libpdbg/libpdbg.h @@ -0,0 +1,89 @@ +#ifndef __LIBPDBG_H +#define __LIBPDBG_H + +struct pdbg_target; +struct pdbg_target_class; + +struct pdbg_taget *pdbg_root_target; + +/* loops/iterators */ +struct pdbg_target *__pdbg_next_target(const char *klass, struct pdbg_target *parent, struct pdbg_target *last); +struct pdbg_target *__pdbg_next_child_target(struct pdbg_target *parent, struct pdbg_target *last); +enum pdbg_target_status {PDBG_TARGET_ENABLED, PDBG_TARGET_DISABLED, PDBG_TARGET_HIDDEN}; + +#define pdbg_for_each_target(class, parent, target) \ + for (target = __pdbg_next_target(class, parent, NULL); \ + target; \ + target = __pdbg_next_target(class, parent, target)) + +#define pdbg_for_each_class_target(class, target) \ + for (target = __pdbg_next_target(class, NULL, NULL); \ + target; \ + target = __pdbg_next_target(class, NULL, target)) + +#define pdbg_for_each_child_target(parent, target) \ + for (target = __pdbg_next_child_target(parent, NULL); \ + target; \ + target = __pdbg_next_child_target(parent, target)) + +/* Set the given property. Will automatically add one if one doesn't exist */ +void pdbg_set_target_property(struct pdbg_target *target, const char *name, const void *val, size_t size); + +/* Get the given property and return the size */ +void *pdbg_get_target_property(struct pdbg_target *target, const char *name, size_t *size); +int pdbg_get_u64_property(struct pdbg_target *target, const char *name, uint64_t *val); +uint64_t pdbg_get_address(struct pdbg_target *target, uint64_t *size); + +/* Misc. */ +void pdbg_targets_init(void *fdt); +void pdbg_target_probe(void); +void pdbg_enable_target(struct pdbg_target *target); +void pdbg_disable_target(struct pdbg_target *target); +enum pdbg_target_status pdbg_target_status(struct pdbg_target *target); +uint32_t pdbg_target_index(struct pdbg_target *target); +uint32_t pdbg_parent_index(struct pdbg_target *target, char *klass); +char *pdbg_target_class_name(struct pdbg_target *target); +char *pdbg_target_name(struct pdbg_target *target); + +/* Procedures */ +int fsi_read(struct pdbg_target *target, uint32_t addr, uint32_t *val); +int fsi_write(struct pdbg_target *target, uint32_t addr, uint32_t val); + +int pib_read(struct pdbg_target *target, uint64_t addr, uint64_t *val); +int pib_write(struct pdbg_target *target, uint64_t addr, uint64_t val); + +int ram_putmsr(struct pdbg_target *target, uint64_t val); +int ram_putnia(struct pdbg_target *target, uint64_t val); +int ram_putspr(struct pdbg_target *target, int spr, uint64_t val); +int ram_putgpr(struct pdbg_target *target, int spr, uint64_t val); +int ram_getmsr(struct pdbg_target *target, uint64_t *val); +int ram_getnia(struct pdbg_target *target, uint64_t *val); +int ram_getspr(struct pdbg_target *target, int spr, uint64_t *val); +int ram_getgpr(struct pdbg_target *target, int gpr, uint64_t *val); +int ram_start_thread(struct pdbg_target *target); +int ram_step_thread(struct pdbg_target *target, int steps); +int ram_stop_thread(struct pdbg_target *target); +int ram_sreset_thread(struct pdbg_target *target); +uint64_t thread_status(struct pdbg_target *target); + +#define THREAD_STATUS_DISABLED PPC_BIT(0) +#define THREAD_STATUS_ACTIVE PPC_BIT(63) +#define THREAD_STATUS_STATE PPC_BITMASK(61, 62) +#define THREAD_STATUS_DOZE PPC_BIT(62) +#define THREAD_STATUS_NAP PPC_BIT(61) +#define THREAD_STATUS_SLEEP PPC_BITMASK(61, 62) +#define THREAD_STATUS_QUIESCE PPC_BIT(60) + +int htm_start(struct pdbg_target *target); +int htm_stop(struct pdbg_target *target); +int htm_status(struct pdbg_target *target); +int htm_reset(struct pdbg_target *target, uint64_t *base, uint64_t *size); +int htm_dump(struct pdbg_target *target, uint64_t size, const char *filename); + +int adu_getmem(struct pdbg_target *target, uint64_t addr, uint8_t *ouput, uint64_t size); +int adu_putmem(struct pdbg_target *target, uint64_t addr, uint8_t *input, uint64_t size); + +int opb_read(struct pdbg_target *target, uint32_t addr, uint32_t *data); +int opb_write(struct pdbg_target *target, uint32_t addr, uint32_t data); + +#endif diff --git a/libpdbg/operations.h b/libpdbg/operations.h index e4a9411..a0b7f01 100644 --- a/libpdbg/operations.h +++ b/libpdbg/operations.h @@ -28,8 +28,6 @@ } \ } while(0) -#define THREADS_PER_CORE 8 - #define FSI2PIB_BASE 0x1000 /* Alter display unit functions */ @@ -55,28 +53,6 @@ int adu_putmem(struct pdbg_target *target, uint64_t start_addr, uint8_t *input, #define MTSPR_OPCODE 0x7c0003a6UL #define LD_OPCODE 0xe8000000UL -int ram_getgpr(struct thread *thread, int gpr, uint64_t *value); -int ram_putgpr(struct thread *thread, int gpr, uint64_t value); -int ram_getnia(struct thread *thread, uint64_t *value); -int ram_putnia(struct thread *thread, uint64_t value); -int ram_getspr(struct thread *thread, int spr, uint64_t *value); -int ram_putspr(struct thread *thread, int spr, uint64_t value); -int ram_getmsr(struct thread *thread, uint64_t *value); -int ram_putmsr(struct thread *thread, uint64_t value); -int ram_getmem(struct thread *thread, uint64_t addr, uint64_t *value); -uint64_t thread_status(struct thread *thread); -int ram_stop_thread(struct pdbg_target *thread); -int ram_step_thread(struct pdbg_target *thread, int count); -int ram_start_thread(struct pdbg_target *thread); -int ram_sreset_thread(struct pdbg_target *thread); -void fsi_destroy(struct pdbg_target *target); - -int htm_stop(struct pdbg_target *target); -int htm_start(struct pdbg_target *target); -int htm_status(struct pdbg_target *target); -int htm_reset(struct pdbg_target *target, uint64_t *base, uint64_t *size); -int htm_dump(struct pdbg_target *target, uint64_t, const char *); - /* GDB server functionality */ int gdbserver_start(uint16_t port); diff --git a/libpdbg/p8chip.c b/libpdbg/p8chip.c index 51de7b9..8944a72 100644 --- a/libpdbg/p8chip.c +++ b/libpdbg/p8chip.c @@ -230,7 +230,7 @@ static int p8_ram_setup(struct thread *thread) return 1; } - if (!(thread_status(thread) & THREAD_STATUS_ACTIVE)) + if (!(thread->status & THREAD_STATUS_ACTIVE)) return 2; /* Activate RAM mode */ diff --git a/libpdbg/target.c b/libpdbg/target.c index e113e77..c34271b 100644 --- a/libpdbg/target.c +++ b/libpdbg/target.c @@ -262,7 +262,7 @@ struct hw_unit_info *find_compatible_target(const char *compat) return NULL; } -void targets_init(void *fdt) +void pdbg_targets_init(void *fdt) { struct dt_node *dn; const struct dt_property *p; @@ -340,7 +340,7 @@ static void _target_probe(struct dt_node *dn) /* We walk the tree root down disabling targets which might/should * exist but don't */ -void target_probe(void) +void pdbg_target_probe(void) { struct dt_node *dn; diff --git a/libpdbg/target.h b/libpdbg/target.h index 8540d0d..c59081e 100644 --- a/libpdbg/target.h +++ b/libpdbg/target.h @@ -21,6 +21,7 @@ #include <ccan/container_of/container_of.h> #include "compiler.h" #include "device.h" +#include "libpdbg.h" #define PR_DEBUG(x, args...) \ fprintf(stderr, x, ##args) @@ -134,14 +135,4 @@ struct thread { }; #define target_to_thread(x) container_of(x, struct thread, target) -void targets_init(void *fdt); -void target_probe(void); - -int pib_read(struct pdbg_target *pib_dt, uint64_t addr, uint64_t *data); -int pib_write(struct pdbg_target *pib_dt, uint64_t addr, uint64_t data); -int opb_read(struct pdbg_target *opb_dt, uint32_t addr, uint32_t *data); -int opb_write(struct pdbg_target *opb_dt, uint32_t addr, uint32_t data); -int fsi_read(struct pdbg_target *fsi_dt, uint32_t addr, uint32_t *data); -int fsi_write(struct pdbg_target *fsi_dt, uint32_t addr, uint32_t data); - #endif @@ -26,17 +26,18 @@ #include <limits.h> #include <inttypes.h> -#include <backend.h> -#include <operations.h> -#include <target.h> -#include <device.h> - #include <config.h> +#include <libpdbg.h> + #include "bitutils.h" #undef PR_DEBUG #define PR_DEBUG(...) +#define PR_ERROR(x, args...) \ + fprintf(stderr, "%s: " x, __FUNCTION__, ##args) + +#define THREADS_PER_CORE 8 #define HTM_DUMP_BASENAME "htm.dump" @@ -71,12 +72,6 @@ static int **processorsel[MAX_PROCESSORS]; static int *chipsel[MAX_PROCESSORS][MAX_CHIPS]; static int threadsel[MAX_PROCESSORS][MAX_CHIPS][MAX_THREADS]; -/* Convenience functions */ -#define for_each_thread(x) while(0) -#define for_each_chiplet(x) while(0) -#define for_each_processor(x) while(0) -#define for_each_cfam(x) while(0) - static void print_usage(char *pname) { printf("Usage: %s [options] command ...\n\n", pname); @@ -373,21 +368,13 @@ static int for_each_child_target(char *class, struct pdbg_target *parent, int rc = 0; struct pdbg_target *target; uint32_t index; - struct dt_node *dn; - - for_each_class_target(class, target) { - struct dt_property *p; + enum pdbg_target_status status; - dn = target->dn; - if (parent && dn->parent != parent->dn) - continue; - - /* Search up the tree for an index */ - for (index = dn->target->index; index == -1; dn = dn->parent); + pdbg_for_each_target(class, parent, target) { + index = pdbg_target_index(target); assert(index != -1); - - p = dt_find_property(dn, "status"); - if (p && (!strcmp(p->prop, "disabled") || !strcmp(p->prop, "hidden"))) + status = pdbg_target_status(target); + if (status == PDBG_TARGET_DISABLED || status == PDBG_TARGET_HIDDEN) continue; rc += cb(target, index, arg1, arg2); @@ -396,9 +383,25 @@ static int for_each_child_target(char *class, struct pdbg_target *parent, return rc; } +/* Call the given call back on each enabled target in the given class */ static int for_each_target(char *class, int (*cb)(struct pdbg_target *, uint32_t, uint64_t *, uint64_t *), uint64_t *arg1, uint64_t *arg2) { - return for_each_child_target(class, NULL, cb, arg1, arg2); + struct pdbg_target *target; + uint32_t index; + enum pdbg_target_status status; + int rc = 0; + + pdbg_for_each_class_target(class, target) { + index = pdbg_target_index(target); + assert(index != -1); + status = pdbg_target_status(target); + if (status == PDBG_TARGET_DISABLED || status == PDBG_TARGET_HIDDEN) + continue; + + rc += cb(target, index, arg1, arg2); + } + + return rc; } static int getcfam(struct pdbg_target *target, uint32_t index, uint64_t *addr, uint64_t *unused) @@ -441,11 +444,9 @@ static int putscom(struct pdbg_target *target, uint32_t index, uint64_t *addr, u return 1; } -static int print_thread_status(struct pdbg_target *thread_target, uint32_t index, uint64_t *status, uint64_t *unused1) +static int print_thread_status(struct pdbg_target *target, uint32_t index, uint64_t *status, uint64_t *unused1) { - struct thread *thread = target_to_thread(thread_target); - - *status = SETFIELD(0xf << (index * 4), *status, thread_status(thread) & 0xf); + *status = SETFIELD(0xf << (index * 4), *status, thread_status(target) & 0xf); return 1; } @@ -504,13 +505,13 @@ static int print_proc_thread_status(struct pdbg_target *pib_target, uint32_t ind #define REG_MSR -2 #define REG_NIA -1 #define REG_R31 31 -static void print_proc_reg(struct thread *thread, uint64_t reg, uint64_t value, int rc) +static void print_proc_reg(struct pdbg_target *target, uint64_t reg, uint64_t value, int rc) { int proc_index, chip_index, thread_index; - thread_index = thread->target.index; - chip_index = thread->target.dn->parent->target->index; - proc_index = thread->target.dn->parent->parent->target->index; + thread_index = pdbg_target_index(target); + chip_index = pdbg_parent_index(target, "chiplet"); + proc_index = pdbg_parent_index(target, "pib"); printf("p%d:c%d:t%d:", proc_index, chip_index, thread_index); if (reg == REG_MSR) @@ -530,41 +531,39 @@ static void print_proc_reg(struct thread *thread, uint64_t reg, uint64_t value, printf("0x%016" PRIx64 "\n", value); } -static int putprocreg(struct pdbg_target *thread_target, uint32_t index, uint64_t *reg, uint64_t *value) +static int putprocreg(struct pdbg_target *target, uint32_t index, uint64_t *reg, uint64_t *value) { - struct thread *thread = target_to_thread(thread_target); int rc; if (*reg == REG_MSR) - rc = ram_putmsr(thread, *value); + rc = ram_putmsr(target, *value); else if (*reg == REG_NIA) - rc = ram_putnia(thread, *value); + rc = ram_putnia(target, *value); else if (*reg > REG_R31) - rc = ram_putspr(thread, *reg - REG_R31, *value); + rc = ram_putspr(target, *reg - REG_R31, *value); else if (*reg >= 0 && *reg <= 31) - rc = ram_putgpr(thread, *reg, *value); + rc = ram_putgpr(target, *reg, *value); - print_proc_reg(thread, *reg, *value, rc); + print_proc_reg(target, *reg, *value, rc); return 0; } -static int getprocreg(struct pdbg_target *thread_target, uint32_t index, uint64_t *reg, uint64_t *unused) +static int getprocreg(struct pdbg_target *target, uint32_t index, uint64_t *reg, uint64_t *unused) { - struct thread *thread = target_to_thread(thread_target); int rc; uint64_t value; if (*reg == REG_MSR) - rc = ram_getmsr(thread, &value); + rc = ram_getmsr(target, &value); else if (*reg == REG_NIA) - rc = ram_getnia(thread, &value); + rc = ram_getnia(target, &value); else if (*reg > REG_R31) - rc = ram_getspr(thread, *reg - REG_R31, &value); + rc = ram_getspr(target, *reg - REG_R31, &value); else if (*reg >= 0 && *reg <= 31) - rc = ram_getgpr(thread, *reg, &value); + rc = ram_getgpr(target, *reg, &value); - print_proc_reg(thread, *reg, value, rc); + print_proc_reg(target, *reg, value, rc); return !rc; } @@ -576,7 +575,7 @@ static int putmem(uint64_t addr) int read_size, rc = 0; struct pdbg_target *adu_target; - for_each_class_target("adu", adu_target) + pdbg_for_each_class_target("adu", adu_target) break; buf = malloc(PUTMEM_BUF_SIZE); @@ -615,39 +614,6 @@ static int sreset_thread(struct pdbg_target *thread_target, uint32_t index, uint return ram_sreset_thread(thread_target) ? 0 : 1; } -static void enable_dn(struct dt_node *dn) -{ - struct dt_property *p; - - PR_DEBUG("Enabling %s\n", dn->name); - p = dt_find_property(dn, "status"); - - if (!p) - /* Default assumption enabled */ - return; - - /* We only override a status of "hidden" */ - if (strcmp(p->prop, "hidden")) - return; - - dt_del_property(dn, p); -} - -static void disable_dn(struct dt_node *dn) -{ - struct dt_property *p; - - PR_DEBUG("Disabling %s\n", dn->name); - p = dt_find_property(dn, "status"); - if (p) - /* We don't override hard-coded device tree - * status. This is needed to avoid disabling that - * backend. */ - return; - - dt_add_property_string(dn, "status", "disabled"); -} - static char *get_htm_dump_filename(void) { char *filename; @@ -672,13 +638,15 @@ static int run_htm_start(void) { struct pdbg_target *target; int rc = 0; + uint64_t chip_id; - for_each_class_target("htm", target) { + pdbg_for_each_class_target("htm", target) { + assert(!pdbg_get_u64_property(target, "chip-id", &chip_id)); printf("Starting HTM@%d#%d\n", - dt_get_chip_id(target->dn), target->index); + (int) chip_id, pdbg_target_index(target)); if (htm_start(target) != 1) printf("Couldn't start HTM@%d#%d\n", - dt_get_chip_id(target->dn), target->index); + (int) chip_id, pdbg_target_index(target)); rc++; } @@ -689,13 +657,15 @@ static int run_htm_stop(void) { struct pdbg_target *target; int rc = 0; + uint64_t chip_id; - for_each_class_target("htm", target) { + pdbg_for_each_class_target("htm", target) { + assert(!pdbg_get_u64_property(target, "chip-id", &chip_id)); printf("Stopping HTM@%d#%d\n", - dt_get_chip_id(target->dn), target->index); + (int) chip_id, pdbg_target_index(target)); if (htm_stop(target) != 1) printf("Couldn't stop HTM@%d#%d\n", - dt_get_chip_id(target->dn), target->index); + (int) chip_id, pdbg_target_index(target)); rc++; } @@ -706,13 +676,15 @@ static int run_htm_status(void) { struct pdbg_target *target; int rc = 0; + uint64_t chip_id; - for_each_class_target("htm", target) { + pdbg_for_each_class_target("htm", target) { + assert(!pdbg_get_u64_property(target, "chip-id", &chip_id)); printf("HTM@%d#%d\n", - dt_get_chip_id(target->dn), target->index); + (int) chip_id, pdbg_target_index(target)); if (htm_status(target) != 1) printf("Couldn't get HTM@%d#%d status\n", - dt_get_chip_id(target->dn), target->index); + (int) chip_id, pdbg_target_index(target)); rc++; printf("\n\n"); } @@ -725,13 +697,15 @@ static int run_htm_reset(void) uint64_t old_base = 0, base, size; struct pdbg_target *target; int rc = 0; + uint64_t chip_id; - for_each_class_target("htm", target) { + pdbg_for_each_class_target("htm", target) { + assert(!pdbg_get_u64_property(target, "chip-id", &chip_id)); printf("Resetting HTM@%d#%d\n", - dt_get_chip_id(target->dn), target->index); + (int) chip_id, pdbg_target_index(target)); if (htm_reset(target, &base, &size) != 1) printf("Couldn't reset HTM@%d#%d\n", - dt_get_chip_id(target->dn), target->index); + (int) chip_id, pdbg_target_index(target)); if (old_base != base) { printf("The kernel has initialised HTM memory at:\n"); printf("base: 0x%016" PRIx64 " for 0x%016" PRIx64 " size\n", @@ -751,6 +725,7 @@ static int run_htm_dump(void) struct pdbg_target *target; char *filename; int rc = 0; + uint64_t chip_id; filename = get_htm_dump_filename(); if (!filename) @@ -758,12 +733,13 @@ static int run_htm_dump(void) /* size = 0 will dump everything */ printf("Dumping HTM trace to file [chip].[#]%s\n", filename); - for_each_class_target("htm", target) { + pdbg_for_each_class_target("htm", target) { + assert(!pdbg_get_u64_property(target, "chip-id", &chip_id)); printf("Dumping HTM@%d#%d\n", - dt_get_chip_id(target->dn), target->index); + (int) chip_id, pdbg_target_index(target)); if (htm_dump(target, 0, filename) == 1) printf("Couldn't dump HTM@%d#%d\n", - dt_get_chip_id(target->dn), target->index); + (int) chip_id, pdbg_target_index(target)); rc++; } free(filename); @@ -776,18 +752,20 @@ static int run_htm_trace(void) uint64_t old_base = 0, base, size; struct pdbg_target *target; int rc = 0; + uint64_t chip_id; - for_each_class_target("htm", target) { + pdbg_for_each_class_target("htm", target) { /* * Don't mind if stop fails, it will fail if it wasn't * running, if anything bad is happening reset will fail */ + assert(!pdbg_get_u64_property(target, "chip-id", &chip_id)); htm_stop(target); printf("Resetting HTM@%d#%d\n", - dt_get_chip_id(target->dn), target->index); + (int) chip_id, pdbg_target_index(target)); if (htm_reset(target, &base, &size) != 1) printf("Couldn't reset HTM@%d#%d\n", - dt_get_chip_id(target->dn), target->index); + (int) chip_id, pdbg_target_index(target)); if (old_base != base) { printf("The kernel has initialised HTM memory at:\n"); printf("base: 0x%016" PRIx64 " for 0x%016" PRIx64 " size\n", @@ -798,12 +776,13 @@ static int run_htm_trace(void) old_base = base; } - for_each_class_target("htm", target) { + pdbg_for_each_class_target("htm", target) { + assert(!pdbg_get_u64_property(target, "chip-id", &chip_id)); printf("Starting HTM@%d#%d\n", - dt_get_chip_id(target->dn), target->index); + (int) chip_id, pdbg_target_index(target)); if (htm_start(target) != 1) printf("Couldn't start HTM@%d#%d\n", - dt_get_chip_id(target->dn), target->index); + (int) chip_id, pdbg_target_index(target)); rc++; } @@ -815,8 +794,9 @@ static int run_htm_analyse(void) struct pdbg_target *target; char *filename; int rc = 0; + uint64_t chip_id; - for_each_class_target("htm", target) + pdbg_for_each_class_target("htm", target) htm_stop(target); filename = get_htm_dump_filename(); @@ -824,12 +804,13 @@ static int run_htm_analyse(void) return 0; printf("Dumping HTM trace to file [chip].[#]%s\n", filename); - for_each_class_target("htm", target) { + pdbg_for_each_class_target("htm", target) { + assert(!pdbg_get_u64_property(target, "chip-id", &chip_id)); printf("Dumping HTM@%d#%d\n", - dt_get_chip_id(target->dn), target->index); + (int) chip_id, pdbg_target_index(target)); if (htm_dump(target, 0, filename) != 1) printf("Couldn't dump HTM@%d#%d\n", - dt_get_chip_id(target->dn), target->index); + (int) chip_id, pdbg_target_index(target)); rc++; } free(filename); @@ -862,7 +843,7 @@ static int target_select(void) switch (backend) { case I2C: - targets_init(&_binary_p8_i2c_dtb_o_start); + pdbg_targets_init(&_binary_p8_i2c_dtb_o_start); break; case FSI: @@ -871,13 +852,13 @@ static int target_select(void) return -1; } if (!strcmp(device_node, "p8")) - targets_init(&_binary_p8_fsi_dtb_o_start); + pdbg_targets_init(&_binary_p8_fsi_dtb_o_start); else if (!strcmp(device_node, "p9w") || !strcmp(device_node, "witherspoon")) - targets_init(&_binary_p9w_fsi_dtb_o_start); + pdbg_targets_init(&_binary_p9w_fsi_dtb_o_start); else if (!strcmp(device_node, "p9r") || !strcmp(device_node, "romulus")) - targets_init(&_binary_p9r_fsi_dtb_o_start); + pdbg_targets_init(&_binary_p9r_fsi_dtb_o_start); else if (!strcmp(device_node, "p9z") || !strcmp(device_node, "zaius")) - targets_init(&_binary_p9z_fsi_dtb_o_start); + pdbg_targets_init(&_binary_p9z_fsi_dtb_o_start); else { PR_ERROR("Invalid device type specified\n"); return -1; @@ -885,11 +866,11 @@ static int target_select(void) break; case KERNEL: - targets_init(&_binary_p9_kernel_dtb_o_start); + pdbg_targets_init(&_binary_p9_kernel_dtb_o_start); break; case FAKE: - targets_init(&_binary_fake_dtb_o_start); + pdbg_targets_init(&_binary_fake_dtb_o_start); break; case HOST: @@ -898,9 +879,9 @@ static int target_select(void) return -1; } if (!strcmp(device_node, "p8")) - targets_init(&_binary_p8_host_dtb_o_start); + pdbg_targets_init(&_binary_p8_host_dtb_o_start); else if (!strcmp(device_node, "p9")) - targets_init(&_binary_p9_host_dtb_o_start); + pdbg_targets_init(&_binary_p9_host_dtb_o_start); else { PR_ERROR("Unsupported device type for host backend\n"); return -1; @@ -915,98 +896,74 @@ static int target_select(void) /* At this point we should have a device-tree loaded. We want * to walk the tree and disabled nodes we don't care about * prior to probing. */ - for_each_class_target("pib", pib) { - struct dt_property *p; - int proc_index = pib->index; - - if (backend == I2C && device_node) { - if ((p = dt_find_property(pib->dn, "bus"))) { - if (strlen(device_node) > p->len) - dt_resize_property(&p, strlen(device_node) + 1); - strcpy(p->prop, device_node); - } else { - dt_add_property(pib->dn, "bus", device_node, strlen(device_node) + 1); - } - } + pdbg_for_each_class_target("pib", pib) { + int proc_index = pdbg_target_index(pib); + + if (backend == I2C && device_node) + pdbg_set_target_property(pib, "bus", device_node, strlen(device_node) + 1); if (processorsel[proc_index]) { - enable_dn(pib->dn); - if (!find_target_class("chiplet")) - continue; - for_each_class_target("chiplet", chip) { - if (chip->dn->parent != pib->dn) - continue; - int chip_index = chip->index; + pdbg_enable_target(pib); + pdbg_for_each_target("chiplet", pib, chip) { + int chip_index = pdbg_target_index(chip); if (chipsel[proc_index][chip_index]) { - enable_dn(chip->dn); - if (!find_target_class("thread")) - continue; - for_each_class_target("thread", thread) { - if (thread->dn->parent != chip->dn) - continue; - - int thread_index = thread->index; + pdbg_enable_target(chip); + pdbg_for_each_target("thread", chip, thread) { + int thread_index = pdbg_target_index(thread); if (threadsel[proc_index][chip_index][thread_index]) - enable_dn(thread->dn); + pdbg_enable_target(thread); else - disable_dn(thread->dn); + pdbg_disable_target(thread); } } else - disable_dn(chip->dn); + pdbg_disable_target(chip); } } else - disable_dn(pib->dn); + pdbg_disable_target(pib); } - for_each_class_target("fsi", fsi) { - int index = fsi->index; + pdbg_for_each_class_target("fsi", fsi) { + int index = pdbg_target_index(fsi); if (processorsel[index]) - enable_dn(fsi->dn); + pdbg_enable_target(fsi); else - disable_dn(fsi->dn); + pdbg_disable_target(fsi); } return 0; } -void print_target(struct dt_node *dn, int level) +void print_target(struct pdbg_target *target, int level) { int i; - struct dt_node *next; - struct dt_property *p; - char *status = ""; - - p = dt_find_property(dn, "status"); - if (p) - status = p->prop; + struct pdbg_target *next; + enum pdbg_target_status status; - if (!strcmp(status, "disabled")) + status = pdbg_target_status(target); + if (status == PDBG_TARGET_DISABLED) return; - if (strcmp(status, "hidden")) { - struct pdbg_target *target; - + if (status == PDBG_TARGET_ENABLED) { for (i = 0; i < level; i++) printf(" "); - target = dn->target; if (target) { char c = 0; - if (!strcmp(target->class, "pib")) + if (!strcmp(pdbg_target_class_name(target), "pib")) c = 'p'; - else if (!strcmp(target->class, "chiplet")) + else if (!strcmp(pdbg_target_class_name(target), "chiplet")) c = 'c'; - else if (!strcmp(target->class, "thread")) + else if (!strcmp(pdbg_target_class_name(target), "thread")) c = 't'; if (c) - printf("%c%d: %s\n", c, target->index, target->name); + printf("%c%d: %s\n", c, pdbg_target_index(target), pdbg_target_name(target)); else - printf("%s\n", target->name); + printf("%s\n", pdbg_target_name(target)); } } - list_for_each(&dn->children, next, list) + pdbg_for_each_child_target(target, next) print_target(next, level + 1); } @@ -1023,7 +980,7 @@ int main(int argc, char *argv[]) if (target_select()) return 1; - target_probe(); + pdbg_target_probe(); switch(cmd) { case GETCFAM: @@ -1041,7 +998,7 @@ int main(int argc, char *argv[]) case GETMEM: buf = malloc(cmd_args[1]); assert(buf); - for_each_class_target("adu", target) { + pdbg_for_each_class_target("adu", target) { if (!adu_getmem(target, cmd_args[0], buf, cmd_args[1])) { if (write(STDOUT_FILENO, buf, cmd_args[1]) < 0) PR_ERROR("Unable to write stdout.\n"); @@ -1109,7 +1066,9 @@ int main(int argc, char *argv[]) break; case PROBE: rc = 1; - print_target(dt_root, 0); + pdbg_for_each_class_target("pib", target) + print_target(target, 0); + printf("\nNote that only selected targets will be shown above. If none are shown\n" "try adding '-a' to select all targets\n"); break; @@ -1147,8 +1106,8 @@ int main(int argc, char *argv[]) } else rc = 0; - if (backend == FSI) - fsi_destroy(NULL); + //if (backend == FSI) + //fsi_destroy(NULL); return rc; } |