📄 cache.c
字号:
#include "leon.h"
#include "test.h"
#define CCTRL_IFP 0x08000
#define CCTRL_DFP 0x04000
#define ITAGMASK ((1<<ILINESZ)-1)
#define DTAGMASK ((1<<DLINESZ)-1)
#define DTAGAMSK 0x7ffff000
asm("
.align 32
.global _line8, _line8int
_line8:
_line8int:
retl; nop;
");
flush()
{
asm(" flush");
}
chkitags(i,j,k,l)
int i,j,k,l;
{
asm("
1:
lda [%o0] 0xc, %o2
subcc %o0, %o1, %o0
bge 1b
or %o2, %o3, %o3
mov %o3, %o0
");
}
chkdtags(i,j,k,l)
int i,j,k,l;
{
asm("
1:
lda [%o0] 0xe, %o2
subcc %o0, %o1, %o0
bge 1b
or %o2, %o3, %o3
mov %o3, %o0
");
}
getitag(addr) int addr; { asm(" lda [%o0] 0xc, %o0 "); }
setitag(addr,data) int *addr,data; { asm(" sta %o1, [%o0] 0xc "); }
getidata(addr) int addr; { asm(" lda [%o0] 0xd, %o0 "); }
setidata(addr,data) int *addr,data; { asm(" sta %o1, [%o0] 0xd "); }
getdtag(addr) int addr; { asm(" lda [%o0] 0xe, %o0 "); }
setdtag(addr,data) int *addr,data; { asm(" sta %o1, [%o0] 0xe "); }
getddata(addr) int *addr; { asm(" lda [%o0] 0xf, %o0 "); }
setddata(addr,data) int *addr,data; { asm(" sta %o1, [%o0] 0xf "); }
setudata(addr,data) int *addr,data; { asm(" sta %o1, [%o0] 0x0 "); }
getudata(addr) int addr; { asm(" lda [%o0] 0x0, %o0 "); }
flushi(addr,data) int *addr,data; { asm(" sta %g0, [%g0] 0x5 "); }
flushd(addr,data) int *addr,data; { asm(" sta %g0, [%g0] 0x6 "); }
extern line8();
extern int line8int;
cache_test()
{
volatile double mrl[DTAGS*DLINESZ/2 + 8];
volatile int mrx[16];
volatile double *ll = (double *) mrx;
volatile struct lregs *lr = (struct lregs *) PREGS;
volatile int *msg = (volatile int *) IOAREA;
extern volatile char irqtbl[];
volatile int *mr = (int *) mrl;
volatile unsigned char *mrc = (char *) mrl;
volatile unsigned short *mrh = (short *) mrl;
int i;
int IVALMSK = (0x03 << ((((int)line8)>>2)&(ILINESZ-1)));
report(CACHE_TEST);
lr->cachectrl &= ~0xf; /* disable cache */
flush();
while(lr->cachectrl & (CCTRL_IFP|CCTRL_DFP) ) {} /* wait for flush to complete */
lr->cachectrl |= 0x0f; /* enable icache $ dcache */
/**** INSTRUCTION CACHE TESTS ****/
/* check that tag is not valid */
if ((getitag(line8) & IVALMSK) != 0) fail(1);
line8();
/* check that all valid bits are set */
if ((getitag((int *) line8) & IVALMSK) != IVALMSK) fail(2);
#ifdef IPAREN
/* idata parity test */
setidata((int *)((int)line8 ^ (1<<31)),0);
line8();
if (((lr->cachectrl & 0xc00) >> 10) != 1) fail(3);
/* itag parity test */
setitag((int *)((int)line8 ^ (1<<31)),getitag((int *)line8));
setidata((int *)line8,0);
line8();
if (((lr->cachectrl & 0x3000) >> 12) != 1) fail(4);
#endif
/**** DATA CACHE TESTS ****/
mr[0] = 5; mr[1] = 1; mr[2] = 2; mr[3] = 3;
/* check that write does not allocate line */
if (((getdtag(&mr[0]) & DTAGMASK) != 0) || (getudata(&mr[0]) != 5))
fail(5);
/* check that line was allocated by getudata */
if ((getdtag(&mr[0]) & DTAGMASK) == 0) fail(6);
/* check that data is in cache */
if (getddata(&mr[0]) != 5) fail(7);
*ll = mrl[0];
if ((mrx[0] != 5) || (mrx[1] != 1)) fail(8);
if (getddata(&mr[1]) != 1) fail(9);
#ifdef DPAREN
/* data parity test */
setddata(&mrx[0],0);
setddata((int *)(((int) mrx) ^ (1<<31)),mrx[0]);
if (mrx[0] != 5) fail(10);
if (((lr->cachectrl & 0xc0) >> 6) != 1) fail(11);
/* tag parity test */
setddata(&mrx[0],0);
setdtag((int *)(((int) mrx) ^ (1<<31)),(1 << DLINESZ)-1);
if (mrx[0] != 5) fail(12);
if (getddata(&mr[0]) != 5) fail(13);
if (((lr->cachectrl & 0x300) >> 8) != 1) fail(14);
if ((getdtag(mrx) & DTAGMASK) != (1 <<((((int) mrx)>>2)&(DLINESZ-1))))
fail(15);
#endif
/* check that tag is properly replaced */
mr[0] = 5; mr[1] = 1; mr[2] = 2; mr[3] = 3;
mr[DTAGS*DLINESZ] = 6;
/* check that tag is not evicted on write miss */
if ((getdtag(mrx) & DTAGAMSK) != (((int) mrx)&DTAGAMSK))
fail(16);
/* check that write update memory ok */
if (mr[DTAGS*DLINESZ] != 6) fail(17);
/* check that tag has been replaced */
if ((getdtag(mr) & DTAGAMSK) != (((int) &mr[DTAGS*DLINESZ])&DTAGAMSK))
fail(18);
/* check that valid bits have been reset */
if ((getdtag(mr) & DTAGMASK) != (1 <<((((int) mr)>>2)&(DLINESZ-1))))
fail(19);
/* check partial word access */
mr[8] = 0x01234567;
mr[9] = 0x89abcdef;
if (mrc[32] != 0x01) fail(26);
if (mrc[33] != 0x23) fail(27);
if (mrc[34] != 0x45) fail(28);
if (mrc[35] != 0x67) fail(29);
if (mrc[36] != 0x89) fail(30);
if (mrc[37] != 0xab) fail(31);
if (mrc[38] != 0xcd) fail(32);
if (mrc[39] != 0xef) fail(33);
if (mrh[16] != 0x0123) fail(34);
if (mrh[17] != 0x4567) fail(35);
if (mrh[18] != 0x89ab) fail(36);
if (mrh[19] != 0xcdef) fail(37);
mrc[32] = 0x30; if (mr[8] != 0x30234567) fail(39);
mrc[33] = 0x31; if (mr[8] != 0x30314567) fail(40);
mrc[34] = 0x32; if (mr[8] != 0x30313267) fail(41);
mrc[35] = 0x33; if (mr[8] != 0x30313233) fail(42);
mrc[36] = 0x34; if (mr[9] != 0x34abcdef) fail(43);
mrc[37] = 0x35; if (mr[9] != 0x3435cdef) fail(44);
mrc[38] = 0x36; if (mr[9] != 0x343536ef) fail(45);
mrc[39] = 0x37; if (mr[9] != 0x34353637) fail(46);
mrh[16] = 0x4041; if (mr[8] != 0x40413233) fail(47);
mrh[17] = 0x4243; if (mr[8] != 0x40414243) fail(48);
mrh[18] = 0x4445; if (mr[9] != 0x44453637) fail(49);
mrh[19] = 0x4647; if (mr[9] != 0x44454647) fail(50);
/* check flush operation */
lr->cachectrl &= ~0x0f; /* disable cache */
flushi();
while(lr->cachectrl & CCTRL_IFP ) {} /* wait for iflush to complete */
/* check that flush clears itag valid bits */
if (chkitags(ITAG_MAX_ADDRESS,(1<<(ILINEBITS + 2)),0,0) & ((1<<ILINESZ)-1))
fail(51);
lr->cachectrl |= 3; /* enable icache */
flushd();
while(lr->cachectrl & CCTRL_DFP) {} /* wait for dflush to complete */
/* check that flush clears dtag valid bits */
if (chkdtags(DTAG_MAX_ADDRESS,(1<<(DLINEBITS + 2)),0,0) & ((1<<DLINESZ)-1))
fail(52);
lr->cachectrl |= 0x0f; /* enable icache $ dcache */
/* to be tested: diag access during flush, diag byte/halfword access,
write error, cache freeze operation */
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -