Source-Changes-HG archive

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

[src/trunk]: src/sys/arch/arm Fix the armv[67] memory attributes for uncached...



details:   https://anonhg.NetBSD.org/src/rev/0e995585787f
branches:  trunk
changeset: 744528:0e995585787f
user:      skrll <skrll%NetBSD.org@localhost>
date:      Wed Feb 05 07:37:35 2020 +0000

description:
Fix the armv[67] memory attributes for uncached memory.  Previously it was
mapped as strongly-ordered which meant that unaligned accesses would fault.

armv7_generic_bs_map now maps pages with PMAP_DEV which is treated as SO

bus_dma continues to use PMAP_NOCACHE as appropriate, but this now get
mapped to the correct memory attribute bits for armv[67]

DEVMAP_ENTRY usees a new flag PTE_DEV.

The workaround for the unaligned access faults is now removed.

XXX Other armv[67] boards bus_space implementations should be checked.
XXX There is scope to reduce the difference to aarch64

diffstat:

 sys/arch/arm/arm/cpufunc.c               |    6 +-
 sys/arch/arm/arm32/armv7_generic_space.c |    6 +-
 sys/arch/arm/arm32/pmap.c                |  117 +++++++++++++++++++++++++-----
 sys/arch/arm/conf/Makefile.arm           |   22 +-----
 sys/arch/arm/include/arm32/pmap.h        |   24 ++++-
 5 files changed, 122 insertions(+), 53 deletions(-)

diffs (truncated from 421 to 300 lines):

diff -r c10fcde939f7 -r 0e995585787f sys/arch/arm/arm/cpufunc.c
--- a/sys/arch/arm/arm/cpufunc.c        Wed Feb 05 07:24:07 2020 +0000
+++ b/sys/arch/arm/arm/cpufunc.c        Wed Feb 05 07:37:35 2020 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: cpufunc.c,v 1.175 2018/10/20 06:35:34 skrll Exp $      */
+/*     $NetBSD: cpufunc.c,v 1.176 2020/02/05 07:37:35 skrll Exp $      */
 
 /*
  * arm7tdmi support code Copyright (c) 2001 John Fremlin
@@ -49,7 +49,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: cpufunc.c,v 1.175 2018/10/20 06:35:34 skrll Exp $");
+__KERNEL_RCSID(0, "$NetBSD: cpufunc.c,v 1.176 2020/02/05 07:37:35 skrll Exp $");
 
 #include "opt_arm_start.h"
 #include "opt_compat_netbsd.h"
@@ -1776,7 +1776,7 @@
 #ifdef ARM11_CACHE_WRITE_THROUGH
                pmap_pte_init_arm11();
 #else
-               pmap_pte_init_generic();
+               pmap_pte_init_armv6();
 #endif
                if (arm_cache_prefer_mask)
                        uvmexp.ncolors = (arm_cache_prefer_mask >> PGSHIFT) + 1;
diff -r c10fcde939f7 -r 0e995585787f sys/arch/arm/arm32/armv7_generic_space.c
--- a/sys/arch/arm/arm32/armv7_generic_space.c  Wed Feb 05 07:24:07 2020 +0000
+++ b/sys/arch/arm/arm32/armv7_generic_space.c  Wed Feb 05 07:37:35 2020 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: armv7_generic_space.c,v 1.10 2018/11/19 10:45:47 jmcneill Exp $        */
+/*     $NetBSD: armv7_generic_space.c,v 1.11 2020/02/05 07:37:35 skrll Exp $   */
 
 /*-
  * Copyright (c) 2012 The NetBSD Foundation, Inc.
@@ -31,7 +31,7 @@
 
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: armv7_generic_space.c,v 1.10 2018/11/19 10:45:47 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: armv7_generic_space.c,v 1.11 2020/02/05 07:37:35 skrll Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -319,7 +319,7 @@
        else if (flag & BUS_SPACE_MAP_CACHEABLE)
                pmapflags = 0;
        else
-               pmapflags = PMAP_NOCACHE;
+               pmapflags = PMAP_DEV;
 
        for (pa = startpa; pa < endpa; pa += PAGE_SIZE, va += PAGE_SIZE) {
                pmap_kenter_pa(va, pa, VM_PROT_READ | VM_PROT_WRITE, pmapflags);
diff -r c10fcde939f7 -r 0e995585787f sys/arch/arm/arm32/pmap.c
--- a/sys/arch/arm/arm32/pmap.c Wed Feb 05 07:24:07 2020 +0000
+++ b/sys/arch/arm/arm32/pmap.c Wed Feb 05 07:37:35 2020 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: pmap.c,v 1.387 2020/02/02 08:56:29 skrll Exp $ */
+/*     $NetBSD: pmap.c,v 1.388 2020/02/05 07:37:35 skrll Exp $ */
 
 /*
  * Copyright 2003 Wasabi Systems, Inc.
@@ -198,7 +198,7 @@
 #endif
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: pmap.c,v 1.387 2020/02/02 08:56:29 skrll Exp $");
+__KERNEL_RCSID(0, "$NetBSD: pmap.c,v 1.388 2020/02/05 07:37:35 skrll Exp $");
 
 #include <sys/param.h>
 #include <sys/types.h>
@@ -3768,8 +3768,11 @@
                if (!(flags & PMAP_NOCACHE))
                        npte |= pte_l2_s_cache_mode_pt;
        } else {
-               switch (flags & PMAP_CACHE_MASK) {
+               switch (flags & (PMAP_CACHE_MASK | PMAP_DEV_MASK)) {
+               case PMAP_DEV ... PMAP_DEV | PMAP_CACHE_MASK:
+                       break;
                case PMAP_NOCACHE:
+                       npte |= pte_l2_s_nocache_mode;
                        break;
                case PMAP_WRITE_COMBINE:
                        npte |= pte_l2_s_wc_mode;
@@ -6759,8 +6762,7 @@
 
        switch (cache) {
        case PTE_NOCACHE:
-       default:
-               fl = 0;
+               fl = pte_l1_s_nocache_mode;
                break;
 
        case PTE_CACHE:
@@ -6770,6 +6772,11 @@
        case PTE_PAGETABLE:
                fl = pte_l1_s_cache_mode_pt;
                break;
+
+       case PTE_DEV:
+       default:
+               fl = 0;
+               break;
        }
 
        const pd_entry_t npde = L1_S_PROTO | pa |
@@ -6795,8 +6802,7 @@
 
        switch (cache) {
        case PTE_NOCACHE:
-       default:
-               npte = 0;
+               npte = pte_l2_s_nocache_mode;
                break;
 
        case PTE_CACHE:
@@ -6806,6 +6812,10 @@
        case PTE_PAGETABLE:
                npte = pte_l2_s_cache_mode_pt;
                break;
+
+       default:
+               npte = 0;
+               break;
        }
 
        if ((pdep[l1slot] & L1_TYPE_MASK) != L1_TYPE_C)
@@ -6874,10 +6884,9 @@
 
        switch (cache) {
        case PTE_NOCACHE:
-       default:
-               f1 = 0;
-               f2l = 0;
-               f2s = 0;
+               f1 = pte_l1_s_nocache_mode;
+               f2l = pte_l2_l_nocache_mode;
+               f2s = pte_l2_s_nocache_mode;
                break;
 
        case PTE_CACHE:
@@ -6891,6 +6900,13 @@
                f2l = pte_l2_l_cache_mode_pt;
                f2s = pte_l2_s_cache_mode_pt;
                break;
+
+       case PTE_DEV:
+       default:
+               f1 = 0;
+               f2l = 0;
+               f2s = 0;
+               break;
        }
 
        size = resid;
@@ -7102,16 +7118,19 @@
  * them (though, they shouldn't).
  */
 
+pt_entry_t     pte_l1_s_nocache_mode;
 pt_entry_t     pte_l1_s_cache_mode;
 pt_entry_t     pte_l1_s_wc_mode;
 pt_entry_t     pte_l1_s_cache_mode_pt;
 pt_entry_t     pte_l1_s_cache_mask;
 
+pt_entry_t     pte_l2_l_nocache_mode;
 pt_entry_t     pte_l2_l_cache_mode;
 pt_entry_t     pte_l2_l_wc_mode;
 pt_entry_t     pte_l2_l_cache_mode_pt;
 pt_entry_t     pte_l2_l_cache_mask;
 
+pt_entry_t     pte_l2_s_nocache_mode;
 pt_entry_t     pte_l2_s_cache_mode;
 pt_entry_t     pte_l2_s_wc_mode;
 pt_entry_t     pte_l2_s_cache_mode_pt;
@@ -7145,14 +7164,17 @@
 pmap_pte_init_generic(void)
 {
 
+       pte_l1_s_nocache_mode = 0;
        pte_l1_s_cache_mode = L1_S_B|L1_S_C;
        pte_l1_s_wc_mode = L1_S_B;
        pte_l1_s_cache_mask = L1_S_CACHE_MASK_generic;
 
+       pte_l2_l_nocache_mode = 0;
        pte_l2_l_cache_mode = L2_B|L2_C;
        pte_l2_l_wc_mode = L2_B;
        pte_l2_l_cache_mask = L2_L_CACHE_MASK_generic;
 
+       pte_l2_s_nocache_mode = 0;
        pte_l2_s_cache_mode = L2_B|L2_C;
        pte_l2_s_wc_mode = L2_B;
        pte_l2_s_cache_mask = L2_S_CACHE_MASK_generic;
@@ -7536,12 +7558,11 @@
 
 
 #if defined(CPU_ARM11MPCORE)
-
 void
 pmap_pte_init_arm11mpcore(void)
 {
 
-       /* cache mode is controlled by 5 bits (B, C, TEX) */
+       /* cache mode is controlled by 5 bits (B, C, TEX[2:0]) */
        pte_l1_s_cache_mask = L1_S_CACHE_MASK_armv6;
        pte_l2_l_cache_mask = L2_L_CACHE_MASK_armv6;
 #if defined(ARM11MPCORE_COMPAT_MMU) || defined(ARMV6_EXTENDED_SMALL_PAGE)
@@ -7620,6 +7641,54 @@
 #endif /* CPU_ARM11MPCORE */
 
 
+#if ARM_MMU_V6 == 1
+void
+pmap_pte_init_armv6(void)
+{
+       /*
+        * The ARMv6-A MMU is mostly compatible with generic. If the
+        * AP field is zero, that now means "no access" rather than
+        * read-only. The prototypes are a little different because of
+        * the XN bit.
+        */
+       pmap_pte_init_generic();
+
+       pte_l1_s_nocache_mode = L1_S_XS_TEX(1);
+       pte_l2_l_nocache_mode = L2_XS_L_TEX(1);
+       pte_l2_s_nocache_mode = L2_XS_T_TEX(1);
+
+#ifdef ARM11_COMPAT_MMU
+       /* with AP[0..3] */
+       pte_l1_ss_proto = L1_SS_PROTO_armv6;
+#else
+       pte_l1_s_cache_mask = L1_S_CACHE_MASK_armv6n;
+       pte_l2_l_cache_mask = L2_L_CACHE_MASK_armv6n;
+       pte_l2_s_cache_mask = L2_S_CACHE_MASK_armv6n;
+
+       pte_l1_ss_proto = L1_SS_PROTO_armv6;
+       pte_l1_s_proto = L1_S_PROTO_armv6;
+       pte_l1_c_proto = L1_C_PROTO_armv6;
+       pte_l2_s_proto = L2_S_PROTO_armv6n;
+
+       pte_l1_s_prot_u = L1_S_PROT_U_armv6;
+       pte_l1_s_prot_w = L1_S_PROT_W_armv6;
+       pte_l1_s_prot_ro = L1_S_PROT_RO_armv6;
+       pte_l1_s_prot_mask = L1_S_PROT_MASK_armv6;
+
+       pte_l2_l_prot_u = L2_L_PROT_U_armv6n;
+       pte_l2_l_prot_w = L2_L_PROT_W_armv6n;
+       pte_l2_l_prot_ro = L2_L_PROT_RO_armv6n;
+       pte_l2_l_prot_mask = L2_L_PROT_MASK_armv6n;
+
+       pte_l2_s_prot_u = L2_S_PROT_U_armv6n;
+       pte_l2_s_prot_w = L2_S_PROT_W_armv6n;
+       pte_l2_s_prot_ro = L2_S_PROT_RO_armv6n;
+       pte_l2_s_prot_mask = L2_S_PROT_MASK_armv6n;
+
+#endif
+}
+#endif /* ARM_MMU_V6 */
+
 #if ARM_MMU_V7 == 1
 void
 pmap_pte_init_armv7(void)
@@ -7634,6 +7703,10 @@
 
        pmap_needs_pte_sync = 1;
 
+       pte_l1_s_nocache_mode = L1_S_XS_TEX(1);
+       pte_l2_l_nocache_mode = L2_XS_L_TEX(1);
+       pte_l2_s_nocache_mode = L2_XS_T_TEX(1);
+
        pte_l1_s_cache_mask = L1_S_CACHE_MASK_armv7;
        pte_l2_l_cache_mask = L2_L_CACHE_MASK_armv7;
        pte_l2_s_cache_mask = L2_S_CACHE_MASK_armv7;
@@ -7785,22 +7858,28 @@
                                        ch = '.';
                                } else {
                                        occ--;
-                                       switch (pte & 0x0c) {
+                                       switch (pte & 0x4c) {
                                        case 0x00:
-                                               ch = 'D'; /* No cache No buff */
+                                               ch = 'N'; /* No cache No buff */
                                                break;
                                        case 0x04:
                                                ch = 'B'; /* No cache buff */
                                                break;
                                        case 0x08:
-                                               if (pte & 0x40)
-                                                       ch = 'm';
-                                               else
-                                                  ch = 'C'; /* Cache No buff */
+                                               ch = 'C'; /* Cache No buff */
                                                break;
                                        case 0x0c:
                                                ch = 'F'; /* Cache Buff */
                                                break;
+                                       case 0x40:
+                                               ch = 'D';
+                                               break;



Home | Main Index | Thread Index | Old Index