[Pdbg] [PATCH 09/10] gdbserver: Fix POWER10 fused-core SPATTN register handling
Nicholas Piggin
npiggin at gmail.com
Tue May 31 19:14:56 AEST 2022
POWER10 in fused-core mode, when a thread executes an attn instruction,
the SPATTN thread bits are set according to fused-core thread ID. The
SPATTN registers for both small cores become set.
So use fc_id, and add logic to clear thread IDs that belong to the
other small core in the pair.
Signed-off-by: Nicholas Piggin <npiggin at gmail.com>
---
src/pdbgproxy.c | 35 ++++++++++++++++++++++++++---------
1 file changed, 26 insertions(+), 9 deletions(-)
diff --git a/src/pdbgproxy.c b/src/pdbgproxy.c
index 29845762..5d06c243 100644
--- a/src/pdbgproxy.c
+++ b/src/pdbgproxy.c
@@ -928,39 +928,56 @@ static void v_contc(uint64_t *stack, void *priv)
static bool thread_check_attn(struct pdbg_target *target)
{
struct thread *thread = target_to_thread(target);
- struct pdbg_target *core;
+ struct pdbg_target *parent;
uint64_t spattn;
if (pdbg_target_compatible(target, "ibm,power8-thread")) {
return true; /* XXX */
} else if (pdbg_target_compatible(target, "ibm,power9-thread")) {
- core = pdbg_target_require_parent("core", target);
- if (pib_read(core, P9_SPATTN, &spattn)) {
+ parent = pdbg_target_require_parent("core", target);
+ if (pib_read(parent, P9_SPATTN, &spattn)) {
PR_ERROR("SPATTN read failed\n");
return false;
}
+ /* XXX: does this need to use fc_id like P10? */
if (spattn & PPC_BIT(1 + 4*thread->id)) {
uint64_t mask = ~PPC_BIT(1 + 4*thread->id);
- if (pib_write(core, P9_SPATTN_AND, mask)) {
+ if (pib_write(parent, P9_SPATTN_AND, mask)) {
PR_ERROR("SPATTN clear failed\n");
return false;
}
return true;
}
+
} else if (pdbg_target_compatible(target, "ibm,power10-thread")) {
- core = pdbg_target_require_parent("core", target);
- if (pib_read(core, P10_SPATTN, &spattn)) {
+ struct core *core;
+
+ parent = pdbg_target_require_parent("core", target);
+ core = target_to_core(target);
+
+ if (pib_read(parent, P10_SPATTN, &spattn)) {
PR_ERROR("SPATTN read failed\n");
return false;
}
- if (spattn & PPC_BIT(1 + 4*thread->id)) {
- uint64_t mask = ~PPC_BIT(1 + 4*thread->id);
+ /* Workaround SPATTN being set in both small-core regs */
+ if (core->status.fused_core_mode &&
+ (spattn & PPC_BIT(1 + 4*(thread->fc_id ^ 1)))) {
+ uint64_t mask = ~PPC_BIT(1 + 4*(thread->fc_id ^ 1));
+
+ if (pib_write(parent, P10_SPATTN_AND, mask)) {
+ PR_ERROR("SPATTN clear failed\n");
+ return false;
+ }
+ }
+
+ if (spattn & PPC_BIT(1 + 4*thread->fc_id)) {
+ uint64_t mask = ~PPC_BIT(1 + 4*thread->fc_id);
- if (pib_write(core, P10_SPATTN_AND, mask)) {
+ if (pib_write(parent, P10_SPATTN_AND, mask)) {
PR_ERROR("SPATTN clear failed\n");
return false;
}
--
2.35.1
More information about the Pdbg
mailing list