From ef4e87b45b96cce65dc26e3bfb67332c3d4d54e1 Mon Sep 17 00:00:00 2001 From: Ionela Voinescu Date: Wed, 18 Feb 2015 13:32:28 +0000 Subject: [PATCH] arch/mips: simplify cache operations Cache operations are simplified by removing assembly implementation and replacing it with simpler C code. BUG=chrome-os-partner:31438 TEST=tested on Pistachio bring up board; caches are properly invalidated; BRANCH=none Change-Id: I0f092660549c368e98c208ae0c991fe6f5a428d7 Signed-off-by: Patrick Georgi Original-Commit-Id: bf99849e75813cba865b15af9e110687816e61e4 Original-Change-Id: I965e7929718424f92f3556369d36a18ef67aa0d0 Original-Signed-off-by: Ionela Voinescu Original-Reviewed-on: https://chromium-review.googlesource.com/250792 Original-Reviewed-by: David Hendricks Reviewed-on: http://review.coreboot.org/9820 Tested-by: build bot (Jenkins) Reviewed-by: Stefan Reinauer --- src/arch/mips/cache.c | 73 ++++++++++++------------------ src/arch/mips/include/arch/cache.h | 4 -- src/arch/mips/include/arch/cpu.h | 7 +++ 3 files changed, 35 insertions(+), 49 deletions(-) diff --git a/src/arch/mips/cache.c b/src/arch/mips/cache.c index cfdae510b6..0347619fc6 100644 --- a/src/arch/mips/cache.c +++ b/src/arch/mips/cache.c @@ -18,46 +18,9 @@ */ #include -#include +#include #include - -/* Cache operations */ - -/* - * __get_line_size: - * Read config register - * Isolate instruction cache line size - * Interpret value as per MIPS manual: 2 << value - * Return cache line size - */ -#define __get_line_size(cfg_no, cfg_sel, lshift, nobits) \ -({ int __res; \ - __asm__ __volatile__( \ - ".set push\n\t" \ - ".set noreorder\n\t" \ - ".set mips32\n\t" \ - "mfc0 $t5, "#cfg_no"," #cfg_sel"\n\t" \ - ".set mips0\n\t" \ - "ext $t6, $t5," #lshift"," #nobits"\n\t" \ - "li $t7, 2\n\t" \ - "sllv %0, $t7, $t6\n\t" \ - ".set pop\n\t" \ - : "=r" (__res)); \ - __res; \ -}) - -/* clear_L2tag: clear L23Tag register */ -#define clear_L2tag() \ -({ \ - __asm__ __volatile__( \ - ".set push\n\t" \ - ".set noreorder\n\t" \ - ".set mips32\n\t" \ - "mtc0 $zero, $28, 4\n\t" \ - ".set mips0\n\t" \ - ".set pop\n\t" \ - ); \ -}) +#include /* cache_op: issues cache operation for specified address */ #define cache_op(op, addr) \ @@ -73,12 +36,32 @@ : "i" (op), "R" (*(unsigned char *)(addr))); \ }) -static int get_cache_line(uint8_t type) +#define MIPS_CONFIG1_DL_SHIFT 10 +#define MIPS_CONFIG1_DL_MASK (0x00000007) +#define MIPS_CONFIG1_IL_SHIFT 19 +#define MIPS_CONFIG1_IL_MASK (0x00000007) +#define MIPS_CONFIG2_SL_SHIFT 4 +#define MIPS_CONFIG2_SL_MASK (0x0000000F) + +/* + * get_cache_line_size: + * Read config register + * Isolate instruction cache line size + * Interpret value as per MIPS manual: 2 << value + * Return cache line size + */ +static int get_cache_line_size(uint8_t type) { switch (type) { - case ICACHE: return get_icache_line(); - case DCACHE: return get_dcache_line(); - case L2CACHE: return get_L2cache_line(); + case ICACHE: + return 2 << ((read_c0_config1() >> MIPS_CONFIG1_IL_SHIFT) & + MIPS_CONFIG1_IL_MASK); + case DCACHE: + return 2 << ((read_c0_config1() >> MIPS_CONFIG1_DL_SHIFT) & + MIPS_CONFIG1_DL_MASK); + case L2CACHE: + return 2 << ((read_c0_config2() >> MIPS_CONFIG2_SL_SHIFT) & + MIPS_CONFIG2_SL_MASK); default: printk(BIOS_ERR, "%s: Error: unsupported cache type.\n", __func__); @@ -92,7 +75,7 @@ void perform_cache_operation(uintptr_t start, size_t size, uint8_t operation) u32 line_size, line_mask; uintptr_t end; - line_size = get_cache_line((operation >> CACHE_TYPE_SHIFT) & + line_size = get_cache_line_size((operation >> CACHE_TYPE_SHIFT) & CACHE_TYPE_MASK); if (!line_size) return; @@ -100,7 +83,7 @@ void perform_cache_operation(uintptr_t start, size_t size, uint8_t operation) end = (start + (line_size - 1) + size) & line_mask; start &= line_mask; if ((operation & L2CACHE) == L2CACHE) - clear_L2tag(); + write_c0_l23taglo(0); while (start < end) { switch (operation) { case CACHE_CODE(ICACHE, WB_INVD): diff --git a/src/arch/mips/include/arch/cache.h b/src/arch/mips/include/arch/cache.h index 907505981b..3b89632dcd 100644 --- a/src/arch/mips/include/arch/cache.h +++ b/src/arch/mips/include/arch/cache.h @@ -23,10 +23,6 @@ #include #include -#define get_icache_line() __get_line_size($16, 1, 19, 3) -#define get_dcache_line() __get_line_size($16, 1, 10, 3) -#define get_L2cache_line() __get_line_size($16, 2, 4, 4) - #define CACHE_TYPE_SHIFT (0) #define CACHE_OP_SHIFT (2) #define CACHE_TYPE_MASK (0x3) diff --git a/src/arch/mips/include/arch/cpu.h b/src/arch/mips/include/arch/cpu.h index 957e427e73..e04621420e 100644 --- a/src/arch/mips/include/arch/cpu.h +++ b/src/arch/mips/include/arch/cpu.h @@ -106,6 +106,13 @@ do { \ #define read_c0_config1() __read_32bit_c0_register($16, 1) #define write_c0_config1(val) __write_32bit_c0_register($16, 1, (val)) +#define read_c0_config2() __read_32bit_c0_register($16, 2) +#define write_c0_config2(val) __write_32bit_c0_register($16, 2, (val)) + +#define read_c0_l23taglo() __read_32bit_c0_register($28, 4) +#define write_c0_l23taglo(val) __write_32bit_c0_register($28, 4, (val)) + + #define C0_ENTRYLO_PFN_SHIFT 6 #define C0_ENTRYLO_WB (0x3 << 3) /* Cacheable, write-back, non-coherent */ #define C0_ENTRYLO_D (0x1 << 2) /* Writeable */