[Pdbg] [PATCH 13/19] pdbg/gdbserver: Add in basic skeleton for a gdbserver on p8

Nicholas Piggin npiggin at gmail.com
Thu Aug 30 21:25:49 AEST 2018


On Thu, 30 Aug 2018 10:18:30 +1000
Rashmica <rashmica.g at gmail.com> wrote:

> On 29/08/18 18:36, Nicholas Piggin wrote:
> 
> > On Wed, 29 Aug 2018 11:50:41 +1000
> > Rashmica Gupta <rashmica.g at gmail.com> wrote:
> >  
> >> From: Alistair Popple <alistair at popple.id.au>
> >>
> >> I have changed a few bits here and there but this patch is largely
> >> authored by Alistair Popple.  
> > So what's missing for P9? enable_attn? Anything else?  
> 
> There's a couple of things that I'm trying to work out regarding P9.
> 
> - we can't mtnia from an arbitrary register in ramming mode (can only do it
>  from the link register).

There's a few bits that seem to make P9 work. No guarantee I didn't
break P8 MTNIA because I haven't tested it.

As we can see, the need for target specific .ram_spr function is
increasing. P9 still isn't quite right with all its MTSPRs either.

--

P9 MTNIA and MTMSR fixes

---
 libpdbg/chip.c   | 19 +++++++++++++++----
 libpdbg/p9chip.c |  6 +++---
 src/reg.c        |  2 +-
 3 files changed, 19 insertions(+), 8 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/p9chip.c b/libpdbg/p9chip.c
index 189d80a..9094c24 100644
--- a/libpdbg/p9chip.c
+++ b/libpdbg/p9chip.c
@@ -291,10 +291,9 @@ static int __p9_ram_instruction(struct thread *thread, uint64_t opcode, uint64_t
 
 	switch(opcode & OPCODE_MASK) {
 	case MTNIA_OPCODE:
+		opcode = 0x4c0000a4;
+		opcode |= 0x001E0000;
 		predecode = 8;
-
-		/* Not currently supported as we can only MTNIA from LR */
-		PR_ERROR("MTNIA is not currently supported\n");
 		break;
 
 	case MFNIA_OPCODE:
@@ -304,6 +303,7 @@ static int __p9_ram_instruction(struct thread *thread, uint64_t opcode, uint64_t
 
 	case MTMSR_OPCODE:
 		predecode = 8;
+		opcode |= 0x001E0000;
 		break;
 
 	case MFSPR_OPCODE:
diff --git a/src/reg.c b/src/reg.c
index aa77a8a..c63f6da 100644
--- a/src/reg.c
+++ b/src/reg.c
@@ -116,7 +116,7 @@ OPTCMD_DEFINE_CMD(getnia, getnia);
 static int putnia(uint64_t nia)
 {
 	uint64_t reg = REG_NIA;
-	return for_each_target("thread", getprocreg, &reg, &nia);
+	return for_each_target("thread", putprocreg, &reg, &nia);
 }
 OPTCMD_DEFINE_CMD_WITH_ARGS(putnia, putnia, (DATA));
 
-- 
2.18.0



More information about the Pdbg mailing list