summaryrefslogtreecommitdiff
path: root/arch/mips/cpu/mips32/cache.S
diff options
context:
space:
mode:
authorPaul Burton <paul.burton@imgtec.com>2013-11-08 11:18:42 +0000
committerDaniel Schwierzeck <daniel.schwierzeck@gmail.com>2013-11-09 17:21:01 +0100
commitfa476f75bfff55772f0ebde3d5e02dc745e70f40 (patch)
tree083e3e4b6f2bf615ee073cdf6d0c25445113bd00 /arch/mips/cpu/mips32/cache.S
parent15c5cdf5aa6b292145e5e3e220ec1f42b11eff6f (diff)
downloadu-boot-imx-fa476f75bfff55772f0ebde3d5e02dc745e70f40.zip
u-boot-imx-fa476f75bfff55772f0ebde3d5e02dc745e70f40.tar.gz
u-boot-imx-fa476f75bfff55772f0ebde3d5e02dc745e70f40.tar.bz2
mips32: detect L1 cache sizes if they're not defined
For boards such as the MIPS Malta with an FPGA core card it is desirable to be able to detect the L1 cache sizes at runtime, since they are not dependant upon the board but on the FPGA bitstream in use. This patch performs that detection when the CONFIG_SYS_[DI]CACHE_SIZE macros are not defined by the board configuration. In cases where the sizes are detected this patch also removes the restriction that the I-cache & D-cache line sizes must be the same, as this is not necessarily true. If the cache sizes are defined by a configuration then they will be hardcoded as before, so this patch will not add overhead to such boards. Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Diffstat (limited to 'arch/mips/cpu/mips32/cache.S')
-rw-r--r--arch/mips/cpu/mips32/cache.S90
1 files changed, 77 insertions, 13 deletions
diff --git a/arch/mips/cpu/mips32/cache.S b/arch/mips/cpu/mips32/cache.S
index 12f656c..22bd844 100644
--- a/arch/mips/cpu/mips32/cache.S
+++ b/arch/mips/cpu/mips32/cache.S
@@ -20,15 +20,6 @@
#define RA t9
-/*
- * 16kB is the maximum size of instruction and data caches on MIPS 4K,
- * 64kB is on 4KE, 24K, 5K, etc. Set bigger size for convenience.
- *
- * Note that the above size is the maximum size of primary cache. U-Boot
- * doesn't have L2 cache support for now.
- */
-#define MIPS_MAX_CACHE_SIZE 0x10000
-
#define INDEX_BASE CKSEG0
.macro cache_op op addr
@@ -126,12 +117,85 @@ LEAF(mips_init_dcache)
*/
NESTED(mips_cache_reset, 0, ra)
move RA, ra
- li t2, CONFIG_SYS_ICACHE_SIZE
- li t3, CONFIG_SYS_DCACHE_SIZE
+
+#if !defined(CONFIG_SYS_ICACHE_SIZE) || !defined(CONFIG_SYS_DCACHE_SIZE) || \
+ !defined(CONFIG_SYS_CACHELINE_SIZE)
+ /* read Config1 for use below */
+ mfc0 t5, CP0_CONFIG, 1
+#endif
+
+#ifdef CONFIG_SYS_CACHELINE_SIZE
+ li t7, CONFIG_SYS_CACHELINE_SIZE
li t8, CONFIG_SYS_CACHELINE_SIZE
+#else
+ /* Detect I-cache line size. */
+ srl t8, t5, MIPS_CONF1_IL_SHIFT
+ andi t8, t8, (MIPS_CONF1_IL >> MIPS_CONF1_IL_SHIFT)
+ beqz t8, 1f
+ li t6, 2
+ sllv t8, t6, t8
- li v0, MIPS_MAX_CACHE_SIZE
+1: /* Detect D-cache line size. */
+ srl t7, t5, MIPS_CONF1_DL_SHIFT
+ andi t7, t7, (MIPS_CONF1_DL >> MIPS_CONF1_DL_SHIFT)
+ beqz t7, 1f
+ li t6, 2
+ sllv t7, t6, t7
+1:
+#endif
+#ifdef CONFIG_SYS_ICACHE_SIZE
+ li t2, CONFIG_SYS_ICACHE_SIZE
+#else
+ /* Detect I-cache size. */
+ srl t6, t5, MIPS_CONF1_IS_SHIFT
+ andi t6, t6, (MIPS_CONF1_IS >> MIPS_CONF1_IS_SHIFT)
+ li t4, 32
+ xori t2, t6, 0x7
+ beqz t2, 1f
+ addi t6, t6, 1
+ sllv t4, t4, t6
+1: /* At this point t4 == I-cache sets. */
+ mul t2, t4, t8
+ srl t6, t5, MIPS_CONF1_IA_SHIFT
+ andi t6, t6, (MIPS_CONF1_IA >> MIPS_CONF1_IA_SHIFT)
+ addi t6, t6, 1
+ /* At this point t6 == I-cache ways. */
+ mul t2, t2, t6
+#endif
+
+#ifdef CONFIG_SYS_DCACHE_SIZE
+ li t3, CONFIG_SYS_DCACHE_SIZE
+#else
+ /* Detect D-cache size. */
+ srl t6, t5, MIPS_CONF1_DS_SHIFT
+ andi t6, t6, (MIPS_CONF1_DS >> MIPS_CONF1_DS_SHIFT)
+ li t4, 32
+ xori t3, t6, 0x7
+ beqz t3, 1f
+ addi t6, t6, 1
+ sllv t4, t4, t6
+1: /* At this point t4 == I-cache sets. */
+ mul t3, t4, t7
+ srl t6, t5, MIPS_CONF1_DA_SHIFT
+ andi t6, t6, (MIPS_CONF1_DA >> MIPS_CONF1_DA_SHIFT)
+ addi t6, t6, 1
+ /* At this point t6 == I-cache ways. */
+ mul t3, t3, t6
+#endif
+
+ /* Determine the largest L1 cache size */
+#if defined(CONFIG_SYS_ICACHE_SIZE) && defined(CONFIG_SYS_DCACHE_SIZE)
+#if CONFIG_SYS_ICACHE_SIZE > CONFIG_SYS_DCACHE_SIZE
+ li v0, CONFIG_SYS_ICACHE_SIZE
+#else
+ li v0, CONFIG_SYS_DCACHE_SIZE
+#endif
+#else
+ move v0, t2
+ sltu t1, t2, t3
+ movn v0, t3, t1
+#endif
/*
* Now clear that much memory starting from zero.
*/
@@ -163,7 +227,7 @@ NESTED(mips_cache_reset, 0, ra)
* then initialize D-cache.
*/
move a1, t3
- move a2, t8
+ move a2, t7
PTR_LA v1, mips_init_dcache
jalr v1