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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [ecos-2.0/] [packages/] [hal/] [arm/] [xscale/] [cores/] [v2_0/] [include/] [hal_cache.h] - Blame information for rev 27

Go to most recent revision | Details | Compare with Previous | View Log

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