diff mbox series

[1/2] libpdbg/chip: implement putnia with a sequence compatible with P9

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

Checks

Context Check Description
snowpatch_ozlabs/apply_patch success master/apply_patch Successfully applied
snowpatch_ozlabs/build-multiarch fail Test build-multiarch on branch master

Commit Message

Nicholas Piggin Sept. 9, 2018, 6:18 a.m. UTC
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(-)

Comments

Rashmica Gupta Sept. 9, 2018, 11:34 p.m. UTC | #1
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 mbox series

Patch

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;