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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [ecos-3.0/] [packages/] [kernel/] [current/] [tests/] [kcache1.c] - Blame information for rev 851

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

Line No. Rev Author Line
1 786 skrzyp
/*=================================================================
2
//
3
//        kcache1.c
4
//
5
//        Cache timing test
6
//
7
//==========================================================================
8
// ####ECOSGPLCOPYRIGHTBEGIN####
9
// -------------------------------------------
10
// This file is part of eCos, the Embedded Configurable Operating System.
11
// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
12
//
13
// eCos is free software; you can redistribute it and/or modify it under
14
// the terms of the GNU General Public License as published by the Free
15
// Software Foundation; either version 2 or (at your option) any later
16
// version.
17
//
18
// eCos is distributed in the hope that it will be useful, but WITHOUT
19
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
20
// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
21
// for more details.
22
//
23
// You should have received a copy of the GNU General Public License
24
// along with eCos; if not, write to the Free Software Foundation, Inc.,
25
// 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
26
//
27
// As a special exception, if other files instantiate templates or use
28
// macros or inline functions from this file, or you compile this file
29
// and link it with other works to produce a work based on this file,
30
// this file does not by itself cause the resulting work to be covered by
31
// the GNU General Public License. However the source code for this file
32
// must still be made available in accordance with section (3) of the GNU
33
// General Public License v2.
34
//
35
// This exception does not invalidate any other reasons why a work based
36
// on this file might be covered by the GNU General Public License.
37
// -------------------------------------------
38
// ####ECOSGPLCOPYRIGHTEND####
39
//==========================================================================
40
//#####DESCRIPTIONBEGIN####
41
//
42
// Author(s):     dsm
43
// Contributors:  dsm, nickg
44
// Date:          1998-06-18
45
//####DESCRIPTIONEND####
46
*/
47
 
48
#include <cyg/hal/hal_arch.h>           // CYGNUM_HAL_STACK_SIZE_TYPICAL
49
 
50
#include <cyg/kernel/kapi.h>
51
 
52
#include <cyg/infra/testcase.h>
53
 
54
#include <cyg/hal/hal_cache.h>
55
 
56
#if defined(HAL_DCACHE_SIZE) || defined(HAL_UCACHE_SIZE)
57
#ifdef CYGVAR_KERNEL_COUNTERS_CLOCK
58
#ifdef CYGFUN_KERNEL_API_C
59
 
60
#include <cyg/infra/diag.h>
61
#include <cyg/hal/hal_intr.h>
62
 
63
// -------------------------------------------------------------------------
64
// If the HAL does not supply this, we supply our own version
65
 
66
#ifndef HAL_DCACHE_PURGE_ALL
67
# ifdef HAL_DCACHE_SYNC
68
 
69
#define HAL_DCACHE_PURGE_ALL() HAL_DCACHE_SYNC()
70
 
71
# else
72
 
73
static cyg_uint8 dca[HAL_DCACHE_SIZE + HAL_DCACHE_LINE_SIZE*2];
74
 
75
#define HAL_DCACHE_PURGE_ALL()                                          \
76
CYG_MACRO_START                                                         \
77
    volatile cyg_uint8 *addr = &dca[HAL_DCACHE_LINE_SIZE];              \
78
    volatile cyg_uint8 tmp = 0;                                         \
79
    int i;                                                              \
80
    for( i = 0; i < HAL_DCACHE_SIZE; i += HAL_DCACHE_LINE_SIZE )        \
81
    {                                                                   \
82
        tmp = addr[i];                                                  \
83
    }                                                                   \
84
CYG_MACRO_END
85
 
86
# endif
87
#endif
88
 
89
// -------------------------------------------------------------------------
90
 
91
#define NTHREADS 1
92
#define STACKSIZE CYGNUM_HAL_STACK_SIZE_TYPICAL
93
 
94
static cyg_handle_t thread[NTHREADS];
95
 
96
static cyg_thread thread_obj[NTHREADS];
97
static char stack[NTHREADS][STACKSIZE];
98
 
99
#ifndef MAX_STRIDE
100
#define MAX_STRIDE 64
101
#endif
102
 
103
volatile char m[(HAL_DCACHE_SIZE/HAL_DCACHE_LINE_SIZE)*MAX_STRIDE];
104
 
105
// -------------------------------------------------------------------------
106
 
107
static void time0(register cyg_uint32 stride)
108
{
109
    register cyg_uint32 j,k;
110
    cyg_tick_count_t count0, count1;
111
    cyg_ucount32 t;
112
    register char c;
113
 
114
    count0 = cyg_current_time();
115
 
116
    k = 0;
117
    if ( cyg_test_is_simulator )
118
        k = 3960;
119
 
120
    for(; k<4000;k++) {
121
        for(j=0; j<(HAL_DCACHE_SIZE/HAL_DCACHE_LINE_SIZE); j++) {
122
            c=m[stride*j];
123
        }
124
    }
125
 
126
    count1 = cyg_current_time();
127
    t = count1 - count0;
128
    diag_printf("stride=%d, time=%d\n", stride, t);
129
}
130
 
131
// -------------------------------------------------------------------------
132
 
133
void time1(void)
134
{
135
    cyg_uint32 i;
136
 
137
    for(i=1; i<=MAX_STRIDE; i+=i) {
138
        time0(i);
139
    }
140
}
141
 
142
// -------------------------------------------------------------------------
143
// With an ICache invalidate in the middle:
144
#ifdef HAL_ICACHE_INVALIDATE_ALL
145
static void time0II(register cyg_uint32 stride)
146
{
147
    register cyg_uint32 j,k;
148
    cyg_tick_count_t count0, count1;
149
    cyg_ucount32 t;
150
    register char c;
151
 
152
    count0 = cyg_current_time();
153
 
154
    k = 0;
155
    if ( cyg_test_is_simulator )
156
        k = 3960;
157
 
158
    for(; k<4000;k++) {
159
        for(j=0; j<(HAL_DCACHE_SIZE/HAL_DCACHE_LINE_SIZE); j++) {
160
            HAL_ICACHE_INVALIDATE_ALL();
161
            c=m[stride*j];
162
        }
163
    }
164
 
165
    count1 = cyg_current_time();
166
    t = count1 - count0;
167
    diag_printf("stride=%d, time=%d\n", stride, t);
168
}
169
 
170
// -------------------------------------------------------------------------
171
 
172
void time1II(void)
173
{
174
    cyg_uint32 i;
175
 
176
    for(i=1; i<=MAX_STRIDE; i+=i) {
177
        time0II(i);
178
    }
179
}
180
#endif
181
// -------------------------------------------------------------------------
182
// With a DCache invalidate in the middle:
183
// This is guaranteed to produce bogus timing results since interrupts
184
// have to be disabled to prevent accidental loss of state.
185
#ifdef HAL_DCACHE_INVALIDATE_ALL
186
static void time0DI(register cyg_uint32 stride)
187
{
188
    register cyg_uint32 j,k;
189
    volatile cyg_tick_count_t count0;
190
    cyg_tick_count_t count1;
191
    cyg_ucount32 t;
192
    register char c;
193
    register CYG_INTERRUPT_STATE oldints;
194
 
195
    count0 = cyg_current_time();
196
 
197
    HAL_DISABLE_INTERRUPTS(oldints);
198
    HAL_DCACHE_SYNC();
199
 
200
    k = 0;
201
    if ( cyg_test_is_simulator )
202
        k = 3960;
203
 
204
    for(; k<4000;k++) {
205
        for(j=0; j<(HAL_DCACHE_SIZE/HAL_DCACHE_LINE_SIZE); j++) {
206
            HAL_DCACHE_INVALIDATE_ALL();
207
            c=m[stride*j];
208
        }
209
    }
210
    HAL_RESTORE_INTERRUPTS(oldints);
211
 
212
    count1 = cyg_current_time();
213
    t = count1 - count0;
214
    diag_printf("stride=%d, time=%d\n", stride, t);
215
}
216
 
217
// -------------------------------------------------------------------------
218
 
219
void time1DI(void)
220
{
221
    cyg_uint32 i;
222
 
223
    for(i=1; i<=MAX_STRIDE; i+=i) {
224
        time0DI(i);
225
    }
226
}
227
#endif
228
// -------------------------------------------------------------------------
229
// This test could be improved by counting number of passes possible 
230
// in a given number of ticks.
231
 
232
static void entry0( cyg_addrword_t data )
233
{
234
    register CYG_INTERRUPT_STATE oldints;
235
 
236
#ifdef HAL_CACHE_UNIFIED
237
 
238
    HAL_DISABLE_INTERRUPTS(oldints);
239
    HAL_DCACHE_PURGE_ALL();             // rely on above definition
240
    HAL_UCACHE_INVALIDATE_ALL();
241
    HAL_UCACHE_DISABLE();
242
    HAL_RESTORE_INTERRUPTS(oldints);
243
    CYG_TEST_INFO("Cache off");
244
    time1();
245
 
246
    HAL_DISABLE_INTERRUPTS(oldints);
247
    HAL_DCACHE_PURGE_ALL();             // rely on above definition
248
    HAL_UCACHE_INVALIDATE_ALL();
249
    HAL_UCACHE_ENABLE();
250
    HAL_RESTORE_INTERRUPTS(oldints);
251
    CYG_TEST_INFO("Cache on");
252
    time1();
253
 
254
#ifdef HAL_DCACHE_INVALIDATE_ALL
255
    HAL_DISABLE_INTERRUPTS(oldints);
256
    HAL_DCACHE_PURGE_ALL();
257
    HAL_UCACHE_INVALIDATE_ALL();
258
    HAL_UCACHE_ENABLE();
259
    HAL_RESTORE_INTERRUPTS(oldints);
260
    CYG_TEST_INFO("Cache on: invalidate Cache (expect bogus timing)");
261
    time1DI();
262
#endif
263
 
264
#else // HAL_CACHE_UNIFIED
265
 
266
    HAL_DISABLE_INTERRUPTS(oldints);
267
    HAL_DCACHE_PURGE_ALL();
268
    HAL_ICACHE_INVALIDATE_ALL();
269
    HAL_DCACHE_INVALIDATE_ALL();
270
    HAL_ICACHE_DISABLE();
271
    HAL_DCACHE_DISABLE();
272
    HAL_RESTORE_INTERRUPTS(oldints);
273
    CYG_TEST_INFO("Dcache off Icache off");
274
    time1();
275
 
276
    HAL_DISABLE_INTERRUPTS(oldints);
277
    HAL_DCACHE_PURGE_ALL();
278
    HAL_ICACHE_INVALIDATE_ALL();
279
    HAL_DCACHE_INVALIDATE_ALL();
280
    HAL_ICACHE_DISABLE();
281
    HAL_DCACHE_ENABLE();
282
    HAL_RESTORE_INTERRUPTS(oldints);
283
    CYG_TEST_INFO("Dcache on  Icache off");
284
    time1();
285
 
286
    HAL_DISABLE_INTERRUPTS(oldints);
287
    HAL_DCACHE_PURGE_ALL();
288
    HAL_ICACHE_INVALIDATE_ALL();
289
    HAL_DCACHE_INVALIDATE_ALL();
290
    HAL_ICACHE_ENABLE();
291
    HAL_DCACHE_DISABLE();
292
    HAL_RESTORE_INTERRUPTS(oldints);
293
    CYG_TEST_INFO("Dcache off Icache on");
294
    time1();
295
 
296
    HAL_DISABLE_INTERRUPTS(oldints);
297
    HAL_DCACHE_PURGE_ALL();
298
    HAL_ICACHE_INVALIDATE_ALL();
299
    HAL_DCACHE_INVALIDATE_ALL();
300
    HAL_ICACHE_ENABLE();
301
    HAL_DCACHE_ENABLE();
302
    HAL_RESTORE_INTERRUPTS(oldints);
303
    CYG_TEST_INFO("Dcache on Icache on");
304
    time1();
305
 
306
 
307
    HAL_DISABLE_INTERRUPTS(oldints);
308
    HAL_DCACHE_PURGE_ALL();
309
    HAL_ICACHE_INVALIDATE_ALL();
310
    HAL_DCACHE_INVALIDATE_ALL();
311
    HAL_ICACHE_DISABLE();
312
    HAL_DCACHE_DISABLE();
313
    HAL_RESTORE_INTERRUPTS(oldints);
314
    CYG_TEST_INFO("Dcache off Icache off (again)");
315
    time1();
316
 
317
#if defined(HAL_DCACHE_INVALIDATE_ALL) || defined(HAL_ICACHE_INVALIDATE_ALL)
318
    HAL_DISABLE_INTERRUPTS(oldints);
319
    HAL_DCACHE_PURGE_ALL();
320
    HAL_ICACHE_INVALIDATE_ALL();
321
    HAL_DCACHE_INVALIDATE_ALL();
322
    HAL_ICACHE_ENABLE();
323
    HAL_DCACHE_ENABLE();
324
    HAL_RESTORE_INTERRUPTS(oldints);
325
    CYG_TEST_INFO("Dcache on Icache on (again)");
326
    time1();
327
 
328
#if defined(CYGPKG_HAL_MIPS)
329
    // In some architectures, the time taken for the next two tests is
330
    // very long, partly because HAL_XCACHE_INVALIDATE_ALL() is implemented
331
    // with a loop over the cache. Hence these tests take longer than the
332
    // testing infrastructure is prepared to wait. The simplest way to get
333
    // these tests to run quickly is to make them think they are running
334
    // under a simulator.
335
    // If the target actually is a simulator, skip the below - it's very
336
    // slow on the simulator, even with reduced loop counts.
337
    if (cyg_test_is_simulator)
338
        CYG_TEST_PASS_FINISH("End of test");
339
 
340
#if defined(CYGPKG_HAL_MIPS_TX49)
341
    // The TX49 has a large cache, and even with reduced loop count,
342
    // 90+ seconds elapses between each INFO output.
343
    CYG_TEST_PASS_FINISH("End of test");
344
#endif
345
 
346
    cyg_test_is_simulator = 1;
347
#endif    
348
 
349
#ifdef HAL_ICACHE_INVALIDATE_ALL
350
    HAL_DISABLE_INTERRUPTS(oldints);
351
    HAL_DCACHE_PURGE_ALL();
352
    HAL_ICACHE_INVALIDATE_ALL();
353
    HAL_DCACHE_INVALIDATE_ALL();
354
    HAL_ICACHE_ENABLE();
355
    HAL_DCACHE_ENABLE();
356
    HAL_RESTORE_INTERRUPTS(oldints);
357
    CYG_TEST_INFO("Dcache on Icache on: invalidate ICache each time");
358
    time1II();
359
#endif
360
#ifdef HAL_DCACHE_INVALIDATE_ALL
361
    HAL_DISABLE_INTERRUPTS(oldints);
362
    HAL_DCACHE_PURGE_ALL();
363
    HAL_ICACHE_INVALIDATE_ALL();
364
    HAL_DCACHE_INVALIDATE_ALL();
365
    HAL_ICACHE_ENABLE();
366
    HAL_DCACHE_ENABLE();
367
    HAL_RESTORE_INTERRUPTS(oldints);
368
    CYG_TEST_INFO("Dcache on Icache on: invalidate DCache (expect bogus times)");
369
    time1DI();
370
#endif
371
#endif // either INVALIDATE_ALL macro
372
 
373
#endif // HAL_CACHE_UNIFIED
374
 
375
    CYG_TEST_PASS_FINISH("End of test");
376
}
377
 
378
// -------------------------------------------------------------------------
379
 
380
void kcache2_main( void )
381
{
382
    CYG_TEST_INIT();
383
 
384
    cyg_thread_create(4, entry0 , (cyg_addrword_t)0, "kcache1",
385
        (void *)stack[0], STACKSIZE, &thread[0], &thread_obj[0]);
386
    cyg_thread_resume(thread[0]);
387
 
388
    cyg_scheduler_start();
389
}
390
 
391
// -------------------------------------------------------------------------
392
 
393
externC void
394
cyg_start( void )
395
{
396
    kcache2_main();
397
}
398
 
399
// -------------------------------------------------------------------------
400
 
401
#else // def CYGFUN_KERNEL_API_C
402
#define N_A_MSG "Kernel C API layer disabled"
403
#endif // def CYGFUN_KERNEL_API_C
404
#else // def CYGVAR_KERNEL_COUNTERS_CLOCK
405
#define N_A_MSG "Kernel real-time clock disabled"
406
#endif // def CYGVAR_KERNEL_COUNTERS_CLOCK
407
#else // def HAL_DCACHE_SIZE
408
#define N_A_MSG "No caches defined"
409
#endif // def HAL_DCACHE_SIZE
410
 
411
#ifdef N_A_MSG
412
externC void
413
cyg_start( void )
414
{
415
    CYG_TEST_INIT();
416
    CYG_TEST_NA( N_A_MSG );
417
}
418
#endif // N_A_MSG
419
 
420
// -------------------------------------------------------------------------
421
/* EOF kcache1.c */

powered by: WebSVN 2.1.0

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