]> git.sur5r.net Git - u-boot/blob - arch/mips/lib/cache_init.S
MIPS: Enable use of the instruction cache earlier
[u-boot] / arch / mips / lib / cache_init.S
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
45 10:     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
84 10:
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 LEAF(mips_cache_reset)
102 #ifndef CONFIG_SYS_CACHE_SIZE_AUTO
103         li      t2, CONFIG_SYS_ICACHE_SIZE
104         li      t8, CONFIG_SYS_ICACHE_LINE_SIZE
105 #else
106         l1_info t2, t8, MIPS_CONF1_IA_SHF
107 #endif
108
109 #ifndef CONFIG_SYS_CACHE_SIZE_AUTO
110         li      t3, CONFIG_SYS_DCACHE_SIZE
111         li      t9, CONFIG_SYS_DCACHE_LINE_SIZE
112 #else
113         l1_info t3, t9, MIPS_CONF1_DA_SHF
114 #endif
115
116 #ifdef CONFIG_SYS_MIPS_CACHE_INIT_RAM_LOAD
117
118         /* Determine the largest L1 cache size */
119 #ifndef CONFIG_SYS_CACHE_SIZE_AUTO
120 #if CONFIG_SYS_ICACHE_SIZE > CONFIG_SYS_DCACHE_SIZE
121         li      v0, CONFIG_SYS_ICACHE_SIZE
122 #else
123         li      v0, CONFIG_SYS_DCACHE_SIZE
124 #endif
125 #else
126         move    v0, t2
127         sltu    t1, t2, t3
128         movn    v0, t3, t1
129 #endif
130         /*
131          * Now clear that much memory starting from zero.
132          */
133         PTR_LI          a0, CKSEG1
134         PTR_ADDU        a1, a0, v0
135 2:      PTR_ADDIU       a0, 64
136         f_fill64        a0, -64, zero
137         bne             a0, a1, 2b
138
139 #endif /* CONFIG_SYS_MIPS_CACHE_INIT_RAM_LOAD */
140
141         /*
142          * The TagLo registers used depend upon the CPU implementation, but the
143          * architecture requires that it is safe for software to write to both
144          * TagLo selects 0 & 2 covering supported cases.
145          */
146         mtc0            zero, CP0_TAGLO
147         mtc0            zero, CP0_TAGLO, 2
148
149         /*
150          * The caches are probably in an indeterminate state, so we force good
151          * parity into them by doing an invalidate for each line. If
152          * CONFIG_SYS_MIPS_CACHE_INIT_RAM_LOAD is set then we'll proceed to
153          * perform a load/fill & a further invalidate for each line, assuming
154          * that the bottom of RAM (having just been cleared) will generate good
155          * parity for the cache.
156          */
157
158         /*
159          * Initialize the I-cache first,
160          */
161         blez            t2, 1f
162         PTR_LI          t0, INDEX_BASE
163         PTR_ADDU        t1, t0, t2
164         /* clear tag to invalidate */
165         cache_loop      t0, t1, t8, INDEX_STORE_TAG_I
166 #ifdef CONFIG_SYS_MIPS_CACHE_INIT_RAM_LOAD
167         /* fill once, so data field parity is correct */
168         PTR_LI          t0, INDEX_BASE
169         cache_loop      t0, t1, t8, FILL
170         /* invalidate again - prudent but not strictly neccessary */
171         PTR_LI          t0, INDEX_BASE
172         cache_loop      t0, t1, t8, INDEX_STORE_TAG_I
173 #endif
174
175         /* Enable use of the I-cache by setting Config.K0 */
176         sync
177         mfc0            t0, CP0_CONFIG
178         li              t1, CONFIG_SYS_MIPS_CACHE_MODE
179 #if __mips_isa_rev >= 2
180         ins             t0, t1, 0, 3
181 #else
182         ori             t0, t0, CONF_CM_CMASK
183         xori            t0, t0, CONF_CM_CMASK
184         or              t0, t0, t1
185 #endif
186         mtc0            t0, CP0_CONFIG
187
188         /*
189          * then initialize D-cache.
190          */
191 1:      blez            t3, 3f
192         PTR_LI          t0, INDEX_BASE
193         PTR_ADDU        t1, t0, t3
194         /* clear all tags */
195         cache_loop      t0, t1, t9, INDEX_STORE_TAG_D
196 #ifdef CONFIG_SYS_MIPS_CACHE_INIT_RAM_LOAD
197         /* load from each line (in cached space) */
198         PTR_LI          t0, INDEX_BASE
199 2:      LONG_L          zero, 0(t0)
200         PTR_ADDU        t0, t9
201         bne             t0, t1, 2b
202         /* clear all tags */
203         PTR_LI          t0, INDEX_BASE
204         cache_loop      t0, t1, t9, INDEX_STORE_TAG_D
205 #endif
206
207 3:      jr      ra
208         END(mips_cache_reset)
209
210 /*
211  * dcache_status - get cache status
212  *
213  * RETURNS: 0 - cache disabled; 1 - cache enabled
214  *
215  */
216 LEAF(dcache_status)
217         mfc0    t0, CP0_CONFIG
218         li      t1, CONF_CM_UNCACHED
219         andi    t0, t0, CONF_CM_CMASK
220         move    v0, zero
221         beq     t0, t1, 2f
222         li      v0, 1
223 2:      jr      ra
224         END(dcache_status)
225
226 /*
227  * dcache_disable - disable cache
228  *
229  * RETURNS: N/A
230  *
231  */
232 LEAF(dcache_disable)
233         mfc0    t0, CP0_CONFIG
234         li      t1, -8
235         and     t0, t0, t1
236         ori     t0, t0, CONF_CM_UNCACHED
237         mtc0    t0, CP0_CONFIG
238         jr      ra
239         END(dcache_disable)
240
241 /*
242  * dcache_enable - enable cache
243  *
244  * RETURNS: N/A
245  *
246  */
247 LEAF(dcache_enable)
248         mfc0    t0, CP0_CONFIG
249         ori     t0, CONF_CM_CMASK
250         xori    t0, CONF_CM_CMASK
251         ori     t0, CONFIG_SYS_MIPS_CACHE_MODE
252         mtc0    t0, CP0_CONFIG
253         jr      ra
254         END(dcache_enable)