[Skiboot] [PATCH] cpu: Fix HID SPR icache flushing and attn change sequence

Nicholas Piggin npiggin at gmail.com
Sat May 28 00:21:48 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>
---
 core/cpu.c          | 22 ++++++++++++++++++++++
 include/processor.h |  6 ++++--
 2 files changed, 26 insertions(+), 2 deletions(-)

diff --git a/core/cpu.c b/core/cpu.c
index f0be5805..48ee1a5c 100644
--- a/core/cpu.c
+++ b/core/cpu.c
@@ -38,6 +38,7 @@ static struct lock reinit_lock = LOCK_UNLOCKED;
 static bool radix_supported;
 static unsigned long hid0_hile;
 static unsigned long hid0_attn;
+static unsigned long hid0_icache;
 static bool reconfigure_idle = false;
 static bool sreset_enabled;
 static bool ipi_enabled;
@@ -969,6 +970,16 @@ static void enable_attn(void)
 	hid0 = mfspr(SPR_HID0);
 	hid0 |= hid0_attn;
 	set_hid0(hid0);
+	if (hid0_icache) {
+		if (hid0 & hid0_icache) {
+			prlog(PR_WARNING, "enable_attn found hid0_cache bit set unexpectedly\n");
+			hid0 &= ~hid0_icache;
+		}
+		/* icache is flushed on hid0_icache 0->1 */
+		set_hid0(hid0 | hid0_icache);
+		set_hid0(hid0);
+	}
+
 }
 
 static void disable_attn(void)
@@ -978,6 +989,15 @@ static void disable_attn(void)
 	hid0 = mfspr(SPR_HID0);
 	hid0 &= ~hid0_attn;
 	set_hid0(hid0);
+	if (hid0_icache) {
+		if (hid0 & hid0_icache) {
+			prlog(PR_WARNING, "disable_attn found hid0_cache bit set unexpectedly\n");
+			hid0 &= ~hid0_icache;
+		}
+		/* icache is flushed on hid0_icache 0->1 */
+		set_hid0(hid0 | hid0_icache);
+		set_hid0(hid0);
+	}
 }
 
 extern void __trigger_attn(void);
@@ -1027,12 +1047,14 @@ void init_boot_cpu(void)
 		radix_supported = true;
 		hid0_hile = SPR_HID0_POWER9_HILE;
 		hid0_attn = SPR_HID0_POWER9_ENABLE_ATTN;
+		hid0_icache = SPR_HID0_POWER9_FLUSH_ICACHE;
 		break;
 	case PVR_TYPE_P10:
 		proc_gen = proc_gen_p10;
 		radix_supported = true;
 		hid0_hile = SPR_HID0_POWER10_HILE;
 		hid0_attn = SPR_HID0_POWER10_ENABLE_ATTN;
+		hid0_icache = SPR_HID0_POWER10_FLUSH_ICACHE;
 		break;
 	default:
 		proc_gen = proc_gen_unknown;
diff --git a/include/processor.h b/include/processor.h
index 7a9c4999..5e5bd9a5 100644
--- a/include/processor.h
+++ b/include/processor.h
@@ -187,8 +187,10 @@
 #define SPR_HID0_POWER9_HILE		PPC_BIT(4)
 #define SPR_HID0_POWER10_HILE		PPC_BIT(4)
 #define SPR_HID0_POWER8_ENABLE_ATTN	PPC_BIT(31)
-#define SPR_HID0_POWER9_ENABLE_ATTN	(PPC_BIT(2) | PPC_BIT(3))
-#define SPR_HID0_POWER10_ENABLE_ATTN	(PPC_BIT(2) | PPC_BIT(3))
+#define SPR_HID0_POWER9_ENABLE_ATTN	PPC_BIT(3)
+#define SPR_HID0_POWER10_ENABLE_ATTN	PPC_BIT(3)
+#define SPR_HID0_POWER9_FLUSH_ICACHE	PPC_BIT(2)
+#define SPR_HID0_POWER10_FLUSH_ICACHE	PPC_BIT(2)
 #define SPR_HID0_POWER9_RADIX		PPC_BIT(8)
 
 /* PVR bits */
-- 
2.35.1



More information about the Skiboot mailing list