From 6ad7513e03952c32650988d2a825f4f1661d5ee9 Mon Sep 17 00:00:00 2001 From: David Milosevic Date: Thu, 16 Nov 2023 21:29:09 +0100 Subject: arch/arm64: Extend cache helper functions This patch extends the cpu_get_cache_info function, so that additional information like size of cache lines can be retrieved. Patch was tested against the qemu-sbsa mainboard. Change-Id: If6fe731dc67ffeaff9344d2bd2627f45185c27de Signed-off-by: David Milosevic Reviewed-on: https://review.coreboot.org/c/coreboot/+/79106 Reviewed-by: Benjamin Doron Reviewed-by: Maximilian Brune Tested-by: build bot (Jenkins) Reviewed-by: Angel Pons --- src/arch/arm64/armv8/cache.c | 29 ++++++++++++++++++----------- src/arch/arm64/include/armv8/arch/cache.h | 10 +++++++++- 2 files changed, 27 insertions(+), 12 deletions(-) (limited to 'src/arch/arm64') diff --git a/src/arch/arm64/armv8/cache.c b/src/arch/arm64/armv8/cache.c index 879ef6297b..f843ed4b61 100644 --- a/src/arch/arm64/armv8/cache.c +++ b/src/arch/arm64/armv8/cache.c @@ -46,27 +46,34 @@ static uint64_t get_ccsidr_el1_numsets(uint64_t ccsidr_el1) } } -void cpu_get_cache_info(enum cache_level level, enum cache_type type, size_t *cache_size, size_t *assoc) +enum cb_err cpu_get_cache_info(const enum cache_level level, const enum cache_type type, + struct cache_info *info) { uint64_t ccsidr_el1; - if (cache_size == NULL || assoc == NULL) - return; + if (info == NULL || level < CACHE_L1 || level > CACHE_L7) + return CB_ERR_ARG; - if (level < CACHE_L1 || level > CACHE_L7) - return; - - /* [0] - Indicates instruction cache; [3:1] - Indicates cache level */ + /* + * select target cache. + * [0] - Indicates instruction cache [3:1] - Indicates cache level + */ raw_write_csselr_el1(((level - 1) << 1) | (type == CACHE_INSTRUCTION)); ccsidr_el1 = raw_read_ccsidr_el1(); /* [2:0] - Indicates (Log2(Number of bytes in cache line) - 4) */ - uint8_t line_length = 1 << ((ccsidr_el1 & 0x7) + 4); + info->line_bytes = (1 << ((ccsidr_el1 & 0x7) + 4)); + /* (Number of sets in cache) - 1 */ - uint64_t num_sets = get_ccsidr_el1_numsets(ccsidr_el1) + 1; + info->numsets = get_ccsidr_el1_numsets(ccsidr_el1) + 1; + /* (Associativity of cache) - 1 */ - *assoc = get_ccsidr_el1_assoc(ccsidr_el1) + 1; - *cache_size = line_length * *assoc * num_sets; + info->associativity = get_ccsidr_el1_assoc(ccsidr_el1) + 1; + + /* computed size of cache in bytes */ + info->size = info->line_bytes * info->associativity * info->numsets; + + return CB_SUCCESS; } unsigned int dcache_line_bytes(void) diff --git a/src/arch/arm64/include/armv8/arch/cache.h b/src/arch/arm64/include/armv8/arch/cache.h index 5097196308..da6edfdcb7 100644 --- a/src/arch/arm64/include/armv8/arch/cache.h +++ b/src/arch/arm64/include/armv8/arch/cache.h @@ -31,8 +31,16 @@ enum cache_type { CACHE_UNIFIED = 4, }; +struct cache_info { + uint64_t size; // total size of cache in bytes + uint64_t associativity; // number of cache lines in a set + uint64_t numsets; // number of sets in a cache + uint8_t line_bytes; // size of cache line in bytes +}; + enum cache_type cpu_get_cache_type(enum cache_level level); -void cpu_get_cache_info(enum cache_level level, enum cache_type, size_t *cache_size, size_t *assoc); +enum cb_err cpu_get_cache_info(const enum cache_level level, const enum cache_type type, + struct cache_info *info); /* dcache clean by virtual address to PoC */ void dcache_clean_by_mva(void const *addr, size_t len); -- cgit v1.2.3