[Pdbg] [PATCH 7/9] libpdbg: Rearrange thread procedures for register access
Amitay Isaacs
amitay at ozlabs.org
Mon Jun 22 10:44:59 AEST 2020
This moves libpdbg thread api to thread.c. Also, the implementation
based ramming instructions moves to the specific thread drivers.
Signed-off-by: Amitay Isaacs <amitay at ozlabs.org>
---
Makefile.am | 3 +-
libpdbg/chip.c | 318 +++++++--------------------------------------
libpdbg/chip.h | 19 +++
libpdbg/hwunit.h | 2 -
libpdbg/p8chip.c | 17 ++-
libpdbg/p9chip.c | 21 ++-
libpdbg/thread.c | 328 +++++++++++++++++++++++++++++++++++++++++++++++
7 files changed, 429 insertions(+), 279 deletions(-)
create mode 100644 libpdbg/thread.c
diff --git a/Makefile.am b/Makefile.am
index f51afb3..4247913 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -207,7 +207,8 @@ libpdbg_la_SOURCES = \
libpdbg/sbefifo.c \
libpdbg/sprs.h \
libpdbg/target.c \
- libpdbg/target.h
+ libpdbg/target.h \
+ libpdbg/thread.c
libpdbg_la_CFLAGS = -Wall -Werror
libpdbg_la_LIBADD = libcronus.la libsbefifo.la
diff --git a/libpdbg/chip.c b/libpdbg/chip.c
index 58eedeb..a5afe5c 100644
--- a/libpdbg/chip.c
+++ b/libpdbg/chip.c
@@ -26,6 +26,7 @@
#include "bitutils.h"
#include "debug.h"
#include "sprs.h"
+#include "chip.h"
uint64_t mfspr(uint64_t reg, uint64_t spr)
{
@@ -107,166 +108,6 @@ static uint64_t ld(uint64_t rt, uint64_t ds, uint64_t ra)
return LD_OPCODE | (rt << 21) | (ra << 16) | (ds << 2);
}
-struct thread_state thread_status(struct pdbg_target *target)
-{
- struct thread *thread;
-
- assert(pdbg_target_is_class(target, "thread"));
- thread = target_to_thread(target);
- return thread->status;
-}
-
-/*
- * Single step the thread count instructions.
- */
-int thread_step(struct pdbg_target *target, int count)
-{
- struct thread *thread;
-
- assert(pdbg_target_is_class(target, "thread"));
- thread = target_to_thread(target);
- return thread->step(thread, count);
-}
-
-int thread_start(struct pdbg_target *target)
-{
- struct thread *thread;
-
- assert(pdbg_target_is_class(target, "thread"));
- thread = target_to_thread(target);
- return thread->start(thread);
-}
-
-int thread_stop(struct pdbg_target *target)
-{
- struct thread *thread;
-
- assert(pdbg_target_is_class(target, "thread"));
- thread = target_to_thread(target);
- return thread->stop(thread);
-}
-
-int thread_sreset(struct pdbg_target *target)
-{
- struct thread *thread;
-
- assert(pdbg_target_is_class(target, "thread"));
- thread = target_to_thread(target);
- return thread->sreset(thread);
-}
-
-int thread_step_all(void)
-{
- struct pdbg_target *target, *thread;
- int rc = 0, count = 0;
-
- pdbg_for_each_class_target("pib", target) {
- struct pib *pib = target_to_pib(target);
-
- if (!pib->thread_step_all)
- break;
-
- rc |= pib->thread_step_all(pib, 1);
- count++;
- }
-
- if (count > 0)
- return rc;
-
- pdbg_for_each_class_target("thread", thread) {
- if (pdbg_target_status(thread) != PDBG_TARGET_ENABLED)
- continue;
-
- rc |= thread_step(thread, 1);
- }
-
- return rc;
-}
-
-int thread_start_all(void)
-{
- struct pdbg_target *target, *thread;
- int rc = 0, count = 0;
-
- pdbg_for_each_class_target("pib", target) {
- struct pib *pib = target_to_pib(target);
-
- if (!pib->thread_start_all)
- break;
-
- rc |= pib->thread_start_all(pib);
- count++;
- }
-
- if (count > 0)
- return rc;
-
- pdbg_for_each_class_target("thread", thread) {
- if (pdbg_target_status(thread) != PDBG_TARGET_ENABLED)
- continue;
-
- rc |= thread_start(thread);
- }
-
- return rc;
-}
-
-int thread_stop_all(void)
-{
- struct pdbg_target *target, *thread;
- int rc = 0, count = 0;
-
- pdbg_for_each_class_target("pib", target) {
- struct pib *pib = target_to_pib(target);
-
- if (!pib->thread_stop_all)
- break;
-
- rc |= pib->thread_stop_all(pib);
- count++;
- }
-
- if (count > 0)
- return rc;
-
- pdbg_for_each_class_target("thread", thread) {
- if (pdbg_target_status(thread) != PDBG_TARGET_ENABLED)
- continue;
-
- rc |= thread_stop(thread);
- }
-
- return rc;
-}
-
-int thread_sreset_all(void)
-{
- struct pdbg_target *target, *thread;
- int rc = 0, count = 0;
-
- pdbg_for_each_class_target("pib", target) {
- struct pib *pib = target_to_pib(target);
-
- if (!pib->thread_sreset_all)
- break;
-
- rc |= pib->thread_sreset_all(pib);
- count++;
- }
-
- if (count > 0)
- return rc;
-
- pdbg_for_each_class_target("thread", thread) {
- if (pdbg_target_status(thread) != PDBG_TARGET_ENABLED)
- continue;
-
- rc |= thread_sreset(thread);
- }
-
- return rc;
-}
-
/*
* RAMs the opcodes in *opcodes and store the results of each opcode
* into *results. *results must point to an array the same size as
@@ -336,40 +177,30 @@ int ram_instructions(struct thread *thread, uint64_t *opcodes,
/*
* Get gpr value. Chip must be stopped.
*/
-int thread_getgpr(struct pdbg_target *target, int gpr, uint64_t *value)
+int ram_getgpr(struct thread *thread, int gpr, uint64_t *value)
{
- struct thread *thread;
uint64_t opcodes[] = {mtspr(277, gpr)};
uint64_t results[] = {0};
- assert(pdbg_target_is_class(target, "thread"));
- thread = target_to_thread(target);
CHECK_ERR(ram_instructions(thread, opcodes, results, ARRAY_SIZE(opcodes), 0));
*value = results[0];
return 0;
}
-int thread_putgpr(struct pdbg_target *target, int gpr, uint64_t value)
+int ram_putgpr(struct thread *thread, int gpr, uint64_t value)
{
- struct thread *thread;
uint64_t opcodes[] = {mfspr(gpr, 277)};
uint64_t results[] = {value};
- assert(pdbg_target_is_class(target, "thread"));
- thread = target_to_thread(target);
CHECK_ERR(ram_instructions(thread, opcodes, results, ARRAY_SIZE(opcodes), 0));
-
return 0;
}
-int thread_getnia(struct pdbg_target *target, uint64_t *value)
+int ram_getnia(struct thread *thread, uint64_t *value)
{
- struct thread *thread;
uint64_t opcodes[] = {mfnia(0), mtspr(277, 0)};
uint64_t results[] = {0, 0};
- assert(pdbg_target_is_class(target, "thread"));
- thread = target_to_thread(target);
CHECK_ERR(ram_instructions(thread, opcodes, results, ARRAY_SIZE(opcodes), 0));
*value = results[1];
return 0;
@@ -382,9 +213,8 @@ int thread_getnia(struct pdbg_target *target, uint64_t *value)
* This is a hack and should be made much cleaner once we have target
* specific putspr commands.
*/
-int thread_putnia(struct pdbg_target *target, uint64_t value)
+int ram_putnia(struct thread *thread, uint64_t value)
{
- struct thread *thread;
uint64_t opcodes[] = { mfspr(1, 8), /* mflr r1 */
mfspr(0, 277), /* value -> r0 */
mtspr(8, 0), /* mtlr r0 */
@@ -392,53 +222,41 @@ int thread_putnia(struct pdbg_target *target, uint64_t value)
mtspr(8, 1), }; /* mtlr r1 */
uint64_t results[] = {0, value, 0, 0, 0};
- assert(pdbg_target_is_class(target, "thread"));
- thread = target_to_thread(target);
CHECK_ERR(ram_instructions(thread, opcodes, results, ARRAY_SIZE(opcodes), 0));
return 0;
}
-int thread_getspr(struct pdbg_target *target, int spr, uint64_t *value)
+int ram_getspr(struct thread *thread, int spr, uint64_t *value)
{
- struct thread *thread;
uint64_t opcodes[] = {mfspr(0, spr), mtspr(277, 0)};
uint64_t results[] = {0, 0};
- assert(pdbg_target_is_class(target, "thread"));
- thread = target_to_thread(target);
CHECK_ERR(ram_instructions(thread, opcodes, results, ARRAY_SIZE(opcodes), 0));
*value = results[1];
return 0;
}
-int thread_putspr(struct pdbg_target *target, int spr, uint64_t value)
+int ram_putspr(struct thread *thread, int spr, uint64_t value)
{
- struct thread *thread;
uint64_t opcodes[] = {mfspr(0, 277), mtspr(spr, 0)};
uint64_t results[] = {value, 0};
- assert(pdbg_target_is_class(target, "thread"));
- thread = target_to_thread(target);
CHECK_ERR(ram_instructions(thread, opcodes, results, ARRAY_SIZE(opcodes), 0));
return 0;
}
-int thread_getmsr(struct pdbg_target *target, uint64_t *value)
+int ram_getmsr(struct thread *thread, uint64_t *value)
{
- struct thread *thread;
uint64_t opcodes[] = {mfmsr(0), mtspr(277, 0)};
uint64_t results[] = {0, 0};
- assert(pdbg_target_is_class(target, "thread"));
- thread = target_to_thread(target);
CHECK_ERR(ram_instructions(thread, opcodes, results, ARRAY_SIZE(opcodes), 0));
*value = results[1];
return 0;
}
-int thread_getcr(struct pdbg_target *target, uint32_t *value)
+int ram_getcr(struct thread *thread, uint32_t *value)
{
- struct thread *thread;
uint64_t opcodes[] = {mfocrf(0, 0), mtspr(277, 0), mfocrf(0, 1), mtspr(277, 0),
mfocrf(0, 2), mtspr(277, 0), mfocrf(0, 3), mtspr(277, 0),
mfocrf(0, 4), mtspr(277, 0), mfocrf(0, 5), mtspr(277, 0),
@@ -447,8 +265,6 @@ int thread_getcr(struct pdbg_target *target, uint32_t *value)
uint32_t cr_field, cr = 0;
int i;
- assert(pdbg_target_is_class(target, "thread"));
- thread = target_to_thread(target);
CHECK_ERR(ram_instructions(thread, opcodes, results, ARRAY_SIZE(opcodes), 0));
for (i = 1; i < 16; i += 2) {
cr_field = results[i];
@@ -460,70 +276,36 @@ int thread_getcr(struct pdbg_target *target, uint32_t *value)
return 0;
}
-int thread_putcr(struct pdbg_target *target, uint32_t value)
+int ram_putcr(struct thread *thread, uint32_t value)
{
- struct thread *thread;
uint64_t opcodes[] = {mfspr(0, 277), mtocrf(0, 0), mtocrf(1, 0),
mtocrf(2, 0), mtocrf(3, 0), mtocrf(4, 0),
mtocrf(5, 0), mtocrf(6, 0), mtocrf(7, 0)};
uint64_t results[] = {value};
- assert(pdbg_target_is_class(target, "thread"));
- thread = target_to_thread(target);
CHECK_ERR(ram_instructions(thread, opcodes, results, ARRAY_SIZE(opcodes), 0));
-
return 0;
}
-int thread_putmsr(struct pdbg_target *target, uint64_t value)
+int ram_putmsr(struct thread *thread, uint64_t value)
{
- struct thread *thread;
uint64_t opcodes[] = {mfspr(0, 277), mtmsr(0)};
uint64_t results[] = {value, 0};
- assert(pdbg_target_is_class(target, "thread"));
- thread = target_to_thread(target);
CHECK_ERR(ram_instructions(thread, opcodes, results, ARRAY_SIZE(opcodes), 0));
return 0;
}
-int thread_getmem(struct pdbg_target *target, uint64_t addr, uint64_t *value)
+int ram_getmem(struct thread *thread, uint64_t addr, uint64_t *value)
{
- struct thread *thread;
uint64_t opcodes[] = {mfspr(0, 277), mfspr(1, 277), ld(0, 0, 1), mtspr(277, 0)};
uint64_t results[] = {0xdeaddeaddeaddead, addr, 0, 0};
- assert(pdbg_target_is_class(target, "thread"));
- thread = target_to_thread(target);
CHECK_ERR(ram_instructions(thread, opcodes, results, ARRAY_SIZE(opcodes), 0));
*value = results[3];
return 0;
}
-int thread_getxer(struct pdbg_target *target, uint64_t *value)
-{
- struct thread *thread;
-
- assert(pdbg_target_is_class(target, "thread"));
- thread = target_to_thread(target);
-
- CHECK_ERR(thread->ram_getxer(thread, value));
-
- return 0;
-}
-
-int thread_putxer(struct pdbg_target *target, uint64_t value)
-{
- struct thread *thread;
-
- assert(pdbg_target_is_class(target, "thread"));
- thread = target_to_thread(target);
-
- CHECK_ERR(thread->ram_putxer(thread, value));
-
- return 0;
-}
-
/*
* Read the given ring from the given chiplet. Result must be large enough to hold ring_len bits.
*/
@@ -536,9 +318,8 @@ int getring(struct pdbg_target *target, uint64_t ring_addr, uint64_t ring_len, u
return chiplet->getring(chiplet, ring_addr, ring_len, result);
}
-int thread_getregs(struct pdbg_target *target, struct thread_regs *regs)
+int ram_getregs(struct thread *thread, struct thread_regs *regs)
{
- struct thread *thread;
struct thread_regs _regs;
uint64_t value = 0;
int i;
@@ -546,9 +327,6 @@ int thread_getregs(struct pdbg_target *target, struct thread_regs *regs)
if (!regs)
regs = &_regs;
- assert(pdbg_target_is_class(target, "thread"));
- thread = target_to_thread(target);
-
CHECK_ERR(thread->ram_setup(thread));
/*
@@ -557,117 +335,117 @@ int thread_getregs(struct pdbg_target *target, struct thread_regs *regs)
* can help to diagnose checkstop issues with ramming to print as
* we go. Once it's more robust and tested, maybe.
*/
- thread_getnia(target, ®s->nia);
+ ram_getnia(thread, ®s->nia);
printf("NIA : 0x%016" PRIx64 "\n", regs->nia);
- thread_getspr(target, SPR_CFAR, ®s->cfar);
+ ram_getspr(thread, SPR_CFAR, ®s->cfar);
printf("CFAR : 0x%016" PRIx64 "\n", regs->cfar);
- thread_getmsr(target, ®s->msr);
+ ram_getmsr(thread, ®s->msr);
printf("MSR : 0x%016" PRIx64 "\n", regs->msr);
- thread_getspr(target, SPR_LR, ®s->lr);
+ ram_getspr(thread, SPR_LR, ®s->lr);
printf("LR : 0x%016" PRIx64 "\n", regs->lr);
- thread_getspr(target, SPR_CTR, ®s->ctr);
+ ram_getspr(thread, SPR_CTR, ®s->ctr);
printf("CTR : 0x%016" PRIx64 "\n", regs->ctr);
- thread_getspr(target, 815, ®s->tar);
+ ram_getspr(thread, 815, ®s->tar);
printf("TAR : 0x%016" PRIx64 "\n", regs->tar);
- thread_getcr(target, ®s->cr);
+ ram_getcr(thread, ®s->cr);
printf("CR : 0x%08" PRIx32 "\n", regs->cr);
- thread_getxer(target, ®s->xer);
+ thread->getxer(thread, ®s->xer);
printf("XER : 0x%08" PRIx64 "\n", regs->xer);
printf("GPRS :\n");
for (i = 0; i < 32; i++) {
- thread_getgpr(target, i, ®s->gprs[i]);
+ ram_getgpr(thread, i, ®s->gprs[i]);
printf(" 0x%016" PRIx64 "", regs->gprs[i]);
if (i % 4 == 3)
printf("\n");
}
- thread_getspr(target, SPR_LPCR, ®s->lpcr);
+ ram_getspr(thread, SPR_LPCR, ®s->lpcr);
printf("LPCR : 0x%016" PRIx64 "\n", regs->lpcr);
- thread_getspr(target, SPR_PTCR, ®s->ptcr);
+ ram_getspr(thread, SPR_PTCR, ®s->ptcr);
printf("PTCR : 0x%016" PRIx64 "\n", regs->ptcr);
- thread_getspr(target, SPR_LPIDR, ®s->lpidr);
+ ram_getspr(thread, SPR_LPIDR, ®s->lpidr);
printf("LPIDR : 0x%016" PRIx64 "\n", regs->lpidr);
- thread_getspr(target, SPR_PIDR, ®s->pidr);
+ ram_getspr(thread, SPR_PIDR, ®s->pidr);
printf("PIDR : 0x%016" PRIx64 "\n", regs->pidr);
- thread_getspr(target, SPR_HFSCR, ®s->hfscr);
+ ram_getspr(thread, SPR_HFSCR, ®s->hfscr);
printf("HFSCR : 0x%016" PRIx64 "\n", regs->hfscr);
- thread_getspr(target, SPR_HDSISR, &value);
+ ram_getspr(thread, SPR_HDSISR, &value);
regs->hdsisr = value;
printf("HDSISR: 0x%08" PRIx32 "\n", regs->hdsisr);
- thread_getspr(target, SPR_HDAR, ®s->hdar);
+ ram_getspr(thread, SPR_HDAR, ®s->hdar);
printf("HDAR : 0x%016" PRIx64 "\n", regs->hdar);
- thread_getspr(target, SPR_HEIR, &value);
+ ram_getspr(thread, SPR_HEIR, &value);
regs->heir = value;
printf("HEIR : 0x%016" PRIx32 "\n", regs->heir);
- thread_getspr(target, SPR_HID, ®s->hid);
+ ram_getspr(thread, SPR_HID, ®s->hid);
printf("HID0 : 0x%016" PRIx64 "\n", regs->hid);
- thread_getspr(target, SPR_HSRR0, ®s->hsrr0);
+ ram_getspr(thread, SPR_HSRR0, ®s->hsrr0);
printf("HSRR0 : 0x%016" PRIx64 "\n", regs->hsrr0);
- thread_getspr(target, SPR_HSRR1, ®s->hsrr1);
+ ram_getspr(thread, SPR_HSRR1, ®s->hsrr1);
printf("HSRR1 : 0x%016" PRIx64 "\n", regs->hsrr1);
- thread_getspr(target, SPR_HDEC, ®s->hdec);
+ ram_getspr(thread, SPR_HDEC, ®s->hdec);
printf("HDEC : 0x%016" PRIx64 "\n", regs->hdec);
- thread_getspr(target, SPR_HSPRG0, ®s->hsprg0);
+ ram_getspr(thread, SPR_HSPRG0, ®s->hsprg0);
printf("HSPRG0: 0x%016" PRIx64 "\n", regs->hsprg0);
- thread_getspr(target, SPR_HSPRG1, ®s->hsprg1);
+ ram_getspr(thread, SPR_HSPRG1, ®s->hsprg1);
printf("HSPRG1: 0x%016" PRIx64 "\n", regs->hsprg1);
- thread_getspr(target, SPR_FSCR, ®s->fscr);
+ ram_getspr(thread, SPR_FSCR, ®s->fscr);
printf("FSCR : 0x%016" PRIx64 "\n", regs->fscr);
- thread_getspr(target, SPR_DSISR, &value);
+ ram_getspr(thread, SPR_DSISR, &value);
regs->dsisr = value;
printf("DSISR : 0x%08" PRIx32 "\n", regs->dsisr);
- thread_getspr(target, SPR_DAR, ®s->dar);
+ ram_getspr(thread, SPR_DAR, ®s->dar);
printf("DAR : 0x%016" PRIx64 "\n", regs->dar);
- thread_getspr(target, SPR_SRR0, ®s->srr0);
+ ram_getspr(thread, SPR_SRR0, ®s->srr0);
printf("SRR0 : 0x%016" PRIx64 "\n", regs->srr0);
- thread_getspr(target, SPR_SRR1, ®s->srr1);
+ ram_getspr(thread, SPR_SRR1, ®s->srr1);
printf("SRR1 : 0x%016" PRIx64 "\n", regs->srr1);
- thread_getspr(target, SPR_DEC, ®s->dec);
+ ram_getspr(thread, SPR_DEC, ®s->dec);
printf("DEC : 0x%016" PRIx64 "\n", regs->dec);
- thread_getspr(target, SPR_TB, ®s->tb);
+ ram_getspr(thread, SPR_TB, ®s->tb);
printf("TB : 0x%016" PRIx64 "\n", regs->tb);
- thread_getspr(target, SPR_SPRG0, ®s->sprg0);
+ ram_getspr(thread, SPR_SPRG0, ®s->sprg0);
printf("SPRG0 : 0x%016" PRIx64 "\n", regs->sprg0);
- thread_getspr(target, SPR_SPRG1, ®s->sprg1);
+ ram_getspr(thread, SPR_SPRG1, ®s->sprg1);
printf("SPRG1 : 0x%016" PRIx64 "\n", regs->sprg1);
- thread_getspr(target, SPR_SPRG2, ®s->sprg2);
+ ram_getspr(thread, SPR_SPRG2, ®s->sprg2);
printf("SPRG2 : 0x%016" PRIx64 "\n", regs->sprg2);
- thread_getspr(target, SPR_SPRG3, ®s->sprg3);
+ ram_getspr(thread, SPR_SPRG3, ®s->sprg3);
printf("SPRG3 : 0x%016" PRIx64 "\n", regs->sprg3);
- thread_getspr(target, SPR_PPR, ®s->ppr);
+ ram_getspr(thread, SPR_PPR, ®s->ppr);
printf("PPR : 0x%016" PRIx64 "\n", regs->ppr);
CHECK_ERR(thread->ram_destroy(thread));
diff --git a/libpdbg/chip.h b/libpdbg/chip.h
index b3342b8..6856c64 100644
--- a/libpdbg/chip.h
+++ b/libpdbg/chip.h
@@ -24,4 +24,23 @@ uint64_t mtspr(uint64_t spr, uint64_t reg) __attribute__ ((visibility("hidden"))
int ram_instructions(struct thread *thread, uint64_t *opcodes,
uint64_t *results, int len, unsigned int lpar) __attribute__
((visibility("hidden")));
+
+int ram_getmem(struct thread *thread, uint64_t addr, uint64_t *value);
+int ram_getregs(struct thread *thread, struct thread_regs *regs);
+
+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_getcr(struct thread *thread, uint32_t *value);
+int ram_putcr(struct thread *thread, uint32_t value);
+
#endif
diff --git a/libpdbg/hwunit.h b/libpdbg/hwunit.h
index fd643b4..691689f 100644
--- a/libpdbg/hwunit.h
+++ b/libpdbg/hwunit.h
@@ -140,8 +140,6 @@ struct thread {
int (*ram_setup)(struct thread *);
int (*ram_instruction)(struct thread *, uint64_t opcode, uint64_t *scratch);
int (*ram_destroy)(struct thread *);
- int (*ram_getxer)(struct thread *, uint64_t *value);
- int (*ram_putxer)(struct thread *, uint64_t value);
int (*enable_attn)(struct thread *);
int (*getmem)(struct thread *, uint64_t, uint64_t *);
diff --git a/libpdbg/p8chip.c b/libpdbg/p8chip.c
index 50ab143..4179557 100644
--- a/libpdbg/p8chip.c
+++ b/libpdbg/p8chip.c
@@ -26,6 +26,7 @@
#include "bitutils.h"
#include "debug.h"
#include "sprs.h"
+#include "chip.h"
#define RAS_STATUS_TIMEOUT 100
@@ -655,9 +656,21 @@ static struct thread p8_thread = {
.ram_setup = p8_ram_setup,
.ram_instruction = p8_ram_instruction,
.ram_destroy = p8_ram_destroy,
- .ram_getxer = p8_ram_getxer,
- .ram_putxer = p8_ram_putxer,
.enable_attn = p8_enable_attn,
+ .getmem = ram_getmem,
+ .getregs = ram_getregs,
+ .getgpr = ram_getgpr,
+ .putgpr = ram_putgpr,
+ .getspr = ram_getspr,
+ .putspr = ram_putspr,
+ .getmsr = ram_getmsr,
+ .putmsr = ram_putmsr,
+ .getnia = ram_getnia,
+ .putnia = ram_putnia,
+ .getxer = p8_ram_getxer,
+ .putxer = p8_ram_putxer,
+ .getcr = ram_getcr,
+ .putcr = ram_putcr,
};
DECLARE_HW_UNIT(p8_thread);
diff --git a/libpdbg/p9chip.c b/libpdbg/p9chip.c
index abd2ab2..a46d053 100644
--- a/libpdbg/p9chip.c
+++ b/libpdbg/p9chip.c
@@ -25,6 +25,7 @@
#include "bitutils.h"
#include "debug.h"
#include "sprs.h"
+#include "chip.h"
/*
* NOTE!
@@ -407,14 +408,14 @@ static int p9_ram_destroy(struct thread *thread)
static int p9_ram_getxer(struct thread *thread, uint64_t *value)
{
- CHECK_ERR(thread_getspr(&thread->target, SPR_XER, value));
+ CHECK_ERR(ram_getspr(thread, SPR_XER, value));
return 0;
}
static int p9_ram_putxer(struct thread *thread, uint64_t value)
{
- CHECK_ERR(thread_putspr(&thread->target, SPR_XER, value));
+ CHECK_ERR(ram_putspr(thread, SPR_XER, value));
return 0;
@@ -435,8 +436,20 @@ static struct thread p9_thread = {
.ram_setup = p9_ram_setup,
.ram_instruction = p9_ram_instruction,
.ram_destroy = p9_ram_destroy,
- .ram_getxer = p9_ram_getxer,
- .ram_putxer = p9_ram_putxer,
+ .getmem = ram_getmem,
+ .getregs = ram_getregs,
+ .getgpr = ram_getgpr,
+ .putgpr = ram_putgpr,
+ .getspr = ram_getspr,
+ .putspr = ram_putspr,
+ .getmsr = ram_getmsr,
+ .putmsr = ram_putmsr,
+ .getnia = ram_getnia,
+ .putnia = ram_putnia,
+ .getxer = p9_ram_getxer,
+ .putxer = p9_ram_putxer,
+ .getcr = ram_getcr,
+ .putcr = ram_putcr,
};
DECLARE_HW_UNIT(p9_thread);
diff --git a/libpdbg/thread.c b/libpdbg/thread.c
new file mode 100644
index 0000000..193efb2
--- /dev/null
+++ b/libpdbg/thread.c
@@ -0,0 +1,328 @@
+/* Copyright 2020 IBM Corp.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ * implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include <stdio.h>
+
+#include "libpdbg.h"
+#include "hwunit.h"
+#include "debug.h"
+
+struct thread_state thread_status(struct pdbg_target *target)
+{
+ struct thread *thread;
+
+ assert(pdbg_target_is_class(target, "thread"));
+ thread = target_to_thread(target);
+ return thread->status;
+}
+
+/*
+ * Single step the thread count instructions.
+ */
+int thread_step(struct pdbg_target *target, int count)
+{
+ struct thread *thread;
+
+ assert(pdbg_target_is_class(target, "thread"));
+ thread = target_to_thread(target);
+ return thread->step(thread, count);
+}
+
+int thread_start(struct pdbg_target *target)
+{
+ struct thread *thread;
+
+ assert(pdbg_target_is_class(target, "thread"));
+ thread = target_to_thread(target);
+ return thread->start(thread);
+}
+
+int thread_stop(struct pdbg_target *target)
+{
+ struct thread *thread;
+
+ assert(pdbg_target_is_class(target, "thread"));
+ thread = target_to_thread(target);
+ return thread->stop(thread);
+}
+
+int thread_sreset(struct pdbg_target *target)
+{
+ struct thread *thread;
+
+ assert(pdbg_target_is_class(target, "thread"));
+ thread = target_to_thread(target);
+ return thread->sreset(thread);
+}
+
+int thread_step_all(void)
+{
+ struct pdbg_target *target, *thread;
+ int rc = 0, count = 0;
+
+ pdbg_for_each_class_target("pib", target) {
+ struct pib *pib = target_to_pib(target);
+
+ if (!pib->thread_step_all)
+ break;
+
+ rc |= pib->thread_step_all(pib, 1);
+ count++;
+ }
+
+ if (count > 0)
+ return rc;
+
+ pdbg_for_each_class_target("thread", thread) {
+ if (pdbg_target_status(thread) != PDBG_TARGET_ENABLED)
+ continue;
+
+ rc |= thread_step(thread, 1);
+ }
+
+ return rc;
+}
+
+int thread_start_all(void)
+{
+ struct pdbg_target *target, *thread;
+ int rc = 0, count = 0;
+
+ pdbg_for_each_class_target("pib", target) {
+ struct pib *pib = target_to_pib(target);
+
+ if (!pib->thread_start_all)
+ break;
+
+ rc |= pib->thread_start_all(pib);
+ count++;
+ }
+
+ if (count > 0)
+ return rc;
+
+ pdbg_for_each_class_target("thread", thread) {
+ if (pdbg_target_status(thread) != PDBG_TARGET_ENABLED)
+ continue;
+
+ rc |= thread_start(thread);
+ }
+
+ return rc;
+}
+
+int thread_stop_all(void)
+{
+ struct pdbg_target *target, *thread;
+ int rc = 0, count = 0;
+
+ pdbg_for_each_class_target("pib", target) {
+ struct pib *pib = target_to_pib(target);
+
+ if (!pib->thread_stop_all)
+ break;
+
+ rc |= pib->thread_stop_all(pib);
+ count++;
+ }
+
+ if (count > 0)
+ return rc;
+
+ pdbg_for_each_class_target("thread", thread) {
+ if (pdbg_target_status(thread) != PDBG_TARGET_ENABLED)
+ continue;
+
+ rc |= thread_stop(thread);
+ }
+
+ return rc;
+}
+
+int thread_sreset_all(void)
+{
+ struct pdbg_target *target, *thread;
+ int rc = 0, count = 0;
+
+ pdbg_for_each_class_target("pib", target) {
+ struct pib *pib = target_to_pib(target);
+
+ if (!pib->thread_sreset_all)
+ break;
+
+ rc |= pib->thread_sreset_all(pib);
+ count++;
+ }
+
+ if (count > 0)
+ return rc;
+
+ pdbg_for_each_class_target("thread", thread) {
+ if (pdbg_target_status(thread) != PDBG_TARGET_ENABLED)
+ continue;
+
+ rc |= thread_sreset(thread);
+ }
+
+ return rc;
+}
+
+int thread_getmem(struct pdbg_target *target, uint64_t addr, uint64_t *value)
+{
+ struct thread *thread;
+
+ assert(pdbg_target_is_class(target, "thread"));
+ thread = target_to_thread(target);
+
+ if (thread->getmem)
+ return thread->getmem(thread, addr, value);
+
+ PR_ERROR("Not implemented on the backend\n");
+ return -1;
+}
+
+int thread_getregs(struct pdbg_target *target, struct thread_regs *regs)
+{
+ struct thread *thread;
+
+ assert(pdbg_target_is_class(target, "thread"));
+ thread = target_to_thread(target);
+
+ if (thread->getregs)
+ return thread->getregs(thread, regs);
+
+ PR_ERROR("Not implemented on the backend\n");
+ return -1;
+}
+
+int thread_getgpr(struct pdbg_target *target, int gpr, uint64_t *value)
+{
+ struct thread *thread;
+
+ assert(pdbg_target_is_class(target, "thread"));
+ thread = target_to_thread(target);
+
+ return thread->getgpr(thread, gpr, value);
+}
+
+int thread_putgpr(struct pdbg_target *target, int gpr, uint64_t value)
+{
+ struct thread *thread;
+
+ assert(pdbg_target_is_class(target, "thread"));
+ thread = target_to_thread(target);
+
+ return thread->putgpr(thread, gpr, value);
+}
+
+int thread_getspr(struct pdbg_target *target, int spr, uint64_t *value)
+{
+ struct thread *thread;
+
+ assert(pdbg_target_is_class(target, "thread"));
+ thread = target_to_thread(target);
+
+ return thread->getspr(thread, spr, value);
+}
+
+int thread_putspr(struct pdbg_target *target, int spr, uint64_t value)
+{
+ struct thread *thread;
+
+ assert(pdbg_target_is_class(target, "thread"));
+ thread = target_to_thread(target);
+
+ return thread->putspr(thread, spr, value);
+}
+
+int thread_getmsr(struct pdbg_target *target, uint64_t *value)
+{
+ struct thread *thread;
+
+ assert(pdbg_target_is_class(target, "thread"));
+ thread = target_to_thread(target);
+
+ return thread->getmsr(thread, value);
+}
+
+int thread_putmsr(struct pdbg_target *target, uint64_t value)
+{
+ struct thread *thread;
+
+ assert(pdbg_target_is_class(target, "thread"));
+ thread = target_to_thread(target);
+
+ return thread->putmsr(thread, value);
+}
+
+int thread_getnia(struct pdbg_target *target, uint64_t *value)
+{
+ struct thread *thread;
+
+ assert(pdbg_target_is_class(target, "thread"));
+ thread = target_to_thread(target);
+
+ return thread->getnia(thread, value);
+}
+
+int thread_putnia(struct pdbg_target *target, uint64_t value)
+{
+ struct thread *thread;
+
+ assert(pdbg_target_is_class(target, "thread"));
+ thread = target_to_thread(target);
+
+ return thread->putnia(thread, value);
+}
+
+int thread_getxer(struct pdbg_target *target, uint64_t *value)
+{
+ struct thread *thread;
+
+ assert(pdbg_target_is_class(target, "thread"));
+ thread = target_to_thread(target);
+
+ return thread->getxer(thread, value);
+}
+
+int thread_putxer(struct pdbg_target *target, uint64_t value)
+{
+ struct thread *thread;
+
+ assert(pdbg_target_is_class(target, "thread"));
+ thread = target_to_thread(target);
+
+ return thread->putxer(thread, value);
+}
+
+int thread_getcr(struct pdbg_target *target, uint32_t *value)
+{
+ struct thread *thread;
+
+ assert(pdbg_target_is_class(target, "thread"));
+ thread = target_to_thread(target);
+
+ return thread->getcr(thread, value);
+}
+
+int thread_putcr(struct pdbg_target *target, uint32_t value)
+{
+ struct thread *thread;
+
+ assert(pdbg_target_is_class(target, "thread"));
+ thread = target_to_thread(target);
+
+ return thread->putcr(thread, value);
+}
--
2.26.2
More information about the Pdbg
mailing list