mirror of
https://github.com/u-boot/u-boot.git
synced 2024-11-28 23:23:30 +08:00
arm: move exception handling out of start.S files
Exception handling is basically identical for all ARM targets. Factorize it out of the various start.S files and into a single vectors.S file, and adjust linker scripts accordingly. Signed-off-by: Albert ARIBAUD <albert.u.boot@aribaud.net>
This commit is contained in:
parent
60a4f39fcd
commit
41623c91b0
@ -15,46 +15,7 @@
|
|||||||
#include <asm-offsets.h>
|
#include <asm-offsets.h>
|
||||||
#include <config.h>
|
#include <config.h>
|
||||||
#include <version.h>
|
#include <version.h>
|
||||||
.globl _start
|
|
||||||
_start: b reset
|
|
||||||
#ifdef CONFIG_SPL_BUILD
|
|
||||||
ldr pc, _hang
|
|
||||||
ldr pc, _hang
|
|
||||||
ldr pc, _hang
|
|
||||||
ldr pc, _hang
|
|
||||||
ldr pc, _hang
|
|
||||||
ldr pc, _hang
|
|
||||||
ldr pc, _hang
|
|
||||||
|
|
||||||
_hang:
|
|
||||||
.word do_hang
|
|
||||||
.word 0x12345678
|
|
||||||
.word 0x12345678
|
|
||||||
.word 0x12345678
|
|
||||||
.word 0x12345678
|
|
||||||
.word 0x12345678
|
|
||||||
.word 0x12345678
|
|
||||||
.word 0x12345678 /* now 16*4=64 */
|
|
||||||
#else
|
|
||||||
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
|
|
||||||
|
|
||||||
_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
|
|
||||||
_pad: .word 0x12345678 /* now 16*4=64 */
|
|
||||||
#endif /* CONFIG_SPL_BUILD */
|
|
||||||
|
|
||||||
.balignl 16,0xdeadbeef
|
|
||||||
/*
|
/*
|
||||||
*************************************************************************
|
*************************************************************************
|
||||||
*
|
*
|
||||||
@ -68,26 +29,7 @@ _pad: .word 0x12345678 /* now 16*4=64 */
|
|||||||
*************************************************************************
|
*************************************************************************
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef CONFIG_USE_IRQ
|
.globl reset
|
||||||
/* 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 memory (calculated at run-time) + 8 bytes */
|
|
||||||
.globl IRQ_STACK_START_IN
|
|
||||||
IRQ_STACK_START_IN:
|
|
||||||
.word 0x0badc0de
|
|
||||||
|
|
||||||
/*
|
|
||||||
* the actual reset code
|
|
||||||
*/
|
|
||||||
|
|
||||||
reset:
|
reset:
|
||||||
/*
|
/*
|
||||||
@ -150,185 +92,3 @@ cpu_init_crit:
|
|||||||
mov lr, ip /* restore link */
|
mov lr, ip /* restore link */
|
||||||
mov pc, lr /* back to my caller */
|
mov pc, lr /* back to my caller */
|
||||||
#endif /* CONFIG_SKIP_LOWLEVEL_INIT */
|
#endif /* CONFIG_SKIP_LOWLEVEL_INIT */
|
||||||
|
|
||||||
#ifndef CONFIG_SPL_BUILD
|
|
||||||
/*
|
|
||||||
*************************************************************************
|
|
||||||
*
|
|
||||||
* Interrupt handling
|
|
||||||
*
|
|
||||||
*************************************************************************
|
|
||||||
*/
|
|
||||||
@
|
|
||||||
@ 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
|
|
||||||
sub sp, sp, #S_FRAME_SIZE @ carve out a frame on current user stack
|
|
||||||
stmia sp, {r0 - r12} @ Save user registers (now in svc mode) r0-r12
|
|
||||||
|
|
||||||
ldr r2, IRQ_STACK_START_IN @ set base 2 words into abort stack
|
|
||||||
ldmia r2, {r2 - r3} @ get values for "aborted" pc and cpsr (into parm regs)
|
|
||||||
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
|
|
||||||
add r8, sp, #S_PC @ !!!! R8 NEEDS to be saved !!!! a reserved stack spot would be good.
|
|
||||||
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 (enter in banked mode)
|
|
||||||
|
|
||||||
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_bad_stack_swi
|
|
||||||
sub r13, r13, #4 @ space on current stack for scratch reg.
|
|
||||||
str r0, [r13] @ save R0's value.
|
|
||||||
ldr r0, IRQ_STACK_START_IN @ get data regions start
|
|
||||||
str lr, [r0] @ save caller lr in position 0 of saved stack
|
|
||||||
mrs lr, spsr @ get the spsr
|
|
||||||
str lr, [r0, #4] @ save spsr in position 1 of saved stack
|
|
||||||
ldr lr, [r0] @ restore lr
|
|
||||||
ldr r0, [r13] @ restore r0
|
|
||||||
add r13, r13, #4 @ pop stack entry
|
|
||||||
.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:
|
|
||||||
bl hang /* 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_swi
|
|
||||||
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 */
|
|
||||||
|
@ -22,46 +22,6 @@
|
|||||||
#define CONFIG_SYS_PHY_UBOOT_BASE CONFIG_SYS_UBOOT_BASE
|
#define CONFIG_SYS_PHY_UBOOT_BASE CONFIG_SYS_UBOOT_BASE
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
|
||||||
*************************************************************************
|
|
||||||
*
|
|
||||||
* Jump vector table as in table 3.1 in [1]
|
|
||||||
*
|
|
||||||
*************************************************************************
|
|
||||||
*/
|
|
||||||
|
|
||||||
.globl _start
|
|
||||||
_start: b reset
|
|
||||||
#ifndef CONFIG_SPL_BUILD
|
|
||||||
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
|
|
||||||
|
|
||||||
_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
|
|
||||||
_pad:
|
|
||||||
.word 0x12345678 /* now 16*4=64 */
|
|
||||||
#else
|
|
||||||
. = _start + 64
|
|
||||||
#endif
|
|
||||||
|
|
||||||
.balignl 16,0xdeadbeef
|
|
||||||
/*
|
/*
|
||||||
*************************************************************************
|
*************************************************************************
|
||||||
*
|
*
|
||||||
@ -75,14 +35,7 @@ _pad:
|
|||||||
*************************************************************************
|
*************************************************************************
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* IRQ stack memory (calculated at run-time) + 8 bytes */
|
.globl reset
|
||||||
.globl IRQ_STACK_START_IN
|
|
||||||
IRQ_STACK_START_IN:
|
|
||||||
.word 0x0badc0de
|
|
||||||
|
|
||||||
/*
|
|
||||||
* the actual reset code
|
|
||||||
*/
|
|
||||||
|
|
||||||
reset:
|
reset:
|
||||||
/*
|
/*
|
||||||
@ -180,150 +133,3 @@ skip_tcmdisable:
|
|||||||
c_runtime_cpu_setup:
|
c_runtime_cpu_setup:
|
||||||
|
|
||||||
mov pc, lr
|
mov pc, lr
|
||||||
|
|
||||||
#ifndef CONFIG_SPL_BUILD
|
|
||||||
/*
|
|
||||||
*************************************************************************
|
|
||||||
*
|
|
||||||
* Interrupt handling
|
|
||||||
*
|
|
||||||
*************************************************************************
|
|
||||||
*/
|
|
||||||
@
|
|
||||||
@ 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 ...
|
|
||||||
*/
|
|
||||||
|
|
||||||
.macro bad_save_user_regs
|
|
||||||
/* carve out a frame on current user stack */
|
|
||||||
sub sp, sp, #S_FRAME_SIZE
|
|
||||||
/* Save user registers (now in svc mode) r0-r12 */
|
|
||||||
stmia sp, {r0 - r12}
|
|
||||||
|
|
||||||
ldr r2, IRQ_STACK_START_IN
|
|
||||||
/* get values for "aborted" pc and cpsr (into parm regs) */
|
|
||||||
ldmia r2, {r2 - r3}
|
|
||||||
/* grab pointer to old stack */
|
|
||||||
add r0, sp, #S_FRAME_SIZE
|
|
||||||
|
|
||||||
add r5, sp, #S_SP
|
|
||||||
mov r1, lr
|
|
||||||
/* save sp_SVC, lr_SVC, pc, cpsr */
|
|
||||||
stmia r5, {r0 - r3}
|
|
||||||
/* save current stack into r0 (param register) */
|
|
||||||
mov r0, sp
|
|
||||||
.endm
|
|
||||||
|
|
||||||
.macro get_bad_stack
|
|
||||||
ldr r13, IRQ_STACK_START_IN @ setup our mode stack
|
|
||||||
|
|
||||||
/* save caller lr in position 0 of saved stack */
|
|
||||||
str lr, [r13]
|
|
||||||
/* get the spsr */
|
|
||||||
mrs lr, spsr
|
|
||||||
/* save spsr in position 1 of saved stack */
|
|
||||||
str lr, [r13, #4]
|
|
||||||
|
|
||||||
/* prepare SVC-Mode */
|
|
||||||
mov r13, #MODE_SVC
|
|
||||||
@ msr spsr_c, r13
|
|
||||||
/* switch modes, make sure moves will execute */
|
|
||||||
msr spsr, r13
|
|
||||||
/* capture return pc */
|
|
||||||
mov lr, pc
|
|
||||||
/* jump to next instruction & switch modes. */
|
|
||||||
movs pc, lr
|
|
||||||
.endm
|
|
||||||
|
|
||||||
.macro get_bad_stack_swi
|
|
||||||
/* space on current stack for scratch reg. */
|
|
||||||
sub r13, r13, #4
|
|
||||||
/* save R0's value. */
|
|
||||||
str r0, [r13]
|
|
||||||
ldr r13, IRQ_STACK_START_IN @ setup our mode stack
|
|
||||||
/* save caller lr in position 0 of saved stack */
|
|
||||||
str lr, [r0]
|
|
||||||
/* get the spsr */
|
|
||||||
mrs lr, spsr
|
|
||||||
/* save spsr in position 1 of saved stack */
|
|
||||||
str lr, [r0, #4]
|
|
||||||
/* restore lr */
|
|
||||||
ldr lr, [r0]
|
|
||||||
/* restore r0 */
|
|
||||||
ldr r0, [r13]
|
|
||||||
/* pop stack entry */
|
|
||||||
add r13, r13, #4
|
|
||||||
.endm
|
|
||||||
|
|
||||||
/*
|
|
||||||
* exception handlers
|
|
||||||
*/
|
|
||||||
.align 5
|
|
||||||
undefined_instruction:
|
|
||||||
get_bad_stack
|
|
||||||
bad_save_user_regs
|
|
||||||
bl do_undefined_instruction
|
|
||||||
|
|
||||||
.align 5
|
|
||||||
software_interrupt:
|
|
||||||
get_bad_stack_swi
|
|
||||||
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
|
|
||||||
|
|
||||||
.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 /* CONFIG_SPL_BUILD */
|
|
||||||
|
@ -12,48 +12,6 @@
|
|||||||
#include <version.h>
|
#include <version.h>
|
||||||
#include <asm/hardware.h>
|
#include <asm/hardware.h>
|
||||||
|
|
||||||
/*
|
|
||||||
*************************************************************************
|
|
||||||
*
|
|
||||||
* Jump vector table as in table 3.1 in [1]
|
|
||||||
*
|
|
||||||
*************************************************************************
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
.globl _start
|
|
||||||
_start: b 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
|
|
||||||
|
|
||||||
#ifdef CONFIG_SPL_BUILD
|
|
||||||
_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
|
|
||||||
_pad: .word 0x12345678 /* now 16*4=64 */
|
|
||||||
#else
|
|
||||||
_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
|
|
||||||
_pad: .word 0x12345678 /* now 16*4=64 */
|
|
||||||
#endif /* CONFIG_SPL_BUILD */
|
|
||||||
|
|
||||||
.balignl 16,0xdeadbeef
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
*************************************************************************
|
*************************************************************************
|
||||||
*
|
*
|
||||||
@ -67,26 +25,7 @@ _pad: .word 0x12345678 /* now 16*4=64 */
|
|||||||
*************************************************************************
|
*************************************************************************
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef CONFIG_USE_IRQ
|
.globl reset
|
||||||
/* 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 memory (calculated at run-time) + 8 bytes */
|
|
||||||
.globl IRQ_STACK_START_IN
|
|
||||||
IRQ_STACK_START_IN:
|
|
||||||
.word 0x0badc0de
|
|
||||||
|
|
||||||
/*
|
|
||||||
* the actual reset code
|
|
||||||
*/
|
|
||||||
|
|
||||||
reset:
|
reset:
|
||||||
/*
|
/*
|
||||||
@ -139,169 +78,3 @@ cpu_init_crit:
|
|||||||
|
|
||||||
mov pc, lr
|
mov pc, lr
|
||||||
#endif /* CONFIG_SKIP_LOWLEVEL_INIT */
|
#endif /* CONFIG_SKIP_LOWLEVEL_INIT */
|
||||||
|
|
||||||
|
|
||||||
#ifndef CONFIG_SPL_BUILD
|
|
||||||
/*
|
|
||||||
*************************************************************************
|
|
||||||
*
|
|
||||||
* Interrupt handling
|
|
||||||
*
|
|
||||||
*************************************************************************
|
|
||||||
*/
|
|
||||||
|
|
||||||
@
|
|
||||||
@ 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
|
|
||||||
sub sp, sp, #S_FRAME_SIZE
|
|
||||||
stmia sp, {r0 - r12} @ Calling r0-r12
|
|
||||||
add r8, sp, #S_PC
|
|
||||||
|
|
||||||
ldr r2, IRQ_STACK_START_IN
|
|
||||||
ldmia r2, {r2 - r4} @ get pc, cpsr, old_r0
|
|
||||||
add r0, sp, #S_FRAME_SIZE @ restore sp_SVC
|
|
||||||
|
|
||||||
add r5, sp, #S_SP
|
|
||||||
mov r1, lr
|
|
||||||
stmia r5, {r0 - r4} @ save sp_SVC, lr_SVC, pc, cpsr, old_r
|
|
||||||
mov r0, sp
|
|
||||||
.endm
|
|
||||||
|
|
||||||
.macro irq_save_user_regs
|
|
||||||
sub sp, sp, #S_FRAME_SIZE
|
|
||||||
stmia sp, {r0 - r12} @ Calling r0-r12
|
|
||||||
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 / spsr
|
|
||||||
mrs lr, spsr
|
|
||||||
str lr, [r13, #4]
|
|
||||||
|
|
||||||
mov r13, #MODE_SVC @ prepare SVC-Mode
|
|
||||||
msr spsr_c, r13
|
|
||||||
mov lr, pc
|
|
||||||
movs pc, lr
|
|
||||||
.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
|
|
||||||
|
|
||||||
/*
|
|
||||||
* exception handlers
|
|
||||||
*/
|
|
||||||
.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 */
|
|
||||||
|
@ -16,7 +16,8 @@ SECTIONS
|
|||||||
.text :
|
.text :
|
||||||
{
|
{
|
||||||
*(.__image_copy_start)
|
*(.__image_copy_start)
|
||||||
arch/arm/cpu/arm920t/start.o (.text*)
|
*(.vectors)
|
||||||
|
arch/arm/cpu/arm920t/start.o (.text*)
|
||||||
/* the EP93xx expects to find the pattern 'CRUS' at 0x1000 */
|
/* the EP93xx expects to find the pattern 'CRUS' at 0x1000 */
|
||||||
. = 0x1000;
|
. = 0x1000;
|
||||||
LONG(0x53555243)
|
LONG(0x53555243)
|
||||||
|
@ -12,36 +12,6 @@
|
|||||||
#include <common.h>
|
#include <common.h>
|
||||||
#include <config.h>
|
#include <config.h>
|
||||||
|
|
||||||
/*
|
|
||||||
*************************************************************************
|
|
||||||
*
|
|
||||||
* Jump vector table as in table 3.1 in [1]
|
|
||||||
*
|
|
||||||
*************************************************************************
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
.globl _start
|
|
||||||
_start: b start_code
|
|
||||||
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
|
|
||||||
|
|
||||||
_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
|
|
||||||
|
|
||||||
.balignl 16,0xdeadbeef
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
*************************************************************************
|
*************************************************************************
|
||||||
*
|
*
|
||||||
@ -55,28 +25,9 @@ _fiq: .word fiq
|
|||||||
*************************************************************************
|
*************************************************************************
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef CONFIG_USE_IRQ
|
.globl reset
|
||||||
/* IRQ stack memory (calculated at run-time) */
|
|
||||||
.globl IRQ_STACK_START
|
|
||||||
IRQ_STACK_START:
|
|
||||||
.word 0x0badc0de
|
|
||||||
|
|
||||||
/* IRQ stack memory (calculated at run-time) */
|
reset:
|
||||||
.globl FIQ_STACK_START
|
|
||||||
FIQ_STACK_START:
|
|
||||||
.word 0x0badc0de
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* IRQ stack memory (calculated at run-time) + 8 bytes */
|
|
||||||
.globl IRQ_STACK_START_IN
|
|
||||||
IRQ_STACK_START_IN:
|
|
||||||
.word 0x0badc0de
|
|
||||||
|
|
||||||
/*
|
|
||||||
* the actual start code
|
|
||||||
*/
|
|
||||||
|
|
||||||
start_code:
|
|
||||||
/*
|
/*
|
||||||
* set the cpu to SVC32 mode
|
* set the cpu to SVC32 mode
|
||||||
*/
|
*/
|
||||||
@ -196,166 +147,3 @@ cpu_init_crit:
|
|||||||
mov lr, ip
|
mov lr, ip
|
||||||
mov pc, lr
|
mov pc, lr
|
||||||
#endif /* CONFIG_SKIP_LOWLEVEL_INIT */
|
#endif /* CONFIG_SKIP_LOWLEVEL_INIT */
|
||||||
|
|
||||||
/*
|
|
||||||
*************************************************************************
|
|
||||||
*
|
|
||||||
* Interrupt handling
|
|
||||||
*
|
|
||||||
*************************************************************************
|
|
||||||
*/
|
|
||||||
|
|
||||||
@
|
|
||||||
@ 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
|
|
||||||
sub sp, sp, #S_FRAME_SIZE
|
|
||||||
stmia sp, {r0 - r12} @ Calling r0-r12
|
|
||||||
ldr r2, IRQ_STACK_START_IN
|
|
||||||
ldmia r2, {r2 - r3} @ get pc, cpsr
|
|
||||||
add r0, sp, #S_FRAME_SIZE @ restore sp_SVC
|
|
||||||
|
|
||||||
add r5, sp, #S_SP
|
|
||||||
mov r1, lr
|
|
||||||
stmia r5, {r0 - r3} @ save sp_SVC, lr_SVC, pc, cpsr
|
|
||||||
mov r0, sp
|
|
||||||
.endm
|
|
||||||
|
|
||||||
.macro irq_save_user_regs
|
|
||||||
sub sp, sp, #S_FRAME_SIZE
|
|
||||||
stmia sp, {r0 - r12} @ Calling r0-r12
|
|
||||||
add r7, sp, #S_PC
|
|
||||||
stmdb r7, {sp, lr}^ @ Calling SP, LR
|
|
||||||
str lr, [r7, #0] @ Save calling PC
|
|
||||||
mrs r6, spsr
|
|
||||||
str r6, [r7, #4] @ Save CPSR
|
|
||||||
str r0, [r7, #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
|
|
||||||
/* return & move spsr_svc into cpsr */
|
|
||||||
subs pc, lr, #4
|
|
||||||
.endm
|
|
||||||
|
|
||||||
.macro get_bad_stack
|
|
||||||
ldr r13, IRQ_STACK_START_IN @ setup our mode stack
|
|
||||||
|
|
||||||
str lr, [r13] @ save caller lr / spsr
|
|
||||||
mrs lr, spsr
|
|
||||||
str lr, [r13, #4]
|
|
||||||
|
|
||||||
mov r13, #MODE_SVC @ prepare SVC-Mode
|
|
||||||
@ msr spsr_c, r13
|
|
||||||
msr spsr, r13
|
|
||||||
mov lr, pc
|
|
||||||
movs pc, lr
|
|
||||||
.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
|
|
||||||
|
|
||||||
/*
|
|
||||||
* exception handlers
|
|
||||||
*/
|
|
||||||
.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
|
|
||||||
|
@ -24,70 +24,6 @@
|
|||||||
#include <common.h>
|
#include <common.h>
|
||||||
#include <version.h>
|
#include <version.h>
|
||||||
|
|
||||||
/*
|
|
||||||
*************************************************************************
|
|
||||||
*
|
|
||||||
* Jump vector table as in table 3.1 in [1]
|
|
||||||
*
|
|
||||||
*************************************************************************
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
.globl _start
|
|
||||||
_start:
|
|
||||||
b reset
|
|
||||||
b undefined_instruction
|
|
||||||
b software_interrupt
|
|
||||||
b prefetch_abort
|
|
||||||
b data_abort
|
|
||||||
b not_used
|
|
||||||
b irq
|
|
||||||
b fiq
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Vector table, located at address 0x20.
|
|
||||||
* This table allows the code running AFTER SPL, the U-Boot, to install it's
|
|
||||||
* interrupt handlers here. The problem is that the U-Boot is loaded into RAM,
|
|
||||||
* including it's interrupt vectoring table and the table at 0x0 is still the
|
|
||||||
* SPLs. So if interrupt happens in U-Boot, the SPLs interrupt vectoring table
|
|
||||||
* is still used.
|
|
||||||
*/
|
|
||||||
_vt_reset:
|
|
||||||
.word _reset
|
|
||||||
_vt_undefined_instruction:
|
|
||||||
.word _hang
|
|
||||||
_vt_software_interrupt:
|
|
||||||
.word _hang
|
|
||||||
_vt_prefetch_abort:
|
|
||||||
.word _hang
|
|
||||||
_vt_data_abort:
|
|
||||||
.word _hang
|
|
||||||
_vt_not_used:
|
|
||||||
.word _reset
|
|
||||||
_vt_irq:
|
|
||||||
.word _hang
|
|
||||||
_vt_fiq:
|
|
||||||
.word _hang
|
|
||||||
|
|
||||||
reset:
|
|
||||||
ldr pc, _vt_reset
|
|
||||||
undefined_instruction:
|
|
||||||
ldr pc, _vt_undefined_instruction
|
|
||||||
software_interrupt:
|
|
||||||
ldr pc, _vt_software_interrupt
|
|
||||||
prefetch_abort:
|
|
||||||
ldr pc, _vt_prefetch_abort
|
|
||||||
data_abort:
|
|
||||||
ldr pc, _vt_data_abort
|
|
||||||
not_used:
|
|
||||||
ldr pc, _vt_not_used
|
|
||||||
irq:
|
|
||||||
ldr pc, _vt_irq
|
|
||||||
fiq:
|
|
||||||
ldr pc, _vt_fiq
|
|
||||||
|
|
||||||
.balignl 16,0xdeadbeef
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
*************************************************************************
|
*************************************************************************
|
||||||
*
|
*
|
||||||
@ -101,28 +37,8 @@ fiq:
|
|||||||
*************************************************************************
|
*************************************************************************
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef CONFIG_USE_IRQ
|
.globl reset
|
||||||
/* IRQ stack memory (calculated at run-time) */
|
reset:
|
||||||
.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 memory (calculated at run-time) + 8 bytes */
|
|
||||||
.globl IRQ_STACK_START_IN
|
|
||||||
IRQ_STACK_START_IN:
|
|
||||||
.word 0x0badc0de
|
|
||||||
|
|
||||||
/*
|
|
||||||
* the actual reset code
|
|
||||||
*/
|
|
||||||
|
|
||||||
_reset:
|
|
||||||
/*
|
/*
|
||||||
* If the CPU is configured in "Wait JTAG connection mode", the stack
|
* If the CPU is configured in "Wait JTAG connection mode", the stack
|
||||||
* pointer is not configured and is zero. This will cause crash when
|
* pointer is not configured and is zero. This will cause crash when
|
||||||
@ -179,7 +95,3 @@ _reset:
|
|||||||
mov r0, #0
|
mov r0, #0
|
||||||
|
|
||||||
bx lr
|
bx lr
|
||||||
|
|
||||||
_hang:
|
|
||||||
1:
|
|
||||||
bl 1b /* hang and never return */
|
|
||||||
|
@ -17,29 +17,6 @@
|
|||||||
|
|
||||||
#include <config.h>
|
#include <config.h>
|
||||||
|
|
||||||
.globl _start
|
|
||||||
_start:
|
|
||||||
b 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
|
|
||||||
|
|
||||||
_undefined_instruction:
|
|
||||||
_software_interrupt:
|
|
||||||
_prefetch_abort:
|
|
||||||
_data_abort:
|
|
||||||
_not_used:
|
|
||||||
_irq:
|
|
||||||
_fiq:
|
|
||||||
.word infinite_loop
|
|
||||||
|
|
||||||
infinite_loop:
|
|
||||||
b infinite_loop
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
*************************************************************************
|
*************************************************************************
|
||||||
*
|
*
|
||||||
@ -53,9 +30,7 @@ infinite_loop:
|
|||||||
*************************************************************************
|
*************************************************************************
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
.globl reset
|
||||||
* the actual reset code
|
|
||||||
*/
|
|
||||||
|
|
||||||
reset:
|
reset:
|
||||||
/*
|
/*
|
||||||
|
@ -21,6 +21,7 @@ SECTIONS
|
|||||||
. = ALIGN(4);
|
. = ALIGN(4);
|
||||||
.text :
|
.text :
|
||||||
{
|
{
|
||||||
|
*(.vectors)
|
||||||
arch/arm/cpu/arm926ejs/spear/start.o (.text*)
|
arch/arm/cpu/arm926ejs/spear/start.o (.text*)
|
||||||
*(.text*)
|
*(.text*)
|
||||||
}
|
}
|
||||||
|
@ -20,75 +20,6 @@
|
|||||||
#include <common.h>
|
#include <common.h>
|
||||||
#include <version.h>
|
#include <version.h>
|
||||||
|
|
||||||
/*
|
|
||||||
*************************************************************************
|
|
||||||
*
|
|
||||||
* Jump vector table as in table 3.1 in [1]
|
|
||||||
*
|
|
||||||
*************************************************************************
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef CONFIG_SYS_DV_NOR_BOOT_CFG
|
|
||||||
.globl _start
|
|
||||||
_start:
|
|
||||||
.globl _NOR_BOOT_CFG
|
|
||||||
_NOR_BOOT_CFG:
|
|
||||||
.word CONFIG_SYS_DV_NOR_BOOT_CFG
|
|
||||||
b reset
|
|
||||||
#else
|
|
||||||
.globl _start
|
|
||||||
_start:
|
|
||||||
b reset
|
|
||||||
#endif
|
|
||||||
#ifdef CONFIG_SPL_BUILD
|
|
||||||
/* No exception handlers in preloader */
|
|
||||||
ldr pc, _hang
|
|
||||||
ldr pc, _hang
|
|
||||||
ldr pc, _hang
|
|
||||||
ldr pc, _hang
|
|
||||||
ldr pc, _hang
|
|
||||||
ldr pc, _hang
|
|
||||||
ldr pc, _hang
|
|
||||||
|
|
||||||
_hang:
|
|
||||||
.word do_hang
|
|
||||||
/* pad to 64 byte boundary */
|
|
||||||
.word 0x12345678
|
|
||||||
.word 0x12345678
|
|
||||||
.word 0x12345678
|
|
||||||
.word 0x12345678
|
|
||||||
.word 0x12345678
|
|
||||||
.word 0x12345678
|
|
||||||
.word 0x12345678
|
|
||||||
#else
|
|
||||||
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
|
|
||||||
|
|
||||||
_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 /* CONFIG_SPL_BUILD */
|
|
||||||
.balignl 16,0xdeadbeef
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
*************************************************************************
|
*************************************************************************
|
||||||
*
|
*
|
||||||
@ -102,26 +33,7 @@ _fiq:
|
|||||||
*************************************************************************
|
*************************************************************************
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef CONFIG_USE_IRQ
|
.globl reset
|
||||||
/* 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 memory (calculated at run-time) + 8 bytes */
|
|
||||||
.globl IRQ_STACK_START_IN
|
|
||||||
IRQ_STACK_START_IN:
|
|
||||||
.word 0x0badc0de
|
|
||||||
|
|
||||||
/*
|
|
||||||
* the actual reset code
|
|
||||||
*/
|
|
||||||
|
|
||||||
reset:
|
reset:
|
||||||
/*
|
/*
|
||||||
@ -198,175 +110,3 @@ flush_dcache:
|
|||||||
mov lr, ip /* restore link */
|
mov lr, ip /* restore link */
|
||||||
mov pc, lr /* back to my caller */
|
mov pc, lr /* back to my caller */
|
||||||
#endif /* CONFIG_SKIP_LOWLEVEL_INIT */
|
#endif /* CONFIG_SKIP_LOWLEVEL_INIT */
|
||||||
|
|
||||||
#ifndef CONFIG_SPL_BUILD
|
|
||||||
/*
|
|
||||||
*************************************************************************
|
|
||||||
*
|
|
||||||
* Interrupt handling
|
|
||||||
*
|
|
||||||
*************************************************************************
|
|
||||||
*/
|
|
||||||
|
|
||||||
@
|
|
||||||
@ 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 */
|
|
||||||
|
@ -19,43 +19,6 @@
|
|||||||
#include <config.h>
|
#include <config.h>
|
||||||
#include <version.h>
|
#include <version.h>
|
||||||
|
|
||||||
/*
|
|
||||||
*************************************************************************
|
|
||||||
*
|
|
||||||
* Jump vector table as in table 3.1 in [1]
|
|
||||||
*
|
|
||||||
*************************************************************************
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
.globl _start
|
|
||||||
_start:
|
|
||||||
b 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
|
|
||||||
|
|
||||||
_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
|
|
||||||
|
|
||||||
.balignl 16,0xdeadbeef
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
*************************************************************************
|
*************************************************************************
|
||||||
*
|
*
|
||||||
@ -69,26 +32,7 @@ _fiq:
|
|||||||
*************************************************************************
|
*************************************************************************
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef CONFIG_USE_IRQ
|
.globl reset
|
||||||
/* 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 memory (calculated at run-time) + 8 bytes */
|
|
||||||
.globl IRQ_STACK_START_IN
|
|
||||||
IRQ_STACK_START_IN:
|
|
||||||
.word 0x0badc0de
|
|
||||||
|
|
||||||
/*
|
|
||||||
* the actual reset code
|
|
||||||
*/
|
|
||||||
|
|
||||||
reset:
|
reset:
|
||||||
/*
|
/*
|
||||||
@ -155,166 +99,3 @@ cpu_init_crit:
|
|||||||
mov lr, ip /* restore link */
|
mov lr, ip /* restore link */
|
||||||
mov pc, lr /* back to my caller */
|
mov pc, lr /* back to my caller */
|
||||||
#endif
|
#endif
|
||||||
/*
|
|
||||||
*************************************************************************
|
|
||||||
*
|
|
||||||
* Interrupt handling
|
|
||||||
*
|
|
||||||
*************************************************************************
|
|
||||||
*/
|
|
||||||
|
|
||||||
@
|
|
||||||
@ 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
|
|
||||||
|
|
||||||
/*
|
|
||||||
* exception handlers
|
|
||||||
*/
|
|
||||||
.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
|
|
||||||
|
@ -18,42 +18,6 @@
|
|||||||
#include <config.h>
|
#include <config.h>
|
||||||
#include <version.h>
|
#include <version.h>
|
||||||
|
|
||||||
/*
|
|
||||||
*************************************************************************
|
|
||||||
*
|
|
||||||
* Jump vector table
|
|
||||||
*
|
|
||||||
*************************************************************************
|
|
||||||
*/
|
|
||||||
|
|
||||||
.globl _start
|
|
||||||
_start:
|
|
||||||
b 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
|
|
||||||
|
|
||||||
_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
|
|
||||||
|
|
||||||
.balignl 16,0xdeadbeef
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
*************************************************************************
|
*************************************************************************
|
||||||
*
|
*
|
||||||
@ -67,26 +31,7 @@ _fiq:
|
|||||||
*************************************************************************
|
*************************************************************************
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef CONFIG_USE_IRQ
|
.globl reset
|
||||||
/* 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 memory (calculated at run-time) + 8 bytes */
|
|
||||||
.globl IRQ_STACK_START_IN
|
|
||||||
IRQ_STACK_START_IN:
|
|
||||||
.word 0x0badc0de
|
|
||||||
|
|
||||||
/*
|
|
||||||
* the actual reset code
|
|
||||||
*/
|
|
||||||
|
|
||||||
reset:
|
reset:
|
||||||
/*
|
/*
|
||||||
@ -132,174 +77,3 @@ cpu_init_crit:
|
|||||||
*/
|
*/
|
||||||
mov pc, lr /* back to my caller */
|
mov pc, lr /* back to my caller */
|
||||||
#endif
|
#endif
|
||||||
/*
|
|
||||||
*************************************************************************
|
|
||||||
*
|
|
||||||
* Interrupt handling
|
|
||||||
*
|
|
||||||
*************************************************************************
|
|
||||||
*/
|
|
||||||
|
|
||||||
@
|
|
||||||
@ 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
|
|
||||||
|
|
||||||
/*
|
|
||||||
* exception handlers
|
|
||||||
*/
|
|
||||||
.align 5
|
|
||||||
.globl undefined_instruction
|
|
||||||
undefined_instruction:
|
|
||||||
get_bad_stack
|
|
||||||
bad_save_user_regs
|
|
||||||
bl do_undefined_instruction
|
|
||||||
|
|
||||||
.align 5
|
|
||||||
.globl software_interrupt
|
|
||||||
software_interrupt:
|
|
||||||
get_bad_stack
|
|
||||||
bad_save_user_regs
|
|
||||||
bl do_software_interrupt
|
|
||||||
|
|
||||||
.align 5
|
|
||||||
.globl prefetch_abort
|
|
||||||
prefetch_abort:
|
|
||||||
get_bad_stack
|
|
||||||
bad_save_user_regs
|
|
||||||
bl do_prefetch_abort
|
|
||||||
|
|
||||||
.align 5
|
|
||||||
.globl data_abort
|
|
||||||
data_abort:
|
|
||||||
get_bad_stack
|
|
||||||
bad_save_user_regs
|
|
||||||
bl do_data_abort
|
|
||||||
|
|
||||||
.align 5
|
|
||||||
.globl not_used
|
|
||||||
not_used:
|
|
||||||
get_bad_stack
|
|
||||||
bad_save_user_regs
|
|
||||||
bl do_not_used
|
|
||||||
|
|
||||||
#ifdef CONFIG_USE_IRQ
|
|
||||||
.align 5
|
|
||||||
.globl irq
|
|
||||||
irq:
|
|
||||||
get_irq_stack
|
|
||||||
irq_save_user_regs
|
|
||||||
bl do_irq
|
|
||||||
irq_restore_user_regs
|
|
||||||
|
|
||||||
.align 5
|
|
||||||
.globl fiq
|
|
||||||
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
|
|
||||||
.globl irq
|
|
||||||
irq:
|
|
||||||
get_bad_stack
|
|
||||||
bad_save_user_regs
|
|
||||||
bl do_irq
|
|
||||||
|
|
||||||
.align 5
|
|
||||||
.globl fiq
|
|
||||||
fiq:
|
|
||||||
get_bad_stack
|
|
||||||
bad_save_user_regs
|
|
||||||
bl do_fiq
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
@ -10,20 +10,7 @@
|
|||||||
/* Save the parameter pass in by previous boot loader */
|
/* Save the parameter pass in by previous boot loader */
|
||||||
.global save_boot_params
|
.global save_boot_params
|
||||||
save_boot_params:
|
save_boot_params:
|
||||||
/* save the parameter here */
|
/* no parameter to save */
|
||||||
|
|
||||||
/*
|
|
||||||
* Setup stack for exception, which is located
|
|
||||||
* at the end of on-chip RAM. We don't expect exception prior to
|
|
||||||
* relocation and if that happens, we won't worry -- it will overide
|
|
||||||
* global data region as the code will goto reset. After relocation,
|
|
||||||
* this region won't be used by other part of program.
|
|
||||||
* Hence it is safe.
|
|
||||||
*/
|
|
||||||
ldr r0, =(CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_INIT_RAM_SIZE)
|
|
||||||
ldr r1, =IRQ_STACK_START_IN
|
|
||||||
str r0, [r1]
|
|
||||||
|
|
||||||
bx lr
|
bx lr
|
||||||
|
|
||||||
|
|
||||||
|
@ -19,43 +19,6 @@
|
|||||||
#include <asm/system.h>
|
#include <asm/system.h>
|
||||||
#include <linux/linkage.h>
|
#include <linux/linkage.h>
|
||||||
|
|
||||||
.globl _start
|
|
||||||
_start: b 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
|
|
||||||
#ifdef CONFIG_SPL_BUILD
|
|
||||||
_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
|
|
||||||
_pad: .word 0x12345678 /* now 16*4=64 */
|
|
||||||
#else
|
|
||||||
.globl _undefined_instruction
|
|
||||||
_undefined_instruction: .word undefined_instruction
|
|
||||||
.globl _software_interrupt
|
|
||||||
_software_interrupt: .word software_interrupt
|
|
||||||
.globl _prefetch_abort
|
|
||||||
_prefetch_abort: .word prefetch_abort
|
|
||||||
.globl _data_abort
|
|
||||||
_data_abort: .word data_abort
|
|
||||||
.globl _not_used
|
|
||||||
_not_used: .word not_used
|
|
||||||
.globl _irq
|
|
||||||
_irq: .word irq
|
|
||||||
.globl _fiq
|
|
||||||
_fiq: .word fiq
|
|
||||||
_pad: .word 0x12345678 /* now 16*4=64 */
|
|
||||||
#endif /* CONFIG_SPL_BUILD */
|
|
||||||
|
|
||||||
.balignl 16,0xdeadbeef
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
*
|
*
|
||||||
* Startup Code (reset vector)
|
* Startup Code (reset vector)
|
||||||
@ -67,26 +30,7 @@ _pad: .word 0x12345678 /* now 16*4=64 */
|
|||||||
*
|
*
|
||||||
*************************************************************************/
|
*************************************************************************/
|
||||||
|
|
||||||
#ifdef CONFIG_USE_IRQ
|
.globl reset
|
||||||
/* 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 memory (calculated at run-time) + 8 bytes */
|
|
||||||
.globl IRQ_STACK_START_IN
|
|
||||||
IRQ_STACK_START_IN:
|
|
||||||
.word 0x0badc0de
|
|
||||||
|
|
||||||
/*
|
|
||||||
* the actual reset code
|
|
||||||
*/
|
|
||||||
|
|
||||||
reset:
|
reset:
|
||||||
bl save_boot_params
|
bl save_boot_params
|
||||||
@ -247,195 +191,3 @@ ENTRY(cpu_init_crit)
|
|||||||
b lowlevel_init @ go setup pll,mux,memory
|
b lowlevel_init @ go setup pll,mux,memory
|
||||||
ENDPROC(cpu_init_crit)
|
ENDPROC(cpu_init_crit)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef CONFIG_SPL_BUILD
|
|
||||||
/*
|
|
||||||
*************************************************************************
|
|
||||||
*
|
|
||||||
* Interrupt handling
|
|
||||||
*
|
|
||||||
*************************************************************************
|
|
||||||
*/
|
|
||||||
@
|
|
||||||
@ 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
|
|
||||||
sub sp, sp, #S_FRAME_SIZE @ carve out a frame on current
|
|
||||||
@ user stack
|
|
||||||
stmia sp, {r0 - r12} @ Save user registers (now in
|
|
||||||
@ svc mode) r0-r12
|
|
||||||
ldr r2, IRQ_STACK_START_IN @ set base 2 words into abort
|
|
||||||
@ stack
|
|
||||||
ldmia r2, {r2 - r3} @ get values for "aborted" pc
|
|
||||||
@ and cpsr (into parm regs)
|
|
||||||
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
|
|
||||||
add r8, sp, #S_PC @ !! R8 NEEDS to be saved !!
|
|
||||||
@ a reserved stack spot would
|
|
||||||
@ be good.
|
|
||||||
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 (enter
|
|
||||||
@ in banked mode)
|
|
||||||
|
|
||||||
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_bad_stack_swi
|
|
||||||
sub r13, r13, #4 @ space on current stack for
|
|
||||||
@ scratch reg.
|
|
||||||
str r0, [r13] @ save R0's value.
|
|
||||||
ldr r0, IRQ_STACK_START_IN @ get data regions start
|
|
||||||
@ spots for abort stack
|
|
||||||
str lr, [r0] @ save caller lr in position 0
|
|
||||||
@ of saved stack
|
|
||||||
mrs lr, spsr @ get the spsr
|
|
||||||
str lr, [r0, #4] @ save spsr in position 1 of
|
|
||||||
@ saved stack
|
|
||||||
ldr lr, [r0] @ restore lr
|
|
||||||
ldr r0, [r13] @ restore r0
|
|
||||||
add r13, r13, #4 @ pop stack entry
|
|
||||||
.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
|
|
||||||
|
|
||||||
/*
|
|
||||||
* exception handlers
|
|
||||||
*/
|
|
||||||
.align 5
|
|
||||||
undefined_instruction:
|
|
||||||
get_bad_stack
|
|
||||||
bad_save_user_regs
|
|
||||||
bl do_undefined_instruction
|
|
||||||
|
|
||||||
.align 5
|
|
||||||
software_interrupt:
|
|
||||||
get_bad_stack_swi
|
|
||||||
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 effective 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 /* CONFIG_USE_IRQ */
|
|
||||||
#endif /* CONFIG_SPL_BUILD */
|
|
||||||
|
@ -88,7 +88,7 @@ SECTIONS
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Zynq needs to discard more sections because the user
|
* Zynq needs to discard these sections because the user
|
||||||
* is expected to pass this image on to tools for boot.bin
|
* is expected to pass this image on to tools for boot.bin
|
||||||
* generation that require them to be dropped.
|
* generation that require them to be dropped.
|
||||||
*/
|
*/
|
||||||
|
@ -23,46 +23,6 @@
|
|||||||
#include <config.h>
|
#include <config.h>
|
||||||
#include <version.h>
|
#include <version.h>
|
||||||
|
|
||||||
.globl _start
|
|
||||||
_start: b reset
|
|
||||||
#ifdef CONFIG_SPL_BUILD
|
|
||||||
ldr pc, _hang
|
|
||||||
ldr pc, _hang
|
|
||||||
ldr pc, _hang
|
|
||||||
ldr pc, _hang
|
|
||||||
ldr pc, _hang
|
|
||||||
ldr pc, _hang
|
|
||||||
ldr pc, _hang
|
|
||||||
|
|
||||||
_hang:
|
|
||||||
.word do_hang
|
|
||||||
.word 0x12345678
|
|
||||||
.word 0x12345678
|
|
||||||
.word 0x12345678
|
|
||||||
.word 0x12345678
|
|
||||||
.word 0x12345678
|
|
||||||
.word 0x12345678
|
|
||||||
.word 0x12345678 /* now 16*4=64 */
|
|
||||||
#else
|
|
||||||
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
|
|
||||||
|
|
||||||
_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
|
|
||||||
_pad: .word 0x12345678 /* now 16*4=64 */
|
|
||||||
#endif /* CONFIG_SPL_BUILD */
|
|
||||||
|
|
||||||
.balignl 16,0xdeadbeef
|
|
||||||
/*
|
/*
|
||||||
*************************************************************************
|
*************************************************************************
|
||||||
*
|
*
|
||||||
@ -76,26 +36,7 @@ _pad: .word 0x12345678 /* now 16*4=64 */
|
|||||||
*************************************************************************
|
*************************************************************************
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef CONFIG_USE_IRQ
|
.globl reset
|
||||||
/* 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 memory (calculated at run-time) + 8 bytes */
|
|
||||||
.globl IRQ_STACK_START_IN
|
|
||||||
IRQ_STACK_START_IN:
|
|
||||||
.word 0x0badc0de
|
|
||||||
|
|
||||||
/*
|
|
||||||
* the actual reset code
|
|
||||||
*/
|
|
||||||
|
|
||||||
reset:
|
reset:
|
||||||
/*
|
/*
|
||||||
@ -166,190 +107,6 @@ cpu_init_crit:
|
|||||||
mov pc, lr /* back to my caller */
|
mov pc, lr /* back to my caller */
|
||||||
#endif /* !CONFIG_SKIP_LOWLEVEL_INIT || CONFIG_CPU_PXA25X */
|
#endif /* !CONFIG_SKIP_LOWLEVEL_INIT || CONFIG_CPU_PXA25X */
|
||||||
|
|
||||||
#ifndef CONFIG_SPL_BUILD
|
|
||||||
/*
|
|
||||||
*************************************************************************
|
|
||||||
*
|
|
||||||
* Interrupt handling
|
|
||||||
*
|
|
||||||
*************************************************************************
|
|
||||||
*/
|
|
||||||
@
|
|
||||||
@ 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
|
|
||||||
sub sp, sp, #S_FRAME_SIZE @ carve out a frame on current user stack
|
|
||||||
stmia sp, {r0 - r12} @ Save user registers (now in svc mode) r0-r12
|
|
||||||
|
|
||||||
ldr r2, IRQ_STACK_START_IN @ set base 2 words into abort stack
|
|
||||||
ldmia r2, {r2 - r3} @ get values for "aborted" pc and cpsr (into parm regs)
|
|
||||||
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
|
|
||||||
add r8, sp, #S_PC @ !!!! R8 NEEDS to be saved !!!! a reserved stack spot would be good.
|
|
||||||
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 (enter in banked mode)
|
|
||||||
|
|
||||||
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_bad_stack_swi
|
|
||||||
sub r13, r13, #4 @ space on current stack for scratch reg.
|
|
||||||
str r0, [r13] @ save R0's value.
|
|
||||||
ldr r0, IRQ_STACK_START_IN @ get data regions start
|
|
||||||
str lr, [r0] @ save caller lr in position 0 of saved stack
|
|
||||||
mrs lr, spsr @ get the spsr
|
|
||||||
str lr, [r0, #4] @ save spsr in position 1 of saved stack
|
|
||||||
ldr lr, [r0] @ restore lr
|
|
||||||
ldr r0, [r13] @ restore r0
|
|
||||||
add r13, r13, #4 @ pop stack entry
|
|
||||||
.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:
|
|
||||||
bl hang /* 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_swi
|
|
||||||
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
|
|
||||||
.align 5
|
|
||||||
#endif /* CONFIG_SPL_BUILD */
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Enable MMU to use DCache as DRAM.
|
* Enable MMU to use DCache as DRAM.
|
||||||
*
|
*
|
||||||
|
@ -13,36 +13,6 @@
|
|||||||
#include <config.h>
|
#include <config.h>
|
||||||
#include <version.h>
|
#include <version.h>
|
||||||
|
|
||||||
/*
|
|
||||||
*************************************************************************
|
|
||||||
*
|
|
||||||
* Jump vector table as in table 3.1 in [1]
|
|
||||||
*
|
|
||||||
*************************************************************************
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
.globl _start
|
|
||||||
_start: b 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
|
|
||||||
|
|
||||||
_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
|
|
||||||
|
|
||||||
.balignl 16,0xdeadbeef
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
*************************************************************************
|
*************************************************************************
|
||||||
*
|
*
|
||||||
@ -56,26 +26,7 @@ _fiq: .word fiq
|
|||||||
*************************************************************************
|
*************************************************************************
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef CONFIG_USE_IRQ
|
.globl reset
|
||||||
/* 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 memory (calculated at run-time) + 8 bytes */
|
|
||||||
.globl IRQ_STACK_START_IN
|
|
||||||
IRQ_STACK_START_IN:
|
|
||||||
.word 0x0badc0de
|
|
||||||
|
|
||||||
/*
|
|
||||||
* the actual reset code
|
|
||||||
*/
|
|
||||||
|
|
||||||
reset:
|
reset:
|
||||||
/*
|
/*
|
||||||
@ -173,167 +124,3 @@ cpu_init_crit:
|
|||||||
mcr p15, 0, r0, c8, c7, 0 /* flush v4 TLB */
|
mcr p15, 0, r0, c8, c7, 0 /* flush v4 TLB */
|
||||||
|
|
||||||
mov pc, lr
|
mov pc, lr
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
*************************************************************************
|
|
||||||
*
|
|
||||||
* Interrupt handling
|
|
||||||
*
|
|
||||||
*************************************************************************
|
|
||||||
*/
|
|
||||||
|
|
||||||
@
|
|
||||||
@ 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
|
|
||||||
sub sp, sp, #S_FRAME_SIZE
|
|
||||||
stmia sp, {r0 - r12} @ Calling r0-r12
|
|
||||||
add r8, sp, #S_PC
|
|
||||||
|
|
||||||
ldr r2, IRQ_STACK_START_IN
|
|
||||||
ldmia r2, {r2 - r4} @ get pc, cpsr, old_r0
|
|
||||||
add r0, sp, #S_FRAME_SIZE @ restore sp_SVC
|
|
||||||
|
|
||||||
add r5, sp, #S_SP
|
|
||||||
mov r1, lr
|
|
||||||
stmia r5, {r0 - r4} @ save sp_SVC, lr_SVC, pc, cpsr, old_r
|
|
||||||
mov r0, sp
|
|
||||||
.endm
|
|
||||||
|
|
||||||
.macro irq_save_user_regs
|
|
||||||
sub sp, sp, #S_FRAME_SIZE
|
|
||||||
stmia sp, {r0 - r12} @ Calling r0-r12
|
|
||||||
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 / spsr
|
|
||||||
mrs lr, spsr
|
|
||||||
str lr, [r13, #4]
|
|
||||||
|
|
||||||
mov r13, #MODE_SVC @ prepare SVC-Mode
|
|
||||||
msr spsr_c, r13
|
|
||||||
mov lr, pc
|
|
||||||
movs pc, lr
|
|
||||||
.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
|
|
||||||
|
|
||||||
/*
|
|
||||||
* exception handlers
|
|
||||||
*/
|
|
||||||
.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
|
|
||||||
|
@ -18,6 +18,7 @@ SECTIONS
|
|||||||
.text :
|
.text :
|
||||||
{
|
{
|
||||||
__image_copy_start = .;
|
__image_copy_start = .;
|
||||||
|
*(.vectors)
|
||||||
CPUDIR/start.o (.text*)
|
CPUDIR/start.o (.text*)
|
||||||
*(.text*)
|
*(.text*)
|
||||||
}
|
}
|
||||||
|
@ -18,6 +18,7 @@ SECTIONS
|
|||||||
.text :
|
.text :
|
||||||
{
|
{
|
||||||
*(.__image_copy_start)
|
*(.__image_copy_start)
|
||||||
|
*(.vectors)
|
||||||
CPUDIR/start.o (.text*)
|
CPUDIR/start.o (.text*)
|
||||||
*(.text*)
|
*(.text*)
|
||||||
}
|
}
|
||||||
|
@ -11,7 +11,7 @@ lib-$(CONFIG_USE_PRIVATE_LIBGCC) += _ashldi3.o _ashrdi3.o _divsi3.o \
|
|||||||
ifdef CONFIG_ARM64
|
ifdef CONFIG_ARM64
|
||||||
obj-y += crt0_64.o
|
obj-y += crt0_64.o
|
||||||
else
|
else
|
||||||
obj-y += crt0.o
|
obj-y += vectors.o crt0.o
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifndef CONFIG_SPL_BUILD
|
ifndef CONFIG_SPL_BUILD
|
||||||
|
291
arch/arm/lib/vectors.S
Normal file
291
arch/arm/lib/vectors.S
Normal file
@ -0,0 +1,291 @@
|
|||||||
|
/*
|
||||||
|
* vectors - Generic ARM exception table code
|
||||||
|
*
|
||||||
|
* Copyright (c) 1998 Dan Malek <dmalek@jlc.net>
|
||||||
|
* Copyright (c) 1999 Magnus Damm <kieraypc01.p.y.kie.era.ericsson.se>
|
||||||
|
* Copyright (c) 2000 Wolfgang Denk <wd@denx.de>
|
||||||
|
* Copyright (c) 2001 Alex Züpke <azu@sysgo.de>
|
||||||
|
* Copyright (c) 2001 Marius Gröger <mag@sysgo.de>
|
||||||
|
* Copyright (c) 2002 Alex Züpke <azu@sysgo.de>
|
||||||
|
* Copyright (c) 2002 Gary Jennejohn <garyj@denx.de>
|
||||||
|
* Copyright (c) 2002 Kyle Harris <kharris@nexus-tech.net>
|
||||||
|
*
|
||||||
|
* 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
|
||||||
|
|
||||||
|
_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
|
||||||
|
|
||||||
|
/*
|
||||||
|
*************************************************************************
|
||||||
|
*
|
||||||
|
* Indirect vectors table
|
||||||
|
*
|
||||||
|
* Symbols referenced here must be defined somewhere else
|
||||||
|
*
|
||||||
|
*************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
.globl _undefined_instruction
|
||||||
|
.globl _software_interrupt
|
||||||
|
.globl _prefetch_abort
|
||||||
|
.globl _data_abort
|
||||||
|
.globl _not_used
|
||||||
|
.globl _irq
|
||||||
|
.globl _fiq
|
||||||
|
|
||||||
|
_reset: .word reset
|
||||||
|
_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
|
||||||
|
|
||||||
|
.balignl 16,0xdeadbeef
|
||||||
|
|
||||||
|
/*
|
||||||
|
*************************************************************************
|
||||||
|
*
|
||||||
|
* Interrupt handling
|
||||||
|
*
|
||||||
|
*************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* SPL interrupt handling: just hang */
|
||||||
|
|
||||||
|
#ifdef CONFIG_SPL_BUILD
|
||||||
|
|
||||||
|
.align 5
|
||||||
|
undefined_instruction:
|
||||||
|
software_interrupt:
|
||||||
|
prefetch_abort:
|
||||||
|
data_abort:
|
||||||
|
not_used:
|
||||||
|
irq:
|
||||||
|
fiq:
|
||||||
|
|
||||||
|
1:
|
||||||
|
bl 1b /* hang and never return */
|
||||||
|
|
||||||
|
#else /* !CONFIG_SPL_BUILD */
|
||||||
|
|
||||||
|
/* IRQ stack memory (calculated at run-time) + 8 bytes */
|
||||||
|
.globl IRQ_STACK_START_IN
|
||||||
|
IRQ_STACK_START_IN:
|
||||||
|
.word 0x0badc0de
|
||||||
|
|
||||||
|
#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 /* CONFIG_USE_IRQ */
|
||||||
|
|
||||||
|
@
|
||||||
|
@ 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
|
||||||
|
|
||||||
|
/*
|
||||||
|
* exception handlers
|
||||||
|
*/
|
||||||
|
|
||||||
|
.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 /* CONFIG_USE_IRQ */
|
||||||
|
|
||||||
|
#endif /* CONFIG_SPL_BUILD */
|
@ -18,6 +18,7 @@ SECTIONS
|
|||||||
.text :
|
.text :
|
||||||
{
|
{
|
||||||
*(.__image_copy_start)
|
*(.__image_copy_start)
|
||||||
|
*(.vectors)
|
||||||
CPUDIR/start.o (.text*)
|
CPUDIR/start.o (.text*)
|
||||||
board/compulab/cm_t335/built-in.o (.text*)
|
board/compulab/cm_t335/built-in.o (.text*)
|
||||||
*(.text*)
|
*(.text*)
|
||||||
|
@ -22,6 +22,7 @@ SECTIONS
|
|||||||
/* WARNING - the following is hand-optimized to fit within */
|
/* WARNING - the following is hand-optimized to fit within */
|
||||||
/* the sector layout of our flash chips! XXX FIXME XXX */
|
/* the sector layout of our flash chips! XXX FIXME XXX */
|
||||||
|
|
||||||
|
* (.vectors)
|
||||||
arch/arm/cpu/arm1136/start.o (.text*)
|
arch/arm/cpu/arm1136/start.o (.text*)
|
||||||
board/freescale/mx31ads/built-in.o (.text*)
|
board/freescale/mx31ads/built-in.o (.text*)
|
||||||
arch/arm/lib/built-in.o (.text*)
|
arch/arm/lib/built-in.o (.text*)
|
||||||
|
@ -34,6 +34,7 @@ SECTIONS
|
|||||||
.text :
|
.text :
|
||||||
{
|
{
|
||||||
*(.__image_copy_start)
|
*(.__image_copy_start)
|
||||||
|
*(.vectors)
|
||||||
CPUDIR/start.o (.text*)
|
CPUDIR/start.o (.text*)
|
||||||
board/ti/am335x/built-in.o (.text*)
|
board/ti/am335x/built-in.o (.text*)
|
||||||
*(.text*)
|
*(.text*)
|
||||||
|
Loading…
Reference in New Issue
Block a user