summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorkettenis <kettenis@openbsd.org>2021-02-10 20:51:27 +0000
committerkettenis <kettenis@openbsd.org>2021-02-10 20:51:27 +0000
commitb2fd32ba746dfde4a07ff2fa1990bfa5287c11f8 (patch)
treea96eb627bec0025ee44d11b844e4c6f02f897ca7
parentIf pf changes the routing table when sending packets, the kernel (diff)
Add a instruction barrier between writing CCSELR_EL1 and reading CCSIDR_EL1
to guarantee that we read the cache parameters of the cache we just selected. The required ISB instruction is present in the examples in the ARM ARM. Fixes the the report on the cores in Apple's M1 SoC. ok patrick@
-rw-r--r--sys/arch/arm64/arm64/cpu.c5
1 files changed, 4 insertions, 1 deletions
diff --git a/sys/arch/arm64/arm64/cpu.c b/sys/arch/arm64/arm64/cpu.c
index e24e8518702..dc65e10a011 100644
--- a/sys/arch/arm64/arm64/cpu.c
+++ b/sys/arch/arm64/arm64/cpu.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: cpu.c,v 1.46 2021/01/29 08:48:19 jsg Exp $ */
+/* $OpenBSD: cpu.c,v 1.47 2021/02/10 20:51:27 kettenis Exp $ */
/*
* Copyright (c) 2016 Dale Rahn <drahn@dalerahn.com>
@@ -242,6 +242,7 @@ cpu_identify(struct cpu_info *ci)
if (clidr & CLIDR_CTYPE_INSN) {
WRITE_SPECIALREG(csselr_el1,
i << CSSELR_LEVEL_SHIFT | CSSELR_IND);
+ __asm volatile("isb");
ccsidr = READ_SPECIALREG(ccsidr_el1);
sets = CCSIDR_SETS(ccsidr);
ways = CCSIDR_WAYS(ccsidr);
@@ -254,6 +255,7 @@ cpu_identify(struct cpu_info *ci)
}
if (clidr & CLIDR_CTYPE_DATA) {
WRITE_SPECIALREG(csselr_el1, i << CSSELR_LEVEL_SHIFT);
+ __asm volatile("isb");
ccsidr = READ_SPECIALREG(ccsidr_el1);
sets = CCSIDR_SETS(ccsidr);
ways = CCSIDR_WAYS(ccsidr);
@@ -264,6 +266,7 @@ cpu_identify(struct cpu_info *ci)
}
if (clidr & CLIDR_CTYPE_UNIFIED) {
WRITE_SPECIALREG(csselr_el1, i << CSSELR_LEVEL_SHIFT);
+ __asm volatile("isb");
ccsidr = READ_SPECIALREG(ccsidr_el1);
sets = CCSIDR_SETS(ccsidr);
ways = CCSIDR_WAYS(ccsidr);