[Pdbg] [PATCH v2 05/10] libpdbg/p9chip.c: query thread active and stop states

Nicholas Piggin npiggin at gmail.com
Wed May 2 02:33:34 AEST 2018


Signed-off-by: Nicholas Piggin <npiggin at gmail.com>
---
 libpdbg/libpdbg.h | 19 ++++++++++++-------
 libpdbg/p9chip.c  | 17 +++++++++++++----
 src/htm.c         |  5 ++++-
 3 files changed, 29 insertions(+), 12 deletions(-)

diff --git a/libpdbg/libpdbg.h b/libpdbg/libpdbg.h
index f843816..f2b5de7 100644
--- a/libpdbg/libpdbg.h
+++ b/libpdbg/libpdbg.h
@@ -95,13 +95,16 @@ int ram_sreset_thread(struct pdbg_target *target);
 uint64_t thread_status(struct pdbg_target *target);
 int getring(struct pdbg_target *chiplet_target, uint64_t ring_addr, uint64_t ring_len, uint32_t result[]);
 
-#define THREAD_STATUS_DISABLED  PPC_BIT(0)
-#define THREAD_STATUS_ACTIVE       PPC_BIT(63)
-#define THREAD_STATUS_STATE        PPC_BITMASK(61, 62)
-#define THREAD_STATUS_DOZE PPC_BIT(62)
-#define THREAD_STATUS_NAP  PPC_BIT(61)
-#define THREAD_STATUS_SLEEP        PPC_BITMASK(61, 62)
-#define THREAD_STATUS_QUIESCE      PPC_BIT(60)
+#define THREAD_STATUS_DISABLED	PPC_BIT(0)
+#define THREAD_STATUS_ACTIVE	PPC_BIT(63)
+
+#define THREAD_STATUS_STATE	PPC_BITMASK(61, 62)
+#define THREAD_STATUS_DOZE	PPC_BIT(62)
+#define THREAD_STATUS_NAP	PPC_BIT(61)
+#define THREAD_STATUS_SLEEP	PPC_BITMASK(61, 62)
+
+#define THREAD_STATUS_QUIESCE	PPC_BIT(60)
+
 #define THREAD_STATUS_SMT	PPC_BITMASK(57, 59)
 #define THREAD_STATUS_SMT_1	PPC_BIT(59)
 #define THREAD_STATUS_SMT_2SH	PPC_BIT(58)
@@ -109,6 +112,8 @@ int getring(struct pdbg_target *chiplet_target, uint64_t ring_addr, uint64_t rin
 #define THREAD_STATUS_SMT_4	PPC_BIT(57)
 #define THREAD_STATUS_SMT_8	(PPC_BIT(57) | PPC_BIT(59))
 
+#define THREAD_STATUS_STOP	PPC_BIT(56)
+
 int htm_start(struct pdbg_target *target);
 int htm_stop(struct pdbg_target *target);
 int htm_status(struct pdbg_target *target);
diff --git a/libpdbg/p9chip.c b/libpdbg/p9chip.c
index 205b4cd..46ec0d9 100644
--- a/libpdbg/p9chip.c
+++ b/libpdbg/p9chip.c
@@ -25,6 +25,7 @@
 #include "bitutils.h"
 
 #define P9_RAS_STATUS 0x10a02
+#define P9_CORE_THREAD_STATE 0x10ab3
 #define P9_THREAD_INFO 0x10a9b
 #define P9_DIRECT_CONTROL 0x10a9c
 #define P9_RAS_MODEREG 0x10a9d
@@ -85,12 +86,20 @@ static uint64_t thread_write(struct thread *thread, uint64_t addr, uint64_t data
 
 static uint64_t p9_get_thread_status(struct thread *thread)
 {
-	uint64_t value, status = THREAD_STATUS_ACTIVE;
+	uint64_t value, status = 0;
 
 	thread_read(thread, P9_RAS_STATUS, &value);
 	if (GETFIELD(PPC_BITMASK(8*thread->id, 3 + 8*thread->id), value) == 0xf)
 		status |= THREAD_STATUS_QUIESCE;
 
+	thread_read(thread, P9_THREAD_INFO, &value);
+	if (value & PPC_BIT(thread->id))
+		status |= THREAD_STATUS_ACTIVE;
+
+	thread_read(thread, P9_CORE_THREAD_STATE, &value);
+	if (value & PPC_BIT(56 + thread->id))
+		status |= THREAD_STATUS_STOP;
+
 	return status;
 }
 
@@ -129,8 +138,8 @@ static int p9_thread_stop(struct thread *thread)
 
 static int p9_thread_sreset(struct thread *thread)
 {
-	/* Can only sreset if a thread is inactive, at least on DD1 */
-	if (p9_get_thread_status(thread) != (THREAD_STATUS_QUIESCE | THREAD_STATUS_ACTIVE))
+	/* Can only sreset if a thread is inactive */
+	if (!(p9_get_thread_status(thread) & THREAD_STATUS_QUIESCE))
 		return 1;
 
 	thread_write(thread, P9_DIRECT_CONTROL, PPC_BIT(4 + 8*thread->id));
@@ -152,7 +161,7 @@ static int p9_ram_setup(struct thread *thread)
 		   so do that now. This will also update the thread status */
 		p9_thread_probe(target);
 		tmp = target_to_thread(target);
-		if (tmp->status != (THREAD_STATUS_QUIESCE | THREAD_STATUS_ACTIVE))
+		if (!(tmp->status & THREAD_STATUS_QUIESCE))
 			return 1;
 	}
 
diff --git a/src/htm.c b/src/htm.c
index 566687e..a7e7d06 100644
--- a/src/htm.c
+++ b/src/htm.c
@@ -322,6 +322,8 @@ int run_htm(int optind, int argc, char *argv[])
 		 * This is as easy as checking that every single
 		 * thread is "ACTIVE" and hasn't gone into any sleep
 		 * state.
+		 *
+		 * On P9 it requires checking for THREAD_STATUS_STOP
 		 */
 		pdbg_for_each_class_target("thread", target) {
 			pdbg_target_probe(target);
@@ -329,7 +331,8 @@ int run_htm(int optind, int argc, char *argv[])
 			if (pdbg_target_status(target) == PDBG_TARGET_NONEXISTENT)
 				continue;
 
-			if ((thread_status(target) & THREAD_STATUS_ACTIVE) != THREAD_STATUS_ACTIVE) {
+			if ((!(thread_status(target) & THREAD_STATUS_ACTIVE)) ||
+			    (thread_status(target) & THREAD_STATUS_STOP)) {
 				fprintf(stderr, "It appears powersave is on 0x%"  PRIx64 "%p\n", thread_status(target), target);
 				fprintf(stderr, "core HTM needs to run with powersave off\n");
 				fprintf(stderr, "Hint: put powersave=off on the kernel commandline\n");
-- 
2.17.0



More information about the Pdbg mailing list