blob: edc0674b24024d0a1b147cbe6bcf229d6028b89b [file] [log] [blame]
wdenkc0218802003-03-27 12:09:35 +00001/*
Shinya Kuribayashi373b16f2008-03-25 21:30:07 +09002 * Cache-handling routined for MIPS CPUs
wdenkc0218802003-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 Denk25ddd1f2010-10-26 14:34:52 +020025#include <asm-offsets.h>
wdenkc0218802003-03-27 12:09:35 +000026#include <config.h>
Shinya Kuribayashi2f5d4142008-03-25 21:30:06 +090027#include <asm/asm.h>
wdenkc0218802003-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 Kuribayashi2e0e5272008-03-25 21:30:06 +090033#define RA t8
34
Shinya Kuribayashi373b16f2008-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
wdenkc0218802003-03-27 12:09:35 +000043
Shinya Kuribayashi7daf2eb2008-06-05 22:29:00 +090044#define INDEX_BASE CKSEG0
Shinya Kuribayashi2e0e5272008-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 Kuribayashi18988402008-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 Kuribayashi2e0e5272008-03-25 21:30:06 +090075/*
76 * mips_init_icache(uint PRId, ulong icache_size, unchar icache_linesz)
77 */
78LEAF(mips_init_icache)
79 blez a1, 9f
80 mtc0 zero, CP0_TAGLO
81 /* 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
979: jr ra
98 END(mips_init_icache)
99
100/*
101 * mips_init_dcache(uint PRId, ulong dcache_size, unchar dcache_linesz)
102 */
103LEAF(mips_init_dcache)
104 blez a1, 9f
105 mtc0 zero, CP0_TAGLO
106 /* 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
1229: jr ra
123 END(mips_init_dcache)
124
wdenkc0218802003-03-27 12:09:35 +0000125/*******************************************************************************
126*
127* mips_cache_reset - low level initialisation of the primary caches
128*
129* This routine initialises the primary caches to ensure that they
130* have good parity. It must be called by the ROM before any cached locations
131* are used to prevent the possibility of data with bad parity being written to
132* memory.
133* To initialise the instruction cache it is essential that a source of data
134* with good parity is available. This routine
135* will initialise an area of memory starting at location zero to be used as
136* a source of parity.
137*
138* RETURNS: N/A
139*
140*/
Shinya Kuribayashi2f5d4142008-03-25 21:30:06 +0900141NESTED(mips_cache_reset, 0, ra)
Shinya Kuribayashi2e0e5272008-03-25 21:30:06 +0900142 move RA, ra
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +0200143 li t2, CONFIG_SYS_ICACHE_SIZE
144 li t3, CONFIG_SYS_DCACHE_SIZE
145 li t4, CONFIG_SYS_CACHELINE_SIZE
wdenkc0218802003-03-27 12:09:35 +0000146 move t5, t4
147
wdenkc0218802003-03-27 12:09:35 +0000148 li v0, MIPS_MAX_CACHE_SIZE
149
Shinya Kuribayashi18988402008-03-25 21:30:06 +0900150 /*
151 * Now clear that much memory starting from zero.
wdenkc0218802003-03-27 12:09:35 +0000152 */
Shinya Kuribayashi7daf2eb2008-06-05 22:29:00 +0900153 PTR_LI a0, CKSEG1
Shinya Kuribayashi18988402008-03-25 21:30:06 +0900154 PTR_ADDU a1, a0, v0
1552: PTR_ADDIU a0, 64
156 f_fill64 a0, -64, zero
157 bne a0, a1, 2b
wdenk8bde7f72003-06-27 21:31:46 +0000158
Shinya Kuribayashi03c031d2007-10-27 15:27:06 +0900159 /*
160 * The caches are probably in an indeterminate state,
161 * so we force good parity into them by doing an
162 * invalidate, load/fill, invalidate for each line.
163 */
wdenkc0218802003-03-27 12:09:35 +0000164
Shinya Kuribayashi2e0e5272008-03-25 21:30:06 +0900165 /*
166 * Assume bottom of RAM will generate good parity for the cache.
wdenkc0218802003-03-27 12:09:35 +0000167 */
168
Shinya Kuribayashi2e0e5272008-03-25 21:30:06 +0900169 /*
170 * Initialize the I-cache first,
wdenkc0218802003-03-27 12:09:35 +0000171 */
Shinya Kuribayashi2e0e5272008-03-25 21:30:06 +0900172 move a1, t2
173 move a2, t4
Shinya Kuribayashi49387db2008-05-06 13:22:52 +0900174 PTR_LA t7, mips_init_icache
175 jalr t7
wdenkc0218802003-03-27 12:09:35 +0000176
Shinya Kuribayashi2e0e5272008-03-25 21:30:06 +0900177 /*
178 * then initialize D-cache.
wdenkc0218802003-03-27 12:09:35 +0000179 */
Shinya Kuribayashi2e0e5272008-03-25 21:30:06 +0900180 move a1, t3
181 move a2, t5
Shinya Kuribayashi49387db2008-05-06 13:22:52 +0900182 PTR_LA t7, mips_init_dcache
183 jalr t7
wdenkc0218802003-03-27 12:09:35 +0000184
Shinya Kuribayashi2e0e5272008-03-25 21:30:06 +0900185 jr RA
Shinya Kuribayashi2f5d4142008-03-25 21:30:06 +0900186 END(mips_cache_reset)
wdenkc0218802003-03-27 12:09:35 +0000187
188/*******************************************************************************
189*
190* dcache_status - get cache status
191*
192* RETURNS: 0 - cache disabled; 1 - cache enabled
193*
194*/
Shinya Kuribayashi2f5d4142008-03-25 21:30:06 +0900195LEAF(dcache_status)
Shinya Kuribayashid98e3482008-03-25 21:30:07 +0900196 mfc0 t0, CP0_CONFIG
197 li t1, CONF_CM_UNCACHED
198 andi t0, t0, CONF_CM_CMASK
199 move v0, zero
200 beq t0, t1, 2f
201 li v0, 1
2022: jr ra
Shinya Kuribayashi2f5d4142008-03-25 21:30:06 +0900203 END(dcache_status)
wdenkc0218802003-03-27 12:09:35 +0000204
205/*******************************************************************************
206*
207* dcache_disable - disable cache
208*
209* RETURNS: N/A
210*
211*/
Shinya Kuribayashi2f5d4142008-03-25 21:30:06 +0900212LEAF(dcache_disable)
wdenkc0218802003-03-27 12:09:35 +0000213 mfc0 t0, CP0_CONFIG
214 li t1, -8
215 and t0, t0, t1
216 ori t0, t0, CONF_CM_UNCACHED
Shinya Kuribayashi03c031d2007-10-27 15:27:06 +0900217 mtc0 t0, CP0_CONFIG
Shinya Kuribayashi43c50922008-04-17 23:35:13 +0900218 jr ra
Shinya Kuribayashi2f5d4142008-03-25 21:30:06 +0900219 END(dcache_disable)
wdenkc0218802003-03-27 12:09:35 +0000220
Shinya Kuribayashiea638952008-05-03 13:51:28 +0900221/*******************************************************************************
222*
223* dcache_enable - enable cache
224*
225* RETURNS: N/A
226*
227*/
228LEAF(dcache_enable)
229 mfc0 t0, CP0_CONFIG
230 ori t0, CONF_CM_CMASK
231 xori t0, CONF_CM_CMASK
232 ori t0, CONF_CM_CACHABLE_NONCOHERENT
233 mtc0 t0, CP0_CONFIG
234 jr ra
235 END(dcache_enable)