blob: 5ce0ec45fc3509fa81a27e0a5e7ea342d3ad1048 [file] [log] [blame]
wdenkbb1b8262003-03-27 12:09:35 +00001/*
Shinya Kuribayashi396aa802008-03-25 21:30:07 +09002 * Cache-handling routined for MIPS CPUs
wdenkbb1b8262003-03-27 12:09:35 +00003 *
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
Wolfgang Denk0191e472010-10-26 14:34:52 +020025#include <asm-offsets.h>
wdenkbb1b8262003-03-27 12:09:35 +000026#include <config.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
Shinya Kuribayashi5bb51af2008-03-25 21:30:06 +090033#define RA t8
34
Shinya Kuribayashi396aa802008-03-25 21:30:07 +090035/*
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
wdenkbb1b8262003-03-27 12:09:35 +000043
Shinya Kuribayashi6c6b2612008-06-05 22:29:00 +090044#define INDEX_BASE CKSEG0
Shinya Kuribayashi5bb51af2008-03-25 21:30:06 +090045
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
Shinya Kuribayashi52c27e62008-03-25 21:30:06 +090054 .macro f_fill64 dst, offset, val
55 LONG_S \val, (\offset + 0 * LONGSIZE)(\dst)
56 LONG_S \val, (\offset + 1 * LONGSIZE)(\dst)
57 LONG_S \val, (\offset + 2 * LONGSIZE)(\dst)
58 LONG_S \val, (\offset + 3 * LONGSIZE)(\dst)
59 LONG_S \val, (\offset + 4 * LONGSIZE)(\dst)
60 LONG_S \val, (\offset + 5 * LONGSIZE)(\dst)
61 LONG_S \val, (\offset + 6 * LONGSIZE)(\dst)
62 LONG_S \val, (\offset + 7 * LONGSIZE)(\dst)
63#if LONGSIZE == 4
64 LONG_S \val, (\offset + 8 * LONGSIZE)(\dst)
65 LONG_S \val, (\offset + 9 * LONGSIZE)(\dst)
66 LONG_S \val, (\offset + 10 * LONGSIZE)(\dst)
67 LONG_S \val, (\offset + 11 * LONGSIZE)(\dst)
68 LONG_S \val, (\offset + 12 * LONGSIZE)(\dst)
69 LONG_S \val, (\offset + 13 * LONGSIZE)(\dst)
70 LONG_S \val, (\offset + 14 * LONGSIZE)(\dst)
71 LONG_S \val, (\offset + 15 * LONGSIZE)(\dst)
72#endif
73 .endm
74
Shinya Kuribayashi5bb51af2008-03-25 21:30:06 +090075/*
76 * mips_init_icache(uint PRId, ulong icache_size, unchar icache_linesz)
77 */
78LEAF(mips_init_icache)
Shinya Kuribayashi6911d0a2011-05-07 00:18:13 +090079 blez a1, 9f
80 mtc0 zero, CP0_TAGLO
Shinya Kuribayashi5bb51af2008-03-25 21:30:06 +090081 /* clear tag to invalidate */
82 PTR_LI t0, INDEX_BASE
83 PTR_ADDU t1, t0, a1
841: cache_op Index_Store_Tag_I t0
85 PTR_ADDU t0, a2
86 bne t0, t1, 1b
87 /* fill once, so data field parity is correct */
88 PTR_LI t0, INDEX_BASE
892: cache_op Fill t0
90 PTR_ADDU t0, a2
91 bne t0, t1, 2b
92 /* invalidate again - prudent but not strictly neccessary */
93 PTR_LI t0, INDEX_BASE
941: cache_op Index_Store_Tag_I t0
95 PTR_ADDU t0, a2
96 bne t0, t1, 1b
Shinya Kuribayashi6911d0a2011-05-07 00:18:13 +0900979: jr ra
Shinya Kuribayashi5bb51af2008-03-25 21:30:06 +090098 END(mips_init_icache)
99
100/*
101 * mips_init_dcache(uint PRId, ulong dcache_size, unchar dcache_linesz)
102 */
103LEAF(mips_init_dcache)
Shinya Kuribayashi6911d0a2011-05-07 00:18:13 +0900104 blez a1, 9f
105 mtc0 zero, CP0_TAGLO
Shinya Kuribayashi5bb51af2008-03-25 21:30:06 +0900106 /* clear all tags */
107 PTR_LI t0, INDEX_BASE
108 PTR_ADDU t1, t0, a1
1091: cache_op Index_Store_Tag_D t0
110 PTR_ADDU t0, a2
111 bne t0, t1, 1b
112 /* load from each line (in cached space) */
113 PTR_LI t0, INDEX_BASE
1142: LONG_L zero, 0(t0)
115 PTR_ADDU t0, a2
116 bne t0, t1, 2b
117 /* clear all tags */
118 PTR_LI t0, INDEX_BASE
1191: cache_op Index_Store_Tag_D t0
120 PTR_ADDU t0, a2
121 bne t0, t1, 1b
Shinya Kuribayashi6911d0a2011-05-07 00:18:13 +09001229: jr ra
Shinya Kuribayashi5bb51af2008-03-25 21:30:06 +0900123 END(mips_init_dcache)
124
Shinya Kuribayashi6911d0a2011-05-07 00:18:13 +0900125/*
126 * mips_cache_reset - low level initialisation of the primary caches
127 *
128 * This routine initialises the primary caches to ensure that they have good
129 * parity. It must be called by the ROM before any cached locations are used
130 * to prevent the possibility of data with bad parity being written to memory.
131 *
132 * To initialise the instruction cache it is essential that a source of data
133 * with good parity is available. This routine will initialise an area of
134 * memory starting at location zero to be used as a source of parity.
135 *
136 * RETURNS: N/A
137 *
138 */
Shinya Kuribayashi06222122008-03-25 21:30:06 +0900139NESTED(mips_cache_reset, 0, ra)
Shinya Kuribayashi5bb51af2008-03-25 21:30:06 +0900140 move RA, ra
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +0200141 li t2, CONFIG_SYS_ICACHE_SIZE
142 li t3, CONFIG_SYS_DCACHE_SIZE
143 li t4, CONFIG_SYS_CACHELINE_SIZE
wdenkbb1b8262003-03-27 12:09:35 +0000144 move t5, t4
145
wdenkbb1b8262003-03-27 12:09:35 +0000146 li v0, MIPS_MAX_CACHE_SIZE
147
Shinya Kuribayashi52c27e62008-03-25 21:30:06 +0900148 /*
149 * Now clear that much memory starting from zero.
wdenkbb1b8262003-03-27 12:09:35 +0000150 */
Shinya Kuribayashi6c6b2612008-06-05 22:29:00 +0900151 PTR_LI a0, CKSEG1
Shinya Kuribayashi52c27e62008-03-25 21:30:06 +0900152 PTR_ADDU a1, a0, v0
1532: PTR_ADDIU a0, 64
154 f_fill64 a0, -64, zero
155 bne a0, a1, 2b
wdenk57b2d802003-06-27 21:31:46 +0000156
Shinya Kuribayashic7faac52007-10-27 15:27:06 +0900157 /*
158 * The caches are probably in an indeterminate state,
159 * so we force good parity into them by doing an
160 * invalidate, load/fill, invalidate for each line.
161 */
wdenkbb1b8262003-03-27 12:09:35 +0000162
Shinya Kuribayashi5bb51af2008-03-25 21:30:06 +0900163 /*
164 * Assume bottom of RAM will generate good parity for the cache.
wdenkbb1b8262003-03-27 12:09:35 +0000165 */
166
Shinya Kuribayashi5bb51af2008-03-25 21:30:06 +0900167 /*
168 * Initialize the I-cache first,
wdenkbb1b8262003-03-27 12:09:35 +0000169 */
Shinya Kuribayashi5bb51af2008-03-25 21:30:06 +0900170 move a1, t2
171 move a2, t4
Shinya Kuribayashib1288822008-05-06 13:22:52 +0900172 PTR_LA t7, mips_init_icache
173 jalr t7
wdenkbb1b8262003-03-27 12:09:35 +0000174
Shinya Kuribayashi5bb51af2008-03-25 21:30:06 +0900175 /*
176 * then initialize D-cache.
wdenkbb1b8262003-03-27 12:09:35 +0000177 */
Shinya Kuribayashi5bb51af2008-03-25 21:30:06 +0900178 move a1, t3
179 move a2, t5
Shinya Kuribayashib1288822008-05-06 13:22:52 +0900180 PTR_LA t7, mips_init_dcache
181 jalr t7
wdenkbb1b8262003-03-27 12:09:35 +0000182
Shinya Kuribayashi5bb51af2008-03-25 21:30:06 +0900183 jr RA
Shinya Kuribayashi06222122008-03-25 21:30:06 +0900184 END(mips_cache_reset)
wdenkbb1b8262003-03-27 12:09:35 +0000185
Shinya Kuribayashi6911d0a2011-05-07 00:18:13 +0900186/*
187 * dcache_status - get cache status
188 *
189 * RETURNS: 0 - cache disabled; 1 - cache enabled
190 *
191 */
Shinya Kuribayashi06222122008-03-25 21:30:06 +0900192LEAF(dcache_status)
Shinya Kuribayashi3bdce4f2008-03-25 21:30:07 +0900193 mfc0 t0, CP0_CONFIG
194 li t1, CONF_CM_UNCACHED
195 andi t0, t0, CONF_CM_CMASK
196 move v0, zero
197 beq t0, t1, 2f
198 li v0, 1
1992: jr ra
Shinya Kuribayashi06222122008-03-25 21:30:06 +0900200 END(dcache_status)
wdenkbb1b8262003-03-27 12:09:35 +0000201
Shinya Kuribayashi6911d0a2011-05-07 00:18:13 +0900202/*
203 * dcache_disable - disable cache
204 *
205 * RETURNS: N/A
206 *
207 */
Shinya Kuribayashi06222122008-03-25 21:30:06 +0900208LEAF(dcache_disable)
wdenkbb1b8262003-03-27 12:09:35 +0000209 mfc0 t0, CP0_CONFIG
210 li t1, -8
211 and t0, t0, t1
212 ori t0, t0, CONF_CM_UNCACHED
Shinya Kuribayashic7faac52007-10-27 15:27:06 +0900213 mtc0 t0, CP0_CONFIG
Shinya Kuribayashi9dabea12008-04-17 23:35:13 +0900214 jr ra
Shinya Kuribayashi06222122008-03-25 21:30:06 +0900215 END(dcache_disable)
wdenkbb1b8262003-03-27 12:09:35 +0000216
Shinya Kuribayashi6911d0a2011-05-07 00:18:13 +0900217/*
218 * dcache_enable - enable cache
219 *
220 * RETURNS: N/A
221 *
222 */
Shinya Kuribayashi4d0e2c92008-05-03 13:51:28 +0900223LEAF(dcache_enable)
224 mfc0 t0, CP0_CONFIG
225 ori t0, CONF_CM_CMASK
226 xori t0, CONF_CM_CMASK
227 ori t0, CONF_CM_CACHABLE_NONCOHERENT
228 mtc0 t0, CP0_CONFIG
229 jr ra
230 END(dcache_enable)