📄 cachesh7604lib.c
字号:
* | 1 0 0 (I/D-cache)| 1 1 0 1 (D-cache) | 1 1 1 0 (I-cache) |* | 1 0 1 (D-cache) | 0 1 0 1 (error) | 0 0 0 0 (disable) |* | 1 1 0 (I-cache) | 0 0 0 0 (disable) | 0 1 1 0 (error) |* | 1 1 1 (locked) | 0 0 0 0 (disable) | 0 0 0 0 (disable) |* +----------------------+-----------------------+-----------------------+*/LOCAL STATUS cacheSh7604Disable ( CACHE_TYPE cache ) { UINT8 ccr = cacheSh7604CCRGet (); switch (cache) { case INSTRUCTION_CACHE: if ((ccr & MC_ENABLE) == 0) /* disabled */ return ERROR; else if (ccr & DC_NOLOAD) /* I-cache or locked */ ccr &= ~(MC_ENABLE | DC_NOLOAD | IC_NOLOAD); else if (ccr & IC_NOLOAD) /* D-cache */ return ERROR; else /* I/D-cache */ ccr |= MC_PURGE | IC_NOLOAD; cacheSh7604CCRSet (ccr); break; case DATA_CACHE: if ((ccr & MC_ENABLE) == 0) /* disabled */ return ERROR; else if (ccr & IC_NOLOAD) /* D-cache or locked */ ccr &= ~(MC_ENABLE | DC_NOLOAD | IC_NOLOAD); else if (ccr & DC_NOLOAD) /* I-cache */ return ERROR; else /* I/D-cache */ ccr |= MC_PURGE | DC_NOLOAD; cacheSh7604CCRSet (ccr); cacheDataEnabled = FALSE; cacheFuncsSet (); /* update cache function pointers */ break; default: errno = S_cacheLib_INVALID_CACHE; return ERROR; } return OK; }/******************************************************************************** cacheSh7604Invalidate - invalidate some or all entries from SH7604 cache** This routine invalidates some or all entries from SH7604 cache.** RETURNS: OK, or ERROR if the specified address is out of cacheable region.** NOMANUAL*/LOCAL STATUS cacheSh7604Invalidate ( CACHE_TYPE cache, void *from, /* address to clear */ size_t bytes ) { UINT32 p = (UINT32)from; UINT8 ccr = cacheSh7604CCRGet (); if (p >= SH7604_CACHE_THRU) /* non-cacheable region */ return ERROR; if (bytes == ENTIRE_CACHE) { cacheSh7604CCRSet (ccr | MC_PURGE); /* invalidate entire cache */ } else if (bytes > 0) { UINT32 ca_begin = p & ~(CAC_LINE_SIZE - 1); UINT32 ca_end = p + bytes - 1; if (ca_end >= SH7604_CACHE_THRU) { ca_end = SH7604_CACHE_THRU - 1; bytes = ca_end - p + 1; } if (bytes < ((ccr & MC_2WAY) ? 5120 : 10240)) /* do associative purge */ { cacheSh7604AInvalidate (ca_begin, ca_end); } else /* check every cache tag */ { int way, ix; int firstway = (ccr & MC_2WAY) ? 2 : 0; for (way = firstway; way < 4; way++) { cacheSh7604CCRSet ((ccr & 0x3f) | (way << 6)); /* select way */ for (ix = 0; ix <= 0x3f0; ix += CAC_LINE_SIZE) { UINT32 *pt = (UINT32 *)(CAC_ADRS_ARRAY | ix); cacheSh7604MInvalidate (pt, ix, ca_begin, ca_end); } } cacheSh7604CCRSet (ccr); /* RESTORE CCR */ } } return OK; }/******************************************************************************** cacheSh7604DmaMalloc - allocate a cache-safe buffer** This routine attempts to return a pointer to a section of memory that will* not experience cache coherency problems. This routine is only called when* MMU support is available for cache control.** RETURNS: A pointer to a cache-safe buffer, or NULL.** NOMANUAL*/LOCAL void *cacheSh7604DmaMalloc ( size_t bytes ) { void *pBuf; int alignment = _CACHE_ALIGN_SIZE; /* adjust bytes to a multiple of cache line length */ bytes = bytes / alignment * alignment + alignment; /* use memalign() to avoid sharing a cache-line with other buffers */ if ((pBuf = memalign (alignment, bytes)) == NULL) return NULL; return (void *)((UINT32)pBuf | SH7604_CACHE_THRU); }/******************************************************************************** cacheSh7604DmaFree - free the buffer acquired by cacheSh7604DmaMalloc()** This routine returns to the free memory pool a block of memory previously* allocated with cacheSh7604DmaMalloc(). The buffer is marked cacheable.** RETURNS: OK, or ERROR if cacheSh7604DmaMalloc() cannot be undone.** NOMANUAL*/LOCAL STATUS cacheSh7604DmaFree ( void *pBuf ) { UINT32 p = (UINT32)pBuf; if (p < SH7604_CACHE_THRU || p >= CAC_ASSOCIATIVE_PURGE) return ERROR; free ((void *)(p & (SH7604_CACHE_THRU - 1))); return OK; }#undef CACHE_DEBUG#ifdef CACHE_DEBUG#include "stdio.h"LOCAL UINT32 va[256][5]; /* (64-entry * 4-way) * (tag[1] + data[4]) *//******************************************************************************** cacheSh7604Dump - dump SH7604 cache** NOMANUAL*/LOCAL int partition (UINT32 a[][5], int l, int r) { int i, j, pivot; UINT32 t; i = l - 1; j = r; pivot = a[r][0]; for (;;) { while (a[++i][0] < pivot) ; while (i < --j && pivot < a[j][0]) ; if (i >= j) break; t = a[i][0]; a[i][0] = a[j][0]; a[j][0] = t; t = a[i][1]; a[i][1] = a[j][1]; a[j][1] = t; t = a[i][2]; a[i][2] = a[j][2]; a[j][2] = t; t = a[i][3]; a[i][3] = a[j][3]; a[j][3] = t; t = a[i][4]; a[i][4] = a[j][4]; a[j][4] = t; } t = a[i][0]; a[i][0] = a[r][0]; a[r][0] = t; t = a[i][1]; a[i][1] = a[r][1]; a[r][1] = t; t = a[i][2]; a[i][2] = a[r][2]; a[r][2] = t; t = a[i][3]; a[i][3] = a[r][3]; a[r][3] = t; t = a[i][4]; a[i][4] = a[r][4]; a[r][4] = t; return i; }LOCAL void quick_sort_1 (UINT32 a[][5], int l, int r) { int v; if (l >= r) return; v = partition (a, l, r); quick_sort_1 (a, l, v - 1); /* sort left partial array */ quick_sort_1 (a, v + 1, r); /* sort right partial array */ }LOCAL void quick_sort (UINT32 a[][5], int n) { quick_sort_1 (a, 0, n - 1); }LOCAL void cacheSh7604DumpOp (UINT32 a[][5], UINT32 ccr) { int ent, i; BOOL t = (ccr & MC_2WAY) ? TRUE : FALSE; /* TRUE if 2-way mode */ for (ent = 0; ent < 64; ent++) { int way; int firstway = t ? 2 : 0; /* 2-way mode uses way 2 and 3 */ for (way = firstway; way <= 3; way++) { UINT32 tag; i = t ? (ent * 2 + way - firstway) : (ent * 4 + way); cacheSh7604CCRSet ((ccr & 0x3f) | (way << 6)); /* select way */ tag = *(UINT32 *)(CAC_ADRS_ARRAY | (ent << 4)); a[i][0] = (tag & 0x1ffffc04) | (ent << 4); a[i][1] = *(UINT32 *)(0xc0000000 | (way << 10) | (ent << 4)); a[i][2] = *(UINT32 *)(0xc0000004 | (way << 10) | (ent << 4)); a[i][3] = *(UINT32 *)(0xc0000008 | (way << 10) | (ent << 4)); a[i][4] = *(UINT32 *)(0xc000000c | (way << 10) | (ent << 4)); } } cacheSh7604CCRSet (ccr); /* RESTORE CCR */ }LOCAL void cacheSh7604Disp (UINT32 a[][5], UINT32 ccr) { int i; int lines = (ccr & MC_2WAY) ? 128 : 256; /* cache lines */ quick_sort (a, lines); for (i = 0; i < lines; i++) { printf ("0x%08x: %08x %08x %08x %08x %s\n", a[i][0] & 0x1ffffff0, a[i][1], a[i][2], a[i][3], a[i][4], a[i][0] & 0x00000004 ? "V+" : "V-"); } }void cacheSh7604ClearTest (int addr, int bytes) { UINT32 pDumpRtn = (UINT32)cacheSh7604DumpOp | SH7604_CACHE_THRU; UINT32 (*a)[256][5] = (UINT32(*)[256][5])((UINT32)va | SH7604_CACHE_THRU); UINT8 ccr = cacheSh7604CCRGet (); int key = intLock (); /* LOCK INTERRUPTS */ cacheClear (INSTRUCTION_CACHE, (void *)addr, bytes); (* (VOIDFUNCPTR)pDumpRtn)(*a, ccr); intUnlock (key); /* UNLOCK INTERRUPTS */ cacheSh7604Disp (*a, ccr); }void cacheSh7604ClearTestAll () { cacheSh7604ClearTest (0, ENTIRE_CACHE); }void cacheSh7604Dump () { cacheSh7604ClearTest (0, 0); }#endif /* CACHE_DEBUG */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -