1 #ifndef CYGONCE_HAL_CACHE_H
2 #define CYGONCE_HAL_CACHE_H
4 //=============================================================================
8 // HAL cache control API
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.
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.
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
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.
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.
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.
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 //=============================================================================
45 #include <cyg/infra/cyg_type.h>
46 #include <cyg/hal/hal_soc.h> // Variant specific hardware definitions
48 //-----------------------------------------------------------------------------
49 // Global control of data cache
51 // Enable the data cache
52 #define HAL_DCACHE_ENABLE_L1() \
55 "mrc p15, 0, r1, c1, c0, 0;" \
56 "orr r1, r1, #0x0007;" /* enable DCache (also ensures \
57 that MMU and alignment faults \
59 "mcr p15, 0, r1, c1, c0, 0" \
62 : "r1" /* Clobber list */ \
66 // Clean+invalidate the both D+I caches at L1 and L2 levels
67 #define HAL_CACHE_FLUSH_ALL() \
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 */ \
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) */ \
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*/ \
91 "ands r7, r7, r1, lsr #13;" /* extract max number of the index size */ \
93 "mov r9, r4;" /* create working copy of max way size */ \
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 */ \
100 "subs r7, r7, #1;" /* decrement the index */ \
103 "add r10, r10, #2;" /* increment cache number */ \
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};" \
113 "mcr p15, 0, r0, c7, c5, 0;" /* invalidate I+BTB */ \
114 "mcr p15, 0, r0, c7, c10, 4;" /* drain WB */ \
117 : "r0" /* Clobber list */ \
121 // Disable the data cache
122 #define HAL_DCACHE_DISABLE_L1() \
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" \
131 : "r1" /* Clobber list */ \
135 // Query the state of the data cache
136 #define HAL_DCACHE_IS_ENABLED(_state_) \
140 "mrc p15, 0, %0, c1, c0, 0;" \
144 (_state_) = (0 != (4 & reg)); /* Bit 2 is DCache enable */ \
147 //-----------------------------------------------------------------------------
148 // Global control of Instruction cache
150 // Enable the instruction cache
151 #define HAL_ICACHE_ENABLE_L1() \
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 \
159 "mcr p15, 0, r1, c1, c0, 0" \
162 : "r1" /* Clobber list */ \
166 // Query the state of the instruction cache
167 #define HAL_ICACHE_IS_ENABLED(_state_) \
169 register cyg_uint32 reg; \
171 "mrc p15, 0, %0, c1, c0, 0" \
175 (_state_) = (0 != (0x1000 & reg)); /* Bit 12 is ICache enable */ \
178 // Disable the instruction cache
179 #define HAL_ICACHE_DISABLE_L1() \
182 /* prepare to disable ICache (but not MMU, etc) */ \
183 "mrc p15, 0, r2, c1, c0, 0;" \
185 "bic r2, r2, #0x1000;" \
186 /* align to cache line */ \
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 */ \
204 : "r1","r2" /* Clobber list */ \
208 // Invalidate the entire cache
209 #define HAL_ICACHE_INVALIDATE_ALL_L1()
211 #define HAL_ICACHE_INVALIDATE_ALL_L1() \
213 /* this macro can discard dirty cache lines (N/A for ICache) */ \
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 */ \
227 : "r1" /* Clobber list */ \
232 // Synchronize the contents of the cache with memory.
233 // (which includes flushing out pending writes)
234 #define HAL_ICACHE_SYNC()
236 #define HAL_ICACHE_SYNC() \
238 HAL_DCACHE_SYNC(); /* ensure data gets to RAM */ \
239 HAL_ICACHE_INVALIDATE_ALL(); /* forget all we know */ \
244 // Query the state of the L2 cache
245 #define HAL_L2CACHE_IS_ENABLED(_state_) \
253 "mrc p15, 0, %0, c1, c0, 1;" \
256 (_state_) = (0 != (2 & reg)); /* Bit 1 is L2 Cache enable */ \
259 #define HAL_ENABLE_L2() \
262 "mrc 15, 0, r0, c1, c0, 1;" \
263 "orr r0, r0, #0x2;" \
264 "mcr 15, 0, r0, c1, c0, 1;" \
271 #define HAL_DISABLE_L2() \
274 "mrc 15, 0, r0, c1, c0, 1;" \
275 "bic r0, r0, #0x2;" \
276 "mcr 15, 0, r0, c1, c0, 1;" \
285 #define HAL_ENABLE_L2() CYG_EMPTY_STATEMENT
286 #define HAL_DISABLE_L2() CYG_EMPTY_STATEMENT
287 #endif //L2CC_ENABLED
289 /*********************** Exported macros *******************/
291 #define HAL_DCACHE_ENABLE() { \
293 HAL_DCACHE_ENABLE_L1(); \
296 #define HAL_DCACHE_DISABLE() { \
297 HAL_CACHE_FLUSH_ALL(); \
298 HAL_DCACHE_DISABLE_L1(); \
301 #define HAL_DCACHE_INVALIDATE_ALL() { \
302 HAL_CACHE_FLUSH_ALL(); \
306 #define HAL_DCACHE_SYNC() \
307 HAL_CACHE_FLUSH_ALL(); \
309 #define HAL_ICACHE_INVALIDATE_ALL() { \
310 HAL_CACHE_FLUSH_ALL(); \
313 #define HAL_ICACHE_DISABLE() { \
314 HAL_ICACHE_DISABLE_L1(); \
317 #define HAL_ICACHE_ENABLE() { \
318 HAL_ICACHE_ENABLE_L1(); \
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 */
330 #define HAL_MMU_OFF() \
333 CYGARC_HAL_MMU_OFF() \
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) \
341 /* prevent 'unused variable' warnings */ \
346 #define HAL_FLASH_CACHES_ON(d,i) CYG_EMPTY_STATEMENT
349 #endif // ifndef CYGONCE_HAL_CACHE_H
350 // End of hal_cache.h