cache.c

来自「宇航级微处理器LEON2 2.2 VHDL源代码,很难找的.」· C语言 代码 · 共 259 行

C
259
字号
#include "leon.h"#include "test.h" #define CCTRL_IFP (1<<15)#define CCTRL_DFP (1<<14)asm("	.align 64	.global _line1, _line2, _line3	.global line1, line2, line3_line1:line1:	nop; nop; nop; nop; nop; nop; retl; nop;_line2:line2:	nop; nop; nop; nop; nop; nop; retl; nop;_line3:line3:	nop; nop; nop; nop; nop; nop; 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 line1();extern line2();extern line3();#define ITAGMASK ((1<<ILINESZ)-1)#define DTAGMASK ((1<<DLINESZ)-1)cache_test(){	volatile double mrl[8192 + 8]; /* enough for 64 K caches */	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 ITAGS, DTAGS;	int ILINESZ, DLINESZ;	int ITAG_BITS, ILINEBITS, DTAG_BITS, DLINEBITS;	int IVALMSK, leonconf, DTAGAMSK;	report(CACHE_TEST);	lr->cachectrl &= ~0xf; 	/* disable cache */	flush();	leonconf = lr->leonconf;	ILINEBITS = (leonconf >> 15) & 3;	DLINEBITS = (leonconf >> 10) & 3;	ITAG_BITS = ((leonconf >> 17) & 7) + 8 - ILINEBITS;	DTAG_BITS = ((leonconf >> 12) & 7) + 8 - DLINEBITS;	ITAGS = (1 << ITAG_BITS);	ILINESZ = (1 << ILINEBITS);	DTAGS = (1 << DTAG_BITS);	DLINESZ = (1 << DLINEBITS);//	IVALMSK = (0x03 << ((((int)line2)>>2)&(ILINESZ-1)));	IVALMSK = (1 << ILINESZ)-1;	DTAGAMSK = 0x7fffffff - (1 << (DTAG_BITS + DLINEBITS +2)) + 1;	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(line2) & IVALMSK) != 0) fail(1);	line1();	line2();	line3();	/* check that all valid bits are set */	if ((getitag((int *) line2) & IVALMSK) != IVALMSK) fail(2);	if ((lr->ectrl >> CPP_CONF_BIT) & CPP_CONF_MASK) { 	  lr->ectrl &= 0x3ff;	/* idata parity test */	  lr->ectrl |= CPTE_MASK;	  setidata((int *)line2,0);	  line2();	  if (((lr->ectrl >> IDE_BIT) & 3) != 1) fail(3);	  	/* itag parity test */	  setitag((int *)line2,	  	getitag((int *)line2) & ~(1<<8) & ~(1<<31));	  lr->ectrl &= ~CPTE_MASK;	  setidata((int *)line2,0);	  line2();	  if (((lr->ectrl >> ITE_BIT) & 3) != 1) fail(4);	}	/**** DATA CACHE TESTS ****/	setdtag(((int) mr) &  ~DTAGAMSK, 0); /* clear tag */	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);	if ((lr->ectrl >> CPP_CONF_BIT) & CPP_CONF_MASK) {	  lr->ectrl &= 0x3ff;	/* ddata parity test */	  setddata(&mrx[0],0);	  lr->ectrl |= CPTE_MASK;	  setddata((int *)mrx,mrx[0]);	  if (mrx[0] != 5) fail(10);	  if (((lr->ectrl >> DDE_BIT) & 3) != 1) fail(11);	/* dtag parity test */	  lr->ectrl &= ~CPTE_MASK;	  setddata(&mrx[0],0);	  lr->ectrl |= CPTE_MASK;	  setdtag((int *)mrx,(1 << DLINESZ)-1);	  lr->ectrl &= ~CPTE_MASK;	  while (lr->ectrl & CPTE_MASK) {}; /* avoid race condition */	  if (mrx[0] != 5) fail(12);	  if (getddata(&mr[0]) != 5) fail(13);	  if (((lr->ectrl >> DTE_BIT) & 3) != 1) fail(14);	  if ((getdtag(mrx) & DTAGMASK) != (1 <<((((int) mrx)>>2)&(DLINESZ-1)))) 		fail(15);	}	/* 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 */	/* check that flush clears valid bits */	/*	lr->cachectrl &= ~0x0f; 	flushi();	while(lr->cachectrl & CCTRL_IFP ) {} 		if (chkitags(ITAG_MAX_ADDRESS,(1<<(ILINEBITS + 2)),0,0) & ((1<<ILINESZ)-1))		fail(51);	lr->cachectrl |= 0x03; 	flushd();	while(lr->cachectrl & CCTRL_DFP) {}	if (chkdtags(DTAG_MAX_ADDRESS,(1<<(DLINEBITS + 2)),0,0) & ((1<<DLINESZ)-1)) 		fail(52);	*/		flush();	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 + =
减小字号Ctrl + -
显示快捷键?