diff mbox series

[06/10] libpdbg: move core state into struct core

Message ID 20220531091457.2208488-7-npiggin@gmail.com
State New
Headers show
Series [01/10] sbefifo: correct typo in thread target name | expand

Commit Message

Nicholas Piggin May 31, 2022, 9:14 a.m. UTC
Create a core state along the same lines as thread state, and move
per-core state (SMT, LPAR-per-thread, fused-core) modes there.

This adds core into the SBEFIFO backend's hierarchy.

Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
---
 libpdbg/chip.h    |  3 +++
 libpdbg/hwunit.h  |  2 ++
 libpdbg/libpdbg.h | 19 ++++++++++++++-
 libpdbg/p10chip.c | 61 +++++++++++++++++++++++++++++------------------
 libpdbg/p8chip.c  | 41 +++++++++++++++++++++++--------
 libpdbg/p9chip.c  | 61 +++++++++++++++++++++++++++++------------------
 libpdbg/sbefifo.c | 39 ++++++++++++++++++++++++++++++
 libpdbg/thread.c  |  9 +++++++
 8 files changed, 178 insertions(+), 57 deletions(-)
diff mbox series

Patch

diff --git a/libpdbg/chip.h b/libpdbg/chip.h
index 22310530..d5b74514 100644
--- a/libpdbg/chip.h
+++ b/libpdbg/chip.h
@@ -46,4 +46,7 @@  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);
 
+struct core_state p9_core_state(struct core *core);
+struct core_state p10_core_state(struct core *core);
+
 #endif
diff --git a/libpdbg/hwunit.h b/libpdbg/hwunit.h
index 563b5812..4f27e34c 100644
--- a/libpdbg/hwunit.h
+++ b/libpdbg/hwunit.h
@@ -132,7 +132,9 @@  struct i2cbus {
 
 struct core {
 	struct pdbg_target target;
+	struct core_state status;
 	bool release_spwkup;
+	struct core_state (*state)(struct core *);
 };
 #define target_to_core(x) container_of(x, struct core, target)
 
diff --git a/libpdbg/libpdbg.h b/libpdbg/libpdbg.h
index 252b1b16..0e314b14 100644
--- a/libpdbg/libpdbg.h
+++ b/libpdbg/libpdbg.h
@@ -1043,12 +1043,20 @@  enum pdbg_smt_state {
 struct thread_state {
 	bool active;
 	bool quiesced;
+	enum pdbg_sleep_state sleep_state;
+};
+
+/**
+ * @struct core_state
+ * @brief Container of core states
+ */
+struct core_state {
 	bool lpar_per_thread;
 	bool fused_core_mode;
-	enum pdbg_sleep_state sleep_state;
 	enum pdbg_smt_state smt_state;
 };
 
+
 /**
  * @brief Start execution of the given thread
  * @param[in] target the thread target to operate on
@@ -1125,6 +1133,15 @@  int thread_stop_proc(struct pdbg_target *target);
  */
 struct thread_state thread_status(struct pdbg_target *target);
 
+/**
+ * @brief Return the core status information
+ *
+ * @param[in]  target the core target to operate on
+ *
+ * @return core_state structure containing core information
+ */
+struct core_state core_status(struct pdbg_target *target);
+
 /**
  * @brief Get SPR id from name
  *
diff --git a/libpdbg/p10chip.c b/libpdbg/p10chip.c
index 632a1a9c..fc661d34 100644
--- a/libpdbg/p10chip.c
+++ b/libpdbg/p10chip.c
@@ -61,7 +61,6 @@  struct thread_state p10_thread_state(struct thread *thread)
 	struct thread_state thread_state;
 	uint64_t value;
 	bool maint_mode, thread_quiesced, ict_empty;
-	uint8_t smt_mode;
 
 	thread_read(thread, P10_RAS_STATUS, &value);
 
@@ -82,34 +81,12 @@  struct thread_state p10_thread_state(struct thread *thread)
 	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;
 
-	thread_state.lpar_per_thread = !(value & PPC_BIT(62));
-	thread_state.fused_core_mode = !!(value & PPC_BIT(63));
-
 	return thread_state;
 }
 
@@ -197,6 +174,41 @@  static struct thread p10_thread = {
 };
 DECLARE_HW_UNIT(p10_thread);
 
+struct core_state p10_core_state(struct core *core)
+{
+	struct core_state core_state;
+	uint64_t value;
+	uint8_t smt_mode;
+
+	pib_read(&core->target, P10_THREAD_INFO, &value);
+
+	smt_mode = GETFIELD(PPC_BITMASK(8,9), value);
+	switch (smt_mode) {
+	case 0:
+		core_state.smt_state = PDBG_SMT_1;
+		break;
+
+	case 2:
+		core_state.smt_state = PDBG_SMT_2;
+		break;
+
+	case 3:
+		core_state.smt_state = PDBG_SMT_4;
+		break;
+
+	default:
+		core_state.smt_state = PDBG_SMT_UNKNOWN;
+		break;
+	}
+
+	pib_read(&core->target, P10_CORE_THREAD_STATE, &value);
+
+	core_state.lpar_per_thread = !(value & PPC_BIT(62));
+	core_state.fused_core_mode = !!(value & PPC_BIT(63));
+
+	return core_state;
+}
+
 static int p10_core_probe(struct pdbg_target *target)
 {
 	struct core *core = target_to_core(target);
@@ -227,6 +239,8 @@  static int p10_core_probe(struct pdbg_target *target)
 
 	core->release_spwkup = true;
 
+	core->status = core->state(core);
+
 	return 0;
 }
 
@@ -301,6 +315,7 @@  static struct core p10_core = {
 		.release = p10_core_release,
 		.translate = translate_cast(p10_core_translate),
 	},
+	.state = p10_core_state,
 };
 DECLARE_HW_UNIT(p10_core);
 
diff --git a/libpdbg/p8chip.c b/libpdbg/p8chip.c
index 0592ca08..1863af74 100644
--- a/libpdbg/p8chip.c
+++ b/libpdbg/p8chip.c
@@ -213,44 +213,62 @@  static struct thread_state p8_thread_state(struct thread *thread)
 		assert(0);
 	}
 
+	/* Clear debug mode */
+	pib_write(&thread->target, RAS_MODE_REG, mode_reg);
+
+	return thread_status;
+}
+
+static struct core_state p8_core_state(struct core *core)
+{
+	uint64_t val, mode_reg;
+	struct core_state core_status;
+
+	/* Need to activete debug mode to get complete status */
+	pib_read(&core->target, RAS_MODE_REG, &mode_reg);
+	pib_write(&core->target, RAS_MODE_REG, mode_reg | MR_THREAD_IN_DEBUG);
+
+	/* Read POW status */
+	pib_read(&core->target, POW_STATUS_REG, &val);
+
 	switch (GETFIELD(PMC_POW_SMT, val)) {
 	case PMC_POW_SMT_0:
-		thread_status.smt_state = PDBG_SMT_UNKNOWN;
+		core_status.smt_state = PDBG_SMT_UNKNOWN;
 		break;
 
 	case PMC_POW_SMT_1:
-		thread_status.smt_state = PDBG_SMT_1;
+		core_status.smt_state = PDBG_SMT_1;
 		break;
 
 	case PMC_POW_SMT_2SH:
 	case PMC_POW_SMT_2SP:
-		thread_status.smt_state = PDBG_SMT_2;
+		core_status.smt_state = PDBG_SMT_2;
 		break;
 
 	/* It's unclear from the documentation what the difference between these
 	 * two are. */
 	case PMC_POW_SMT_4_3:
 	case PMC_POW_SMT_4_4:
-		thread_status.smt_state = PDBG_SMT_4;
+		core_status.smt_state = PDBG_SMT_4;
 		break;
 
 	/* Ditto */
 	case PMC_POW_SMT_8_5:
 	case PMC_POW_SMT_8_8:
-		thread_status.smt_state = PDBG_SMT_8;
+		core_status.smt_state = PDBG_SMT_8;
 		break;
 
 	default:
 		assert(0);
 	}
 
-	/* Clear debug mode */
-	pib_write(&thread->target, RAS_MODE_REG, mode_reg);
+	core_status.lpar_per_thread = false;
+	core_status.fused_core_mode = false;
 
-	thread_state.lppar_per_thread = false;
-	thread_state.fused_core_mode = false;
+	/* Clear debug mode */
+	pib_write(&core->target, RAS_MODE_REG, mode_reg);
 
-	return thread_status;
+	return core_status;
 }
 
 static int p8_thread_step(struct thread *thread, int count)
@@ -667,6 +685,8 @@  static int p8_core_probe(struct pdbg_target *target)
 	/* Child threads will set this to false if they are released while quiesced */
 	core->release_spwkup = true;
 
+	core->status = core->state(core);
+
 	return 0;
 }
 
@@ -711,6 +731,7 @@  static struct core p8_core = {
 		.probe = p8_core_probe,
 		.release = p8_core_release,
 	},
+	.state = p8_core_state,
 };
 DECLARE_HW_UNIT(p8_core);
 
diff --git a/libpdbg/p9chip.c b/libpdbg/p9chip.c
index 036be521..1167dac8 100644
--- a/libpdbg/p9chip.c
+++ b/libpdbg/p9chip.c
@@ -94,7 +94,6 @@  struct thread_state p9_thread_state(struct thread *thread)
 {
 	uint64_t value;
 	struct thread_state thread_state;
-	uint8_t smt_mode;
 
 	thread_read(thread, P9_RAS_STATUS, &value);
 
@@ -103,34 +102,12 @@  struct thread_state p9_thread_state(struct thread *thread)
 	thread_read(thread, P9_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, P9_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;
 
-	thread_state.lpar_per_thread = !(value & PPC_BIT(62));
-	thread_state.fused_core_mode = !!(value & PPC_BIT(63));
-
 	return thread_state;
 }
 
@@ -474,6 +451,41 @@  static struct thread p9_thread = {
 };
 DECLARE_HW_UNIT(p9_thread);
 
+struct core_state p9_core_state(struct core *core)
+{
+	uint64_t value;
+	struct core_state core_state;
+	uint8_t smt_mode;
+
+	pib_read(&core->target, P9_THREAD_INFO, &value);
+
+	smt_mode = GETFIELD(PPC_BITMASK(8,9), value);
+	switch (smt_mode) {
+	case 0:
+		core_state.smt_state = PDBG_SMT_1;
+		break;
+
+	case 2:
+		core_state.smt_state = PDBG_SMT_2;
+		break;
+
+	case 3:
+		core_state.smt_state = PDBG_SMT_4;
+		break;
+
+	default:
+		core_state.smt_state = PDBG_SMT_UNKNOWN;
+		break;
+	}
+
+	pib_read(&core->target, P9_CORE_THREAD_STATE, &value);
+
+	core_state.lpar_per_thread = !(value & PPC_BIT(62));
+	core_state.fused_core_mode = !!(value & PPC_BIT(63));
+
+	return core_state;
+}
+
 static int p9_core_probe(struct pdbg_target *target)
 {
 	struct core *core = target_to_core(target);
@@ -495,6 +507,8 @@  static int p9_core_probe(struct pdbg_target *target)
 	/* Child threads will set this to false if they are released while quiesced */
 	core->release_spwkup = true;
 
+	core->status = core->state(core);
+
 	return 0;
 }
 
@@ -539,6 +553,7 @@  static struct core p9_core = {
 		.probe = p9_core_probe,
 		.release = p9_core_release,
 	},
+	.state = p9_core_state,
 };
 DECLARE_HW_UNIT(p9_core);
 
diff --git a/libpdbg/sbefifo.c b/libpdbg/sbefifo.c
index 5cb9c913..3be19b80 100644
--- a/libpdbg/sbefifo.c
+++ b/libpdbg/sbefifo.c
@@ -895,6 +895,45 @@  static struct thread sbefifo_thread = {
 };
 DECLARE_HW_UNIT(sbefifo_thread);
 
+static struct core_state sbefifo_core_state(struct core *core)
+{
+	struct pdbg_target *pib = pdbg_target_require_parent("pib", &core->target);
+	struct sbefifo *sbefifo = pib_to_sbefifo(pib);
+	struct sbefifo_context *sctx = sbefifo->get_sbefifo_context(sbefifo);
+
+	if (sbefifo_proc(sctx) == SBEFIFO_PROC_P9)
+		return p9_core_state(core);
+	else if (sbefifo_proc(sctx) == SBEFIFO_PROC_P10)
+		return p10_core_state(core);
+	else
+		abort();
+}
+
+static int sbefifo_core_probe(struct pdbg_target *target)
+{
+	struct core *core = target_to_core(target);
+
+	core->status = core->state(core);
+
+	return 0;
+}
+
+static void sbefifo_core_release(struct pdbg_target *target)
+{
+}
+
+static struct core sbefifo_core = {
+	.target = {
+		.name = "SBE FIFO Core",
+		.compatible = "ibm,power-core",
+		.class = "core",
+		.probe = sbefifo_core_probe,
+		.release = sbefifo_core_release,
+	},
+	.state = sbefifo_core_state,
+};
+DECLARE_HW_UNIT(sbefifo_core);
+
 static struct sbefifo kernel_sbefifo = {
 	.target = {
 		.name =	"Kernel based FSI SBE FIFO",
diff --git a/libpdbg/thread.c b/libpdbg/thread.c
index 78a59b8b..f93250ab 100644
--- a/libpdbg/thread.c
+++ b/libpdbg/thread.c
@@ -30,6 +30,15 @@  struct thread_state thread_status(struct pdbg_target *target)
 	return thread->status;
 }
 
+struct core_state core_status(struct pdbg_target *target)
+{
+	struct core *core;
+
+	assert(pdbg_target_is_class(target, "core"));
+	core = target_to_core(target);
+	return core->status;
+}
+
 /*
  * Single step the thread count instructions.
  */