summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlistair Popple <alistair@popple.id.au>2017-12-04 13:15:16 +1100
committerAlistair Popple <alistair@popple.id.au>2017-12-08 11:22:09 +1100
commit5f815d7a742eaebe01d44251db833b8051f393aa (patch)
tree0c23107ede525f761ebbcb2b17a8bb99188f12a2
parent07aa13ea742ee447d7b5d5c295116510f2918119 (diff)
downloadpdbg-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.am1
-rw-r--r--libpdbg/chip.c29
-rw-r--r--libpdbg/libpdbg.c196
-rw-r--r--libpdbg/libpdbg.h89
-rw-r--r--libpdbg/operations.h24
-rw-r--r--libpdbg/p8chip.c2
-rw-r--r--libpdbg/target.c4
-rw-r--r--libpdbg/target.h11
-rw-r--r--src/main.c309
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
diff --git a/src/main.c b/src/main.c
index 3b722e3..c823819 100644
--- a/src/main.c
+++ b/src/main.c
@@ -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;
}
OpenPOWER on IntegriCloud