@@ -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;
}
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@gmail.com> --- src/pdbgproxy.c | 35 ++++++++++++++++++++++++++--------- 1 file changed, 26 insertions(+), 9 deletions(-)