summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIonela Voinescu <ionela.voinescu@imgtec.com>2015-02-18 13:32:28 +0000
committerPatrick Georgi <pgeorgi@google.com>2015-04-21 08:12:51 +0200
commitef4e87b45b96cce65dc26e3bfb67332c3d4d54e1 (patch)
treea8af9a13c3bd554d76a80014e88d4546c9484a65
parent8cc3a2a467cf44f107a6049fc225d2ba9c85b639 (diff)
downloadcoreboot-ef4e87b45b96cce65dc26e3bfb67332c3d4d54e1.tar.xz
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>
-rw-r--r--src/arch/mips/cache.c73
-rw-r--r--src/arch/mips/include/arch/cache.h4
-rw-r--r--src/arch/mips/include/arch/cpu.h7
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 */