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

Subversion Repositories mips_enhanced

[/] [mips_enhanced/] [trunk/] [grlib-gpl-1.0.19-b3188/] [software/] [leon3/] [cache.c] - Blame information for rev 2

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 dimamali
#include "testmod.h"
2
#include "leon3.h"
3
 
4
#define CCTRL_IFP (1<<15)
5
#define CCTRL_DFP (1<<14)
6
 
7
#define DDIAGMSK ((1<<DTAGLOW)-1)
8
#define IDIAGMSK ((1<<ITAGLOW)-1)
9
 
10
#define ICLOCK_BIT 6
11
#define DCLOCK_BIT 7
12
 
13
 
14
int icconf, dcconf, dsetsize, isetsize;
15
int dsetbits, isetbits;
16
int DSETS, DTAGLOW, DTAGAMSK, ITAGAMSK, ITAGLOW;
17
 
18
flush()
19
{
20
        asm(" flush");
21
}
22
 
23
getitag(addr, set)
24
int addr, set;
25
{
26
  int tag;
27
 
28
  tag = asmgetitag((addr & IDIAGMSK) + (set<<isetbits));
29
  return(tag);
30
}
31
 
32
 
33
setitag(addr, set, data)
34
int addr, set, data;
35
{
36
  asmsetitag((addr & IDIAGMSK) + (set<<isetbits), data);
37
}
38
 
39
setidata(addr, set, data)
40
int addr, set, data;
41
{
42
  asmsetidata((addr & IDIAGMSK) + (set<<isetbits), data);
43
}
44
 
45
 
46
getidata(addr, set)
47
int addr, set;
48
{
49
  int idata;
50
 
51
  idata = asmgetidata((addr & IDIAGMSK) + (set<<isetbits));
52
  return(idata);
53
}
54
 
55
 
56
asmgetitag(addr) int addr; { asm(" lda  [%o0] 0xc, %o0 "); }
57
asmsetitag(addr,data) int *addr,data; { asm(" sta       %o1, [%o0] 0xc "); }
58
 
59
asmgetidata(addr) int addr; { asm(" lda [%o0] 0xd, %o0 "); }
60
asmsetidata(addr,data) int *addr,data; { asm(" sta      %o1, [%o0] 0xd "); }
61
 
62
wsysreg(addr,data) int *addr,data; { asm(" sta  %o1, [%o0] 0x2 "); }
63
rsysreg(addr) int addr; { asm(" lda     [%o0] 0x2, %o0 "); }
64
 
65
 
66
setdtag(addr, set, data)
67
int addr, set, data;
68
{
69
  asmsetdtag((addr & DDIAGMSK) + (set<<dsetbits), data);
70
}
71
 
72
setddata(addr, set, data)
73
int addr, set, data;
74
{
75
  asmsetddata((addr & DDIAGMSK) + (set<<dsetbits), data);
76
}
77
 
78
chkdtag(addr)
79
int addr;
80
{
81
  int tm[16];
82
  int tmp, i;
83
 
84
  tmp = 0;
85
  for (i=0;i<DSETS;i++) {
86
    if (((asmgetdtag((addr & DDIAGMSK) + (i<<dsetbits))) & DTAGAMSK) == (addr & DTAGAMSK))
87
      tmp++;
88
  }
89
  if (tmp != 0)
90
    return 0;
91
  else
92
    return 1;
93
}
94
 
95
getdtag(addr, set)
96
int addr;
97
{
98
  int tag;
99
 
100
  tag = asmgetdtag((addr & DDIAGMSK) + (set<<dsetbits));
101
  return(tag);
102
}
103
 
104
 
105
getddata(addr, set)
106
int addr, set;
107
{
108
  int ddata;
109
 
110
  ddata = asmgetddata((addr & DDIAGMSK) + (set<<dsetbits));
111
  return(ddata);
112
}
113
 
114
 
115
 
116
dma(int addr, int len,  int write)
117
{
118
        volatile unsigned int *dm = (unsigned int *) 0xa0000000;
119
 
120
        dm[0] = addr;
121
        dm[1] = (write <<13) + 0x1000 + len;
122
 
123
}
124
 
125
asmgetdtag(addr) int addr; { asm(" lda  [%o0] 0xe, %o0 "); }
126
asmsetdtag(addr,data) int addr,data; { asm(" sta        %o1, [%o0] 0xe "); }
127
 
128
asmgetddata(addr) int *addr; { asm(" lda        [%o0] 0xf, %o0 "); }
129
asmsetddata(addr,data) int *addr,data; { asm(" sta      %o1, [%o0] 0xf "); }
130
 
131
setudata(addr,data) int *addr,data; { asm(" sta %o1, [%o0] 0x0 "); }
132
getudata(addr) int addr; { asm(" lda    [%o0] 0x0, %o0 "); }
133
xgetpsr() { asm(" mov   %psr, %o0 "); }
134
setpsr(psr) int psr; { asm(" mov  %o0, %psr; nop; nop; nop "); }
135
 
136
flushi(addr,data) int *addr,data; { asm(" sta   %g0, [%g0] 0x5 "); }
137
flushd(addr,data) int *addr,data; { asm(" sta   %g0, [%g0] 0x6 "); }
138
 
139
extern line0();
140
extern line1();
141
extern line2();
142
extern line3();
143
 
144
asm(
145
"    .text           \n"
146
"    .align 4        \n"
147
"getdw:              \n"
148
"    retl            \n"
149
"    ldd [%o0], %o0  \n"
150
);
151
 
152
 
153
 
154
 
155
 
156
#define ITAGMASK ((1<<ILINESZ)-1)
157
#define DTAGMASK (~((1<<DLINESZ)-1))
158
#define DIAGADDRMASK ((1<<DTAGLOW)-1)
159
 
160
static maintest();
161
 
162
cachetest()
163
{
164
    int tmp;
165
 
166
    tmp = maintest();
167
    wsysreg(0, 0x81000f);
168
    return(tmp);
169
}
170
 
171
long long int getdw();
172
 
173
 
174
static maintest()
175
{
176
 
177
        volatile double mrl[8192 + 8]; /* enough for 64 K caches */
178
        volatile int mrx[16];
179
        volatile double *ll = (double *) mrx;
180
        volatile int *mr = (int *) mrl;
181
        volatile unsigned char *mrc = (char *) mrl;
182
        volatile unsigned short *mrh = (short *) mrl;
183
        volatile long long int dw;
184
        int vbits, vpos, addrmsk;
185
        int i, j, tmp, cachectrl;
186
        int ITAGS, DTAGS;
187
        int ILINESZ, DLINESZ;
188
        int ITAG_BITS, ILINEBITS, DTAG_BITS, DLINEBITS;
189
        int IVALMSK, tag, data;
190
        int ISETS;
191
        int (*line[4])() = {line0, line1, line2, line3};
192
 
193
        report_subtest(CACHE_TEST);
194
 
195
        cachectrl = rsysreg(0); wsysreg(0, cachectrl & ~0x0f);
196
        do cachectrl = rsysreg(0); while(cachectrl & (CCTRL_IFP | CCTRL_DFP));
197
        flush();
198
        do cachectrl = rsysreg(0); while(cachectrl & (CCTRL_IFP | CCTRL_DFP));
199
        cachectrl = rsysreg(0); wsysreg(0, cachectrl | 0x81000f);
200
 
201
        icconf = rsysreg(8);
202
        dcconf = rsysreg(12);
203
 
204
        ILINEBITS = (icconf >> 16) & 7;
205
        DLINEBITS = ((dcconf >> 16) & 7);
206
        ITAG_BITS = ((icconf >> 20) & 15) + 8 - ILINEBITS;
207
        DTAG_BITS = ((dcconf >> 20) & 15) + 8 - DLINEBITS;
208
        isetsize = (1<<((icconf >> 20) & 15)) * 1024;
209
        dsetsize = (1<<((dcconf >> 20) & 15)) * 1024;
210
        isetbits = ((icconf >> 20) & 15) + 10;
211
        dsetbits = ((dcconf >> 20) & 15) + 10;
212
        ITAGS = (1 << ITAG_BITS);
213
        ILINESZ = (1 << ILINEBITS);
214
        DTAGS = (1 << DTAG_BITS);
215
        DLINESZ = (1 << DLINEBITS);
216
        IVALMSK = (1 << ILINESZ)-1;
217
        ITAGAMSK = 0x7fffffff - (1 << (ITAG_BITS + ILINEBITS +2)) + 1;
218
        DTAGAMSK = 0x7fffffff - (1 << (DTAG_BITS + DLINEBITS +2)) + 1;
219
        ISETS = ((icconf >> 24) & 3) + 1;
220
        DSETS = ((dcconf >> 24) & 3) + 1;
221
 
222
        ITAGLOW = 10 + ((icconf >> 20) & 15);
223
        DTAGLOW = 10 + ((dcconf >> 20) & 15);
224
 
225
        /**** INSTRUCTION CACHE TESTS ****/
226
 
227
        for (i=0;i<ISETS;i++) {
228
          line[i]();
229
        }
230
 
231
        cachectrl = rsysreg(0); wsysreg(0, cachectrl & ~0x03); /* disable icache */
232
        /* check tags */
233
        tmp = 0;
234
        for (i=0;i<ISETS;i++) {
235
          for (j=0;j<ISETS;j++) {
236
            tag = getitag((int) line[i], j);
237
            if ( ((tag & IVALMSK) == IVALMSK) && ((tag & ITAGAMSK) == (((int) line[i]) & ITAGAMSK)) )
238
              tmp++;
239
          }
240
        }
241
        cachectrl = rsysreg(0); wsysreg(0, cachectrl | 3); /* enable icache */
242
        if (tmp == 0) fail(1);
243
 
244
      if (((cachectrl >> ITE_BIT) & 3) == 0) {
245
        /* iparity checks */
246
        if ((cachectrl >> CPP_CONF_BIT) & CPP_CONF_MASK) {
247
          cachectrl = rsysreg(0); wsysreg(0, cachectrl & ~0x3fc0);
248
          line2();
249
          wsysreg(0, cachectrl | CPTB_MASK);
250
          for (i=0;i<ISETS;i++) {
251
            setidata((int) line2, i, 0);
252
          }
253
          line2();
254
          cachectrl = rsysreg(0);
255
          if (((cachectrl >> IDE_BIT) & 3) != 1) fail(2);
256
 
257
          setitag((int) line2, 0, 0);
258
          cachectrl = rsysreg(0); wsysreg(0, cachectrl & ~CPTB_MASK);
259
          //setidata((int) line2, 0, 0);
260
          line2();
261
          cachectrl = rsysreg(0);
262
          if (((cachectrl >> ITE_BIT) & 3) != 1) fail(3);
263
        }
264
 
265
 
266
        /**** DATA CACHE TESTS ****/
267
 
268
        flush();
269
        do cachectrl = rsysreg(0); while(cachectrl & (CCTRL_IFP | CCTRL_DFP));
270
 
271
        for (i=0;i<DSETS;i++) {
272
          setdtag((int) mr, i, 0);       /* clear tags */
273
        }
274
        for (i=0;i<31;i++) mr[i] = 0;
275
        mr[0] = 5; mr[1] = 1; mr[2] = 2; mr[3] = 3;
276
 
277
        /* check that write does not allocate line */
278
        if (chkdtag((int) mr) == 0) fail(5);
279
 
280
        if (mr[0] != 5) fail(6);
281
 
282
        /* check that line was allocated */
283
        if (chkdtag((int) mr) != 0) fail(7);
284
 
285
        /* check that data is in cache */
286
        for (i=0;i<DSETS;i++) {
287
                setddata((int)mr,i,0); setddata((int) &mr[1], i, 0);
288
        }
289
        getudata((int) &mr[0]); getudata((int) &mr[8]);
290
        getudata((int) &mr[16]); getudata((int) &mr[24]);
291
        tmp = 0;
292
        for (i=0;i<DSETS;i++) { if (getddata((int) mr, i) == 5) tmp++; }
293
        if (tmp == 0) fail(8);
294
 
295
        *ll = mrl[0];
296
        if ((mrx[0] != 5) || (mrx[1] != 1)) fail(9);
297
        tmp = 0;
298
        for (i=0;i<DSETS;i++) {
299
          if (getddata((int) &mr[1], i) == 1) tmp++;
300
        }
301
        if (tmp != 1) fail(10);
302
 
303
        /* dcache parity */
304
        if ((cachectrl >> CPP_CONF_BIT) & CPP_CONF_MASK) {
305
          cachectrl = rsysreg(0); wsysreg(0, cachectrl & ~CE_CLEAR);
306
          setddata(&mrx[0],0,0);
307
          cachectrl = rsysreg(0); wsysreg(0, cachectrl | CPTB_MASK);
308
          for (i=0;i<DSETS;i++) setddata((int *)mrx,i,5);
309
          *((char *) mrx) = 1;
310
          if (mrx[0] != 0x01000005) fail(11);
311
          cachectrl = rsysreg(0);
312
          if (((cachectrl >> DDE_BIT) & 3) != 1) fail(12);
313
          cachectrl = rsysreg(0); wsysreg(0, cachectrl & ~CPTB_MASK);
314
          setddata(&mrx[0],0,0);
315
          cachectrl = rsysreg(0); wsysreg(0, cachectrl | CPTB_MASK);
316
          do cachectrl = rsysreg(0); while (!(cachectrl & CPTB_MASK));
317
          for (i=0;i<DSETS;i++) {
318
            setdtag((int *)mrx,i,(1 << DLINESZ)-1);
319
          }
320
          wsysreg(0, cachectrl & ~CPTB_MASK);
321
          do cachectrl = rsysreg(0); while (cachectrl & CPTB_MASK);
322
          if (mrx[0] != 0x01000005) fail(13);
323
//        if (getddata(&mr[0],0) != 5) fail(14);
324
          cachectrl = rsysreg(0); if (((cachectrl >> DTE_BIT) & 3) != 1) fail(15);
325
//        if ((getdtag(mrx,1) & DTAGMASK) != (1 <<((((int) mrx)>>2)&(DLINESZ-1)))) fail(16);
326
          *((volatile long long int *) &dw) = 0x0000001100000055LL;
327
          cachectrl = rsysreg(0); wsysreg(0, (cachectrl | CPTB_MASK) & ~DDE_MASK);
328
          getdw(&dw);
329
          for (i=0;i<DSETS;i++) {
330
            setddata(((int)&dw)+4,i,0x00000055);
331
          }
332
          if (getdw(&dw) != 0x0000001100000055LL) fail(16);
333
          cachectrl = rsysreg(0); if (((cachectrl >> DDE_BIT) & 3) != 1) fail(16);
334
          wsysreg(0, cachectrl & (~CE_CLEAR & ~CPTB_MASK));
335
        }
336
 
337
        /* check that tag is properly replaced */
338
        mr[0] = 5; mr[1] = 1; mr[2] = 2; mr[3] = 3;
339
        mr[DTAGS*DLINESZ] = 0xbbbbbbbb;
340
 
341
        /* check that tag is not evicted on write miss */
342
        if (chkdtag((int) mr) != 0) fail(17);
343
 
344
        /* check that write update memory ok */
345
        if (mr[DTAGS*DLINESZ] != 0xbbbbbbbb) fail(18);
346
 
347
 
348
        /* check that valid bits have been reset */
349
/*      if ((getdtag(mr) & DTAGMASK) != (1 <<((((int) mr)>>2)&(DLINESZ-1))))  */
350
/*              fail(19); */
351
/*      tmp = 0; */
352
/*      if ((getdtag((int) mr & DIAGADDRMASK + i*dsetsize) & DTAGMASK) != (1 <<((((int) mr)>>2)&(DLINESZ-1)))) */
353
/*        tmp = 1; */
354
/*      if (tmp == 1)  fail(19); */
355
 
356
 
357
      }
358
        /* check partial word access */
359
 
360
        mr[8] = 0x01234567;
361
        mr[9] = 0x89abcdef;
362
        if (mrc[32] != 0x01) fail(26);
363
        if (mrc[33] != 0x23) fail(27);
364
        if (mrc[34] != 0x45) fail(28);
365
        if (mrc[35] != 0x67) fail(29);
366
        if (mrc[36] != 0x89) fail(30);
367
        if (mrc[37] != 0xab) fail(31);
368
        if (mrc[38] != 0xcd) fail(32);
369
        if (mrc[39] != 0xef) fail(33);
370
        if (mrh[16] != 0x0123) fail(34);
371
        if (mrh[17] != 0x4567) fail(35);
372
        if (mrh[18] != 0x89ab) fail(36);
373
        if (mrh[19] != 0xcdef) fail(37);
374
        mrc[32] = 0x30; if (mr[8] != 0x30234567) fail(39);
375
        mrc[33] = 0x31; if (mr[8] != 0x30314567) fail(40);
376
        mrc[34] = 0x32; if (mr[8] != 0x30313267) fail(41);
377
        mrc[35] = 0x33; if (mr[8] != 0x30313233) fail(42);
378
        mrc[36] = 0x34; if (mr[9] != 0x34abcdef) fail(43);
379
        mrc[37] = 0x35; if (mr[9] != 0x3435cdef) fail(44);
380
        mrc[38] = 0x36; if (mr[9] != 0x343536ef) fail(45);
381
        mrc[39] = 0x37; if (mr[9] != 0x34353637) fail(46);
382
        mrh[16] = 0x4041; if (mr[8] != 0x40413233) fail(47);
383
        mrh[17] = 0x4243; if (mr[8] != 0x40414243) fail(48);
384
        mrh[18] = 0x4445; if (mr[9] != 0x44453637) fail(49);
385
        mrh[19] = 0x4647; if (mr[9] != 0x44454647) fail(50);
386
 
387
        /*
388
        if (((lr->leonconf >> 2) & 3) == 3) { dma((int)&mr[0], 9, 1); }
389
        if (((lr->leonconf >> 2) & 3) == 3) { dma((int)&mr[0], 9, 1); }
390
        */
391
 
392
        /* write data to the memory */
393
        flush();
394
        for (i=0;i<DSETS;i++) {
395
          for (j=0;j<DLINESZ;j++) {
396
            mr[j+(i<<dsetbits)] = ((i<<16) | j);
397
          }
398
        }
399
 
400
        /* check that write miss does not allocate line */
401
        do cachectrl = rsysreg(0); while(cachectrl & (CCTRL_DFP));
402
        for (i=0;i<DSETS;i++) {
403
          if ((getdtag((int) mr, i) & DTAGAMSK) == ((int) mr & DTAGAMSK))
404
            fail(51);
405
        }
406
 
407
        /* check flush operation */
408
        /* check that flush clears valid bits */
409
        /*
410
        cachectrl = rsysreg(0); wsysreg(0, cachectrl & ~0x0f);
411
        flushi();
412
        do cachectrl = rsysreg(0); while(cachectrl & (CCTRL_IFP));
413
 
414
        if (chkitags(ITAG_MAX_ADDRESS,(1<<(ILINEBITS + 2)),0,0) & ((1<<ILINESZ)-1))
415
                fail(51);
416
 
417
        for (i
418
 
419
        lr->cachectrl |= 0x03;
420
        flushd();
421
        while(lr->cachectrl & CCTRL_DFP) {}
422
 
423
        if (chkdtags(DTAG_MAX_ADDRESS,(1<<(DLINEBITS + 2)),0,0) & ((1<<DLINESZ)-1))
424
                fail(52);
425
        */
426
 
427
        /* flush();
428
        setdtag(0,0,0x11111111);
429
        setdtag(0,1,0x22222222);
430
        setdtag(0,2,0x33333333);
431
        setdtag(0,3,0x44444444);*/
432
 
433
        cachectrl = rsysreg(0); wsysreg(0, cachectrl | 0xf);
434
 
435
        return(0);
436
 
437
/* to be tested: diag access during flush, diag byte/halfword access,
438
   write error, cache freeze operation */
439
 
440
}
441
 
442
 

powered by: WebSVN 2.1.0

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