Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 26 Aug 2012 02:23:22 +0000 (UTC)
From:      Oleksandr Tymoshenko <gonzo@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r239701 - in head/sys/arm: arm include
Message-ID:  <201208260223.q7Q2NMv1040538@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: gonzo
Date: Sun Aug 26 02:23:21 2012
New Revision: 239701
URL: http://svn.freebsd.org/changeset/base/239701

Log:
  Add support for ARM11 cpufunc
  
  Obtained from:	NetBSD (partially)

Added:
  head/sys/arm/arm/cpufunc_asm_armv6.S   (contents, props changed)
Modified:
  head/sys/arm/arm/cpufunc.c
  head/sys/arm/include/cpufunc.h

Modified: head/sys/arm/arm/cpufunc.c
==============================================================================
--- head/sys/arm/arm/cpufunc.c	Sun Aug 26 01:41:41 2012	(r239700)
+++ head/sys/arm/arm/cpufunc.c	Sun Aug 26 02:23:21 2012	(r239701)
@@ -968,6 +968,68 @@ struct cpu_functions fa526_cpufuncs = {
 };
 #endif	/* CPU_FA526 || CPU_FA626TE */
 
+#if defined(CPU_ARM11)
+struct cpu_functions arm11_cpufuncs = {
+	/* CPU functions */
+	
+	cpufunc_id,                     /* id                   */
+	arm11_drain_writebuf,           /* cpwait               */
+	
+	/* MMU functions */
+	
+	cpufunc_control,                /* control              */
+	cpufunc_domains,                /* Domain               */
+	arm11_setttb,                   /* Setttb               */
+	cpufunc_faultstatus,            /* Faultstatus          */
+	cpufunc_faultaddress,           /* Faultaddress         */
+	
+	/* TLB functions */
+	
+	arm11_tlb_flushID,              /* tlb_flushID          */
+	arm11_tlb_flushID_SE,           /* tlb_flushID_SE       */
+	arm11_tlb_flushI,               /* tlb_flushI           */
+	arm11_tlb_flushI_SE,            /* tlb_flushI_SE        */
+	arm11_tlb_flushD,               /* tlb_flushD           */
+	arm11_tlb_flushD_SE,            /* tlb_flushD_SE        */
+	
+	/* Cache operations */
+	
+	armv6_icache_sync_all,          /* icache_sync_all      */
+	armv6_icache_sync_range,        /* icache_sync_range    */
+	
+	armv6_dcache_wbinv_all,         /* dcache_wbinv_all     */
+	armv6_dcache_wbinv_range,       /* dcache_wbinv_range   */
+	armv6_dcache_inv_range,         /* dcache_inv_range     */
+	armv6_dcache_wb_range,          /* dcache_wb_range      */
+	
+	armv6_idcache_wbinv_all,        /* idcache_wbinv_all    */
+	armv6_idcache_wbinv_range,      /* idcache_wbinv_range  */
+	
+	(void*)cpufunc_nullop,          /* l2cache_wbinv_all    */
+	(void *)cpufunc_nullop,         /* l2cache_wbinv_range  */
+	(void *)cpufunc_nullop,         /* l2cache_inv_range    */
+	(void *)cpufunc_nullop,         /* l2cache_wb_range     */
+	
+	/* Other functions */
+	
+	cpufunc_nullop,                 /* flush_prefetchbuf    */
+	arm11_drain_writebuf,           /* drain_writebuf       */
+	cpufunc_nullop,                 /* flush_brnchtgt_C     */
+	(void *)cpufunc_nullop,         /* flush_brnchtgt_E     */
+	
+	arm11_sleep,                    /* sleep                */
+	
+	/* Soft functions */
+	
+	cpufunc_null_fixup,             /* dataabt_fixup        */
+	cpufunc_null_fixup,             /* prefetchabt_fixup    */
+	
+	arm11_context_switch,           /* context_switch       */
+	
+	arm11_setup                     /* cpu setup            */
+};
+#endif /* CPU_ARM11 */
+
 #if defined(CPU_CORTEXA)
 struct cpu_functions cortexa_cpufuncs = {
 	/* CPU functions */
@@ -1324,6 +1386,15 @@ set_cpufuncs()
 		goto out;
 	}
 #endif /* CPU_ARM10 */
+#ifdef CPU_ARM11
+	cpufuncs = arm11_cpufuncs;
+	cpu_reset_needs_v4_MMU_disable = 1;     /* V4 or higher */
+	get_cachetype_cp15();
+	
+	pmap_pte_init_mmu_v6();
+
+	goto out;
+#endif /* CPU_ARM11 */
 #ifdef CPU_CORTEXA
 	if (cputype == CPU_ID_CORTEXA8R1 ||
 	    cputype == CPU_ID_CORTEXA8R2 ||
@@ -2197,38 +2268,36 @@ void
 arm11_setup(args)
 	char *args;
 {
-	int cpuctrl, cpuctrlmask;
-
-	cpuctrl = CPU_CONTROL_MMU_ENABLE | CPU_CONTROL_SYST_ENABLE
-	    | CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE
-	    /* | CPU_CONTROL_BPRD_ENABLE */;
-	cpuctrlmask = CPU_CONTROL_MMU_ENABLE | CPU_CONTROL_SYST_ENABLE
-	    | CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE
-	    | CPU_CONTROL_ROM_ENABLE | CPU_CONTROL_BPRD_ENABLE
-	    | CPU_CONTROL_BEND_ENABLE | CPU_CONTROL_AFLT_ENABLE
-	    | CPU_CONTROL_ROUNDROBIN | CPU_CONTROL_CPCLK;
+	int cpuctrl;
 
+	cpuctrl = CPU_CONTROL_MMU_ENABLE;
 #ifndef ARM32_DISABLE_ALIGNMENT_FAULTS
 	cpuctrl |= CPU_CONTROL_AFLT_ENABLE;
 #endif
-
+	cpuctrl |= CPU_CONTROL_DC_ENABLE;
+	cpuctrl |= (0xf << 3);
 	cpuctrl = parse_cpu_options(args, arm11_options, cpuctrl);
-
 #ifdef __ARMEB__
 	cpuctrl |= CPU_CONTROL_BEND_ENABLE;
 #endif
+	cpuctrl |= CPU_CONTROL_SYST_ENABLE;
+	cpuctrl |= CPU_CONTROL_BPRD_ENABLE;
+	cpuctrl |= CPU_CONTROL_IC_ENABLE;
+	if (vector_page == ARM_VECTORS_HIGH)
+		cpuctrl |= CPU_CONTROL_VECRELOC;
+	cpuctrl |= (0x5 << 16);
+	cpuctrl |= CPU_CONTROL_V6_EXTPAGE;
 
-	/* Clear out the cache */
+	/* Make sure caches are clean.  */
 	cpu_idcache_wbinv_all();
-
-	/* Now really make sure they are clean.  */
-	__asm __volatile ("mcr\tp15, 0, r0, c7, c7, 0" : : );
+	cpu_l2cache_wbinv_all();
 
 	/* Set the control register */
+	ctrl = cpuctrl;
 	cpu_control(0xffffffff, cpuctrl);
 
-	/* And again. */
 	cpu_idcache_wbinv_all();
+	cpu_l2cache_wbinv_all();
 }
 #endif	/* CPU_ARM11 */
 

Added: head/sys/arm/arm/cpufunc_asm_armv6.S
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/sys/arm/arm/cpufunc_asm_armv6.S	Sun Aug 26 02:23:21 2012	(r239701)
@@ -0,0 +1,140 @@
+/*	$NetBSD: cpufunc_asm_armv6.S,v 1.4 2010/12/10 02:06:22 bsh Exp $	*/
+
+/*
+ * Copyright (c) 2002, 2005 ARM Limited
+ * Portions Copyright (c) 2007 Microsoft
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. The name of the company may not be used to endorse or promote
+ *    products derived from this software without specific prior written
+ *    permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * ARMv6 assembly functions for manipulating caches.
+ * These routines can be used by any core that supports the mcrr address
+ * range operations.
+ */
+
+/*
+ * $FreeBSD$
+ */
+ 
+#include <machine/asm.h>
+
+	.arch	armv6
+
+/*
+ * Functions to set the MMU Translation Table Base register
+ *
+ * We need to clean and flush the cache as it uses virtual
+ * addresses that are about to change.
+ */
+ENTRY(armv6_setttb)
+#ifdef PMAP_CACHE_VIVT
+	mcr	p15, 0, r0, c7, c5, 0	/* Flush I cache */
+	mcr	p15, 0, r0, c7, c14, 0	/* clean and invalidate D cache */
+#endif
+	mcr	p15, 0, r0, c7, c10, 4	/* drain the write buffer */
+
+	mcr	p15, 0, r0, c2, c0, 0	/* load new TTB */
+
+	mcr	p15, 0, r0, c8, c7, 0	/* invalidate I+D TLBs */
+	RET
+
+/*
+ * Cache operations.
+ */
+
+/* LINTSTUB: void armv6_icache_sync_range(vaddr_t, vsize_t); */
+ENTRY_NP(armv6_icache_sync_range)
+	add	r1, r1, r0
+	sub	r1, r1, #1
+	mcrr	p15, 0, r1, r0, c5	/* invalidate I cache range */
+	mcrr	p15, 0, r1, r0, c12	/* clean D cache range */
+	mcr	p15, 0, r0, c7, c10, 4	/* drain the write buffer */
+	RET
+
+/* LINTSTUB: void armv6_icache_sync_all(void); */
+ENTRY_NP(armv6_icache_sync_all)
+	/*
+	 * We assume that the code here can never be out of sync with the
+	 * dcache, so that we can safely flush the Icache and fall through
+	 * into the Dcache cleaning code.
+	 */
+	mcr	p15, 0, r0, c7, c5, 0	/* Flush I cache */
+	mcr	p15, 0, r0, c7, c10, 0	/* Clean D cache */
+	mcr	p15, 0, r0, c7, c10, 4	/* drain the write buffer */
+	RET
+
+/* LINTSTUB: void armv6_dcache_wb_range(vaddr_t, vsize_t); */
+ENTRY(armv6_dcache_wb_range)
+	add	r1, r1, r0
+	sub	r1, r1, #1
+	mcrr	p15, 0, r1, r0, c12	/* clean D cache range */
+	mcr	p15, 0, r0, c7, c10, 4	/* drain the write buffer */
+	RET
+	
+/* LINTSTUB: void armv6_dcache_wbinv_range(vaddr_t, vsize_t); */
+ENTRY(armv6_dcache_wbinv_range)
+	add	r1, r1, r0
+	sub	r1, r1, #1
+	mcrr	p15, 0, r1, r0, c14	/* clean and invaliate D cache range */
+	mcr	p15, 0, r0, c7, c10, 4	/* drain the write buffer */
+	RET
+	
+/*
+ * Note, we must not invalidate everything.  If the range is too big we
+ * must use wb-inv of the entire cache.
+ *
+ * LINTSTUB: void armv6_dcache_inv_range(vaddr_t, vsize_t);
+ */
+ENTRY(armv6_dcache_inv_range)
+	add	r1, r1, r0
+	sub	r1, r1, #1
+	mcrr	p15, 0, r1, r0, c6	/* invaliate D cache range */
+	mcr	p15, 0, r0, c7, c10, 4	/* drain the write buffer */
+	RET
+
+/* LINTSTUB: void armv6_idcache_wbinv_range(vaddr_t, vsize_t); */
+ENTRY(armv6_idcache_wbinv_range)
+	add	r1, r1, r0
+	sub	r1, r1, #1
+	mcrr	p15, 0, r1, r0, c5	/* invaliate I cache range */
+	mcrr	p15, 0, r1, r0, c14	/* clean & invaliate D cache range */
+	mcr	p15, 0, r0, c7, c10, 4	/* drain the write buffer */
+	RET
+
+/* LINTSTUB: void armv6_idcache_wbinv_all(void); */
+ENTRY_NP(armv6_idcache_wbinv_all)
+	/*
+	 * We assume that the code here can never be out of sync with the
+	 * dcache, so that we can safely flush the Icache and fall through
+	 * into the Dcache purging code.
+	 */
+	mcr	p15, 0, r0, c7, c5, 0	/* Flush I cache */
+	/* Fall through to purge Dcache. */
+
+/* LINTSTUB: void armv6_dcache_wbinv_all(void); */
+ENTRY(armv6_dcache_wbinv_all)
+	mcr	p15, 0, r0, c7, c14, 0	/* clean & invalidate D cache */
+	mcr	p15, 0, r0, c7, c10, 4	/* drain the write buffer */
+	RET

Modified: head/sys/arm/include/cpufunc.h
==============================================================================
--- head/sys/arm/include/cpufunc.h	Sun Aug 26 01:41:41 2012	(r239700)
+++ head/sys/arm/include/cpufunc.h	Sun Aug 26 02:23:21 2012	(r239701)
@@ -495,8 +495,15 @@ void	pj4b_flush_brnchtgt_va		(u_int);
 void	pj4b_sleep			(int);
 
 void	armv6_icache_sync_all		(void);
+void	armv6_icache_sync_range		(vm_offset_t, vm_size_t);
+
 void	armv6_dcache_wbinv_all		(void);
+void	armv6_dcache_wbinv_range	(vm_offset_t, vm_size_t);
+void	armv6_dcache_inv_range		(vm_offset_t, vm_size_t);
+void	armv6_dcache_wb_range		(vm_offset_t, vm_size_t);
+
 void	armv6_idcache_wbinv_all		(void);
+void	armv6_idcache_wbinv_range	(vm_offset_t, vm_size_t);
 
 void	armv7_setttb			(u_int);
 void	armv7_tlb_flushID		(void);



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201208260223.q7Q2NMv1040538>