Source-Changes-HG archive

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

[src/trunk]: src/sys/arch add synchronization barrier for AURORA_IO_CACHE_COH...



details:   https://anonhg.NetBSD.org/src/rev/eda823bba54f
branches:  trunk
changeset: 338200:eda823bba54f
user:      hsuenaga <hsuenaga%NetBSD.org@localhost>
date:      Thu May 14 05:39:32 2015 +0000

description:
add synchronization barrier for AURORA_IO_CACHE_COHERENCY.
cleanup MARVELL L2 cache code.

diffstat:

 sys/arch/arm/arm/cpufunc.c                |   52 +++++++---
 sys/arch/arm/arm/cpufunc_asm_pj4b.S       |   26 +++++-
 sys/arch/arm/include/cpufunc_proto.h      |    4 +
 sys/arch/arm/marvell/armadaxp.c           |  136 +++++++++++++++++++++--------
 sys/arch/arm/marvell/armadaxpreg.h        |   44 ++++++++-
 sys/arch/arm/marvell/mvsocreg.h           |   20 +++-
 sys/arch/evbarm/marvell/marvell_machdep.c |   11 +-
 7 files changed, 219 insertions(+), 74 deletions(-)

diffs (truncated from 508 to 300 lines):

diff -r 68668b88b401 -r eda823bba54f sys/arch/arm/arm/cpufunc.c
--- a/sys/arch/arm/arm/cpufunc.c        Thu May 14 02:43:33 2015 +0000
+++ b/sys/arch/arm/arm/cpufunc.c        Thu May 14 05:39:32 2015 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: cpufunc.c,v 1.153 2015/04/17 13:39:01 hsuenaga Exp $   */
+/*     $NetBSD: cpufunc.c,v 1.154 2015/05/14 05:39:32 hsuenaga 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.153 2015/04/17 13:39:01 hsuenaga Exp $");
+__KERNEL_RCSID(0, "$NetBSD: cpufunc.c,v 1.154 2015/05/14 05:39:32 hsuenaga Exp $");
 
 #include "opt_compat_netbsd.h"
 #include "opt_cpuoptions.h"
@@ -1371,8 +1371,7 @@
        .cf_tlb_flushD          = armv7_tlb_flushID,
        .cf_tlb_flushD_SE       = armv7_tlb_flushID_SE,
 
-       /* Cache operations */
-
+       /* Cache operations (see also pj4bv7_setup) */
        .cf_icache_sync_all     = armv7_idcache_wbinv_all,
        .cf_icache_sync_range   = armv7_icache_sync_range,
 
@@ -1381,18 +1380,6 @@
        .cf_dcache_inv_range    = armv7_dcache_inv_range,
        .cf_dcache_wb_range     = armv7_dcache_wb_range,
 
-#if defined(L2CACHE_ENABLE) && \
-    !defined(AURORA_IO_CACHE_COHERENCY) && \
-    defined(ARMADAXP)
-       .cf_sdcache_wbinv_range = armadaxp_sdcache_wbinv_range,
-       .cf_sdcache_inv_range   = armadaxp_sdcache_inv_range,
-       .cf_sdcache_wb_range    = armadaxp_sdcache_wb_range,
-#else
-       .cf_sdcache_wbinv_range = (void *)cpufunc_nullop,
-       .cf_sdcache_inv_range   = (void *)cpufunc_nullop,
-       .cf_sdcache_wb_range    = (void *)cpufunc_nullop,
-#endif
-
        .cf_idcache_wbinv_all   = armv7_idcache_wbinv_all,
        .cf_idcache_wbinv_range = armv7_idcache_wbinv_range,
 
@@ -3096,6 +3083,36 @@
                cpuctrl |= CPU_CONTROL_VECRELOC;
 #endif
 
+#ifdef L2CACHE_ENABLE
+       /* Setup L2 cache */
+       arm_scache.cache_type = CPU_CT_CTYPE_WT;
+       arm_scache.cache_unified = 1;
+       arm_scache.dcache_type = arm_scache.icache_type = CACHE_TYPE_PIPT;
+       arm_scache.dcache_size = arm_scache.icache_size = ARMADAXP_L2_SIZE;
+       arm_scache.dcache_ways = arm_scache.icache_ways = ARMADAXP_L2_WAYS;
+       arm_scache.dcache_way_size = arm_scache.icache_way_size =
+           ARMADAXP_L2_WAY_SIZE;
+       arm_scache.dcache_line_size = arm_scache.icache_line_size =
+           ARMADAXP_L2_LINE_SIZE;
+       arm_scache.dcache_sets = arm_scache.icache_sets =
+           ARMADAXP_L2_SETS;
+
+       cpufuncs.cf_sdcache_wbinv_range = armadaxp_sdcache_wbinv_range;
+       cpufuncs.cf_sdcache_inv_range   = armadaxp_sdcache_inv_range;
+       cpufuncs.cf_sdcache_wb_range    = armadaxp_sdcache_wb_range;
+#endif
+
+#ifdef AURORA_IO_CACHE_COHERENCY
+       /* use AMBA and I/O Coherency Fabric to maintain cache */
+       cpufuncs.cf_dcache_wbinv_range  = pj4b_dcache_cfu_wbinv_range;
+       cpufuncs.cf_dcache_inv_range    = pj4b_dcache_cfu_inv_range;
+       cpufuncs.cf_dcache_wb_range     = pj4b_dcache_cfu_wb_range;
+
+       cpufuncs.cf_sdcache_wbinv_range = (void *)cpufunc_nullop;
+       cpufuncs.cf_sdcache_inv_range   = (void *)cpufunc_nullop;
+       cpufuncs.cf_sdcache_wb_range    = (void *)cpufunc_nullop;
+#endif
+
        /* Clear out the cache */
        cpu_idcache_wbinv_all();
 
@@ -3104,6 +3121,9 @@
 
        /* And again. */
        cpu_idcache_wbinv_all();
+#ifdef L2CACHE_ENABLE
+       armadaxp_sdcache_wbinv_all();
+#endif
 
        curcpu()->ci_ctrl = cpuctrl;
 }
diff -r 68668b88b401 -r eda823bba54f sys/arch/arm/arm/cpufunc_asm_pj4b.S
--- a/sys/arch/arm/arm/cpufunc_asm_pj4b.S       Thu May 14 02:43:33 2015 +0000
+++ b/sys/arch/arm/arm/cpufunc_asm_pj4b.S       Thu May 14 05:39:32 2015 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: cpufunc_asm_pj4b.S,v 1.7 2015/04/15 10:52:18 hsuenaga Exp $ */
+/*     $NetBSD: cpufunc_asm_pj4b.S,v 1.8 2015/05/14 05:39:32 hsuenaga Exp $ */
 
 /*******************************************************************************
 Copyright (C) Marvell International Ltd. and its affiliates
@@ -41,9 +41,10 @@
 #include <arm/asm.h>
 #include <arm/locore.h>
 
-.Lpj4b_cache_line_size:
-       .word   _C_LABEL(arm_dcache_align)
+.Lpj4b_l2_barrier_reg:
+       .word   _C_LABEL(armadaxp_l2_barrier_reg)
 
+/* LINTSTUB: void pj4b_cpu_sleep(int); */
 ENTRY(pj4b_cpu_sleep)
        dsb
        wfi                             @ wait for an interrupt
@@ -51,6 +52,7 @@
        b       irq_idle_entry          @ assume we got an interrupt
 END(pj4b_cpu_sleep)
 
+/* LINTSTUB: void pj4b_config(void); */
 ENTRY(pj4b_config)
        /* Set Auxiliary Debug Modes Control 0 register */
        mrc     p15, 1, r0, c15, c1, 0
@@ -87,3 +89,21 @@
 
        RET
 END(pj4b_config)
+
+/* LINTSTUB: void pj4b_io_coherency_barrier(vaddr_t, paddr_t, vsize_t); */
+ENTRY_NP(pj4b_io_coherency_barrier)
+       ldr     r0, .Lpj4b_l2_barrier_reg
+       ldr     r0, [r0]        @ MVSOC_MLMB_CIB_BARRIER
+       mov     r1, #1          @ MVSOC_MLMB_CIB_BARRIER_TRIGGER
+       str     r1, [r0]
+1:
+       ldr     r1, [r0]
+       tst     r1, #1
+       beq     1b
+       dsb
+       RET
+END(pj4b_io_coherency_barrier)
+
+STRONG_ALIAS(pj4b_dcache_cfu_wbinv_range, pj4b_io_coherency_barrier)
+STRONG_ALIAS(pj4b_dcache_cfu_inv_range, pj4b_io_coherency_barrier)
+STRONG_ALIAS(pj4b_dcache_cfu_wb_range, pj4b_io_coherency_barrier)
diff -r 68668b88b401 -r eda823bba54f sys/arch/arm/include/cpufunc_proto.h
--- a/sys/arch/arm/include/cpufunc_proto.h      Thu May 14 02:43:33 2015 +0000
+++ b/sys/arch/arm/include/cpufunc_proto.h      Thu May 14 05:39:32 2015 +0000
@@ -326,6 +326,10 @@
 void   pj4b_cpu_sleep(int);
 void   pj4bv7_setup(char *string);
 void   pj4b_config(void);
+void   pj4b_io_coherency_barrier(vaddr_t, paddr_t, vsize_t);
+void   pj4b_dcache_cfu_inv_range(vaddr_t, vsize_t);
+void   pj4b_dcache_cfu_wb_range(vaddr_t, vsize_t);
+void   pj4b_dcache_cfu_wbinv_range(vaddr_t, vsize_t);
 #endif /* CPU_PJ4B */
 
 #if defined(CPU_ARM1136) || defined(CPU_ARM1176)
diff -r 68668b88b401 -r eda823bba54f sys/arch/arm/marvell/armadaxp.c
--- a/sys/arch/arm/marvell/armadaxp.c   Thu May 14 02:43:33 2015 +0000
+++ b/sys/arch/arm/marvell/armadaxp.c   Thu May 14 05:39:32 2015 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: armadaxp.c,v 1.12 2015/05/03 06:29:31 hsuenaga Exp $   */
+/*     $NetBSD: armadaxp.c,v 1.13 2015/05/14 05:39:32 hsuenaga Exp $   */
 /*******************************************************************************
 Copyright (C) Marvell International Ltd. and its affiliates
 
@@ -37,7 +37,7 @@
 *******************************************************************************/
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: armadaxp.c,v 1.12 2015/05/03 06:29:31 hsuenaga Exp $");
+__KERNEL_RCSID(0, "$NetBSD: armadaxp.c,v 1.13 2015/05/14 05:39:32 hsuenaga Exp $");
 
 #define _INTR_PRIVATE
 
@@ -89,6 +89,7 @@
 int iocc_state = 0;
 #define read_miscreg(r)                (*(volatile uint32_t *)(misc_base + (r)))
 vaddr_t misc_base;
+vaddr_t armadaxp_l2_barrier_reg;
 
 extern void (*mvsoc_intr_init)(void);
 static void armadaxp_intr_init(void);
@@ -432,11 +433,18 @@
                return (-1);
        }
 
+       /* Variables for cpufunc_asm_pj4b.S */
+       armadaxp_l2_barrier_reg = mlmb_base + MVSOC_MLMB_CIB_BARRIER_TRIGGER;
+
        /* Set L2 policy */
        reg = L2_READ(ARMADAXP_L2_AUX_CTRL);
-       reg &= ~(L2_WBWT_MODE_MASK);
-       reg &= ~(L2_REP_STRAT_MASK);
-       reg |= L2_REP_STRAT_SEMIPLRU;
+       reg &= ~(L2_AUX_WBWT_MODE_MASK);
+       reg &= ~(L2_AUX_REP_STRAT_MASK);
+       reg |= L2_AUX_WBWT_MODE_WB;
+       reg |= L2_AUX_ECC_ENABLE;
+       reg |= L2_AUX_PARITY_ENABLE;
+       reg |= L2_AUX_FORCE_WA;
+       reg |= L2_AUX_REP_STRAT_SEMIPLRU;
        L2_WRITE(ARMADAXP_L2_AUX_CTRL, reg);
 
        /* Invalidate L2 cache */
@@ -460,7 +468,7 @@
 
        /* Enable L2 cache */
        reg = L2_READ(ARMADAXP_L2_CTRL);
-       L2_WRITE(ARMADAXP_L2_CTRL, reg | L2_ENABLE);
+       L2_WRITE(ARMADAXP_L2_CTRL, reg | L2_CTRL_ENABLE);
 
        /* Mark as enabled */
        l2cache_state = 1;
@@ -497,39 +505,88 @@
        __asm__ __volatile__("dsb");
 }
 
+static paddr_t
+armadaxp_sdcache_wbalign_base(vaddr_t va, paddr_t pa, psize_t sz)
+{
+       paddr_t line_start = pa & ~ARMADAXP_L2_ALIGN;
+       vaddr_t save_start;
+       uint8_t save_buf[ARMADAXP_L2_LINE_SIZE];
+       size_t unalign;
+
+       unalign = va & ARMADAXP_L2_ALIGN;
+       if (unalign == 0)
+               return line_start;  /* request is aligned to cache line size */
+
+       /* save data that is not intended to invalidate */
+       save_start = va & ~ARMADAXP_L2_ALIGN;
+       memcpy(save_buf, (void *)save_start, unalign);
+
+       /* invalidate include saved data */
+       L2_WRITE(ARMADAXP_L2_INV_PHYS, line_start);
+
+       /* write back saved data */
+       memcpy((void *)save_start, save_buf, unalign);
+       L2_WRITE(ARMADAXP_L2_WB_PHYS, line_start);
+       L2_WRITE(ARMADAXP_L2_SYNC, 0);
+       __asm__ __volatile__("dsb");
+
+       return line_start;
+}
+
+static paddr_t
+armadaxp_sdcache_wbalign_end(vaddr_t va, paddr_t pa, psize_t sz)
+{
+       paddr_t line_start = (pa + sz - 1) & ~ARMADAXP_L2_ALIGN;
+       vaddr_t save_start = va + sz;
+       uint8_t save_buf[ARMADAXP_L2_LINE_SIZE];
+       size_t save_len;
+       size_t unalign;
+
+       unalign = save_start & ARMADAXP_L2_ALIGN;
+       if (unalign == 0)
+               return line_start; /* request is aligned to cache line size */
+
+       /* save data that is not intended to invalidate */
+       save_len = ARMADAXP_L2_LINE_SIZE - unalign;
+       memcpy(save_buf, (void *)save_start, save_len);
+
+       /* invalidate include saved data */
+       L2_WRITE(ARMADAXP_L2_INV_PHYS, line_start);
+
+       /* write back saved data */
+       memcpy((void *)save_start, save_buf, save_len);
+       L2_WRITE(ARMADAXP_L2_WB_PHYS, line_start);
+       __asm__ __volatile__("dsb");
+
+       return line_start;
+}
+
 void
 armadaxp_sdcache_inv_range(vaddr_t va, paddr_t pa, psize_t sz)
 {
-       paddr_t pa_base = pa;
-       paddr_t pa_end  = pa + sz - 1;
+       paddr_t pa_base;
+       paddr_t pa_end;
 
-       /* need write back if boundary is not aligned */
-       if (pa_base & 0x1f)
-               L2_WRITE(ARMADAXP_L2_WB_PHYS, (pa_base & ~0x1f));
-       if (pa_end & 0x1f)
-               L2_WRITE(ARMADAXP_L2_WB_PHYS, (pa_end & ~0x1f));
-       L2_WRITE(ARMADAXP_L2_SYNC, 0);
-       __asm__ __volatile__("dsb");
+       /* align and write-back the boundary */
+       pa_base = armadaxp_sdcache_wbalign_base(va, pa, sz);
+       pa_end = armadaxp_sdcache_wbalign_end(va, pa, sz);
 
        /* invalidate other cache */
-       pa_base &= ~0x1f;
-       pa_end &= ~0x1f;
-       if (pa_base == pa_end)



Home | Main Index | Thread Index | Old Index