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

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [rtos/] [ecos-2.0/] [packages/] [hal/] [mips/] [arch/] [v2_0/] [include/] [hal_cache.h] - Blame information for rev 390

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 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):   nickg
47
// Contributors:        nickg
48
// Date:        1998-02-17
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/hal.h>
62
#include <cyg/infra/cyg_type.h>
63
 
64
#include <cyg/hal/var_cache.h>
65
 
66
// Use this macro to allow the assembler to accept "cache" instructions,
67
// which are MIPS ISA 3. This is useful if someone is compiling
68
// with -mips2, but the architecture is really MIPS ISA 3.
69
 
70
#define _hal_asm_mips_cpp_stringize( _x_ ) #_x_
71
#define _HAL_ASM_SET_MIPS_ISA( _isal_ ) asm volatile ( \
72
      ".set mips" _hal_asm_mips_cpp_stringize(_isal_) )
73
 
74
 
75
//=============================================================================
76
// Default Implementation. This uses the standard MIPS CP0 registers and
77
// cache instructions. Note that not all variants will have all of the
78
// functionality defined here. 
79
 
80
//-----------------------------------------------------------------------------
81
// Cache dimensions.
82
// These really should be defined in var_cache.h. If they are not, then provide
83
// a set of numbers that are typical of many variants.
84
 
85
#ifndef HAL_DCACHE_SIZE
86
 
87
// Data cache
88
#define HAL_DCACHE_SIZE                 4096    // Size of data cache in bytes
89
#define HAL_DCACHE_LINE_SIZE            16      // Size of a data cache line
90
#define HAL_DCACHE_WAYS                 2       // Associativity of the cache
91
 
92
// Instruction cache
93
#define HAL_ICACHE_SIZE                 4096    // Size of cache in bytes
94
#define HAL_ICACHE_LINE_SIZE            16      // Size of a cache line
95
#define HAL_ICACHE_WAYS                 2       // Associativity of the cache
96
 
97
#define HAL_DCACHE_SETS (HAL_DCACHE_SIZE/(HAL_DCACHE_LINE_SIZE*HAL_DCACHE_WAYS))
98
#define HAL_ICACHE_SETS (HAL_ICACHE_SIZE/(HAL_ICACHE_LINE_SIZE*HAL_ICACHE_WAYS))
99
 
100
#endif
101
 
102
//-----------------------------------------------------------------------------
103
// Cache instruction uses LSBs or MSBs (depending on the
104
// implementation) of the virtual address to specify which WAY to
105
// affect. The _ALL_WAYS macro defines the necessary cache instructions
106
// to affect all ways.
107
 
108
#ifdef HAL_MIPS_CACHE_INSN_USES_LSB
109
# define _IWAY(_n_) ((_n_)*HAL_ICACHE_SIZE/HAL_ICACHE_WAYS+(_n_))
110
# define _DWAY(_n_) ((_n_)*HAL_DCACHE_SIZE/HAL_DCACHE_WAYS+(_n_))
111
#else
112
# define _IWAY(_n_) ((_n_)*HAL_ICACHE_SIZE/HAL_ICACHE_WAYS)
113
# define _DWAY(_n_) ((_n_)*HAL_DCACHE_SIZE/HAL_DCACHE_WAYS)
114
#endif
115
 
116
#if (HAL_DCACHE_WAYS == 1)
117
#define _HAL_ASM_DCACHE_ALL_WAYS( _cmd_ , _addr_ )       \
118
    asm volatile ("cache %0,0(%1);"                      \
119
                    : : "I" ((_cmd_) | 1), "r"(_addr_) )
120
#elif (HAL_DCACHE_WAYS == 2)
121
#define _HAL_ASM_DCACHE_ALL_WAYS( _cmd_ , _addr_ )      \
122
    asm volatile ("cache %0,0(%1);"                     \
123
                  "cache %0,%2(%1);"                    \
124
                    : : "I" ((_cmd_) | 1), "r"(_addr_), \
125
                        "I" (_DWAY(1)))
126
#elif (HAL_DCACHE_WAYS == 4)
127
#define _HAL_ASM_DCACHE_ALL_WAYS( _cmd_ , _addr_ )      \
128
    asm volatile ("cache %0,0(%1);"                     \
129
                  "cache %0,%2(%1);"                    \
130
                  "cache %0,%3(%1);"                    \
131
                  "cache %0,%4(%1);"                    \
132
                    : : "I" ((_cmd_) | 1), "r"(_addr_), \
133
                        "I" (_DWAY(1)),                  \
134
                        "I" (_DWAY(2)),                  \
135
                        "I" (_DWAY(3)))
136
#else
137
# error "Unsupported number of ways"
138
#endif
139
 
140
#if (HAL_ICACHE_WAYS == 1)
141
#define _HAL_ASM_ICACHE_ALL_WAYS( _cmd_ , _addr_ )       \
142
    asm volatile ("cache %0,0(%1);"                      \
143
                    : : "I" (_cmd_), "r"(_addr_) )
144
#elif (HAL_ICACHE_WAYS == 2)
145
#define _HAL_ASM_ICACHE_ALL_WAYS( _cmd_ , _addr_ )      \
146
    asm volatile ("cache %0,0(%1);"                     \
147
                  "cache %0,%2(%1);"                    \
148
                    : : "I" (_cmd_), "r"(_addr_),       \
149
                        "I" (_IWAY(1)))
150
#elif (HAL_ICACHE_WAYS == 4)
151
#define _HAL_ASM_ICACHE_ALL_WAYS( _cmd_ , _addr_ )      \
152
    asm volatile ("cache %0,0(%1);"                     \
153
                  "cache %0,%2(%1);"                    \
154
                  "cache %0,%3(%1);"                    \
155
                  "cache %0,%4(%1);"                    \
156
                    : : "I" (_cmd_), "r"(_addr_),       \
157
                        "I" (_IWAY(1)),                  \
158
                        "I" (_IWAY(2)),                  \
159
                        "I" (_IWAY(3)))
160
#else
161
# error "Unsupported number of ways"
162
#endif
163
 
164
//-----------------------------------------------------------------------------
165
// Address adjustment.
166
// Given an address and a size, these macros return the first 
167
// cacheline containing the requested range and a terminating address.
168
 
169
#define HAL_DCACHE_START_ADDRESS(_addr_) \
170
(((CYG_ADDRESS)(_addr_)) & ~(HAL_DCACHE_LINE_SIZE-1))
171
 
172
#define HAL_DCACHE_END_ADDRESS(_addr_, _asize_) \
173
((CYG_ADDRESS)((_addr_) + (_asize_)))
174
 
175
#define HAL_ICACHE_START_ADDRESS(_addr_) \
176
(((CYG_ADDRESS)(_addr_)) & ~(HAL_ICACHE_LINE_SIZE-1))
177
 
178
#define HAL_ICACHE_END_ADDRESS(_addr_, _asize_) \
179
((CYG_ADDRESS)((_addr_) + (_asize_)))
180
 
181
//-----------------------------------------------------------------------------
182
// Global control of data cache
183
 
184
// Enable the data cache
185
// There is no default mechanism for enabling or disabling the caches.
186
#ifndef HAL_DCACHE_ENABLE_DEFINED
187
#define HAL_DCACHE_ENABLE()
188
#endif
189
 
190
// Disable the data cache
191
#ifndef HAL_DCACHE_DISABLE_DEFINED
192
#define HAL_DCACHE_DISABLE()
193
#endif
194
 
195
#ifndef HAL_DCACHE_IS_ENABLED_DEFINED
196
#define HAL_DCACHE_IS_ENABLED(_state_) (_state_) = 1;
197
#endif
198
 
199
// Invalidate the entire cache
200
// We simply use HAL_DCACHE_SYNC() to do this. For writeback caches this
201
// is not quite what we want, but there is no index-invalidate operation
202
// available.
203
#ifndef HAL_DCACHE_INVALIDATE_ALL_DEFINED
204
#define HAL_DCACHE_INVALIDATE_ALL() HAL_DCACHE_SYNC()
205
#endif
206
 
207
// Synchronize the contents of the cache with memory.
208
// This uses the index-writeback-invalidate operation.
209
#ifndef HAL_DCACHE_SYNC_DEFINED
210
#define HAL_DCACHE_SYNC()                                               \
211
    CYG_MACRO_START                                                     \
212
    register CYG_ADDRESS _baddr_ = 0x80000000;                          \
213
    register CYG_ADDRESS _addr_ = 0x80000000;                           \
214
    register CYG_WORD _size_ = HAL_DCACHE_SIZE;                         \
215
    _HAL_ASM_SET_MIPS_ISA(3);                                           \
216
    for( ; _addr_ <= _baddr_+_size_; _addr_ += HAL_DCACHE_LINE_SIZE )   \
217
    { _HAL_ASM_DCACHE_ALL_WAYS(0x01, _addr_); }                         \
218
    _HAL_ASM_SET_MIPS_ISA(0);                                           \
219
    CYG_MACRO_END
220
#endif
221
 
222
// Set the data cache refill burst size
223
//#define HAL_DCACHE_BURST_SIZE(_size_)
224
 
225
// Set the data cache write mode
226
//#define HAL_DCACHE_WRITE_MODE( _mode_ )
227
 
228
//#define HAL_DCACHE_WRITETHRU_MODE       0
229
//#define HAL_DCACHE_WRITEBACK_MODE       1
230
 
231
// Load the contents of the given address range into the data cache
232
// and then lock the cache so that it stays there.
233
// This uses the fetch-and-lock cache operation.
234
#ifndef HAL_DCACHE_LOCK_DEFINED
235
#define HAL_DCACHE_LOCK(_base_, _asize_)                                    \
236
    CYG_MACRO_START                                                         \
237
    register CYG_ADDRESS _addr_  = HAL_DCACHE_START_ADDRESS(_base_);        \
238
    register CYG_ADDRESS _eaddr_ = HAL_DCACHE_END_ADDRESS(_base_, _asize_); \
239
    register CYG_WORD _state_;                                              \
240
    HAL_DCACHE_IS_ENABLED( _state_ );                                       \
241
    if( _state_ ) {                                                         \
242
        _HAL_ASM_SET_MIPS_ISA(3);                                           \
243
        for( ; _addr_ < _eaddr_; _addr_ += HAL_DCACHE_LINE_SIZE )           \
244
        { _HAL_ASM_DCACHE_ALL_WAYS(0x1d, _addr_); }                         \
245
        _HAL_ASM_SET_MIPS_ISA(0);                                           \
246
    }                                                                       \
247
    CYG_MACRO_END
248
#endif
249
 
250
// Undo a previous lock operation.
251
// Do this by flushing the cache, which is defined to clear the lock bit.
252
#ifndef HAL_DCACHE_UNLOCK_DEFINED
253
#define HAL_DCACHE_UNLOCK(_base_, _size_) \
254
        HAL_DCACHE_FLUSH( _base_, _size_ )
255
#endif
256
 
257
// Unlock entire cache
258
#ifndef HAL_DCACHE_UNLOCK_ALL_DEFINED
259
#define HAL_DCACHE_UNLOCK_ALL() \
260
        HAL_DCACHE_INVALIDATE_ALL()
261
#endif
262
 
263
//-----------------------------------------------------------------------------
264
// Data cache line control
265
 
266
// Allocate cache lines for the given address range without reading its
267
// contents from memory.
268
//#define HAL_DCACHE_ALLOCATE( _base_ , _size_ )
269
 
270
// Write dirty cache lines to memory and invalidate the cache entries
271
// for the given address range.
272
// This uses the hit-writeback-invalidate cache operation.
273
#ifndef HAL_DCACHE_FLUSH_DEFINED
274
#define HAL_DCACHE_FLUSH( _base_ , _asize_ )                                \
275
    CYG_MACRO_START                                                         \
276
    register CYG_ADDRESS _addr_  = HAL_DCACHE_START_ADDRESS(_base_);        \
277
    register CYG_ADDRESS _eaddr_ = HAL_DCACHE_END_ADDRESS(_base_, _asize_); \
278
    register CYG_WORD _state_;                                              \
279
    HAL_DCACHE_IS_ENABLED( _state_ );                                       \
280
    if( _state_ ) {                                                         \
281
        _HAL_ASM_SET_MIPS_ISA(3);                                           \
282
        for( ; _addr_ < _eaddr_; _addr_ += HAL_DCACHE_LINE_SIZE )           \
283
        { _HAL_ASM_DCACHE_ALL_WAYS(0x15, _addr_); }                         \
284
        _HAL_ASM_SET_MIPS_ISA(0);                                           \
285
    }                                                                       \
286
    CYG_MACRO_END
287
#endif
288
 
289
// Invalidate cache lines in the given range without writing to memory.
290
// This uses the hit-invalidate cache operation.
291
#ifndef HAL_DCACHE_INVALIDATE_DEFINED
292
#define HAL_DCACHE_INVALIDATE( _base_ , _asize_ )                           \
293
    CYG_MACRO_START                                                         \
294
    register CYG_ADDRESS _addr_  = HAL_DCACHE_START_ADDRESS(_base_);        \
295
    register CYG_ADDRESS _eaddr_ = HAL_DCACHE_END_ADDRESS(_base_, _asize_); \
296
    _HAL_ASM_SET_MIPS_ISA(3);                                               \
297
    for( ; _addr_ < _eaddr_; _addr_ += HAL_DCACHE_LINE_SIZE )               \
298
    { _HAL_ASM_DCACHE_ALL_WAYS(0x11, _addr_); }                             \
299
    _HAL_ASM_SET_MIPS_ISA(0);                                               \
300
    CYG_MACRO_END
301
#endif
302
 
303
// Write dirty cache lines to memory for the given address range.
304
// This uses the hit-writeback cache operation.
305
#ifndef HAL_DCACHE_STORE_DEFINED
306
#define HAL_DCACHE_STORE( _base_ , _asize_ )                                \
307
    CYG_MACRO_START                                                         \
308
    register CYG_ADDRESS _addr_  = HAL_DCACHE_START_ADDRESS(_base_);        \
309
    register CYG_ADDRESS _eaddr_ = HAL_DCACHE_END_ADDRESS(_base_, _asize_); \
310
    register CYG_WORD _state_;                                              \
311
    HAL_DCACHE_IS_ENABLED( _state_ );                                       \
312
    if( _state_ ) {                                                         \
313
        _HAL_ASM_SET_MIPS_ISA(3);                                           \
314
        for( ; _addr_ < _eaddr_; _addr_ += HAL_DCACHE_LINE_SIZE )           \
315
        { _HAL_ASM_DCACHE_ALL_WAYS(0x19, _addr_); }                         \
316
        _HAL_ASM_SET_MIPS_ISA(0);                                           \
317
    }                                                                       \
318
    CYG_MACRO_END
319
#endif
320
 
321
// Preread the given range into the cache with the intention of reading
322
// from it later.
323
//#define HAL_DCACHE_READ_HINT( _base_ , _size_ )
324
 
325
// Preread the given range into the cache with the intention of writing
326
// to it later.
327
//#define HAL_DCACHE_WRITE_HINT( _base_ , _size_ )
328
 
329
// Allocate and zero the cache lines associated with the given range.
330
//#define HAL_DCACHE_ZERO( _base_ , _size_ )
331
 
332
//-----------------------------------------------------------------------------
333
// Global control of Instruction cache
334
 
335
// Enable the instruction cache
336
// There is no default mechanism for enabling or disabling the caches.
337
#ifndef HAL_ICACHE_ENABLE_DEFINED
338
#define HAL_ICACHE_ENABLE()
339
#endif
340
 
341
// Disable the instruction cache
342
#ifndef HAL_ICACHE_DISABLE_DEFINED
343
#define HAL_ICACHE_DISABLE()
344
#endif
345
 
346
#ifndef HAL_ICACHE_IS_ENABLED_DEFINED
347
#define HAL_ICACHE_IS_ENABLED(_state_) (_state_) = 1;
348
#endif
349
 
350
// Invalidate the entire cache
351
// This uses the index-invalidate cache operation.
352
#ifndef HAL_ICACHE_INVALIDATE_ALL_DEFINED
353
#define HAL_ICACHE_INVALIDATE_ALL()                                           \
354
    CYG_MACRO_START                                                           \
355
    register CYG_ADDRESS _baddr_ = 0x80000000;                                \
356
    register CYG_ADDRESS _addr_ = 0x80000000;                                 \
357
    _HAL_ASM_SET_MIPS_ISA(3);                                                 \
358
    for( ; _addr_ < _baddr_+HAL_ICACHE_SIZE; _addr_ += HAL_ICACHE_LINE_SIZE ) \
359
    { _HAL_ASM_ICACHE_ALL_WAYS(0x00, _addr_); }                               \
360
    _HAL_ASM_SET_MIPS_ISA(0);                                                 \
361
    CYG_MACRO_END
362
#endif
363
 
364
// Synchronize the contents of the cache with memory.
365
// Simply force the cache to reload.
366
#ifndef HAL_ICACHE_SYNC_DEFINED
367
#define HAL_ICACHE_SYNC() HAL_ICACHE_INVALIDATE_ALL()
368
#endif
369
 
370
// Set the instruction cache refill burst size
371
//#define HAL_ICACHE_BURST_SIZE(_size_)
372
 
373
// Load the contents of the given address range into the instruction cache
374
// and then lock the cache so that it stays there.
375
// This uses the fetch-and-lock cache operation.
376
#ifndef HAL_ICACHE_LOCK_DEFINED
377
#define HAL_ICACHE_LOCK(_base_, _asize_)                                    \
378
    CYG_MACRO_START                                                         \
379
    register CYG_ADDRESS _addr_  = HAL_ICACHE_START_ADDRESS(_base_);        \
380
    register CYG_ADDRESS _eaddr_ = HAL_ICACHE_END_ADDRESS(_base_, _asize_); \
381
    register CYG_WORD _state_;                                              \
382
    HAL_ICACHE_IS_ENABLED( _state_ );                                       \
383
    if( _state_ ) {                                                         \
384
        _HAL_ASM_SET_MIPS_ISA(3);                                           \
385
        for( ; _addr_ < _eaddr_; _addr_ += HAL_ICACHE_LINE_SIZE )           \
386
        { _HAL_ASM_ICACHE_ALL_WAYS(0x1c, _addr_); }                         \
387
        _HAL_ASM_SET_MIPS_ISA(0);                                           \
388
    }                                                                       \
389
    CYG_MACRO_END
390
#endif
391
 
392
// Undo a previous lock operation.
393
// Do this by invalidating the cache, which is defined to clear the lock bit.
394
#ifndef HAL_ICACHE_UNLOCK_DEFINED
395
#define HAL_ICACHE_UNLOCK(_base_, _size_) \
396
        HAL_ICACHE_INVALIDATE( _base_, _size_ )
397
#endif
398
 
399
// Unlock entire cache
400
//#define HAL_ICACHE_UNLOCK_ALL()
401
 
402
//-----------------------------------------------------------------------------
403
// Instruction cache line control
404
 
405
// Invalidate cache lines in the given range without writing to memory.
406
// This uses the hit-invalidate cache operation.
407
#ifndef HAL_ICACHE_INVALIDATE_DEFINED
408
#define HAL_ICACHE_INVALIDATE( _base_ , _asize_ )                           \
409
    CYG_MACRO_START                                                         \
410
    register CYG_ADDRESS _addr_  = HAL_ICACHE_START_ADDRESS(_base_);        \
411
    register CYG_ADDRESS _eaddr_ = HAL_ICACHE_END_ADDRESS(_base_, _asize_); \
412
    _HAL_ASM_SET_MIPS_ISA(3);                                               \
413
    for( ; _addr_ < _eaddr_; _addr_ += HAL_ICACHE_LINE_SIZE )               \
414
    { _HAL_ASM_ICACHE_ALL_WAYS(0x10, _addr_); }                             \
415
    _HAL_ASM_SET_MIPS_ISA(0);                                               \
416
    CYG_MACRO_END
417
#endif
418
 
419
//-----------------------------------------------------------------------------
420
// Check that a supported configuration has actually defined some macros.
421
 
422
#ifndef HAL_DCACHE_ENABLE
423
 
424
#error Unsupported MIPS configuration
425
 
426
#endif
427
 
428
//-----------------------------------------------------------------------------
429
#endif // ifndef CYGONCE_HAL_CACHE_H
430
// 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.