Module Name:    src
Committed By:   skrll
Date:           Sat Jul 21 12:19:15 UTC 2012

Modified Files:
        src/sys/arch/arm/arm: cpufunc.c cpufunc_asm_arm1136.S
        src/sys/arch/arm/conf: files.arm
        src/sys/arch/arm/include: cpufunc.h
Added Files:
        src/sys/arch/arm/arm: cpufunc_asm_arm11x6.S

Log Message:
Add support for the ARM1176JZS


To generate a diff of this commit:
cvs rdiff -u -r1.107 -r1.108 src/sys/arch/arm/arm/cpufunc.c
cvs rdiff -u -r1.2 -r1.3 src/sys/arch/arm/arm/cpufunc_asm_arm1136.S
cvs rdiff -u -r0 -r1.1 src/sys/arch/arm/arm/cpufunc_asm_arm11x6.S
cvs rdiff -u -r1.105 -r1.106 src/sys/arch/arm/conf/files.arm
cvs rdiff -u -r1.56 -r1.57 src/sys/arch/arm/include/cpufunc.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.107 src/sys/arch/arm/arm/cpufunc.c:1.108
--- src/sys/arch/arm/arm/cpufunc.c:1.107	Sat Jul 14 12:59:55 2012
+++ src/sys/arch/arm/arm/cpufunc.c	Sat Jul 21 12:19:15 2012
@@ -1,4 +1,4 @@
-/*	$NetBSD: cpufunc.c,v 1.107 2012/07/14 12:59:55 hans Exp $	*/
+/*	$NetBSD: cpufunc.c,v 1.108 2012/07/21 12:19:15 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.107 2012/07/14 12:59:55 hans Exp $");
+__KERNEL_RCSID(0, "$NetBSD: cpufunc.c,v 1.108 2012/07/21 12:19:15 skrll Exp $");
 
 #include "opt_compat_netbsd.h"
 #include "opt_cpuoptions.h"
@@ -747,7 +747,7 @@ struct cpu_functions arm1136_cpufuncs = 
 
 	.cf_control		= cpufunc_control,
 	.cf_domains		= cpufunc_domains,
-	.cf_setttb		= arm1136_setttb,
+	.cf_setttb		= arm11x6_setttb,
 	.cf_faultstatus		= cpufunc_faultstatus,
 	.cf_faultaddress	= cpufunc_faultaddress,
 
@@ -762,25 +762,25 @@ struct cpu_functions arm1136_cpufuncs = 
 
 	/* Cache operations */
 
-	.cf_icache_sync_all	= arm1136_icache_sync_all,	/* 411920 */
-	.cf_icache_sync_range	= arm1136_icache_sync_range,	/* 371025 */
+	.cf_icache_sync_all	= arm11x6_icache_sync_all,	/* 411920 */
+	.cf_icache_sync_range	= arm11x6_icache_sync_range,	/* 371025 */
 
-	.cf_dcache_wbinv_all	= arm1136_dcache_wbinv_all,	/* 411920 */
+	.cf_dcache_wbinv_all	= arm11x6_dcache_wbinv_all,	/* 411920 */
 	.cf_dcache_wbinv_range	= armv6_dcache_wbinv_range,
 	.cf_dcache_inv_range	= armv6_dcache_inv_range,
 	.cf_dcache_wb_range	= armv6_dcache_wb_range,
 
-	.cf_idcache_wbinv_all	= arm1136_idcache_wbinv_all,	/* 411920 */
-	.cf_idcache_wbinv_range = arm1136_idcache_wbinv_range,	/* 371025 */
+	.cf_idcache_wbinv_all	= arm11x6_idcache_wbinv_all,	/* 411920 */
+	.cf_idcache_wbinv_range = arm11x6_idcache_wbinv_range,	/* 371025 */
 
 	/* Other functions */
 
-	.cf_flush_prefetchbuf	= arm1136_flush_prefetchbuf,
+	.cf_flush_prefetchbuf	= arm11x6_flush_prefetchbuf,
 	.cf_drain_writebuf	= arm11_drain_writebuf,
 	.cf_flush_brnchtgt_C	= cpufunc_nullop,
 	.cf_flush_brnchtgt_E	= (void *)cpufunc_nullop,
 
-	.cf_sleep		= arm11_sleep,
+	.cf_sleep		= arm11_sleep,	/* arm1136_sleep_rev0 */
 
 	/* Soft functions */
 
@@ -789,11 +789,70 @@ struct cpu_functions arm1136_cpufuncs = 
 
 	.cf_context_switch	= arm11_context_switch,
 
-	.cf_setup		= arm1136_setup
+	.cf_setup		= arm11x6_setup
 
 };
 #endif /* CPU_ARM1136 */
 
+#ifdef CPU_ARM1176
+struct cpu_functions arm1176_cpufuncs = {
+	/* CPU functions */
+
+	.cf_id			= cpufunc_id,
+	.cf_cpwait		= cpufunc_nullop,
+
+	/* MMU functions */
+
+	.cf_control		= cpufunc_control,
+	.cf_domains		= cpufunc_domains,
+	.cf_setttb		= arm11x6_setttb,
+	.cf_faultstatus		= cpufunc_faultstatus,
+	.cf_faultaddress	= cpufunc_faultaddress,
+
+	/* TLB functions */
+
+	.cf_tlb_flushID		= arm11_tlb_flushID,
+	.cf_tlb_flushID_SE	= arm11_tlb_flushID_SE,
+	.cf_tlb_flushI		= arm11_tlb_flushI,
+	.cf_tlb_flushI_SE	= arm11_tlb_flushI_SE,
+	.cf_tlb_flushD		= arm11_tlb_flushD,
+	.cf_tlb_flushD_SE	= arm11_tlb_flushD_SE,
+
+	/* Cache operations */
+
+	.cf_icache_sync_all	= arm11x6_icache_sync_all,	/* 415045 */
+	.cf_icache_sync_range	= arm11x6_icache_sync_range,	/* 371367 */
+
+	.cf_dcache_wbinv_all	= arm11x6_dcache_wbinv_all,	/* 415045 */
+	.cf_dcache_wbinv_range	= armv6_dcache_wbinv_range,
+	.cf_dcache_inv_range	= armv6_dcache_inv_range,
+	.cf_dcache_wb_range	= armv6_dcache_wb_range,
+
+	.cf_idcache_wbinv_all	= arm11x6_idcache_wbinv_all,	/* 415045 */
+	.cf_idcache_wbinv_range = arm11x6_idcache_wbinv_range,	/* 371367 */
+
+	/* Other functions */
+
+	.cf_flush_prefetchbuf	= arm11x6_flush_prefetchbuf,
+	.cf_drain_writebuf	= arm11_drain_writebuf,
+	.cf_flush_brnchtgt_C	= cpufunc_nullop,
+	.cf_flush_brnchtgt_E	= (void *)cpufunc_nullop,
+
+	.cf_sleep		= arm11x6_sleep,		/* no ref. */
+
+	/* Soft functions */
+
+	.cf_dataabt_fixup	= cpufunc_null_fixup,
+	.cf_prefetchabt_fixup	= cpufunc_null_fixup,
+
+	.cf_context_switch	= arm11_context_switch,
+
+	.cf_setup		= arm11x6_setup
+
+};
+#endif /* CPU_ARM1176 */
+
+
 #ifdef CPU_ARM11MPCORE
 struct cpu_functions arm11mpcore_cpufuncs = {
 	/* CPU functions */
@@ -1650,12 +1709,18 @@ set_cpufuncs(void)
 	    cputype == CPU_ID_ARM1176JZS) {
 		cpufuncs = arm11_cpufuncs;
 #if defined(CPU_ARM1136)
-		if (cputype != CPU_ID_ARM1176JZS) {
+		if (cputype == CPU_ID_ARM1136JS &&
+		    cputype == CPU_ID_ARM1136JSR1) {
 			cpufuncs = arm1136_cpufuncs;
 			if (cputype == CPU_ID_ARM1136JS)
 				cpufuncs.cf_sleep = arm1136_sleep_rev0;
 		}
 #endif
+#if defined(CPU_ARM1176)
+		if (cputype == CPU_ID_ARM1176JZS) {
+			cpufuncs = arm1176_cpufuncs;
+		}
+#endif
 		cpu_reset_needs_v4_MMU_disable = 1;	/* V4 or higher */
 		cpu_do_powersave = 1;			/* Enable powersave */
 		get_cachetype_cp15();
@@ -2249,7 +2314,7 @@ late_abort_fixup(void *arg)
 	defined(CPU_SA110) || defined(CPU_SA1100) || defined(CPU_SA1110) || \
 	defined(CPU_XSCALE_80200) || defined(CPU_XSCALE_80321) || \
 	defined(__CPU_XSCALE_PXA2XX) || defined(CPU_XSCALE_IXP425) || \
-	defined(CPU_ARM10) || defined(CPU_ARM11) || defined(CPU_ARM1136) || \
+	defined(CPU_ARM10) || defined(CPU_ARM11) || \
 	defined(CPU_FA526) || defined(CPU_CORTEX) || defined(CPU_SHEEVA)
 
 #define IGN	0
@@ -2860,10 +2925,9 @@ armv7_dcache_wbinv_all(void)
 #endif /* CPU_CORTEX */
 
 
-
-#if defined(CPU_ARM1136)
+#if defined(CPU_ARM1136) || defined(CPU_ARM1176) 
 void
-arm1136_setup(char *args)
+arm11x6_setup(char *args)
 {
 	int cpuctrl, cpuctrl_wax;
 	uint32_t auxctrl, auxctrl_wax;
@@ -2918,7 +2982,8 @@ arm1136_setup(char *args)
 
 	auxctrl = 0;
 	auxctrl_wax = ~0;
-	/* This options enables the workaround for the 364296 ARM1136
+	/*
+	 * This options enables the workaround for the 364296 ARM1136
 	 * r0pX errata (possible cache data corruption with
 	 * hit-under-miss enabled). It sets the undocumented bit 31 in
 	 * the auxiliary control register and the FI bit in the control
@@ -2932,6 +2997,14 @@ arm1136_setup(char *args)
 		auxctrl_wax = ~ARM11R0_AUXCTL_PFI;
 	}
 
+	/*
+	 * Enable an errata workaround
+	 */
+	if ((cpuid & CPU_ID_CPU_MASK) == CPU_ID_ARM1176JZS) { /* ARM1176JZSr0 */
+		auxctrl = ARM1176_AUXCTL_PHD;
+		auxctrl_wax = ~ARM1176_AUXCTL_PHD;
+	}
+
 	/* Clear out the cache */
 	cpu_idcache_wbinv_all();
 
@@ -2946,17 +3019,17 @@ arm1136_setup(char *args)
 	cpu_control(~cpuctrl_wax, cpuctrl);
 
 	__asm volatile ("mrc	p15, 0, %0, c1, c0, 1\n\t"
-			"bic	%1, %0, %2\n\t"
-			"eor	%1, %0, %3\n\t"
+			"and	%1, %0, %2\n\t"
+			"orr	%1, %1, %3\n\t"
 			"teq	%0, %1\n\t"
 			"mcrne	p15, 0, %1, c1, c0, 1\n\t"
 			: "=r"(tmp), "=r"(tmp2) :
-			  "r"(~auxctrl_wax), "r"(auxctrl));
+			  "r"(auxctrl_wax), "r"(auxctrl));
 
 	/* And again. */
 	cpu_idcache_wbinv_all();
 }
-#endif	/* CPU_ARM1136 */
+#endif	/* CPU_ARM1136 || CPU_ARM1176 */
 
 #ifdef CPU_SA110
 struct cpu_option sa110_options[] = {

Index: src/sys/arch/arm/arm/cpufunc_asm_arm1136.S
diff -u src/sys/arch/arm/arm/cpufunc_asm_arm1136.S:1.2 src/sys/arch/arm/arm/cpufunc_asm_arm1136.S:1.3
--- src/sys/arch/arm/arm/cpufunc_asm_arm1136.S:1.2	Sun Apr 27 18:58:43 2008
+++ src/sys/arch/arm/arm/cpufunc_asm_arm1136.S	Sat Jul 21 12:19:15 2012
@@ -1,4 +1,4 @@
-/* $NetBSD: cpufunc_asm_arm1136.S,v 1.2 2008/04/27 18:58:43 matt Exp $ */
+/* $NetBSD: cpufunc_asm_arm1136.S,v 1.3 2012/07/21 12:19:15 skrll Exp $ */
 
 /*
  * Copyright (c) 2007 Microsoft
@@ -33,131 +33,7 @@
 #include <machine/cpu.h>
 #include <machine/asm.h>
 
-RCSID("$NetBSD: cpufunc_asm_arm1136.S,v 1.2 2008/04/27 18:58:43 matt Exp $")
-
-#if 0
-#define Invalidate_I_cache(Rtmp1, Rtmp2) \
-	mcr	p15, 0, Rtmp1, c7, c5, 0	/* Invalidate Entire I cache */
-#else
-/*
- * Workaround Erratum 411920 
- * 
- *	- value of arg 'reg' Should Be Zero
- */
-#define Invalidate_I_cache(Rtmp1, Rtmp2) \
-	mov	Rtmp1, #0;		/* SBZ */			\
-	mrs	Rtmp2, cpsr;						\
-	cpsid	ifa;							\
-	mcr	p15, 0, Rtmp1, c7, c5, 0;	/* Nuke Whole Icache */	\
-	mcr	p15, 0, Rtmp1, c7, c5, 0;	/* Nuke Whole Icache */	\
-	mcr	p15, 0, Rtmp1, c7, c5, 0;	/* Nuke Whole Icache */	\
-	mcr	p15, 0, Rtmp1, c7, c5, 0;	/* Nuke Whole Icache */	\
-	msr	cpsr_cx, Rtmp2;						\
-	nop;								\
-	nop;								\
-	nop;								\
-	nop;								\
-	nop;								\
-	nop;								\
-	nop;								\
-	nop;								\
-	nop;								\
-	nop;								\
-	nop;
-#endif
-
-#if 1
-#define Flush_D_cache(reg) \
-	mov	reg, #0;		/* SBZ */					\
-	mcr	p15, 0, reg, c7, c14, 0;/* Clean and Invalidate Entire Data Cache */	\
-	mcr	p15, 0, reg, c7, c10, 4;/* Data Synchronization Barrier */
-#else
-#define Flush_D_cache(reg) \
-1:	mov	reg, #0;		/* SBZ */					\
-	mcr	p15, 0, reg, c7, c14, 0;/* Clean and Invalidate Entire Data Cache */	\
-	mrc	p15, 0, reg, C7, C10, 6;/* Read Cache Dirty Status Register */		\
-	ands	reg, reg, #01;		/* Check if it is clean */			\
-	bne	1b;			/* loop if not */				\
-	mcr	p15, 0, reg, c7, c10, 4;/* Data Synchronization Barrier */
-#endif
-
-ENTRY(arm1136_setttb)
-#ifdef PMAP_CACHE_VIVT
-	Flush_D_cache(r1)
-	Invalidate_I_cache(r1, r2)
-#endif
-	mcr	p15, 0, r0, c2, c0, 0	/* load new TTB */
-	mcr	p15, 0, r1, c8, c7, 0	/* invalidate I+D TLBs */
-	mcr	p15, 0, r1, c7, c10, 4	/* drain write buffer */
-	RET
-
-ENTRY_NP(arm1136_idcache_wbinv_all)
-	Flush_D_cache(r0)
-	Invalidate_I_cache(r0, r1)
-	RET
-
-ENTRY_NP(arm1136_dcache_wbinv_all)
-	Flush_D_cache(r0)
-	RET
-
-ENTRY_NP(arm1136_icache_sync_all)
-	Flush_D_cache(r0)
-	Invalidate_I_cache(r0, r1)
-	RET
-
-ENTRY_NP(arm1136_flush_prefetchbuf)
-	mcr	p15, 0, r0, c7, c5, 4	/* Flush Prefetch Buffer */
-	RET
-
-ENTRY_NP(arm1136_icache_sync_range)
-	add	r1, r1, r0
-	sub	r1, r1, #1
-	/* Erratum 371025, workaround #2 */
-	mrs	r2, cpsr		/* save the CPSR */
-	cpsid	ifa			/* disable interrupts (irq,fiq,abort) */
-	mov	r3, #0 
-	mcr	p15, 0, r3, c13, c0, 0	/* write FCSE (uTLB invalidate) */
-	mcr	p15, 0, r3, c7, c5, 4	/* flush prefetch buffer */
-	add	r3, pc, #0x24 
-	mcr	p15, 0, r3, c7, c13, 1	/* prefetch I-cache line */
-	mcrr	p15, 0, r1, r0, c5	/* invalidate I-cache range */
-	msr	cpsr_cx, r2		/* local_irq_restore */
-	nop 
-	nop 
-	nop 
-	nop 
-	nop 
-	nop 
-	nop 
-
-	mcrr	p15, 0, r1, r0, c12	/* clean and invalidate D cache range */
-	mcr	p15, 0, r0, c7, c10, 4	/* drain the write buffer */
-	RET
-
-ENTRY_NP(arm1136_idcache_wbinv_range)
-	add	r1, r1, r0
-	sub	r1, r1, #1
-	/* Erratum 371025, workaround #2 */
-	mrs	r2, cpsr		/* save the CPSR */
-	cpsid	ifa			/* disable interrupts (irq,fiq,abort) */
-	mov	r3, #0 
-	mcr	p15, 0, r3, c13, c0, 0	/* write FCSE (uTLB invalidate) */
-	mcr	p15, 0, r3, c7, c5, 4	/* flush prefetch buffer */
-	add	r3, pc, #0x24 
-	mcr	p15, 0, r3, c7, c13, 1	/* prefetch I-cache line */
-	mcrr	p15, 0, r1, r0, c5	/* invalidate I-cache range */
-	msr	cpsr_cx, r2		/* local_irq_restore */
-	nop 
-	nop 
-	nop 
-	nop 
-	nop 
-	nop 
-	nop 
-
-	mcrr	p15, 0, r1, r0, c14	/* clean and invalidate D cache range */
-	mcr	p15, 0, r0, c7, c10, 4	/* drain the write buffer */
-	RET
+RCSID("$NetBSD: cpufunc_asm_arm1136.S,v 1.3 2012/07/21 12:19:15 skrll Exp $")
 
 ENTRY_NP(arm1136_sleep_rev0)		/* errata 336501 */
 	mov	r0, #0

Index: src/sys/arch/arm/conf/files.arm
diff -u src/sys/arch/arm/conf/files.arm:1.105 src/sys/arch/arm/conf/files.arm:1.106
--- src/sys/arch/arm/conf/files.arm:1.105	Sat Jul 14 07:57:26 2012
+++ src/sys/arch/arm/conf/files.arm	Sat Jul 21 12:19:15 2012
@@ -1,4 +1,4 @@
-#	$NetBSD: files.arm,v 1.105 2012/07/14 07:57:26 matt Exp $
+#	$NetBSD: files.arm,v 1.106 2012/07/21 12:19:15 skrll Exp $
 
 # temporary define to allow easy moving to ../arch/arm/arm32
 defflag				ARM32
@@ -117,6 +117,7 @@ file	arch/arm/arm/cpufunc_asm_arm10.S	cp
 							cpu_sheeva
 file	arch/arm/arm/cpufunc_asm_arm11.S	cpu_arm11 | cpu_cortex
 file	arch/arm/arm/cpufunc_asm_arm1136.S	cpu_arm1136
+file	arch/arm/arm/cpufunc_asm_arm11x6.S	cpu_arm1136 | cpu_arm1176
 file	arch/arm/arm/cpufunc_asm_armv4.S	cpu_arm9 | cpu_arm9e |
 							cpu_arm10 |
 							cpu_fa526 |

Index: src/sys/arch/arm/include/cpufunc.h
diff -u src/sys/arch/arm/include/cpufunc.h:1.56 src/sys/arch/arm/include/cpufunc.h:1.57
--- src/sys/arch/arm/include/cpufunc.h:1.56	Sat Jul 14 12:59:55 2012
+++ src/sys/arch/arm/include/cpufunc.h	Sat Jul 21 12:19:15 2012
@@ -470,15 +470,18 @@ void	armv7_setup		(char *string);
 #endif
 
 
+#if defined(CPU_ARM1136) || defined(CPU_ARM1176)
+void	arm11x6_setttb			(u_int);
+void	arm11x6_idcache_wbinv_all	(void);
+void	arm11x6_dcache_wbinv_all	(void);
+void	arm11x6_icache_sync_all		(void);
+void	arm11x6_flush_prefetchbuf	(void);
+void	arm11x6_icache_sync_range	(vaddr_t, vsize_t);
+void	arm11x6_idcache_wbinv_range	(vaddr_t, vsize_t);
+void	arm11x6_setup			(char *string);
+void	arm11x6_sleep			(int);	/* no ref. for errata */
+#endif
 #if defined(CPU_ARM1136)
-void	arm1136_setttb			(u_int);
-void	arm1136_idcache_wbinv_all	(void);
-void	arm1136_dcache_wbinv_all	(void);
-void	arm1136_icache_sync_all		(void);
-void	arm1136_flush_prefetchbuf	(void);
-void	arm1136_icache_sync_range	(vaddr_t, vsize_t);
-void	arm1136_idcache_wbinv_range	(vaddr_t, vsize_t);
-void	arm1136_setup			(char *string);
 void	arm1136_sleep_rev0		(int);	/* for errata 336501 */
 #endif
 

Added files:

Index: src/sys/arch/arm/arm/cpufunc_asm_arm11x6.S
diff -u /dev/null src/sys/arch/arm/arm/cpufunc_asm_arm11x6.S:1.1
--- /dev/null	Sat Jul 21 12:19:15 2012
+++ src/sys/arch/arm/arm/cpufunc_asm_arm11x6.S	Sat Jul 21 12:19:15 2012
@@ -0,0 +1,219 @@
+/*	$NetBSD: cpufunc_asm_arm11x6.S,v 1.1 2012/07/21 12:19:15 skrll Exp $	*/
+
+/*
+ * 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. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by Microsoft
+ *
+ * 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 CONTRIBUTERS 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.
+ */
+
+/*-
+ * Copyright (c) 2012 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Eben Upton
+ *
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``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 FOUNDATION 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.
+ */
+
+
+#include "assym.h"
+#include <machine/cpu.h>
+#include <machine/asm.h>
+
+RCSID("$NetBSD: cpufunc_asm_arm11x6.S,v 1.1 2012/07/21 12:19:15 skrll Exp $")
+
+#if 0
+#define Invalidate_I_cache(Rtmp1, Rtmp2) \
+	mcr	p15, 0, Rtmp1, c7, c5, 0	/* Invalidate Entire I cache */
+#else
+/*
+ * Workaround for
+ *
+ *    Erratum 411920 in ARM1136 (fixed in r1p4)
+ *    Erratum 415045 in ARM1176 (fixed in r0p5?)
+ * 
+ *	- value of arg 'reg' Should Be Zero
+ */
+#define Invalidate_I_cache(Rtmp1, Rtmp2) \
+	mov	Rtmp1, #0;		/* SBZ */			\
+	mrs	Rtmp2, cpsr;						\
+	cpsid	ifa;							\
+	mcr	p15, 0, Rtmp1, c7, c5, 0;	/* Nuke Whole Icache */	\
+	mcr	p15, 0, Rtmp1, c7, c5, 0;	/* Nuke Whole Icache */	\
+	mcr	p15, 0, Rtmp1, c7, c5, 0;	/* Nuke Whole Icache */	\
+	mcr	p15, 0, Rtmp1, c7, c5, 0;	/* Nuke Whole Icache */	\
+	msr	cpsr_cx, Rtmp2;						\
+	nop;								\
+	nop;								\
+	nop;								\
+	nop;								\
+	nop;								\
+	nop;								\
+	nop;								\
+	nop;								\
+	nop;								\
+	nop;								\
+	nop;
+#endif
+
+#if 1
+#define Flush_D_cache(reg) \
+	mov	reg, #0;		/* SBZ */					\
+	mcr	p15, 0, reg, c7, c14, 0;/* Clean and Invalidate Entire Data Cache */	\
+	mcr	p15, 0, reg, c7, c10, 4;/* Data Synchronization Barrier */
+#else
+#define Flush_D_cache(reg) \
+1:	mov	reg, #0;		/* SBZ */					\
+	mcr	p15, 0, reg, c7, c14, 0;/* Clean and Invalidate Entire Data Cache */	\
+	mrc	p15, 0, reg, C7, C10, 6;/* Read Cache Dirty Status Register */		\
+	ands	reg, reg, #01;		/* Check if it is clean */			\
+	bne	1b;			/* loop if not */				\
+	mcr	p15, 0, reg, c7, c10, 4;/* Data Synchronization Barrier */
+#endif
+
+ENTRY(arm11x6_setttb)
+#ifdef PMAP_CACHE_VIVT
+	Flush_D_cache(r1)
+	Invalidate_I_cache(r1, r2)
+#else
+	mov	r1, #0
+#endif
+	mcr	p15, 0, r0, c2, c0, 0	/* load new TTB */
+	mcr	p15, 0, r1, c8, c7, 0	/* invalidate I+D TLBs */
+	mcr	p15, 0, r1, c7, c10, 4	/* drain write buffer */
+	RET
+
+ENTRY_NP(arm11x6_idcache_wbinv_all)
+	Flush_D_cache(r0)
+	Invalidate_I_cache(r0, r1)
+	RET
+
+ENTRY_NP(arm11x6_dcache_wbinv_all)
+	Flush_D_cache(r0)
+	RET
+
+ENTRY_NP(arm11x6_icache_sync_all)
+	Flush_D_cache(r0)
+	Invalidate_I_cache(r0, r1)
+	RET
+
+ENTRY_NP(arm11x6_flush_prefetchbuf)
+	mcr	p15, 0, r0, c7, c5, 4	/* Flush Prefetch Buffer */
+	RET
+
+ENTRY_NP(arm11x6_icache_sync_range)
+	add	r1, r1, r0
+	sub	r1, r1, #1
+	/* Erratum ARM1136 371025, workaround #2 */
+	/* Erratum ARM1176 371367 */
+	mrs	r2, cpsr		/* save the CPSR */
+	cpsid	ifa			/* disable interrupts (irq,fiq,abort) */
+	mov	r3, #0 
+	mcr	p15, 0, r3, c13, c0, 0	/* write FCSE (uTLB invalidate) */
+	mcr	p15, 0, r3, c7, c5, 4	/* flush prefetch buffer */
+	add	r3, pc, #0x24 
+	mcr	p15, 0, r3, c7, c13, 1	/* prefetch I-cache line */
+	mcrr	p15, 0, r1, r0, c5	/* invalidate I-cache range */
+	msr	cpsr_cx, r2		/* local_irq_restore */
+	nop 
+	nop 
+	nop 
+	nop 
+	nop 
+	nop 
+	nop 
+
+	mcrr	p15, 0, r1, r0, c12	/* clean and invalidate D cache range */ /* XXXNH */
+	mcr	p15, 0, r0, c7, c10, 4	/* drain the write buffer */
+	RET
+
+ENTRY_NP(arm11x6_idcache_wbinv_range)
+	add	r1, r1, r0
+	sub	r1, r1, #1
+	/* Erratum ARM1136 371025, workaround #2 */
+	/* Erratum ARM1176 371367 */
+	mrs	r2, cpsr		/* save the CPSR */
+	cpsid	ifa			/* disable interrupts (irq,fiq,abort) */
+	mov	r3, #0 
+	mcr	p15, 0, r3, c13, c0, 0	/* write FCSE (uTLB invalidate) */
+	mcr	p15, 0, r3, c7, c5, 4	/* flush prefetch buffer */
+	add	r3, pc, #0x24 
+	mcr	p15, 0, r3, c7, c13, 1	/* prefetch I-cache line */
+	mcrr	p15, 0, r1, r0, c5	/* invalidate I-cache range */
+	msr	cpsr_cx, r2		/* local_irq_restore */
+	nop 
+	nop 
+	nop 
+	nop 
+	nop 
+	nop 
+	nop 
+
+	mcrr	p15, 0, r1, r0, c14	/* clean and invalidate D cache range */
+	mcr	p15, 0, r0, c7, c10, 4	/* drain the write buffer */
+	RET
+
+/*
+ * Preload the cache before issuing the WFI by conditionally disabling the
+ * mcr intstructions the first time around the loop. Ensure the function is 
+ * cacheline aligned.
+ */
+	.arch	armv6
+	.p2align 5
+
+ENTRY_NP(arm11x6_sleep)
+	mov	r0, #0
+	mov	r1, #2
+1:
+	subs	r1, #1
+	nop
+	mcreq	p15, 0, r0, c7, c10, 4		/* data sync barrier */
+	mcreq	p15, 0, r0, c7, c0, 4		/* wait for interrupt */
+	nop
+	nop
+	nop
+	bne	1b
+	RET

Reply via email to