[Pdbg] [PATCH 02/10] gdbserver: Fix attn enable HID change icache flushing sequence

Nicholas Piggin npiggin at gmail.com
Tue May 31 19:14:49 AEST 2022


Changing the HID attn enable bit on POWER9 and POWER10 requires the
icache to be flushed *after* ATTN is changed. It is not clear that it
may be done at the same time, so move it to after the attn bit change.

Flushing the icache with HID requires a 0->1 edge and the bit does not
reset back to 0, so first write 1 then 0 ready for the next flush.

Signed-off-by: Nicholas Piggin <npiggin at gmail.com>
---
 src/pdbgproxy.c | 38 +++++++++++++++++++++++++++++++++-----
 1 file changed, 33 insertions(+), 5 deletions(-)

diff --git a/src/pdbgproxy.c b/src/pdbgproxy.c
index 13b72408..2d579a4a 100644
--- a/src/pdbgproxy.c
+++ b/src/pdbgproxy.c
@@ -303,6 +303,9 @@ static int thread_set_attn(struct pdbg_target *target, bool enable)
 				return 0;
 			hid &= ~POWER8_HID_ENABLE_ATTN;
 		}
+		if (thread_putspr(target, SPR_HID, hid))
+			return -1;
+
 	} else if (pdbg_target_compatible(target, "ibm,power9-thread")) {
 		if (enable) {
 			if (hid & POWER9_HID_ENABLE_ATTN)
@@ -314,7 +317,22 @@ static int thread_set_attn(struct pdbg_target *target, bool enable)
 				return 0;
 			hid &= ~POWER9_HID_ENABLE_ATTN;
 		}
-		hid |= POWER9_HID_FLUSH_ICACHE;
+
+		if (hid & POWER9_HID_FLUSH_ICACHE) {
+			PR_WARNING("set_attn found HID flush icache bit unexpectedly set\n");
+			hid &= ~POWER9_HID_FLUSH_ICACHE;
+		}
+
+		/* Change the ENABLE_ATTN bit in the register */
+		if (thread_putspr(target, SPR_HID, hid))
+			return -1;
+		/* FLUSH_ICACHE 0->1 to flush */
+		if (thread_putspr(target, SPR_HID, hid | POWER9_HID_FLUSH_ICACHE))
+			return -1;
+		/* Restore FLUSH_ICACHE back to 0 */
+		if (thread_putspr(target, SPR_HID, hid))
+			return -1;
+
 	} else if (pdbg_target_compatible(target, "ibm,power10-thread")) {
 		if (enable) {
 			if (hid & POWER10_HID_ENABLE_ATTN)
@@ -326,14 +344,24 @@ static int thread_set_attn(struct pdbg_target *target, bool enable)
 				return 0;
 			hid &= ~POWER10_HID_ENABLE_ATTN;
 		}
-		hid |= POWER10_HID_FLUSH_ICACHE;
+		if (hid & POWER10_HID_FLUSH_ICACHE) {
+			PR_WARNING("set_attn found HID flush icache bit unexpectedly set\n");
+			hid &= ~POWER10_HID_FLUSH_ICACHE;
+		}
+
+		/* Change the ENABLE_ATTN bit in the register */
+		if (thread_putspr(target, SPR_HID, hid))
+			return -1;
+		/* FLUSH_ICACHE 0->1 to flush */
+		if (thread_putspr(target, SPR_HID, hid | POWER10_HID_FLUSH_ICACHE))
+			return -1;
+		/* Restore FLUSH_ICACHE back to 0 */
+		if (thread_putspr(target, SPR_HID, hid))
+			return -1;
 	} else {
 		return -1;
 	}
 
-	if (thread_putspr(target, SPR_HID, hid))
-		return -1;
-
 	return 0;
 }
 
-- 
2.35.1



More information about the Pdbg mailing list