Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/netbsd-3]: src/sys/arch/mips Pull up following revision(s) (requested by...



details:   https://anonhg.NetBSD.org/src/rev/7a073ea98253
branches:  netbsd-3
changeset: 577506:7a073ea98253
user:      tron <tron%NetBSD.org@localhost>
date:      Mon Nov 21 20:02:26 2005 +0000

description:
Pull up following revision(s) (requested by tsutsui in ticket #961):
        sys/arch/mips/mips/cache.c: revision 1.27
        sys/arch/mips/include/cache.h: revision 1.8
        sys/arch/mips/mips/pmap.c: revision 1.158
        sys/arch/mips/mips/vm_machdep.c: revision 1.106
        sys/arch/mips/mips/mem.c: revision 1.30
        sys/arch/mips/include/pmap.h: revision 1.47
Add a workaround to handle virtual alias which may cause data corruption
on R5000/Rm52xx machines:
- Add a new global variable mips_cache_virtual_alias in mips/cache.c,
  which indicates that VIPT cache on the CPU could cause virtual alias
  and software support is required to handle it. (i.e. no VCED/VCEI)
- Add several cache flush/invalidate ops around KSEG0 access which
  might cause virtual alias if mips_cache_virtual_alias is true.
  (note checking mips_sdcache_line_size isn't valid for R5000/Rm52xx
   because only R4000/R4400 with L2 cache have VCED/VCEI)
- Remove a global variable mips_sdcache_forceinv, which is now superseded
  by new mips_cache_virtual_alias.
While here, also change some R4000/R4400 cache ops:
- Don't override mips_cache_alias_mask and mips_cache_prefer_mask with
  values based on MIPS3_MAX_PCACHE_SIZE for R4000/R4400 with L2 cache
  because it's still worth to reduce VCED/VCEI.
- Flush dcache in pmap_zero_page(9) unconditionally on all MIPS_HAS_R4K_MMU
  CPUs and remove cache flush code from cpu_lwp_fork() in vm_machdep.c.
Thanks to Markus W Kilbinger for testing patches on port-cobalt/port-mips.
XXX This fix is just a workaround because it doesn't handle all possible
XXX virtual aliases. As discussed on port-mips, maybe the real fix
XXX for virtual alias is to change MI UVM to adapt it to VIPT cache.
XXX (all VA mappings against the same PA must have the same VAC index etc.)

diffstat:

 sys/arch/mips/include/cache.h   |    6 +-
 sys/arch/mips/include/pmap.h    |    8 +-
 sys/arch/mips/mips/cache.c      |   28 +++++++++-
 sys/arch/mips/mips/mem.c        |   17 +++++-
 sys/arch/mips/mips/pmap.c       |  104 +++++++++++++++++++++++++++++++++------
 sys/arch/mips/mips/vm_machdep.c |   16 +-----
 6 files changed, 135 insertions(+), 44 deletions(-)

diffs (truncated from 435 to 300 lines):

diff -r 04d63fd15551 -r 7a073ea98253 sys/arch/mips/include/cache.h
--- a/sys/arch/mips/include/cache.h     Mon Nov 21 20:00:27 2005 +0000
+++ b/sys/arch/mips/include/cache.h     Mon Nov 21 20:02:26 2005 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: cache.h,v 1.7 2005/03/01 04:23:44 sekiya Exp $ */
+/*     $NetBSD: cache.h,v 1.7.2.1 2005/11/21 20:02:26 tron Exp $       */
 
 /*
  * Copyright 2001 Wasabi Systems, Inc.
@@ -185,8 +185,6 @@
 
 extern int mips_scache_unified;
 
-extern u_int mips_sdcache_forceinv;    /* force pmap to invalidate for r5ksc */
-
 /* TERTIARY CACHE VARIABLES */
 extern u_int mips_tcache_size;         /* always unified */
 extern u_int mips_tcache_line_size;
@@ -201,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
  */
diff -r 04d63fd15551 -r 7a073ea98253 sys/arch/mips/include/pmap.h
--- a/sys/arch/mips/include/pmap.h      Mon Nov 21 20:00:27 2005 +0000
+++ b/sys/arch/mips/include/pmap.h      Mon Nov 21 20:02:26 2005 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: pmap.h,v 1.46 2005/01/17 04:54:14 atatat Exp $ */
+/*     $NetBSD: pmap.h,v 1.46.6.1 2005/11/21 20:02:26 tron Exp $       */
 
 /*
  * Copyright (c) 1992, 1993
@@ -180,8 +180,10 @@
 /*
  * Alternate mapping hooks for pool pages.  Avoids thrashing the TLB.
  */
-#define        PMAP_MAP_POOLPAGE(pa)   MIPS_PHYS_TO_KSEG0((pa))
-#define        PMAP_UNMAP_POOLPAGE(va) MIPS_KSEG0_TO_PHYS((va))
+vaddr_t mips_pmap_map_poolpage(paddr_t);
+paddr_t mips_pmap_unmap_poolpage(vaddr_t);
+#define        PMAP_MAP_POOLPAGE(pa)   mips_pmap_map_poolpage(pa)
+#define        PMAP_UNMAP_POOLPAGE(va) mips_pmap_unmap_poolpage(va)
 
 /*
  * Other hooks for the pool allocator.
diff -r 04d63fd15551 -r 7a073ea98253 sys/arch/mips/mips/cache.c
--- a/sys/arch/mips/mips/cache.c        Mon Nov 21 20:00:27 2005 +0000
+++ b/sys/arch/mips/mips/cache.c        Mon Nov 21 20:02:26 2005 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: cache.c,v 1.26 2005/03/01 04:23:44 sekiya Exp $        */
+/*     $NetBSD: cache.c,v 1.26.2.1 2005/11/21 20:02:26 tron Exp $      */
 
 /*
  * Copyright 2001, 2002 Wasabi Systems, Inc.
@@ -68,7 +68,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: cache.c,v 1.26 2005/03/01 04:23:44 sekiya Exp $");
+__KERNEL_RCSID(0, "$NetBSD: cache.c,v 1.26.2.1 2005/11/21 20:02:26 tron Exp $");
 
 #include "opt_cputype.h"
 #include "opt_mips_cache.h"
@@ -129,8 +129,6 @@
 
 int mips_scache_unified;
 
-u_int mips_sdcache_forceinv = 0;
-
 /* TERTIARY CACHE VARIABLES */
 u_int mips_tcache_size;                /* always unified */
 u_int mips_tcache_line_size;
@@ -154,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
@@ -421,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 =
@@ -494,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 =
@@ -590,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;
@@ -619,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 =
@@ -669,14 +681,22 @@
        switch (MIPS_PRID_IMPL(cpu_id)) {
 #if defined(MIPS3) || defined(MIPS4)
        case MIPS_R4000:
+#if 0
                /*
                 * R4000/R4400 always detects virtual alias as if
                 * primary cache size is 32KB. Actual primary cache size
                 * is ignored wrt VCED/VCEI.
                 */
+               /*
+                * XXX
+                * It's still better to avoid virtual alias even with VCE,
+                * isn't it?
+                */
                mips_cache_alias_mask =
                        (MIPS3_MAX_PCACHE_SIZE - 1) & ~(PAGE_SIZE - 1);
                mips_cache_prefer_mask = MIPS3_MAX_PCACHE_SIZE - 1;
+#endif
+               mips_cache_virtual_alias = 0;
                /* FALLTHROUGH */
        case MIPS_R4600:
 #ifdef ENABLE_MIPS_R4700
diff -r 04d63fd15551 -r 7a073ea98253 sys/arch/mips/mips/mem.c
--- a/sys/arch/mips/mips/mem.c  Mon Nov 21 20:00:27 2005 +0000
+++ b/sys/arch/mips/mips/mem.c  Mon Nov 21 20:02:26 2005 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: mem.c,v 1.29 2003/08/07 16:28:33 agc Exp $     */
+/*     $NetBSD: mem.c,v 1.29.14.1 2005/11/21 20:02:26 tron Exp $       */
 
 /*
  * Copyright (c) 1982, 1986, 1990, 1993
@@ -76,8 +76,11 @@
  * Memory special file
  */
 
+#include "opt_cputype.h"
+#include "opt_mips_cache.h"
+
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: mem.c,v 1.29 2003/08/07 16:28:33 agc Exp $");
+__KERNEL_RCSID(0, "$NetBSD: mem.c,v 1.29.14.1 2005/11/21 20:02:26 tron Exp $");
 
 #include <sys/param.h>
 #include <sys/conf.h>
@@ -89,6 +92,8 @@
 
 #include <machine/cpu.h>
 
+#include <mips/cache.h>
+
 #include <uvm/uvm_extern.h>
 
 extern paddr_t avail_end;
@@ -142,6 +147,10 @@
                                return (EFAULT);
                        v += MIPS_KSEG0_START;
                        error = uiomove((void *)v, c, uio);
+#if defined(MIPS3_PLUS)
+                       if (mips_cache_virtual_alias)
+                               mips_dcache_wbinv_range(v, c);
+#endif
                        continue;
 
                case DEV_KMEM:
@@ -156,6 +165,10 @@
                            uio->uio_rw == UIO_READ ? B_READ : B_WRITE)))
                                return (EFAULT);
                        error = uiomove((void *)v, c, uio);
+#if defined(MIPS3_PLUS)
+                       if (mips_cache_virtual_alias)
+                               mips_dcache_wbinv_range(v, c);
+#endif
                        continue;
 
                case DEV_NULL:
diff -r 04d63fd15551 -r 7a073ea98253 sys/arch/mips/mips/pmap.c
--- a/sys/arch/mips/mips/pmap.c Mon Nov 21 20:00:27 2005 +0000
+++ b/sys/arch/mips/mips/pmap.c Mon Nov 21 20:02:26 2005 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: pmap.c,v 1.157 2005/03/01 04:23:44 sekiya Exp $        */
+/*     $NetBSD: pmap.c,v 1.157.2.1 2005/11/21 20:02:26 tron Exp $      */
 
 /*-
  * Copyright (c) 1998, 2001 The NetBSD Foundation, Inc.
@@ -74,7 +74,7 @@
 
 #include <sys/cdefs.h>
 
-__KERNEL_RCSID(0, "$NetBSD: pmap.c,v 1.157 2005/03/01 04:23:44 sekiya Exp $");
+__KERNEL_RCSID(0, "$NetBSD: pmap.c,v 1.157.2.1 2005/11/21 20:02:26 tron Exp $");
 
 /*
  *     Manages physical address maps.
@@ -641,10 +641,10 @@
                         * were being accessed by KSEG0 (cached) addresses and
                         * may cause cache coherency problems when the page
                         * is reused with KSEG2 (mapped) addresses.  This may
-                        * cause problems on machines without secondary caches.
+                        * cause problems on machines without VCED/VCEI.
                         */
-                       if (MIPS_HAS_R4K_MMU)
-                               mips_dcache_wbinv_range((vaddr_t) pte,
+                       if (mips_cache_virtual_alias)
+                               mips_dcache_inv_range((vaddr_t)pte,
                                    PAGE_SIZE);
 #endif /* MIPS3_PLUS */
                        uvm_pagefree(PHYS_TO_VM_PAGE(MIPS_KSEG0_TO_PHYS(pte)));
@@ -1577,6 +1577,11 @@
 pmap_zero_page(phys)
        paddr_t phys;
 {
+       vaddr_t va;
+#if defined(MIPS3_PLUS)
+       pv_entry_t pv;
+#endif
+
 #ifdef DEBUG
        if (pmapdebug & PDB_FOLLOW)
                printf("pmap_zero_page(%lx)\n", (u_long)phys);
@@ -1585,8 +1590,18 @@
        if (! (phys < MIPS_MAX_MEM_ADDR))
                printf("pmap_zero_page(%lx) nonphys\n", (u_long)phys);
 #endif
+       va = MIPS_PHYS_TO_KSEG0(phys);
 
-       mips_pagezero((caddr_t)MIPS_PHYS_TO_KSEG0(phys));
+#if defined(MIPS3_PLUS)        /* XXX mmu XXX */
+       if (mips_cache_virtual_alias) {
+               pv = pa_to_pvh(phys);
+               if ((pv->pv_flags & PV_UNCACHED) == 0 &&
+                   mips_cache_indexof(pv->pv_va) != mips_cache_indexof(va))
+                       mips_dcache_wbinv_range_index(pv->pv_va, PAGE_SIZE);
+       }
+#endif
+
+       mips_pagezero((caddr_t)va);
 
 #if defined(MIPS3_PLUS)        /* XXX mmu XXX */
        /*
@@ -1598,9 +1613,8 @@
         *
         * XXXJRT This is totally disgusting.
         */
-       if (MIPS_HAS_R4K_MMU &&
-               ( (mips_sdcache_line_size == 0) || (mips_sdcache_forceinv) ) )
-               mips_dcache_wbinv_range(MIPS_PHYS_TO_KSEG0(phys), NBPG);
+       if (MIPS_HAS_R4K_MMU)   /* XXX VCED on kernel stack is not allowed */
+               mips_dcache_wbinv_range(va, PAGE_SIZE);
 #endif /* MIPS3_PLUS */
 }
 
@@ -1636,11 +1650,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) || (mips_sdcache_forceinv)) ) {
+       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 */
 
@@ -1659,10 +1674,9 @@
         *
         * XXXJRT -- This is totally disgusting.
         */
-       if (MIPS_HAS_R4K_MMU &&
-               ( (mips_sdcache_line_size == 0) || (mips_sdcache_forceinv)) ) {
-               mips_dcache_wbinv_range(MIPS_PHYS_TO_KSEG0(src), NBPG);



Home | Main Index | Thread Index | Old Index