diff --git a/arch/arm/cpu/armv7/start.S b/arch/arm/cpu/armv7/start.S index fedd7c8..fdc05b9 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 8035251..b4a258c 100644 --- a/arch/arm/lib/relocate.S +++ b/arch/arm/lib/relocate.S @@ -6,6 +6,8 @@ * SPDX-License-Identifier: GPL-2.0+ */ +#include +#include #include /* @@ -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__