Subject: Re: CVS commit: src/sys/arch/mips
To: None <port-mips@netbsd.org>
From: Izumi Tsutsui <tsutsui@ceres.dti.ne.jp>
List: port-mips
Date: 03/02/2005 22:02:17
In article <20050302090407.GF140@rezrov.net>
wileyc@rezrov.net wrote:
> > Please see my recent patch:
> > http://mail-index.netbsd.org/port-mips/2005/02/26/0007.html
>
> Hmmm, that's much more elegant. Would you like to replace what I committed
> with your version?
Well, I think it's better that some MIPS guys review it before committing.
(related diffs attached)
> Agreed, there is something else wrong that happened post-2.0. My r5ksc indy
> is not very stable running -current, but is rock-solid with 2.0 (with my
> version of the cache patches).
I guess the problem is around 2-way set-associative cache,
i.e. the problem could only happen on R4600/R4700/R5000/R1x000 machines.
Does anyone see the similar problems on R4000 without L2 cache
or R41xx machines, which have direct-mapped cache but no VCE support?
---
Izumi Tsutsui
tsutsui@ceres.dti.ne.jp
Index: include/cache.h
===================================================================
RCS file: /cvsroot/src/sys/arch/mips/include/cache.h,v
retrieving revision 1.6
diff -u -r1.6 cache.h
--- include/cache.h 17 Feb 2003 11:35:01 -0000 1.6
+++ include/cache.h 2 Mar 2005 12:13:05 -0000
@@ -199,6 +199,8 @@
extern u_int mips_cache_alias_mask;
extern u_int mips_cache_prefer_mask;
+extern int mips_cache_virtual_alias;
+
/*
* XXX XXX XXX THIS SHOULD NOT EXIST XXX XXX XXX
*/
Index: mips/cache.c
===================================================================
RCS file: /cvsroot/src/sys/arch/mips/mips/cache.c,v
retrieving revision 1.25
diff -u -r1.25 cache.c
--- mips/cache.c 13 Dec 2004 08:39:21 -0000 1.25
+++ mips/cache.c 2 Mar 2005 12:13:05 -0000
@@ -152,6 +152,8 @@
u_int mips_cache_alias_mask; /* for virtually-indexed caches */
u_int mips_cache_prefer_mask;
+int mips_cache_virtual_alias;
+
struct mips_cache_ops mips_cache_ops;
#ifdef MIPS1
@@ -419,6 +421,11 @@
mips3_get_cache_config(csizebase);
+ if (mips_picache_size > PAGE_SIZE ||
+ mips_pdcache_size > PAGE_SIZE)
+ /* no VCE support if there is no L2 cache */
+ mips_cache_virtual_alias = 1;
+
switch (mips_picache_line_size) {
case 16:
mips_cache_ops.mco_icache_sync_all =
@@ -492,6 +499,10 @@
mips3_get_cache_config(csizebase);
+ if (mips_picache_size > PAGE_SIZE ||
+ mips_pdcache_size > PAGE_SIZE)
+ mips_cache_virtual_alias = 1;
+
switch (mips_picache_line_size) {
case 32:
mips_cache_ops.mco_icache_sync_all =
@@ -588,6 +599,7 @@
~(PAGE_SIZE - 1);
mips_cache_prefer_mask =
max(mips_pdcache_size, mips_picache_size) - 1;
+ mips_cache_virtual_alias = 1;
/* cache ops */
mips_cache_ops.mco_icache_sync_all =
r5900_icache_sync_all_64;
@@ -617,6 +629,8 @@
mips4_get_cache_config(csizebase);
+ /* VCE is handled by hardware */
+
mips_cache_ops.mco_icache_sync_all =
r10k_icache_sync_all;
mips_cache_ops.mco_icache_sync_range =
@@ -675,6 +689,7 @@
mips_cache_alias_mask =
(MIPS3_MAX_PCACHE_SIZE - 1) & ~(PAGE_SIZE - 1);
mips_cache_prefer_mask = MIPS3_MAX_PCACHE_SIZE - 1;
+ mips_cache_virtual_alias = 0;
/* FALLTHROUGH */
case MIPS_R4600:
#ifdef ENABLE_MIPS_R4700
Index: mips/pmap.c
===================================================================
RCS file: /cvsroot/src/sys/arch/mips/mips/pmap.c,v
retrieving revision 1.156
diff -u -r1.156 pmap.c
--- mips/pmap.c 17 Jan 2005 04:54:14 -0000 1.156
+++ mips/pmap.c 2 Mar 2005 12:13:06 -0000
@@ -643,7 +643,7 @@
* is reused with KSEG2 (mapped) addresses. This may
* cause problems on machines without secondary caches.
*/
- if (MIPS_HAS_R4K_MMU)
+ if (mips_cache_virtual_alias)
mips_dcache_wbinv_range((vaddr_t) pte,
PAGE_SIZE);
#endif /* MIPS3_PLUS */
@@ -1598,7 +1598,7 @@
*
* XXXJRT This is totally disgusting.
*/
- if (MIPS_HAS_R4K_MMU && mips_sdcache_line_size == 0)
+ if (MIPS_HAS_R4K_MMU) /*XXX VCED on kernel stack is not allowed */
mips_dcache_wbinv_range(MIPS_PHYS_TO_KSEG0(phys), NBPG);
#endif /* MIPS3_PLUS */
}
@@ -1635,10 +1635,12 @@
* It would probably be better to map the destination as a
* write-through no allocate to reduce cache thrash.
*/
- if (MIPS_HAS_R4K_MMU && mips_sdcache_line_size == 0) {
+ if (mips_cache_virtual_alias) {
/*XXX FIXME Not very sophisticated */
mips_flushcache_allpvh(src);
-/* mips_flushcache_allpvh(dst); */
+#if 0
+ mips_flushcache_allpvh(dst);
+#endif
}
#endif /* MIPS3_PLUS */
@@ -1657,7 +1659,7 @@
*
* XXXJRT -- This is totally disgusting.
*/
- if (MIPS_HAS_R4K_MMU && mips_sdcache_line_size == 0) {
+ if (mips_cache_virtual_alias) {
mips_dcache_wbinv_range(MIPS_PHYS_TO_KSEG0(src), NBPG);
mips_dcache_wbinv_range(MIPS_PHYS_TO_KSEG0(dst), NBPG);
}
@@ -1888,7 +1890,7 @@
pv->pv_next = NULL;
} else {
#if defined(MIPS3_PLUS) /* XXX mmu XXX */
- if (MIPS_HAS_R4K_MMU && mips_sdcache_line_size == 0) {
+ if (mips_cache_virtual_alias) {
/*
* There is at least one other VA mapping this page.
* Check if they are cache index compatible.
@@ -2086,7 +2088,7 @@
pmap_page_cache(pa, 0);
}
#endif
- if (MIPS_HAS_R4K_MMU && last != 0)
+ if (last != 0 && mips_cache_virtual_alias)
mips_dcache_wbinv_range_index(va, PAGE_SIZE);
#endif /* MIPS3_PLUS */
}
@@ -2116,6 +2118,11 @@
void
pmap_pv_page_free(struct pool *pp, void *v)
{
+
+#ifdef MIPS3_PLUS
+ if (mips_cache_virtual_alias)
+ mips_dcache_inv_range((vaddr_t)v, PAGE_SIZE);
+#endif
uvm_pagefree(PHYS_TO_VM_PAGE(MIPS_KSEG0_TO_PHYS((vaddr_t)v)));
}
Index: mips/vm_machdep.c
===================================================================
RCS file: /cvsroot/src/sys/arch/mips/mips/vm_machdep.c,v
retrieving revision 1.105
diff -u -r1.105 vm_machdep.c
--- mips/vm_machdep.c 1 Jan 2005 03:25:46 -0000 1.105
+++ mips/vm_machdep.c 2 Mar 2005 12:13:06 -0000
@@ -131,18 +131,6 @@
pt_entry_t *pte;
int i, x;
-#ifdef MIPS3_PLUS
- /*
- * To eliminate virtual aliases created by pmap_zero_page(),
- * this cache flush operation is necessary.
- * VCED on kernel stack is not allowed.
- * XXXJRT Confirm that this is necessry, and/or fix
- * XXXJRT pmap_zero_page().
- */
- if (CPUISMIPS3 && mips_sdcache_line_size)
- mips_dcache_wbinv_range((vaddr_t) l2->l_addr, USPACE);
-#endif
-
#ifdef DIAGNOSTIC
/*
* If l1 != curlwp && l1 == &lwp0, we're creating a kernel thread.