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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [or1ksim/] [testsuite/] [test-code-or1k/] [cache/] [cache.c] - Blame information for rev 123

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

Line No. Rev Author Line
1 90 jeremybenn
/* cache.c. Cache test of Or1ksim
2
 
3
   Copyright (C) 1999-2006 OpenCores
4
   Copyright (C) 2010 Embecosm Limited
5
 
6
   Contributors various OpenCores participants
7
   Contributor Jeremy Bennett <jeremy.bennett@embecosm.com>
8
 
9
   This file is part of OpenRISC 1000 Architectural Simulator.
10
 
11
   This program is free software; you can redistribute it and/or modify it
12
   under the terms of the GNU General Public License as published by the Free
13
   Software Foundation; either version 3 of the License, or (at your option)
14
   any later version.
15
 
16
   This program is distributed in the hope that it will be useful, but WITHOUT
17
   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18
   FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
19
   more details.
20
 
21
   You should have received a copy of the GNU General Public License along
22
   with this program.  If not, see <http:  www.gnu.org/licenses/>.  */
23
 
24
/* ----------------------------------------------------------------------------
25
   This code is commented throughout for use with Doxygen.
26
   --------------------------------------------------------------------------*/
27
 
28
#include "support.h"
29
#include "spr-defs.h"
30
 
31
 
32
#undef  UART
33
 
34
#define MEM_RAM 0x00100000
35
 
36
/* Number of IC sets (power of 2) */
37
#define IC_SETS 256
38
#define DC_SETS 256
39
 
40
/* Block size in bytes (1, 2, 4, 8, 16, 32 etc.) */
41
#define IC_BLOCK_SIZE 16
42
#define DC_BLOCK_SIZE 16
43
 
44
/* Number of IC ways (1, 2, 3 etc.). */
45
#define IC_WAYS 1
46
#define DC_WAYS 1
47
 
48
/* Cache size */
49
#define IC_SIZE (IC_WAYS*IC_SETS*IC_BLOCK_SIZE)
50
#define DC_SIZE (DC_WAYS*DC_SETS*DC_BLOCK_SIZE)
51
 
52
#if UART
53
#include "uart.h"
54
#define IN_CLK  20000000
55
#define UART_BASE  0x9c000000
56
#define UART_BAUD_RATE 9600
57
 
58
#define BOTH_EMPTY (UART_LSR_TEMT | UART_LSR_THRE)
59
 
60
#define WAIT_FOR_XMITR \
61
        do { \
62
                lsr = REG8(UART_BASE + UART_LSR); \
63
        } while ((lsr & BOTH_EMPTY) != BOTH_EMPTY)
64
 
65
#define WAIT_FOR_THRE \
66
        do { \
67
                lsr = REG8(UART_BASE + UART_LSR); \
68
        } while ((lsr & UART_LSR_THRE) != UART_LSR_THRE)
69
 
70
#define CHECK_FOR_CHAR \
71
        (REG8(UART_BASE + UART_LSR) & UART_LSR_DR)
72
 
73
#define WAIT_FOR_CHAR \
74
         do { \
75
                lsr = REG8(UART_BASE + UART_LSR); \
76
         } while ((lsr & UART_LSR_DR) != UART_LSR_DR)
77
 
78
#define UART_TX_BUFF_LEN 32
79
#define UART_TX_BUFF_MASK (UART_TX_BUFF_LEN -1)
80
 
81
#define print_n(x)  \
82
  { \
83
    uart_putc(s[((x) >> 28) & 0x0f]); \
84
    uart_putc(s[((x) >> 24) & 0x0f]); \
85
    uart_putc(s[((x) >> 20) & 0x0f]); \
86
    uart_putc(s[((x) >> 16) & 0x0f]); \
87
    uart_putc(s[((x) >> 12) & 0x0f]); \
88
    uart_putc(s[((x) >> 8) & 0x0f]);  \
89
    uart_putc(s[((x) >> 4) & 0x0f]);  \
90
    uart_putc(s[((x) >> 0) & 0x0f]);  \
91
  }
92
 
93
const char s[] = "0123456789abcdef";
94
 
95
void uart_init(void)
96
{
97
        int devisor;
98
 
99
        /* Reset receiver and transmiter */
100
        REG8(UART_BASE + UART_FCR) = UART_FCR_ENABLE_FIFO | UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT | UART_FCR_TRIGGER_14;
101
 
102
        /* Disable all interrupts */
103
        REG8(UART_BASE + UART_IER) = 0x00;
104
 
105
        /* Set 8 bit char, 1 stop bit, no parity */
106
        REG8(UART_BASE + UART_LCR) = UART_LCR_WLEN8 & ~(UART_LCR_STOP | UART_LCR_PARITY);
107
 
108
        /* Set baud rate */
109
        devisor = IN_CLK/(16 * UART_BAUD_RATE);
110
        REG8(UART_BASE + UART_LCR) |= UART_LCR_DLAB;
111
        REG8(UART_BASE + UART_DLL) = devisor & 0x000000ff;
112
        REG8(UART_BASE + UART_DLM) = (devisor >> 8) & 0x000000ff;
113
        REG8(UART_BASE + UART_LCR) &= ~(UART_LCR_DLAB);
114
 
115
        return;
116
}
117
 
118
static inline void uart_putc(char c)
119
{
120
        unsigned char lsr;
121
 
122
        WAIT_FOR_THRE;
123
        REG8(UART_BASE + UART_TX) = c;
124
        if(c == '\n') {
125
          WAIT_FOR_THRE;
126
          REG8(UART_BASE + UART_TX) = '\r';
127
        }
128
        WAIT_FOR_XMITR;
129
}
130
 
131
static inline void print_str(char *str)
132
{
133
  while(*str != 0) {
134
    uart_putc(*str);
135
    str++;
136
  }
137
}
138
 
139
static inline char uart_getc()
140
{
141
        unsigned char lsr;
142
        char c;
143
 
144
        WAIT_FOR_CHAR;
145
        c = REG8(UART_BASE + UART_RX);
146
        return c;
147
}
148
#endif
149
 
150
extern void ic_enable(void);
151
extern void ic_disable(void);
152
extern void dc_enable(void);
153
extern void dc_disable(void);
154
extern void dc_inv(void);
155
extern unsigned long ic_inv_test(void);
156
extern unsigned long dc_inv_test(unsigned long);
157
 
158
extern void (*jalr)(void);
159
extern void (*jr)(void);
160
 
161
/* Index on jump table */
162
unsigned long jump_indx;
163
 
164
/* Jump address table */
165
unsigned long jump_add[15*IC_WAYS];
166
 
167
void dummy();
168
 
169
void jump_and_link(void)
170
{
171
        asm("_jalr:");
172
  asm("l.jr\tr9");
173
  asm("l.nop");
174
}
175
 
176
void jump(void)
177
{
178
        asm("_jr:");
179
        /* Read and increment index */
180
        asm("l.lwz\t\tr3,0(r11)");
181
        asm("l.addi\t\tr3,r3,4");
182
        asm("l.sw\t\t0(r11),r3");
183
        /* Load next executin address from table */
184
        asm("l.lwz\t\tr3,0(r3)");
185
        /* Jump to that address */
186
        asm("l.jr\t\tr3") ;
187
        /* Report that we succeeded */
188
        asm("l.nop\t0");
189
}
190
 
191
void copy_jr(unsigned long add)
192
{
193
        memcpy((void *)add, (void *)&jr, 24);
194
}
195
 
196
void call(unsigned long add)
197
{
198
  asm("l.movhi\tr11,hi(_jump_indx)" : :);
199
  asm("l.ori\tr11,r11,lo(_jump_indx)" : :);
200
        asm("l.jalr\t\t%0" : : "r" (add) : "r11", "r9");
201
        asm("l.nop" : :);
202
}
203
 
204
int dc_test(void)
205
{
206
        int i;
207
        unsigned long base, add, ul;
208
 
209
        base = (((unsigned long)MEM_RAM / (IC_SETS*IC_BLOCK_SIZE)) * IC_SETS*IC_BLOCK_SIZE) + IC_SETS*IC_BLOCK_SIZE;
210
 
211
        dc_enable();
212
 
213
        /* Cache miss r */
214
        add = base;
215
        for(i = 0; i < DC_WAYS; i++) {
216
                ul = REG32(add);
217
                ul = REG32(add + DC_BLOCK_SIZE + 4);
218
                ul = REG32(add + 2*DC_BLOCK_SIZE + 8);
219
                ul = REG32(add + 3*DC_BLOCK_SIZE + 12);
220
                add += DC_SETS*DC_BLOCK_SIZE;
221
        }
222
 
223
        /* Cache hit w */
224
        add = base;
225
        for(i = 0; i < DC_WAYS; i++) {
226
                REG32(add + 0) = 0x00000001;
227
                REG32(add + 4) = 0x00000000;
228
                REG32(add + 8) = 0x00000000;
229
                REG32(add + 12) = 0x00000000;
230
                REG32(add + DC_BLOCK_SIZE + 0) = 0x00000000;
231
                REG32(add + DC_BLOCK_SIZE + 4) = 0x00000002;
232
                REG32(add + DC_BLOCK_SIZE + 8) = 0x00000000;
233
                REG32(add + DC_BLOCK_SIZE + 12) = 0x00000000;
234
                REG32(add + 2*DC_BLOCK_SIZE + 0) = 0x00000000;
235
                REG32(add + 2*DC_BLOCK_SIZE + 4) = 0x00000000;
236
                REG32(add + 2*DC_BLOCK_SIZE + 8) = 0x00000003;
237
                REG32(add + 2*DC_BLOCK_SIZE + 12) = 0x00000000;
238
                REG32(add + 3*DC_BLOCK_SIZE + 0) = 0x00000000;
239
                REG32(add + 3*DC_BLOCK_SIZE + 4) = 0x00000000;
240
                REG32(add + 3*DC_BLOCK_SIZE + 8) = 0x00000000;
241
                REG32(add + 3*DC_BLOCK_SIZE + 12) = 0x00000004;
242
                add += DC_SETS*DC_BLOCK_SIZE;
243
        }
244
 
245
        /* Cache hit r/w */
246
        add = base;
247
        for(i = 0; i < DC_WAYS; i++) {
248
                REG8(add + DC_BLOCK_SIZE - 4) = REG8(add + 3);
249
                REG8(add + 2*DC_BLOCK_SIZE - 8) = REG8(add + DC_BLOCK_SIZE + 7);
250
                REG8(add + 3*DC_BLOCK_SIZE - 12) = REG8(add + 2*DC_BLOCK_SIZE + 11);
251
                REG8(add + 4*DC_BLOCK_SIZE - 16) = REG8(add + 3*DC_BLOCK_SIZE + 15);
252
                add += DC_SETS*DC_BLOCK_SIZE;
253
        }
254
 
255
        /* Cache hit/miss r/w */
256
        add = base;
257
        for(i = 0; i < DC_WAYS; i++) {
258
                REG16(add + (IC_SETS - 1)*IC_BLOCK_SIZE) = REG16(add + DC_BLOCK_SIZE - 4) + REG16(add + 2);
259
                REG16(add + (IC_SETS - 1)*IC_BLOCK_SIZE + 2) = REG16(add + DC_BLOCK_SIZE - 8) + REG16(add + DC_BLOCK_SIZE + 6);
260
                REG16(add + (IC_SETS - 1)*IC_BLOCK_SIZE + 4) = REG16(add + DC_BLOCK_SIZE - 12) + REG16(add + 2*DC_BLOCK_SIZE + 10);
261
                REG16(add + (IC_SETS - 1)*IC_BLOCK_SIZE + 6) = REG16(add+ DC_BLOCK_SIZE - 16) + REG16(add + 2*DC_BLOCK_SIZE + 14);
262
                add += DC_SETS*DC_BLOCK_SIZE;
263
        }
264
 
265
        /* Fill cache with unused data */
266
        add = base + DC_WAYS*DC_SETS*DC_BLOCK_SIZE;
267
        for(i = 0; i < DC_WAYS; i++) {
268
                ul = REG32(add);
269
                ul = REG32(add + DC_BLOCK_SIZE);
270
                ul = REG32(add + 2*DC_BLOCK_SIZE);
271
                ul = REG32(add + 3*DC_BLOCK_SIZE);
272
                add += DC_SETS*DC_BLOCK_SIZE;
273
        }
274
 
275
        /* Cache hit/miss r */
276
        ul = 0;
277
        add = base;
278
        for(i = 0; i < DC_WAYS; i++) {
279
                ul +=   REG16(add + (IC_SETS - 1)*IC_BLOCK_SIZE) +
280
                        REG16(add + DC_BLOCK_SIZE - 4) +
281
                        REG16(add + 2);
282
                ul +=   REG16(add + (IC_SETS - 1)*IC_BLOCK_SIZE + 2) +
283
                        REG16(add + DC_BLOCK_SIZE - 8) +
284
                        REG16(add + DC_BLOCK_SIZE + 6);
285
                ul +=   REG16(add + (IC_SETS - 1)*IC_BLOCK_SIZE + 4) +
286
                        REG16(add + DC_BLOCK_SIZE - 12) +
287
                        REG16(add + 2*DC_BLOCK_SIZE + 10);
288
                ul +=   REG16(add + (IC_SETS - 1)*IC_BLOCK_SIZE + 6) +
289
                        REG16(add+ DC_BLOCK_SIZE - 16) +
290
                        REG16(add + 2*DC_BLOCK_SIZE + 14);
291
                add += DC_SETS*DC_BLOCK_SIZE;
292
        }
293
 
294
        dc_disable();
295
 
296
        return ul;
297
}
298
 
299
int ic_test(void)
300
{
301
        int i;
302
        unsigned long base, add;
303
 
304
        base = (((unsigned long)MEM_RAM / (IC_SETS*IC_BLOCK_SIZE)) * IC_SETS*IC_BLOCK_SIZE) + IC_SETS*IC_BLOCK_SIZE;
305
 
306
        /* Copy jr to various location */
307
        add = base;
308
        for(i = 0; i < IC_WAYS; i++) {
309
                copy_jr(add);
310
                copy_jr(add + 2*IC_BLOCK_SIZE + 4);
311
                copy_jr(add + 4*IC_BLOCK_SIZE + 8);
312
                copy_jr(add + 6*IC_BLOCK_SIZE + 12);
313
 
314
                copy_jr(add + (IC_SETS - 2)*IC_BLOCK_SIZE + 0);
315
                copy_jr(add + (IC_SETS - 4)*IC_BLOCK_SIZE + 4);
316
                copy_jr(add + (IC_SETS - 6)*IC_BLOCK_SIZE + 8);
317
                copy_jr(add + (IC_SETS - 8)*IC_BLOCK_SIZE + 12);
318
                add += IC_SETS*IC_BLOCK_SIZE;
319
        }
320
 
321
        /* Load execution table which starts at address 4 (at address 0 is table index) */
322
        add = base;
323
        for(i = 0; i < IC_WAYS; i++) {
324
                /* Cache miss */
325
                jump_add[15*i + 0] = add + 2*IC_BLOCK_SIZE + 4;
326
                jump_add[15*i + 1] = add + 4*IC_BLOCK_SIZE + 8;
327
                jump_add[15*i + 2] = add + 6*IC_BLOCK_SIZE + 12;
328
                /* Cache hit/miss */
329
                jump_add[15*i + 3] = add;
330
                jump_add[15*i + 4] = add + (IC_SETS - 2)*IC_BLOCK_SIZE + 0;
331
                jump_add[15*i + 5] = add + 2*IC_BLOCK_SIZE + 4;
332
                jump_add[15*i + 6] = add + (IC_SETS - 4)*IC_BLOCK_SIZE + 4;
333
                jump_add[15*i + 7] = add + 4*IC_BLOCK_SIZE + 8;
334
                jump_add[15*i + 8] = add + (IC_SETS - 6)*IC_BLOCK_SIZE + 8;
335
                jump_add[15*i + 9] = add + 6*IC_BLOCK_SIZE + 12;
336
                jump_add[15*i + 10] = add + (IC_SETS - 8)*IC_BLOCK_SIZE + 12;
337
                /* Cache hit */
338
                jump_add[15*i + 11] = add + (IC_SETS - 2)*IC_BLOCK_SIZE + 0;
339
                jump_add[15*i + 12] = add + (IC_SETS - 4)*IC_BLOCK_SIZE + 4;
340
                jump_add[15*i + 13] = add + (IC_SETS - 6)*IC_BLOCK_SIZE + 8;
341
                jump_add[15*i + 14] = add + (IC_SETS - 8)*IC_BLOCK_SIZE + 12;
342
 
343
                add += IC_SETS*IC_BLOCK_SIZE;
344
        }
345
 
346
        /* Go home */
347
        jump_add[15*i] = (unsigned long)&jalr;
348
 
349
        /* Initilalize table index */
350
        jump_indx = (unsigned long)&jump_add[0];
351
 
352
        ic_enable();
353
 
354
        /* Go */
355
        call(base);
356
 
357
        ic_disable();
358
 
359
        return 0;
360
}
361
 
362
/* Each of the 5 reports should be 0xdeaddead if the code is working
363
   correctly. */
364
int main(void)
365
{
366
        unsigned long rc, ret = 0;
367
 
368
#ifdef UART
369
  /* Initialize controller */
370
  uart_init();
371
#endif
372
 
373
#ifdef UART
374
  print_str("DC test :            ");
375
#endif
376
        rc = dc_test();
377
  ret += rc;
378
#ifdef UART
379
  print_n(rc+0xdeaddca1);
380
  print_str("\n");
381
#else
382
        report(rc + 0xdeaddca1);
383
#endif
384
 
385
#ifdef UART
386
  print_str("DC invalidate test : ");
387
#endif
388
        rc = dc_inv_test(MEM_RAM);
389
  ret += rc;
390
#ifdef UART
391
  print_n(rc + 0x9e8daa91);
392
  print_str("\n");
393
#else
394
        report(rc + 0x9e8daa91);
395
#endif
396
 
397
#ifdef UART
398
  print_str("IC test :            ");
399
#endif
400
        rc = ic_test();
401
  ret += rc;
402
#ifdef UART
403
  print_n(rc + 0xdeaddead);
404
  print_str("\n");
405
#else
406
        report(rc + 0xdeaddead);
407
#endif
408
 
409
 
410
#ifdef UART
411
  print_str("IC invalidate test : ");
412
#endif
413
  ic_enable();
414
  rc = ic_inv_test();
415
  ret += rc;
416
#ifdef UART
417
  print_n(rc + 0xdeadde8f);
418
  print_str("\n");
419
  while(1);
420
#else
421
        report(rc + 0xdeadde8f);
422
#endif
423
 
424
 
425
        report(ret + 0x9e8da867);
426
  exit(0);
427
 
428
        return 0;
429
}
430
 
431
/* just for size calculation */
432
void dummy()
433
{
434
}

powered by: WebSVN 2.1.0

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