Message ID | 20180909061859.21445-1-npiggin@gmail.com |
---|---|
State | Accepted |
Headers | show |
Series | [1/2] libpdbg/chip: implement putnia with a sequence compatible with P9 | expand |
Context | Check | Description |
---|---|---|
snowpatch_ozlabs/apply_patch | success | master/apply_patch Successfully applied |
snowpatch_ozlabs/build-multiarch | fail | Test build-multiarch on branch master |
On Sun, 2018-09-09 at 16:18 +1000, Nicholas Piggin wrote: > P9 MTNIA uses LR as the source register, so set LR as well as GPR0. > This will work on P8 and P9. This is a bit ugly, but it will work > until we have general getspr/putspr calls for target backends. > Tested-by: Rashmica Gupta <rashmica.g@gmail.com> > Signed-off-by: Nicholas Piggin <npiggin@gmail.com> > --- > > These require Rashmica's "pdbg: Fix function call for putnia command" > patch to test properly. > > libpdbg/chip.c | 19 +++++++++++++++---- > 1 file changed, 15 insertions(+), 4 deletions(-) > > diff --git a/libpdbg/chip.c b/libpdbg/chip.c > index 80a2261..1d41d87 100644 > --- a/libpdbg/chip.c > +++ b/libpdbg/chip.c > @@ -145,8 +145,8 @@ int ram_sreset_thread(struct pdbg_target > *thread_target) > * into *results. *results must point to an array the same size as > * *opcodes. Each entry from *results is put into SCR0 prior to > * executing an opcode so that it may also be used to pass in > - * data. Note that only register r0 is saved and restored so opcodes > - * must not touch other registers. > + * data. Note that only registers r0 and r1 are saved and restored > so > + * opcode sequences must preserve other registers. > */ > static int ram_instructions(struct pdbg_target *thread_target, > uint64_t *opcodes, > uint64_t *results, int len, unsigned int > lpar) > @@ -242,10 +242,21 @@ int ram_getnia(struct pdbg_target *thread, > uint64_t *value) > return 0; > } > > +/* > + * P9 must MTNIA from LR, P8 can MTNIA from R0. So we set both LR > and R0 > + * to value. LR must be saved and restored. > + * > + * This is a hack and should be made much cleaner once we have > target > + * specific putspr commands. > + */ > int ram_putnia(struct pdbg_target *thread, uint64_t value) > { > - uint64_t opcodes[] = {mfspr(0, 277), mtnia(0)}; > - uint64_t results[] = {value, 0}; > + uint64_t opcodes[] = { mfspr(1, 8), /* mflr r1 > */ > + mfspr(0, 277), /* value -> r0 > */ > + mtspr(8, 0), /* mtlr r0 */ > + mtnia(0), > + mtspr(8, 1), }; /* mtlr r1 */ > + uint64_t results[] = {0, value, 0, 0, 0}; > > CHECK_ERR(ram_instructions(thread, opcodes, results, > ARRAY_SIZE(opcodes), 0)); > return 0;
diff --git a/libpdbg/chip.c b/libpdbg/chip.c index 80a2261..1d41d87 100644 --- a/libpdbg/chip.c +++ b/libpdbg/chip.c @@ -145,8 +145,8 @@ int ram_sreset_thread(struct pdbg_target *thread_target) * into *results. *results must point to an array the same size as * *opcodes. Each entry from *results is put into SCR0 prior to * executing an opcode so that it may also be used to pass in - * data. Note that only register r0 is saved and restored so opcodes - * must not touch other registers. + * data. Note that only registers r0 and r1 are saved and restored so + * opcode sequences must preserve other registers. */ static int ram_instructions(struct pdbg_target *thread_target, uint64_t *opcodes, uint64_t *results, int len, unsigned int lpar) @@ -242,10 +242,21 @@ int ram_getnia(struct pdbg_target *thread, uint64_t *value) return 0; } +/* + * P9 must MTNIA from LR, P8 can MTNIA from R0. So we set both LR and R0 + * to value. LR must be saved and restored. + * + * This is a hack and should be made much cleaner once we have target + * specific putspr commands. + */ int ram_putnia(struct pdbg_target *thread, uint64_t value) { - uint64_t opcodes[] = {mfspr(0, 277), mtnia(0)}; - uint64_t results[] = {value, 0}; + uint64_t opcodes[] = { mfspr(1, 8), /* mflr r1 */ + mfspr(0, 277), /* value -> r0 */ + mtspr(8, 0), /* mtlr r0 */ + mtnia(0), + mtspr(8, 1), }; /* mtlr r1 */ + uint64_t results[] = {0, value, 0, 0, 0}; CHECK_ERR(ram_instructions(thread, opcodes, results, ARRAY_SIZE(opcodes), 0)); return 0;
P9 MTNIA uses LR as the source register, so set LR as well as GPR0. This will work on P8 and P9. This is a bit ugly, but it will work until we have general getspr/putspr calls for target backends. Signed-off-by: Nicholas Piggin <npiggin@gmail.com> --- These require Rashmica's "pdbg: Fix function call for putnia command" patch to test properly. libpdbg/chip.c | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-)