[Pdbg] [PATCH 08/10] libpdbg/p9chip.c: ram allow ram to be used on running threads

Nicholas Piggin npiggin at gmail.com
Thu May 3 16:27:00 AEST 2018


Like the sreset change, this allows rammers to use !expert mode.

Signed-off-by: Nicholas Piggin <npiggin at gmail.com>
---
 libpdbg/operations.h | 10 +++++++-
 libpdbg/p9chip.c     | 60 ++++++++++++++++++++++++++++++++++++++++----
 libpdbg/target.h     |  2 ++
 3 files changed, 66 insertions(+), 6 deletions(-)

diff --git a/libpdbg/operations.h b/libpdbg/operations.h
index d6c947f..3954c59 100644
--- a/libpdbg/operations.h
+++ b/libpdbg/operations.h
@@ -22,13 +22,21 @@
 /* Error codes */
 #define EFSI 1
 
+#define PRINT_ERR PR_DEBUG("%s: %d\n", __FUNCTION__, __LINE__)
 #define CHECK_ERR(x) do {					\
 	if (x) {	       					\
-		PR_DEBUG("%s: %d\n", __FUNCTION__, __LINE__);	\
+		PRINT_ERR;					\
 		return x;					\
 	}							\
 	} while(0)
 
+#define CHECK_ERR_GOTO(label, x) do {				\
+	if (x) {	       					\
+		PRINT_ERR;					\
+		goto label;					\
+	}							\
+	} while(0)
+
 #define FSI2PIB_BASE	0x1000
 
 /* Alter display unit functions */
diff --git a/libpdbg/p9chip.c b/libpdbg/p9chip.c
index 3dafcf2..7182ae1 100644
--- a/libpdbg/p9chip.c
+++ b/libpdbg/p9chip.c
@@ -214,12 +214,52 @@ static int p9_thread_sreset(struct thread *thread)
 	return 0;
 }
 
+static void ram_nonexpert_cleanup(struct thread *thread)
+{
+	struct pdbg_target *target;
+	struct core *chip = target_to_core(thread->target.parent);
+
+	if (pdbg_expert_mode)
+		return;
+
+	/* We can only ram a thread if all the threads on the core/chip are
+	 * quiesced */
+	dt_for_each_compatible(&chip->target, target, "ibm,power9-thread") {
+		struct thread *tmp;
+
+		tmp = target_to_thread(target);
+		if (tmp->ram_did_quiesce) {
+			p9_thread_start(tmp);
+			tmp->ram_did_quiesce = false;
+		}
+	}
+}
+
 static int p9_ram_setup(struct thread *thread)
 {
 	struct pdbg_target *target;
 	struct core *chip = target_to_core(thread->target.parent);
 	uint64_t value;
 
+	if (pdbg_expert_mode)
+		goto expert;
+
+	dt_for_each_compatible(&chip->target, target, "ibm,power9-thread") {
+		struct thread *tmp;
+
+		p9_thread_probe(target);
+		tmp = target_to_thread(target);
+		/* Something already quiesced it, fail*/
+		if (tmp->status & THREAD_STATUS_QUIESCE)
+			goto out_fail;
+		if (!(tmp->status & THREAD_STATUS_QUIESCE)) {
+			if (p9_thread_stop(tmp))
+				goto out_fail;
+			tmp->ram_did_quiesce = true;
+		}
+	}
+
+expert:
 	/* We can only ram a thread if all the threads on the core/chip are
 	 * quiesced */
 	dt_for_each_compatible(&chip->target, target, "ibm,power9-thread") {
@@ -230,7 +270,7 @@ static int p9_ram_setup(struct thread *thread)
 		p9_thread_probe(target);
 		tmp = target_to_thread(target);
 		if (!(tmp->status & THREAD_STATUS_QUIESCE))
-			return 1;
+			goto out_fail;
 	}
 
 	/* Wait for NEST_ACTIVE to clear */
@@ -244,18 +284,26 @@ static int p9_ram_setup(struct thread *thread)
 	} while (value & PPC_BIT(23));
 
 	/* Activate thread for ramming */
-	CHECK_ERR(thread_write(thread, P9_THREAD_INFO, PPC_BIT(18 + thread->id)));
+	CHECK_ERR_GOTO(out_fail,
+		thread_write(thread, P9_THREAD_INFO, PPC_BIT(18 + thread->id)));
 
  	/* Enable ram mode */
-	CHECK_ERR(thread_write(thread, P9_RAM_MODEREG, PPC_BIT(0)));
+	CHECK_ERR_GOTO(out_fail,
+		thread_write(thread, P9_RAM_MODEREG, PPC_BIT(0)));
 
 	/* Setup SPRC to use SPRD */
-	CHECK_ERR(thread_write(thread, P9_SPR_MODE, 0x00000ff000000000));
-	CHECK_ERR(thread_write(thread, P9_SCOMC, 0x0));
+	CHECK_ERR_GOTO(out_fail,
+		thread_write(thread, P9_SPR_MODE, 0x00000ff000000000));
+	CHECK_ERR_GOTO(out_fail,
+		thread_write(thread, P9_SCOMC, 0x0));
 
 	thread->status = p9_get_thread_status(thread);
 
 	return 0;
+
+out_fail:
+	ram_nonexpert_cleanup(thread);
+	return 1;
 }
 
 
@@ -352,6 +400,8 @@ static int p9_ram_destroy(struct thread *thread)
 
 	thread->status = p9_get_thread_status(thread);
 
+	ram_nonexpert_cleanup(thread);
+
 	return 0;
 }
 
diff --git a/libpdbg/target.h b/libpdbg/target.h
index a33e089..0d310fd 100644
--- a/libpdbg/target.h
+++ b/libpdbg/target.h
@@ -151,6 +151,8 @@ struct thread {
 	int (*stop)(struct thread *);
 	int (*sreset)(struct thread *);
 
+	bool ram_did_quiesce; /* was the thread quiesced by ram mode */
+
 	/* ram_setup() should be called prior to using ram_instruction() to
 	 * actually ram the instruction and return the result. ram_destroy()
 	 * should be called at completion to clean-up. */
-- 
2.17.0



More information about the Pdbg mailing list