On Thu, Oct 02, 2014 at 09:16:43PM +0200, Patrick Wildt wrote:
> Hi,
>
> I remember that there has been an issue, only seen on Cortex-A7/A15, like the
> Allwinner A20.
>
> The fix for that issue is somewhere here[0].
>
> Try this[1] kernel and have a look if it has the same issue or not.
>
> I do not have an A20, so I canât test it, sorry. But Iâll probably buy
> this[2][3] one once itâs available.
>
> \Patrick
>
> [0]
> https://github.com/bitrig/bitrig/commit/f1932308435a4b2c3daf0e880dc0adc829f5803d
> [1] https://www.blueri.se/bitrig/armv7/20140925/bsd.rd.SUNXI.umg
> [2]
> http://www.allnet.de/at/allnet-brand/produkte/neuheiten/p/banana-pi-router-board/
> [3] http://www.sinovoip.com.cn/ecp_view.asp?id=554
Here is a diff against -current that handles the L1 pte bits for v7
in the same manner as L2 as suggested by Patrick.
Note that the armv7 snapshot won't install correctly at the
moment as it is missing etc56.tgz
Index: arm/pmap.c
===================================================================
RCS file: /cvs/src/sys/arch/arm/arm/pmap.c,v
retrieving revision 1.46
diff -u -p -r1.46 pmap.c
--- arm/pmap.c 29 Mar 2014 18:09:28 -0000 1.46
+++ arm/pmap.c 3 Oct 2014 06:54:02 -0000
@@ -4585,6 +4585,12 @@ pt_entry_t pte_l1_s_coherent;
pt_entry_t pte_l2_l_coherent;
pt_entry_t pte_l2_s_coherent;
+pt_entry_t pte_l1_s_prot_ur;
+pt_entry_t pte_l1_s_prot_uw;
+pt_entry_t pte_l1_s_prot_kr;
+pt_entry_t pte_l1_s_prot_kw;
+pt_entry_t pte_l1_s_prot_mask;
+
pt_entry_t pte_l2_s_prot_ur;
pt_entry_t pte_l2_s_prot_uw;
pt_entry_t pte_l2_s_prot_kr;
@@ -4631,6 +4637,12 @@ pmap_pte_init_generic(void)
pte_l2_l_coherent = L2_L_COHERENT_generic;
pte_l2_s_coherent = L2_S_COHERENT_generic;
+ pte_l1_s_prot_ur = L1_S_PROT_UR_generic;
+ pte_l1_s_prot_uw = L1_S_PROT_UW_generic;
+ pte_l1_s_prot_kr = L1_S_PROT_KR_generic;
+ pte_l1_s_prot_kw = L1_S_PROT_KW_generic;
+ pte_l1_s_prot_mask = L1_S_PROT_MASK_generic;
+
pte_l2_s_prot_ur = L2_S_PROT_UR_generic;
pte_l2_s_prot_uw = L2_S_PROT_UW_generic;
pte_l2_s_prot_kr = L2_S_PROT_KR_generic;
@@ -4754,6 +4766,12 @@ pmap_pte_init_armv7(void)
pte_l2_l_coherent = L2_L_COHERENT_v7;
pte_l2_s_coherent = L2_S_COHERENT_v7;
+ pte_l1_s_prot_ur = L1_S_PROT_UR_v7;
+ pte_l1_s_prot_uw = L1_S_PROT_UW_v7;
+ pte_l1_s_prot_kr = L1_S_PROT_KR_v7;
+ pte_l1_s_prot_kw = L1_S_PROT_KW_v7;
+ pte_l1_s_prot_mask = L1_S_PROT_MASK_v7;
+
pte_l2_s_prot_ur = L2_S_PROT_UR_v7;
pte_l2_s_prot_uw = L2_S_PROT_UW_v7;
pte_l2_s_prot_kr = L2_S_PROT_KR_v7;
@@ -4885,6 +4903,12 @@ pmap_pte_init_xscale(void)
pte_l1_s_coherent = L1_S_COHERENT_xscale;
pte_l2_l_coherent = L2_L_COHERENT_xscale;
pte_l2_s_coherent = L2_S_COHERENT_xscale;
+
+ pte_l1_s_prot_ur = L1_S_PROT_UR_xscale;
+ pte_l1_s_prot_uw = L1_S_PROT_UW_xscale;
+ pte_l1_s_prot_kr = L1_S_PROT_KR_xscale;
+ pte_l1_s_prot_kw = L1_S_PROT_KW_xscale;
+ pte_l1_s_prot_mask = L1_S_PROT_MASK_xscale;
pte_l2_s_prot_ur = L2_S_PROT_UR_xscale;
pte_l2_s_prot_uw = L2_S_PROT_UW_xscale;
Index: arm/pmap7.c
===================================================================
RCS file: /cvs/src/sys/arch/arm/arm/pmap7.c,v
retrieving revision 1.15
diff -u -p -r1.15 pmap7.c
--- arm/pmap7.c 12 Jul 2014 18:44:41 -0000 1.15
+++ arm/pmap7.c 3 Oct 2014 06:19:40 -0000
@@ -3418,6 +3418,12 @@ pt_entry_t pte_l1_s_coherent;
pt_entry_t pte_l2_l_coherent;
pt_entry_t pte_l2_s_coherent;
+pt_entry_t pte_l1_s_prot_ur;
+pt_entry_t pte_l1_s_prot_uw;
+pt_entry_t pte_l1_s_prot_kr;
+pt_entry_t pte_l1_s_prot_kw;
+pt_entry_t pte_l1_s_prot_mask;
+
pt_entry_t pte_l2_s_prot_ur;
pt_entry_t pte_l2_s_prot_uw;
pt_entry_t pte_l2_s_prot_kr;
@@ -3463,6 +3469,12 @@ pmap_pte_init_generic(void)
pte_l2_l_coherent = L2_L_COHERENT_generic;
pte_l2_s_coherent = L2_S_COHERENT_generic;
+ pte_l1_s_prot_ur = L1_S_PROT_UR_generic;
+ pte_l1_s_prot_uw = L1_S_PROT_UW_generic;
+ pte_l1_s_prot_kr = L1_S_PROT_KR_generic;
+ pte_l1_s_prot_kw = L1_S_PROT_KW_generic;
+ pte_l1_s_prot_mask = L1_S_PROT_MASK_generic;
+
pte_l2_s_prot_ur = L2_S_PROT_UR_generic;
pte_l2_s_prot_uw = L2_S_PROT_UW_generic;
pte_l2_s_prot_kr = L2_S_PROT_KR_generic;
@@ -3505,6 +3517,12 @@ pmap_pte_init_armv7(void)
pte_l1_s_coherent = L1_S_COHERENT_v7;
pte_l2_l_coherent = L2_L_COHERENT_v7;
pte_l2_s_coherent = L2_S_COHERENT_v7;
+
+ pte_l1_s_prot_ur = L1_S_PROT_UR_v7;
+ pte_l1_s_prot_uw = L1_S_PROT_UW_v7;
+ pte_l1_s_prot_kr = L1_S_PROT_KR_v7;
+ pte_l1_s_prot_kw = L1_S_PROT_KW_v7;
+ pte_l1_s_prot_mask = L1_S_PROT_MASK_v7;
pte_l2_s_prot_ur = L2_S_PROT_UR_v7;
pte_l2_s_prot_uw = L2_S_PROT_UW_v7;
Index: include/pmap.h
===================================================================
RCS file: /cvs/src/sys/arch/arm/include/pmap.h,v
retrieving revision 1.25
diff -u -p -r1.25 pmap.h
--- include/pmap.h 30 Jan 2014 18:16:41 -0000 1.25
+++ include/pmap.h 3 Oct 2014 07:25:50 -0000
@@ -440,6 +440,12 @@ extern pt_entry_t pte_l1_s_coherent;
extern pt_entry_t pte_l2_l_coherent;
extern pt_entry_t pte_l2_s_coherent;
+extern pt_entry_t pte_l1_s_prot_ur;
+extern pt_entry_t pte_l1_s_prot_uw;
+extern pt_entry_t pte_l1_s_prot_kr;
+extern pt_entry_t pte_l1_s_prot_kw;
+extern pt_entry_t pte_l1_s_prot_mask;
+
extern pt_entry_t pte_l2_s_prot_ur;
extern pt_entry_t pte_l2_s_prot_uw;
extern pt_entry_t pte_l2_s_prot_kr;
@@ -470,9 +476,23 @@ extern void (*pmap_zero_page_func)(struc
* We use these macros since we use different bits on different processor
* models.
*/
-#define L1_S_PROT_U (L1_S_AP(AP_U))
-#define L1_S_PROT_W (L1_S_AP(AP_W))
-#define L1_S_PROT_MASK (L1_S_PROT_U|L1_S_PROT_W)
+#define L1_S_PROT_UR_generic (L1_S_AP(AP_U))
+#define L1_S_PROT_UW_generic (L1_S_AP(AP_U|AP_W))
+#define L1_S_PROT_KR_generic (L1_S_AP(0))
+#define L1_S_PROT_KW_generic (L1_S_AP(AP_W))
+#define L1_S_PROT_MASK_generic (L1_S_AP(0x03))
+
+#define L1_S_PROT_UR_xscale (L1_S_AP(AP_U))
+#define L1_S_PROT_UW_xscale (L1_S_AP(AP_U|AP_W))
+#define L1_S_PROT_KR_xscale (L1_S_AP(0))
+#define L1_S_PROT_KW_xscale (L1_S_AP(AP_W))
+#define L1_S_PROT_MASK_xscale (L1_S_AP(0x03))
+
+#define L1_S_PROT_UR_v7 (L1_S_AP(AP_KRWUR))
+#define L1_S_PROT_UW_v7 (L1_S_AP(AP_KRWURW))
+#define L1_S_PROT_KR_v7 (L1_S_AP(AP_V7_KR))
+#define L1_S_PROT_KW_v7 (L1_S_AP(AP_KRW))
+#define L1_S_PROT_MASK_v7 (L1_S_AP(0x07))
#define L1_S_CACHE_MASK_generic (L1_S_B|L1_S_C)
#define L1_S_CACHE_MASK_xscale
(L1_S_B|L1_S_C|L1_S_XSCALE_TEX(TEX_XSCALE_X))
@@ -542,6 +562,12 @@ extern void (*pmap_zero_page_func)(struc
#if ARM_NMMUS > 1
/* More than one MMU class configured; use variables. */
+#define L1_S_PROT_UR pte_l1_s_prot_ur
+#define L1_S_PROT_UW pte_l1_s_prot_uw
+#define L1_S_PROT_KR pte_l1_s_prot_kr
+#define L1_S_PROT_KW pte_l1_s_prot_kw
+#define L1_S_PROT_MASK pte_l1_s_prot_mask
+
#define L2_S_PROT_UR pte_l2_s_prot_ur
#define L2_S_PROT_UW pte_l2_s_prot_uw
#define L2_S_PROT_KR pte_l2_s_prot_kr
@@ -563,6 +589,12 @@ extern void (*pmap_zero_page_func)(struc
#define pmap_copy_page(s, d) (*pmap_copy_page_func)((s), (d))
#define pmap_zero_page(d) (*pmap_zero_page_func)((d))
#elif (ARM_MMU_GENERIC + ARM_MMU_SA1) != 0
+#define L1_S_PROT_UR L1_S_PROT_UR_generic
+#define L1_S_PROT_UW L1_S_PROT_UW_generic
+#define L1_S_PROT_KR L1_S_PROT_KR_generic
+#define L1_S_PROT_KW L1_S_PROT_KW_generic
+#define L1_S_PROT_MASK L1_S_PROT_MASK_generic
+
#define L2_S_PROT_UR L2_S_PROT_UR_generic
#define L2_S_PROT_UW L2_S_PROT_UW_generic
#define L2_S_PROT_KR L2_S_PROT_KR_generic
@@ -584,6 +616,12 @@ extern void (*pmap_zero_page_func)(struc
#define pmap_copy_page(s, d) pmap_copy_page_generic((s), (d))
#define pmap_zero_page(d) pmap_zero_page_generic((d))
#elif ARM_MMU_XSCALE == 1
+#define L1_S_PROT_UR L1_S_PROT_UR_xscale
+#define L1_S_PROT_UW L1_S_PROT_UW_xscale
+#define L1_S_PROT_KR L1_S_PROT_KR_xscale
+#define L1_S_PROT_KW L1_S_PROT_KW_xscale
+#define L1_S_PROT_MASK L1_S_PROT_MASK_xscale
+
#define L2_S_PROT_UR L2_S_PROT_UR_xscale
#define L2_S_PROT_UW L2_S_PROT_UW_xscale
#define L2_S_PROT_KR L2_S_PROT_KR_xscale
@@ -605,6 +643,12 @@ extern void (*pmap_zero_page_func)(struc
#define pmap_copy_page(s, d) pmap_copy_page_xscale((s), (d))
#define pmap_zero_page(d) pmap_zero_page_xscale((d))
#elif ARM_MMU_V7 == 1
+#define L1_S_PROT_UR L1_S_PROT_UR_v7
+#define L1_S_PROT_UW L1_S_PROT_UW_v7
+#define L1_S_PROT_KR L1_S_PROT_KR_v7
+#define L1_S_PROT_KW L1_S_PROT_KW_v7
+#define L1_S_PROT_MASK L1_S_PROT_MASK_v7
+
#define L2_S_PROT_UR L2_S_PROT_UR_v7
#define L2_S_PROT_UW L2_S_PROT_UW_v7
#define L2_S_PROT_KR L2_S_PROT_KR_v7
@@ -631,10 +675,27 @@ extern void (*pmap_zero_page_func)(struc
* These macros return various bits based on kernel/user and protection.
* Note that the compiler will usually fold these at compile time.
*/
-#define L1_S_PROT(ku, pr) ((((ku) == PTE_USER) ? L1_S_PROT_U : 0)
| \
- (((pr) & VM_PROT_WRITE) ? L1_S_PROT_W : 0))
-
#ifndef _LOCORE
+static __inline pt_entry_t
+L1_S_PROT(int ku, vm_prot_t pr)
+{
+ pt_entry_t pte;
+
+ if (ku == PTE_USER)
+ pte = (pr & VM_PROT_WRITE) ? L1_S_PROT_UW : L1_S_PROT_UR;
+ else
+ pte = (pr & VM_PROT_WRITE) ? L1_S_PROT_KW : L1_S_PROT_KR;
+ /*
+ * If we set the XN bit, the abort handlers or the vector page
+ * might be marked as such. Needs Debugging.
+ */
+ /*
+ if ((pr & VM_PROT_EXECUTE) == 0)
+ pte |= L1_S_V7_XN;
+ */
+
+ return pte;
+}
static __inline pt_entry_t
L2_L_PROT(int ku, vm_prot_t pr)
{