diff options
author | Alistair Popple <alistair@popple.id.au> | 2017-07-31 15:08:00 +1000 |
---|---|---|
committer | Alistair Popple <alistair@popple.id.au> | 2017-07-31 15:08:00 +1000 |
commit | ac22a4005d40e6e7d23cc1a7e73c4da8b8b6a898 (patch) | |
tree | 3ccb51c1ebaff165ea45e60e903c9ba5f644390b /libpdbg | |
parent | 5aa6dd48db50d93188f6f5fe2966f802ba85d5b1 (diff) | |
download | pdbg-ac22a4005d40e6e7d23cc1a7e73c4da8b8b6a898.tar.gz pdbg-ac22a4005d40e6e7d23cc1a7e73c4da8b8b6a898.zip |
libpdbg: Add sreset command
Signed-off-by: Alistair Popple <alistair@popple.id.au>
Diffstat (limited to 'libpdbg')
-rw-r--r-- | libpdbg/chip.c | 9 | ||||
-rw-r--r-- | libpdbg/operations.h | 1 | ||||
-rw-r--r-- | libpdbg/p9chip.c | 17 | ||||
-rw-r--r-- | libpdbg/target.h | 1 |
4 files changed, 28 insertions, 0 deletions
diff --git a/libpdbg/chip.c b/libpdbg/chip.c index 70d349d..539438a 100644 --- a/libpdbg/chip.c +++ b/libpdbg/chip.c @@ -115,6 +115,15 @@ int ram_stop_thread(struct target *thread_target) return thread->stop(thread); } +int ram_sreset_thread(struct target *thread_target) +{ + struct thread *thread; + + assert(!strcmp(thread_target->class, "thread")); + thread = target_to_thread(thread_target); + return thread->sreset(thread); +} + /* * RAMs the opcodes in *opcodes and store the results of each opcode * into *results. *results must point to an array the same size as diff --git a/libpdbg/operations.h b/libpdbg/operations.h index 62ff5c4..2290f3b 100644 --- a/libpdbg/operations.h +++ b/libpdbg/operations.h @@ -68,6 +68,7 @@ uint64_t thread_status(struct thread *thread); int ram_stop_thread(struct target *thread); int ram_step_thread(struct target *thread, int count); int ram_start_thread(struct target *thread); +int ram_sreset_thread(struct target *thread); void fsi_destroy(struct target *target); /* GDB server functionality */ diff --git a/libpdbg/p9chip.c b/libpdbg/p9chip.c index 677401e..96ce067 100644 --- a/libpdbg/p9chip.c +++ b/libpdbg/p9chip.c @@ -107,6 +107,22 @@ static int p9_thread_stop(struct thread *thread) return 0; } +static int p9_thread_sreset(struct thread *thread) +{ + /* Can only sreset if a thread is inactive, at least on DD1 */ + if (p9_get_thread_status(thread) != (THREAD_STATUS_QUIESCE | THREAD_STATUS_ACTIVE)) + return 1; + + /* This will force SRR1[46:47] == 0b00 which means the kernel should + * enter xmon. However it will hide the fact we may have come from a + * powersave state in which register contents were lost. We need a + * kernel side fix for that. */ + thread_write(thread, P9_DIRECT_CONTROL, PPC_BIT(32 + 8*thread->id)); + thread_write(thread, P9_DIRECT_CONTROL, PPC_BIT(4 + 8*thread->id)); + + return 0; +} + static int p9_ram_setup(struct thread *thread) { struct dt_node *dn; @@ -192,6 +208,7 @@ struct thread p9_thread = { }, .start = p9_thread_start, .stop = p9_thread_stop, + .sreset = p9_thread_sreset, .ram_setup = p9_ram_setup, .ram_instruction = p9_ram_instruction, .ram_destroy = p9_ram_destroy, diff --git a/libpdbg/target.h b/libpdbg/target.h index ba91cf5..cd7a183 100644 --- a/libpdbg/target.h +++ b/libpdbg/target.h @@ -112,6 +112,7 @@ struct thread { int (*step)(struct thread *, int); int (*start)(struct thread *); int (*stop)(struct thread *); + int (*sreset)(struct thread *); /* ram_setup() should be called prior to using ram_instruction() to * actually ram the instruction and return the result. ram_destroy() |