[U-Boot] [PATCH v1 2/2] imx: fix exception vectors relocation in i.MX27

trem
2014-11-11T18:02:21Z

On 11/11/14 17:46, Albert ARIBAUD wrote:
> Commit 3ff46cc4 fixed exception vectors setting in
> the general ARM case, by either copying the exception
> and indirect vector tables to normal (0x00000000) or
> high (0xFFFF0000) vectors address, or setting VBAR to
> U-Boot's base if applicable.
>
> i.MX27 SoC is ARM926E-JS, thus has only normal and
> high options, but does not provide RAM at 0xFFFF0000
> and has only ROM at 0x00000000; it is therefore not
> possible to move or change its exception vectors.
>
> Besides, i.MX27 ROM code does provide an indirect
> vectors table but at a non-standard address and with
> the reset and reserved vectors missing.
>
> Turn the current vector relocation code into a weak
> routine called after relocate_code from crt0, and add
> strong version for i.MX27.
>
> Signed-off-by: Albert ARIBAUD<albert.u.boot@aribaud.net>
> ---
>
> arch/arm/cpu/arm926ejs/mx27/Makefile | 4 ++
> arch/arm/cpu/arm926ejs/mx27/relocate.S | 49 ++++++++++++++++++++++++
> arch/arm/lib/crt0.S | 5 +++
> arch/arm/lib/relocate.S | 69 ++++++++++++++++++++--------------
> 4 files changed, 99 insertions(+), 28 deletions(-)
> create mode 100644 arch/arm/cpu/arm926ejs/mx27/relocate.S
>
> diff --git a/arch/arm/cpu/arm926ejs/mx27/Makefile b/arch/arm/cpu/arm926ejs/mx27/Makefile
> index 4976bbb..0edf144 100644
> --- a/arch/arm/cpu/arm926ejs/mx27/Makefile
> +++ b/arch/arm/cpu/arm926ejs/mx27/Makefile
> @@ -5,3 +5,7 @@
> # SPDX-License-Identifier: GPL-2.0+
>
> obj-y = generic.o reset.o timer.o
> +
> +ifndef CONFIG_SPL_BUILD
> +obj-y += relocate.o
> +endif
> diff --git a/arch/arm/cpu/arm926ejs/mx27/relocate.S b/arch/arm/cpu/arm926ejs/mx27/relocate.S
> new file mode 100644
> index 0000000..97003b3
> --- /dev/null
> +++ b/arch/arm/cpu/arm926ejs/mx27/relocate.S
> @@ -0,0 +1,49 @@
> +/*
> + * 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 0x00 (reset) and 0x14 (reserved).
> + */
> +
> + .section .text.relocate_vectors,"ax",%progbits
> +
> +ENTRY(relocate_vectors)
> +
> + ldr r0, [r9, #GD_RELOCADDR] /* r0 = gd->relocaddr */
> + ldr r1, =0xFFFFFEF0
> + ldmia r0!, {r2-r8,r10} /* load all eight vectors */
> + stmia r1!, {r3-r6,r8,r10} /* only write supported vectors */
> +
> + bx lr
> +
> +ENDPROC(relocate_vectors)
> diff --git a/arch/arm/lib/crt0.S b/arch/arm/lib/crt0.S
> index 29cdad0..a33ad3e 100644
> --- a/arch/arm/lib/crt0.S
> +++ b/arch/arm/lib/crt0.S
> @@ -104,6 +104,11 @@ clr_gd:
> ldr r0, [r9, #GD_RELOCADDR] /* r0 = gd->relocaddr */
> b relocate_code
> here:
> +/*
> + * now relocate vectors
> + */
> +
> + bl relocate_vectors
>
> /* Set up final (full) environment */
>
> diff --git a/arch/arm/lib/relocate.S b/arch/arm/lib/relocate.S
> index 6ede41c..92f5314 100644
> --- a/arch/arm/lib/relocate.S
> +++ b/arch/arm/lib/relocate.S
> @@ -11,6 +11,47 @@
> #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)
> *
> * This function relocates the monitor code.
> @@ -54,34 +95,6 @@ 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__

Hi Albert,

I've tested this patch, and it fix my boot issue on armadeus apf27.
(without this patch, u-boot freeze on relocation on apf27).
But after a "mw.l 0 0" I don't have the log "data abort",
neither the board reboot.

Regards,
Philippe