OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [ecos-3.0/] [packages/] [hal/] [arm/] [xscale/] [cores/] [current/] [include/] [hal_cache.h] - Blame information for rev 786

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 786 skrzyp
#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, 2003 Free Software Foundation, 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      
19
// version.                                                                 
20
//
21
// eCos is distributed in the hope that it will be useful, but WITHOUT      
22
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or    
23
// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License    
24
// for more details.                                                        
25
//
26
// You should have received a copy of the GNU General Public License        
27
// along with eCos; if not, write to the Free Software Foundation, Inc.,    
28
// 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.            
29
//
30
// As a special exception, if other files instantiate templates or use      
31
// macros or inline functions from this file, or you compile this file      
32
// and link it with other works to produce a work based on this file,       
33
// this file does not by itself cause the resulting work to be covered by   
34
// the GNU General Public License. However the source code for this file    
35
// must still be made available in accordance with section (3) of the GNU   
36
// General Public License v2.                                               
37
//
38
// This exception does not invalidate any other reasons why a work based    
39
// on this file might be covered by the GNU General Public License.         
40
// -------------------------------------------                              
41
// ####ECOSGPLCOPYRIGHTEND####                                              
42
//=============================================================================
43
//#####DESCRIPTIONBEGIN####
44
//
45
// Author(s):   msalter
46
// Contributors:
47
// Date:        2001-12-03
48
// Purpose:     Cache control API
49
// Description: The macros defined here provide the HAL APIs for handling
50
//              cache control operations.
51
// Usage:
52
//              #include <cyg/hal/hal_cache.h>
53
//              ...
54
//              
55
//
56
//####DESCRIPTIONEND####
57
//
58
//=============================================================================
59
 
60
#include <pkgconf/system.h>             // System-wide configuration info
61
#include <cyg/hal/hal_io.h>             // DCACHE_FLUSH_AREA
62
#include <cyg/infra/cyg_type.h>
63
#include CYGBLD_HAL_VAR_H
64
#include <cyg/hal/hal_mmu.h>
65
 
66
//-----------------------------------------------------------------------------
67
// Cache dimensions
68
 
69
#define HAL_DCACHE_SIZE                 0x8000 // Size of data cache in bytes
70
#define HAL_DCACHE_LINE_SIZE            32     // Size of a data cache line
71
#define HAL_DCACHE_WAYS                 32     // Associativity of the cache
72
#define HAL_DCACHE_SETS (HAL_DCACHE_SIZE/(HAL_DCACHE_LINE_SIZE*HAL_DCACHE_WAYS))
73
 
74
#define HAL_ICACHE_SIZE                 0x8000 // Size of icache in bytes
75
#define HAL_ICACHE_LINE_SIZE            32     // Size of ins cache line
76
#define HAL_ICACHE_WAYS                 32     // Associativity of the cache
77
#define HAL_ICACHE_SETS (HAL_ICACHE_SIZE/(HAL_ICACHE_LINE_SIZE*HAL_ICACHE_WAYS))
78
 
79
//-----------------------------------------------------------------------------
80
// Global control of Instruction cache
81
 
82
// Enable the instruction cache
83
#define HAL_ICACHE_ENABLE()                                             \
84
CYG_MACRO_START                                                         \
85
    asm volatile (                                                      \
86
        "mrc  p15,0,r1,c1,c0,0;"                                        \
87
        "orr  r1,r1,#0x1000;" /* enable ICache */                       \
88
        "mcr  p15,0,r1,c1,c0,0;"                                        \
89
        :                                                               \
90
        :                                                               \
91
        : "r1" /* Clobber list */                                       \
92
        );                                                              \
93
CYG_MACRO_END
94
 
95
// Disable the instruction cache (and invalidate it, required semanitcs)
96
#define HAL_ICACHE_DISABLE()                                            \
97
CYG_MACRO_START                                                         \
98
    asm volatile (                                                      \
99
        "mrc    p15,0,r1,c1,c0,0;"                                      \
100
        "bic    r1,r1,#0x1000;" /* disable Icache */                    \
101
        "mcr    p15,0,r1,c1,c0,0;"                                      \
102
        "mcr    p15,0,r1,c7,c5,0;"  /* invalidate instruction cache */  \
103
        "nop;" /* next few instructions may be via cache */             \
104
        "nop;"                                                          \
105
        "nop;"                                                          \
106
        "nop;"                                                          \
107
        "nop;"                                                          \
108
        "nop"                                                           \
109
        :                                                               \
110
        :                                                               \
111
        : "r1" /* Clobber list */                                       \
112
        );                                                              \
113
CYG_MACRO_END
114
 
115
// Query the state of the instruction cache
116
#define HAL_ICACHE_IS_ENABLED(_state_)                                   \
117
CYG_MACRO_START                                                          \
118
    register cyg_uint32 reg;                                             \
119
    asm volatile ("mrc  p15,0,%0,c1,c0,0"                                \
120
                  : "=r"(reg)                                            \
121
                  :                                                      \
122
        );                                                               \
123
    (_state_) = (0 != (0x1000 & reg)); /* Bit 12 is ICache enable */     \
124
CYG_MACRO_END
125
 
126
// Invalidate the entire cache
127
#define HAL_ICACHE_INVALIDATE_ALL()                                     \
128
CYG_MACRO_START                                                         \
129
    asm volatile (                                                      \
130
        "mcr    p15,0,r1,c7,c5,0;"  /* clear instruction cache */       \
131
        "mcr    p15,0,r1,c8,c5,0;"  /* flush I TLB only */              \
132
        /* cpuwait */                                                   \
133
        "mrc    p15,0,r1,c2,c0,0;"  /* arbitrary read   */              \
134
        "mov    r1,r1;"                                                 \
135
        "sub    pc,pc,#4;"                                              \
136
        "nop;" /* next few instructions may be via cache */             \
137
        "nop;"                                                          \
138
        "nop;"                                                          \
139
        "nop;"                                                          \
140
        "nop;"                                                          \
141
        "nop"                                                           \
142
        :                                                               \
143
        :                                                               \
144
        : "r1" /* Clobber list */                                       \
145
        );                                                              \
146
CYG_MACRO_END
147
 
148
// Synchronize the contents of the cache with memory.
149
// (which includes flushing out pending writes)
150
#define HAL_ICACHE_SYNC()                                       \
151
CYG_MACRO_START                                                 \
152
    HAL_DCACHE_SYNC(); /* ensure data gets to RAM */            \
153
    HAL_ICACHE_INVALIDATE_ALL(); /* forget all we know */       \
154
CYG_MACRO_END
155
 
156
// Set the instruction cache refill burst size
157
//#define HAL_ICACHE_BURST_SIZE(_size_)
158
// This feature is not available on the XScale.
159
 
160
// Load the contents of the given address range into the instruction cache
161
// and then lock the cache so that it stays there.
162
//#define HAL_ICACHE_LOCK(_base_, _size_)
163
// This feature is not available on the XScale.
164
 
165
// Undo a previous lock operation
166
//#define HAL_ICACHE_UNLOCK(_base_, _size_)
167
// This feature is not available on the XScale.
168
 
169
// Unlock entire cache
170
//#define HAL_ICACHE_UNLOCK_ALL()
171
// This feature is not available on the XScale.
172
 
173
//-----------------------------------------------------------------------------
174
// Instruction cache line control
175
 
176
// Invalidate cache lines in the given range without writing to memory.
177
//#define HAL_ICACHE_INVALIDATE( _base_ , _size_ )
178
// This feature is not available on the XScale.
179
 
180
//-----------------------------------------------------------------------------
181
// Global control of data cache
182
 
183
// Enable the data cache
184
#define HAL_DCACHE_ENABLE()                                             \
185
CYG_MACRO_START                                                         \
186
    asm volatile (                                                      \
187
        "mcr  p15,0,r1,c7,c10,4;"   /* drain write buffer */            \
188
        "mrc  p15,0,r1,c1,c0,0;"                                        \
189
        "orr  r1,r1,#0x0007;"  /* enable DCache (also ensures the */    \
190
                               /* MMU and alignment faults are    */    \
191
                               /* enabled)                        */    \
192
        "mcr  p15,0,r1,c1,c0,0;"                                        \
193
        "mrc  p15,0,r1,c1,c0,1;"                                        \
194
        "bic  r1,r1,#1;"                                                \
195
        "mcr  p15,0,r1,c1,c0,1;"                                        \
196
        :                                                               \
197
        :                                                               \
198
        : "r1" /* Clobber list */                                       \
199
        );                                                              \
200
CYG_MACRO_END
201
 
202
// Disable the data cache (and invalidate it, required semanitcs)
203
#define HAL_DCACHE_DISABLE()                                            \
204
CYG_MACRO_START                                                         \
205
    asm volatile (                                                      \
206
        "mrc  p15,0,r1,c1,c0,0;"    /* disable cache */                 \
207
        "bic  r1,r1,#4;"                                                \
208
        "mcr  p15,0,r1,c1,c0,0;"                                        \
209
        "mrc  p15,0,r1,c1,c0,1;"    /* disable coalescing */            \
210
        "orr  r1,r1,#1;"                                                \
211
        "mcr  p15,0,r1,c1,c0,1;"                                        \
212
        "mcr    p15,0,r1,c7,c6,0;"  /* invalidate data cache */         \
213
        /* cpuwait */                                                   \
214
        "mrc    p15,0,r1,c2,c0,0;"  /* arbitrary read   */              \
215
        "mov    r1,r1;"                                                 \
216
        "sub    pc,pc,#4;"                                              \
217
        :                                                               \
218
        :                                                               \
219
        : "r1" /* Clobber list */                                       \
220
        );                                                              \
221
CYG_MACRO_END
222
 
223
// Query the state of the data cache
224
#define HAL_DCACHE_IS_ENABLED(_state_)                                   \
225
CYG_MACRO_START                                                          \
226
    register int reg;                                                   \
227
    asm volatile ("mrc  p15,0,%0,c1,c0,0"                               \
228
                  : "=r"(reg)                                           \
229
                  :                                                     \
230
                /*:*/                                                   \
231
        );                                                              \
232
    (_state_) = (0 != (4 & reg)); /* Bit 2 is DCache enable */          \
233
CYG_MACRO_END
234
 
235
// Flush the entire dcache (and then both TLBs, just in case)
236
#define HAL_DCACHE_INVALIDATE_ALL()                                     \
237
CYG_MACRO_START    /* this macro can discard dirty cache lines. */      \
238
    /* this macro can discard dirty cache lines. */                     \
239
    asm volatile (                                                      \
240
        "mcr    p15,0,r1,c7,c6,0;"  /* invalidate data cache */         \
241
        "mcr    p15,0,r1,c8,c7,0;"  /* flush I+D TLBs */                \
242
        :                                                               \
243
        :                                                               \
244
        : "r1" /* Clobber list */                                       \
245
        );                                                              \
246
CYG_MACRO_END
247
 
248
// DCACHE_FLUSH_AREA is defined if writeback caching is used. Otherwise
249
// write-through is assumed.
250
#ifdef DCACHE_FLUSH_AREA
251
 
252
// Evict dirty lines from write-back caches
253
#define HAL_DCACHE_EVICT()                                              \
254
CYG_MACRO_START                                                         \
255
    /* The best way to evict a dirty line is by using the          */   \
256
    /* line allocate operation on non-existent memory.             */   \
257
    asm volatile (                                                      \
258
        "mov    r0, %0;"            /* cache flush region */            \
259
        "add    r1, r0, #0x8800;"   /* 32KB main + 2KB mini cache */    \
260
 "667: "                                                                \
261
        "mcr    p15,0,r0,c7,c2,5;"  /* allocate a line    */            \
262
        "add    r0, r0, #32;"       /* 32 bytes/line      */            \
263
        "teq    r1, r0;"                                                \
264
        "bne    667b;"                                                  \
265
        :                                                               \
266
        : "i" (DCACHE_FLUSH_AREA)                                       \
267
        : "r0","r1"      /* Clobber list */                             \
268
        );                                                              \
269
CYG_MACRO_END
270
#else
271
#define HAL_DCACHE_EVICT()
272
#endif
273
 
274
// Synchronize the contents of the cache with memory.
275
#define HAL_DCACHE_SYNC()                                               \
276
CYG_MACRO_START                                                         \
277
    HAL_DCACHE_EVICT();                                                 \
278
    asm volatile (                                                      \
279
        "mcr    p15,0,r0,c7,c6,0;"  /* invalidate data cache */         \
280
        /* cpuwait */                                                   \
281
        "mrc    p15,0,r1,c2,c0,0;"  /* arbitrary read   */              \
282
        "mov    r1,r1;"                                                 \
283
        "sub    pc,pc,#4;"                                              \
284
        "mcr    p15,0,r0,c7,c10,4;" /* and drain the write buffer */    \
285
        /* cpuwait */                                                   \
286
        "mrc    p15,0,r1,c2,c0,0;"  /* arbitrary read   */              \
287
        "mov    r1,r1;"                                                 \
288
        "sub    pc,pc,#4;"                                              \
289
        "nop"                                                           \
290
        :                                                               \
291
        :                                                               \
292
        : "r0","r1"      /* Clobber list */                             \
293
        );                                                              \
294
CYG_MACRO_END
295
 
296
// Set the data cache refill burst size
297
//#define HAL_DCACHE_BURST_SIZE(_size_)
298
// This feature is not available on the XScale.
299
 
300
// Set the data cache write mode
301
//#define HAL_DCACHE_WRITE_MODE( _mode_ )
302
// This feature is not available on the XScale.
303
 
304
#define HAL_DCACHE_WRITETHRU_MODE       0
305
#define HAL_DCACHE_WRITEBACK_MODE       1
306
 
307
// Get the current writeback mode - or only writeback mode if fixed
308
#ifdef DCACHE_FLUSH_AREA
309
#define HAL_DCACHE_QUERY_WRITE_MODE( _mode_ ) CYG_MACRO_START           \
310
    _mode_ = HAL_DCACHE_WRITEBACK_MODE;                                 \
311
CYG_MACRO_END
312
#else
313
#define HAL_DCACHE_QUERY_WRITE_MODE( _mode_ ) CYG_MACRO_START           \
314
    _mode_ = HAL_DCACHE_WRITETHRU_MODE;                                 \
315
CYG_MACRO_END
316
#endif
317
 
318
// Load the contents of the given address range into the data cache
319
// and then lock the cache so that it stays there.
320
//#define HAL_DCACHE_LOCK(_base_, _size_)
321
// This feature is not available on the XScale.
322
 
323
// Undo a previous lock operation
324
//#define HAL_DCACHE_UNLOCK(_base_, _size_)
325
// This feature is not available on the XScale.
326
 
327
// Unlock entire cache
328
//#define HAL_DCACHE_UNLOCK_ALL()
329
// This feature is not available on the XScale.
330
 
331
//-----------------------------------------------------------------------------
332
// Data cache line control
333
 
334
// Allocate cache lines for the given address range without reading its
335
// contents from memory.
336
//#define HAL_DCACHE_ALLOCATE( _base_ , _size_ )
337
// This feature is not available on the XScale.
338
 
339
// Write dirty cache lines to memory and invalidate the cache entries
340
// for the given address range.
341
#define HAL_DCACHE_FLUSH( _base_ , _size_ )     \
342
CYG_MACRO_START                                 \
343
    HAL_DCACHE_STORE( _base_ , _size_ );        \
344
    HAL_DCACHE_INVALIDATE( _base_ , _size_ );   \
345
CYG_MACRO_END
346
 
347
// Invalidate cache lines in the given range without writing to memory.
348
#define HAL_DCACHE_INVALIDATE( _base_ , _size_ )                        \
349
CYG_MACRO_START                                                         \
350
    register int addr, enda;                                            \
351
    for ( addr = (~(HAL_DCACHE_LINE_SIZE - 1)) & (int)(_base_),         \
352
              enda = (int)(_base_) + (_size_);                          \
353
          addr < enda ;                                                 \
354
          addr += HAL_DCACHE_LINE_SIZE )                                \
355
    {                                                                   \
356
        asm volatile (                                                  \
357
                      "mcr  p15,0,%0,c7,c6,1;" /* flush entry away */   \
358
                      :                                                 \
359
                      : "r"(addr)                                       \
360
                      : "memory"                                        \
361
            );                                                          \
362
    }                                                                   \
363
CYG_MACRO_END
364
 
365
// Write dirty cache lines to memory for the given address range.
366
#define HAL_DCACHE_STORE( _base_ , _size_ )                             \
367
CYG_MACRO_START                                                         \
368
    register int addr, enda;                                            \
369
    for ( addr = (~(HAL_DCACHE_LINE_SIZE - 1)) & (int)(_base_),         \
370
              enda = (int)(_base_) + (_size_);                          \
371
          addr < enda ;                                                 \
372
          addr += HAL_DCACHE_LINE_SIZE )                                \
373
    {                                                                   \
374
        asm volatile ("mcr  p15,0,%0,c7,c10,1;" /* push entry to RAM */ \
375
                      :                                                 \
376
                      : "r"(addr)                                       \
377
                      : "memory"                                        \
378
            );                                                          \
379
    }                                                                   \
380
    /* and also drain the write buffer */                               \
381
    asm volatile (                                                      \
382
        "mov    r1,#0;"                                                 \
383
        "mcr    p15,0,r1,c7,c10,4;"                                     \
384
        :                                                               \
385
        :                                                               \
386
        : "r1", "memory" /* Clobber list */                             \
387
    );                                                                  \
388
CYG_MACRO_END
389
 
390
// Preread the given range into the cache with the intention of reading
391
// from it later.
392
//#define HAL_DCACHE_READ_HINT( _base_ , _size_ )
393
// This feature is available on the XScale, but due to tricky
394
// coherency issues with the read buffer (see XScale developer's
395
// manual) we don't bother to implement it here.
396
 
397
// Preread the given range into the cache with the intention of writing
398
// to it later.
399
//#define HAL_DCACHE_WRITE_HINT( _base_ , _size_ )
400
// This feature is not available on the XScale.
401
 
402
// Allocate and zero the cache lines associated with the given range.
403
//#define HAL_DCACHE_ZERO( _base_ , _size_ )
404
// This feature is not available on the XScale.
405
 
406
 
407
//-----------------------------------------------------------------------------
408
#endif // ifndef CYGONCE_HAL_CACHE_H
409
// End of hal_cache.h

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.