]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - arch/mips/cpu/mips32/cache.S
Merge branch 'master' of git://git.denx.de/u-boot-mips
[karo-tx-uboot.git] / arch / mips / cpu / mips32 / cache.S
1 /*
2  *  Cache-handling routined for MIPS 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
25 #include <asm-offsets.h>
26 #include <config.h>
27 #include <asm/asm.h>
28 #include <asm/regdef.h>
29 #include <asm/mipsregs.h>
30 #include <asm/addrspace.h>
31 #include <asm/cacheops.h>
32
33 #define RA              t8
34
35 /*
36  * 16kB is the maximum size of instruction and data caches on MIPS 4K,
37  * 64kB is on 4KE, 24K, 5K, etc. Set bigger size for convenience.
38  *
39  * Note that the above size is the maximum size of primary cache. U-Boot
40  * doesn't have L2 cache support for now.
41  */
42 #define MIPS_MAX_CACHE_SIZE     0x10000
43
44 #define INDEX_BASE      CKSEG0
45
46         .macro  cache_op op addr
47         .set    push
48         .set    noreorder
49         .set    mips3
50         cache   \op, 0(\addr)
51         .set    pop
52         .endm
53
54 /*
55  * cacheop macro to automate cache operations
56  * first some helpers...
57  */
58 #define _mincache(size, maxsize) \
59    bltu  size,maxsize,9f ; \
60    move  size,maxsize ;    \
61 9:
62
63 #define _align(minaddr, maxaddr, linesize) \
64    .set noat ; \
65    subu  AT,linesize,1 ;   \
66    not   AT ;        \
67    and   minaddr,AT ;      \
68    addu  maxaddr,-1 ;      \
69    and   maxaddr,AT ;      \
70    .set at
71
72 /* general operations */
73 #define doop1(op1) \
74    cache op1,0(a0)
75 #define doop2(op1, op2) \
76    cache op1,0(a0) ;    \
77    nop ;          \
78    cache op2,0(a0)
79
80 /* specials for cache initialisation */
81 #define doop1lw(op1) \
82    lw zero,0(a0)
83 #define doop1lw1(op1) \
84    cache op1,0(a0) ;    \
85    lw zero,0(a0) ;      \
86    cache op1,0(a0)
87 #define doop121(op1,op2) \
88    cache op1,0(a0) ;    \
89    nop;           \
90    cache op2,0(a0) ;    \
91    nop;           \
92    cache op1,0(a0)
93
94 #define _oploopn(minaddr, maxaddr, linesize, tag, ops) \
95    .set  noreorder ;    \
96 10:   doop##tag##ops ;  \
97    bne     minaddr,maxaddr,10b ; \
98    add      minaddr,linesize ;   \
99    .set  reorder
100
101 /* finally the cache operation macros */
102 #define vcacheopn(kva, n, cacheSize, cacheLineSize, tag, ops) \
103    blez  n,11f ;        \
104    addu  n,kva ;        \
105    _align(kva, n, cacheLineSize) ; \
106    _oploopn(kva, n, cacheLineSize, tag, ops) ; \
107 11:
108
109 #define icacheopn(kva, n, cacheSize, cacheLineSize, tag, ops) \
110    _mincache(n, cacheSize);   \
111    blez  n,11f ;        \
112    addu  n,kva ;        \
113    _align(kva, n, cacheLineSize) ; \
114    _oploopn(kva, n, cacheLineSize, tag, ops) ; \
115 11:
116
117 #define vcacheop(kva, n, cacheSize, cacheLineSize, op) \
118    vcacheopn(kva, n, cacheSize, cacheLineSize, 1, (op))
119
120 #define icacheop(kva, n, cacheSize, cacheLineSize, op) \
121    icacheopn(kva, n, cacheSize, cacheLineSize, 1, (op))
122
123         .macro  f_fill64 dst, offset, val
124         LONG_S  \val, (\offset +  0 * LONGSIZE)(\dst)
125         LONG_S  \val, (\offset +  1 * LONGSIZE)(\dst)
126         LONG_S  \val, (\offset +  2 * LONGSIZE)(\dst)
127         LONG_S  \val, (\offset +  3 * LONGSIZE)(\dst)
128         LONG_S  \val, (\offset +  4 * LONGSIZE)(\dst)
129         LONG_S  \val, (\offset +  5 * LONGSIZE)(\dst)
130         LONG_S  \val, (\offset +  6 * LONGSIZE)(\dst)
131         LONG_S  \val, (\offset +  7 * LONGSIZE)(\dst)
132 #if LONGSIZE == 4
133         LONG_S  \val, (\offset +  8 * LONGSIZE)(\dst)
134         LONG_S  \val, (\offset +  9 * LONGSIZE)(\dst)
135         LONG_S  \val, (\offset + 10 * LONGSIZE)(\dst)
136         LONG_S  \val, (\offset + 11 * LONGSIZE)(\dst)
137         LONG_S  \val, (\offset + 12 * LONGSIZE)(\dst)
138         LONG_S  \val, (\offset + 13 * LONGSIZE)(\dst)
139         LONG_S  \val, (\offset + 14 * LONGSIZE)(\dst)
140         LONG_S  \val, (\offset + 15 * LONGSIZE)(\dst)
141 #endif
142         .endm
143
144 /*
145  * mips_init_icache(uint PRId, ulong icache_size, unchar icache_linesz)
146  */
147 LEAF(mips_init_icache)
148         blez    a1, 9f
149         mtc0    zero, CP0_TAGLO
150         /* clear tag to invalidate */
151         PTR_LI          t0, INDEX_BASE
152         PTR_ADDU        t1, t0, a1
153 1:      cache_op        Index_Store_Tag_I t0
154         PTR_ADDU        t0, a2
155         bne             t0, t1, 1b
156         /* fill once, so data field parity is correct */
157         PTR_LI          t0, INDEX_BASE
158 2:      cache_op        Fill t0
159         PTR_ADDU        t0, a2
160         bne             t0, t1, 2b
161         /* invalidate again - prudent but not strictly neccessary */
162         PTR_LI          t0, INDEX_BASE
163 1:      cache_op        Index_Store_Tag_I t0
164         PTR_ADDU        t0, a2
165         bne             t0, t1, 1b
166 9:      jr      ra
167         END(mips_init_icache)
168
169 /*
170  * mips_init_dcache(uint PRId, ulong dcache_size, unchar dcache_linesz)
171  */
172 LEAF(mips_init_dcache)
173         blez    a1, 9f
174         mtc0    zero, CP0_TAGLO
175         /* clear all tags */
176         PTR_LI          t0, INDEX_BASE
177         PTR_ADDU        t1, t0, a1
178 1:      cache_op        Index_Store_Tag_D t0
179         PTR_ADDU        t0, a2
180         bne             t0, t1, 1b
181         /* load from each line (in cached space) */
182         PTR_LI          t0, INDEX_BASE
183 2:      LONG_L          zero, 0(t0)
184         PTR_ADDU        t0, a2
185         bne             t0, t1, 2b
186         /* clear all tags */
187         PTR_LI          t0, INDEX_BASE
188 1:      cache_op        Index_Store_Tag_D t0
189         PTR_ADDU        t0, a2
190         bne             t0, t1, 1b
191 9:      jr      ra
192         END(mips_init_dcache)
193
194 /*******************************************************************************
195 *
196 * mips_cache_reset - low level initialisation of the primary caches
197 *
198 * This routine initialises the primary caches to ensure that they
199 * have good parity.  It must be called by the ROM before any cached locations
200 * are used to prevent the possibility of data with bad parity being written to
201 * memory.
202 * To initialise the instruction cache it is essential that a source of data
203 * with good parity is available. This routine
204 * will initialise an area of memory starting at location zero to be used as
205 * a source of parity.
206 *
207 * RETURNS: N/A
208 *
209 */
210 NESTED(mips_cache_reset, 0, ra)
211         move    RA, ra
212         li      t2, CONFIG_SYS_ICACHE_SIZE
213         li      t3, CONFIG_SYS_DCACHE_SIZE
214         li      t4, CONFIG_SYS_CACHELINE_SIZE
215         move    t5, t4
216
217         li      v0, MIPS_MAX_CACHE_SIZE
218
219         /*
220          * Now clear that much memory starting from zero.
221          */
222         PTR_LI          a0, CKSEG1
223         PTR_ADDU        a1, a0, v0
224 2:      PTR_ADDIU       a0, 64
225         f_fill64        a0, -64, zero
226         bne             a0, a1, 2b
227
228         /*
229          * The caches are probably in an indeterminate state,
230          * so we force good parity into them by doing an
231          * invalidate, load/fill, invalidate for each line.
232          */
233
234         /*
235          * Assume bottom of RAM will generate good parity for the cache.
236          */
237
238         /*
239          * Initialize the I-cache first,
240          */
241         move    a1, t2
242         move    a2, t4
243         PTR_LA  t7, mips_init_icache
244         jalr    t7
245
246         /*
247          * then initialize D-cache.
248          */
249         move    a1, t3
250         move    a2, t5
251         PTR_LA  t7, mips_init_dcache
252         jalr    t7
253
254         jr      RA
255         END(mips_cache_reset)
256
257 /*******************************************************************************
258 *
259 * dcache_status - get cache status
260 *
261 * RETURNS: 0 - cache disabled; 1 - cache enabled
262 *
263 */
264 LEAF(dcache_status)
265         mfc0    t0, CP0_CONFIG
266         li      t1, CONF_CM_UNCACHED
267         andi    t0, t0, CONF_CM_CMASK
268         move    v0, zero
269         beq     t0, t1, 2f
270         li      v0, 1
271 2:      jr      ra
272         END(dcache_status)
273
274 /*******************************************************************************
275 *
276 * dcache_disable - disable cache
277 *
278 * RETURNS: N/A
279 *
280 */
281 LEAF(dcache_disable)
282         mfc0    t0, CP0_CONFIG
283         li      t1, -8
284         and     t0, t0, t1
285         ori     t0, t0, CONF_CM_UNCACHED
286         mtc0    t0, CP0_CONFIG
287         jr      ra
288         END(dcache_disable)
289
290 /*******************************************************************************
291 *
292 * dcache_enable - enable cache
293 *
294 * RETURNS: N/A
295 *
296 */
297 LEAF(dcache_enable)
298         mfc0    t0, CP0_CONFIG
299         ori     t0, CONF_CM_CMASK
300         xori    t0, CONF_CM_CMASK
301         ori     t0, CONF_CM_CACHABLE_NONCOHERENT
302         mtc0    t0, CP0_CONFIG
303         jr      ra
304         END(dcache_enable)
305
306 #ifdef CONFIG_SYS_INIT_RAM_LOCK_MIPS
307 /*******************************************************************************
308 *
309 * mips_cache_lock - lock RAM area pointed to by a0 in cache.
310 *
311 * RETURNS: N/A
312 *
313 */
314 # define        CACHE_LOCK_SIZE (CONFIG_SYS_DCACHE_SIZE)
315         .globl  mips_cache_lock
316         .ent    mips_cache_lock
317 mips_cache_lock:
318         li      a1, CKSEG0 - CACHE_LOCK_SIZE
319         addu    a0, a1
320         li      a2, CACHE_LOCK_SIZE
321         li      a3, CONFIG_SYS_CACHELINE_SIZE
322         move    a1, a2
323         icacheop(a0,a1,a2,a3,0x1d)
324
325         jr      ra
326
327         .end    mips_cache_lock
328 #endif /* CONFIG_SYS_INIT_RAM_LOCK_MIPS */