1/* 2 * Cache-handling routined for MIPS CPUs 3 * 4 * Copyright (c) 2003 Wolfgang Denk <wd@denx.de> 5 * 6 * SPDX-License-Identifier: GPL-2.0+ 7 */ 8 9#include <asm-offsets.h> 10#include <config.h> 11#include <asm/asm.h> 12#include <asm/regdef.h> 13#include <asm/mipsregs.h> 14#include <asm/addrspace.h> 15#include <asm/cacheops.h> 16 17#ifndef CONFIG_SYS_MIPS_CACHE_MODE 18#define CONFIG_SYS_MIPS_CACHE_MODE CONF_CM_CACHABLE_NONCOHERENT 19#endif 20 21#define INDEX_BASE CKSEG0 22 23 .macro f_fill64 dst, offset, val 24 LONG_S \val, (\offset + 0 * LONGSIZE)(\dst) 25 LONG_S \val, (\offset + 1 * LONGSIZE)(\dst) 26 LONG_S \val, (\offset + 2 * LONGSIZE)(\dst) 27 LONG_S \val, (\offset + 3 * LONGSIZE)(\dst) 28 LONG_S \val, (\offset + 4 * LONGSIZE)(\dst) 29 LONG_S \val, (\offset + 5 * LONGSIZE)(\dst) 30 LONG_S \val, (\offset + 6 * LONGSIZE)(\dst) 31 LONG_S \val, (\offset + 7 * LONGSIZE)(\dst) 32#if LONGSIZE == 4 33 LONG_S \val, (\offset + 8 * LONGSIZE)(\dst) 34 LONG_S \val, (\offset + 9 * LONGSIZE)(\dst) 35 LONG_S \val, (\offset + 10 * LONGSIZE)(\dst) 36 LONG_S \val, (\offset + 11 * LONGSIZE)(\dst) 37 LONG_S \val, (\offset + 12 * LONGSIZE)(\dst) 38 LONG_S \val, (\offset + 13 * LONGSIZE)(\dst) 39 LONG_S \val, (\offset + 14 * LONGSIZE)(\dst) 40 LONG_S \val, (\offset + 15 * LONGSIZE)(\dst) 41#endif 42 .endm 43 44 .macro cache_loop curr, end, line_sz, op 4510: cache \op, 0(\curr) 46 PTR_ADDU \curr, \curr, \line_sz 47 bne \curr, \end, 10b 48 .endm 49 50 .macro l1_info sz, line_sz, off 51 .set push 52 .set noat 53 54 mfc0 $1, CP0_CONFIG, 1 55 56 /* detect line size */ 57 srl \line_sz, $1, \off + MIPS_CONF1_DL_SHF - MIPS_CONF1_DA_SHF 58 andi \line_sz, \line_sz, (MIPS_CONF1_DL >> MIPS_CONF1_DL_SHF) 59 move \sz, zero 60 beqz \line_sz, 10f 61 li \sz, 2 62 sllv \line_sz, \sz, \line_sz 63 64 /* detect associativity */ 65 srl \sz, $1, \off + MIPS_CONF1_DA_SHF - MIPS_CONF1_DA_SHF 66 andi \sz, \sz, (MIPS_CONF1_DA >> MIPS_CONF1_DA_SHF) 67 addiu \sz, \sz, 1 68 69 /* sz *= line_sz */ 70 mul \sz, \sz, \line_sz 71 72 /* detect log32(sets) */ 73 srl $1, $1, \off + MIPS_CONF1_DS_SHF - MIPS_CONF1_DA_SHF 74 andi $1, $1, (MIPS_CONF1_DS >> MIPS_CONF1_DS_SHF) 75 addiu $1, $1, 1 76 andi $1, $1, 0x7 77 78 /* sz <<= log32(sets) */ 79 sllv \sz, \sz, $1 80 81 /* sz *= 32 */ 82 li $1, 32 83 mul \sz, \sz, $1 8410: 85 .set pop 86 .endm 87/* 88 * mips_cache_reset - low level initialisation of the primary caches 89 * 90 * This routine initialises the primary caches to ensure that they have good 91 * parity. It must be called by the ROM before any cached locations are used 92 * to prevent the possibility of data with bad parity being written to memory. 93 * 94 * To initialise the instruction cache it is essential that a source of data 95 * with good parity is available. This routine will initialise an area of 96 * memory starting at location zero to be used as a source of parity. 97 * 98 * RETURNS: N/A 99 * 100 */ 101#define R_IC_SIZE t2 102#define R_IC_LINE t8 103#define R_DC_SIZE t3 104#define R_DC_LINE t9 105LEAF(mips_cache_reset) 106#ifndef CONFIG_SYS_CACHE_SIZE_AUTO 107 li R_IC_SIZE, CONFIG_SYS_ICACHE_SIZE 108 li R_IC_LINE, CONFIG_SYS_ICACHE_LINE_SIZE 109#else 110 l1_info R_IC_SIZE, R_IC_LINE, MIPS_CONF1_IA_SHF 111#endif 112 113#ifndef CONFIG_SYS_CACHE_SIZE_AUTO 114 li R_DC_SIZE, CONFIG_SYS_DCACHE_SIZE 115 li R_DC_LINE, CONFIG_SYS_DCACHE_LINE_SIZE 116#else 117 l1_info R_DC_SIZE, R_DC_LINE, MIPS_CONF1_DA_SHF 118#endif 119 120#ifdef CONFIG_SYS_MIPS_CACHE_INIT_RAM_LOAD 121 122 /* Determine the largest L1 cache size */ 123#ifndef CONFIG_SYS_CACHE_SIZE_AUTO 124#if CONFIG_SYS_ICACHE_SIZE > CONFIG_SYS_DCACHE_SIZE 125 li v0, CONFIG_SYS_ICACHE_SIZE 126#else 127 li v0, CONFIG_SYS_DCACHE_SIZE 128#endif 129#else 130 move v0, R_IC_SIZE 131 sltu t1, R_IC_SIZE, R_DC_SIZE 132 movn v0, R_DC_SIZE, t1 133#endif 134 /* 135 * Now clear that much memory starting from zero. 136 */ 137 PTR_LI a0, CKSEG1 138 PTR_ADDU a1, a0, v0 1392: PTR_ADDIU a0, 64 140 f_fill64 a0, -64, zero 141 bne a0, a1, 2b 142 143#endif /* CONFIG_SYS_MIPS_CACHE_INIT_RAM_LOAD */ 144 145 /* 146 * The TagLo registers used depend upon the CPU implementation, but the 147 * architecture requires that it is safe for software to write to both 148 * TagLo selects 0 & 2 covering supported cases. 149 */ 150 mtc0 zero, CP0_TAGLO 151 mtc0 zero, CP0_TAGLO, 2 152 153 /* 154 * The caches are probably in an indeterminate state, so we force good 155 * parity into them by doing an invalidate for each line. If 156 * CONFIG_SYS_MIPS_CACHE_INIT_RAM_LOAD is set then we'll proceed to 157 * perform a load/fill & a further invalidate for each line, assuming 158 * that the bottom of RAM (having just been cleared) will generate good 159 * parity for the cache. 160 */ 161 162 /* 163 * Initialize the I-cache first, 164 */ 165 blez R_IC_SIZE, 1f 166 PTR_LI t0, INDEX_BASE 167 PTR_ADDU t1, t0, R_IC_SIZE 168 /* clear tag to invalidate */ 169 cache_loop t0, t1, R_IC_LINE, INDEX_STORE_TAG_I 170#ifdef CONFIG_SYS_MIPS_CACHE_INIT_RAM_LOAD 171 /* fill once, so data field parity is correct */ 172 PTR_LI t0, INDEX_BASE 173 cache_loop t0, t1, R_IC_LINE, FILL 174 /* invalidate again - prudent but not strictly neccessary */ 175 PTR_LI t0, INDEX_BASE 176 cache_loop t0, t1, R_IC_LINE, INDEX_STORE_TAG_I 177#endif 178 179 /* Enable use of the I-cache by setting Config.K0 */ 180 sync 181 mfc0 t0, CP0_CONFIG 182 li t1, CONFIG_SYS_MIPS_CACHE_MODE 183#if __mips_isa_rev >= 2 184 ins t0, t1, 0, 3 185#else 186 ori t0, t0, CONF_CM_CMASK 187 xori t0, t0, CONF_CM_CMASK 188 or t0, t0, t1 189#endif 190 mtc0 t0, CP0_CONFIG 191 192 /* 193 * then initialize D-cache. 194 */ 1951: blez R_DC_SIZE, 3f 196 PTR_LI t0, INDEX_BASE 197 PTR_ADDU t1, t0, R_DC_SIZE 198 /* clear all tags */ 199 cache_loop t0, t1, R_DC_LINE, INDEX_STORE_TAG_D 200#ifdef CONFIG_SYS_MIPS_CACHE_INIT_RAM_LOAD 201 /* load from each line (in cached space) */ 202 PTR_LI t0, INDEX_BASE 2032: LONG_L zero, 0(t0) 204 PTR_ADDU t0, R_DC_LINE 205 bne t0, t1, 2b 206 /* clear all tags */ 207 PTR_LI t0, INDEX_BASE 208 cache_loop t0, t1, R_DC_LINE, INDEX_STORE_TAG_D 209#endif 210 2113: jr ra 212 END(mips_cache_reset) 213 214/* 215 * dcache_status - get cache status 216 * 217 * RETURNS: 0 - cache disabled; 1 - cache enabled 218 * 219 */ 220LEAF(dcache_status) 221 mfc0 t0, CP0_CONFIG 222 li t1, CONF_CM_UNCACHED 223 andi t0, t0, CONF_CM_CMASK 224 move v0, zero 225 beq t0, t1, 2f 226 li v0, 1 2272: jr ra 228 END(dcache_status) 229 230/* 231 * dcache_disable - disable cache 232 * 233 * RETURNS: N/A 234 * 235 */ 236LEAF(dcache_disable) 237 mfc0 t0, CP0_CONFIG 238 li t1, -8 239 and t0, t0, t1 240 ori t0, t0, CONF_CM_UNCACHED 241 mtc0 t0, CP0_CONFIG 242 jr ra 243 END(dcache_disable) 244 245/* 246 * dcache_enable - enable cache 247 * 248 * RETURNS: N/A 249 * 250 */ 251LEAF(dcache_enable) 252 mfc0 t0, CP0_CONFIG 253 ori t0, CONF_CM_CMASK 254 xori t0, CONF_CM_CMASK 255 ori t0, CONFIG_SYS_MIPS_CACHE_MODE 256 mtc0 t0, CP0_CONFIG 257 jr ra 258 END(dcache_enable) 259