summaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
Diffstat (limited to 'arch')
-rw-r--r--arch/arm/cpu/armv7/start.S6
-rw-r--r--arch/arm/lib/relocate.S30
2 files changed, 30 insertions, 6 deletions
diff --git a/arch/arm/cpu/armv7/start.S b/arch/arm/cpu/armv7/start.S
index fedd7c8f7e..fdc05b942f 100644
--- a/arch/arm/cpu/armv7/start.S
+++ b/arch/arm/cpu/armv7/start.S
@@ -81,12 +81,6 @@ ENTRY(c_runtime_cpu_setup)
mcr p15, 0, r0, c7, c10, 4 @ DSB
mcr p15, 0, r0, c7, c5, 4 @ ISB
#endif
-/*
- * Move vector table
- */
- /* Set vector address in CP15 VBAR register */
- ldr r0, =_start
- mcr p15, 0, r0, c12, c0, 0 @Set VBAR
bx lr
diff --git a/arch/arm/lib/relocate.S b/arch/arm/lib/relocate.S
index 8035251563..b4a258ce5c 100644
--- a/arch/arm/lib/relocate.S
+++ b/arch/arm/lib/relocate.S
@@ -6,6 +6,8 @@
* SPDX-License-Identifier: GPL-2.0+
*/
+#include <asm-offsets.h>
+#include <config.h>
#include <linux/linkage.h>
/*
@@ -52,6 +54,34 @@ fixnext:
cmp r2, r3
blo fixloop
+ /*
+ * Relocate the exception vectors
+ */
+#ifdef CONFIG_HAS_VBAR
+ /*
+ * If the ARM processor has the security extensions,
+ * use VBAR to relocate the exception vectors.
+ */
+ ldr r0, [r9, #GD_RELOCADDR] /* r0 = gd->relocaddr */
+ mcr p15, 0, r0, c12, c0, 0 /* Set VBAR */
+#else
+ /*
+ * Copy the relocated exception vectors to the
+ * correct address
+ * CP15 c1 V bit gives us the location of the vectors:
+ * 0x00000000 or 0xFFFF0000.
+ */
+ ldr r0, [r9, #GD_RELOCADDR] /* r0 = gd->relocaddr */
+ mrc p15, 0, r2, c1, c0, 0 /* V bit (bit[13]) in CP15 c1 */
+ ands r2, r2, #(1 << 13)
+ ldreq r1, =0x00000000 /* If V=0 */
+ ldrne r1, =0xFFFF0000 /* If V=1 */
+ ldmia r0!, {r2-r8,r10}
+ stmia r1!, {r2-r8,r10}
+ ldmia r0!, {r2-r8,r10}
+ stmia r1!, {r2-r8,r10}
+#endif
+
relocate_done:
#ifdef __XSCALE__
OpenPOWER on IntegriCloud