diff options
author | Jake Burkholder <jake@FreeBSD.org> | 2001-12-29 07:14:07 +0000 |
---|---|---|
committer | Jake Burkholder <jake@FreeBSD.org> | 2001-12-29 07:14:07 +0000 |
commit | f5832be731b0360d3d5d15e369e7992e730d1a09 (patch) | |
tree | 244815c894af013642ddf7638a4e1254e7d2f235 /sys/sparc64/sparc64/cache.c | |
parent | 21d56e9c33a19f2f97ddf9f009f325b349f8c39c (diff) | |
download | src-f5832be731b0360d3d5d15e369e7992e730d1a09.tar.gz src-f5832be731b0360d3d5d15e369e7992e730d1a09.zip |
Implement dcache_inval_phys, which shoots the cache lines that correspond
to a specific physical address. This is used for page copy and zero
routines which use physical addresses directly.
Submitted by: tmm
Notes
Notes:
svn path=/head/; revision=88634
Diffstat (limited to 'sys/sparc64/sparc64/cache.c')
-rw-r--r-- | sys/sparc64/sparc64/cache.c | 33 |
1 files changed, 29 insertions, 4 deletions
diff --git a/sys/sparc64/sparc64/cache.c b/sys/sparc64/sparc64/cache.c index 1b3520141a2c..c600b9f6cecd 100644 --- a/sys/sparc64/sparc64/cache.c +++ b/sys/sparc64/sparc64/cache.c @@ -234,7 +234,7 @@ icache_flush(vm_offset_t start, vm_offset_t end) } /* - * Blast a I$ physical range using diagnostic accesses. + * Invalidate a I$ physical range using diagnostic accesses. * NOTE: there is a race between checking the tag and invalidating it. It * cannot be closed by disabling interrupts, since the fetch for the next * instruction may be in that line, so we don't even bother. @@ -294,9 +294,8 @@ dcache_flush(vm_offset_t start, vm_offset_t end) } /* - * Blast a D$ range using diagnostic accesses. + * Invalidate a D$ range using diagnostic accesses. * This has the same (harmless) races as icache_blast(). - * Assumes a page in the kernel map. */ void dcache_inval(pmap_t pmap, vm_offset_t start, vm_offset_t end) @@ -322,6 +321,32 @@ dcache_inval(pmap_t pmap, vm_offset_t start, vm_offset_t end) } } +/* + * Invalidate a physical D$ range using diagnostic accesses. + * This has the same (harmless) races as icache_blast(). + */ +void +dcache_inval_phys(vm_offset_t start, vm_offset_t end) +{ + vm_offset_t pa, dca; + u_long tag, color, ncolors; + + if (!cache.c_enabled) + return; + ncolors = 1 << (cache.dc_l2size - PAGE_SHIFT_MIN); + for (pa = start & ~(cache.dc_linesize - 1); pa <= end; + pa += cache.dc_linesize) { + for (color = 0; color < ncolors; color++) { + dca = (color << PAGE_SHIFT_MIN) | (pa & PAGE_MASK_MIN); + CDIAG_RD(ASI_DCACHE_TAG, dca, tag); + if (DCDT_TAG(tag) == pa >> PAGE_SHIFT_MIN) { + CDIAG_CLR(ASI_DCACHE_TAG, dca); + break; + } + } + } +} + /* Discard all lines in D$. */ void dcache_blast() @@ -360,7 +385,7 @@ ecache_flush(vm_offset_t start, vm_offset_t end) #if 0 /* - * Blast a E$ range using diagnostic accesses. + * Invalidate a E$ range using diagnostic accesses. * This is disabled: it suffers from the same races as dcache_blast() and * icache_blast_phys(), but they may be fatal here because blasting an E$ line * can discard modified data. |