diff mbox series

[3/4] libpdbg: Add p10 thread state

Message ID 20201110045217.137133-4-amitay@ozlabs.org
State Accepted
Headers show
Series Implement thread status for p10 | expand

Checks

Context Check Description
snowpatch_ozlabs/build-multiarch success Test build-multiarch on branch master
snowpatch_ozlabs/apply_patch success Successfully applied on branch master (bdec2f8c512ff4a70eaadcb01a7494b4cb5e13e5)

Commit Message

Amitay Isaacs Nov. 10, 2020, 4:52 a.m. UTC
Signed-off-by: Amitay Isaacs <amitay@ozlabs.org>
---
 libpdbg/chip.h    |  1 +
 libpdbg/p10chip.c | 52 +++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 53 insertions(+)
diff mbox series

Patch

diff --git a/libpdbg/chip.h b/libpdbg/chip.h
index 11e8e8b..2231053 100644
--- a/libpdbg/chip.h
+++ b/libpdbg/chip.h
@@ -44,5 +44,6 @@  int ram_getcr(struct thread *thread, uint32_t *value);
 int ram_putcr(struct thread *thread, uint32_t value);
 
 struct thread_state p9_thread_state(struct thread *thread);
+struct thread_state p10_thread_state(struct thread *thread);
 
 #endif
diff --git a/libpdbg/p10chip.c b/libpdbg/p10chip.c
index b1eb4a6..12395f5 100644
--- a/libpdbg/p10chip.c
+++ b/libpdbg/p10chip.c
@@ -22,6 +22,10 @@ 
 #include "chip.h"
 #include "debug.h"
 
+#define P10_CORE_THREAD_STATE	0x28412
+#define P10_THREAD_INFO		0x28413
+#define P10_RAS_STATUS		0x28454
+
 /* PCB Slave registers */
 #define QME_SSH_FSP		0xE8824
 #define  SPECIAL_WKUP_DONE	PPC_BIT(1)
@@ -29,6 +33,54 @@ 
 
 #define SPECIAL_WKUP_TIMEOUT	100 /* 100ms */
 
+static int thread_read(struct thread *thread, uint64_t addr, uint64_t *data)
+{
+	struct pdbg_target *core = pdbg_target_require_parent("core", &thread->target);
+
+	return pib_read(core, addr, data);
+}
+
+struct thread_state p10_thread_state(struct thread *thread)
+{
+	struct thread_state thread_state;
+	uint64_t value;
+	uint8_t smt_mode;
+
+	thread_read(thread, P10_RAS_STATUS, &value);
+
+	thread_state.quiesced = (GETFIELD(PPC_BITMASK(1 + 8*thread->id, 3 + 8*thread->id), value) == 0x7);
+
+	thread_read(thread, P10_THREAD_INFO, &value);
+	thread_state.active = !!(value & PPC_BIT(thread->id));
+
+	smt_mode = GETFIELD(PPC_BITMASK(8,9), value);
+	switch (smt_mode) {
+	case 0:
+		thread_state.smt_state = PDBG_SMT_1;
+		break;
+
+	case 2:
+		thread_state.smt_state = PDBG_SMT_2;
+		break;
+
+	case 3:
+		thread_state.smt_state = PDBG_SMT_4;
+		break;
+
+	default:
+		thread_state.smt_state = PDBG_SMT_UNKNOWN;
+		break;
+	}
+
+	thread_read(thread, P10_CORE_THREAD_STATE, &value);
+	if (value & PPC_BIT(56 + thread->id))
+		thread_state.sleep_state = PDBG_THREAD_STATE_STOP;
+	else
+		thread_state.sleep_state = PDBG_THREAD_STATE_RUN;
+
+	return thread_state;
+}
+
 static int p10_core_probe(struct pdbg_target *target)
 {
 	struct core *core = target_to_core(target);