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