aboutsummaryrefslogtreecommitdiff
path: root/sys/sparc64/sparc64/cache.c
diff options
context:
space:
mode:
authorJake Burkholder <jake@FreeBSD.org>2001-12-29 07:14:07 +0000
committerJake Burkholder <jake@FreeBSD.org>2001-12-29 07:14:07 +0000
commitf5832be731b0360d3d5d15e369e7992e730d1a09 (patch)
tree244815c894af013642ddf7638a4e1254e7d2f235 /sys/sparc64/sparc64/cache.c
parent21d56e9c33a19f2f97ddf9f009f325b349f8c39c (diff)
downloadsrc-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.c33
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.