Commit c327cf96 authored by Russell King's avatar Russell King

[ARM] Replace duplicate sets of vector code with assembler macro.

Signed-off-by: default avatarRussell King <rmk@arm.linux.org.uk>
parent 831add78
...@@ -429,186 +429,131 @@ ENTRY(__switch_to) ...@@ -429,186 +429,131 @@ ENTRY(__switch_to)
__INIT __INIT
/* /*
* Vector stubs. NOTE that we only align 'vector_irq' to a cache line boundary, * Vector stubs.
* and we rely on each stub being exactly 48 (1.5 cache lines) in size. This *
* means that we only ever load two cache lines for this code, or one if we're * This code is copied to 0x200 or 0xffff0200 so we can use branches in the
* lucky. We also copy this code to 0x200 so that we can use branches in the
* vectors, rather than ldr's. * vectors, rather than ldr's.
*
* Common stub entry macro:
* Enter in IRQ mode, spsr = SVC/USR CPSR, lr = SVC/USR PC
*/ */
.align 5 .macro vector_stub, name, sym, correction=0
.align 5
vector_\name:
ldr r13, .LCs\sym
.if \correction
sub lr, lr, #\correction
.endif
str lr, [r13] @ save lr_IRQ
mrs lr, spsr
str lr, [r13, #4] @ save spsr_IRQ
@
@ now branch to the relevant MODE handling routine
@
mrs r13, cpsr
bic r13, r13, #MODE_MASK
orr r13, r13, #MODE_SVC
msr spsr_cxsf, r13 @ switch to SVC_32 mode
and lr, lr, #15
ldr lr, [pc, lr, lsl #2]
movs pc, lr @ Changes mode and branches
.endm
__stubs_start: __stubs_start:
/* /*
* Interrupt dispatcher * Interrupt dispatcher
* Enter in IRQ mode, spsr = SVC/USR CPSR, lr = SVC/USR PC
*/ */
vector_irq: @ vector_stub irq, irq, 4
@ save mode specific registers
@ .long __irq_usr @ 0 (USR_26 / USR_32)
ldr r13, .LCsirq .long __irq_invalid @ 1 (FIQ_26 / FIQ_32)
sub lr, lr, #4 .long __irq_invalid @ 2 (IRQ_26 / IRQ_32)
str lr, [r13] @ save lr_IRQ .long __irq_svc @ 3 (SVC_26 / SVC_32)
mrs lr, spsr .long __irq_invalid @ 4
str lr, [r13, #4] @ save spsr_IRQ .long __irq_invalid @ 5
@ .long __irq_invalid @ 6
@ now branch to the relevant MODE handling routine .long __irq_invalid @ 7
@ .long __irq_invalid @ 8
mrs r13, cpsr .long __irq_invalid @ 9
bic r13, r13, #MODE_MASK .long __irq_invalid @ a
orr r13, r13, #MODE_SVC .long __irq_invalid @ b
msr spsr_cxsf, r13 @ switch to SVC_32 mode .long __irq_invalid @ c
.long __irq_invalid @ d
and lr, lr, #15 .long __irq_invalid @ e
ldr lr, [pc, lr, lsl #2] .long __irq_invalid @ f
movs pc, lr @ Changes mode and branches
.LCtab_irq: .word __irq_usr @ 0 (USR_26 / USR_32)
.word __irq_invalid @ 1 (FIQ_26 / FIQ_32)
.word __irq_invalid @ 2 (IRQ_26 / IRQ_32)
.word __irq_svc @ 3 (SVC_26 / SVC_32)
.word __irq_invalid @ 4
.word __irq_invalid @ 5
.word __irq_invalid @ 6
.word __irq_invalid @ 7
.word __irq_invalid @ 8
.word __irq_invalid @ 9
.word __irq_invalid @ a
.word __irq_invalid @ b
.word __irq_invalid @ c
.word __irq_invalid @ d
.word __irq_invalid @ e
.word __irq_invalid @ f
.align 5
/* /*
* Data abort dispatcher - dispatches it to the correct handler for the processor mode * Data abort dispatcher
* Enter in ABT mode, spsr = USR CPSR, lr = USR PC * Enter in ABT mode, spsr = USR CPSR, lr = USR PC
*/ */
vector_dabt: @ vector_stub dabt, abt, 8
@ save mode specific registers
@ .long __dabt_usr @ 0 (USR_26 / USR_32)
ldr r13, .LCsabt .long __dabt_invalid @ 1 (FIQ_26 / FIQ_32)
sub lr, lr, #8 .long __dabt_invalid @ 2 (IRQ_26 / IRQ_32)
str lr, [r13] .long __dabt_svc @ 3 (SVC_26 / SVC_32)
mrs lr, spsr .long __dabt_invalid @ 4
str lr, [r13, #4] .long __dabt_invalid @ 5
@ .long __dabt_invalid @ 6
@ now branch to the relevant MODE handling routine .long __dabt_invalid @ 7
@ .long __dabt_invalid @ 8
mrs r13, cpsr .long __dabt_invalid @ 9
bic r13, r13, #MODE_MASK .long __dabt_invalid @ a
orr r13, r13, #MODE_SVC .long __dabt_invalid @ b
msr spsr_cxsf, r13 @ switch to SVC_32 mode .long __dabt_invalid @ c
.long __dabt_invalid @ d
and lr, lr, #15 .long __dabt_invalid @ e
ldr lr, [pc, lr, lsl #2] .long __dabt_invalid @ f
movs pc, lr @ Changes mode and branches
.LCtab_dabt: .word __dabt_usr @ 0 (USR_26 / USR_32)
.word __dabt_invalid @ 1 (FIQ_26 / FIQ_32)
.word __dabt_invalid @ 2 (IRQ_26 / IRQ_32)
.word __dabt_svc @ 3 (SVC_26 / SVC_32)
.word __dabt_invalid @ 4
.word __dabt_invalid @ 5
.word __dabt_invalid @ 6
.word __dabt_invalid @ 7
.word __dabt_invalid @ 8
.word __dabt_invalid @ 9
.word __dabt_invalid @ a
.word __dabt_invalid @ b
.word __dabt_invalid @ c
.word __dabt_invalid @ d
.word __dabt_invalid @ e
.word __dabt_invalid @ f
.align 5
/* /*
* Prefetch abort dispatcher - dispatches it to the correct handler for the processor mode * Prefetch abort dispatcher
* Enter in ABT mode, spsr = USR CPSR, lr = USR PC * Enter in ABT mode, spsr = USR CPSR, lr = USR PC
*/ */
vector_pabt: vector_stub pabt, abt, 4
@
@ save mode specific registers .long __pabt_usr @ 0 (USR_26 / USR_32)
@ .long __pabt_invalid @ 1 (FIQ_26 / FIQ_32)
ldr r13, .LCsabt .long __pabt_invalid @ 2 (IRQ_26 / IRQ_32)
sub lr, lr, #4 .long __pabt_svc @ 3 (SVC_26 / SVC_32)
str lr, [r13] @ save lr_ABT .long __pabt_invalid @ 4
mrs lr, spsr .long __pabt_invalid @ 5
str lr, [r13, #4] @ save spsr_ABT .long __pabt_invalid @ 6
@ .long __pabt_invalid @ 7
@ now branch to the relevant MODE handling routine .long __pabt_invalid @ 8
@ .long __pabt_invalid @ 9
mrs r13, cpsr .long __pabt_invalid @ a
bic r13, r13, #MODE_MASK .long __pabt_invalid @ b
orr r13, r13, #MODE_SVC .long __pabt_invalid @ c
msr spsr_cxsf, r13 @ switch to SVC_32 mode .long __pabt_invalid @ d
.long __pabt_invalid @ e
ands lr, lr, #15 .long __pabt_invalid @ f
ldr lr, [pc, lr, lsl #2]
movs pc, lr
.LCtab_pabt: .word __pabt_usr @ 0 (USR_26 / USR_32)
.word __pabt_invalid @ 1 (FIQ_26 / FIQ_32)
.word __pabt_invalid @ 2 (IRQ_26 / IRQ_32)
.word __pabt_svc @ 3 (SVC_26 / SVC_32)
.word __pabt_invalid @ 4
.word __pabt_invalid @ 5
.word __pabt_invalid @ 6
.word __pabt_invalid @ 7
.word __pabt_invalid @ 8
.word __pabt_invalid @ 9
.word __pabt_invalid @ a
.word __pabt_invalid @ b
.word __pabt_invalid @ c
.word __pabt_invalid @ d
.word __pabt_invalid @ e
.word __pabt_invalid @ f
.align 5
/* /*
* Undef instr entry dispatcher - dispatches it to the correct handler for the processor mode * Undef instr entry dispatcher
* Enter in UND mode, spsr = SVC/USR CPSR, lr = SVC/USR PC * Enter in UND mode, spsr = SVC/USR CPSR, lr = SVC/USR PC
*/ */
vector_und: vector_stub und, und
@
@ save mode specific registers .long __und_usr @ 0 (USR_26 / USR_32)
@ .long __und_invalid @ 1 (FIQ_26 / FIQ_32)
ldr r13, .LCsund .long __und_invalid @ 2 (IRQ_26 / IRQ_32)
str lr, [r13] @ save lr_UND .long __und_svc @ 3 (SVC_26 / SVC_32)
mrs lr, spsr .long __und_invalid @ 4
str lr, [r13, #4] @ save spsr_UND .long __und_invalid @ 5
@ .long __und_invalid @ 6
@ now branch to the relevant MODE handling routine .long __und_invalid @ 7
@ .long __und_invalid @ 8
mrs r13, cpsr .long __und_invalid @ 9
bic r13, r13, #MODE_MASK .long __und_invalid @ a
orr r13, r13, #MODE_SVC .long __und_invalid @ b
msr spsr_cxsf, r13 @ switch to SVC_32 mode .long __und_invalid @ c
.long __und_invalid @ d
and lr, lr, #15 .long __und_invalid @ e
ldr lr, [pc, lr, lsl #2] .long __und_invalid @ f
movs pc, lr @ Changes mode and branches
.align 5
.LCtab_und: .word __und_usr @ 0 (USR_26 / USR_32)
.word __und_invalid @ 1 (FIQ_26 / FIQ_32)
.word __und_invalid @ 2 (IRQ_26 / IRQ_32)
.word __und_svc @ 3 (SVC_26 / SVC_32)
.word __und_invalid @ 4
.word __und_invalid @ 5
.word __und_invalid @ 6
.word __und_invalid @ 7
.word __und_invalid @ 8
.word __und_invalid @ 9
.word __und_invalid @ a
.word __und_invalid @ b
.word __und_invalid @ c
.word __und_invalid @ d
.word __und_invalid @ e
.word __und_invalid @ f
.align 5
/*============================================================================= /*=============================================================================
* Undefined FIQs * Undefined FIQs
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment