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 /* the MMU, alignment faults, and */ \
58 "mcr p15, 0, r1, c1, c0, 0" \
61 : "r1" /* Clobber list */ \
65 // Clean+invalidate the both D+I caches at L1 and L2 levels
66 #define HAL_CACHE_FLUSH_ALL() \
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*/ \
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) */ \
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*/ \
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 */ \
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:" */ \
112 "mcr p15, 0, r0, c7, c5, 0;" /* @ invalidate I+BTB */ \
113 "mcr p15, 0, r0, c7, c10, 4;" /* @ drain WB */ \
117 // Disable the data cache
118 #define HAL_DCACHE_DISABLE_C1() \
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" \
127 : "r1" /* Clobber list */ \
131 // Query the state of the data cache
132 #define HAL_DCACHE_IS_ENABLED(_state_) \
141 "mrc p15, 0, %0, c1, c0, 0;" \
145 (_state_) = (0 != (4 & reg)); /* Bit 2 is DCache enable */ \
148 //-----------------------------------------------------------------------------
149 // Global control of Instruction cache
151 // Enable the instruction cache
152 #define HAL_ICACHE_ENABLE_L1() \
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 */ \
160 "mcr p15, 0, r1, c1, c0, 0" \
163 : "r1" /* Clobber list */ \
167 // Query the state of the instruction cache
168 #define HAL_ICACHE_IS_ENABLED(_state_) \
170 register cyg_uint32 reg; \
172 "mrc p15, 0, %0, c1, c0, 0" \
177 (_state_) = (0 != (0x1000 & reg)); /* Bit 12 is ICache enable */ \
180 // Disable the instruction cache
181 #define HAL_ICACHE_DISABLE_L1() \
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;" \
188 "nop;" /* next few instructions may be via cache */ \
196 : "r1" /* Clobber list */ \
200 // Invalidate the entire cache
201 #define HAL_ICACHE_INVALIDATE_ALL_L1()
203 #define HAL_ICACHE_INVALIDATE_ALL_L1() \
205 /* this macro can discard dirty cache lines (N/A for ICache) */ \
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 */ \
219 : "r1" /* Clobber list */ \
224 // Synchronize the contents of the cache with memory.
225 // (which includes flushing out pending writes)
226 #define HAL_ICACHE_SYNC()
228 #define HAL_ICACHE_SYNC() \
230 HAL_DCACHE_SYNC(); /* ensure data gets to RAM */ \
231 HAL_ICACHE_INVALIDATE_ALL(); /* forget all we know */ \
236 // Query the state of the L2 cache
237 #define HAL_L2CACHE_IS_ENABLED(_state_) \
245 "mrc p15, 0, %0, c1, c0, 1;" \
249 (_state_) = (0 != (2 & reg)); /* Bit 1 is L2 Cache enable */ \
252 #define HAL_ENABLE_L2() \
254 asm("mrc 15, 0, r0, c1, c0, 1"); \
255 asm("orr r0, r0, #0x2"); \
256 asm("mcr 15, 0, r0, c1, c0, 1"); \
259 #define HAL_DISABLE_L2() \
261 asm("mrc 15, 0, r0, c1, c0, 1"); \
262 asm("bic r0, r0, #0x2"); \
263 asm("mcr 15, 0, r0, c1, c0, 1"); \
268 #define HAL_ENABLE_L2()
269 #define HAL_DISABLE_L2()
270 #endif //L2CC_ENABLED
272 /*********************** Exported macros *******************/
274 #define HAL_DCACHE_ENABLE() { \
276 HAL_DCACHE_ENABLE_L1(); \
279 #define HAL_DCACHE_DISABLE() { \
280 HAL_CACHE_FLUSH_ALL(); \
281 HAL_DCACHE_DISABLE_C1(); \
284 #define HAL_DCACHE_INVALIDATE_ALL() { \
285 HAL_CACHE_FLUSH_ALL(); \
289 #define HAL_DCACHE_SYNC()
291 #define HAL_ICACHE_INVALIDATE_ALL() { \
292 HAL_CACHE_FLUSH_ALL(); \
295 #define HAL_ICACHE_DISABLE() { \
296 HAL_ICACHE_DISABLE_L1(); \
299 #define HAL_ICACHE_ENABLE() { \
300 HAL_ICACHE_ENABLE_L1(); \
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 */
312 #define HAL_MMU_OFF() \
315 CYGARC_HAL_MMU_OFF() \
319 #endif // ifndef CYGONCE_HAL_CACHE_H
320 // End of hal_cache.h