armv7-a/r: use SRS and RFE for exception handler
This commit is contained in:
parent
8b8534c4b4
commit
3b889d820f
@ -66,10 +66,8 @@
|
||||
#define REG_R12 (12)
|
||||
#define REG_R13 (13)
|
||||
#define REG_R14 (14)
|
||||
#define REG_R15 (15)
|
||||
#define REG_CPSR (16)
|
||||
|
||||
#define ARM_CONTEXT_REGS (17)
|
||||
#define ARM_CONTEXT_REGS (15)
|
||||
|
||||
/* If the MCU supports a floating point unit, then it will be necessary
|
||||
* to save the state of the FPU status register and data registers on
|
||||
@ -162,9 +160,12 @@
|
||||
# define FPU_CONTEXT_REGS (0)
|
||||
#endif
|
||||
|
||||
#define REG_R15 (ARM_CONTEXT_REGS + FPU_CONTEXT_REGS)
|
||||
#define REG_CPSR (REG_R15 + 1)
|
||||
|
||||
/* The total number of registers saved by software */
|
||||
|
||||
#define XCPTCONTEXT_REGS (ARM_CONTEXT_REGS + FPU_CONTEXT_REGS)
|
||||
#define XCPTCONTEXT_REGS (REG_CPSR + 1)
|
||||
#define XCPTCONTEXT_SIZE (4 * XCPTCONTEXT_REGS)
|
||||
|
||||
/* Friendly register names */
|
||||
|
@ -66,10 +66,8 @@
|
||||
#define REG_R12 (12)
|
||||
#define REG_R13 (13)
|
||||
#define REG_R14 (14)
|
||||
#define REG_R15 (15)
|
||||
#define REG_CPSR (16)
|
||||
|
||||
#define ARM_CONTEXT_REGS (17)
|
||||
#define ARM_CONTEXT_REGS (15)
|
||||
|
||||
/* If the MCU supports a floating point unit, then it will be necessary
|
||||
* to save the state of the FPU status register and data registers on
|
||||
@ -162,9 +160,12 @@
|
||||
# define FPU_CONTEXT_REGS (0)
|
||||
#endif
|
||||
|
||||
#define REG_R15 (ARM_CONTEXT_REGS + FPU_CONTEXT_REGS)
|
||||
#define REG_CPSR (REG_R15 + 1)
|
||||
|
||||
/* The total number of registers saved by software */
|
||||
|
||||
#define XCPTCONTEXT_REGS (ARM_CONTEXT_REGS + FPU_CONTEXT_REGS)
|
||||
#define XCPTCONTEXT_REGS (REG_CPSR + 1)
|
||||
#define XCPTCONTEXT_SIZE (4 * XCPTCONTEXT_REGS)
|
||||
|
||||
/* Friendly register names */
|
||||
|
@ -171,6 +171,12 @@
|
||||
.type arm_vectorirq, %function
|
||||
|
||||
arm_vectorirq:
|
||||
|
||||
/* Save the LR and SPSR onto the SYS mode stack before switch. */
|
||||
|
||||
sub lr, lr, #4
|
||||
srsdb sp, #PSR_MODE_SYS
|
||||
|
||||
/* Switch to SYS mode */
|
||||
|
||||
#ifdef CONFIG_ARMV7A_DECODEFIQ
|
||||
@ -186,24 +192,15 @@ arm_vectorirq:
|
||||
sub sp, sp, #XCPTCONTEXT_SIZE
|
||||
stmia sp, {r0-r12} /* Save the SYS mode regs */
|
||||
|
||||
cps #PSR_MODE_IRQ /* Switch back IRQ mode */
|
||||
|
||||
/* Get the values for r15(pc) and CPSR in r3 and r4 */
|
||||
|
||||
sub r3, lr, #4
|
||||
mrs r4, spsr
|
||||
|
||||
cps #PSR_MODE_SYS /* Then switch back to SYS mode */
|
||||
|
||||
/* Get the correct values of USR/SYS r13(sp) and r14(lr) in r1 and r2 */
|
||||
|
||||
add r1, sp, #XCPTCONTEXT_SIZE
|
||||
mov r2, r14
|
||||
|
||||
/* Save r13(sp), r14(lr), r15(pc), and the CPSR */
|
||||
/* Save r13(sp), r14(lr) */
|
||||
|
||||
add r0, sp, #(4*REG_SP) /* Offset to pc, cpsr storage */
|
||||
stmia r0, {r1-r4}
|
||||
stmia r0, {r1-r2}
|
||||
|
||||
#ifdef CONFIG_ARCH_FPU
|
||||
/* Save the state of the floating point registers. */
|
||||
@ -265,18 +262,16 @@ arm_vectorirq:
|
||||
* context switch is required.
|
||||
*/
|
||||
|
||||
/* Restore the CPSR, IRQ mode registers and return */
|
||||
|
||||
ldr r1, [r0, #(4*REG_CPSR)] /* Fetch the return SPSR */
|
||||
msr spsr_cxsf, r1 /* Set the return mode SPSR */
|
||||
|
||||
/* Life is simple when everything is IRQ mode */
|
||||
|
||||
mov r14, r0 /* (IRQ) r14=Register storage area */
|
||||
ldmia r14!, {r0-r12} /* Restore common r0-r12 */
|
||||
ldmia r14, {r13, r14}^ /* Restore user mode r13/r14 */
|
||||
add r14, r14, #(4*2) /* (IRQ) r14=address of r15 storage */
|
||||
ldmia r14, {r15}^ /* Return */
|
||||
|
||||
/* Restore the CPSR, SYS mode registers and return. */
|
||||
|
||||
add r14, r14, #(4*(REG_R15-REG_R13))
|
||||
rfeia r14
|
||||
|
||||
#if !defined(CONFIG_SMP) && CONFIG_ARCH_INTERRUPTSTACK > 7
|
||||
.Lirqstacktop:
|
||||
@ -299,6 +294,11 @@ arm_vectorirq:
|
||||
.type arm_vectorsvc, %function
|
||||
|
||||
arm_vectorsvc:
|
||||
|
||||
/* Save the LR and SPSR onto the SYS mode stack before switch. */
|
||||
|
||||
srsdb sp, #PSR_MODE_SYS
|
||||
|
||||
/* Switch to SYS mode */
|
||||
|
||||
#ifdef CONFIG_ARMV7A_DECODEFIQ
|
||||
@ -314,24 +314,15 @@ arm_vectorsvc:
|
||||
sub sp, sp, #XCPTCONTEXT_SIZE
|
||||
stmia sp, {r0-r12} /* Save the SYS mode regs */
|
||||
|
||||
cps #PSR_MODE_SVC /* Switch back SVC mode */
|
||||
|
||||
/* Get the values for r15(pc) and CPSR in r3 and r4 */
|
||||
|
||||
mov r3, r14 /* Save r14 as the PC as well */
|
||||
mrs r4, spsr /* Get the saved CPSR */
|
||||
|
||||
cps #PSR_MODE_SYS /* Then switch back to SYS mode */
|
||||
|
||||
/* Get the correct values of USR/SYS r13(sp) and r14(lr) in r1 and r2 */
|
||||
|
||||
add r1, sp, #XCPTCONTEXT_SIZE
|
||||
mov r2, r14
|
||||
|
||||
/* Save r13(sp), r14(lr), r15(pc), and the CPSR */
|
||||
/* Save r13(sp), r14(lr) */
|
||||
|
||||
add r0, sp, #(4*REG_SP) /* Offset to pc, cpsr storage */
|
||||
stmia r0, {r1-r4}
|
||||
stmia r0, {r1-r2}
|
||||
|
||||
#ifdef CONFIG_ARCH_FPU
|
||||
/* Save the state of the floating point registers. */
|
||||
@ -395,18 +386,16 @@ arm_vectorsvc:
|
||||
* context switch is required.
|
||||
*/
|
||||
|
||||
/* Restore the CPSR, SYS mode registers and return */
|
||||
|
||||
ldr r1, [r0, #(4*REG_CPSR)] /* Fetch the return SPSR */
|
||||
msr spsr_cxsf, r1 /* Set the return mode SPSR */
|
||||
|
||||
/* Life is simple when everything is SVC mode */
|
||||
|
||||
mov r14, r0 /* (SVC) r14=Register storage area */
|
||||
ldmia r14!, {r0-r12} /* Restore common r0-r12 */
|
||||
ldmia r14, {r13, r14}^ /* Restore user mode r13/r14 */
|
||||
add r14, r14, #(4*2) /* (SVC) r14=address of r15 storage */
|
||||
ldmia r14, {r15}^ /* Return */
|
||||
|
||||
/* Restore the CPSR, SYS mode registers and return. */
|
||||
|
||||
add r14, r14, #(4*(REG_R15-REG_R13))
|
||||
rfeia r14
|
||||
.size arm_vectorsvc, . - arm_vectorsvc
|
||||
|
||||
.align 5
|
||||
@ -427,6 +416,12 @@ arm_vectorsvc:
|
||||
.type arm_vectordata, %function
|
||||
|
||||
arm_vectordata:
|
||||
|
||||
/* Save the LR and SPSR onto the SYS mode stack before switch. */
|
||||
|
||||
sub lr, lr, #8
|
||||
srsdb sp, #PSR_MODE_SYS
|
||||
|
||||
/* Switch to SYS mode */
|
||||
|
||||
#ifdef CONFIG_ARMV7A_DECODEFIQ
|
||||
@ -442,24 +437,15 @@ arm_vectordata:
|
||||
sub sp, sp, #XCPTCONTEXT_SIZE
|
||||
stmia sp, {r0-r12} /* Save the SYS mode regs */
|
||||
|
||||
cps #PSR_MODE_ABT /* Switch back ABT mode */
|
||||
|
||||
/* Get the values for r15(pc) and CPSR in r3 and r4 */
|
||||
|
||||
sub r3, lr, #8
|
||||
mrs r4, spsr
|
||||
|
||||
cps #PSR_MODE_SYS /* Then switch back to SYS mode */
|
||||
|
||||
/* Get the correct values of USR/SYS r13(sp) and r14(lr) in r1 and r2 */
|
||||
|
||||
add r1, sp, #XCPTCONTEXT_SIZE
|
||||
mov r2, r14
|
||||
|
||||
/* Save r13(sp), r14(lr), r15(pc), and the CPSR */
|
||||
/* Save r13(sp), r14(lr) */
|
||||
|
||||
add r0, sp, #(4*REG_SP) /* Offset to pc, cpsr storage */
|
||||
stmia r0, {r1-r4}
|
||||
stmia r0, {r1-r2}
|
||||
|
||||
#ifdef CONFIG_ARCH_FPU
|
||||
/* Save the state of the floating point registers. */
|
||||
@ -498,18 +484,16 @@ arm_vectordata:
|
||||
* context switch is required.
|
||||
*/
|
||||
|
||||
/* Restore the CPSR, ABT mode registers and return */
|
||||
|
||||
ldr r1, [r0, #(4*REG_CPSR)] /* Fetch the return SPSR */
|
||||
msr spsr_cxsf, r1 /* Set the return mode SPSR */
|
||||
|
||||
/* Life is simple when everything is ABT mode */
|
||||
|
||||
mov r14, r0 /* (ABT) r14=Register storage area */
|
||||
ldmia r14!, {r0-r12} /* Restore common r0-r12 */
|
||||
ldmia r14, {r13, r14}^ /* Restore user mode r13/r14 */
|
||||
add r14, r14, #(4*2) /* (ABT) r14=address of r15 storage */
|
||||
ldmia r14, {r15}^ /* Return */
|
||||
|
||||
/* Restore the CPSR, SYS mode registers and return. */
|
||||
|
||||
add r14, r14, #(4*(REG_R15-REG_R13))
|
||||
rfeia r14
|
||||
.size arm_vectordata, . - arm_vectordata
|
||||
|
||||
.align 5
|
||||
@ -530,6 +514,12 @@ arm_vectordata:
|
||||
.type arm_vectorprefetch, %function
|
||||
|
||||
arm_vectorprefetch:
|
||||
|
||||
/* Save the LR and SPSR onto the SYS mode stack before switch. */
|
||||
|
||||
sub lr, lr, #4
|
||||
srsdb sp, #PSR_MODE_SYS
|
||||
|
||||
cpsid if, #PSR_MODE_SYS /* Switch to SYS mode */
|
||||
|
||||
/* Create a context structure. First set aside a stack frame
|
||||
@ -539,24 +529,15 @@ arm_vectorprefetch:
|
||||
sub sp, sp, #XCPTCONTEXT_SIZE
|
||||
stmia sp, {r0-r12} /* Save the SYS mode regs */
|
||||
|
||||
cps #PSR_MODE_ABT /* Switch back ABT mode */
|
||||
|
||||
/* Get the values for r15(pc) and CPSR in r3 and r4 */
|
||||
|
||||
sub r3, lr, #4
|
||||
mrs r4, spsr
|
||||
|
||||
cps #PSR_MODE_SYS /* Then switch back to SYS mode */
|
||||
|
||||
/* Get the correct values of USR/SYS r13(sp) and r14(lr) in r1 and r2 */
|
||||
|
||||
add r1, sp, #XCPTCONTEXT_SIZE
|
||||
mov r2, r14
|
||||
|
||||
/* Save r13(sp), r14(lr), r15(pc), and the CPSR */
|
||||
/* Save r13(sp), r14(lr) */
|
||||
|
||||
add r0, sp, #(4*REG_SP) /* Offset to pc, cpsr storage */
|
||||
stmia r0, {r1-r4}
|
||||
stmia r0, {r1-r2}
|
||||
|
||||
#ifdef CONFIG_ARCH_FPU
|
||||
/* Save the state of the floating point registers. */
|
||||
@ -595,18 +576,16 @@ arm_vectorprefetch:
|
||||
* context switch is required.
|
||||
*/
|
||||
|
||||
/* Restore the CPSR, ABT mode registers and return */
|
||||
|
||||
ldr r1, [r0, #(4*REG_CPSR)] /* Fetch the return SPSR */
|
||||
msr spsr_cxsf, r1 /* Set the return mode SPSR */
|
||||
|
||||
/* Life is simple when everything is ABT mode */
|
||||
|
||||
mov r14, r0 /* (ABT) r14=Register storage area */
|
||||
ldmia r14!, {r0-r12} /* Restore common r0-r12 */
|
||||
ldmia r14, {r13, r14}^ /* Restore user mode r13/r14 */
|
||||
add r14, r14, #(4*2) /* (ABT) r14=address of r15 storage */
|
||||
ldmia r14, {r15}^ /* Return */
|
||||
|
||||
/* Restore the CPSR, SYS mode registers and return. */
|
||||
|
||||
add r14, r14, #(4*(REG_R15-REG_R13))
|
||||
rfeia r14
|
||||
.size arm_vectorprefetch, . - arm_vectorprefetch
|
||||
|
||||
.align 5
|
||||
@ -625,6 +604,11 @@ arm_vectorprefetch:
|
||||
.type arm_vectorundefinsn, %function
|
||||
|
||||
arm_vectorundefinsn:
|
||||
|
||||
/* Save the LR and SPSR onto the SYS mode stack before switch. */
|
||||
|
||||
srsdb sp, #PSR_MODE_SYS
|
||||
|
||||
cpsid if, #PSR_MODE_SYS /* Switch to SYS mode */
|
||||
|
||||
/* Create a context structure. First set aside a stack frame
|
||||
@ -634,24 +618,15 @@ arm_vectorundefinsn:
|
||||
sub sp, sp, #XCPTCONTEXT_SIZE
|
||||
stmia sp, {r0-r12} /* Save the SYS mode regs */
|
||||
|
||||
cps #PSR_MODE_UND /* Switch back UND mode */
|
||||
|
||||
/* Get the values for r15(pc) and CPSR in r3 and r4 */
|
||||
|
||||
mov r3, lr
|
||||
mrs r4, spsr
|
||||
|
||||
cps #PSR_MODE_SYS /* Then switch back to SYS mode */
|
||||
|
||||
/* Get the correct values of USR/SYS r13(sp) and r14(lr) in r1 and r2 */
|
||||
|
||||
add r1, sp, #XCPTCONTEXT_SIZE
|
||||
mov r2, r14
|
||||
|
||||
/* Save r13(sp), r14(lr), r15(pc), and the CPSR */
|
||||
/* Save r13(sp), r14(lr) */
|
||||
|
||||
add r0, sp, #(4*REG_SP) /* Offset to pc, cpsr storage */
|
||||
stmia r0, {r1-r4}
|
||||
stmia r0, {r1-r2}
|
||||
|
||||
#ifdef CONFIG_ARCH_FPU
|
||||
/* Save the state of the floating point registers. */
|
||||
@ -688,18 +663,16 @@ arm_vectorundefinsn:
|
||||
* context switch is required.
|
||||
*/
|
||||
|
||||
/* Restore the CPSR, UND mode registers and return */
|
||||
|
||||
ldr r1, [r0, #(4*REG_CPSR)] /* Fetch the return SPSR */
|
||||
msr spsr_cxsf, r1 /* Set the return mode SPSR */
|
||||
|
||||
/* Life is simple when everything is UND mode */
|
||||
|
||||
mov r14, r0 /* (UND) r14=Register storage area */
|
||||
ldmia r14!, {r0-r12} /* Restore common r0-r12 */
|
||||
ldmia r14, {r13, r14}^ /* Restore user mode r13/r14 */
|
||||
add r14, r14, #(4*2) /* (UND) r14=address of r15 storage */
|
||||
ldmia r14, {r15}^ /* Return */
|
||||
|
||||
/* Restore the CPSR, SYS mode registers and return. */
|
||||
|
||||
add r14, r14, #(4*(REG_R15-REG_R13))
|
||||
rfeia r14
|
||||
.size arm_vectorundefinsn, . - arm_vectorundefinsn
|
||||
|
||||
.align 5
|
||||
@ -721,6 +694,12 @@ arm_vectorundefinsn:
|
||||
|
||||
arm_vectorfiq:
|
||||
#ifdef CONFIG_ARMV7A_DECODEFIQ
|
||||
|
||||
/* Save the LR and SPSR onto the SYS mode stack before switch. */
|
||||
|
||||
sub lr, lr, #4
|
||||
srsdb sp, #PSR_MODE_SYS
|
||||
|
||||
cpsid if, #PSR_MODE_SYS /* Switch to SYS mode */
|
||||
|
||||
/* Create a context structure. First set aside a stack frame
|
||||
@ -730,24 +709,15 @@ arm_vectorfiq:
|
||||
sub sp, sp, #XCPTCONTEXT_SIZE
|
||||
stmia sp, {r0-r12} /* Save the SYS mode regs */
|
||||
|
||||
cps #PSR_MODE_FIQ /* Switch back FIQ mode */
|
||||
|
||||
/* Get the values for r15(pc) and CPSR in r3 and r4 */
|
||||
|
||||
sub r3, lr, #4
|
||||
mrs r4, spsr
|
||||
|
||||
cps #PSR_MODE_SYS /* Then switch back to SYS mode */
|
||||
|
||||
/* Get the correct values of USR/SYS r13(sp) and r14(lr) in r1 and r2 */
|
||||
|
||||
add r1, sp, #XCPTCONTEXT_SIZE
|
||||
mov r2, r14
|
||||
|
||||
/* Save r13(sp), r14(lr), r15(pc), and the CPSR */
|
||||
/* Save r13(sp), r14(lr) */
|
||||
|
||||
add r0, sp, #(4*REG_SP) /* Offset to pc, cpsr storage */
|
||||
stmia r0, {r1-r4}
|
||||
stmia r0, {r1-r2}
|
||||
|
||||
#ifdef CONFIG_ARCH_FPU
|
||||
/* Save the state of the floating point registers. */
|
||||
@ -796,18 +766,16 @@ arm_vectorfiq:
|
||||
* context switch is required.
|
||||
*/
|
||||
|
||||
/* Restore the CPSR, FIQ mode registers and return */
|
||||
|
||||
ldr r1, [r0, #(4*REG_CPSR)] /* Fetch the return SPSR */
|
||||
msr spsr_cxsf, r1 /* Set the return mode SPSR */
|
||||
|
||||
/* Life is simple when everything is FIQ mode */
|
||||
|
||||
mov r14, r0 /* (FIQ) r14=Register storage area */
|
||||
ldmia r14!, {r0-r7} /* Restore common r0-r7 */
|
||||
ldmia r14, {r8-r14}^ /* Restore user mode r8-r14 */
|
||||
add r14, r14, #(4*7) /* (FIQ) r14=address of r15 storage */
|
||||
ldmia r14, {r15}^ /* Return */
|
||||
|
||||
/* Restore the CPSR, SYS mode registers and return. */
|
||||
|
||||
add r14, r14, #(4*(REG_R15-REG_R13))
|
||||
rfeia r14
|
||||
|
||||
#if !defined(CONFIG_SMP) && CONFIG_ARCH_INTERRUPTSTACK > 7
|
||||
.Lfiqstacktop:
|
||||
|
@ -125,6 +125,12 @@
|
||||
.type arm_vectorirq, %function
|
||||
|
||||
arm_vectorirq:
|
||||
|
||||
/* Save the LR and SPSR onto the SYS mode stack before switch. */
|
||||
|
||||
sub lr, lr, #4
|
||||
srsdb sp, #PSR_MODE_SYS
|
||||
|
||||
/* Switch to SYS mode */
|
||||
|
||||
#ifdef CONFIG_ARMV7A_DECODEFIQ
|
||||
@ -140,24 +146,15 @@ arm_vectorirq:
|
||||
sub sp, sp, #XCPTCONTEXT_SIZE
|
||||
stmia sp, {r0-r12} /* Save the SYS mode regs */
|
||||
|
||||
cps #PSR_MODE_IRQ /* Switch back IRQ mode */
|
||||
|
||||
/* Get the values for r15(pc) and CPSR in r3 and r4 */
|
||||
|
||||
sub r3, lr, #4
|
||||
mrs r4, spsr
|
||||
|
||||
cps #PSR_MODE_SYS /* Then switch back to SYS mode */
|
||||
|
||||
/* Get the correct values of USR/SYS r13(sp) and r14(lr) in r1 and r2 */
|
||||
|
||||
add r1, sp, #XCPTCONTEXT_SIZE
|
||||
mov r2, r14
|
||||
|
||||
/* Save r13(sp), r14(lr), r15(pc), and the CPSR */
|
||||
/* Save r13(sp), r14(lr) */
|
||||
|
||||
add r0, sp, #(4*REG_SP) /* Offset to pc, cpsr storage */
|
||||
stmia r0, {r1-r4}
|
||||
stmia r0, {r1-r2}
|
||||
|
||||
#ifdef CONFIG_ARCH_FPU
|
||||
/* Save the state of the floating point registers. */
|
||||
@ -219,18 +216,16 @@ arm_vectorirq:
|
||||
* context switch is required.
|
||||
*/
|
||||
|
||||
/* Restore the CPSR, IRQ mode registers and return */
|
||||
|
||||
ldr r1, [r0, #(4*REG_CPSR)] /* Fetch the return SPSR */
|
||||
msr spsr_cxsf, r1 /* Set the return mode SPSR */
|
||||
|
||||
/* Life is simple when everything is IRQ mode */
|
||||
|
||||
mov r14, r0 /* (IRQ) r14=Register storage area */
|
||||
ldmia r14!, {r0-r12} /* Restore common r0-r12 */
|
||||
ldmia r14, {r13, r14}^ /* Restore user mode r13/r14 */
|
||||
add r14, r14, #(4*2) /* (IRQ) r14=address of r15 storage */
|
||||
ldmia r14, {r15}^ /* Return */
|
||||
|
||||
/* Restore the CPSR, SYS mode registers and return. */
|
||||
|
||||
add r14, r14, #(4*(REG_R15-REG_R13))
|
||||
rfeia r14
|
||||
|
||||
#if CONFIG_ARCH_INTERRUPTSTACK > 7
|
||||
.Lirqstacktop:
|
||||
@ -253,6 +248,11 @@ arm_vectorirq:
|
||||
.type arm_vectorsvc, %function
|
||||
|
||||
arm_vectorsvc:
|
||||
|
||||
/* Save the LR and SPSR onto the SYS mode stack before switch. */
|
||||
|
||||
srsdb sp, #PSR_MODE_SYS
|
||||
|
||||
/* Switch to SYS mode */
|
||||
|
||||
#ifdef CONFIG_ARMV7A_DECODEFIQ
|
||||
@ -268,24 +268,15 @@ arm_vectorsvc:
|
||||
sub sp, sp, #XCPTCONTEXT_SIZE
|
||||
stmia sp, {r0-r12} /* Save the SYS mode regs */
|
||||
|
||||
cps #PSR_MODE_SVC /* Switch back SVC mode */
|
||||
|
||||
/* Get the values for r15(pc) and CPSR in r3 and r4 */
|
||||
|
||||
mov r3, r14 /* Save r14 as the PC as well */
|
||||
mrs r4, spsr /* Get the saved CPSR */
|
||||
|
||||
cps #PSR_MODE_SYS /* Then switch back to SYS mode */
|
||||
|
||||
/* Get the correct values of USR/SYS r13(sp) and r14(lr) in r1 and r2 */
|
||||
|
||||
add r1, sp, #XCPTCONTEXT_SIZE
|
||||
mov r2, r14
|
||||
|
||||
/* Save r13(sp), r14(lr), r15(pc), and the CPSR */
|
||||
/* Save r13(sp), r14(lr) */
|
||||
|
||||
add r0, sp, #(4*REG_SP) /* Offset to pc, cpsr storage */
|
||||
stmia r0, {r1-r4}
|
||||
stmia r0, {r1-r2}
|
||||
|
||||
#ifdef CONFIG_ARCH_FPU
|
||||
/* Save the state of the floating point registers. */
|
||||
@ -349,18 +340,16 @@ arm_vectorsvc:
|
||||
* context switch is required.
|
||||
*/
|
||||
|
||||
/* Restore the CPSR, SYS mode registers and return */
|
||||
|
||||
ldr r1, [r0, #(4*REG_CPSR)] /* Fetch the return SPSR */
|
||||
msr spsr_cxsf, r1 /* Set the return mode SPSR */
|
||||
|
||||
/* Life is simple when everything is SVC mode */
|
||||
|
||||
mov r14, r0 /* (SVC) r14=Register storage area */
|
||||
ldmia r14!, {r0-r12} /* Restore common r0-r12 */
|
||||
ldmia r14, {r13, r14}^ /* Restore user mode r13/r14 */
|
||||
add r14, r14, #(4*2) /* (SVC) r14=address of r15 storage */
|
||||
ldmia r14, {r15}^ /* Return */
|
||||
|
||||
/* Restore the CPSR, SYS mode registers and return. */
|
||||
|
||||
add r14, r14, #(4*(REG_R15-REG_R13))
|
||||
rfeia r14
|
||||
.size arm_vectorsvc, . - arm_vectorsvc
|
||||
|
||||
.align 5
|
||||
@ -381,6 +370,12 @@ arm_vectorsvc:
|
||||
.type arm_vectordata, %function
|
||||
|
||||
arm_vectordata:
|
||||
|
||||
/* Save the LR and SPSR onto the SYS mode stack before switch. */
|
||||
|
||||
sub lr, lr, #8
|
||||
srsdb sp, #PSR_MODE_SYS
|
||||
|
||||
/* Switch to SYS mode */
|
||||
|
||||
#ifdef CONFIG_ARMV7A_DECODEFIQ
|
||||
@ -396,24 +391,15 @@ arm_vectordata:
|
||||
sub sp, sp, #XCPTCONTEXT_SIZE
|
||||
stmia sp, {r0-r12} /* Save the SYS mode regs */
|
||||
|
||||
cps #PSR_MODE_ABT /* Switch back ABT mode */
|
||||
|
||||
/* Get the values for r15(pc) and CPSR in r3 and r4 */
|
||||
|
||||
sub r3, lr, #8
|
||||
mrs r4, spsr
|
||||
|
||||
cps #PSR_MODE_SYS /* Then switch back to SYS mode */
|
||||
|
||||
/* Get the correct values of USR/SYS r13(sp) and r14(lr) in r1 and r2 */
|
||||
|
||||
add r1, sp, #XCPTCONTEXT_SIZE
|
||||
mov r2, r14
|
||||
|
||||
/* Save r13(sp), r14(lr), r15(pc), and the CPSR */
|
||||
/* Save r13(sp), r14(lr) */
|
||||
|
||||
add r0, sp, #(4*REG_SP) /* Offset to pc, cpsr storage */
|
||||
stmia r0, {r1-r4}
|
||||
stmia r0, {r1-r2}
|
||||
|
||||
#ifdef CONFIG_ARCH_FPU
|
||||
/* Save the state of the floating point registers. */
|
||||
@ -452,18 +438,16 @@ arm_vectordata:
|
||||
* context switch is required.
|
||||
*/
|
||||
|
||||
/* Restore the CPSR, ABT mode registers and return */
|
||||
|
||||
ldr r1, [r0, #(4*REG_CPSR)] /* Fetch the return SPSR */
|
||||
msr spsr_cxsf, r1 /* Set the return mode SPSR */
|
||||
|
||||
/* Life is simple when everything is ABT mode */
|
||||
|
||||
mov r14, r0 /* (ABT) r14=Register storage area */
|
||||
ldmia r14!, {r0-r12} /* Restore common r0-r12 */
|
||||
ldmia r14, {r13, r14}^ /* Restore user mode r13/r14 */
|
||||
add r14, r14, #(4*2) /* (ABT) r14=address of r15 storage */
|
||||
ldmia r14, {r15}^ /* Return */
|
||||
|
||||
/* Restore the CPSR, SYS mode registers and return. */
|
||||
|
||||
add r14, r14, #(4*(REG_R15-REG_R13))
|
||||
rfeia r14
|
||||
.size arm_vectordata, . - arm_vectordata
|
||||
|
||||
.align 5
|
||||
@ -484,6 +468,12 @@ arm_vectordata:
|
||||
.type arm_vectorprefetch, %function
|
||||
|
||||
arm_vectorprefetch:
|
||||
|
||||
/* Save the LR and SPSR onto the SYS mode stack before switch. */
|
||||
|
||||
sub lr, lr, #4
|
||||
srsdb sp, #PSR_MODE_SYS
|
||||
|
||||
cpsid if, #PSR_MODE_SYS /* Switch to SYS mode */
|
||||
|
||||
/* Create a context structure. First set aside a stack frame
|
||||
@ -493,24 +483,15 @@ arm_vectorprefetch:
|
||||
sub sp, sp, #XCPTCONTEXT_SIZE
|
||||
stmia sp, {r0-r12} /* Save the SYS mode regs */
|
||||
|
||||
cps #PSR_MODE_ABT /* Switch back ABT mode */
|
||||
|
||||
/* Get the values for r15(pc) and CPSR in r3 and r4 */
|
||||
|
||||
sub r3, lr, #4
|
||||
mrs r4, spsr
|
||||
|
||||
cps #PSR_MODE_SYS /* Then switch back to SYS mode */
|
||||
|
||||
/* Get the correct values of USR/SYS r13(sp) and r14(lr) in r1 and r2 */
|
||||
|
||||
add r1, sp, #XCPTCONTEXT_SIZE
|
||||
mov r2, r14
|
||||
|
||||
/* Save r13(sp), r14(lr), r15(pc), and the CPSR */
|
||||
/* Save r13(sp), r14(lr) */
|
||||
|
||||
add r0, sp, #(4*REG_SP) /* Offset to pc, cpsr storage */
|
||||
stmia r0, {r1-r4}
|
||||
stmia r0, {r1-r2}
|
||||
|
||||
#ifdef CONFIG_ARCH_FPU
|
||||
/* Save the state of the floating point registers. */
|
||||
@ -549,18 +530,16 @@ arm_vectorprefetch:
|
||||
* context switch is required.
|
||||
*/
|
||||
|
||||
/* Restore the CPSR, ABT mode registers and return */
|
||||
|
||||
ldr r1, [r0, #(4*REG_CPSR)] /* Fetch the return SPSR */
|
||||
msr spsr_cxsf, r1 /* Set the return mode SPSR */
|
||||
|
||||
/* Life is simple when everything is ABT mode */
|
||||
|
||||
mov r14, r0 /* (ABT) r14=Register storage area */
|
||||
ldmia r14!, {r0-r12} /* Restore common r0-r12 */
|
||||
ldmia r14, {r13, r14}^ /* Restore user mode r13/r14 */
|
||||
add r14, r14, #(4*2) /* (ABT) r14=address of r15 storage */
|
||||
ldmia r14, {r15}^ /* Return */
|
||||
|
||||
/* Restore the CPSR, SYS mode registers and return. */
|
||||
|
||||
add r14, r14, #(4*(REG_R15-REG_R13))
|
||||
rfeia r14
|
||||
.size arm_vectorprefetch, . - arm_vectorprefetch
|
||||
|
||||
.align 5
|
||||
@ -579,6 +558,11 @@ arm_vectorprefetch:
|
||||
.type arm_vectorundefinsn, %function
|
||||
|
||||
arm_vectorundefinsn:
|
||||
|
||||
/* Save the LR and SPSR onto the SYS mode stack before switch. */
|
||||
|
||||
srsdb sp, #PSR_MODE_SYS
|
||||
|
||||
cpsid if, #PSR_MODE_SYS /* Switch to SYS mode */
|
||||
|
||||
/* Create a context structure. First set aside a stack frame
|
||||
@ -588,24 +572,15 @@ arm_vectorundefinsn:
|
||||
sub sp, sp, #XCPTCONTEXT_SIZE
|
||||
stmia sp, {r0-r12} /* Save the SYS mode regs */
|
||||
|
||||
cps #PSR_MODE_UND /* Switch back UND mode */
|
||||
|
||||
/* Get the values for r15(pc) and CPSR in r3 and r4 */
|
||||
|
||||
mov r3, lr
|
||||
mrs r4, spsr
|
||||
|
||||
cps #PSR_MODE_SYS /* Then switch back to SYS mode */
|
||||
|
||||
/* Get the correct values of USR/SYS r13(sp) and r14(lr) in r1 and r2 */
|
||||
|
||||
add r1, sp, #XCPTCONTEXT_SIZE
|
||||
mov r2, r14
|
||||
|
||||
/* Save r13(sp), r14(lr), r15(pc), and the CPSR */
|
||||
/* Save r13(sp), r14(lr) */
|
||||
|
||||
add r0, sp, #(4*REG_SP) /* Offset to pc, cpsr storage */
|
||||
stmia r0, {r1-r4}
|
||||
stmia r0, {r1-r2}
|
||||
|
||||
#ifdef CONFIG_ARCH_FPU
|
||||
/* Save the state of the floating point registers. */
|
||||
@ -642,18 +617,16 @@ arm_vectorundefinsn:
|
||||
* context switch is required.
|
||||
*/
|
||||
|
||||
/* Restore the CPSR, UND mode registers and return */
|
||||
|
||||
ldr r1, [r0, #(4*REG_CPSR)] /* Fetch the return SPSR */
|
||||
msr spsr_cxsf, r1 /* Set the return mode SPSR */
|
||||
|
||||
/* Life is simple when everything is UND mode */
|
||||
|
||||
mov r14, r0 /* (UND) r14=Register storage area */
|
||||
ldmia r14!, {r0-r12} /* Restore common r0-r12 */
|
||||
ldmia r14, {r13, r14}^ /* Restore user mode r13/r14 */
|
||||
add r14, r14, #(4*2) /* (UND) r14=address of r15 storage */
|
||||
ldmia r14, {r15}^ /* Return */
|
||||
|
||||
/* Restore the CPSR, SYS mode registers and return. */
|
||||
|
||||
add r14, r14, #(4*(REG_R15-REG_R13))
|
||||
rfeia r14
|
||||
.size arm_vectorundefinsn, . - arm_vectorundefinsn
|
||||
|
||||
.align 5
|
||||
@ -675,6 +648,12 @@ arm_vectorundefinsn:
|
||||
|
||||
arm_vectorfiq:
|
||||
#ifdef CONFIG_ARMV7R_DECODEFIQ
|
||||
|
||||
/* Save the LR and SPSR onto the SYS mode stack before switch. */
|
||||
|
||||
sub lr, lr, #4
|
||||
srsdb sp, #PSR_MODE_SYS
|
||||
|
||||
cpsid if, #PSR_MODE_SYS /* Switch to SYS mode */
|
||||
|
||||
/* Create a context structure. First set aside a stack frame
|
||||
@ -684,24 +663,15 @@ arm_vectorfiq:
|
||||
sub sp, sp, #XCPTCONTEXT_SIZE
|
||||
stmia sp, {r0-r12} /* Save the SYS mode regs */
|
||||
|
||||
cps #PSR_MODE_FIQ /* Switch back FIQ mode */
|
||||
|
||||
/* Get the values for r15(pc) and CPSR in r3 and r4 */
|
||||
|
||||
sub r3, lr, #4
|
||||
mrs r4, spsr
|
||||
|
||||
cps #PSR_MODE_SYS /* Then switch back to SYS mode */
|
||||
|
||||
/* Get the correct values of USR/SYS r13(sp) and r14(lr) in r1 and r2 */
|
||||
|
||||
add r1, sp, #XCPTCONTEXT_SIZE
|
||||
mov r2, r14
|
||||
|
||||
/* Save r13(sp), r14(lr), r15(pc), and the CPSR */
|
||||
/* Save r13(sp), r14(lr) */
|
||||
|
||||
add r0, sp, #(4*REG_SP) /* Offset to pc, cpsr storage */
|
||||
stmia r0, {r1-r4}
|
||||
stmia r0, {r1-r2}
|
||||
|
||||
#ifdef CONFIG_ARCH_FPU
|
||||
/* Save the state of the floating point registers. */
|
||||
@ -750,18 +720,16 @@ arm_vectorfiq:
|
||||
* context switch is required.
|
||||
*/
|
||||
|
||||
/* Restore the CPSR, FIQ mode registers and return */
|
||||
|
||||
ldr r1, [r0, #(4*REG_CPSR)] /* Fetch the return SPSR */
|
||||
msr spsr_cxsf, r1 /* Set the return mode SPSR */
|
||||
|
||||
/* Life is simple when everything is FIQ mode */
|
||||
|
||||
mov r14, r0 /* (FIQ) r14=Register storage area */
|
||||
ldmia r14!, {r0-r7} /* Restore common r0-r7 */
|
||||
ldmia r14, {r8-r14}^ /* Restore user mode r8-r14 */
|
||||
add r14, r14, #(4*7) /* (FIQ) r14=address of r15 storage */
|
||||
ldmia r14, {r15}^ /* Return */
|
||||
|
||||
/* Restore the CPSR, SYS mode registers and return. */
|
||||
|
||||
add r14, r14, #(4*(REG_R15-REG_R13))
|
||||
rfeia r14
|
||||
|
||||
#if CONFIG_ARCH_INTERRUPTSTACK > 7
|
||||
.Lfiqstacktop:
|
||||
|
Loading…
Reference in New Issue
Block a user