]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - arch/mips/cpu/mips32/cache.S
MIPS: mips32/cache.S: use v1 register for indirect function calls
[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  * 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 RA              t9
22
23 /*
24  * 16kB is the maximum size of instruction and data caches on MIPS 4K,
25  * 64kB is on 4KE, 24K, 5K, etc. Set bigger size for convenience.
26  *
27  * Note that the above size is the maximum size of primary cache. U-Boot
28  * doesn't have L2 cache support for now.
29  */
30 #define MIPS_MAX_CACHE_SIZE     0x10000
31
32 #define INDEX_BASE      CKSEG0
33
34         .macro  cache_op op addr
35         .set    push
36         .set    noreorder
37         .set    mips3
38         cache   \op, 0(\addr)
39         .set    pop
40         .endm
41
42         .macro  f_fill64 dst, offset, val
43         LONG_S  \val, (\offset +  0 * LONGSIZE)(\dst)
44         LONG_S  \val, (\offset +  1 * LONGSIZE)(\dst)
45         LONG_S  \val, (\offset +  2 * LONGSIZE)(\dst)
46         LONG_S  \val, (\offset +  3 * LONGSIZE)(\dst)
47         LONG_S  \val, (\offset +  4 * LONGSIZE)(\dst)
48         LONG_S  \val, (\offset +  5 * LONGSIZE)(\dst)
49         LONG_S  \val, (\offset +  6 * LONGSIZE)(\dst)
50         LONG_S  \val, (\offset +  7 * LONGSIZE)(\dst)
51 #if LONGSIZE == 4
52         LONG_S  \val, (\offset +  8 * LONGSIZE)(\dst)
53         LONG_S  \val, (\offset +  9 * LONGSIZE)(\dst)
54         LONG_S  \val, (\offset + 10 * LONGSIZE)(\dst)
55         LONG_S  \val, (\offset + 11 * LONGSIZE)(\dst)
56         LONG_S  \val, (\offset + 12 * LONGSIZE)(\dst)
57         LONG_S  \val, (\offset + 13 * LONGSIZE)(\dst)
58         LONG_S  \val, (\offset + 14 * LONGSIZE)(\dst)
59         LONG_S  \val, (\offset + 15 * LONGSIZE)(\dst)
60 #endif
61         .endm
62
63 /*
64  * mips_init_icache(uint PRId, ulong icache_size, unchar icache_linesz)
65  */
66 LEAF(mips_init_icache)
67         blez            a1, 9f
68         mtc0            zero, CP0_TAGLO
69         /* clear tag to invalidate */
70         PTR_LI          t0, INDEX_BASE
71         PTR_ADDU        t1, t0, a1
72 1:      cache_op        INDEX_STORE_TAG_I t0
73         PTR_ADDU        t0, a2
74         bne             t0, t1, 1b
75         /* fill once, so data field parity is correct */
76         PTR_LI          t0, INDEX_BASE
77 2:      cache_op        FILL t0
78         PTR_ADDU        t0, a2
79         bne             t0, t1, 2b
80         /* invalidate again - prudent but not strictly neccessary */
81         PTR_LI          t0, INDEX_BASE
82 1:      cache_op        INDEX_STORE_TAG_I t0
83         PTR_ADDU        t0, a2
84         bne             t0, t1, 1b
85 9:      jr              ra
86         END(mips_init_icache)
87
88 /*
89  * mips_init_dcache(uint PRId, ulong dcache_size, unchar dcache_linesz)
90  */
91 LEAF(mips_init_dcache)
92         blez            a1, 9f
93         mtc0            zero, CP0_TAGLO
94         /* clear all tags */
95         PTR_LI          t0, INDEX_BASE
96         PTR_ADDU        t1, t0, a1
97 1:      cache_op        INDEX_STORE_TAG_D t0
98         PTR_ADDU        t0, a2
99         bne             t0, t1, 1b
100         /* load from each line (in cached space) */
101         PTR_LI          t0, INDEX_BASE
102 2:      LONG_L          zero, 0(t0)
103         PTR_ADDU        t0, a2
104         bne             t0, t1, 2b
105         /* clear all tags */
106         PTR_LI          t0, INDEX_BASE
107 1:      cache_op        INDEX_STORE_TAG_D t0
108         PTR_ADDU        t0, a2
109         bne             t0, t1, 1b
110 9:      jr              ra
111         END(mips_init_dcache)
112
113 /*
114  * mips_cache_reset - low level initialisation of the primary caches
115  *
116  * This routine initialises the primary caches to ensure that they have good
117  * parity.  It must be called by the ROM before any cached locations are used
118  * to prevent the possibility of data with bad parity being written to memory.
119  *
120  * To initialise the instruction cache it is essential that a source of data
121  * with good parity is available. This routine will initialise an area of
122  * memory starting at location zero to be used as a source of parity.
123  *
124  * RETURNS: N/A
125  *
126  */
127 NESTED(mips_cache_reset, 0, ra)
128         move    RA, ra
129         li      t2, CONFIG_SYS_ICACHE_SIZE
130         li      t3, CONFIG_SYS_DCACHE_SIZE
131         li      t8, CONFIG_SYS_CACHELINE_SIZE
132
133         li      v0, MIPS_MAX_CACHE_SIZE
134
135         /*
136          * Now clear that much memory starting from zero.
137          */
138         PTR_LI          a0, CKSEG1
139         PTR_ADDU        a1, a0, v0
140 2:      PTR_ADDIU       a0, 64
141         f_fill64        a0, -64, zero
142         bne             a0, a1, 2b
143
144         /*
145          * The caches are probably in an indeterminate state,
146          * so we force good parity into them by doing an
147          * invalidate, load/fill, invalidate for each line.
148          */
149
150         /*
151          * Assume bottom of RAM will generate good parity for the cache.
152          */
153
154         /*
155          * Initialize the I-cache first,
156          */
157         move    a1, t2
158         move    a2, t8
159         PTR_LA  v1, mips_init_icache
160         jalr    v1
161
162         /*
163          * then initialize D-cache.
164          */
165         move    a1, t3
166         move    a2, t8
167         PTR_LA  v1, mips_init_dcache
168         jalr    v1
169
170         jr      RA
171         END(mips_cache_reset)
172
173 /*
174  * dcache_status - get cache status
175  *
176  * RETURNS: 0 - cache disabled; 1 - cache enabled
177  *
178  */
179 LEAF(dcache_status)
180         mfc0    t0, CP0_CONFIG
181         li      t1, CONF_CM_UNCACHED
182         andi    t0, t0, CONF_CM_CMASK
183         move    v0, zero
184         beq     t0, t1, 2f
185         li      v0, 1
186 2:      jr      ra
187         END(dcache_status)
188
189 /*
190  * dcache_disable - disable cache
191  *
192  * RETURNS: N/A
193  *
194  */
195 LEAF(dcache_disable)
196         mfc0    t0, CP0_CONFIG
197         li      t1, -8
198         and     t0, t0, t1
199         ori     t0, t0, CONF_CM_UNCACHED
200         mtc0    t0, CP0_CONFIG
201         jr      ra
202         END(dcache_disable)
203
204 /*
205  * dcache_enable - enable cache
206  *
207  * RETURNS: N/A
208  *
209  */
210 LEAF(dcache_enable)
211         mfc0    t0, CP0_CONFIG
212         ori     t0, CONF_CM_CMASK
213         xori    t0, CONF_CM_CMASK
214         ori     t0, CONFIG_SYS_MIPS_CACHE_MODE
215         mtc0    t0, CP0_CONFIG
216         jr      ra
217         END(dcache_enable)