]> git.kernelconcepts.de Git - karo-tx-redboot.git/blob - packages/hal/arm/mx51/var/v2_0/include/hal_cache.h
Initial revision
[karo-tx-redboot.git] / packages / hal / arm / mx51 / var / v2_0 / include / hal_cache.h
1 #ifndef CYGONCE_HAL_CACHE_H
2 #define CYGONCE_HAL_CACHE_H
3
4 //=============================================================================
5 //
6 //      hal_cache.h
7 //
8 //      HAL cache control API
9 //
10 //=============================================================================
11 //####ECOSGPLCOPYRIGHTBEGIN####
12 // -------------------------------------------
13 // This file is part of eCos, the Embedded Configurable Operating System.
14 // Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
15 //
16 // eCos is free software; you can redistribute it and/or modify it under
17 // the terms of the GNU General Public License as published by the Free
18 // Software Foundation; either version 2 or (at your option) any later version.
19 //
20 // eCos is distributed in the hope that it will be useful, but WITHOUT ANY
21 // WARRANTY; without even the implied warranty of MERCHANTABILITY or
22 // FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
23 // for more details.
24 //
25 // You should have received a copy of the GNU General Public License along
26 // with eCos; if not, write to the Free Software Foundation, Inc.,
27 // 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
28 //
29 // As a special exception, if other files instantiate templates or use macros
30 // or inline functions from this file, or you compile this file and link it
31 // with other works to produce a work based on this file, this file does not
32 // by itself cause the resulting work to be covered by the GNU General Public
33 // License. However the source code for this file must still be made available
34 // in accordance with section (3) of the GNU General Public License.
35 //
36 // This exception does not invalidate any other reasons why a work based on
37 // this file might be covered by the GNU General Public License.
38 //
39 // Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
40 // at http://sources.redhat.com/ecos/ecos-license/
41 // -------------------------------------------
42 //####ECOSGPLCOPYRIGHTEND####
43 //=============================================================================
44
45 #include <cyg/infra/cyg_type.h>
46 #include <cyg/hal/hal_soc.h>         // Variant specific hardware definitions
47
48 //-----------------------------------------------------------------------------
49 // Global control of data cache
50
51 // Enable the data cache
52 #define HAL_DCACHE_ENABLE_L1()                                          \
53 CYG_MACRO_START                                                         \
54     asm volatile (                                                      \
55         "mrc p15, 0, r1, c1, c0, 0;"                                    \
56         "orr r1, r1, #0x0007;" /* enable DCache (also ensures */        \
57                                /* the MMU, alignment faults, and */       \
58         "mcr p15, 0, r1, c1, c0, 0"                                     \
59         :                                                               \
60         :                                                               \
61         : "r1" /* Clobber list */                                       \
62         );                                                              \
63 CYG_MACRO_END
64
65 // Clean+invalidate the both D+I caches at L1 and L2 levels
66 #define HAL_CACHE_FLUSH_ALL()                                         \
67 CYG_MACRO_START                                                         \
68     asm volatile (                                                      \
69         "stmfd  sp!, {r0-r5, r7, r9-r11};"  \
70             "mrc        p15, 1, r0, c0, c0, 1;" /*@ read clidr*/ \
71             "ands       r3, r0, #0x7000000;"    /*@ extract loc from clidr */ \
72             "mov        r3, r3, lsr #23;"       /*@ left align loc bit field*/ \
73             "beq        555f;" /* finished;" */         /*@ if loc is 0, then no need to clean*/ \
74             "mov        r10, #0;"               /*@ start clean at cache level 0*/ \
75     "111:" /*"loop1: */                                                         \
76             "add        r2, r10, r10, lsr #1;"  /*@ work out 3x current cache level*/ \
77             "mov        r1, r0, lsr r2;"        /*@ extract cache type bits from clidr*/ \
78             "and        r1, r1, #7;"            /*@ mask of the bits for current cache only*/ \
79             "cmp        r1, #2;"                /*@ see what cache we have at this level*/ \
80             "blt        444f;" /* skip;" */                     /*@ skip if no cache, or just i-cache*/ \
81             "mcr        p15, 2, r10, c0, c0, 0;" /*@ select current cache level in cssr*/ \
82                 "mcr    p15, 0, r10, c7, c5, 4;" /*     @ isb to sych the new cssr&csidr */ \
83             "mrc        p15, 1, r1, c0, c0, 0;" /*@ read the new csidr*/ \
84             "and        r2, r1, #7;"    /*@ extract the length of the cache lines*/ \
85             "add        r2, r2, #4;"    /*@ add 4 (line length offset) */ \
86             "ldr        r4, =0x3ff;"    \
87             "ands       r4, r4, r1, lsr #3;"    /*@ find maximum number on the way size*/ \
88             ".word 0xE16F5F14;" /*"clz  r5, r4;"        @ find bit position of way size increment*/ \
89             "ldr        r7, =0x7fff;"   \
90             "ands       r7, r7, r1, lsr #13;"   /*@ extract max number of the index size*/ \
91     "222:" /* loop2:"   */ \
92             "mov        r9, r4;"        /*@ create working copy of max way size*/       \
93     "333:" /* loop3:"   */      \
94             "orr        r11, r10, r9, lsl r5;"  /*@ factor way and cache number into r11*/ \
95             "orr        r11, r11, r7, lsl r2;"  /*@ factor index number into r11*/      \
96             "mcr        p15, 0, r11, c7, c14, 2;" /*@ clean & invalidate by set/way */ \
97             "subs       r9, r9, #1;"    /*@ decrement the way */ \
98             "bge        333b;" /* loop3;" */            \
99             "subs       r7, r7, #1;"    /*@ decrement the index */ \
100             "bge        222b;" /* loop2;" */            \
101     "444:" /* skip:"    */                       \
102             "add        r10, r10, #2;"  /*@ increment cache number */ \
103             "cmp        r3, r10;"       \
104             "bgt        111b;" /*loop1;"        */ \
105     "555:" /* "finished:" */            \
106             "mov        r10, #0;"                /*@ swith back to cache level 0 */     \
107             "mcr        p15, 2, r10, c0, c0, 0;" /*@ select current cache level in cssr */ \
108                 "mcr    p15, 0, r10, c7, c5, 4;" /*     @ isb to sych the new cssr&csidr */ \
109                 "ldmfd  sp!, {r0-r5, r7, r9-r11};"  \
110     "666:" /* iflush:" */ \
111         "mov    r0, #0x0;"  \
112                 "mcr    p15, 0, r0, c7, c5, 0;" /*      @ invalidate I+BTB */ \
113                 "mcr    p15, 0, r0, c7, c10, 4;" /*     @ drain WB */ \
114     );                                                                  \
115 CYG_MACRO_END
116
117 // Disable the data cache
118 #define HAL_DCACHE_DISABLE_C1()                                         \
119 CYG_MACRO_START                                                         \
120     asm volatile (                                                      \
121         "mrc p15, 0, r1, c1, c0, 0;"                                    \
122         "bic r1, r1, #0x0004;" /* disable DCache by clearing C bit */   \
123                              /* but not MMU and alignment faults */     \
124         "mcr p15, 0, r1, c1, c0, 0"                                     \
125         :                                                               \
126         :                                                               \
127         : "r1" /* Clobber list */                                       \
128     );                                                                  \
129 CYG_MACRO_END
130
131 // Query the state of the data cache
132 #define HAL_DCACHE_IS_ENABLED(_state_)                                  \
133 CYG_MACRO_START                                                         \
134     register int reg;                                                   \
135     asm volatile (                                                      \
136         "nop; "                                                         \
137         "nop; "                                                         \
138         "nop; "                                                         \
139         "nop; "                                                         \
140         "nop; "                                                         \
141         "mrc p15, 0, %0, c1, c0, 0;"                                    \
142                   : "=r"(reg)                                           \
143                   :                                                     \
144         );                                                              \
145     (_state_) = (0 != (4 & reg)); /* Bit 2 is DCache enable */          \
146 CYG_MACRO_END
147
148 //-----------------------------------------------------------------------------
149 // Global control of Instruction cache
150
151 // Enable the instruction cache
152 #define HAL_ICACHE_ENABLE_L1()                                          \
153 CYG_MACRO_START                                                         \
154     asm volatile (                                                      \
155         "mrc p15, 0, r1, c1, c0, 0;"                                    \
156         "orr r1, r1, #0x1000;"                                          \
157         "orr r1, r1, #0x0003;"  /* enable ICache (also ensures   */     \
158                                 /* that MMU and alignment faults */     \
159                                 /* are enabled)                  */     \
160         "mcr p15, 0, r1, c1, c0, 0"                                     \
161         :                                                               \
162         :                                                               \
163         : "r1" /* Clobber list */                                       \
164         );                                                              \
165 CYG_MACRO_END
166
167 // Query the state of the instruction cache
168 #define HAL_ICACHE_IS_ENABLED(_state_)                                  \
169 CYG_MACRO_START                                                         \
170     register cyg_uint32 reg;                                            \
171     asm volatile (                                                      \
172         "mrc p15, 0, %0, c1, c0, 0"                                     \
173         : "=r"(reg)                                                     \
174         :                                                               \
175         );                                                              \
176                                                                         \
177     (_state_) = (0 != (0x1000 & reg)); /* Bit 12 is ICache enable */    \
178 CYG_MACRO_END
179
180 // Disable the instruction cache
181 #define HAL_ICACHE_DISABLE_L1()                                         \
182 CYG_MACRO_START                                                         \
183     asm volatile (                                                      \
184         "mrc p15, 0, r1, c1, c0, 0;"                                    \
185         "bic r1, r1, #0x1000;" /* disable ICache (but not MMU, etc) */  \
186         "mcr p15, 0, r1, c1, c0, 0;"                                    \
187         "mov r1, #0;"                                                   \
188         "nop;" /* next few instructions may be via cache    */          \
189         "nop;"                                                          \
190         "nop;"                                                          \
191         "nop;"                                                          \
192         "nop;"                                                          \
193         "nop"                                                           \
194         :                                                               \
195         :                                                               \
196         : "r1" /* Clobber list */                                       \
197         );                                                              \
198 CYG_MACRO_END
199
200 // Invalidate the entire cache
201 #define HAL_ICACHE_INVALIDATE_ALL_L1()
202 #ifdef TODO
203 #define HAL_ICACHE_INVALIDATE_ALL_L1()                                  \
204 CYG_MACRO_START                                                         \
205     /* this macro can discard dirty cache lines (N/A for ICache) */     \
206     asm volatile (                                                      \
207         "mov r1, #0;"                                                   \
208         "mcr p15, 0, r1, c7, c5, 0;"  /* flush ICache */                \
209         "mcr p15, 0, r1, c8, c5, 0;"  /* flush ITLB only */             \
210         "mcr p15, 0, r1, c7, c5, 4;"  /* flush prefetch buffer */       \
211         "nop;" /* next few instructions may be via cache    */          \
212         "nop;"                                                          \
213         "nop;"                                                          \
214         "nop;"                                                          \
215         "nop;"                                                          \
216         "nop;"                                                          \
217         :                                                               \
218         :                                                               \
219         : "r1" /* Clobber list */                                       \
220         );                                                              \
221 CYG_MACRO_END
222 #endif
223
224 // Synchronize the contents of the cache with memory.
225 // (which includes flushing out pending writes)
226 #define HAL_ICACHE_SYNC()
227 #ifdef TODO
228 #define HAL_ICACHE_SYNC()                                       \
229 CYG_MACRO_START                                                 \
230     HAL_DCACHE_SYNC(); /* ensure data gets to RAM */            \
231     HAL_ICACHE_INVALIDATE_ALL(); /* forget all we know */       \
232 CYG_MACRO_END
233 #endif
234
235 #ifdef L2CC_ENABLED
236 // Query the state of the L2 cache
237 #define HAL_L2CACHE_IS_ENABLED(_state_)                         \
238 CYG_MACRO_START                                                         \
239     register int reg;                                                   \
240     asm volatile (                                                      \
241         "nop; "                                                         \
242         "nop; "                                                         \
243         "nop; "                                                         \
244         "nop; "                                                         \
245         "mrc p15, 0, %0, c1, c0, 1;"                                    \
246                   : "=r"(reg)                                           \
247                   :                                                     \
248         );                                                              \
249     (_state_) = (0 != (2 & reg)); /* Bit 1 is L2 Cache enable */          \
250 CYG_MACRO_END
251
252 #define HAL_ENABLE_L2()                             \
253 {                                                   \
254     asm("mrc 15, 0, r0, c1, c0, 1");    \
255     asm("orr r0, r0, #0x2");            \
256     asm("mcr 15, 0, r0, c1, c0, 1");    \
257 }
258
259 #define HAL_DISABLE_L2()                            \
260 {                                                   \
261         asm("mrc 15, 0, r0, c1, c0, 1");    \
262         asm("bic r0, r0, #0x2");            \
263         asm("mcr 15, 0, r0, c1, c0, 1");    \
264 }
265
266 #else //L2CC_ENABLED
267
268 #define HAL_ENABLE_L2()
269 #define HAL_DISABLE_L2()
270 #endif //L2CC_ENABLED
271
272 /*********************** Exported macros *******************/
273
274 #define HAL_DCACHE_ENABLE() {           \
275         HAL_ENABLE_L2();                \
276         HAL_DCACHE_ENABLE_L1();         \
277 }
278
279 #define HAL_DCACHE_DISABLE() {          \
280         HAL_CACHE_FLUSH_ALL();        \
281         HAL_DCACHE_DISABLE_C1();               \
282 }
283
284 #define HAL_DCACHE_INVALIDATE_ALL() {   \
285         HAL_CACHE_FLUSH_ALL(); \
286 }
287
288 // not needed
289 #define HAL_DCACHE_SYNC()
290
291 #define HAL_ICACHE_INVALIDATE_ALL() {   \
292         HAL_CACHE_FLUSH_ALL(); \
293 }
294
295 #define HAL_ICACHE_DISABLE() {          \
296         HAL_ICACHE_DISABLE_L1();        \
297 }
298
299 #define HAL_ICACHE_ENABLE() {           \
300         HAL_ICACHE_ENABLE_L1();         \
301 }
302
303 #define CYGARC_HAL_MMU_OFF(__paddr__)  \
304         "mrc p15, 0, r0, c1, c0, 0;" /* read c1 */                      \
305         "bic r0, r0, #0x7;" /* disable DCache and MMU */                \
306         "bic r0, r0, #0x1000;" /* disable ICache */                     \
307         "mcr p15, 0, r0, c1, c0, 0;" /*  */                             \
308         "nop;" /* flush i+d-TLBs */                                     \
309         "nop;" /* flush i+d-TLBs */                                     \
310         "nop;" /* flush i+d-TLBs */
311
312 #define HAL_MMU_OFF() \
313 CYG_MACRO_START          \
314     asm volatile (                                                      \
315         CYGARC_HAL_MMU_OFF()   \
316     );      \
317 CYG_MACRO_END
318
319 #endif // ifndef CYGONCE_HAL_CACHE_H
320 // End of hal_cache.h