📄 cachesh7750lib.c
字号:
*/LOCAL STATUS cacheSh7750DmaFree ( void *pBuf ) { STATUS status = OK; if (cacheDataEnabled) { BLOCK_HDR *pHdr = BLOCK_TO_HDR (pBuf); status = VM_STATE_SET (NULL, pBuf, (pHdr->nWords * 2) - sizeof(BLOCK_HDR), VM_STATE_MASK_CACHEABLE, VM_STATE_CACHEABLE); } free (pBuf); return status; }/******************************************************************************** cacheSh7750P2DmaMalloc - allocate a cache-safe buffer from P2 region** This routine attempts to return a pointer to a section of memory that will* not experience cache coherency problems. This routine may be called when* MMU support is NOT available for cache control.** RETURNS: A pointer to a cache-safe buffer, or NULL.** NOMANUAL*/LOCAL void *cacheSh7750P2DmaMalloc ( size_t bytes ) { void *pBuf; int alignment = VM_PAGE_SIZE_GET (); if (alignment != ERROR && _func_valloc != NULL) { /* adjust bytes to a multiple of MMU page size */ bytes = bytes / alignment * alignment + alignment; /* get a page aligned memory */ if ((pBuf = (void *)(*_func_valloc)(bytes)) == NULL) return NULL; /* mark it as non-cacheable, non-writable on virtual space */ VM_STATE_SET (NULL, pBuf, bytes, VM_STATE_MASK_WRITABLE | VM_STATE_MASK_CACHEABLE, VM_STATE_WRITABLE_NOT | VM_STATE_CACHEABLE_NOT); } else { /* adjust bytes to a multiple of cache line length */ alignment = _CACHE_ALIGN_SIZE; bytes = bytes / alignment * alignment + alignment; /* use memalign() to avoid sharing a cache-line with other buffers */ if ((pBuf = memalign (alignment, bytes)) == NULL) return NULL; } /* make sure nothing in pBuf is cached on cacheable region */ if (cacheLib.flushRtn != NULL) cacheLib.flushRtn (DATA_CACHE, pBuf, bytes); /* relocate the buffer to P2 (mmu-bypass, non-cacheable) region */ return (void *)(((UINT32)pBuf & SH7750_PHYS_MASK) | SH7750_P2_BASE); }/******************************************************************************** cacheSh7750P2DmaFree - free the buffer acquired by cacheSh7750P2DmaMalloc()** This routine returns to the free memory pool a block of memory previously* allocated with cacheSh7750P2DmaMalloc().** RETURNS: OK, or ERROR if cacheSh7750P2DmaMalloc() cannot be undone.** NOMANUAL*/LOCAL STATUS cacheSh7750P2DmaFree ( void *pBuf ) { STATUS status = OK; UINT32 p = (UINT32)pBuf; if (p < SH7750_P2_BASE || p > (SH7750_P2_BASE | SH7750_PHYS_MASK)) return ERROR; if (cacheDataMode & CACHE_DMA_BYPASS_P0) p = p & SH7750_PHYS_MASK; /* relocate to P0 */ else if (cacheDataMode & CACHE_DMA_BYPASS_P1) p = (p & SH7750_PHYS_MASK) | SH7750_P1_BASE; /* relocate to P1 */ else if (cacheDataMode & CACHE_DMA_BYPASS_P3) p = (p & SH7750_PHYS_MASK) | SH7750_P3_BASE; /* relocate to P3 */ else return ERROR; if (VM_PAGE_SIZE_GET () != ERROR && _func_valloc != NULL) { BLOCK_HDR *pHdr = BLOCK_TO_HDR ((void *)p); status = VM_STATE_SET (NULL, (void *)p, (pHdr->nWords * 2) - sizeof(BLOCK_HDR), VM_STATE_MASK_WRITABLE | VM_STATE_MASK_CACHEABLE, VM_STATE_WRITABLE | VM_STATE_CACHEABLE); } free ((void *)p); return status; }#undef CACHE_DEBUG#ifdef CACHE_DEBUGSTATUS cacheSh7750Test (CACHE_TYPE cache, int addr, int bytes, int op);/******************************************************************************** cacheSh7750Dump - dump SH7750 cache** NOMANUAL*/STATUS cacheSh7750Dump (CACHE_TYPE cache) { return cacheSh7750Test (cache, 0, 0, OP_NONE); }#include "stdio.h"#include "intLib.h" /* for intLock()/intUnlock() */#undef DISPALY_CACHE_SORTED /* display cache items sorted */ LOCAL UINT32 va[512][9]; /* (512-entry) * (tag[1] + data[8]) */LOCAL UINT32 eva[1024][9]; /* (512-entry) * 2ways * (tag[1] + data[8]) : enhanced mode */LOCAL UINT32 sva[256][9]; /* (512-entry) * (tag[1] + data[8]) */LOCAL UINT32 seva[512][9]; /* (512-entry) * 2ways * (tag[1] + data[8]) : enhanced mode */#ifdef DISPLAY_CACHE_SORTEDLOCAL int partition (UINT32 a[][9], int l, int r) { int i, j, k, 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; for (k = 0; k < 9; k++) {t = a[i][k]; a[i][k] = a[j][k]; a[j][k] = t;} } for (k = 0; k < 9; k++) {t = a[i][k]; a[i][k] = a[r][k]; a[r][k] = t;} return i; }LOCAL void quick_sort_1 (UINT32 a[][9], 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[][9], int n) { quick_sort_1 (a, 0, n - 1); }#endif /* DISPLAY_CACHE_SORTED */LOCAL void cacheSh7750IDumpOp (UINT32 a[][9], UINT32 ccr) { int ent, i, j, k, way; if ( ccr & CCR_2WAY_EMODE ) { for ( way = 0; way <= 0x2000; way += 0x2000 ) for (ent = 0, i = 0; ent <= 0x1fe0; ent += 0x20, i++) { UINT32 tag = *(UINT32 *)(ICACHE_ADRS_ARRAY | way | ent); UINT32 dt; if (ccr & CCR_IC_INDEX_ENABLE) { dt = (((tag ^ (ent << 13)) & 0x02000000) || ((tag ^ ent) & 0x0c00)) ? 0x4 : 0x0; } else dt = ((tag ^ ent) & 0x1c00) ? 0x4 : 0x0; a[i + (way >> 13)*255][0] = (tag & 0xfffffc01) | (ent & 0x3e0) | dt; for (j = 1, k = 0; j <= 8; j++, k += 0x4) a[i + (way >> 13)*255][j] = *(UINT32 *)(ICACHE_DATA_ARRAY | way | ent | k); } } else { for (ent = 0, i = 0; ent <= 0x1fe0; ent += 0x20, i++) { UINT32 tag = *(UINT32 *)(ICACHE_ADRS_ARRAY | ent); UINT32 dt; if (ccr & CCR_IC_INDEX_ENABLE) { dt = (((tag ^ (ent << 13)) & 0x02000000) || ((tag ^ ent) & 0x0c00)) ? 0x4 : 0x0; } else dt = ((tag ^ ent) & 0x1c00) ? 0x4 : 0x0; a[i][0] = (tag & 0xfffffc01) | (ent & 0x3e0) | dt; for (j = 1, k = 0; j <= 8; j++, k += 0x4) a[i][j] = *(UINT32 *)(ICACHE_DATA_ARRAY | ent | k); } } }LOCAL void cacheSh7750DDumpOp (UINT32 a[][9], UINT32 ccr) { int ent, i, j, k; UINT32 bsel, way; if ( ccr & CCR_2WAY_EMODE ) { for ( way = 0; way <= 0x4000; way += 0x4000 ) { for (i = 0, bsel = 0; bsel <= 0x3000; bsel += 0x1000) { if ((ccr & CCR_OC_RAM_ENABLE) && (bsel & 0x2000)) continue; for (ent = 0; ent <= 0xfe0; ent += 0x20, i++) { UINT32 tag = *(UINT32 *)(DCACHE_ADRS_ARRAY | way | bsel | ent); UINT32 dt; UINT32 mask = (ccr & CCR_OC_RAM_ENABLE) ? 0x2c00 : 0x3c00; dt = ((tag ^ (way | bsel | ent)) & mask) ? 0x4 : 0x0; a[i + (way >> 14)*511][0] = (tag & 0xfffffc03) | (ent & 0x3e0) | dt; for (j = 1, k = 0; j <= 8; j++, k += 0x4) a[i + (way >> 14)*511][j] = *(UINT32 *)(DCACHE_DATA_ARRAY | way | bsel | ent | k); } } } } else { for (i = 0, bsel = 0; bsel <= 0x3000; bsel += 0x1000) { if ((ccr & CCR_OC_RAM_ENABLE) && (bsel & 0x1000)) continue; for (ent = 0; ent <= 0xfe0; ent += 0x20, i++) { UINT32 tag = *(UINT32 *)(DCACHE_ADRS_ARRAY | bsel | ent); UINT32 dt; UINT32 mask = (ccr & CCR_OC_RAM_ENABLE) ? 0x2c00 : 0x3c00; if ( ccr & CCR_OC_INDEX_ENABLE ) { dt = (((tag ^ (ent << 12)) & 0x02000000) || ((tag ^ (bsel | ent)) & mask & 0x1fff)) ? 0x4 : 0x0; } else dt = ((tag ^ (bsel | ent)) & mask) ? 0x4 : 0x0; a[i][0] = (tag & 0xfffffc03) | (ent & 0x3e0) | dt; for (j = 1, k = 0; j <= 8; j++, k += 0x4) a[i][j] = *(UINT32 *)(DCACHE_DATA_ARRAY | bsel | ent | k); } } } }LOCAL void cacheSh7750IDisp (UINT32 a[][9], UINT32 ccr) { int i; int lines = 256; /* cache lines */ if ( ccr & CCR_2WAY_EMODE ) { #ifdef DISPLAY_CACHE_SORTED quick_sort (a, lines * 2);#else /* way 0 */ printf("\t\t******** Way 0 ************\n");#endif for (i = 0; i < lines; i++) { printf ("0x%08x: %08x %08x %08x %08x %08x %08x %08x %08x %s %s\n", a[i][0] & 0xfffffff0, a[i][1], a[i][2], a[i][3], a[i][4], a[i][5], a[i][6], a[i][7], a[i][8], a[i][0] & 0x4 ? "!" : " ", a[i][0] & 0x1 ? "V+" : "V-"); }#ifndef DISPLAY_CACHE_SORTED /* way 1 */ printf("\t\t******** Way 1 ************\n");#endif for (i = lines; i < lines * 2; i++) { printf ("0x%08x: %08x %08x %08x %08x %08x %08x %08x %08x %s %s\n", a[i][0] & 0xfffffff0, a[i][1], a[i][2], a[i][3], a[i][4], a[i][5], a[i][6], a[i][7], a[i][8], a[i][0] & 0x4 ? "!" : " ", a[i][0] & 0x1 ? "V+" : "V-"); } } else {#ifdef DISPLAY_CACHE_SORTED quick_sort (a, lines);#endif for (i = 0; i < lines; i++) { printf ("0x%08x: %08x %08x %08x %08x %08x %08x %08x %08x %s %s\n", a[i][0] & 0xfffffff0, a[i][1], a[i][2], a[i][3], a[i][4], a[i][5], a[i][6], a[i][7], a[i][8], a[i][0] & 0x4 ? "!" : " ", a[i][0] & 0x1 ? "V+" : "V-"); } } }LOCAL void cacheSh7750DDisp (UINT32 a[][9], UINT32 ccr) { int i; int lines = (ccr & CCR_OC_RAM_ENABLE) ? 256 : 512; /* cache lines */ if ( ccr & CCR_2WAY_EMODE ) {#ifdef DISPLAY_CACHE_SORTED quick_sort (a, lines * 2);#else /* way 0 */ printf("\t\t******** Way 0 ************\n");#endif for (i = 0; i < lines; i++) { printf ("0x%08x: %08x %08x %08x %08x %08x %08x %08x %08x %s %s %s\n", a[i][0] & 0xfffffff0, a[i][1], a[i][2], a[i][3], a[i][4], a[i][5], a[i][6], a[i][7], a[i][8], a[i][0] & 0x4 ? "!" : " ", a[i][0] & 0x2 ? "U+" : "U-", a[i][0] & 0x1 ? "V+" : "V-"); }#ifndef DISPLAY_CACHE_SORTED /* way 1 */ printf("\t\t******** Way 1 ************\n");#endif for (i = lines; i < lines * 2; i++) { printf ("0x%08x: %08x %08x %08x %08x %08x %08x %08x %08x %s %s %s\n", a[i][0] & 0xfffffff0, a[i][1], a[i][2], a[i][3], a[i][4], a[i][5], a[i][6], a[i][7], a[i][8], a[i][0] & 0x4 ? "!" : " ", a[i][0] & 0x2 ? "U+" : "U-", a[i][0] & 0x1 ? "V+" : "V-"); } } else {#ifdef DISPLAY_CACHE_SORTED quick_sort (a, lines);#endif for (i = 0; i < lines; i++) { printf("0x%08x: %08x %08x %08x %08x %08x %08x %08x %08x %s %s %s\n", a[i][0] & 0xfffffff0, a[i][1], a[i][2], a[i][3], a[i][4], a[i][5], a[i][6], a[i][7], a[i][8], a[i][0] & 0x4 ? "!" : " ", a[i][0] & 0x2 ? "U+" : "U-", a[i][0] & 0x1 ? "V+" : "V-"); } } }#define OP_NONE 0#define OP_FLUSH 1#define OP_CLEAR 2#define OP_INVALIDATE 3STATUS cacheSh7750Test (CACHE_TYPE cache, int addr, int bytes, 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; if (cache == INSTRUCTION_CACHE) pDumpRtn = (UINT32)cacheSh7750IDumpOp; else pDumpRtn = (UINT32)cacheSh7750DDumpOp; pDumpRtn = (pDumpRtn & SH7750_PHYS_MASK) | SH7750_P2_BASE; key = intLock (); /* LOCK INTERRUPTS */ switch (op) { case OP_FLUSH: status = cacheSh7750Flush (cache, (void *)addr, bytes); break; case OP_CLEAR: status = cacheSh7750Clear (cache, (void *)addr, bytes); break; case OP_INVALIDATE: status = cacheSh7750Invalidate (cache, (void *)addr, bytes); break; default: status = ERROR; case OP_NONE: } if ( ccr & CCR_2WAY_EMODE ) (* (VOIDFUNCPTR)pDumpRtn)(*ea, ccr); else (* (VOIDFUNCPTR)pDumpRtn)(*a, ccr); intUnlock (key); /* UNLOCK INTERRUPTS */ if (cache == INSTRUCTION_CACHE) if ( ccr & CCR_2WAY_EMODE ) cacheSh7750IDisp (*ea, ccr);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -