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)
 {

Reply via email to