summaryrefslogtreecommitdiff
path: root/util
diff options
context:
space:
mode:
authorRichard Henderson <richard.henderson@linaro.org>2022-06-20 18:48:36 -0700
committerRichard Henderson <richard.henderson@linaro.org>2022-06-21 09:28:41 -0700
commitbdd50dc7d09c90525b80da4f056b849049893732 (patch)
tree342bfa05abb2c61caedaad36a4b6e9afd025f48a /util
parent79713752870c7d730d128b9158edb0c58b82fcf9 (diff)
util/cacheflush: Merge aarch64 ctr_el0 usage
Merge init_ctr_el0 into arch_cache_info. In flush_idcache_range, use the pre-computed line sizes from the global variables. Use CONFIG_DARWIN in preference to __APPLE__. Signed-off-by: Richard Henderson <richard.henderson@linaro.org> Reviewed-by: Peter Maydell <peter.maydell@linaro.org> Message-Id: <20220621014837.189139-3-richard.henderson@linaro.org>
Diffstat (limited to 'util')
-rw-r--r--util/cacheflush.c44
1 files changed, 19 insertions, 25 deletions
diff --git a/util/cacheflush.c b/util/cacheflush.c
index 8096afd33c..01b6cb7583 100644
--- a/util/cacheflush.c
+++ b/util/cacheflush.c
@@ -70,7 +70,7 @@ static void sys_cache_info(int *isize, int *dsize)
g_free(buf);
}
-#elif defined(__APPLE__)
+#elif defined(CONFIG_DARWIN)
# include <sys/sysctl.h>
static void sys_cache_info(int *isize, int *dsize)
{
@@ -117,20 +117,25 @@ static void sys_cache_info(int *isize, int *dsize)
* Architecture (+ OS) specific cache detection mechanisms.
*/
-#if defined(__aarch64__)
-
+#if defined(__aarch64__) && !defined(CONFIG_DARWIN)
+/* Apple does not expose CTR_EL0, so we must use system interfaces. */
+static uint64_t save_ctr_el0;
static void arch_cache_info(int *isize, int *dsize)
{
- if (*isize == 0 || *dsize == 0) {
- uint64_t ctr;
+ uint64_t ctr;
- /*
- * The real cache geometry is in CCSIDR_EL1/CLIDR_EL1/CSSELR_EL1,
- * but (at least under Linux) these are marked protected by the
- * kernel. However, CTR_EL0 contains the minimum linesize in the
- * entire hierarchy, and is used by userspace cache flushing.
- */
- asm volatile("mrs\t%0, ctr_el0" : "=r"(ctr));
+ /*
+ * The real cache geometry is in CCSIDR_EL1/CLIDR_EL1/CSSELR_EL1,
+ * but (at least under Linux) these are marked protected by the
+ * kernel. However, CTR_EL0 contains the minimum linesize in the
+ * entire hierarchy, and is used by userspace cache flushing.
+ *
+ * We will also use this value in flush_idcache_range.
+ */
+ asm volatile("mrs\t%0, ctr_el0" : "=r"(ctr));
+ save_ctr_el0 = ctr;
+
+ if (*isize == 0 || *dsize == 0) {
if (*isize == 0) {
*isize = 4 << (ctr & 0xf);
}
@@ -229,17 +234,6 @@ void flush_idcache_range(uintptr_t rx, uintptr_t rw, size_t len)
#else
/*
- * TODO: unify this with cacheinfo.c.
- * We want to save the whole contents of CTR_EL0, so that we
- * have more than the linesize, but also IDC and DIC.
- */
-static uint64_t save_ctr_el0;
-static void __attribute__((constructor)) init_ctr_el0(void)
-{
- asm volatile("mrs\t%0, ctr_el0" : "=r"(save_ctr_el0));
-}
-
-/*
* This is a copy of gcc's __aarch64_sync_cache_range, modified
* to fit this three-operand interface.
*/
@@ -248,8 +242,8 @@ void flush_idcache_range(uintptr_t rx, uintptr_t rw, size_t len)
const unsigned CTR_IDC = 1u << 28;
const unsigned CTR_DIC = 1u << 29;
const uint64_t ctr_el0 = save_ctr_el0;
- const uintptr_t icache_lsize = 4 << extract64(ctr_el0, 0, 4);
- const uintptr_t dcache_lsize = 4 << extract64(ctr_el0, 16, 4);
+ const uintptr_t icache_lsize = qemu_icache_linesize;
+ const uintptr_t dcache_lsize = qemu_dcache_linesize;
uintptr_t p;
/*