summaryrefslogtreecommitdiffstats
path: root/arch/arm/lib/relocate.S
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/lib/relocate.S')
-rw-r--r--arch/arm/lib/relocate.S30
1 files changed, 30 insertions, 0 deletions
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