]> git.kernelconcepts.de Git - karo-tx-redboot.git/blob - packages/hal/arm/mx53/var/v2_0/include/hal_cache.h
TX53 Release 2011-12-20
[karo-tx-redboot.git] / packages / hal / arm / mx53 / 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                                                                    that MMU and alignment faults                \
58                                                                    are enabled)                                  */             \
59                 "mcr p15, 0, r1, c1, c0, 0"                                                                             \
60                 :                                                                                                                               \
61                 :                                                                                                                               \
62                 : "r1" /* Clobber list */                                                                               \
63                 );                                                                                                                              \
64         CYG_MACRO_END
65
66 // Clean+invalidate the both D+I caches at L1 and L2 levels
67 #define HAL_CACHE_FLUSH_ALL()                                                                                   \
68         CYG_MACRO_START                                                                                                         \
69         asm volatile (                                                                                                          \
70                 "stmfd  sp!, {r0-r5, r7, r9-r11};"                                                              \
71                 "mrc    p15, 1, r0, c0, c0, 1;" /* read clidr */                                \
72                 "ands   r3, r0, #0x7000000;"    /* extract loc from clidr */    \
73                 "mov    r3, r3, lsr #23;"       /* left align loc bit field */          \
74                 "beq    555f;"          /* if loc is 0, then no need to clean */        \
75                 "mov    r10, #0;"       /* start clean at cache level 0 */                      \
76         "111:"                                                                                                                          \
77                 "add    r2, r10, r10, lsr #1;"  /* work out 3x current cache level */ \
78                 "mov    r1, r0, lsr r2;"/* extract cache type bits from clidr */ \
79                 "and    r1, r1, #7;"    /* mask of the bits for current cache only */ \
80                 "cmp    r1, #2;"                /* see what cache we have at this level*/ \
81                 "blt    444f;"                  /* skip if no cache, or just i-cache */ \
82                 "mcr    p15, 2, r10, c0, c0, 0;" /* select current cache level in cssr */ \
83                 "mcr    p15, 0, r10, c7, c5, 4;" /* isb to synch the new cssr & csidr */ \
84                 "mrc    p15, 1, r1, c0, c0, 0;" /* read the new csidr */                \
85                 "and    r2, r1, #7;"    /* extract the length of the cache lines */ \
86                 "add    r2, r2, #4;"    /* add 4 (line length offset) */                \
87                 "ldr    r4, =0x3ff;"                                                                                    \
88                 "ands   r4, r4, r1, lsr #3;"    /* find maximum number on the way size */ \
89                 "clz    r5, r4;"                /* find bit position of way size increment*/ \
90                 "ldr    r7, =0x7fff;"                                                                                   \
91                 "ands   r7, r7, r1, lsr #13;"   /* extract max number of the index size */ \
92         "222:"                                                                                                                          \
93                 "mov    r9, r4;"        /* create working copy of max way size */       \
94         "333:"                                                                                                                          \
95                 "orr    r11, r10, r9, lsl r5;"  /* factor way and cache number into r11 */ \
96                 "orr    r11, r11, r7, lsl r2;"  /* factor index number into r11 */ \
97                 "mcr    p15, 0, r11, c7, c14, 2;" /* clean & invalidate by set/way */ \
98                 "subs   r9, r9, #1;"    /* decrement the way */                                 \
99                 "bge    333b;"                                                                                                  \
100                 "subs   r7, r7, #1;"    /* decrement the index */                               \
101                 "bge    222b;"                                                                                                  \
102         "444:"                                                                                                                          \
103                 "add    r10, r10, #2;"  /* increment cache number */                    \
104                 "cmp    r3, r10;"                                                                                               \
105                 "bgt    111b;"                                                                                                  \
106         "555:"                                                                                                                          \
107                 "mov    r10, #0;"                /* swith back to cache level 0 */              \
108                 "mcr    p15, 2, r10, c0, c0, 0;" /* select current cache level in cssr */ \
109                 "mcr    p15, 0, r10, c7, c5, 4;" /* isb to synch the new cssr & csidr */ \
110                 "ldmfd  sp!, {r0-r5, r7, r9-r11};"                                                              \
111         "666:"                                                                                                                          \
112                 "mov    r0, #0x0;"                                                                                              \
113                 "mcr    p15, 0, r0, c7, c5, 0;" /* invalidate I+BTB */                  \
114                 "mcr    p15, 0, r0, c7, c10, 4;" /* drain WB */                                 \
115                 :                                                                                                                               \
116                 :                                                                                                                               \
117                 : "r0" /* Clobber list */                                                                               \
118                 );                                                                                                                              \
119         CYG_MACRO_END
120
121 // Disable the data cache
122 #define HAL_DCACHE_DISABLE_L1()                                                                                 \
123         CYG_MACRO_START                                                                                                         \
124         asm volatile (                                                                                                          \
125                 "mrc p15, 0, r1, c1, c0, 0;"                                                                    \
126                 "bic r1, r1, #0x0004;"  /* disable DCache by clearing C bit,    \
127                                                                    but not MMU and alignment faults */  \
128                 "mcr p15, 0, r1, c1, c0, 0"                                                                             \
129                 :                                                                                                                               \
130                 :                                                                                                                               \
131                 : "r1" /* Clobber list */                                                                               \
132         );                                                                                                                                      \
133         CYG_MACRO_END
134
135 // Query the state of the data cache
136 #define HAL_DCACHE_IS_ENABLED(_state_)                                                                  \
137         CYG_MACRO_START                                                                                                         \
138         register int reg;                                                                                                       \
139         asm volatile (                                                                                                          \
140                 "mrc p15, 0, %0, c1, c0, 0;"                                                                    \
141                 : "=r"(reg)                                                                                                             \
142                 :                                                                                                                               \
143                 );                                                                                                                              \
144         (_state_) = (0 != (4 & reg)); /* Bit 2 is DCache enable */                      \
145         CYG_MACRO_END
146
147 //-----------------------------------------------------------------------------
148 // Global control of Instruction cache
149
150 // Enable the instruction cache
151 #define HAL_ICACHE_ENABLE_L1()                                                                                  \
152         CYG_MACRO_START                                                                                                         \
153         asm volatile (                                                                                                          \
154                 "mrc p15, 0, r1, c1, c0, 0;"                                                                    \
155                 "orr r1, r1, #0x1000;"                                                                                  \
156                 "orr r1, r1, #0x0003;"  /* enable ICache (also ensures                  \
157                                                                    that MMU and alignment faults                \
158                                                                    are enabled)                                  */             \
159                 "mcr p15, 0, r1, c1, c0, 0"                                                                             \
160                 :                                                                                                                               \
161                 :                                                                                                                               \
162                 : "r1" /* Clobber list */                                                                               \
163                 );                                                                                                                              \
164         CYG_MACRO_END
165
166 // Query the state of the instruction cache
167 #define HAL_ICACHE_IS_ENABLED(_state_)                                                                  \
168         CYG_MACRO_START                                                                                                         \
169         register cyg_uint32 reg;                                                                                        \
170         asm volatile (                                                                                                          \
171                 "mrc p15, 0, %0, c1, c0, 0"                                                                             \
172                 : "=r"(reg)                                                                                                             \
173                 :                                                                                                                               \
174                 );                                                                                                                              \
175         (_state_) = (0 != (0x1000 & reg)); /* Bit 12 is ICache enable */        \
176         CYG_MACRO_END
177
178 // Disable the instruction cache
179 #define HAL_ICACHE_DISABLE_L1()                                                                                 \
180 CYG_MACRO_START                                                                                                                 \
181         asm volatile (                                                                                                          \
182                 /* prepare to disable ICache (but not MMU, etc) */                              \
183                 "mrc p15, 0, r2, c1, c0, 0;"                                                                    \
184                 "mov r1, #0;"                                                                                                   \
185                 "bic r2, r2, #0x1000;"                                                                                  \
186                 /* align to cache line */                                                                               \
187                 "b 1f;"                                                                                                                 \
188                 ".align 5;"                                                                                                             \
189         "1:;"                                                                                                                           \
190                 /* flush icache */                                                                                              \
191                 "mcr p15, 0, r1, c7, c5, 0;"  /* flush ICache */                                \
192                 "mcr p15, 0, r1, c8, c5, 0;"  /* flush ITLB only */                             \
193                 "mcr p15, 0, r1, c7, c5, 4;"  /* flush prefetch buffer */               \
194                 /* disable icache */                                                                                    \
195                 "mcr p15, 0, r2, c1, c0, 0;"                                                                    \
196                 "nop;" /* next few instructions may be via cache        */                      \
197                 "nop;"                                                                                                                  \
198                 "nop;"                                                                                                                  \
199                 "nop;"                                                                                                                  \
200                 "nop;"                                                                                                                  \
201                 "nop;"                                                                                                                  \
202                 :                                                                                                                               \
203                 :                                                                                                                               \
204                 : "r1","r2" /* Clobber list */                                                                  \
205                 );                                                                                                                              \
206 CYG_MACRO_END
207
208 // Invalidate the entire cache
209 #define HAL_ICACHE_INVALIDATE_ALL_L1()
210 #ifdef TODO
211 #define HAL_ICACHE_INVALIDATE_ALL_L1()                                                          \
212         CYG_MACRO_START                                                                                                 \
213         /* this macro can discard dirty cache lines (N/A for ICache) */ \
214         asm volatile (                                                                                                  \
215                 "mov r1, #0;"                                                                                           \
216                 "mcr p15, 0, r1, c7, c5, 0;"  /* flush ICache */                        \
217                 "mcr p15, 0, r1, c8, c5, 0;"  /* flush ITLB only */                     \
218                 "mcr p15, 0, r1, c7, c5, 4;"  /* flush prefetch buffer */       \
219                 "nop;" /* next few instructions may be via cache        */              \
220                 "nop;"                                                                                                          \
221                 "nop;"                                                                                                          \
222                 "nop;"                                                                                                          \
223                 "nop;"                                                                                                          \
224                 "nop;"                                                                                                          \
225                 :                                                                                                                       \
226                 :                                                                                                                       \
227                 : "r1" /* Clobber list */                                                                       \
228                 );                                                                                                                      \
229         CYG_MACRO_END
230 #endif
231
232 // Synchronize the contents of the cache with memory.
233 // (which includes flushing out pending writes)
234 #define HAL_ICACHE_SYNC()
235 #ifdef TODO
236 #define HAL_ICACHE_SYNC()                                                                       \
237         CYG_MACRO_START                                                                                 \
238         HAL_DCACHE_SYNC(); /* ensure data gets to RAM */                \
239         HAL_ICACHE_INVALIDATE_ALL(); /* forget all we know */   \
240         CYG_MACRO_END
241 #endif
242
243 #ifdef L2CC_ENABLED
244 // Query the state of the L2 cache
245 #define HAL_L2CACHE_IS_ENABLED(_state_)                                                         \
246         CYG_MACRO_START                                                                                                 \
247         register int reg;                                                                                               \
248         asm volatile (                                                                                                  \
249                 "nop;"                                                                                                          \
250                 "nop;"                                                                                                          \
251                 "nop;"                                                                                                          \
252                 "nop;"                                                                                                          \
253                 "mrc p15, 0, %0, c1, c0, 1;"                                                            \
254                 : "=r"(reg)                                                                                                     \
255                 );                                                                                                                      \
256         (_state_) = (0 != (2 & reg)); /* Bit 1 is L2 Cache enable */    \
257         CYG_MACRO_END
258
259 #define HAL_ENABLE_L2()                                                 \
260         CYG_MACRO_START                                                         \
261         asm volatile(                                                           \
262                 "mrc 15, 0, r0, c1, c0, 1;"                             \
263                 "orr r0, r0, #0x2;"                                             \
264                 "mcr 15, 0, r0, c1, c0, 1;"                             \
265                 :                                                                               \
266                 :                                                                               \
267                 : "r0"                                                                  \
268                 );                                                                              \
269         CYG_MACRO_END
270
271 #define HAL_DISABLE_L2()                                                \
272         CYG_MACRO_START                                                         \
273         asm volatile(                                                           \
274                 "mrc 15, 0, r0, c1, c0, 1;"                             \
275                 "bic r0, r0, #0x2;"                                             \
276                 "mcr 15, 0, r0, c1, c0, 1;"                             \
277                 :                                                                               \
278                 :                                                                               \
279                 : "r0"                                                                  \
280                 );                                                                              \
281         CYG_MACRO_END
282
283 #else //L2CC_ENABLED
284
285 #define HAL_ENABLE_L2()                                                 CYG_EMPTY_STATEMENT
286 #define HAL_DISABLE_L2()                                                CYG_EMPTY_STATEMENT
287 #endif //L2CC_ENABLED
288
289 /*********************** Exported macros *******************/
290
291 #define HAL_DCACHE_ENABLE() {                                   \
292                 HAL_ENABLE_L2();                                                \
293                 HAL_DCACHE_ENABLE_L1();                                 \
294 }
295
296 #define HAL_DCACHE_DISABLE() {                                  \
297                 HAL_CACHE_FLUSH_ALL();                                  \
298                 HAL_DCACHE_DISABLE_L1();                                \
299 }
300
301 #define HAL_DCACHE_INVALIDATE_ALL() {                   \
302                 HAL_CACHE_FLUSH_ALL();                                  \
303 }
304
305 // not needed
306 #define HAL_DCACHE_SYNC()                                               \
307                 HAL_CACHE_FLUSH_ALL();                                  \
308
309 #define HAL_ICACHE_INVALIDATE_ALL() {                   \
310                 HAL_CACHE_FLUSH_ALL();                                  \
311 }
312
313 #define HAL_ICACHE_DISABLE() {                                  \
314                 HAL_ICACHE_DISABLE_L1();                                \
315 }
316
317 #define HAL_ICACHE_ENABLE() {                                   \
318                 HAL_ICACHE_ENABLE_L1();                                 \
319 }
320
321 #define CYGARC_HAL_MMU_OFF(__paddr__)                                           \
322                 "mrc p15, 0, r0, c1, c0, 0;" /* read c1 */                      \
323                 "bic r0, r0, #0x7;" /* disable DCache and MMU */        \
324                 "bic r0, r0, #0x1000;" /* disable ICache */                     \
325                 "mcr p15, 0, r0, c1, c0, 0;" /*  */                                     \
326                 "nop;" /* flush i+d-TLBs */                                                     \
327                 "nop;" /* flush i+d-TLBs */                                                     \
328                 "nop;" /* flush i+d-TLBs */
329
330 #define HAL_MMU_OFF()                                                   \
331         CYG_MACRO_START                                                         \
332         asm volatile (                                                          \
333                 CYGARC_HAL_MMU_OFF()                                    \
334                 );                                                                              \
335         CYG_MACRO_END
336
337 #if 1
338 /* There is no direct access to the flash area, thus there is no need for these macros */
339 #define HAL_FLASH_CACHES_OFF(d,i)                               \
340         CYG_MACRO_START                                                         \
341         /* prevent 'unused variable' warnings */        \
342         (void)d;                                                                        \
343         (void)i;                                                                        \
344         CYG_MACRO_END
345
346 #define HAL_FLASH_CACHES_ON(d,i)                        CYG_EMPTY_STATEMENT
347 #endif
348
349 #endif // ifndef CYGONCE_HAL_CACHE_H
350 // End of hal_cache.h