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>
This commit is contained in:
parent
7971375287
commit
bdd50dc7d0
@ -70,7 +70,7 @@ static void sys_cache_info(int *isize, int *dsize)
|
|||||||
g_free(buf);
|
g_free(buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
#elif defined(__APPLE__)
|
#elif defined(CONFIG_DARWIN)
|
||||||
# include <sys/sysctl.h>
|
# include <sys/sysctl.h>
|
||||||
static void sys_cache_info(int *isize, int *dsize)
|
static void sys_cache_info(int *isize, int *dsize)
|
||||||
{
|
{
|
||||||
@ -117,11 +117,11 @@ static void sys_cache_info(int *isize, int *dsize)
|
|||||||
* Architecture (+ OS) specific cache detection mechanisms.
|
* 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)
|
static void arch_cache_info(int *isize, int *dsize)
|
||||||
{
|
{
|
||||||
if (*isize == 0 || *dsize == 0) {
|
|
||||||
uint64_t ctr;
|
uint64_t ctr;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -129,8 +129,13 @@ static void arch_cache_info(int *isize, int *dsize)
|
|||||||
* but (at least under Linux) these are marked protected by the
|
* but (at least under Linux) these are marked protected by the
|
||||||
* kernel. However, CTR_EL0 contains the minimum linesize in the
|
* kernel. However, CTR_EL0 contains the minimum linesize in the
|
||||||
* entire hierarchy, and is used by userspace cache flushing.
|
* 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));
|
asm volatile("mrs\t%0, ctr_el0" : "=r"(ctr));
|
||||||
|
save_ctr_el0 = ctr;
|
||||||
|
|
||||||
|
if (*isize == 0 || *dsize == 0) {
|
||||||
if (*isize == 0) {
|
if (*isize == 0) {
|
||||||
*isize = 4 << (ctr & 0xf);
|
*isize = 4 << (ctr & 0xf);
|
||||||
}
|
}
|
||||||
@ -228,17 +233,6 @@ void flush_idcache_range(uintptr_t rx, uintptr_t rw, size_t len)
|
|||||||
}
|
}
|
||||||
#else
|
#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
|
* This is a copy of gcc's __aarch64_sync_cache_range, modified
|
||||||
* to fit this three-operand interface.
|
* 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_IDC = 1u << 28;
|
||||||
const unsigned CTR_DIC = 1u << 29;
|
const unsigned CTR_DIC = 1u << 29;
|
||||||
const uint64_t ctr_el0 = save_ctr_el0;
|
const uint64_t ctr_el0 = save_ctr_el0;
|
||||||
const uintptr_t icache_lsize = 4 << extract64(ctr_el0, 0, 4);
|
const uintptr_t icache_lsize = qemu_icache_linesize;
|
||||||
const uintptr_t dcache_lsize = 4 << extract64(ctr_el0, 16, 4);
|
const uintptr_t dcache_lsize = qemu_dcache_linesize;
|
||||||
uintptr_t p;
|
uintptr_t p;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
Loading…
x
Reference in New Issue
Block a user