|
@@ -0,0 +1,71 @@
|
|
|
+/*
|
|
|
+ * Copyright 2011 Freescale Semiconductor, Inc.
|
|
|
+ * Copyright 2011 Linaro Ltd.
|
|
|
+ *
|
|
|
+ * The code contained herein is licensed under the GNU General Public
|
|
|
+ * License. You may obtain a copy of the GNU General Public License
|
|
|
+ * Version 2 or later at the following locations:
|
|
|
+ *
|
|
|
+ * http://www.opensource.org/licenses/gpl-license.html
|
|
|
+ * http://www.gnu.org/copyleft/gpl.html
|
|
|
+ */
|
|
|
+
|
|
|
+#include <linux/linkage.h>
|
|
|
+#include <linux/init.h>
|
|
|
+#include <asm/hardware/cache-l2x0.h>
|
|
|
+
|
|
|
+ .section ".text.head", "ax"
|
|
|
+ __CPUINIT
|
|
|
+
|
|
|
+/*
|
|
|
+ * The secondary kernel init calls v7_flush_dcache_all before it enables
|
|
|
+ * the L1; however, the L1 comes out of reset in an undefined state, so
|
|
|
+ * the clean + invalidate performed by v7_flush_dcache_all causes a bunch
|
|
|
+ * of cache lines with uninitialized data and uninitialized tags to get
|
|
|
+ * written out to memory, which does really unpleasant things to the main
|
|
|
+ * processor. We fix this by performing an invalidate, rather than a
|
|
|
+ * clean + invalidate, before jumping into the kernel.
|
|
|
+ *
|
|
|
+ * This funciton is cloned from arch/arm/mach-tegra/headsmp.S, and needs
|
|
|
+ * to be called for both secondary cores startup and primary core resume
|
|
|
+ * procedures. Ideally, it should be moved into arch/arm/mm/cache-v7.S.
|
|
|
+ */
|
|
|
+ENTRY(v7_invalidate_l1)
|
|
|
+ mov r0, #0
|
|
|
+ mcr p15, 2, r0, c0, c0, 0
|
|
|
+ mrc p15, 1, r0, c0, c0, 0
|
|
|
+
|
|
|
+ ldr r1, =0x7fff
|
|
|
+ and r2, r1, r0, lsr #13
|
|
|
+
|
|
|
+ ldr r1, =0x3ff
|
|
|
+
|
|
|
+ and r3, r1, r0, lsr #3 @ NumWays - 1
|
|
|
+ add r2, r2, #1 @ NumSets
|
|
|
+
|
|
|
+ and r0, r0, #0x7
|
|
|
+ add r0, r0, #4 @ SetShift
|
|
|
+
|
|
|
+ clz r1, r3 @ WayShift
|
|
|
+ add r4, r3, #1 @ NumWays
|
|
|
+1: sub r2, r2, #1 @ NumSets--
|
|
|
+ mov r3, r4 @ Temp = NumWays
|
|
|
+2: subs r3, r3, #1 @ Temp--
|
|
|
+ mov r5, r3, lsl r1
|
|
|
+ mov r6, r2, lsl r0
|
|
|
+ orr r5, r5, r6 @ Reg = (Temp<<WayShift)|(NumSets<<SetShift)
|
|
|
+ mcr p15, 0, r5, c7, c6, 2
|
|
|
+ bgt 2b
|
|
|
+ cmp r2, #0
|
|
|
+ bgt 1b
|
|
|
+ dsb
|
|
|
+ isb
|
|
|
+ mov pc, lr
|
|
|
+ENDPROC(v7_invalidate_l1)
|
|
|
+
|
|
|
+#ifdef CONFIG_SMP
|
|
|
+ENTRY(v7_secondary_startup)
|
|
|
+ bl v7_invalidate_l1
|
|
|
+ b secondary_startup
|
|
|
+ENDPROC(v7_secondary_startup)
|
|
|
+#endif
|