blob: e2e1da050503af07cd5d078ff5ad9f4de3f74e2c [file] [log] [blame]
wdenkbb1b8262003-03-27 12:09:35 +00001/*
2 * Cache-handling routined for MIPS 4K CPUs
3 *
4 * Copyright (c) 2003 Wolfgang Denk <wd@denx.de>
5 *
6 * See file CREDITS for list of people who contributed to this
7 * project.
8 *
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License as
11 * published by the Free Software Foundation; either version 2 of
12 * the License, or (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
22 * MA 02111-1307 USA
23 */
24
wdenkbb1b8262003-03-27 12:09:35 +000025#include <config.h>
26#include <version.h>
Shinya Kuribayashi06222122008-03-25 21:30:06 +090027#include <asm/asm.h>
wdenkbb1b8262003-03-27 12:09:35 +000028#include <asm/regdef.h>
29#include <asm/mipsregs.h>
30#include <asm/addrspace.h>
31#include <asm/cacheops.h>
32
wdenkbb1b8262003-03-27 12:09:35 +000033 /* 16KB is the maximum size of instruction and data caches on
34 * MIPS 4K.
35 */
36#define MIPS_MAX_CACHE_SIZE 0x4000
37
wdenkbb1b8262003-03-27 12:09:35 +000038/*
39 * cacheop macro to automate cache operations
40 * first some helpers...
41 */
42#define _mincache(size, maxsize) \
43 bltu size,maxsize,9f ; \
44 move size,maxsize ; \
459:
46
47#define _align(minaddr, maxaddr, linesize) \
48 .set noat ; \
49 subu AT,linesize,1 ; \
50 not AT ; \
51 and minaddr,AT ; \
52 addu maxaddr,-1 ; \
53 and maxaddr,AT ; \
54 .set at
55
56/* general operations */
57#define doop1(op1) \
58 cache op1,0(a0)
59#define doop2(op1, op2) \
60 cache op1,0(a0) ; \
61 nop ; \
62 cache op2,0(a0)
63
64/* specials for cache initialisation */
65#define doop1lw(op1) \
66 lw zero,0(a0)
67#define doop1lw1(op1) \
68 cache op1,0(a0) ; \
69 lw zero,0(a0) ; \
70 cache op1,0(a0)
71#define doop121(op1,op2) \
72 cache op1,0(a0) ; \
73 nop; \
74 cache op2,0(a0) ; \
75 nop; \
76 cache op1,0(a0)
77
78#define _oploopn(minaddr, maxaddr, linesize, tag, ops) \
79 .set noreorder ; \
8010: doop##tag##ops ; \
81 bne minaddr,maxaddr,10b ; \
82 add minaddr,linesize ; \
83 .set reorder
84
85/* finally the cache operation macros */
86#define vcacheopn(kva, n, cacheSize, cacheLineSize, tag, ops) \
87 blez n,11f ; \
88 addu n,kva ; \
89 _align(kva, n, cacheLineSize) ; \
90 _oploopn(kva, n, cacheLineSize, tag, ops) ; \
9111:
92
93#define icacheopn(kva, n, cacheSize, cacheLineSize, tag, ops) \
94 _mincache(n, cacheSize); \
95 blez n,11f ; \
96 addu n,kva ; \
97 _align(kva, n, cacheLineSize) ; \
98 _oploopn(kva, n, cacheLineSize, tag, ops) ; \
9911:
100
101#define vcacheop(kva, n, cacheSize, cacheLineSize, op) \
102 vcacheopn(kva, n, cacheSize, cacheLineSize, 1, (op))
103
104#define icacheop(kva, n, cacheSize, cacheLineSize, op) \
105 icacheopn(kva, n, cacheSize, cacheLineSize, 1, (op))
106
107/*******************************************************************************
108*
109* mips_cache_reset - low level initialisation of the primary caches
110*
111* This routine initialises the primary caches to ensure that they
112* have good parity. It must be called by the ROM before any cached locations
113* are used to prevent the possibility of data with bad parity being written to
114* memory.
115* To initialise the instruction cache it is essential that a source of data
116* with good parity is available. This routine
117* will initialise an area of memory starting at location zero to be used as
118* a source of parity.
119*
120* RETURNS: N/A
121*
122*/
Shinya Kuribayashi06222122008-03-25 21:30:06 +0900123NESTED(mips_cache_reset, 0, ra)
wdenkbb1b8262003-03-27 12:09:35 +0000124 li t2, CFG_ICACHE_SIZE
125 li t3, CFG_DCACHE_SIZE
126 li t4, CFG_CACHELINE_SIZE
127 move t5, t4
128
wdenkbb1b8262003-03-27 12:09:35 +0000129 li v0, MIPS_MAX_CACHE_SIZE
130
131 /* Now clear that much memory starting from zero.
132 */
133
134 li a0, KSEG1
135 addu a1, a0, v0
Shinya Kuribayashic7faac52007-10-27 15:27:06 +09001362:
137 sw zero, 0(a0)
wdenkbb1b8262003-03-27 12:09:35 +0000138 sw zero, 4(a0)
139 sw zero, 8(a0)
140 sw zero, 12(a0)
141 sw zero, 16(a0)
142 sw zero, 20(a0)
143 sw zero, 24(a0)
144 sw zero, 28(a0)
145 addu a0, 32
146 bltu a0, a1, 2b
wdenk57b2d802003-06-27 21:31:46 +0000147
wdenkbb1b8262003-03-27 12:09:35 +0000148 /* Set invalid tag.
149 */
150
151 mtc0 zero, CP0_TAGLO
152
Shinya Kuribayashic7faac52007-10-27 15:27:06 +0900153 /*
154 * The caches are probably in an indeterminate state,
155 * so we force good parity into them by doing an
156 * invalidate, load/fill, invalidate for each line.
157 */
wdenkbb1b8262003-03-27 12:09:35 +0000158
159 /* Assume bottom of RAM will generate good parity for the cache.
160 */
161
162 li a0, K0BASE
163 move a2, t2 # icacheSize
164 move a3, t4 # icacheLineSize
165 move a1, a2
166 icacheopn(a0,a1,a2,a3,121,(Index_Store_Tag_I,Fill))
167
168 /* To support Orion/R4600, we initialise the data cache in 3 passes.
169 */
170
171 /* 1: initialise dcache tags.
172 */
173
174 li a0, K0BASE
175 move a2, t3 # dcacheSize
176 move a3, t5 # dcacheLineSize
177 move a1, a2
178 icacheop(a0,a1,a2,a3,Index_Store_Tag_D)
179
180 /* 2: fill dcache.
181 */
182
183 li a0, K0BASE
184 move a2, t3 # dcacheSize
185 move a3, t5 # dcacheLineSize
186 move a1, a2
187 icacheopn(a0,a1,a2,a3,1lw,(dummy))
188
189 /* 3: clear dcache tags.
190 */
191
192 li a0, K0BASE
193 move a2, t3 # dcacheSize
194 move a3, t5 # dcacheLineSize
195 move a1, a2
196 icacheop(a0,a1,a2,a3,Index_Store_Tag_D)
197
Shinya Kuribayashic7faac52007-10-27 15:27:06 +0900198 j ra
Shinya Kuribayashi06222122008-03-25 21:30:06 +0900199 END(mips_cache_reset)
wdenkbb1b8262003-03-27 12:09:35 +0000200
201/*******************************************************************************
202*
203* dcache_status - get cache status
204*
205* RETURNS: 0 - cache disabled; 1 - cache enabled
206*
207*/
Shinya Kuribayashi06222122008-03-25 21:30:06 +0900208LEAF(dcache_status)
wdenkbb1b8262003-03-27 12:09:35 +0000209 mfc0 v0, CP0_CONFIG
210 andi v0, v0, 1
211 j ra
Shinya Kuribayashi06222122008-03-25 21:30:06 +0900212 END(dcache_status)
wdenkbb1b8262003-03-27 12:09:35 +0000213
214/*******************************************************************************
215*
216* dcache_disable - disable cache
217*
218* RETURNS: N/A
219*
220*/
Shinya Kuribayashi06222122008-03-25 21:30:06 +0900221LEAF(dcache_disable)
wdenkbb1b8262003-03-27 12:09:35 +0000222 mfc0 t0, CP0_CONFIG
223 li t1, -8
224 and t0, t0, t1
225 ori t0, t0, CONF_CM_UNCACHED
Shinya Kuribayashic7faac52007-10-27 15:27:06 +0900226 mtc0 t0, CP0_CONFIG
wdenkbb1b8262003-03-27 12:09:35 +0000227 j ra
Shinya Kuribayashi06222122008-03-25 21:30:06 +0900228 END(dcache_disable)
wdenkbb1b8262003-03-27 12:09:35 +0000229
Shinya Kuribayashib8275892008-03-25 11:39:29 +0900230#ifdef CFG_INIT_RAM_LOCK_MIPS
wdenkbb1b8262003-03-27 12:09:35 +0000231/*******************************************************************************
232*
233* mips_cache_lock - lock RAM area pointed to by a0 in cache.
234*
235* RETURNS: N/A
236*
237*/
wdenk9b7f3842003-10-09 20:09:04 +0000238#if defined(CONFIG_PURPLE)
wdenka6db71d2003-04-08 23:25:21 +0000239# define CACHE_LOCK_SIZE (CFG_DCACHE_SIZE/2)
wdenk9b7f3842003-10-09 20:09:04 +0000240#else
241# define CACHE_LOCK_SIZE (CFG_DCACHE_SIZE)
wdenka6db71d2003-04-08 23:25:21 +0000242#endif
wdenkbb1b8262003-03-27 12:09:35 +0000243 .globl mips_cache_lock
244 .ent mips_cache_lock
245mips_cache_lock:
wdenka6db71d2003-04-08 23:25:21 +0000246 li a1, K0BASE - CACHE_LOCK_SIZE
wdenkbb1b8262003-03-27 12:09:35 +0000247 addu a0, a1
wdenka6db71d2003-04-08 23:25:21 +0000248 li a2, CACHE_LOCK_SIZE
wdenkbb1b8262003-03-27 12:09:35 +0000249 li a3, CFG_CACHELINE_SIZE
250 move a1, a2
251 icacheop(a0,a1,a2,a3,0x1d)
252
253 j ra
Shinya Kuribayashic7faac52007-10-27 15:27:06 +0900254
wdenkbb1b8262003-03-27 12:09:35 +0000255 .end mips_cache_lock
Shinya Kuribayashib8275892008-03-25 11:39:29 +0900256#endif /* CFG_INIT_RAM_LOCK_MIPS */