[RFC] [yeeloong] cache algorithms
Vladimir 'φ-coder/phcoder' Serbinenko
phcoder at gmail.com
Mon Sep 27 11:08:50 UTC 2010
On 09/27/2010 09:21 AM, Vladimir 'φ-coder/phcoder' Serbinenko wrote:
> On Loongson the cache maintenance routines are subtly different (took me
> a very long time to figure out). Here I attach the patch which would
> adapt the algorithms for Loongson but it would also break other CPUs so
> I would like your comment on how to best incorporate it into current
> tree? The problems are:
> 1) Other bits are used to specify the way
> 2) i-cache has only index_invalidate and no hit_invalidate
> 3) secondary cache flush is a must on dma operations
> Is it better to copy-paste mipsNN_* to something like mipsNN_loongson_*
> or is it better to use #ifdef's ?
> Should I define mips_sdcache_* to a nop on non-Loongson?
>
>
>
--
Regards
Vladimir 'φ-coder/phcoder' Serbinenko
-------------- next part --------------
=== modified file 'mips/mips/bus_space_generic.c'
--- mips/mips/bus_space_generic.c 2010-08-13 22:16:49 +0000
+++ mips/mips/bus_space_generic.c 2010-08-15 04:18:21 +0000
@@ -593,6 +593,9 @@
{
#if 0
if (flags & BUS_SPACE_BARRIER_WRITE)
+ {
mips_dcache_wbinv_all();
+ mips_sdcache_wbinv_all();
+ }
#endif
}
=== modified file 'mips/mips/busdma_machdep.c'
--- mips/mips/busdma_machdep.c 2010-08-13 22:16:49 +0000
+++ mips/mips/busdma_machdep.c 2010-08-17 14:02:19 +0000
@@ -638,6 +638,8 @@
newmap->allocbuffer = tmpaddr;
mips_dcache_wbinv_range((vm_offset_t)*vaddr,
dmat->maxsize);
+ mips_sdcache_wbinv_range((vm_offset_t)*vaddr,
+ dmat->maxsize);
*vaddr = tmpaddr;
} else
newmap->origbuffer = newmap->allocbuffer = NULL;
@@ -1074,6 +1079,7 @@
if (size_clend)
memcpy (tmp_clend, (void*)buf_clend, size_clend);
mips_dcache_inv_range((vm_offset_t)buf, len);
+ mips_sdcache_inv_range((vm_offset_t)buf, len);
/*
* Restore them
*/
@@ -1088,15 +1094,23 @@
* necessary.
*/
if (size_cl)
+ {
mips_dcache_wbinv_range((vm_offset_t)buf_cl, size_cl);
+ mips_sdcache_wbinv_range((vm_offset_t)buf_cl, size_cl);
+ }
if (size_clend && (size_cl == 0 ||
buf_clend - buf_cl > mips_pdcache_linesize))
+ {
mips_dcache_wbinv_range((vm_offset_t)buf_clend,
size_clend);
+ mips_sdcache_wbinv_range((vm_offset_t)buf_clend,
+ size_clend);
+ }
break;
case BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE:
mips_dcache_wbinv_range((vm_offset_t)buf_cl, len);
+ mips_sdcache_wbinv_range((vm_offset_t)buf_cl, len);
break;
case BUS_DMASYNC_PREREAD:
@@ -1108,6 +1122,7 @@
if (size_clend)
memcpy (tmp_clend, (void *)buf_clend, size_clend);
mips_dcache_inv_range((vm_offset_t)buf, len);
+ mips_sdcache_inv_range((vm_offset_t)buf, len);
/*
* Restore them
*/
@@ -1122,15 +1137,23 @@
* necessary.
*/
if (size_cl)
+ {
mips_dcache_wbinv_range((vm_offset_t)buf_cl, size_cl);
+ mips_sdcache_wbinv_range((vm_offset_t)buf_cl, size_cl);
+ }
if (size_clend && (size_cl == 0 ||
buf_clend - buf_cl > mips_pdcache_linesize))
+ {
mips_dcache_wbinv_range((vm_offset_t)buf_clend,
size_clend);
+ mips_sdcache_wbinv_range((vm_offset_t)buf_clend,
+ size_clend);
+ }
break;
case BUS_DMASYNC_PREWRITE:
mips_dcache_wb_range((vm_offset_t)buf, len);
+ mips_sdcache_wb_range((vm_offset_t)buf, len);
break;
}
}
@@ -1149,6 +1172,8 @@
if (bpage->vaddr_nocache == 0) {
mips_dcache_wb_range(bpage->vaddr,
bpage->datacount);
+ mips_sdcache_wb_range(bpage->vaddr,
+ bpage->datacount);
}
dmat->bounce_zone->total_bounced++;
}
@@ -1156,6 +1181,8 @@
if (bpage->vaddr_nocache == 0) {
mips_dcache_inv_range(bpage->vaddr,
bpage->datacount);
+ mips_sdcache_inv_range(bpage->vaddr,
+ bpage->datacount);
}
bcopy((void *)(bpage->vaddr_nocache != 0 ?
bpage->vaddr_nocache : bpage->vaddr),
=== modified file 'mips/include/cache.h'
--- mips/include/cache.h 2010-08-13 22:16:49 +0000
+++ mips/include/cache.h 2010-08-15 07:38:23 +0000
@@ -213,6 +213,22 @@
#define mips_intern_dcache_wb_range(v, s) \
__mco_2args(intern_, dcache_wb_range, (v), (s))
+#define mips_sdcache_wbinv_all() \
+ __mco_noargs(, dcache_wbinv_all)
+
+#define mips_sdcache_wbinv_range(v, s) \
+ __mco_2args(, dcache_wbinv_range, (v), (s))
+
+#define mips_sdcache_wbinv_range_index(v, s) \
+ __mco_2args(, dcache_wbinv_range_index, (v), (s))
+
+#define mips_sdcache_inv_range(v, s) \
+ __mco_2args(, dcache_inv_range, (v), (s))
+
+#define mips_sdcache_wb_range(v, s) \
+ __mco_2args(, dcache_wb_range, (v), (s))
+
+
/* forward declaration */
struct mips_cpuinfo;
=== modified file 'mips/include/cache_mipsNN.h'
--- mips/include/cache_mipsNN.h 2010-08-13 22:16:49 +0000
+++ mips/include/cache_mipsNN.h 2010-08-15 07:39:31 +0000
@@ -57,6 +57,13 @@
void mipsNN_pdcache_inv_range_32(vm_offset_t, vm_size_t);
void mipsNN_pdcache_wb_range_16(vm_offset_t, vm_size_t);
void mipsNN_pdcache_wb_range_32(vm_offset_t, vm_size_t);
+
+void mipsNN_sdcache_wbinv_all_32(void);
+void mipsNN_sdcache_wbinv_range_32(vm_offset_t, vm_size_t);
+void mipsNN_sdcache_wbinv_range_index_32(vm_offset_t, vm_size_t);
+void mipsNN_sdcache_inv_range_32(vm_offset_t, vm_size_t);
+void mipsNN_sdcache_wb_range_32(vm_offset_t, vm_size_t);
+
#ifdef CPU_CNMIPS
void mipsNN_icache_sync_all_128(void);
void mipsNN_icache_sync_range_128(vm_offset_t, vm_size_t);
=== modified file 'mips/include/cpuinfo.h'
--- mips/include/cpuinfo.h 2010-08-13 22:16:49 +0000
+++ mips/include/cpuinfo.h 2010-08-15 07:43:39 +0000
@@ -67,6 +67,12 @@
u_int8_t dc_nways;
u_int16_t dc_nsets;
} l1;
+ struct {
+ u_int32_t dc_size;
+ u_int8_t dc_linesize;
+ u_int8_t dc_nways;
+ u_int16_t dc_nsets;
+ } l2;
};
extern struct mips_cpuinfo cpuinfo;
=== modified file 'mips/include/cpuregs.h'
--- mips/include/cpuregs.h 2010-08-13 22:16:49 +0000
+++ mips/include/cpuregs.h 2010-08-15 11:09:51 +0000
@@ -136,6 +136,10 @@
#define MIPS_CCA_UC 0x02 /* Uncached. */
#define MIPS_CCA_C 0x03 /* Cacheable, coherency unspecified. */
+#if defined (CPU_R10000) || defined (TARGET_YEELOONG)
+#define MIPS_CCA_UA 0x07
+#endif
+
#if defined(CPU_R4000) || defined(CPU_R10000)
#define MIPS_CCA_CNC 0x03
#define MIPS_CCA_CCE 0x04
@@ -145,10 +149,6 @@
#define MIPS_CCA_CCUOW 0x06
#endif
-#ifdef CPU_R10000
-#define MIPS_CCA_UA 0x07
-#endif
-
#define MIPS_CCA_CACHED MIPS_CCA_CCEW
#endif /* defined(CPU_R4000) || defined(CPU_R10000) */
@@ -188,8 +188,14 @@
#define MIPS_XKSEG_START 0xc000000000000000
#define MIPS_XKSEG_END 0xc00000ff80000000
+#if __mips == 32 || __mips == 64
+#define SSNOP ssnop
+#else
+#define SSNOP nop
+#endif
+
/* CPU dependent mtc0 hazard hook */
-#ifdef CPU_CNMIPS
+#if defined (CPU_CNMIPS) || defined (TARGET_YEELOONG)
#define COP0_SYNC nop; nop; nop; nop; nop;
#elif defined(CPU_SB1)
#define COP0_SYNC ssnop; ssnop; ssnop; ssnop; ssnop; ssnop; ssnop; ssnop; ssnop
@@ -416,7 +422,7 @@
#define MIPS_VEC_EJTAG 0xBFC00480
#define MIPS_VEC_TLB 0x80000000
#define MIPS_VEC_XTLB 0x80000080
-#define MIPS_VEC_CACHE 0x80000100
+#define MIPS_VEC_CACHE 0xa0000100
#define MIPS_VEC_GENERIC 0x80000180 /* Most exceptions */
#define MIPS_VEC_INTERRUPT 0x80000200
=== modified file 'mips/mips/cache.c'
--- mips/mips/cache.c 2010-08-13 22:16:49 +0000
+++ mips/mips/cache.c 2010-08-15 04:07:37 +0000
@@ -194,6 +194,28 @@
cpuinfo->l1.dc_linesize);
}
+ switch (cpuinfo->l2.dc_linesize) {
+ case 32:
+ mips_cache_ops.mco_sdcache_wbinv_all =
+ mips_cache_ops.mco_intern_sdcache_wbinv_all =
+ mipsNN_sdcache_wbinv_all_32;
+ mips_cache_ops.mco_sdcache_wbinv_range =
+ mipsNN_sdcache_wbinv_range_32;
+ mips_cache_ops.mco_sdcache_wbinv_range_index =
+ mips_cache_ops.mco_intern_sdcache_wbinv_range_index =
+ mipsNN_sdcache_wbinv_range_index_32;
+ mips_cache_ops.mco_sdcache_inv_range =
+ mipsNN_sdcache_inv_range_32;
+ mips_cache_ops.mco_sdcache_wb_range =
+ mips_cache_ops.mco_intern_sdcache_wb_range =
+ mipsNN_sdcache_wb_range_32;
+ break;
+ default:
+ panic("no SDcache ops for %d byte lines",
+ cpuinfo->l1.dc_linesize);
+ }
+
+
mipsNN_cache_init(cpuinfo);
#if 0
=== modified file 'mips/mips/cache_mipsNN.c'
--- mips/mips/cache_mipsNN.c 2010-08-13 22:16:49 +0000
+++ mips/mips/cache_mipsNN.c 2010-08-16 22:00:16 +0000
@@ -82,6 +82,12 @@
static int pdcache_loopcount;
static int pdcache_way_mask;
+static int sdcache_size;
+static int sdcache_stride;
+static int sdcache_loopcount;
+static int sdcache_way_mask;
+
+
void
mipsNN_cache_init(struct mips_cpuinfo * cpuinfo)
{
@@ -115,6 +121,15 @@
cpuinfo->l1.dc_nways;
}
+ if (cpuinfo->l2.dc_nsets * cpuinfo->l2.dc_linesize < PAGE_SIZE) {
+ sdcache_stride = cpuinfo->l2.dc_nsets * cpuinfo->l2.dc_linesize;
+ sdcache_loopcount = cpuinfo->l2.dc_nways;
+ } else {
+ sdcache_stride = PAGE_SIZE;
+ sdcache_loopcount = (cpuinfo->l2.dc_nsets * cpuinfo->l2.dc_linesize / PAGE_SIZE) *
+ cpuinfo->l2.dc_nways;
+ }
+
mips_picache_linesize = cpuinfo->l1.ic_linesize;
mips_pdcache_linesize = cpuinfo->l1.dc_linesize;
@@ -123,6 +138,9 @@
pdcache_size = cpuinfo->l1.dc_size;
pdcache_way_mask = cpuinfo->l1.dc_nways - 1;
+ sdcache_size = cpuinfo->l2.dc_size;
+ sdcache_way_mask = cpuinfo->l2.dc_nways - 1;
+
#define CACHE_DEBUG
#ifdef CACHE_DEBUG
printf("Cache info:\n");
@@ -181,6 +199,12 @@
SYNC;
}
+#if __mips == 3
+#define HIT_I_INV CACHE_R4K_I|CACHEOP_R4K_INDEX_INV
+#else
+#define HIT_I_INV CACHE_R4K_I|CACHEOP_R4K_HIT_INV
+#endif
+
void
mipsNN_icache_sync_range_16(vm_offset_t va, vm_size_t size)
{
@@ -192,12 +216,12 @@
mips_intern_dcache_wb_range(va, (eva - va));
while ((eva - va) >= (32 * 16)) {
- cache_r4k_op_32lines_16(va, CACHE_R4K_I|CACHEOP_R4K_HIT_INV);
+ cache_r4k_op_32lines_16(va, HIT_I_INV);
va += (32 * 16);
}
while (va < eva) {
- cache_op_r4k_line(va, CACHE_R4K_I|CACHEOP_R4K_HIT_INV);
+ cache_op_r4k_line(va, HIT_I_INV);
va += 16;
}
@@ -215,12 +239,12 @@
mips_intern_dcache_wb_range(va, (eva - va));
while ((eva - va) >= (32 * 32)) {
- cache_r4k_op_32lines_32(va, CACHE_R4K_I|CACHEOP_R4K_HIT_INV);
+ cache_r4k_op_32lines_32(va, HIT_I_INV);
va += (32 * 32);
}
while (va < eva) {
- cache_op_r4k_line(va, CACHE_R4K_I|CACHEOP_R4K_HIT_INV);
+ cache_op_r4k_line(va, HIT_I_INV);
va += 32;
}
@@ -230,7 +254,7 @@
void
mipsNN_icache_sync_range_index_16(vm_offset_t va, vm_size_t size)
{
- unsigned int eva, tmpva;
+ vm_offset_t eva, tmpva;
int i, stride, loopcount;
/*
@@ -273,8 +297,8 @@
void
mipsNN_icache_sync_range_index_32(vm_offset_t va, vm_size_t size)
{
- unsigned int eva, tmpva;
- int i, stride, loopcount;
+ vm_offset_t eva, tmpva;
+ int stride, loopcount;
/*
* Since we're doing Index ops, we expect to not be able
@@ -282,7 +306,7 @@
* bits that determine the cache index, and make a KSEG0
* address out of them.
*/
- va = MIPS_PHYS_TO_KSEG0(va & picache_way_mask);
+ va = MIPS_PHYS_TO_KSEG0(va & 0x3fe0);
eva = round_line32(va + size);
va = trunc_line32(va);
@@ -298,7 +322,7 @@
while ((eva - va) >= (8 * 32)) {
tmpva = va;
- for (i = 0; i < loopcount; i++, tmpva += stride)
+// for (i = 0; i < loopcount; i++, tmpva += stride)
cache_r4k_op_8lines_32(tmpva,
CACHE_R4K_I|CACHEOP_R4K_INDEX_INV);
va += 8 * 32;
@@ -306,7 +330,7 @@
while (va < eva) {
tmpva = va;
- for (i = 0; i < loopcount; i++, tmpva += stride)
+ // for (i = 0; i < loopcount; i++, tmpva += stride)
cache_op_r4k_line(tmpva,
CACHE_R4K_I|CACHEOP_R4K_INDEX_INV);
va += 32;
@@ -351,12 +375,19 @@
while (va < eva) {
cache_r4k_op_32lines_32(va,
CACHE_R4K_D|CACHEOP_R4K_INDEX_WB_INV);
+ cache_r4k_op_32lines_32(va + 1,
+ CACHE_R4K_D|CACHEOP_R4K_INDEX_WB_INV);
+ cache_r4k_op_32lines_32(va + 2,
+ CACHE_R4K_D|CACHEOP_R4K_INDEX_WB_INV);
+ cache_r4k_op_32lines_32(va + 3,
+ CACHE_R4K_D|CACHEOP_R4K_INDEX_WB_INV);
va += (32 * 32);
}
SYNC;
}
+
void
mipsNN_pdcache_wbinv_range_16(vm_offset_t va, vm_size_t size)
{
@@ -390,11 +421,20 @@
while ((eva - va) >= (32 * 32)) {
cache_r4k_op_32lines_32(va,
CACHE_R4K_D|CACHEOP_R4K_HIT_WB_INV);
+ cache_r4k_op_32lines_32(va + 1,
+ CACHE_R4K_D|CACHEOP_R4K_HIT_WB_INV);
+ cache_r4k_op_32lines_32(va + 2,
+ CACHE_R4K_D|CACHEOP_R4K_HIT_WB_INV);
+ cache_r4k_op_32lines_32(va + 3,
+ CACHE_R4K_D|CACHEOP_R4K_HIT_WB_INV);
va += (32 * 32);
}
while (va < eva) {
cache_op_r4k_line(va, CACHE_R4K_D|CACHEOP_R4K_HIT_WB_INV);
+ cache_op_r4k_line(va + 1, CACHE_R4K_D|CACHEOP_R4K_HIT_WB_INV);
+ cache_op_r4k_line(va + 2, CACHE_R4K_D|CACHEOP_R4K_HIT_WB_INV);
+ cache_op_r4k_line(va + 3, CACHE_R4K_D|CACHEOP_R4K_HIT_WB_INV);
va += 32;
}
@@ -413,7 +453,7 @@
* bits that determine the cache index, and make a KSEG0
* address out of them.
*/
- va = MIPS_PHYS_TO_KSEG0(va & pdcache_way_mask);
+ va = MIPS_PHYS_TO_KSEG0(va & 0x3ff);
eva = round_line16(va + size);
va = trunc_line16(va);
@@ -427,7 +467,7 @@
while ((eva - va) >= (8 * 16)) {
tmpva = va;
- for (i = 0; i < loopcount; i++, tmpva += stride)
+ for (i = 0; i < 4; i++, tmpva ++)
cache_r4k_op_8lines_16(tmpva,
CACHE_R4K_D|CACHEOP_R4K_INDEX_WB_INV);
va += 8 * 16;
@@ -454,7 +494,7 @@
* bits that determine the cache index, and make a KSEG0
* address out of them.
*/
- va = MIPS_PHYS_TO_KSEG0(va & pdcache_way_mask);
+ va = MIPS_PHYS_TO_KSEG0 (va & pdcache_way_mask);
eva = round_line32(va + size);
va = trunc_line32(va);
@@ -482,7 +522,7 @@
va += 32;
}
}
-
+
void
mipsNN_pdcache_inv_range_16(vm_offset_t va, vm_size_t size)
{
@@ -514,11 +554,18 @@
while ((eva - va) >= (32 * 32)) {
cache_r4k_op_32lines_32(va, CACHE_R4K_D|CACHEOP_R4K_HIT_INV);
+ cache_r4k_op_32lines_32(va + 1, CACHE_R4K_D|CACHEOP_R4K_HIT_INV);
+ cache_r4k_op_32lines_32(va + 2, CACHE_R4K_D|CACHEOP_R4K_HIT_INV);
+ cache_r4k_op_32lines_32(va + 3, CACHE_R4K_D|CACHEOP_R4K_HIT_INV);
+
va += (32 * 32);
}
while (va < eva) {
cache_op_r4k_line(va, CACHE_R4K_D|CACHEOP_R4K_HIT_INV);
+ cache_op_r4k_line(va + 1, CACHE_R4K_D|CACHEOP_R4K_HIT_INV);
+ cache_op_r4k_line(va + 2, CACHE_R4K_D|CACHEOP_R4K_HIT_INV);
+ cache_op_r4k_line(va + 3, CACHE_R4K_D|CACHEOP_R4K_HIT_INV);
va += 32;
}
@@ -556,18 +603,23 @@
while ((eva - va) >= (32 * 32)) {
cache_r4k_op_32lines_32(va, CACHE_R4K_D|CACHEOP_R4K_HIT_WB);
+ cache_r4k_op_32lines_32(va + 1, CACHE_R4K_D|CACHEOP_R4K_HIT_WB);
+ cache_r4k_op_32lines_32(va + 2, CACHE_R4K_D|CACHEOP_R4K_HIT_WB);
+ cache_r4k_op_32lines_32(va + 3, CACHE_R4K_D|CACHEOP_R4K_HIT_WB);
va += (32 * 32);
}
while (va < eva) {
cache_op_r4k_line(va, CACHE_R4K_D|CACHEOP_R4K_HIT_WB);
+ cache_op_r4k_line(va + 1, CACHE_R4K_D|CACHEOP_R4K_HIT_WB);
+ cache_op_r4k_line(va + 2, CACHE_R4K_D|CACHEOP_R4K_HIT_WB);
+ cache_op_r4k_line(va + 3, CACHE_R4K_D|CACHEOP_R4K_HIT_WB);
va += 32;
}
SYNC;
}
-
#ifdef CPU_CNMIPS
void
@@ -617,3 +669,136 @@
}
#endif
+
+void
+mipsNN_sdcache_wbinv_all_32(void)
+{
+ vm_offset_t va, eva;
+
+ va = MIPS_PHYS_TO_KSEG0(0);
+ eva = va + sdcache_size;
+
+ /*
+ * Since we're hitting the whole thing, we don't have to
+ * worry about the N different "ways".
+ */
+
+ while (va < eva) {
+ cache_r4k_op_32lines_32(va,
+ CACHE_R4K_SD|CACHEOP_R4K_INDEX_WB_INV);
+ cache_r4k_op_32lines_32(va + 1,
+ CACHE_R4K_SD|CACHEOP_R4K_INDEX_WB_INV);
+ cache_r4k_op_32lines_32(va + 2,
+ CACHE_R4K_SD|CACHEOP_R4K_INDEX_WB_INV);
+ cache_r4k_op_32lines_32(va + 3,
+ CACHE_R4K_SD|CACHEOP_R4K_INDEX_WB_INV);
+ va += (32 * 32);
+ }
+
+ SYNC;
+}
+
+void
+mipsNN_sdcache_wbinv_range_32(vm_offset_t va, vm_size_t size)
+{
+ vm_offset_t eva;
+
+ eva = round_line32(va + size);
+ va = trunc_line32(va);
+
+ while ((eva - va) >= (32 * 32)) {
+ cache_r4k_op_32lines_32(va,
+ CACHE_R4K_SD|CACHEOP_R4K_HIT_WB_INV);
+ va += (32 * 32);
+ }
+
+ while (va < eva) {
+ cache_op_r4k_line(va, CACHE_R4K_SD|CACHEOP_R4K_HIT_WB_INV);
+ va += 32;
+ }
+
+ SYNC;
+}
+
+void
+mipsNN_sdcache_wbinv_range_index_32(vm_offset_t va, vm_size_t size)
+{
+ vm_offset_t eva, tmpva;
+ int i, stride, loopcount;
+
+ /*
+ * Since we're doing Index ops, we expect to not be able
+ * to access the address we've been given. So, get the
+ * bits that determine the cache index, and make a KSEG0
+ * address out of them.
+ */
+ va = MIPS_PHYS_TO_KSEG0 (va & 0x1ffff);
+
+ eva = round_line32(va + size);
+ va = trunc_line32(va);
+
+ /*
+ * GCC generates better code in the loops if we reference local
+ * copies of these global variables.
+ */
+ stride = sdcache_stride;
+ loopcount = sdcache_loopcount;
+
+ while ((eva - va) >= (8 * 32)) {
+ tmpva = va;
+ for (i = 0; i < 4; i++, tmpva++)
+ cache_r4k_op_8lines_32(tmpva,
+ CACHE_R4K_SD|CACHEOP_R4K_INDEX_WB_INV);
+ va += 8 * 32;
+ }
+
+ while (va < eva) {
+ tmpva = va;
+ for (i = 0; i < loopcount; i++, tmpva += stride)
+ cache_op_r4k_line(tmpva,
+ CACHE_R4K_SD|CACHEOP_R4K_INDEX_WB_INV);
+ va += 32;
+ }
+}
+
+void
+mipsNN_sdcache_inv_range_32(vm_offset_t va, vm_size_t size)
+{
+ vm_offset_t eva;
+
+ eva = round_line32(va + size);
+ va = trunc_line32(va);
+
+ while ((eva - va) >= (32 * 32)) {
+ cache_r4k_op_32lines_32(va, CACHE_R4K_SD|CACHEOP_R4K_HIT_INV);
+ va += (32 * 32);
+ }
+
+ while (va < eva) {
+ cache_op_r4k_line(va, CACHE_R4K_SD|CACHEOP_R4K_HIT_INV);
+ va += 32;
+ }
+
+ SYNC;
+}
+
+void
+mipsNN_sdcache_wb_range_32(vm_offset_t va, vm_size_t size)
+{
+ vm_offset_t eva;
+
+ eva = round_line32(va + size);
+ va = trunc_line32(va);
+
+ while ((eva - va) >= (32 * 32)) {
+ cache_r4k_op_32lines_32(va, CACHE_R4K_SD|CACHEOP_R4K_HIT_WB);
+ va += (32 * 32);
+ }
+
+ while (va < eva) {
+ cache_op_r4k_line(va, CACHE_R4K_SD|CACHEOP_R4K_HIT_WB);
+ va += 32;
+ }
+
+ SYNC;
+}
=== modified file 'mips/mips/machdep.c'
--- mips/mips/machdep.c 2010-08-13 22:16:49 +0000
+++ mips/mips/machdep.c 2010-08-17 11:49:47 +0000
@@ -232,7 +232,8 @@
void
cpu_flush_dcache(void *ptr, size_t len)
{
- /* TBD */
+ mips_dcache_wbinv_range((vm_offset_t)ptr, len);
+ mips_sdcache_wbinv_range((vm_offset_t)ptr, len);
}
/* Get current clock frequency for the given cpu id. */
@@ -351,6 +353,7 @@
*/
mips_icache_sync_all();
mips_dcache_wbinv_all();
+ mips_sdcache_wbinv_all();
/*
* Mask all interrupts. Each interrupt will be enabled
=== modified file 'mips/mips/mp_machdep.c'
--- mips/mips/mp_machdep.c 2010-08-13 22:16:49 +0000
+++ mips/mips/mp_machdep.c 2010-08-15 04:18:27 +0000
@@ -272,6 +272,7 @@
* on the BSP.
*/
mips_dcache_wbinv_all();
+ mips_sdcache_wbinv_all();
mips_icache_sync_all();
mips_sync();
=== modified file 'mips/mips/uio_machdep.c'
--- mips/mips/uio_machdep.c 2010-08-13 22:16:49 +0000
+++ mips/mips/uio_machdep.c 2010-08-15 09:23:26 +0000
@@ -100,6 +100,7 @@
* in order to get it overwritten by correct data
*/
mips_dcache_wbinv_range((vm_offset_t)cp, cnt);
+ mips_sdcache_wbinv_range((vm_offset_t)cp, cnt);
pmap_flush_pvcache(m);
} else {
sf = sf_buf_alloc(m, 0);
@@ -131,7 +132,10 @@
if (sf != NULL)
sf_buf_free(sf);
else
+ {
mips_dcache_wbinv_range((vm_offset_t)cp, cnt);
+ mips_sdcache_wbinv_range((vm_offset_t)cp, cnt);
+ }
iov->iov_base = (char *)iov->iov_base + cnt;
iov->iov_len -= cnt;
uio->uio_resid -= cnt;
More information about the freebsd-mips
mailing list