[Pdbg] [PATCH v3 05/13] libpdbg/p9chip.c: query thread active and stop states
Nicholas Piggin
npiggin at gmail.com
Wed May 2 16:28:00 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