diff options
author | Ionela Voinescu <ionela.voinescu@imgtec.com> | 2015-02-18 13:32:28 +0000 |
---|---|---|
committer | Patrick Georgi <pgeorgi@google.com> | 2015-04-21 08:12:51 +0200 |
commit | ef4e87b45b96cce65dc26e3bfb67332c3d4d54e1 (patch) | |
tree | a8af9a13c3bd554d76a80014e88d4546c9484a65 /src | |
parent | 8cc3a2a467cf44f107a6049fc225d2ba9c85b639 (diff) |
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 <pgeorgi@chromium.org>
Original-Commit-Id: bf99849e75813cba865b15af9e110687816e61e4
Original-Change-Id: I965e7929718424f92f3556369d36a18ef67aa0d0
Original-Signed-off-by: Ionela Voinescu <ionela.voinescu@imgtec.com>
Original-Reviewed-on: https://chromium-review.googlesource.com/250792
Original-Reviewed-by: David Hendricks <dhendrix@chromium.org>
Reviewed-on: http://review.coreboot.org/9820
Tested-by: build bot (Jenkins)
Reviewed-by: Stefan Reinauer <stefan.reinauer@coreboot.org>
Diffstat (limited to 'src')
-rw-r--r-- | src/arch/mips/cache.c | 73 | ||||
-rw-r--r-- | src/arch/mips/include/arch/cache.h | 4 | ||||
-rw-r--r-- | 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 <arch/cache.h> -#include <symbols.h> +#include <arch/cpu.h> #include <console/console.h> - -/* 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 <symbols.h> /* 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 <stddef.h> #include <stdint.h> -#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 */ |