@@ -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
@@ -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)
@@ -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
*
@@ -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);
@@ -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);
@@ -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);
@@ -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",
@@ -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.
*/
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(-)