⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cache.c

📁 一个航天航空用的Sparc处理器(配美国欧洲宇航局用的R_tems嵌入式操作系统)的VHDL源代码
💻 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 + -