--- /dev/null
+/*
+ * relocate - i.MX27-specific vector relocation
+ *
+ * Copyright (c) 2013 Albert ARIBAUD <albert.u.boot@aribaud.net>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <asm-offsets.h>
+#include <config.h>
+#include <linux/linkage.h>
+
+/*
+ * The i.MX27 SoC is very specific with respect to exceptions: it
+ * does not provide RAM at the high vectors address (0xFFFF0000),
+ * thus only the low address (0x00000000) is useable; but that is
+ * in ROM. Therefore, vectors cannot be changed at all.
+ *
+ * However, these ROM-based vectors actually just perform indirect
+ * calls through pointers located in RAM at SoC-specific addresses,
+ * as follows:
+ *
+ * Offset Exception Use by ROM code
+ * 0x00000000 reset indirect branch to [0x00000014]
+ * 0x00000004 undefined instruction indirect branch to [0xfffffef0]
+ * 0x00000008 software interrupt indirect branch to [0xfffffef4]
+ * 0x0000000c prefetch abort indirect branch to [0xfffffef8]
+ * 0x00000010 data abort indirect branch to [0xfffffefc]
+ * 0x00000014 (reserved in ARMv5) vector to ROM reset: 0xc0000000
+ * 0x00000018 IRQ indirect branch to [0xffffff00]
+ * 0x0000001c FIQ indirect branch to [0xffffff04]
+ *
+ * In order to initialize exceptions on i.MX27, we must copy U-Boot's
+ * indirect (not exception!) vector table into 0xfffffef0..0xffffff04
+ * taking care not to copy vectors number 5 (reserved exception).
+ */
+
+ .section .text.relocate_vectors,"ax",%progbits
+
+ENTRY(relocate_vectors)
+
+ ldr r0, [r9, #GD_RELOCADDR] /* r0 = gd->relocaddr */
+ ldr r1, =32 /* size of vector table */
+ add r0, r0, r1 /* skip to indirect table */
+ ldr r1, =0xFFFFFEF0 /* i.MX27 indirect table */
+ ldmia r0!, {r2-r8} /* load indirect vectors 1..7 */
+ stmia r1!, {r2-r5, r7,r8} /* write all but vector 5 */
+
+ bx lr
+
+ENDPROC(relocate_vectors)
#include <config.h>
#include <linux/linkage.h>
+/*
+ * Default/weak exception vectors relocation routine
+ *
+ * This routine covers the standard ARM cases: normal (0x00000000),
+ * high (0xffff0000) and VBAR. SoCs which do not comply with any of
+ * the standard cases must provide their own, strong, version.
+ */
+
+ .section .text.relocate_vectors,"ax",%progbits
+ .weak relocate_vectors
+
+ENTRY(relocate_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
+ bx lr
+
+ENDPROC(relocate_vectors)
+
/*
* void relocate_code(addr_moni)
*
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__