[Pdbg] [PATCH v3 10/13] libpdbg/p9chip.c: fix ram instruction status sequence

Nicholas Piggin npiggin at gmail.com
Wed May 2 16:28:05 AEST 2018


This comes from the workbook. Without this, some types of mfspr
loops forever despite having completed with bit 1 status set.

Signed-off-by: Nicholas Piggin <npiggin at gmail.com>
---
 libpdbg/p9chip.c | 36 +++++++++++++++++++++++++++++-------
 1 file changed, 29 insertions(+), 7 deletions(-)

diff --git a/libpdbg/p9chip.c b/libpdbg/p9chip.c
index 8c03476..2cb87c9 100644
--- a/libpdbg/p9chip.c
+++ b/libpdbg/p9chip.c
@@ -209,6 +209,7 @@ static int p9_ram_setup(struct thread *thread)
 static int p9_ram_instruction(struct thread *thread, uint64_t opcode, uint64_t *scratch)
 {
 	uint64_t predecode, value;
+	int rc;
 
 	switch(opcode & OPCODE_MASK) {
 	case MTNIA_OPCODE:
@@ -236,14 +237,35 @@ static int p9_ram_instruction(struct thread *thread, uint64_t opcode, uint64_t *
 	value = SETFIELD(PPC_BITMASK(2, 5), value, predecode);
 	value = SETFIELD(PPC_BITMASK(8, 39), value, opcode);
 	CHECK_ERR(thread_write(thread, P9_RAM_CTRL, value));
-	do {
-		CHECK_ERR(thread_read(thread, P9_RAM_STATUS, &value));
-		if (((value & PPC_BIT(0)) || (value & PPC_BIT(2))))
-			return 1;
-	} while (!(value & PPC_BIT(1) && !(value & PPC_BIT(3))));
-	CHECK_ERR(thread_read(thread, P9_SCR0_REG, scratch));
 
-	return 0;
+	CHECK_ERR(thread_read(thread, P9_RAM_STATUS, &value));
+
+	rc = 0;
+	if (value & PPC_BIT(0)) {
+		printf("Error RAMing opcode=%" PRIx64 " attempting to RAM while in recovery (status=%" PRIx64")\n", opcode, value);
+		rc = 1;
+		goto out;
+	}
+	if (value & PPC_BIT(2)) {
+		printf("Error RAMing opcode=%" PRIx64 " exception or interrupt (status=%" PRIx64")\n", opcode, value);
+		rc = 1;
+		goto out;
+	}
+	if (!(value & PPC_BIT(1))) {
+		printf("Warning RAMing opcode=%" PRIx64 " unexpected status=%" PRIx64"\n", opcode, value);
+	}
+
+out:
+	if ((opcode & OPCODE_MASK) == LD_OPCODE) {
+		while (!(value & PPC_BIT(3))) {
+			CHECK_ERR(thread_read(thread, P9_RAM_STATUS, &value));
+		}
+	}
+
+	if (!rc)
+		CHECK_ERR(thread_read(thread, P9_SCR0_REG, scratch));
+
+	return rc;
 }
 
 static int p9_ram_destroy(struct thread *thread)
-- 
2.17.0



More information about the Pdbg mailing list