From mboxrd@z Thu Jan 1 00:00:00 1970 From: =?UTF-8?B?QW5kcmVhcyBCaWXDn21hbm4=?= Date: Sun, 09 Mar 2014 19:21:24 +0100 Subject: [U-Boot] [PATCH v2 5/5] arm: move exception handling out of start.S files In-Reply-To: <1394381903-7007-6-git-send-email-albert.u.boot@aribaud.net> References: <1394381903-7007-1-git-send-email-albert.u.boot@aribaud.net> <1394381903-7007-2-git-send-email-albert.u.boot@aribaud.net> <1394381903-7007-3-git-send-email-albert.u.boot@aribaud.net> <1394381903-7007-4-git-send-email-albert.u.boot@aribaud.net> <1394381903-7007-5-git-send-email-albert.u.boot@aribaud.net> <1394381903-7007-6-git-send-email-albert.u.boot@aribaud.net> Message-ID: <531CB124.5010407@googlemail.com> List-Id: MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit To: u-boot@lists.denx.de Dear Albert Aribaud, On 09.03.2014 17:18, Albert ARIBAUD wrote: > diff --git a/arch/arm/lib/vectors.S b/arch/arm/lib/vectors.S > new file mode 100644 > index 0000000..1655d49 > --- /dev/null > +++ b/arch/arm/lib/vectors.S > @@ -0,0 +1,304 @@ > +/* > + * vectors - Generic ARM exception table code > + * > + * Copyright (c) 1998 Dan Malek > + * Copyright (c) 1999 Magnus Damm > + * Copyright (c) 2000 Wolfgang Denk > + * Copyright (c) 2001 Alex Z?pke > + * Copyright (c) 2001 Marius Gr?ger > + * Copyright (c) 2002 Alex Z?pke > + * Copyright (c) 2002 Gary Jennejohn > + * Copyright (c) 2002 Kyle Harris > + * > + * SPDX-License-Identifier: GPL-2.0+ > + */ > + > +/* > + ************************************************************************* > + * > + * Symbol _start is referenced elsewhere, so make it global > + * > + ************************************************************************* > + */ > + > +.globl _start > + > +/* > + ************************************************************************* > + * > + * Vectors have their own section so linker script can map them easily > + * > + ************************************************************************* > + */ > + > + .section ".vectors", "x" > + > +/* > + ************************************************************************* > + * > + * Exception vectors as described in ARM reference manuals > + * > + * Uses indirect branch to allow reaching handlers anywhere in memory. > + * > + ************************************************************************* > + */ > + > +_start: > + > +#ifdef CONFIG_SYS_DV_NOR_BOOT_CFG > + .word CONFIG_SYS_DV_NOR_BOOT_CFG > +#endif > + > +#ifdef CONFIG_SPL_BUILD > + > +_start: > + ldr pc, _reset > + ldr pc, _hang > + ldr pc, _hang > + ldr pc, _hang > + ldr pc, _hang > + ldr pc, _hang > + ldr pc, _hang > + ldr pc, _hang > + > +#else > + > +_start: > + ldr pc, _reset > + ldr pc, _undefined_instruction > + ldr pc, _software_interrupt > + ldr pc, _prefetch_abort > + ldr pc, _data_abort > + ldr pc, _not_used > + ldr pc, _irq > + ldr pc, _fiq > + > +#endif > + > +/* > + ************************************************************************* > + * > + * Indirect vectors table > + * > + * Symbols referenced here must be defined somewhere else > + * > + ************************************************************************* > + */ > + > +_reset: .word reset > + > +#ifdef CONFIG_SPL_BUILD > + > +_hang: .word do_hang > + > +#else > + > + .globl _undefined_instruction > + .globl _software_interrupt > + .globl _prefetch_abort > + .globl _data_abort > + .globl _not_used > + .globl _irq > + .globl _fiq > + > +_undefined_instruction: .word undefined_instruction > +_software_interrupt: .word software_interrupt > +_prefetch_abort: .word prefetch_abort > +_data_abort: .word data_abort > +_not_used: .word not_used > +_irq: .word irq > +_fiq: .word fiq > + > +#endif > + > + .balignl 16,0xdeadbeef > + > +/* > + ************************************************************************* > + * > + * Interrupt handling > + * > + ************************************************************************* > + */ > + > +/* IRQ stack memory (calculated at run-time) + 8 bytes */ > +.globl IRQ_STACK_START_IN > +IRQ_STACK_START_IN: > + .word 0x0badc0de > + > +#ifndef CONFIG_SPL_BUILD > + > +#ifdef CONFIG_USE_IRQ > +/* IRQ stack memory (calculated at run-time) */ > +.globl IRQ_STACK_START > +IRQ_STACK_START: > + .word 0x0badc0de > + > +/* IRQ stack memory (calculated at run-time) */ > +.globl FIQ_STACK_START > +FIQ_STACK_START: > + .word 0x0badc0de > +#endif > + > +@ > +@ IRQ stack frame. > +@ > +#define S_FRAME_SIZE 72 > + > +#define S_OLD_R0 68 > +#define S_PSR 64 > +#define S_PC 60 > +#define S_LR 56 > +#define S_SP 52 > + > +#define S_IP 48 > +#define S_FP 44 > +#define S_R10 40 > +#define S_R9 36 > +#define S_R8 32 > +#define S_R7 28 > +#define S_R6 24 > +#define S_R5 20 > +#define S_R4 16 > +#define S_R3 12 > +#define S_R2 8 > +#define S_R1 4 > +#define S_R0 0 > + > +#define MODE_SVC 0x13 > +#define I_BIT 0x80 > + > +/* > + * use bad_save_user_regs for abort/prefetch/undef/swi ... > + * use irq_save_user_regs / irq_restore_user_regs for IRQ/FIQ handling > + */ > + > + .macro bad_save_user_regs > + @ carve out a frame on current user stack > + sub sp, sp, #S_FRAME_SIZE > + stmia sp, {r0 - r12} @ Save user registers (now in svc mode) r0-r12 > + ldr r2, IRQ_STACK_START_IN > + @ get values for "aborted" pc and cpsr (into parm regs) > + ldmia r2, {r2 - r3} > + add r0, sp, #S_FRAME_SIZE @ grab pointer to old stack > + add r5, sp, #S_SP > + mov r1, lr > + stmia r5, {r0 - r3} @ save sp_SVC, lr_SVC, pc, cpsr > + mov r0, sp @ save current stack into r0 (param register) > + .endm > + > + .macro irq_save_user_regs > + sub sp, sp, #S_FRAME_SIZE > + stmia sp, {r0 - r12} @ Calling r0-r12 > + @ !!!! R8 NEEDS to be saved !!!! a reserved stack spot would be good. > + add r8, sp, #S_PC > + stmdb r8, {sp, lr}^ @ Calling SP, LR > + str lr, [r8, #0] @ Save calling PC > + mrs r6, spsr > + str r6, [r8, #4] @ Save CPSR > + str r0, [r8, #8] @ Save OLD_R0 > + mov r0, sp > + .endm > + > + .macro irq_restore_user_regs > + ldmia sp, {r0 - lr}^ @ Calling r0 - lr > + mov r0, r0 > + ldr lr, [sp, #S_PC] @ Get PC > + add sp, sp, #S_FRAME_SIZE > + subs pc, lr, #4 @ return & move spsr_svc into cpsr > + .endm > + > + .macro get_bad_stack > + ldr r13, IRQ_STACK_START_IN @ setup our mode stack > + > + str lr, [r13] @ save caller lr in position 0 of saved stack > + mrs lr, spsr @ get the spsr > + str lr, [r13, #4] @ save spsr in position 1 of saved stack > + mov r13, #MODE_SVC @ prepare SVC-Mode > + @ msr spsr_c, r13 > + msr spsr, r13 @ switch modes, make sure moves will execute > + mov lr, pc @ capture return pc > + movs pc, lr @ jump to next instruction & switch modes. > + .endm > + > + .macro get_irq_stack @ setup IRQ stack > + ldr sp, IRQ_STACK_START > + .endm > + > + .macro get_fiq_stack @ setup FIQ stack > + ldr sp, FIQ_STACK_START > + .endm > +#endif /* CONFIG_SPL_BUILD */ > + > +/* > + * exception handlers > + */ > +#ifdef CONFIG_SPL_BUILD > + .align 5 > +do_hang: > +1: > + bl 1b /* hang and never return */ > +#else /* !CONFIG_SPL_BUILD */ > + .align 5 > +undefined_instruction: > + get_bad_stack > + bad_save_user_regs > + bl do_undefined_instruction > + > + .align 5 > +software_interrupt: > + get_bad_stack > + bad_save_user_regs > + bl do_software_interrupt > + > + .align 5 > +prefetch_abort: > + get_bad_stack > + bad_save_user_regs > + bl do_prefetch_abort > + > + .align 5 > +data_abort: > + get_bad_stack > + bad_save_user_regs > + bl do_data_abort > + > + .align 5 > +not_used: > + get_bad_stack > + bad_save_user_regs > + bl do_not_used > + > +#ifdef CONFIG_USE_IRQ > + > + .align 5 > +irq: > + get_irq_stack > + irq_save_user_regs > + bl do_irq > + irq_restore_user_regs > + > + .align 5 > +fiq: > + get_fiq_stack > + /* someone ought to write a more effiction fiq_save_user_regs */ > + irq_save_user_regs > + bl do_fiq > + irq_restore_user_regs > + > +#else > + > + .align 5 > +irq: > + get_bad_stack > + bad_save_user_regs > + bl do_irq > + > + .align 5 > +fiq: > + get_bad_stack > + bad_save_user_regs > + bl do_fiq > + > +#endif > +#endif /* CONFIG_SPL_BUILD */ this file is completely different for SPL and non-SPL builds. They both share just the header of the file. I wonder why we introduce a single vectors.S then. Wouldn't it be better to have a vectors.S for non-SPL builds and lets say a vectors_SPL.S for SPL builds? Best regards Andreas Bie?mann