source: rtems/c/src/lib/libcpu/shared/src/cache_manager.c @ fc6a0ae

4.11
Last change on this file since fc6a0ae was fc6a0ae, checked in by Aleksandr Platonov <pam@…>, on Jan 14, 2014 at 1:40:07 PM

rtems_cache_invalidate_multiple_instruction_lines

According with comment in
rtems_cache_invalidate_multiple_instruction_lines(), final_address
indicates the last address which needs to be invalidated. But if in
while loop we got final_address == i_addr condition then loop breaks and
final_address will not be invalidated.

  • Property mode set to 100644
File size: 7.7 KB
Line 
1/*
2 *  Cache Manager
3 *
4 *  COPYRIGHT (c) 1989-1999.
5 *  On-Line Applications Research Corporation (OAR).
6 *
7 *  The license and distribution terms for this file may be
8 *  found in the file LICENSE in this distribution or at
9 *  http://www.rtems.com/license/LICENSE.
10 *
11 *
12 *  The functions in this file implement the API to the RTEMS Cache Manager and
13 *  are divided into data cache and instruction cache functions. Data cache
14 *  functions only have bodies if a data cache is supported. Instruction
15 *  cache functions only have bodies if an instruction cache is supported.
16 *  Support for a particular cache exists only if CPU_x_CACHE_ALIGNMENT is
17 *  defined, where x E {DATA, INSTRUCTION}. These definitions are found in
18 *  the Cache Manager Wrapper header files, often
19 *
20 *  rtems/c/src/lib/libcpu/CPU/cache_.h
21 *
22 *  The cache implementation header file can define
23 *  CPU_CACHE_SUPPORT_PROVIDES_RANGE_FUNCTIONS
24 *  if it provides cache maintenance functions which operate on multiple lines.
25 *  Otherwise a generic loop with single line operations will be used.
26 *
27 *  The functions below are implemented with CPU dependent inline routines
28 *  found in the cache.c files for each CPU. In the event that a CPU does
29 *  not support a specific function for a cache it has, the CPU dependent
30 *  routine does nothing (but does exist).
31 *
32 *  At this point, the Cache Manager makes no considerations, and provides no
33 *  support for BSP specific issues such as a secondary cache. In such a system,
34 *  the CPU dependent routines would have to be modified, or a BSP layer added
35 *  to this Manager.
36 */
37
38#include <rtems.h>
39#include "cache_.h"
40
41/*
42 * THESE FUNCTIONS ONLY HAVE BODIES IF WE HAVE A DATA CACHE
43 */
44
45/*
46 * This function is called to flush the data cache by performing cache
47 * copybacks. It must determine how many cache lines need to be copied
48 * back and then perform the copybacks.
49 */
50void
51rtems_cache_flush_multiple_data_lines( const void * d_addr, size_t n_bytes )
52{
53#if defined(CPU_DATA_CACHE_ALIGNMENT)
54#if defined(CPU_CACHE_SUPPORT_PROVIDES_RANGE_FUNCTIONS)
55  _CPU_cache_flush_data_range( d_addr, n_bytes );
56#else
57  const void * final_address;
58
59 /*
60  * Set d_addr to the beginning of the cache line; final_address indicates
61  * the last address_t which needs to be pushed. Increment d_addr and push
62  * the resulting line until final_address is passed.
63  */
64
65  if( n_bytes == 0 )
66    /* Do nothing if number of bytes to flush is zero */
67    return;
68
69  final_address = (void *)((size_t)d_addr + n_bytes - 1);
70  d_addr = (void *)((size_t)d_addr & ~(CPU_DATA_CACHE_ALIGNMENT - 1));
71  while( d_addr <= final_address )  {
72    _CPU_cache_flush_1_data_line( d_addr );
73    d_addr = (void *)((size_t)d_addr + CPU_DATA_CACHE_ALIGNMENT);
74  }
75#endif
76#endif
77}
78
79
80/*
81 * This function is responsible for performing a data cache invalidate.
82 * It must determine how many cache lines need to be invalidated and then
83 * perform the invalidations.
84 */
85
86void
87rtems_cache_invalidate_multiple_data_lines( const void * d_addr, size_t n_bytes )
88{
89#if defined(CPU_DATA_CACHE_ALIGNMENT)
90#if defined(CPU_CACHE_SUPPORT_PROVIDES_RANGE_FUNCTIONS)
91  _CPU_cache_invalidate_data_range( d_addr, n_bytes );
92#else
93  const void * final_address;
94
95 /*
96  * Set d_addr to the beginning of the cache line; final_address indicates
97  * the last address_t which needs to be invalidated. Increment d_addr and
98  * invalidate the resulting line until final_address is passed.
99  */
100
101  if( n_bytes == 0 )
102    /* Do nothing if number of bytes to invalidate is zero */
103    return;
104
105  final_address = (void *)((size_t)d_addr + n_bytes - 1);
106  d_addr = (void *)((size_t)d_addr & ~(CPU_DATA_CACHE_ALIGNMENT - 1));
107  while( final_address >= d_addr ) {
108    _CPU_cache_invalidate_1_data_line( d_addr );
109    d_addr = (void *)((size_t)d_addr + CPU_DATA_CACHE_ALIGNMENT);
110  }
111#endif
112#endif
113}
114
115
116/*
117 * This function is responsible for performing a data cache flush.
118 * It flushes the entire cache.
119 */
120void
121rtems_cache_flush_entire_data( void )
122{
123#if defined(CPU_DATA_CACHE_ALIGNMENT)
124   /*
125    * Call the CPU-specific routine
126    */
127   _CPU_cache_flush_entire_data();
128#endif
129}
130
131
132/*
133 * This function is responsible for performing a data cache
134 * invalidate. It invalidates the entire cache.
135 */
136void
137rtems_cache_invalidate_entire_data( void )
138{
139#if defined(CPU_DATA_CACHE_ALIGNMENT)
140 /*
141  * Call the CPU-specific routine
142  */
143
144 _CPU_cache_invalidate_entire_data();
145#endif
146}
147
148
149/*
150 * This function returns the data cache granularity.
151 */
152int
153rtems_cache_get_data_line_size( void )
154{
155#if defined(CPU_DATA_CACHE_ALIGNMENT)
156  return CPU_DATA_CACHE_ALIGNMENT;
157#else
158  return 0;
159#endif
160}
161
162
163/*
164 * This function freezes the data cache; cache lines
165 * are not replaced.
166 */
167void
168rtems_cache_freeze_data( void )
169{
170#if defined(CPU_DATA_CACHE_ALIGNMENT)
171  _CPU_cache_freeze_data();
172#endif
173}
174
175
176/*
177 * This function unfreezes the instruction cache.
178 */
179void rtems_cache_unfreeze_data( void )
180{
181#if defined(CPU_DATA_CACHE_ALIGNMENT)
182  _CPU_cache_unfreeze_data();
183#endif
184}
185
186
187/* Turn on the data cache. */
188void
189rtems_cache_enable_data( void )
190{
191#if defined(CPU_DATA_CACHE_ALIGNMENT)
192  _CPU_cache_enable_data();
193#endif
194}
195
196
197/* Turn off the data cache. */
198void
199rtems_cache_disable_data( void )
200{
201#if defined(CPU_DATA_CACHE_ALIGNMENT)
202  _CPU_cache_disable_data();
203#endif
204}
205
206
207
208/*
209 * THESE FUNCTIONS ONLY HAVE BODIES IF WE HAVE AN INSTRUCTION CACHE
210 */
211
212/*
213 * This function is responsible for performing an instruction cache
214 * invalidate. It must determine how many cache lines need to be invalidated
215 * and then perform the invalidations.
216 */
217void
218rtems_cache_invalidate_multiple_instruction_lines( const void * i_addr, size_t n_bytes )
219{
220#if defined(CPU_INSTRUCTION_CACHE_ALIGNMENT)
221#if defined(CPU_CACHE_SUPPORT_PROVIDES_RANGE_FUNCTIONS)
222  _CPU_cache_invalidate_instruction_range( i_addr, n_bytes );
223#else
224  const void * final_address;
225
226 /*
227  * Set i_addr to the beginning of the cache line; final_address indicates
228  * the last address_t which needs to be invalidated. Increment i_addr and
229  * invalidate the resulting line until final_address is passed.
230  */
231
232  if( n_bytes == 0 )
233    /* Do nothing if number of bytes to invalidate is zero */
234    return;
235
236  final_address = (void *)((size_t)i_addr + n_bytes - 1);
237  i_addr = (void *)((size_t)i_addr & ~(CPU_INSTRUCTION_CACHE_ALIGNMENT - 1));
238  while( final_address >= i_addr ) {
239    _CPU_cache_invalidate_1_instruction_line( i_addr );
240    i_addr = (void *)((size_t)i_addr + CPU_INSTRUCTION_CACHE_ALIGNMENT);
241  }
242#endif
243#endif
244}
245
246
247/*
248 * This function is responsible for performing an instruction cache
249 * invalidate. It invalidates the entire cache.
250 */
251void
252rtems_cache_invalidate_entire_instruction( void )
253{
254#if defined(CPU_INSTRUCTION_CACHE_ALIGNMENT)
255 /*
256  * Call the CPU-specific routine
257  */
258
259 _CPU_cache_invalidate_entire_instruction();
260#endif
261}
262
263
264/*
265 * This function returns the instruction cache granularity.
266 */
267int
268rtems_cache_get_instruction_line_size( void )
269{
270#if defined(CPU_INSTRUCTION_CACHE_ALIGNMENT)
271  return CPU_INSTRUCTION_CACHE_ALIGNMENT;
272#else
273  return 0;
274#endif
275}
276
277
278/*
279 * This function freezes the instruction cache; cache lines
280 * are not replaced.
281 */
282void
283rtems_cache_freeze_instruction( void )
284{
285#if defined(CPU_INSTRUCTION_CACHE_ALIGNMENT)
286  _CPU_cache_freeze_instruction();
287#endif
288}
289
290
291/*
292 * This function unfreezes the instruction cache.
293 */
294void rtems_cache_unfreeze_instruction( void )
295{
296#if defined(CPU_INSTRUCTION_CACHE_ALIGNMENT)
297  _CPU_cache_unfreeze_instruction();
298#endif
299}
300
301
302/* Turn on the instruction cache. */
303void
304rtems_cache_enable_instruction( void )
305{
306#if defined(CPU_INSTRUCTION_CACHE_ALIGNMENT)
307  _CPU_cache_enable_instruction();
308#endif
309}
310
311
312/* Turn off the instruction cache. */
313void
314rtems_cache_disable_instruction( void )
315{
316#if defined(CPU_INSTRUCTION_CACHE_ALIGNMENT)
317  _CPU_cache_disable_instruction();
318#endif
319}
Note: See TracBrowser for help on using the repository browser.