Module Name:    src
Committed By:   skrll
Date:           Wed Feb  5 07:37:36 UTC 2020

Modified Files:
        src/sys/arch/arm/arm: cpufunc.c
        src/sys/arch/arm/arm32: armv7_generic_space.c pmap.c
        src/sys/arch/arm/conf: Makefile.arm
        src/sys/arch/arm/include/arm32: pmap.h

Log Message:
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


To generate a diff of this commit:
cvs rdiff -u -r1.175 -r1.176 src/sys/arch/arm/arm/cpufunc.c
cvs rdiff -u -r1.10 -r1.11 src/sys/arch/arm/arm32/armv7_generic_space.c
cvs rdiff -u -r1.387 -r1.388 src/sys/arch/arm/arm32/pmap.c
cvs rdiff -u -r1.53 -r1.54 src/sys/arch/arm/conf/Makefile.arm
cvs rdiff -u -r1.160 -r1.161 src/sys/arch/arm/include/arm32/pmap.h

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/arch/arm/arm/cpufunc.c
diff -u src/sys/arch/arm/arm/cpufunc.c:1.175 src/sys/arch/arm/arm/cpufunc.c:1.176
--- src/sys/arch/arm/arm/cpufunc.c:1.175	Sat Oct 20 06:35:34 2018
+++ src/sys/arch/arm/arm/cpufunc.c	Wed Feb  5 07:37:35 2020
@@ -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 @@ set_cpufuncs(void)
 #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;

Index: src/sys/arch/arm/arm32/armv7_generic_space.c
diff -u src/sys/arch/arm/arm32/armv7_generic_space.c:1.10 src/sys/arch/arm/arm32/armv7_generic_space.c:1.11
--- src/sys/arch/arm/arm32/armv7_generic_space.c:1.10	Mon Nov 19 10:45:47 2018
+++ src/sys/arch/arm/arm32/armv7_generic_space.c	Wed Feb  5 07:37:35 2020
@@ -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 @@ armv7_generic_bs_map(void *t, bus_addr_t
 	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);

Index: src/sys/arch/arm/arm32/pmap.c
diff -u src/sys/arch/arm/arm32/pmap.c:1.387 src/sys/arch/arm/arm32/pmap.c:1.388
--- src/sys/arch/arm/arm32/pmap.c:1.387	Sun Feb  2 08:56:29 2020
+++ src/sys/arch/arm/arm32/pmap.c	Wed Feb  5 07:37:35 2020
@@ -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 @@ pmap_kenter_pa(vaddr_t va, paddr_t pa, v
 		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 @@ pmap_map_section(vaddr_t l1pt, vaddr_t v
 
 	switch (cache) {
 	case PTE_NOCACHE:
-	default:
-		fl = 0;
+		fl = pte_l1_s_nocache_mode;
 		break;
 
 	case PTE_CACHE:
@@ -6770,6 +6772,11 @@ pmap_map_section(vaddr_t l1pt, vaddr_t v
 	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 @@ pmap_map_entry(vaddr_t l1pt, vaddr_t va,
 
 	switch (cache) {
 	case PTE_NOCACHE:
-	default:
-		npte = 0;
+		npte = pte_l2_s_nocache_mode;
 		break;
 
 	case PTE_CACHE:
@@ -6806,6 +6812,10 @@ pmap_map_entry(vaddr_t l1pt, vaddr_t va,
 	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 @@ pmap_map_chunk(vaddr_t l1pt, vaddr_t va,
 
 	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 @@ pmap_map_chunk(vaddr_t l1pt, vaddr_t va,
 		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 @@ pmap_devmap_find_va(vaddr_t va, vsize_t 
  * 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 @@ void
 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 @@ pmap_uarea(vaddr_t va)
 
 
 #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 @@ pmap_pte_init_arm11mpcore(void)
 #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_pte_init_armv7(void)
 
 	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 @@ pmap_dump(pmap_t pm)
 					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;
+					case 0x48:
+						ch = 'm'; /* Xscale mini-data */
+						break;
+					default:
+						ch = '?';
+						break;
 					}
 
 					if ((pte & L2_S_PROT_U) == L2_S_PROT_U)

Index: src/sys/arch/arm/conf/Makefile.arm
diff -u src/sys/arch/arm/conf/Makefile.arm:1.53 src/sys/arch/arm/conf/Makefile.arm:1.54
--- src/sys/arch/arm/conf/Makefile.arm:1.53	Mon Jan  6 07:40:45 2020
+++ src/sys/arch/arm/conf/Makefile.arm	Wed Feb  5 07:37:36 2020
@@ -1,4 +1,4 @@
-#	$NetBSD: Makefile.arm,v 1.53 2020/01/06 07:40:45 skrll Exp $
+#	$NetBSD: Makefile.arm,v 1.54 2020/02/05 07:37:36 skrll Exp $
 
 # Makefile for NetBSD
 #
@@ -56,26 +56,6 @@ CPPFLAGS.cpufunc_asm_armv6.S+=	-mcpu=arm
 CPPFLAGS.cpufunc_asm_arm11.S+=	-mcpu=arm1136j-s
 CPPFLAGS.cpufunc_asm_xscale.S+=	-mcpu=xscale
 
-.if !empty(MACHINE_ARCH:Mearmv6*) || !empty(MACHINE_ARCH:Mearmv7*)
-# XXX
-#
-# Workaround for alignment faults on ARMv6+, at least occur with
-# axe(4) and athn(4) drivers.
-#
-# For ARMv6+, unaligned access is enabled by default. However, it
-# cannot be used for non-cacheable memory, which is used as DMA
-# buffers. This results in alignment faults above. A real fix is
-# to use cacheable memory as DMA buffers. However, it breaks some
-# drivers, awge(4) and vchiq(4) at least.
-#
-# Until we figure out problems and fix them, we choose a fail-safe
-# workaround here; forbid unaligned memory access for whole kernel.
-# Affects on performance is negligibly small as far as we can see.
-#
-# See PR kern/54486 for more details.
-CFLAGS+=	-mno-unaligned-access
-.endif
-
 OPT_DDB=	%DDB%
 .if !empty(OPT_DDB) && ${HAVE_GCC:U0} > 0
 CFLAGS+=	-mapcs-frame

Index: src/sys/arch/arm/include/arm32/pmap.h
diff -u src/sys/arch/arm/include/arm32/pmap.h:1.160 src/sys/arch/arm/include/arm32/pmap.h:1.161
--- src/sys/arch/arm/include/arm32/pmap.h:1.160	Mon Jan 20 22:13:58 2020
+++ src/sys/arch/arm/include/arm32/pmap.h	Wed Feb  5 07:37:36 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: pmap.h,v 1.160 2020/01/20 22:13:58 skrll Exp $	*/
+/*	$NetBSD: pmap.h,v 1.161 2020/02/05 07:37:36 skrll Exp $	*/
 
 /*
  * Copyright (c) 2002, 2003 Wasabi Systems, Inc.
@@ -221,7 +221,7 @@ struct pmap_devmap {
 		.pd_pa = DEVMAP_ALIGN(pa),		\
 		.pd_size = DEVMAP_SIZE(sz),		\
 		.pd_prot = VM_PROT_READ|VM_PROT_WRITE,	\
-		.pd_cache = PTE_NOCACHE			\
+		.pd_cache = PTE_DEV			\
 	}
 #define	DEVMAP_ENTRY_END	{ 0 }
 
@@ -302,6 +302,7 @@ extern bool arm_has_tlbiasid_p;	/* also 
 #define	PTE_NOCACHE	0
 #define	PTE_CACHE	1
 #define	PTE_PAGETABLE	2
+#define	PTE_DEV		3
 
 /*
  * Flags that indicate attributes of pages or mappings of pages.
@@ -366,6 +367,9 @@ u_int arm32_mmap_flags(paddr_t);
 #define pmap_mmap_flags(ppn)		arm32_mmap_flags(ppn)
 
 #define	PMAP_PTE			0x10000000 /* kenter_pa */
+#define	PMAP_DEV			0x20000000 /* kenter_pa */
+#define	PMAP_DEV_SO			0x40000000 /* kenter_pa */
+#define	PMAP_DEV_MASK			(PMAP_DEV | PMAP_DEV_SO)
 
 /*
  * Functions that we need to export
@@ -662,6 +666,9 @@ void	pmap_pte_init_arm11(void);
 #if defined(CPU_ARM11MPCORE)	/* ARM_MMU_V6 */
 void	pmap_pte_init_arm11mpcore(void);
 #endif
+#if ARM_MMU_V6 == 1
+void	pmap_pte_init_armv6(void);
+#endif /* ARM_MMU_V6 */
 #if ARM_MMU_V7 == 1
 void	pmap_pte_init_armv7(void);
 #endif /* ARM_MMU_V7 */
@@ -683,14 +690,13 @@ void	xscale_setup_minidata(vaddr_t, vadd
 void	pmap_uarea(vaddr_t);
 #endif /* ARM_MMU_XSCALE == 1 */
 
-extern pt_entry_t		pte_l1_s_cache_mode;
-extern pt_entry_t		pte_l1_s_cache_mask;
+extern pt_entry_t		pte_l1_s_nocache_mode;
+extern pt_entry_t		pte_l2_l_nocache_mode;
+extern pt_entry_t		pte_l2_s_nocache_mode;
 
+extern pt_entry_t		pte_l1_s_cache_mode;
 extern pt_entry_t		pte_l2_l_cache_mode;
-extern pt_entry_t		pte_l2_l_cache_mask;
-
 extern pt_entry_t		pte_l2_s_cache_mode;
-extern pt_entry_t		pte_l2_s_cache_mask;
 
 extern pt_entry_t		pte_l1_s_cache_mode_pt;
 extern pt_entry_t		pte_l2_l_cache_mode_pt;
@@ -700,6 +706,10 @@ extern pt_entry_t		pte_l1_s_wc_mode;
 extern pt_entry_t		pte_l2_l_wc_mode;
 extern pt_entry_t		pte_l2_s_wc_mode;
 
+extern pt_entry_t		pte_l1_s_cache_mask;
+extern pt_entry_t		pte_l2_l_cache_mask;
+extern pt_entry_t		pte_l2_s_cache_mask;
+
 extern pt_entry_t		pte_l1_s_prot_u;
 extern pt_entry_t		pte_l1_s_prot_w;
 extern pt_entry_t		pte_l1_s_prot_ro;

Reply via email to