]> git.kernelconcepts.de Git - karo-tx-redboot.git/blob - packages/hal/arm/xscale/triton270/v2_0/include/hal_cache.h
RedBoot TX53 Release 2012-02-15
[karo-tx-redboot.git] / packages / hal / arm / xscale / triton270 / 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 //#####DESCRIPTIONBEGIN####
45 //
46 // Author(s):   hmt
47 // Contributors:hmt
48 // Date:        1999-07-05
49 // Purpose:     Cache control API
50 // Description: The macros defined here provide the HAL APIs for handling
51 //              cache control operations.
52 // Usage:
53 //              #include <cyg/hal/hal_cache.h>
54 //              ...
55 //              
56 //
57 //####DESCRIPTIONEND####
58 //
59 //=============================================================================
60
61 #include <cyg/infra/cyg_type.h>
62 //#include <cyg/hal/hal_mmu.h>
63
64 //-----------------------------------------------------------------------------
65 // Cache dimensions
66
67 #define HAL_DCACHE_SIZE                 0x8000 // Size of data cache in bytes
68 #define HAL_DCACHE_LINE_SIZE            32     // Size of a data cache line
69 #define HAL_DCACHE_WAYS                 32     // Associativity of the cache
70 #define HAL_DCACHE_SETS (HAL_DCACHE_SIZE/(HAL_DCACHE_LINE_SIZE*HAL_DCACHE_WAYS))
71
72 #define HAL_ICACHE_SIZE                 0x8000 // Size of icache in bytes
73 #define HAL_ICACHE_LINE_SIZE            32     // Size of ins cache line
74 #define HAL_ICACHE_WAYS                 32     // Associativity of the cache
75 #define HAL_ICACHE_SETS (HAL_ICACHE_SIZE/(HAL_ICACHE_LINE_SIZE*HAL_ICACHE_WAYS))
76
77 //-----------------------------------------------------------------------------
78 // Global control of data cache
79
80 // Enable the data cache
81 #define HAL_DCACHE_ENABLE()                                             \
82 CYG_MACRO_START                                                         \
83     asm volatile (                                                      \
84         "mrc  p15,0,r1,c7,c10,4;"   /* drain write buffer */            \
85         "mrc  p15,0,r1,c1,c0,0;"                                        \
86         "orr  r1,r1,#0x0007;"  /* enable DCache (also ensures the */    \
87                                /* MMU and alignment faults are    */    \
88                                /* enabled)                        */    \
89         "mcr  p15,0,r1,c1,c0,0;"                                        \
90         :                                                               \
91         :                                                               \
92         : "r1" /* Clobber list */                                       \
93         );                                                              \
94 CYG_MACRO_END
95
96 // Disable the data cache (and invalidate it, required semanitcs)
97 #define HAL_DCACHE_DISABLE()                                            \
98 CYG_MACRO_START                                                         \
99     asm volatile (                                                      \
100         "mrc  p15,0,r1,c1,c0,0;"                                        \
101         "bic  r1,r1,#4;"                                                \
102         "mcr  p15,0,r1,c1,c0,0;"                                        \
103         /* cpuwait */                                                   \
104         "mrc    p15,0,r1,c2,c0,0;"  /* arbitrary read   */              \
105         "mov    r1,r1;"                                                 \
106         "sub    pc,pc,#4;"                                              \
107         "mcr    p15,0,r1,c7,c6,0;" /* invalidate data cache */          \
108         /* cpuwait */                                                   \
109         "mrc    p15,0,r1,c2,c0,0;"  /* arbitrary read   */              \
110         "mov    r1,r1;"                                                 \
111         "sub    pc,pc,#4;"                                              \
112         :                                                               \
113         :                                                               \
114         : "r1" /* Clobber list */                                       \
115         );                                                              \
116 CYG_MACRO_END
117
118 // Invalidate the entire cache (and both TLBs, just in case)
119 #define HAL_DCACHE_INVALIDATE_ALL()                                     \
120 CYG_MACRO_START                                                         \
121     /* this macro can discard dirty cache lines. */                     \
122     asm volatile (                                                      \
123         "mcr    p15,0,r1,c7,c6,0;"  /* invalidate data cache */         \
124         "mcr    p15,0,r1,c8,c7,0;"  /* flush I+D TLBs */                \
125         :                                                               \
126         :                                                               \
127         : "r1" /* Clobber list */                                       \
128         );                                                              \
129 CYG_MACRO_END
130      
131
132 // Synchronize the contents of the cache with memory.
133 #define HAL_DCACHE_SYNC()                                               \
134 CYG_MACRO_START                                                         \
135     /* The best way to evict a dirty line is by using the          */   \
136     /* line allocate operation on non-existent memory.             */   \
137     asm volatile (                                                      \
138         "mov    r0, #0xa4000000;"   /* cache flush region */            \
139         "add    r1, r0, #0x8000;"   /* 32KB cache         */            \
140  "667: "                                                                \
141         "mcr    p15,0,r0,c7,c2,5;"  /* allocate a line    */            \
142         "add    r0, r0, #32;"       /* 32 bytes/line      */            \
143         "teq    r1, r0;"                                                \
144         "bne    667b;"                                                  \
145         "mcr    p15,0,r0,c7,c6,0;"  /* invalidate data cache */         \
146         /* cpuwait */                                                   \
147         "mrc    p15,0,r1,c2,c0,0;"  /* arbitrary read   */              \
148         "mov    r1,r1;"                                                 \
149         "sub    pc,pc,#4;"                                              \
150         "mcr    p15,0,r0,c7,c10,4;" /* and drain the write buffer */    \
151         /* cpuwait */                                                   \
152         "mrc    p15,0,r1,c2,c0,0;"  /* arbitrary read   */              \
153         "mov    r1,r1;"                                                 \
154         "sub    pc,pc,#4;"                                              \
155         "nop"                                                           \
156         :                                                               \
157         :                                                               \
158         : "r0","r1"      /* Clobber list */                             \
159         );                                                              \
160 CYG_MACRO_END
161
162 // Query the state of the data cache
163 #define HAL_DCACHE_IS_ENABLED(_state_)                                  \
164 CYG_MACRO_START                                                         \
165     register int reg;                                                   \
166     asm volatile ("mrc  p15,0,%0,c1,c0,0"                               \
167                   : "=r"(reg)                                           \
168                   :                                                     \
169                 /*:*/                                                   \
170         );                                                              \
171     (_state_) = (0 != (4 & reg)); /* Bit 2 is DCache enable */          \
172 CYG_MACRO_END
173
174 // Set the data cache refill burst size
175 //#define HAL_DCACHE_BURST_SIZE(_size_)
176
177 // Set the data cache write mode
178 //#define HAL_DCACHE_WRITE_MODE( _mode_ )
179
180 #define HAL_DCACHE_WRITETHRU_MODE       0
181 #define HAL_DCACHE_WRITEBACK_MODE       1
182
183 // Get the current writeback mode - or only writeback mode if fixed
184 #define HAL_DCACHE_QUERY_WRITE_MODE( _mode_ ) CYG_MACRO_START           \
185     _mode_ = HAL_DCACHE_WRITEBACK_MODE;                                 \
186 CYG_MACRO_END
187
188
189 //-----------------------------------------------------------------------------
190 // Global control of Instruction cache
191
192 // Enable the instruction cache
193 #define HAL_ICACHE_ENABLE()                                             \
194 CYG_MACRO_START                                                         \
195     asm volatile (                                                      \
196         "mrc  p15,0,r1,c1,c0,0;"                                        \
197         "orr  r1,r1,#0x1000;" /* enable ICache */                       \
198         "mcr  p15,0,r1,c1,c0,0;"                                        \
199         :                                                               \
200         :                                                               \
201         : "r1" /* Clobber list */                                       \
202         );                                                              \
203 CYG_MACRO_END
204
205 // Disable the instruction cache (and invalidate it, required semanitcs)
206 #define HAL_ICACHE_DISABLE()                                            \
207 CYG_MACRO_START                                                         \
208     asm volatile (                                                      \
209         "mrc    p15,0,r1,c1,c0,0;"                                      \
210         "bic    r1,r1,#0x1000;" /* disable Icache */                    \
211         "mcr    p15,0,r1,c1,c0,0;"                                      \
212         "mcr    p15,0,r1,c7,c5,0;"  /* invalidate instruction cache */  \
213         "nop;" /* next few instructions may be via cache */             \
214         "nop;"                                                          \
215         "nop;"                                                          \
216         "nop;"                                                          \
217         "nop;"                                                          \
218         "nop"                                                           \
219         :                                                               \
220         :                                                               \
221         : "r1" /* Clobber list */                                       \
222         );                                                              \
223 CYG_MACRO_END
224
225 // Invalidate the entire cache
226 #define HAL_ICACHE_INVALIDATE_ALL()                                     \
227 CYG_MACRO_START                                                         \
228     asm volatile (                                                      \
229         "mcr    p15,0,r1,c7,c5,0;"  /* clear instruction cache */       \
230         "mcr    p15,0,r1,c8,c5,0;"  /* flush I TLB only */              \
231         /* cpuwait */                                                   \
232         "mrc    p15,0,r1,c2,c0,0;"  /* arbitrary read   */              \
233         "mov    r1,r1;"                                                 \
234         "sub    pc,pc,#4;"                                              \
235         "nop;" /* next few instructions may be via cache */             \
236         "nop;"                                                          \
237         "nop;"                                                          \
238         "nop;"                                                          \
239         "nop;"                                                          \
240         "nop"                                                           \
241         :                                                               \
242         :                                                               \
243         : "r1" /* Clobber list */                                       \
244         );                                                              \
245 CYG_MACRO_END
246      
247
248 // Synchronize the contents of the cache with memory.
249 // (which includes flushing out pending writes)
250 #define HAL_ICACHE_SYNC()                                       \
251 CYG_MACRO_START                                                 \
252     HAL_DCACHE_SYNC(); /* ensure data gets to RAM */            \
253     HAL_ICACHE_INVALIDATE_ALL(); /* forget all we know */       \
254 CYG_MACRO_END
255
256 // Query the state of the instruction cache
257 #define HAL_ICACHE_IS_ENABLED(_state_)                                  \
258 CYG_MACRO_START                                                         \
259     /* SA-110 manual states clearly that the control reg is readable */ \
260     register cyg_uint32 reg;                                            \
261     asm volatile ("mrc  p15,0,%0,c1,c0,0"                               \
262                   : "=r"(reg)                                           \
263                   :                                                     \
264                 /*:*/                                                   \
265         );                                                              \
266     (_state_) = (0 != (0x1000 & reg)); /* Bit 12 is ICache enable */    \
267 CYG_MACRO_END
268
269
270 //-----------------------------------------------------------------------------
271 #endif // ifndef CYGONCE_HAL_CACHE_H
272 // End of hal_cache.h