📄 cachesh7750lib.c
字号:
else cacheSh7750IDisp (*a, ccr); else if ( ccr & CCR_2WAY_EMODE ) cacheSh7750DDisp (*ea, ccr); else cacheSh7750DDisp (*a, ccr); return status; }STATUS cacheSh7750ICTest (int op) { STATUS status = OK; int key; UINT32 ccr = cacheSh7750CCRGet (); UINT32 (*a)[256][9] = (UINT32(*)[256][9])(((UINT32)sva & SH7750_PHYS_MASK) | SH7750_P2_BASE); UINT32 (*ea)[512][9] = (UINT32(*)[512][9])(((UINT32)seva & SH7750_PHYS_MASK) | SH7750_P2_BASE); UINT32 pDumpRtn; pDumpRtn = (UINT32)cacheSh7750IDumpOp; pDumpRtn = (pDumpRtn & SH7750_PHYS_MASK) | SH7750_P2_BASE; key = intLock (); /* LOCK INTERRUPTS */ if ( ccr & CCR_2WAY_EMODE ) { switch (op) { case OP_FLUSH: status = cacheSh7750Flush (0, 0, ENTIRE_CACHE); break; case OP_CLEAR: status = cacheSh7750Clear (0, 0, ENTIRE_CACHE); break; case OP_INVALIDATE: status = cacheSh7750Invalidate (0, 0, ENTIRE_CACHE); break; default: status = ERROR; case OP_NONE: } (* (VOIDFUNCPTR)pDumpRtn)(*ea, ccr); } else { switch (op) { case OP_FLUSH: status = cacheSh7750Flush (0, 0, ENTIRE_CACHE); break; case OP_CLEAR: status = cacheSh7750Clear (0, 0, ENTIRE_CACHE); break; case OP_INVALIDATE: status = cacheSh7750Invalidate (0, 0, ENTIRE_CACHE); break; default: status = ERROR; case OP_NONE: } (* (VOIDFUNCPTR)pDumpRtn)(*a, ccr); } intUnlock (key); /* UNLOCK INTERRUPTS */ if ( ccr & CCR_2WAY_EMODE ) cacheSh7750IDisp (*ea, ccr); else cacheSh7750IDisp (*a, ccr); return status; }STATUS cacheSh7750OCTest (int op) { STATUS status = OK; int key; UINT32 ccr = cacheSh7750CCRGet (); UINT32 (*a)[512][9] = (UINT32(*)[512][9])(((UINT32)va & SH7750_PHYS_MASK) | SH7750_P2_BASE); UINT32 (*ea)[1024][9] = (UINT32(*)[1024][9])(((UINT32)eva & SH7750_PHYS_MASK) | SH7750_P2_BASE); UINT32 pDumpRtn; pDumpRtn = (UINT32)cacheSh7750DDumpOp; pDumpRtn = (pDumpRtn & SH7750_PHYS_MASK) | SH7750_P2_BASE; key = intLock (); /* LOCK INTERRUPTS */ if ( ccr & CCR_2WAY_EMODE ) { switch (op) { case OP_FLUSH: status = cacheSh7750Flush (1, 0, ENTIRE_CACHE); break; case OP_CLEAR: status = cacheSh7750Clear (1, 0, ENTIRE_CACHE); break; case OP_INVALIDATE: status = cacheSh7750Invalidate (1, 0, ENTIRE_CACHE); break; default: status = ERROR; case OP_NONE: } (* (VOIDFUNCPTR)pDumpRtn)(*ea, ccr); } else { switch (op) { case OP_FLUSH: status = cacheSh7750Flush (1, 0, ENTIRE_CACHE); break; case OP_CLEAR: status = cacheSh7750Clear (1, 0, ENTIRE_CACHE); break; case OP_INVALIDATE: status = cacheSh7750Invalidate (1, 0, ENTIRE_CACHE); break; default: status = ERROR; case OP_NONE: } (* (VOIDFUNCPTR)pDumpRtn)(*a, ccr); } intUnlock (key); /* UNLOCK INTERRUPTS */ if ( ccr & CCR_2WAY_EMODE ) cacheSh7750DDisp (*ea, ccr); else cacheSh7750DDisp (*a, ccr); return status; }STATUS cacheSh7750FlushTestAll (CACHE_TYPE cache) { return cacheSh7750Test (cache, 0, ENTIRE_CACHE, OP_FLUSH); }STATUS cacheSh7750ClearTestAll (CACHE_TYPE cache) { return cacheSh7750Test (cache, 0, ENTIRE_CACHE, OP_CLEAR); }STATUS cacheSh7750InvalidateTestAll (CACHE_TYPE cache) { return cacheSh7750Test (cache, 0, ENTIRE_CACHE, OP_INVALIDATE); }#define TEST_BUF_SIZE 128/******************************************************************************** cacheSh7750Test2 - demonstrate cache flush/invalidate/clear differences** NOMANUAL*/void cacheSh7750Test2 (void) { void *buf = malloc (TEST_BUF_SIZE); char *vp = (char *)buf; char *pp = (char *)(((UINT32)buf & SH7750_PHYS_MASK) | SH7750_P2_BASE); /* FLUSH */ printf("\n\n\t\tCACHE FLUSH TEST\n\n"); strcpy (pp, "1st message in physical memory."); strcpy (vp, "This is a cached message. "); printf ("WRITE P0 & P2---> P0: %s P2: %s\n", vp, pp); cacheFlush (DATA_CACHE, vp, TEST_BUF_SIZE); printf ("FLUSH BY OCBWB--> P0: %s P2: %s\n", vp, pp); cacheFlush (DATA_CACHE, vp, TEST_BUF_SIZE); strcpy (pp, "2nd message in physical memory."); printf ("WRITE P2--------> P0: %s P2: %s\n", vp, pp); printf ("\n"); strcpy (pp, "1st message in physical memory."); strcpy (vp, "This is a cached message. "); printf ("WRITE P0 & P2---> P0: %s P2: %s\n", vp, pp); cacheFlush (DATA_CACHE, vp, ENTIRE_CACHE); printf ("FLUSH ALL TAGS--> P0: %s P2: %s\n", vp, pp); cacheFlush (DATA_CACHE, vp, ENTIRE_CACHE); strcpy (pp, "2nd message in physical memory."); printf ("WRITE P2--------> P0: %s P2: %s\n", vp, pp); printf ("\n"); strcpy (pp, "1st message in physical memory."); strcpy (vp, "This is a cached message. "); printf ("WRITE P0 & P2---> P0: %s P2: %s\n", vp, pp); cacheFlush (DATA_CACHE, vp, 0x100001); printf ("FLUSH TAG BY RMW> P0: %s P2: %s\n", vp, pp); cacheFlush (DATA_CACHE, vp, 0x100001); strcpy (pp, "2nd message in physical memory."); printf ("WRITE P2--------> P0: %s P2: %s\n", vp, pp); printf ("\n"); /* INVALIDATE */ printf("\n\n\t\tCACHE INVALIDATE TEST\n\n"); strcpy (pp, "1st message in physical memory."); strcpy (vp, "This is a cached message. "); printf ("WRITE P0 & P2-----> P0: %s P2: %s\n", vp, pp); cacheInvalidate (DATA_CACHE, vp, TEST_BUF_SIZE); printf ("INVALIDATE BY OCBI> P0: %s P2: %s\n", vp, pp); cacheInvalidate (DATA_CACHE, vp, TEST_BUF_SIZE); strcpy (pp, "2nd message in physical memory."); printf ("WRITE P2----------> P0: %s P2: %s\n", vp, pp); printf ("\n"); strcpy (pp, "1st message in physical memory."); strcpy (vp, "This is a cached message. "); printf ("WRITE P0 & P2-----> P0: %s P2: %s\n", vp, pp); cacheInvalidate (DATA_CACHE, vp, ENTIRE_CACHE); printf ("INVALIDATE ALL TAG> P0: %s P2: %s\n", vp, pp); cacheInvalidate (DATA_CACHE, vp, ENTIRE_CACHE); strcpy (pp, "2nd message in physical memory."); printf ("WRITE P2----------> P0: %s P2: %s\n", vp, pp); printf ("\n"); strcpy (pp, "1st message in physical memory."); strcpy (vp, "This is a cached message. "); printf ("WRITE P0 & P2-----> P0: %s P2: %s\n", vp, pp); cacheInvalidate (DATA_CACHE, vp, 0x100001); printf ("INVALIDATE BY RMW-> P0: %s P2: %s\n", vp, pp); cacheInvalidate (DATA_CACHE, vp, 0x100001); strcpy (pp, "2nd message in physical memory."); printf ("WRITE P2----------> P0: %s P2: %s\n", vp, pp); printf ("\n"); /* CLEAR */ printf("\n\n\t\tCACHE CLEAR TEST\n\n"); strcpy (pp, "1st message in physical memory."); strcpy (vp, "This is a cached message. "); printf ("WRITE P0 & P2---> P0: %s P2: %s\n", vp, pp); cacheClear (DATA_CACHE, vp, TEST_BUF_SIZE); printf ("CLEAR BY OCBP---> P0: %s P2: %s\n", vp, pp); cacheClear (DATA_CACHE, vp, TEST_BUF_SIZE); strcpy (pp, "2nd message in physical memory."); printf ("WRITE P2--------> P0: %s P2: %s\n", vp, pp); printf ("\n"); strcpy (pp, "1st message in physical memory."); strcpy (vp, "This is a cached message. "); printf ("WRITE P0 & P2---> P0: %s P2: %s\n", vp, pp); cacheClear (DATA_CACHE, vp, ENTIRE_CACHE); printf ("CLEAR ALL TAGS--> P0: %s P2: %s\n", vp, pp); cacheClear (DATA_CACHE, vp, ENTIRE_CACHE); strcpy (pp, "2nd message in physical memory."); printf ("WRITE P2--------> P0: %s P2: %s\n", vp, pp); printf ("\n"); strcpy (pp, "1st message in physical memory."); strcpy (vp, "This is a cached message. "); printf ("WRITE P0 & P2---> P0: %s P2: %s\n", vp, pp); cacheClear (DATA_CACHE, vp, 0x100001); printf ("CLEAR TAG BY RMW> P0: %s P2: %s\n", vp, pp); cacheClear (DATA_CACHE, vp, 0x100001); strcpy (pp, "2nd message in physical memory."); printf ("WRITE P2--------> P0: %s P2: %s\n", vp, pp); printf ("\n"); free (buf); }/******************************************************************************** cacheSh7750Test3 - test cacheSh7750TextUpdate functionality** NOMANUAL*/STATUS cacheSh7750Test3 (BOOL update) { USHORT text1 [] = { 0x000b, 0xe0ff }; /* rts; mov #-1,r0 */ USHORT text2 [] = { 0x000b, 0xe000 }; /* rts; mov #0, r0 */ USHORT *pCode = (USHORT *)memalign (_CACHE_ALIGN_SIZE, TEST_BUF_SIZE); bcopy ((char *)text1, (char *)pCode, sizeof (text1)); cacheLib.textUpdateRtn (pCode, sizeof (text1)); bcopy ((char *)text2, (char *)pCode, sizeof (text2)); if (update) cacheLib.textUpdateRtn (pCode, sizeof (text2)); return (* (FUNCPTR)pCode)(); }/******************************************************************************** cacheSh7750Test4 - test write-back buffer synchronization by P2-read** NOMANUAL*/void cacheSh7750Test4 (BOOL clear) { IMPORT int cacheSh7750SyncTest (BOOL clear, char *p0, char *p2); void *buf = malloc (TEST_BUF_SIZE); char *p0 = (char *)buf; char *p2 = (char *)(((UINT32)buf & SH7750_PHYS_MASK) | SH7750_P2_BASE); char mem; *p2 = 'm'; *p0 = 'c'; mem = cacheSh7750SyncTest (clear, p0, p2); printf ("cache: %c, memory: %c\n", *p0, mem); free (buf); }__asm__ (" .global _cacheSh7750SyncTest .type _cacheSh7750SyncTest,@function .align 5_cacheSh7750SyncTest: tst r4,r4 bt .+4 ocbp @r5 ! flush and invalidate cache entry mov.b @r6,r0 ! read P2 immediately rts; nop");/******************************************************************************** cacheSh7750Test5 - test associative I-cache invalidation with MMU enabled** This routine is currently written for big-endian only.** NOMANUAL*/int cacheSh7750Test5 ( int method, /* 0: simple, 1: refill I-TLB, 2: invalidate whole I-cache */ BOOL noPurge, /* 0: purge I-TLB prior to invalidate, 1: no-purge */ int repeat /* times to repeat */ ) { int i, j, purgeCount; STATUS invalResult, testResult = ERROR; UINT32 ccr = cacheSh7750CCRGet (); int pageSize = VM_PAGE_SIZE_GET (); int cacheSize = (ccr & CCR_2WAY_EMODE) ? 16384 : 8192; /* allocate page aligned memories for testing */ USHORT *hop = (USHORT *)memalign (pageSize, 6*2); USHORT *step = (USHORT *)memalign (pageSize, 6*2); USHORT *jump = (USHORT *)memalign (pageSize, 6*2); USHORT *landing = (USHORT *)memalign (pageSize, 3*2); USHORT *test = (USHORT *)memalign (pageSize, cacheSize); if (repeat <= 0 ) repeat = 1; else if (repeat > cacheSize/4) repeat = cacheSize/4; printf ("pageSize: %d, cacheSize: %d, repeat: %d\n", pageSize, cacheSize, repeat); printf ("hop: %x, step: %x, jump: %x, landing: %x, test: %x\n", (int)hop, (int)step, (int)jump, (int)landing, (int)test); /* setup 4 page jumping code to refill I-TLB with new entries */ hop[0] = 0xd001; /* mov.l .+8,r0 */ hop[1] = 0x402b; /* jmp @r0 */ hop[2] = 0x7401; /* add #1,r4 */ hop[3] = 0x0009; /* nop */ hop[4] = (USHORT)(((int)step & 0xffff0000) >> 16); /* .long step */ hop[5] = (USHORT)( (int)step & 0x0000ffff); /* */ cacheSh7750DFlush ((void *)hop, 12); step[0] = 0xd001; /* mov.l .+8,r0 */ step[1] = 0x402b; /* jmp @r0 */ step[2] = 0x7401; /* add #1,r4 */ step[3] = 0x0009; /* nop */ step[4] = (USHORT)(((int)jump & 0xffff0000) >> 16); /* .long jump */ step[5] = (USHORT)( (int)jump & 0x0000ffff); /* */ cacheSh7750DFlush ((void *)step, 12); jump[0] = 0xd001; /* mov.l .+8,r0 */ jump[1] = 0x402b; /* jmp @r0 */ jump[2] = 0x7401; /* add #1,r4 */ jump[3] = 0x0009; /* nop */ jump[4] = (USHORT)(((int)landing & 0xffff0000)>>16);/* .long landing*/ jump[5] = (USHORT)( (int)landing & 0x0000ffff); /* */ cacheSh7750DFlush ((void *)jump, 12); landing[0] = 0x7401; /* add #1,r4 */ landing[1] = 0x000b; /* rts */ landing[2] = 0x6043; /* mov r4,r0 */ cacheSh7750DFlush ((void *)landing, 6); /* setup test codes which return ERROR */ for (i = 0; i < cacheSize/2; i += 2) { test[i] = 0x000b; /* rts */ test[i+1] = 0xe0ff; /* mov #-1,r0 */ } cacheSh7750DFlush ((void *)test, cacheSize); cacheSh7750CCRSet (ccr | CCR_IC_INVALIDATE); /* invalidate whole I-cache */ for (i = 0, j = 0; j < repeat; i += 2, j++) { /* load test code to I-cache (I-TLB mapping is loaded too) */ (* (FUNCPTR)&test[i])(); /* just execute it */ /* modify test code on memory to return OK */ test[i+1] = 0xe000; /* put 'mov #0,r0' on D-cache */ cacheSh7750DFlush ((void *)&test[i+1], 2); /* push out to memory */ /* purge test code mapping on I-TLB (skip if noPurge) */ purgeCount = noPurge ? 0 : (* (FUNCPTR)hop)(0); /* purge whole I-TLB */ /* Now 'return OK' code sits on memory, but 'return ERROR' would * probably stay on I-cache. We should be able to execute 'return OK' * after invalidating the 'return ERROR' on I-cache. */ if (method == 0) { /* I-TLB mishit voids this associative I-cache invalidation */ invalResult = cacheSh7750IInvalidate ((void *)&test[i+1], 2); } else if (method == 1) { /* refill I-TLB before associative I-cache invalidation */ invalResult = cacheSh7750ILineInvalidate ((void *)&test[i+1]); } else if (method == 2) { /* invalidate whole I-cache, it works but inefficient */ invalResult = cacheSh7750CCRSet (ccr | CCR_IC_INVALIDATE); } else invalResult = ERROR; /* execute the modified test code, this should return OK */ testResult = (* (FUNCPTR)&test[i])(); /* revert test code to return ERROR */ test[i+1] = 0xe0ff; /* put 'mov #-1,r0' on D-cache*/ cacheSh7750DFlush ((void *)&test[i+1], 2); /* push out to memory */ /* dump results */ printf ("%d: I-TLB purge: %d, I-cache invalidate: %#x, Test result: %s\n", j, purgeCount, invalResult, testResult ? "FAILED" : "PASSED"); } free (test); free (landing); free (jump); free (step); free (hop); return testResult; }#endif /* CACHE_DEBUG */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -