📄 cachesh7750lib.c
字号:
UINT32 bsel, ix, way, nMaxWay = 0x4000; if (ccr & CCR_OC_RAM_ENABLE) nMaxWay = 0; /* only one way */ for (way = 0; way <= nMaxWay; way += 0x4000 ) { for (bsel = 0; bsel <= 0x3000; bsel += 0x1000) { /*if ((ccr & CCR_OC_RAM_ENABLE) && * (bsel == 0x2000) ) continue; */ for (ix = 0; ix <= 0xfe0; ix += 0x20) { UINT32 *pt; pt = (UINT32 *)(DCACHE_ADRS_ARRAY | way | bsel | ix); cacheSh7750TFlush (pt, ix, ca_begin, ca_end); } } } /* way */ } /* (ccr & CCR_OC_RAM_ENABLE) */ } /* (ccr & CCR_2WAY_EMODE) */ else { if (bytes <= ((ccr & CCR_OC_RAM_ENABLE) ? 0x80000 : 0x100000)) { /* use ocbwb instr. */ cacheSh7750DFlush (from, bytes); } else /* check every D-cache tag */ { UINT32 ca_begin = p & 0xffffffe0; UINT32 ca_end = p + bytes - 1; UINT32 bsel, ix; for (bsel = 0; bsel <= 0x3000; bsel += 0x1000) { if ((ccr & CCR_OC_RAM_ENABLE) && (bsel == 0x1000 || bsel == 0x3000)) continue; for (ix = 0; ix <= 0xfe0; ix += 0x20) { UINT32 *pt; pt = (UINT32 *)(DCACHE_ADRS_ARRAY | bsel | ix); cacheSh7750TFlush (pt, ix, ca_begin, ca_end); } } } } } /* (bytes == ENTIRE_CACHE) */ cacheLib.pipeFlushRtn (); break; default: errno = S_cacheLib_INVALID_CACHE; case INSTRUCTION_CACHE: return ERROR; /* no flush operation for I-cache */ } return OK; }/******************************************************************************** cacheSh7750Clear - clear all or some entries from a SH7750 cache** This routine flushes and invalidates all or some entries of the specified* SH7750 cache.** RETURNS: OK, or ERROR if the cache type is invalid or the cache control* is not supported.** NOMANUAL*/LOCAL STATUS cacheSh7750Clear ( CACHE_TYPE cache, void * from, size_t bytes ) { UINT32 ccr = cacheSh7750CCRGet (); UINT32 p = (UINT32)from; if (p >= SH7750_P2_BASE && p <= (SH7750_P2_BASE | SH7750_PHYS_MASK)) return ERROR; /* P2 non-cacheable */ else if (p >= SH7750_P4_BASE) return ERROR; /* P4 non-cacheable */ switch (cache) { case DATA_CACHE: if (bytes == ENTIRE_CACHE) { cacheSh7750DClearAll (); } else { if (ccr & CCR_2WAY_EMODE) { if (bytes <= ((ccr & CCR_OC_RAM_ENABLE) ? 0x80000 : 0x100000)) { /* use ocbp instr. */ cacheSh7750DClear (from, bytes); } else /* check every D-cache tag */ { UINT32 ca_begin = p & 0xffffffe0; UINT32 ca_end = p + bytes - 1; UINT32 bsel, ix, way, nMaxWay = 0x4000; if (ccr & CCR_OC_RAM_ENABLE) nMaxWay = 0; /* only one way */ for (way = 0; way <= nMaxWay; way += 0x4000 ) { for (bsel = 0; bsel <= 0x3000; bsel += 0x1000) { /*if ((ccr & CCR_OC_RAM_ENABLE) && * (bsel == 0x2000) ) continue; */ for (ix = 0; ix <= 0xfe0; ix += 0x20) { UINT32 *pt; pt = (UINT32 *)(DCACHE_ADRS_ARRAY | way | bsel | ix); cacheSh7750TClear (pt, ix, ca_begin, ca_end); } } } /* way */ } /* (ccr & CCR_OC_RAM_ENABLE) */ } /* (ccr & CCR_2WAY_EMODE) */ else { if (bytes <= ((ccr & CCR_OC_RAM_ENABLE) ? 0x80000 : 0x100000)) { /* use ocbp instr. */ cacheSh7750DClear (from, bytes); } else /* check every D-cache tag */ { UINT32 ca_begin = p & 0xffffffe0; UINT32 ca_end = p + bytes - 1; UINT32 bsel, ix; for (bsel = 0; bsel <= 0x3000; bsel += 0x1000) { if ((ccr & CCR_OC_RAM_ENABLE) && (bsel == 0x1000 || bsel == 0x3000)) continue; for (ix = 0; ix <= 0xfe0; ix += 0x20) { UINT32 *pt; pt = (UINT32 *)(DCACHE_ADRS_ARRAY | bsel | ix); cacheSh7750TClear (pt, ix, ca_begin, ca_end); } } } } } cacheLib.pipeFlushRtn (); break; case INSTRUCTION_CACHE: if (bytes == ENTIRE_CACHE) { cacheSh7750CCRSet (ccr | CCR_IC_INVALIDATE); } else { UINT32 mmucr = *(volatile UINT32 *)0xff000010; if (mmucr & 0x1) /* ITLB mishit voids associative invalidation*/ { UINT32 startline = p & 0xffffffe0; UINT32 endline = (p + bytes - 1) & 0xffffffe0; if (startline == endline) return cacheSh7750ILineInvalidate (from); else cacheSh7750CCRSet (ccr | CCR_IC_INVALIDATE); } else if (bytes <= 32768) /* do associative invalidation */ { cacheSh7750IInvalidate (from, bytes); } else /* check every I-cache tag (it takes a while) */ { UINT32 ca_begin = p & 0xffffffe0; UINT32 ca_end = p + bytes - 1; UINT32 ix, way, nMaxWay = 0; if ( ccr & CCR_2WAY_EMODE ) nMaxWay = 0x2000; for (way = 0; way <= nMaxWay; way += 0x2000) { for (ix = 0; ix <= 0x1fe0; ix += 0x20) { UINT32 *pt = (UINT32 *)(ICACHE_ADRS_ARRAY|way|ix); cacheSh7750TInvalidate (pt, ix, ca_begin, ca_end); } } } } break; default: errno = S_cacheLib_INVALID_CACHE; return ERROR; } return OK; }/******************************************************************************** cacheSh7750Invalidate - invalidate all or some entries from a SH7750 cache** This routine invalidates all or some entries of the SH7750 cache.* Depending on cache design, the invalidation may be similar to the flush,* or the tags may be invalidated directly.** RETURNS: OK, or ERROR if the cache type is invalid or the cache control* is not supported.** NOMANUAL*/LOCAL STATUS cacheSh7750Invalidate ( CACHE_TYPE cache, void * from, size_t bytes ) { UINT32 ccr = cacheSh7750CCRGet (); UINT32 p = (UINT32)from; if (p >= SH7750_P2_BASE && p <= (SH7750_P2_BASE | SH7750_PHYS_MASK)) return ERROR; /* P2 non-cacheable */ else if (p >= SH7750_P4_BASE) return ERROR; /* P4 non-cacheable */ switch (cache) { case DATA_CACHE: { if (bytes == ENTIRE_CACHE) { UINT32 mmucr = *(volatile UINT32 *)0xff000010; if ((mmucr & 0x1) == 0 && (ccr & (CCR_WRITE_BACK_P1 | CCR_WRITE_THRU)) == CCR_WRITE_THRU) cacheSh7750CCRSet (ccr | CCR_OC_INVALIDATE); else cacheSh7750DClearAll (); /* MMU may set copyback page */ } else { if (ccr & CCR_2WAY_EMODE) { if (bytes <= ((ccr & CCR_OC_RAM_ENABLE) ? 0x80000 : 0x100000)) { /* use ocbi instr. */ cacheSh7750DInvalidate (from, bytes); } else /* check every D-cache tag */ { UINT32 bsel, ix, way, nMaxWay = 0x4000; UINT32 ca_begin = p & 0xffffffe0; UINT32 ca_end = p + bytes - 1; if (ccr & CCR_OC_RAM_ENABLE) nMaxWay = 0; /* only one way */ for (way = 0; way <= nMaxWay; way += 0x4000) { for (bsel = 0; bsel <= 0x3000; bsel += 0x1000) { /*if ((ccr & CCR_OC_RAM_ENABLE) && * (bsel == 0x2000) ) continue; */ for (ix = 0; ix <= 0xfe0; ix += 0x20) { UINT32 *pt; pt = (UINT32 *)(DCACHE_ADRS_ARRAY | way | bsel | ix); cacheSh7750TInvalidate (pt, ix, ca_begin, ca_end); } } } } } else /* (ccr & CCR_2WAY_EMODE) */ { if (bytes <= ((ccr & CCR_OC_RAM_ENABLE) ? 0x80000 : 0x100000)) { /* use ocbi instr. */ cacheSh7750DInvalidate (from, bytes); } else /* check every D-cache tag */ { UINT32 bsel, ix; UINT32 ca_begin = p & 0xffffffe0; UINT32 ca_end = p + bytes - 1; for (bsel = 0; bsel <= 0x3000; bsel += 0x1000) { if ((ccr & CCR_OC_RAM_ENABLE) && (bsel == 0x1000 || bsel == 0x3000)) continue; for (ix = 0; ix <= 0xfe0; ix += 0x20) { UINT32 *pt; pt = (UINT32 *)(DCACHE_ADRS_ARRAY | bsel | ix); cacheSh7750TInvalidate (pt, ix, ca_begin, ca_end); } } } } /* (ccr & CCR_2WAY_EMODE) */ } /* (bytes == ENTIRE_CACHE) */ } break; case INSTRUCTION_CACHE: if (bytes == ENTIRE_CACHE) { cacheSh7750CCRSet (ccr | CCR_IC_INVALIDATE); } else { UINT32 mmucr = *(volatile UINT32 *)0xff000010; if (mmucr & 0x1) /* ITLB mishit voids associative invalidation*/ { UINT32 startline = p & 0xffffffe0; UINT32 endline = (p + bytes - 1) & 0xffffffe0; if (startline == endline) return cacheSh7750ILineInvalidate (from); else cacheSh7750CCRSet (ccr | CCR_IC_INVALIDATE); } else if (bytes <= 32768) /* do associative invalidation */ { cacheSh7750IInvalidate (from, bytes); } else /* check every I-cache tag (it takes a while) */ { UINT32 ix, way, nMaxWay = 0; UINT32 ca_begin = p & 0xffffffe0; UINT32 ca_end = p + bytes - 1; if ( ccr & CCR_2WAY_EMODE ) nMaxWay = 0x2000; for (way = 0; way <= nMaxWay; way += 0x2000) { for (ix = 0; ix <= 0x1fe0; ix += 0x20) { UINT32 *pt = (UINT32 *)(ICACHE_ADRS_ARRAY|way|ix); cacheSh7750TInvalidate (pt, ix, ca_begin, ca_end); } } } } break; default: errno = S_cacheLib_INVALID_CACHE; return ERROR; } return OK; }/******************************************************************************** cacheSh7750TextUpdate - invalidate updated text section** This routine invalidates the specified text section so that* the correct updated text is executed.** NOMANUAL*/LOCAL STATUS cacheSh7750TextUpdate ( void * from, /* Physical address */ size_t bytes /* bytes to invalidate */ ) { if (cacheLib.flushRtn != NULL) if (cacheLib.flushRtn (DATA_CACHE, from, bytes) != OK) return ERROR; return cacheLib.invalidateRtn (INSTRUCTION_CACHE, from, bytes); }/******************************************************************************** cacheSh7750DmaMalloc - 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.** INTERNAL* We check if the cache is actually on before allocating the memory. It is* possible that the user wants Memory Management Unit (MMU) support but does* not need caching.** RETURNS: A pointer to a cache-safe buffer, or NULL.** NOMANUAL*/LOCAL void *cacheSh7750DmaMalloc ( size_t bytes ) { void *pBuf; int pageSize; if (cacheDataEnabled == FALSE) return malloc (bytes); /* cache is off just allocate buffer */ if ((pageSize = VM_PAGE_SIZE_GET ()) == ERROR) return NULL; /* make sure bytes is a multiple of pageSize */ bytes = bytes / pageSize * pageSize + pageSize; if (_func_valloc == NULL || (pBuf = (void *)(*_func_valloc)(bytes)) == NULL) return NULL; VM_STATE_SET (NULL, pBuf, bytes, VM_STATE_MASK_CACHEABLE, VM_STATE_CACHEABLE_NOT); return pBuf; }/******************************************************************************** cacheSh7750DmaFree - free the buffer acquired by cacheSh7750DmaMalloc()** This routine returns to the free memory pool a block of memory previously* allocated with cacheSh7750DmaMalloc(). The buffer is marked cacheable.** RETURNS: OK, or ERROR if cacheSh7750DmaMalloc() cannot be undone.** NOMANUAL
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -