arm/armv7-a/r: set the default CPU mode to System
In SVC mode, the banked register will be inconsistent with the user mode register: arch/arm/src/armv7-a/arm_vectors.S 276 .globl arm_syscall 277 .globl arm_vectorsvc 278 .type arm_vectorsvc, %function 279 280 arm_vectorsvc: ... 286 sub sp, sp, #XCPTCONTEXT_SIZE // < SVC mode SP ... 308 stmia r0, {r13, r14}^ // < USR mode SP/LR ... [ 2.200000] [ 4] [ ALERT] SYSCALL Entry: regs: 0x80202708 cmd: 4 [ 2.200000] [ 4] [ ALERT] R0: 00000004 80001229 00000001 80202018 00000000 00000000 00000000 802027d0 [ 2.200000] [ 4] [ ALERT] R8: 00000000 00000000 00000000 00000000 00000000 802027d0 1080f710 1080f710 [ 2.200000] [ 4] [ ALERT] CPSR: 00000073 [ 2.200000] [ 4] [ ALERT] SYSCALL Exit: regs: 0x80202708 [ 2.200000] [ 4] [ ALERT] R0: 1 80202018 1 80202018 0 0 0 802027d0 [ 2.200000] [ 4] [ ALERT] R8: 0 0 0 0 0 802027d0 1080f710 80001229 [ 2.200000] [ 4] [ ALERT] CPSR: 00000070 SVC SP is 0x80202708 USR SP is 0x802027d0 0x802027d0 - 0x80202708 should be XCPTCONTEXT_SIZE [ 2.200000] [ 4] [ ALERT] SYSCALL Entry: regs: 0x80202708 cmd: 51 [ 2.200000] [ 4] [ ALERT] R0: 00000033 00000000 80202780 00000000 00000000 00000000 00000000 80202710 [ 2.200000] [ 4] [ ALERT] R8: 00000000 00000000 00000000 00000000 00000000 80202710 800039d5 800039b2 [ 2.200000] [ 4] [ ALERT] CPSR: 00000070 [ 2.200000] [ 4] [ ALERT] SYSCALL Exit: regs: 0x80202708 [ 2.200000] [ 4] [ ALERT] R0: 2b 0 80202780 0 0 0 0 80202710 [ 2.200000] [ 4] [ ALERT] R8: 0 0 0 0 0 10843d80 800039d5 10801425 [ 2.200000] [ 4] [ ALERT] CPSR: 00000073 SVC SP is 0x80202708 USR SP is 0x80202710 SP overlap in SVC and USR mode This commit change the default CPU mode to System and ensure the consistency of SP/LR in USR/SYS mode during syscall. Signed-off-by: chao.an <anchao@xiaomi.com>
This commit is contained in:
parent
54e630e14d
commit
7c02432f0e
@ -220,9 +220,9 @@
|
||||
.type __start, #function
|
||||
|
||||
__start:
|
||||
/* Make sure that we are in SVC mode with all IRQs disabled */
|
||||
/* Make sure that we are in SYS mode with all IRQs disabled */
|
||||
|
||||
mov r0, #(PSR_MODE_SVC | PSR_I_BIT | PSR_F_BIT)
|
||||
mov r0, #(PSR_MODE_SYS | PSR_I_BIT | PSR_F_BIT)
|
||||
msr cpsr_c, r0
|
||||
|
||||
/* Initialize DRAM using a macro provided by board-specific logic */
|
||||
|
@ -111,7 +111,7 @@ void up_initial_state(struct tcb_s *tcb)
|
||||
{
|
||||
/* It is a kernel thread.. set supervisor mode */
|
||||
|
||||
cpsr = PSR_MODE_SVC | PSR_F_BIT;
|
||||
cpsr = PSR_MODE_SYS | PSR_F_BIT;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -124,7 +124,7 @@ void up_initial_state(struct tcb_s *tcb)
|
||||
* supervisor-mode.
|
||||
*/
|
||||
|
||||
cpsr = PSR_MODE_SVC | PSR_F_BIT;
|
||||
cpsr = PSR_MODE_SYS | PSR_F_BIT;
|
||||
#endif
|
||||
|
||||
/* Enable or disable interrupts, based on user configuration */
|
||||
|
@ -58,7 +58,7 @@ __start:
|
||||
|
||||
/* First, setup initial processor mode */
|
||||
|
||||
mov r0, #(PSR_MODE_SVC | PSR_I_BIT | PSR_F_BIT )
|
||||
mov r0, #(PSR_MODE_SYS | PSR_I_BIT | PSR_F_BIT )
|
||||
msr cpsr, r0
|
||||
|
||||
/* Setup system stack (and get the BSS range) */
|
||||
|
@ -130,7 +130,7 @@ void up_schedule_sigaction(struct tcb_s *tcb, sig_deliver_t sigdeliver)
|
||||
*/
|
||||
|
||||
CURRENT_REGS[REG_PC] = (uint32_t)arm_sigdeliver;
|
||||
CURRENT_REGS[REG_CPSR] = PSR_MODE_SVC | PSR_I_BIT | PSR_F_BIT;
|
||||
CURRENT_REGS[REG_CPSR] = PSR_MODE_SYS | PSR_I_BIT | PSR_F_BIT;
|
||||
|
||||
/* And make sure that the saved context in the TCB
|
||||
* is the same as the interrupt return context.
|
||||
@ -162,7 +162,7 @@ void up_schedule_sigaction(struct tcb_s *tcb, sig_deliver_t sigdeliver)
|
||||
*/
|
||||
|
||||
tcb->xcp.regs[REG_PC] = (uint32_t)arm_sigdeliver;
|
||||
tcb->xcp.regs[REG_CPSR] = PSR_MODE_SVC | PSR_I_BIT | PSR_F_BIT;
|
||||
tcb->xcp.regs[REG_CPSR] = PSR_MODE_SYS | PSR_I_BIT | PSR_F_BIT;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -68,15 +68,15 @@ arm_vectorirq:
|
||||
* and r14.
|
||||
*/
|
||||
|
||||
mov r13, #(PSR_MODE_SVC | PSR_I_BIT)
|
||||
msr cpsr_c, r13 /* Switch to SVC mode */
|
||||
mov r13, #(PSR_MODE_SYS | PSR_I_BIT)
|
||||
msr cpsr_c, r13 /* Switch to SYS mode */
|
||||
|
||||
/* Create a context structure. First set aside a stack frame
|
||||
* and store r0-r12 into the frame.
|
||||
*/
|
||||
|
||||
sub sp, sp, #XCPTCONTEXT_SIZE
|
||||
stmia sp, {r0-r12} /* Save the SVC mode regs */
|
||||
stmia sp, {r0-r12} /* Save the SYS mode regs */
|
||||
|
||||
mov r0, #(PSR_MODE_IRQ | PSR_I_BIT)
|
||||
msr cpsr_c, r0 /* Switch back IRQ mode */
|
||||
@ -86,47 +86,12 @@ arm_vectorirq:
|
||||
sub r3, lr, #4
|
||||
mrs r4, spsr
|
||||
|
||||
/* Then switch back to SVC mode */
|
||||
/* Then switch back to SYS mode */
|
||||
|
||||
orr r0, r0, #(PSR_MODE_SVC | PSR_I_BIT)
|
||||
orr r0, r0, #(PSR_MODE_SYS | PSR_I_BIT)
|
||||
msr cpsr_c, r0
|
||||
|
||||
#ifdef CONFIG_BUILD_KERNEL
|
||||
/* Did we enter from user mode? If so then we need get the values of
|
||||
* USER mode r13(sp) and r14(lr).
|
||||
*/
|
||||
|
||||
and r1, r4, #PSR_MODE_MASK /* Interrupted mode */
|
||||
cmp r1, #PSR_MODE_USR /* User mode? */
|
||||
bne .Lirqentersvc /* Branch if not user mode */
|
||||
|
||||
/* ldmia with ^ will return the user mode registers (provided that r15
|
||||
* is not in the register list).
|
||||
*/
|
||||
|
||||
add r0, sp, #(4*REG_SP) /* Offset to sp/lr storage */
|
||||
stmia r0, {r13, r14}^ /* Save user mode r13(sp) and r14(lr) */
|
||||
add r0, sp, #(4*REG_R15) /* Offset to pc/cpsr storage */
|
||||
stmia r0, {r3, r4} /* Save r15(pc), and the CPSR */
|
||||
b .Lirqcontinue
|
||||
|
||||
.Lirqentersvc:
|
||||
/* Otherwise, get the correct values of SVC 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 */
|
||||
|
||||
add r0, sp, #(4*REG_SP) /* Offset to pc, cpsr storage */
|
||||
stmia r0, {r1-r4}
|
||||
|
||||
.Lirqcontinue:
|
||||
|
||||
#else
|
||||
/* Get the correct values of SVC r13(sp) and r14(lr) in r1 and r2 */
|
||||
/* Get the correct values of USR/SYS r13(sp) and r14(lr) in r1 and r2 */
|
||||
|
||||
add r1, sp, #XCPTCONTEXT_SIZE
|
||||
mov r2, r14
|
||||
@ -135,7 +100,6 @@ arm_vectorirq:
|
||||
|
||||
add r0, sp, #(4*REG_SP) /* Offset to pc, cpsr storage */
|
||||
stmia r0, {r1-r4}
|
||||
#endif
|
||||
|
||||
/* Then call the IRQ handler with interrupts disabled. */
|
||||
|
||||
@ -155,35 +119,11 @@ arm_vectorirq:
|
||||
bl arm_decodeirq /* Call the handler */
|
||||
#endif
|
||||
|
||||
/* Restore the CPSR, SVC mode registers and return */
|
||||
/* Restore the CPSR, SYS mode registers and return */
|
||||
|
||||
ldr r0, [sp, #(4*REG_CPSR)] /* Fetch the return SPSR */
|
||||
msr spsr_cxsf, r0 /* Set the return mode SPSR */
|
||||
|
||||
#ifdef CONFIG_BUILD_KERNEL
|
||||
/* Are we leaving in user mode? If so then we need to restore the
|
||||
* values of USER mode r13(sp) and r14(lr).
|
||||
*/
|
||||
|
||||
and r2, r0, #PSR_MODE_MASK /* Interrupted mode */
|
||||
cmp r2, #PSR_MODE_USR /* User mode? */
|
||||
bne .Lirqleavesvc /* Branch if not user mode */
|
||||
|
||||
mov r14, sp /* Get r14=xcp */
|
||||
add sp, sp, #XCPTCONTEXT_SIZE /* Restore SVC's sp */
|
||||
|
||||
/* ldmia with ^ will return the user mode registers (provided that r15
|
||||
* is not in the register list).
|
||||
*/
|
||||
|
||||
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 */
|
||||
|
||||
.Lirqleavesvc:
|
||||
#endif
|
||||
|
||||
ldmia sp, {r0-r15}^ /* Return */
|
||||
|
||||
#if CONFIG_ARCH_INTERRUPTSTACK > 3
|
||||
@ -198,7 +138,7 @@ arm_vectorirq:
|
||||
* Function: arm_vectorsvc
|
||||
*
|
||||
* Description:
|
||||
* SVC interrupt. We enter the SVC in SVC mode.
|
||||
* SVC interrupt. We enter the SVC in SYS mode.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
@ -207,55 +147,34 @@ arm_vectorirq:
|
||||
.type arm_vectorsvc, %function
|
||||
|
||||
arm_vectorsvc:
|
||||
/* On entry, we are in SVC mode. We are free to use the SVC mode r13
|
||||
* and r14.
|
||||
*/
|
||||
|
||||
mov r13, #(PSR_MODE_SYS | PSR_I_BIT)
|
||||
msr cpsr_c, r13 /* Switch to SYS mode */
|
||||
|
||||
/* Create a context structure. First set aside a stack frame
|
||||
* and store r0-r12 into the frame.
|
||||
*/
|
||||
|
||||
sub sp, sp, #XCPTCONTEXT_SIZE
|
||||
stmia sp, {r0-r12} /* Save the SVC mode regs */
|
||||
stmia sp, {r0-r12} /* Save the SYS mode regs */
|
||||
|
||||
mov r0, #(PSR_MODE_SVC | PSR_I_BIT)
|
||||
msr cpsr_c, r0 /* 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 */
|
||||
|
||||
#ifdef CONFIG_BUILD_KERNEL
|
||||
/* Did we enter from user mode? If so then we need get the values of
|
||||
* USER mode r13(sp) and r14(lr).
|
||||
*/
|
||||
/* Then switch back to SYS mode */
|
||||
|
||||
and r1, r4, #PSR_MODE_MASK /* Interrupted mode */
|
||||
cmp r1, #PSR_MODE_USR /* User mode? */
|
||||
bne .Lsvcentersvc /* Branch if not user mode */
|
||||
orr r0, r0, #(PSR_MODE_SYS | PSR_I_BIT)
|
||||
msr cpsr_c, r0
|
||||
|
||||
/* ldmia with ^ will return the user mode registers (provided that r15
|
||||
* is not in the register list).
|
||||
*/
|
||||
|
||||
add r0, sp, #(4*REG_SP) /* Offset to sp/lr storage */
|
||||
stmia r0, {r13, r14}^ /* Save user mode r13(sp) and r14(lr) */
|
||||
add r0, sp, #(4*REG_R15) /* Offset to pc/cpsr storage */
|
||||
stmia r0, {r3, r4} /* Save r15(pc), and the CPSR */
|
||||
b .Lsvccontinue
|
||||
|
||||
.Lsvcentersvc:
|
||||
/* Otherwise, get the correct values of SVC 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 */
|
||||
|
||||
add r0, sp, #(4*REG_SP) /* Offset to pc, cpsr storage */
|
||||
stmia r0, {r1-r4}
|
||||
|
||||
.Lsvccontinue:
|
||||
|
||||
#else
|
||||
/* Get the correct values of SVC r13(sp) and r14(lr) in r1 and r2 */
|
||||
/* Get the correct values of USR/SYS r13(sp) and r14(lr) in r1 and r2 */
|
||||
|
||||
add r1, sp, #XCPTCONTEXT_SIZE
|
||||
mov r2, r14
|
||||
@ -264,7 +183,6 @@ arm_vectorsvc:
|
||||
|
||||
add r0, sp, #(4*REG_SP) /* Offset to pc, cpsr storage */
|
||||
stmia r0, {r1-r4}
|
||||
#endif
|
||||
|
||||
/* Then call the SVC handler with interrupts disabled.
|
||||
* void arm_syscall(struct xcptcontext *xcp)
|
||||
@ -274,35 +192,11 @@ arm_vectorsvc:
|
||||
mov r0, sp /* Get r0=xcp */
|
||||
bl arm_syscall /* Call the handler */
|
||||
|
||||
/* Restore the CPSR, SVC mode registers and return */
|
||||
/* Restore the CPSR, SYS mode registers and return */
|
||||
|
||||
ldr r0, [sp, #(4*REG_CPSR)] /* Fetch the return SPSR */
|
||||
msr spsr_cxsf, r0 /* Set the return mode SPSR */
|
||||
|
||||
#ifdef CONFIG_BUILD_KERNEL
|
||||
/* Are we leaving in user mode? If so then we need to restore the
|
||||
* values of USER mode r13(sp) and r14(lr).
|
||||
*/
|
||||
|
||||
and r2, r0, #PSR_MODE_MASK /* Interrupted mode */
|
||||
cmp r2, #PSR_MODE_USR /* User mode? */
|
||||
bne .Lleavesvcsvc /* Branch if not user mode */
|
||||
|
||||
mov r14, sp /* Get r14=xcp */
|
||||
add sp, sp, #XCPTCONTEXT_SIZE /* Restore SVC's sp */
|
||||
|
||||
/* ldmia with ^ will return the user mode registers (provided that r15
|
||||
* is not in the register list).
|
||||
*/
|
||||
|
||||
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 */
|
||||
|
||||
.Lleavesvcsvc:
|
||||
#endif
|
||||
|
||||
ldmia sp, {r0-r15}^ /* Return */
|
||||
.size arm_vectorsvc, . - arm_vectorsvc
|
||||
|
||||
@ -328,15 +222,15 @@ arm_vectordata:
|
||||
* r13 and r14
|
||||
*/
|
||||
|
||||
mov r13, #(PSR_MODE_SVC | PSR_I_BIT)
|
||||
msr cpsr_c, r13 /* Switch to SVC mode */
|
||||
mov r13, #(PSR_MODE_SYS | PSR_I_BIT)
|
||||
msr cpsr_c, r13 /* Switch to SYS mode */
|
||||
|
||||
/* Create a context structure. First set aside a stack frame
|
||||
* and store r0-r12 into the frame.
|
||||
*/
|
||||
|
||||
sub sp, sp, #XCPTCONTEXT_SIZE
|
||||
stmia sp, {r0-r12} /* Save the SVC mode regs */
|
||||
stmia sp, {r0-r12} /* Save the SYS mode regs */
|
||||
|
||||
mov r0, #(PSR_MODE_ABT | PSR_I_BIT)
|
||||
msr cpsr_c, r0 /* Switch back ABT mode */
|
||||
@ -346,47 +240,12 @@ arm_vectordata:
|
||||
sub r3, lr, #8
|
||||
mrs r4, spsr
|
||||
|
||||
/* Then switch back to SVC mode */
|
||||
/* Then switch back to SYS mode */
|
||||
|
||||
mov r0, #(PSR_MODE_SVC | PSR_I_BIT)
|
||||
mov r0, #(PSR_MODE_SYS | PSR_I_BIT)
|
||||
msr cpsr_c, r0
|
||||
|
||||
#ifdef CONFIG_BUILD_KERNEL
|
||||
/* Did we enter from user mode? If so then we need get the values of
|
||||
* USER mode r13(sp) and r14(lr).
|
||||
*/
|
||||
|
||||
and r1, r4, #PSR_MODE_MASK /* Interrupted mode */
|
||||
cmp r1, #PSR_MODE_USR /* User mode? */
|
||||
bne .Ldabtentersvc /* Branch if not user mode */
|
||||
|
||||
/* ldmia with ^ will return the user mode registers (provided that r15
|
||||
* is not in the register list).
|
||||
*/
|
||||
|
||||
add r0, sp, #(4*REG_SP) /* Offset to sp/lr storage */
|
||||
stmia r0, {r13, r14}^ /* Save user mode r13(sp) and r14(lr) */
|
||||
add r0, sp, #(4*REG_R15) /* Offset to pc/cpsr storage */
|
||||
stmia r0, {r3, r4} /* Save r15(pc), and the CPSR */
|
||||
b .Ldabtcontinue
|
||||
|
||||
.Ldabtentersvc:
|
||||
/* Otherwise, get the correct values of SVC 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 */
|
||||
|
||||
add r0, sp, #(4*REG_SP) /* Offset to pc, cpsr storage */
|
||||
stmia r0, {r1-r4}
|
||||
|
||||
.Ldabtcontinue:
|
||||
|
||||
#else
|
||||
/* Get the correct values of SVC r13(sp) and r14(lr) in r1 and r2 */
|
||||
/* Get the correct values of USR/SYS r13(sp) and r14(lr) in r1 and r2 */
|
||||
|
||||
add r1, sp, #XCPTCONTEXT_SIZE
|
||||
mov r2, r14
|
||||
@ -395,7 +254,6 @@ arm_vectordata:
|
||||
|
||||
add r0, sp, #(4*REG_SP) /* Offset to pc, cpsr storage */
|
||||
stmia r0, {r1-r4}
|
||||
#endif
|
||||
|
||||
/* Then call the data abort handler with interrupts disabled.
|
||||
* void arm_dataabort(struct xcptcontext *xcp)
|
||||
@ -409,35 +267,11 @@ arm_vectordata:
|
||||
#endif
|
||||
bl arm_dataabort /* Call the handler */
|
||||
|
||||
/* Restore the CPSR, SVC mode registers and return */
|
||||
/* Restore the CPSR, SYS mode registers and return */
|
||||
|
||||
ldr r0, [sp, #(4*REG_CPSR)] /* Fetch the return SPSR */
|
||||
msr spsr_cxsf, r0 /* Set the return mode SPSR */
|
||||
|
||||
#ifdef CONFIG_BUILD_KERNEL
|
||||
/* Are we leaving in user mode? If so then we need to restore the
|
||||
* values of USER mode r13(sp) and r14(lr).
|
||||
*/
|
||||
|
||||
and r2, r0, #PSR_MODE_MASK /* Interrupted mode */
|
||||
cmp r2, #PSR_MODE_USR /* User mode? */
|
||||
bne .Ldabtleavesvc /* Branch if not user mode */
|
||||
|
||||
mov r14, sp /* Get r14=xcp */
|
||||
add sp, sp, #XCPTCONTEXT_SIZE /* Restore SVC's sp */
|
||||
|
||||
/* ldmia with ^ will return the user mode registers (provided that r15
|
||||
* is not in the register list).
|
||||
*/
|
||||
|
||||
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 */
|
||||
|
||||
.Ldabtleavesvc:
|
||||
#endif
|
||||
|
||||
ldmia sp, {r0-r15}^ /* Return */
|
||||
.size arm_vectordata, . - arm_vectordata
|
||||
|
||||
@ -463,15 +297,15 @@ arm_vectorprefetch:
|
||||
* r13 and r14
|
||||
*/
|
||||
|
||||
mov r13, #(PSR_MODE_SVC | PSR_I_BIT)
|
||||
msr cpsr_c, r13 /* Switch to SVC mode */
|
||||
mov r13, #(PSR_MODE_SYS | PSR_I_BIT)
|
||||
msr cpsr_c, r13 /* Switch to SYS mode */
|
||||
|
||||
/* Create a context structure. First set aside a stack frame
|
||||
* and store r0-r12 into the frame.
|
||||
*/
|
||||
|
||||
sub sp, sp, #XCPTCONTEXT_SIZE
|
||||
stmia sp, {r0-r12} /* Save the SVC mode regs */
|
||||
stmia sp, {r0-r12} /* Save the SYS mode regs */
|
||||
|
||||
mov r0, #(PSR_MODE_ABT | PSR_I_BIT)
|
||||
msr cpsr_c, r0 /* Switch back ABT mode */
|
||||
@ -481,47 +315,12 @@ arm_vectorprefetch:
|
||||
sub r3, lr, #4
|
||||
mrs r4, spsr
|
||||
|
||||
/* Then switch back to SVC mode */
|
||||
/* Then switch back to SYS mode */
|
||||
|
||||
mov r0, #(PSR_MODE_SVC | PSR_I_BIT)
|
||||
mov r0, #(PSR_MODE_SYS | PSR_I_BIT)
|
||||
msr cpsr_c, r0
|
||||
|
||||
#ifdef CONFIG_BUILD_KERNEL
|
||||
/* Did we enter from user mode? If so then we need get the values of
|
||||
* USER mode r13(sp) and r14(lr).
|
||||
*/
|
||||
|
||||
and r1, r4, #PSR_MODE_MASK /* Interrupted mode */
|
||||
cmp r1, #PSR_MODE_USR /* User mode? */
|
||||
bne .Lpabtentersvc /* Branch if not user mode */
|
||||
|
||||
/* ldmia with ^ will return the user mode registers (provided that r15
|
||||
* is not in the register list).
|
||||
*/
|
||||
|
||||
add r0, sp, #(4*REG_SP) /* Offset to sp/lr storage */
|
||||
stmia r0, {r13, r14}^ /* Save user mode r13(sp) and r14(lr) */
|
||||
add r0, sp, #(4*REG_R15) /* Offset to pc/cpsr storage */
|
||||
stmia r0, {r3, r4} /* Save r15(pc), and the CPSR */
|
||||
b .Lpabtcontinue
|
||||
|
||||
.Lpabtentersvc:
|
||||
/* Otherwise, get the correct values of SVC 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 */
|
||||
|
||||
add r0, sp, #(4*REG_SP) /* Offset to pc, cpsr storage */
|
||||
stmia r0, {r1-r4}
|
||||
|
||||
.Lpabtcontinue:
|
||||
|
||||
#else
|
||||
/* Get the correct values of SVC r13(sp) and r14(lr) in r1 and r2 */
|
||||
/* Get the correct values of USR/SYS r13(sp) and r14(lr) in r1 and r2 */
|
||||
|
||||
add r1, sp, #XCPTCONTEXT_SIZE
|
||||
mov r2, r14
|
||||
@ -530,7 +329,6 @@ arm_vectorprefetch:
|
||||
|
||||
add r0, sp, #(4*REG_SP) /* Offset to pc, cpsr storage */
|
||||
stmia r0, {r1-r4}
|
||||
#endif
|
||||
|
||||
/* Then call the prefetch abort handler with interrupts disabled.
|
||||
* void arm_prefetchabort(struct xcptcontext *xcp)
|
||||
@ -540,35 +338,11 @@ arm_vectorprefetch:
|
||||
mov r0, sp /* Get r0=xcp */
|
||||
bl arm_prefetchabort /* Call the handler */
|
||||
|
||||
/* Restore the CPSR, SVC mode registers and return */
|
||||
/* Restore the CPSR, SYS mode registers and return */
|
||||
|
||||
ldr r0, [sp, #(4*REG_CPSR)] /* Fetch the return SPSR */
|
||||
msr spsr_cxsf, r0 /* Set the return mode SPSR */
|
||||
|
||||
#ifdef CONFIG_BUILD_KERNEL
|
||||
/* Are we leaving in user mode? If so then we need to restore the
|
||||
* values of USER mode r13(sp) and r14(lr).
|
||||
*/
|
||||
|
||||
and r2, r0, #PSR_MODE_MASK /* Interrupted mode */
|
||||
cmp r2, #PSR_MODE_USR /* User mode? */
|
||||
bne .Lpabtleavesvc /* Branch if not user mode */
|
||||
|
||||
mov r14, sp /* Get r14=xcp */
|
||||
add sp, sp, #XCPTCONTEXT_SIZE /* Restore SVC's sp */
|
||||
|
||||
/* ldmia with ^ will return the user mode registers (provided that r15
|
||||
* is not in the register list).
|
||||
*/
|
||||
|
||||
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 */
|
||||
|
||||
.Lpabtleavesvc:
|
||||
#endif
|
||||
|
||||
ldmia sp, {r0-r15}^ /* Return */
|
||||
.size arm_vectorprefetch, . - arm_vectorprefetch
|
||||
|
||||
@ -592,15 +366,15 @@ arm_vectorundefinsn:
|
||||
* r13 and r14
|
||||
*/
|
||||
|
||||
mov r13, #(PSR_MODE_SVC | PSR_I_BIT)
|
||||
msr cpsr_c, r13 /* Switch to SVC mode */
|
||||
mov r13, #(PSR_MODE_SYS | PSR_I_BIT)
|
||||
msr cpsr_c, r13 /* Switch to SYS mode */
|
||||
|
||||
/* Create a context structure. First set aside a stack frame
|
||||
* and store r0-r12 into the frame.
|
||||
*/
|
||||
|
||||
sub sp, sp, #XCPTCONTEXT_SIZE
|
||||
stmia sp, {r0-r12} /* Save the SVC mode regs */
|
||||
stmia sp, {r0-r12} /* Save the SYS mode regs */
|
||||
|
||||
mov r0, #(PSR_MODE_UND | PSR_I_BIT)
|
||||
msr cpsr_c, r0 /* Switch back UND mode */
|
||||
@ -610,47 +384,12 @@ arm_vectorundefinsn:
|
||||
mov r3, lr
|
||||
mrs r4, spsr
|
||||
|
||||
/* Then switch back to SVC mode */
|
||||
/* Then switch back to SYS mode */
|
||||
|
||||
mov r0, #(PSR_MODE_SVC | PSR_I_BIT)
|
||||
mov r0, #(PSR_MODE_SYS | PSR_I_BIT)
|
||||
msr cpsr_c, r0
|
||||
|
||||
#ifdef CONFIG_BUILD_KERNEL
|
||||
/* Did we enter from user mode? If so then we need get the values of
|
||||
* USER mode r13(sp) and r14(lr).
|
||||
*/
|
||||
|
||||
and r1, r4, #PSR_MODE_MASK /* Interrupted mode */
|
||||
cmp r1, #PSR_MODE_USR /* User mode? */
|
||||
bne .Lundefentersvc /* Branch if not user mode */
|
||||
|
||||
/* ldmia with ^ will return the user mode registers (provided that r15
|
||||
* is not in the register list).
|
||||
*/
|
||||
|
||||
add r0, sp, #(4*REG_SP) /* Offset to sp/lr storage */
|
||||
stmia r0, {r13, r14}^ /* Save user mode r13(sp) and r14(lr) */
|
||||
add r0, sp, #(4*REG_R15) /* Offset to pc/cpsr storage */
|
||||
stmia r0, {r3, r4} /* Save r15(pc), and the CPSR */
|
||||
b .Lundefcontinue
|
||||
|
||||
.Lundefentersvc:
|
||||
/* Otherwise, get the correct values of SVC 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 */
|
||||
|
||||
add r0, sp, #(4*REG_SP) /* Offset to pc, cpsr storage */
|
||||
stmia r0, {r1-r4}
|
||||
|
||||
.Lundefcontinue:
|
||||
|
||||
#else
|
||||
/* Get the correct values of SVC r13(sp) and r14(lr) in r1 and r2 */
|
||||
/* Get the correct values of USR/SYS r13(sp) and r14(lr) in r1 and r2 */
|
||||
|
||||
add r1, sp, #XCPTCONTEXT_SIZE
|
||||
mov r2, r14
|
||||
@ -659,7 +398,6 @@ arm_vectorundefinsn:
|
||||
|
||||
add r0, sp, #(4*REG_SP) /* Offset to pc, cpsr storage */
|
||||
stmia r0, {r1-r4}
|
||||
#endif
|
||||
|
||||
/* Then call the undef insn handler with interrupts disabled.
|
||||
* void arm_undefinedinsn(struct xcptcontext *xcp)
|
||||
@ -669,35 +407,11 @@ arm_vectorundefinsn:
|
||||
mov r0, sp /* Get r0=xcp */
|
||||
bl arm_undefinedinsn /* Call the handler */
|
||||
|
||||
/* Restore the CPSR, SVC mode registers and return */
|
||||
/* Restore the CPSR, SYS mode registers and return */
|
||||
|
||||
ldr r0, [sp, #(4*REG_CPSR)] /* Fetch the return SPSR */
|
||||
msr spsr_cxsf, r0 /* Set the return mode SPSR */
|
||||
|
||||
#ifdef CONFIG_BUILD_KERNEL
|
||||
/* Are we leaving in user mode? If so then we need to restore the
|
||||
* values of USER mode r13(sp) and r14(lr).
|
||||
*/
|
||||
|
||||
and r2, r0, #PSR_MODE_MASK /* Interrupted mode */
|
||||
cmp r2, #PSR_MODE_USR /* User mode? */
|
||||
bne .Lundefleavesvc /* Branch if not user mode */
|
||||
|
||||
mov r14, sp /* Get r14=xcp */
|
||||
add sp, sp, #XCPTCONTEXT_SIZE /* Restore SVC's sp */
|
||||
|
||||
/* ldmia with ^ will return the user mode registers (provided that r15
|
||||
* is not in the register list).
|
||||
*/
|
||||
|
||||
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 */
|
||||
|
||||
.Lundefleavesvc:
|
||||
#endif
|
||||
|
||||
ldmia sp, {r0-r15}^ /* Return */
|
||||
.size arm_vectorundefinsn, . - arm_vectorundefinsn
|
||||
|
||||
|
@ -90,6 +90,11 @@
|
||||
.type __cpu1_start, #function
|
||||
|
||||
__cpu1_start:
|
||||
/* Make sure that we are in SYS mode with IRQs and FIQs disabled */
|
||||
|
||||
mov r0, #(PSR_MODE_SYS | PSR_I_BIT | PSR_F_BIT)
|
||||
msr cpsr_c, r0
|
||||
|
||||
/* Set up the stack pointer and the CPU index */
|
||||
|
||||
ldr sp, .Lcpu1_stackpointer
|
||||
@ -108,6 +113,11 @@ __cpu1_start:
|
||||
.type __cpu2_start, #function
|
||||
|
||||
__cpu2_start:
|
||||
/* Make sure that we are in SYS mode with IRQs and FIQs disabled */
|
||||
|
||||
mov r0, #(PSR_MODE_SYS | PSR_I_BIT | PSR_F_BIT)
|
||||
msr cpsr_c, r0
|
||||
|
||||
/* Set up the stack pointer and the CPU index */
|
||||
|
||||
ldr sp, .Lcpu2_stackpointer
|
||||
@ -126,6 +136,11 @@ __cpu2_start:
|
||||
.type __cpu3_start, #function
|
||||
|
||||
__cpu3_start:
|
||||
/* Make sure that we are in SYS mode with IRQs and FIQs disabled */
|
||||
|
||||
mov r0, #(PSR_MODE_SYS | PSR_I_BIT | PSR_F_BIT)
|
||||
msr cpsr_c, r0
|
||||
|
||||
/* Set up the stack pointer and the CPU index */
|
||||
|
||||
ldr sp, .Lcpu3_stackpointer
|
||||
@ -162,11 +177,6 @@ __cpu3_start:
|
||||
.type .Lcpu_start, #function
|
||||
|
||||
.Lcpu_start:
|
||||
/* Make sure that we are in SVC mode with IRQs and FIQs disabled */
|
||||
|
||||
mov r0, #(PSR_MODE_SVC | PSR_I_BIT | PSR_F_BIT)
|
||||
msr cpsr_c, r0
|
||||
|
||||
/* The MMU and caches should be disabled */
|
||||
|
||||
mrc CP15_SCTLR(r0)
|
||||
|
@ -172,9 +172,9 @@
|
||||
.type __start, #function
|
||||
|
||||
__start:
|
||||
/* Make sure that we are in SVC mode with IRQs and FIQs disabled */
|
||||
/* Make sure that we are in SYS mode with IRQs and FIQs disabled */
|
||||
|
||||
mov r0, #(PSR_MODE_SVC | PSR_I_BIT | PSR_F_BIT)
|
||||
mov r0, #(PSR_MODE_SYS | PSR_I_BIT | PSR_F_BIT)
|
||||
msr cpsr_c, r0
|
||||
|
||||
/* The MMU and caches should be disabled */
|
||||
|
@ -109,7 +109,7 @@ void up_initial_state(struct tcb_s *tcb)
|
||||
* privileges will be dropped before transitioning to user code.
|
||||
*/
|
||||
|
||||
cpsr = PSR_MODE_SVC;
|
||||
cpsr = PSR_MODE_SYS;
|
||||
|
||||
/* Enable or disable interrupts, based on user configuration */
|
||||
|
||||
|
@ -201,9 +201,9 @@
|
||||
.type __start, #function
|
||||
|
||||
__start:
|
||||
/* Make sure that we are in SVC mode with IRQs and FIQs disabled */
|
||||
/* Make sure that we are in SYS mode with IRQs and FIQs disabled */
|
||||
|
||||
mov r0, #(PSR_MODE_SVC | PSR_I_BIT | PSR_F_BIT)
|
||||
mov r0, #(PSR_MODE_SYS | PSR_I_BIT | PSR_F_BIT)
|
||||
msr cpsr_c, r0
|
||||
|
||||
/* Clear the 16K level 1 page table */
|
||||
|
@ -135,7 +135,7 @@ void up_schedule_sigaction(struct tcb_s *tcb, sig_deliver_t sigdeliver)
|
||||
*/
|
||||
|
||||
CURRENT_REGS[REG_PC] = (uint32_t)arm_sigdeliver;
|
||||
CURRENT_REGS[REG_CPSR] = (PSR_MODE_SVC | PSR_I_BIT |
|
||||
CURRENT_REGS[REG_CPSR] = (PSR_MODE_SYS | PSR_I_BIT |
|
||||
PSR_F_BIT);
|
||||
#ifdef CONFIG_ARM_THUMB
|
||||
CURRENT_REGS[REG_CPSR] |= PSR_T_BIT;
|
||||
@ -170,7 +170,7 @@ void up_schedule_sigaction(struct tcb_s *tcb, sig_deliver_t sigdeliver)
|
||||
*/
|
||||
|
||||
tcb->xcp.regs[REG_PC] = (uint32_t)arm_sigdeliver;
|
||||
tcb->xcp.regs[REG_CPSR] = (PSR_MODE_SVC | PSR_I_BIT | PSR_F_BIT);
|
||||
tcb->xcp.regs[REG_CPSR] = (PSR_MODE_SYS | PSR_I_BIT | PSR_F_BIT);
|
||||
#ifdef CONFIG_ARM_THUMB
|
||||
tcb->xcp.regs[REG_CPSR] |= PSR_T_BIT;
|
||||
#endif
|
||||
@ -257,7 +257,7 @@ void up_schedule_sigaction(struct tcb_s *tcb, sig_deliver_t sigdeliver)
|
||||
*/
|
||||
|
||||
tcb->xcp.regs[REG_PC] = (uint32_t)arm_sigdeliver;
|
||||
tcb->xcp.regs[REG_CPSR] = (PSR_MODE_SVC | PSR_I_BIT |
|
||||
tcb->xcp.regs[REG_CPSR] = (PSR_MODE_SYS | PSR_I_BIT |
|
||||
PSR_F_BIT);
|
||||
#ifdef CONFIG_ARM_THUMB
|
||||
tcb->xcp.regs[REG_CPSR] |= PSR_T_BIT;
|
||||
@ -283,7 +283,7 @@ void up_schedule_sigaction(struct tcb_s *tcb, sig_deliver_t sigdeliver)
|
||||
*/
|
||||
|
||||
CURRENT_REGS[REG_PC] = (uint32_t)arm_sigdeliver;
|
||||
CURRENT_REGS[REG_CPSR] = (PSR_MODE_SVC | PSR_I_BIT |
|
||||
CURRENT_REGS[REG_CPSR] = (PSR_MODE_SYS | PSR_I_BIT |
|
||||
PSR_F_BIT);
|
||||
#ifdef CONFIG_ARM_THUMB
|
||||
CURRENT_REGS[REG_CPSR] |= PSR_T_BIT;
|
||||
@ -347,7 +347,7 @@ void up_schedule_sigaction(struct tcb_s *tcb, sig_deliver_t sigdeliver)
|
||||
*/
|
||||
|
||||
tcb->xcp.regs[REG_PC] = (uint32_t)arm_sigdeliver;
|
||||
tcb->xcp.regs[REG_CPSR] = (PSR_MODE_SVC | PSR_I_BIT | PSR_F_BIT);
|
||||
tcb->xcp.regs[REG_CPSR] = (PSR_MODE_SYS | PSR_I_BIT | PSR_F_BIT);
|
||||
#ifdef CONFIG_ARM_THUMB
|
||||
tcb->xcp.regs[REG_CPSR] |= PSR_T_BIT;
|
||||
#endif
|
||||
|
@ -424,7 +424,7 @@ uint32_t *arm_syscall(uint32_t *regs)
|
||||
|
||||
regs[REG_PC] = rtcb->xcp.sigreturn;
|
||||
cpsr = regs[REG_CPSR] & ~PSR_MODE_MASK;
|
||||
regs[REG_CPSR] = cpsr | PSR_MODE_SVC;
|
||||
regs[REG_CPSR] = cpsr | PSR_MODE_SYS;
|
||||
rtcb->xcp.sigreturn = 0;
|
||||
|
||||
#ifdef CONFIG_ARCH_KERNEL_STACK
|
||||
@ -477,7 +477,7 @@ uint32_t *arm_syscall(uint32_t *regs)
|
||||
regs[REG_PC] = (uint32_t)dispatch_syscall;
|
||||
#ifdef CONFIG_BUILD_KERNEL
|
||||
cpsr = regs[REG_CPSR] & ~PSR_MODE_MASK;
|
||||
regs[REG_CPSR] = cpsr | PSR_MODE_SVC;
|
||||
regs[REG_CPSR] = cpsr | PSR_MODE_SYS;
|
||||
#endif
|
||||
/* Offset R0 to account for the reserved values */
|
||||
|
||||
|
@ -116,18 +116,18 @@ arm_vectorirq:
|
||||
*/
|
||||
|
||||
#ifdef CONFIG_ARMV7A_DECODEFIQ
|
||||
mov r13, #(PSR_MODE_SVC | PSR_I_BIT | PSR_F_BIT)
|
||||
mov r13, #(PSR_MODE_SYS | PSR_I_BIT | PSR_F_BIT)
|
||||
#else
|
||||
mov r13, #(PSR_MODE_SVC | PSR_I_BIT)
|
||||
mov r13, #(PSR_MODE_SYS | PSR_I_BIT)
|
||||
#endif
|
||||
msr cpsr_c, r13 /* Switch to SVC mode */
|
||||
msr cpsr_c, r13 /* Switch to SYS mode */
|
||||
|
||||
/* Create a context structure. First set aside a stack frame
|
||||
* and store r0-r12 into the frame.
|
||||
*/
|
||||
|
||||
sub sp, sp, #XCPTCONTEXT_SIZE
|
||||
stmia sp, {r0-r12} /* Save the SVC mode regs */
|
||||
stmia sp, {r0-r12} /* Save the SYS mode regs */
|
||||
|
||||
#ifdef CONFIG_ARMV7A_DECODEFIQ
|
||||
mov r0, #(PSR_MODE_IRQ | PSR_I_BIT | PSR_F_BIT)
|
||||
@ -141,38 +141,16 @@ arm_vectorirq:
|
||||
sub r3, lr, #4
|
||||
mrs r4, spsr
|
||||
|
||||
/* Then switch back to SVC mode */
|
||||
/* Then switch back to SYS mode */
|
||||
|
||||
#ifdef CONFIG_ARMV7A_DECODEFIQ
|
||||
orr r0, r0, #(PSR_MODE_SVC | PSR_I_BIT | PSR_F_BIT)
|
||||
orr r0, r0, #(PSR_MODE_SYS | PSR_I_BIT | PSR_F_BIT)
|
||||
#else
|
||||
orr r0, r0, #(PSR_MODE_SVC | PSR_I_BIT)
|
||||
orr r0, r0, #(PSR_MODE_SYS | PSR_I_BIT)
|
||||
#endif
|
||||
msr cpsr_c, r0
|
||||
|
||||
#ifdef CONFIG_BUILD_KERNEL
|
||||
/* Did we enter from user mode? If so then we need get the values of
|
||||
* USER mode r13(sp) and r14(lr).
|
||||
*/
|
||||
|
||||
and r1, r4, #PSR_MODE_MASK /* Interrupted mode */
|
||||
cmp r1, #PSR_MODE_USR /* User mode? */
|
||||
bne .Lirqentersvc /* Branch if not user mode */
|
||||
|
||||
/* ldmia with ^ will return the user mode registers (provided that r15
|
||||
* is not in the register list).
|
||||
*/
|
||||
|
||||
add r0, sp, #(4*REG_SP) /* Offset to sp/lr storage */
|
||||
stmia r0, {r13, r14}^ /* Save user mode r13(sp) and r14(lr) */
|
||||
add r0, sp, #(4*REG_R15) /* Offset to pc/cpsr storage */
|
||||
stmia r0, {r3, r4} /* Save r15(pc), and the CPSR */
|
||||
b .Lirqcontinue
|
||||
|
||||
.Lirqentersvc:
|
||||
/* Otherwise, get the correct values of SVC r13(sp) and r14(lr) in r1
|
||||
* and r2.
|
||||
*/
|
||||
/* Get the correct values of USR/SYS r13(sp) and r14(lr) in r1 and r2 */
|
||||
|
||||
add r1, sp, #XCPTCONTEXT_SIZE
|
||||
mov r2, r14
|
||||
@ -182,20 +160,6 @@ arm_vectorirq:
|
||||
add r0, sp, #(4*REG_SP) /* Offset to pc, cpsr storage */
|
||||
stmia r0, {r1-r4}
|
||||
|
||||
.Lirqcontinue:
|
||||
|
||||
#else
|
||||
/* Get the correct values of SVC 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 */
|
||||
|
||||
add r0, sp, #(4*REG_SP) /* Offset to pc, cpsr storage */
|
||||
stmia r0, {r1-r4}
|
||||
#endif
|
||||
|
||||
/* Then call the IRQ handler with interrupts disabled. */
|
||||
|
||||
mov fp, #0 /* Init frame pointer */
|
||||
@ -225,35 +189,12 @@ arm_vectorirq:
|
||||
* context switch is required.
|
||||
*/
|
||||
|
||||
/* Restore the CPSR, SVC mode registers and return */
|
||||
/* 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 */
|
||||
|
||||
#ifdef CONFIG_BUILD_KERNEL
|
||||
/* Are we leaving in user mode? If so then we need to restore the
|
||||
* values of USER mode r13(sp) and r14(lr).
|
||||
*/
|
||||
|
||||
and r2, r1, #PSR_MODE_MASK /* Interrupted mode */
|
||||
cmp r2, #PSR_MODE_USR /* User mode? */
|
||||
bne .Lirqleavesvc /* Branch if not user mode */
|
||||
|
||||
add sp, sp, #XCPTCONTEXT_SIZE /* Restore SVC's sp */
|
||||
|
||||
/* ldmia with ^ will return the user mode registers (provided that r15
|
||||
* is not in the register list).
|
||||
*/
|
||||
|
||||
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 */
|
||||
|
||||
.Lirqleavesvc:
|
||||
#endif
|
||||
/* Life is simple when everything is SVC mode */
|
||||
/* Life is simple when everything is SYS mode */
|
||||
|
||||
ldmia r0, {r0-r15}^ /* Return */
|
||||
|
||||
@ -269,7 +210,7 @@ arm_vectorirq:
|
||||
* Function: arm_vectorsvc
|
||||
*
|
||||
* Description:
|
||||
* SVC interrupt. We enter the SVC in SVC mode.
|
||||
* SVC interrupt. We enter the SVC in SYS mode.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
@ -279,54 +220,40 @@ arm_vectorirq:
|
||||
|
||||
arm_vectorsvc:
|
||||
|
||||
#ifdef CONFIG_ARMV7A_DECODEFIQ
|
||||
mov r13, #(PSR_MODE_SYS | PSR_I_BIT | PSR_F_BIT)
|
||||
#else
|
||||
mov r13, #(PSR_MODE_SYS | PSR_I_BIT)
|
||||
#endif
|
||||
msr cpsr_c, r13 /* Switch to SYS mode */
|
||||
|
||||
/* Create a context structure. First set aside a stack frame
|
||||
* and store r0-r12 into the frame.
|
||||
*/
|
||||
|
||||
sub sp, sp, #XCPTCONTEXT_SIZE
|
||||
stmia sp, {r0-r12} /* Save the SVC mode regs */
|
||||
stmia sp, {r0-r12} /* Save the SYS mode regs */
|
||||
|
||||
#ifdef CONFIG_ARMV7A_DECODEFIQ
|
||||
mov r0, #(PSR_MODE_SVC | PSR_I_BIT | PSR_F_BIT)
|
||||
#else
|
||||
mov r0, #(PSR_MODE_SVC | PSR_I_BIT)
|
||||
#endif
|
||||
msr cpsr_c, r0 /* 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 */
|
||||
|
||||
#ifdef CONFIG_BUILD_KERNEL
|
||||
/* Did we enter from user mode? If so then we need get the values of
|
||||
* USER mode r13(sp) and r14(lr).
|
||||
*/
|
||||
|
||||
and r1, r4, #PSR_MODE_MASK /* Interrupted mode */
|
||||
cmp r1, #PSR_MODE_USR /* User mode? */
|
||||
bne .Lsvcentersvc /* Branch if not user mode */
|
||||
|
||||
/* ldmia with ^ will return the user mode registers (provided that r15
|
||||
* is not in the register list).
|
||||
*/
|
||||
|
||||
add r0, sp, #(4*REG_SP) /* Offset to sp/lr storage */
|
||||
stmia r0, {r13, r14}^ /* Save user mode r13(sp) and r14(lr) */
|
||||
add r0, sp, #(4*REG_R15) /* Offset to pc/cpsr storage */
|
||||
stmia r0, {r3, r4} /* Save r15(pc), and the CPSR */
|
||||
b .Lsvccontinue
|
||||
|
||||
.Lsvcentersvc:
|
||||
/* Otherwise, get the correct values of SVC 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 */
|
||||
|
||||
add r0, sp, #(4*REG_SP) /* Offset to pc, cpsr storage */
|
||||
stmia r0, {r1-r4}
|
||||
|
||||
.Lsvccontinue:
|
||||
|
||||
#ifdef CONFIG_ARMV7A_DECODEFIQ
|
||||
orr r0, r0, #(PSR_MODE_SYS | PSR_I_BIT | PSR_F_BIT)
|
||||
#else
|
||||
/* Get the correct values of SVC r13(sp) and r14(lr) in r1 and r2 */
|
||||
orr r0, r0, #(PSR_MODE_SYS | PSR_I_BIT)
|
||||
#endif
|
||||
msr cpsr_c, r0
|
||||
|
||||
/* Get the correct values of USR/SYS r13(sp) and r14(lr) in r1 and r2 */
|
||||
|
||||
add r1, sp, #XCPTCONTEXT_SIZE
|
||||
mov r2, r14
|
||||
@ -335,7 +262,6 @@ arm_vectorsvc:
|
||||
|
||||
add r0, sp, #(4*REG_SP) /* Offset to pc, cpsr storage */
|
||||
stmia r0, {r1-r4}
|
||||
#endif
|
||||
|
||||
/* Then call the SVC handler with interrupts disabled.
|
||||
* void arm_syscall(struct xcptcontext *xcp)
|
||||
@ -368,35 +294,12 @@ arm_vectorsvc:
|
||||
* context switch is required.
|
||||
*/
|
||||
|
||||
/* Restore the CPSR, SVC mode registers and return */
|
||||
/* 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 */
|
||||
|
||||
#ifdef CONFIG_BUILD_KERNEL
|
||||
/* Are we leaving in user mode? If so then we need to restore the
|
||||
* values of USER mode r13(sp) and r14(lr).
|
||||
*/
|
||||
|
||||
and r2, r1, #PSR_MODE_MASK /* Interrupted mode */
|
||||
cmp r2, #PSR_MODE_USR /* User mode? */
|
||||
bne .Lleavesvcsvc /* Branch if not user mode */
|
||||
|
||||
add sp, sp, #XCPTCONTEXT_SIZE /* Restore SVC's sp */
|
||||
|
||||
/* ldmia with ^ will return the user mode registers (provided that r15
|
||||
* is not in the register list).
|
||||
*/
|
||||
|
||||
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 */
|
||||
|
||||
.Lleavesvcsvc:
|
||||
#endif
|
||||
/* Life is simple when everything is SVC mode */
|
||||
/* Life is simple when everything is SYS mode */
|
||||
|
||||
ldmia r0, {r0-r15}^ /* Return */
|
||||
.size arm_vectorsvc, . - arm_vectorsvc
|
||||
@ -424,18 +327,18 @@ arm_vectordata:
|
||||
*/
|
||||
|
||||
#ifdef CONFIG_ARMV7A_DECODEFIQ
|
||||
mov r13, #(PSR_MODE_SVC | PSR_I_BIT | PSR_F_BIT)
|
||||
mov r13, #(PSR_MODE_SYS | PSR_I_BIT | PSR_F_BIT)
|
||||
#else
|
||||
mov r13, #(PSR_MODE_SVC | PSR_I_BIT)
|
||||
mov r13, #(PSR_MODE_SYS | PSR_I_BIT)
|
||||
#endif
|
||||
msr cpsr_c, r13 /* Switch to SVC mode */
|
||||
msr cpsr_c, r13 /* Switch to SYS mode */
|
||||
|
||||
/* Create a context structure. First set aside a stack frame
|
||||
* and store r0-r12 into the frame.
|
||||
*/
|
||||
|
||||
sub sp, sp, #XCPTCONTEXT_SIZE
|
||||
stmia sp, {r0-r12} /* Save the SVC mode regs */
|
||||
stmia sp, {r0-r12} /* Save the SYS mode regs */
|
||||
|
||||
#ifdef CONFIG_ARMV7A_DECODEFIQ
|
||||
mov r0, #(PSR_MODE_ABT | PSR_I_BIT | PSR_F_BIT)
|
||||
@ -449,38 +352,16 @@ arm_vectordata:
|
||||
sub r3, lr, #8
|
||||
mrs r4, spsr
|
||||
|
||||
/* Then switch back to SVC mode */
|
||||
/* Then switch back to SYS mode */
|
||||
|
||||
#ifdef CONFIG_ARMV7A_DECODEFIQ
|
||||
mov r0, #(PSR_MODE_SVC | PSR_I_BIT | PSR_F_BIT)
|
||||
mov r0, #(PSR_MODE_SYS | PSR_I_BIT | PSR_F_BIT)
|
||||
#else
|
||||
mov r0, #(PSR_MODE_SVC | PSR_I_BIT)
|
||||
mov r0, #(PSR_MODE_SYS | PSR_I_BIT)
|
||||
#endif
|
||||
msr cpsr_c, r0
|
||||
|
||||
#ifdef CONFIG_BUILD_KERNEL
|
||||
/* Did we enter from user mode? If so then we need get the values of
|
||||
* USER mode r13(sp) and r14(lr).
|
||||
*/
|
||||
|
||||
and r1, r4, #PSR_MODE_MASK /* Interrupted mode */
|
||||
cmp r1, #PSR_MODE_USR /* User mode? */
|
||||
bne .Ldabtentersvc /* Branch if not user mode */
|
||||
|
||||
/* ldmia with ^ will return the user mode registers (provided that r15
|
||||
* is not in the register list).
|
||||
*/
|
||||
|
||||
add r0, sp, #(4*REG_SP) /* Offset to sp/lr storage */
|
||||
stmia r0, {r13, r14}^ /* Save user mode r13(sp) and r14(lr) */
|
||||
add r0, sp, #(4*REG_R15) /* Offset to pc/cpsr storage */
|
||||
stmia r0, {r3, r4} /* Save r15(pc), and the CPSR */
|
||||
b .Ldabtcontinue
|
||||
|
||||
.Ldabtentersvc:
|
||||
/* Otherwise, get the correct values of SVC r13(sp) and r14(lr) in r1
|
||||
* and r2.
|
||||
*/
|
||||
/* Get the correct values of USR/SYS r13(sp) and r14(lr) in r1 and r2 */
|
||||
|
||||
add r1, sp, #XCPTCONTEXT_SIZE
|
||||
mov r2, r14
|
||||
@ -490,20 +371,6 @@ arm_vectordata:
|
||||
add r0, sp, #(4*REG_SP) /* Offset to pc, cpsr storage */
|
||||
stmia r0, {r1-r4}
|
||||
|
||||
.Ldabtcontinue:
|
||||
|
||||
#else
|
||||
/* Get the correct values of SVC 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 */
|
||||
|
||||
add r0, sp, #(4*REG_SP) /* Offset to pc, cpsr storage */
|
||||
stmia r0, {r1-r4}
|
||||
#endif
|
||||
|
||||
/* Then call the data abort handler with interrupts disabled.
|
||||
* void arm_dataabort(struct xcptcontext *xcp)
|
||||
*/
|
||||
@ -523,35 +390,12 @@ arm_vectordata:
|
||||
* context switch is required.
|
||||
*/
|
||||
|
||||
/* Restore the CPSR, SVC mode registers and return */
|
||||
/* 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 */
|
||||
|
||||
#ifdef CONFIG_BUILD_KERNEL
|
||||
/* Are we leaving in user mode? If so then we need to restore the
|
||||
* values of USER mode r13(sp) and r14(lr).
|
||||
*/
|
||||
|
||||
and r2, r1, #PSR_MODE_MASK /* Interrupted mode */
|
||||
cmp r2, #PSR_MODE_USR /* User mode? */
|
||||
bne .Ldabtleavesvc /* Branch if not user mode */
|
||||
|
||||
add sp, sp, #XCPTCONTEXT_SIZE /* Restore SVC's sp */
|
||||
|
||||
/* ldmia with ^ will return the user mode registers (provided that r15
|
||||
* is not in the register list).
|
||||
*/
|
||||
|
||||
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 */
|
||||
|
||||
.Ldabtleavesvc:
|
||||
#endif
|
||||
/* Life is simple when everything is SVC mode */
|
||||
/* Life is simple when everything is SYS mode */
|
||||
|
||||
ldmia r0, {r0-r15}^ /* Return */
|
||||
.size arm_vectordata, . - arm_vectordata
|
||||
@ -578,15 +422,15 @@ arm_vectorprefetch:
|
||||
* r13 and r14
|
||||
*/
|
||||
|
||||
mov r13, #(PSR_MODE_SVC | PSR_I_BIT | PSR_F_BIT)
|
||||
msr cpsr_c, r13 /* Switch to SVC mode */
|
||||
mov r13, #(PSR_MODE_SYS | PSR_I_BIT | PSR_F_BIT)
|
||||
msr cpsr_c, r13 /* Switch to SYS mode */
|
||||
|
||||
/* Create a context structure. First set aside a stack frame
|
||||
* and store r0-r12 into the frame.
|
||||
*/
|
||||
|
||||
sub sp, sp, #XCPTCONTEXT_SIZE
|
||||
stmia sp, {r0-r12} /* Save the SVC mode regs */
|
||||
stmia sp, {r0-r12} /* Save the SYS mode regs */
|
||||
|
||||
mov r0, #(PSR_MODE_ABT | PSR_I_BIT | PSR_F_BIT)
|
||||
msr cpsr_c, r0 /* Switch back ABT mode */
|
||||
@ -596,34 +440,12 @@ arm_vectorprefetch:
|
||||
sub r3, lr, #4
|
||||
mrs r4, spsr
|
||||
|
||||
/* Then switch back to SVC mode */
|
||||
/* Then switch back to SYS mode */
|
||||
|
||||
mov r0, #(PSR_MODE_SVC | PSR_I_BIT | PSR_F_BIT)
|
||||
mov r0, #(PSR_MODE_SYS | PSR_I_BIT | PSR_F_BIT)
|
||||
msr cpsr_c, r0
|
||||
|
||||
#ifdef CONFIG_BUILD_KERNEL
|
||||
/* Did we enter from user mode? If so then we need get the values of
|
||||
* USER mode r13(sp) and r14(lr).
|
||||
*/
|
||||
|
||||
and r1, r4, #PSR_MODE_MASK /* Interrupted mode */
|
||||
cmp r1, #PSR_MODE_USR /* User mode? */
|
||||
bne .Lpabtentersvc /* Branch if not user mode */
|
||||
|
||||
/* ldmia with ^ will return the user mode registers (provided that r15
|
||||
* is not in the register list).
|
||||
*/
|
||||
|
||||
add r0, sp, #(4*REG_SP) /* Offset to sp/lr storage */
|
||||
stmia r0, {r13, r14}^ /* Save user mode r13(sp) and r14(lr) */
|
||||
add r0, sp, #(4*REG_R15) /* Offset to pc/cpsr storage */
|
||||
stmia r0, {r3, r4} /* Save r15(pc), and the CPSR */
|
||||
b .Lpabtcontinue
|
||||
|
||||
.Lpabtentersvc:
|
||||
/* Otherwise, get the correct values of SVC r13(sp) and r14(lr) in r1
|
||||
* and r2.
|
||||
*/
|
||||
/* Get the correct values of USR/SYS r13(sp) and r14(lr) in r1 and r2 */
|
||||
|
||||
add r1, sp, #XCPTCONTEXT_SIZE
|
||||
mov r2, r14
|
||||
@ -633,20 +455,6 @@ arm_vectorprefetch:
|
||||
add r0, sp, #(4*REG_SP) /* Offset to pc, cpsr storage */
|
||||
stmia r0, {r1-r4}
|
||||
|
||||
.Lpabtcontinue:
|
||||
|
||||
#else
|
||||
/* Get the correct values of SVC 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 */
|
||||
|
||||
add r0, sp, #(4*REG_SP) /* Offset to pc, cpsr storage */
|
||||
stmia r0, {r1-r4}
|
||||
#endif
|
||||
|
||||
/* Then call the prefetch abort handler with interrupts disabled.
|
||||
* void arm_prefetchabort(struct xcptcontext *xcp)
|
||||
*/
|
||||
@ -666,35 +474,12 @@ arm_vectorprefetch:
|
||||
* context switch is required.
|
||||
*/
|
||||
|
||||
/* Restore the CPSR, SVC mode registers and return */
|
||||
/* 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 */
|
||||
|
||||
#ifdef CONFIG_BUILD_KERNEL
|
||||
/* Are we leaving in user mode? If so then we need to restore the
|
||||
* values of USER mode r13(sp) and r14(lr).
|
||||
*/
|
||||
|
||||
and r2, r1, #PSR_MODE_MASK /* Interrupted mode */
|
||||
cmp r2, #PSR_MODE_USR /* User mode? */
|
||||
bne .Lpabtleavesvc /* Branch if not user mode */
|
||||
|
||||
add sp, sp, #XCPTCONTEXT_SIZE /* Restore SVC's sp */
|
||||
|
||||
/* ldmia with ^ will return the user mode registers (provided that r15
|
||||
* is not in the register list).
|
||||
*/
|
||||
|
||||
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 */
|
||||
|
||||
.Lpabtleavesvc:
|
||||
#endif
|
||||
/* Life is simple when everything is SVC mode */
|
||||
/* Life is simple when everything is SYS mode */
|
||||
|
||||
ldmia r0, {r0-r15}^ /* Return */
|
||||
.size arm_vectorprefetch, . - arm_vectorprefetch
|
||||
@ -719,15 +504,15 @@ arm_vectorundefinsn:
|
||||
* r13 and r14
|
||||
*/
|
||||
|
||||
mov r13, #(PSR_MODE_SVC | PSR_I_BIT | PSR_F_BIT)
|
||||
msr cpsr_c, r13 /* Switch to SVC mode */
|
||||
mov r13, #(PSR_MODE_SYS | PSR_I_BIT | PSR_F_BIT)
|
||||
msr cpsr_c, r13 /* Switch to SYS mode */
|
||||
|
||||
/* Create a context structure. First set aside a stack frame
|
||||
* and store r0-r12 into the frame.
|
||||
*/
|
||||
|
||||
sub sp, sp, #XCPTCONTEXT_SIZE
|
||||
stmia sp, {r0-r12} /* Save the SVC mode regs */
|
||||
stmia sp, {r0-r12} /* Save the SYS mode regs */
|
||||
|
||||
mov r0, #(PSR_MODE_UND | PSR_I_BIT | PSR_F_BIT)
|
||||
msr cpsr_c, r0 /* Switch back UND mode */
|
||||
@ -737,34 +522,12 @@ arm_vectorundefinsn:
|
||||
mov r3, lr
|
||||
mrs r4, spsr
|
||||
|
||||
/* Then switch back to SVC mode */
|
||||
/* Then switch back to SYS mode */
|
||||
|
||||
mov r0, #(PSR_MODE_SVC | PSR_I_BIT | PSR_F_BIT)
|
||||
mov r0, #(PSR_MODE_SYS | PSR_I_BIT | PSR_F_BIT)
|
||||
msr cpsr_c, r0
|
||||
|
||||
#ifdef CONFIG_BUILD_KERNEL
|
||||
/* Did we enter from user mode? If so then we need get the values of
|
||||
* USER mode r13(sp) and r14(lr).
|
||||
*/
|
||||
|
||||
and r1, r4, #PSR_MODE_MASK /* Interrupted mode */
|
||||
cmp r1, #PSR_MODE_USR /* User mode? */
|
||||
bne .Lundefentersvc /* Branch if not user mode */
|
||||
|
||||
/* ldmia with ^ will return the user mode registers (provided that r15
|
||||
* is not in the register list).
|
||||
*/
|
||||
|
||||
add r0, sp, #(4*REG_SP) /* Offset to sp/lr storage */
|
||||
stmia r0, {r13, r14}^ /* Save user mode r13(sp) and r14(lr) */
|
||||
add r0, sp, #(4*REG_R15) /* Offset to pc/cpsr storage */
|
||||
stmia r0, {r3, r4} /* Save r15(pc), and the CPSR */
|
||||
b .Lundefcontinue
|
||||
|
||||
.Lundefentersvc:
|
||||
/* Otherwise, get the correct values of SVC r13(sp) and r14(lr) in r1
|
||||
* and r2.
|
||||
*/
|
||||
/* Get the correct values of USR/SYS r13(sp) and r14(lr) in r1 and r2 */
|
||||
|
||||
add r1, sp, #XCPTCONTEXT_SIZE
|
||||
mov r2, r14
|
||||
@ -774,20 +537,6 @@ arm_vectorundefinsn:
|
||||
add r0, sp, #(4*REG_SP) /* Offset to pc, cpsr storage */
|
||||
stmia r0, {r1-r4}
|
||||
|
||||
.Lundefcontinue:
|
||||
|
||||
#else
|
||||
/* Get the correct values of SVC 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 */
|
||||
|
||||
add r0, sp, #(4*REG_SP) /* Offset to pc, cpsr storage */
|
||||
stmia r0, {r1-r4}
|
||||
#endif
|
||||
|
||||
/* Then call the undef insn handler with interrupts disabled.
|
||||
* void arm_undefinedinsn(struct xcptcontext *xcp)
|
||||
*/
|
||||
@ -805,35 +554,12 @@ arm_vectorundefinsn:
|
||||
* context switch is required.
|
||||
*/
|
||||
|
||||
/* Restore the CPSR, SVC mode registers and return */
|
||||
/* 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 */
|
||||
|
||||
#ifdef CONFIG_BUILD_KERNEL
|
||||
/* Are we leaving in user mode? If so then we need to restore the
|
||||
* values of USER mode r13(sp) and r14(lr).
|
||||
*/
|
||||
|
||||
and r2, r1, #PSR_MODE_MASK /* Interrupted mode */
|
||||
cmp r2, #PSR_MODE_USR /* User mode? */
|
||||
bne .Lundefleavesvc /* Branch if not user mode */
|
||||
|
||||
add sp, sp, #XCPTCONTEXT_SIZE /* Restore SVC's sp */
|
||||
|
||||
/* ldmia with ^ will return the user mode registers (provided that r15
|
||||
* is not in the register list).
|
||||
*/
|
||||
|
||||
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 */
|
||||
|
||||
.Lundefleavesvc:
|
||||
#endif
|
||||
/* Life is simple when everything is SVC mode */
|
||||
/* Life is simple when everything is SYS mode */
|
||||
|
||||
ldmia r0, {r0-r15}^ /* Return */
|
||||
.size arm_vectorundefinsn, . - arm_vectorundefinsn
|
||||
@ -859,15 +585,15 @@ arm_vectorfiq:
|
||||
#ifdef CONFIG_ARMV7A_DECODEFIQ
|
||||
/* On entry we are free to use the FIQ mode registers r8 through r14 */
|
||||
|
||||
mov r13, #(PSR_MODE_SVC | PSR_I_BIT | PSR_F_BIT)
|
||||
msr cpsr_c, r13 /* Switch to SVC mode */
|
||||
mov r13, #(PSR_MODE_SYS | PSR_I_BIT | PSR_F_BIT)
|
||||
msr cpsr_c, r13 /* Switch to SYS mode */
|
||||
|
||||
/* Create a context structure. First set aside a stack frame
|
||||
* and store r0-r12 into the frame.
|
||||
*/
|
||||
|
||||
sub sp, sp, #XCPTCONTEXT_SIZE
|
||||
stmia sp, {r0-r12} /* Save the SVC mode regs */
|
||||
stmia sp, {r0-r12} /* Save the SYS mode regs */
|
||||
|
||||
mov r0, #(PSR_MODE_FIQ | PSR_I_BIT | PSR_F_BIT)
|
||||
msr cpsr_c, r0 /* Switch back FIQ mode */
|
||||
@ -877,34 +603,12 @@ arm_vectorfiq:
|
||||
sub r3, lr, #4
|
||||
mrs r4, spsr
|
||||
|
||||
/* Then switch back to SVC mode */
|
||||
/* Then switch back to SYS mode */
|
||||
|
||||
mov r0, #(PSR_MODE_SVC | PSR_I_BIT | PSR_F_BIT)
|
||||
mov r0, #(PSR_MODE_SYS | PSR_I_BIT | PSR_F_BIT)
|
||||
msr cpsr_c, r0
|
||||
|
||||
#ifdef CONFIG_BUILD_KERNEL
|
||||
/* Did we enter from user mode? If so then we need get the values of
|
||||
* USER mode r13(sp) and r14(lr).
|
||||
*/
|
||||
|
||||
and r1, r4, #PSR_MODE_MASK /* Interrupted mode */
|
||||
cmp r1, #PSR_MODE_USR /* User mode? */
|
||||
bne .Lfiqentersvc /* Branch if not user mode */
|
||||
|
||||
/* ldmia with ^ will return the user mode registers (provided that r15
|
||||
* is not in the register list).
|
||||
*/
|
||||
|
||||
add r0, sp, #(4*REG_SP) /* Offset to sp/lr storage */
|
||||
stmia r0, {r13, r14}^ /* Save user mode r13(sp) and r14(lr) */
|
||||
add r0, sp, #(4*REG_R15) /* Offset to pc/cpsr storage */
|
||||
stmia r0, {r3, r4} /* Save r15(pc), and the CPSR */
|
||||
b .Lfiqcontinue
|
||||
|
||||
.Lfiqentersvc:
|
||||
/* Otherwise, get the correct values of SVC r13(sp) and r14(lr) in r1
|
||||
* and r2.
|
||||
*/
|
||||
/* Get the correct values of USR/SYS r13(sp) and r14(lr) in r1 and r2 */
|
||||
|
||||
add r1, sp, #XCPTCONTEXT_SIZE
|
||||
mov r2, r14
|
||||
@ -914,20 +618,6 @@ arm_vectorfiq:
|
||||
add r0, sp, #(4*REG_SP) /* Offset to pc, cpsr storage */
|
||||
stmia r0, {r1-r4}
|
||||
|
||||
.Lfiqcontinue:
|
||||
|
||||
#else
|
||||
/* Get the correct values of SVC 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 */
|
||||
|
||||
add r0, sp, #(4*REG_SP) /* Offset to pc, cpsr storage */
|
||||
stmia r0, {r1-r4}
|
||||
#endif
|
||||
|
||||
/* Then call the FIQ handler with interrupts disabled. */
|
||||
|
||||
mov fp, #0 /* Init frame pointer */
|
||||
@ -957,35 +647,12 @@ arm_vectorfiq:
|
||||
* context switch is required.
|
||||
*/
|
||||
|
||||
/* Restore the CPSR, SVC mode registers and return */
|
||||
/* 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 */
|
||||
|
||||
#ifdef CONFIG_BUILD_KERNEL
|
||||
/* Are we leaving in user mode? If so then we need to restore the
|
||||
* values of USER mode r13(sp) and r14(lr).
|
||||
*/
|
||||
|
||||
and r2, r1, #PSR_MODE_MASK /* Interrupted mode */
|
||||
cmp r2, #PSR_MODE_USR /* User mode? */
|
||||
bne .Lfiqleavesvc /* Branch if not user mode */
|
||||
|
||||
add sp, sp, #XCPTCONTEXT_SIZE /* Restore SVC's sp */
|
||||
|
||||
/* ldmia with ^ will return the user mode registers (provided that r15
|
||||
* is not in the register list).
|
||||
*/
|
||||
|
||||
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 */
|
||||
|
||||
.Lfiqleavesvc:
|
||||
#endif
|
||||
/* Life is simple when everything is SVC mode */
|
||||
/* Life is simple when everything is SYS mode */
|
||||
|
||||
ldmia r0, {r0-r15}^ /* Return */
|
||||
|
||||
|
@ -134,9 +134,9 @@
|
||||
.type __start, #function
|
||||
|
||||
__start:
|
||||
/* Make sure that we are in SVC mode with IRQs and FIQs disabled */
|
||||
/* Make sure that we are in SYS mode with IRQs and FIQs disabled */
|
||||
|
||||
mov r0, #(PSR_MODE_SVC | PSR_I_BIT | PSR_F_BIT)
|
||||
mov r0, #(PSR_MODE_SYS | PSR_I_BIT | PSR_F_BIT)
|
||||
msr cpsr_c, r0
|
||||
|
||||
/* Set up the stack pointer and clear the frame pointer. */
|
||||
|
@ -109,7 +109,7 @@ void up_initial_state(struct tcb_s *tcb)
|
||||
* privileges will be dropped before transitioning to user code.
|
||||
*/
|
||||
|
||||
cpsr = PSR_MODE_SVC;
|
||||
cpsr = PSR_MODE_SYS;
|
||||
|
||||
/* Enable or disable interrupts, based on user configuration */
|
||||
|
||||
|
@ -130,7 +130,7 @@ void up_schedule_sigaction(struct tcb_s *tcb, sig_deliver_t sigdeliver)
|
||||
*/
|
||||
|
||||
CURRENT_REGS[REG_PC] = (uint32_t)arm_sigdeliver;
|
||||
CURRENT_REGS[REG_CPSR] = (PSR_MODE_SVC | PSR_I_BIT |
|
||||
CURRENT_REGS[REG_CPSR] = (PSR_MODE_SYS | PSR_I_BIT |
|
||||
PSR_F_BIT);
|
||||
|
||||
#ifdef CONFIG_ENDIAN_BIG
|
||||
@ -166,7 +166,7 @@ void up_schedule_sigaction(struct tcb_s *tcb, sig_deliver_t sigdeliver)
|
||||
*/
|
||||
|
||||
tcb->xcp.regs[REG_PC] = (uint32_t)arm_sigdeliver;
|
||||
tcb->xcp.regs[REG_CPSR] = (PSR_MODE_SVC | PSR_I_BIT |
|
||||
tcb->xcp.regs[REG_CPSR] = (PSR_MODE_SYS | PSR_I_BIT |
|
||||
PSR_F_BIT);
|
||||
|
||||
#ifdef CONFIG_ENDIAN_BIG
|
||||
|
@ -419,7 +419,7 @@ uint32_t *arm_syscall(uint32_t *regs)
|
||||
|
||||
regs[REG_PC] = rtcb->xcp.sigreturn;
|
||||
cpsr = regs[REG_CPSR] & ~PSR_MODE_MASK;
|
||||
regs[REG_CPSR] = cpsr | PSR_MODE_SVC;
|
||||
regs[REG_CPSR] = cpsr | PSR_MODE_SYS;
|
||||
rtcb->xcp.sigreturn = 0;
|
||||
|
||||
#ifdef CONFIG_ARCH_KERNEL_STACK
|
||||
@ -472,7 +472,7 @@ uint32_t *arm_syscall(uint32_t *regs)
|
||||
regs[REG_PC] = (uint32_t)dispatch_syscall;
|
||||
#ifdef CONFIG_BUILD_PROTECTED
|
||||
cpsr = regs[REG_CPSR] & ~PSR_MODE_MASK;
|
||||
regs[REG_CPSR] = cpsr | PSR_MODE_SVC;
|
||||
regs[REG_CPSR] = cpsr | PSR_MODE_SYS;
|
||||
#endif
|
||||
/* Offset R0 to account for the reserved values */
|
||||
|
||||
|
@ -70,18 +70,18 @@ arm_vectorirq:
|
||||
*/
|
||||
|
||||
#ifdef CONFIG_ARMV7A_DECODEFIQ
|
||||
mov r13, #(PSR_MODE_SVC | PSR_I_BIT | PSR_F_BIT)
|
||||
mov r13, #(PSR_MODE_SYS | PSR_I_BIT | PSR_F_BIT)
|
||||
#else
|
||||
mov r13, #(PSR_MODE_SVC | PSR_I_BIT)
|
||||
mov r13, #(PSR_MODE_SYS | PSR_I_BIT)
|
||||
#endif
|
||||
msr cpsr_c, r13 /* Switch to SVC mode */
|
||||
msr cpsr_c, r13 /* Switch to SYS mode */
|
||||
|
||||
/* Create a context structure. First set aside a stack frame
|
||||
* and store r0-r12 into the frame.
|
||||
*/
|
||||
|
||||
sub sp, sp, #XCPTCONTEXT_SIZE
|
||||
stmia sp, {r0-r12} /* Save the SVC mode regs */
|
||||
stmia sp, {r0-r12} /* Save the SYS mode regs */
|
||||
|
||||
#ifdef CONFIG_ARMV7A_DECODEFIQ
|
||||
mov r0, #(PSR_MODE_IRQ | PSR_I_BIT | PSR_F_BIT)
|
||||
@ -95,38 +95,16 @@ arm_vectorirq:
|
||||
sub r3, lr, #4
|
||||
mrs r4, spsr
|
||||
|
||||
/* Then switch back to SVC mode */
|
||||
/* Then switch back to SYS mode */
|
||||
|
||||
#ifdef CONFIG_ARMV7A_DECODEFIQ
|
||||
orr r0, r0, #(PSR_MODE_SVC | PSR_I_BIT | PSR_F_BIT)
|
||||
orr r0, r0, #(PSR_MODE_SYS | PSR_I_BIT | PSR_F_BIT)
|
||||
#else
|
||||
orr r0, r0, #(PSR_MODE_SVC | PSR_I_BIT)
|
||||
orr r0, r0, #(PSR_MODE_SYS | PSR_I_BIT)
|
||||
#endif
|
||||
msr cpsr_c, r0
|
||||
|
||||
#ifdef CONFIG_BUILD_PROTECTED
|
||||
/* Did we enter from user mode? If so then we need get the values of
|
||||
* USER mode r13(sp) and r14(lr).
|
||||
*/
|
||||
|
||||
and r1, r4, #PSR_MODE_MASK /* Interrupted mode */
|
||||
cmp r1, #PSR_MODE_USR /* User mode? */
|
||||
bne .Lirqentersvc /* Branch if not user mode */
|
||||
|
||||
/* ldmia with ^ will return the user mode registers (provided that r15
|
||||
* is not in the register list).
|
||||
*/
|
||||
|
||||
add r0, sp, #(4*REG_SP) /* Offset to sp/lr storage */
|
||||
stmia r0, {r13, r14}^ /* Save user mode r13(sp) and r14(lr) */
|
||||
add r0, sp, #(4*REG_R15) /* Offset to pc/cpsr storage */
|
||||
stmia r0, {r3, r4} /* Save r15(pc), and the CPSR */
|
||||
b .Lirqcontinue
|
||||
|
||||
.Lirqentersvc:
|
||||
/* Otherwise, get the correct values of SVC r13(sp) and r14(lr) in r1
|
||||
* and r2.
|
||||
*/
|
||||
/* Get the correct values of USR/SYS r13(sp) and r14(lr) in r1 and r2 */
|
||||
|
||||
add r1, sp, #XCPTCONTEXT_SIZE
|
||||
mov r2, r14
|
||||
@ -136,20 +114,6 @@ arm_vectorirq:
|
||||
add r0, sp, #(4*REG_SP) /* Offset to pc, cpsr storage */
|
||||
stmia r0, {r1-r4}
|
||||
|
||||
.Lirqcontinue:
|
||||
|
||||
#else
|
||||
/* Get the correct values of SVC 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 */
|
||||
|
||||
add r0, sp, #(4*REG_SP) /* Offset to pc, cpsr storage */
|
||||
stmia r0, {r1-r4}
|
||||
#endif
|
||||
|
||||
/* Then call the IRQ handler with interrupts disabled. */
|
||||
|
||||
mov fp, #0 /* Init frame pointer */
|
||||
@ -179,35 +143,12 @@ arm_vectorirq:
|
||||
* context switch is required.
|
||||
*/
|
||||
|
||||
/* Restore the CPSR, SVC mode registers and return */
|
||||
/* 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 */
|
||||
|
||||
#ifdef CONFIG_BUILD_PROTECTED
|
||||
/* Are we leaving in user mode? If so then we need to restore the
|
||||
* values of USER mode r13(sp) and r14(lr).
|
||||
*/
|
||||
|
||||
and r2, r1, #PSR_MODE_MASK /* Interrupted mode */
|
||||
cmp r2, #PSR_MODE_USR /* User mode? */
|
||||
bne .Lirqleavesvc /* Branch if not user mode */
|
||||
|
||||
add sp, sp, #XCPTCONTEXT_SIZE /* Restore SVC's sp */
|
||||
|
||||
/* ldmia with ^ will return the user mode registers (provided that r15
|
||||
* is not in the register list).
|
||||
*/
|
||||
|
||||
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 */
|
||||
|
||||
.Lirqleavesvc:
|
||||
#endif
|
||||
/* Life is simple when everything is SVC mode */
|
||||
/* Life is simple when everything is SYS mode */
|
||||
|
||||
ldmia r0, {r0-r15}^ /* Return */
|
||||
|
||||
@ -223,7 +164,7 @@ arm_vectorirq:
|
||||
* Function: arm_vectorsvc
|
||||
*
|
||||
* Description:
|
||||
* SVC interrupt. We enter the SVC in SVC mode.
|
||||
* SVC interrupt. We enter the SVC in SYS mode.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
@ -233,54 +174,40 @@ arm_vectorirq:
|
||||
|
||||
arm_vectorsvc:
|
||||
|
||||
#ifdef CONFIG_ARMV7A_DECODEFIQ
|
||||
mov r13, #(PSR_MODE_SYS | PSR_I_BIT | PSR_F_BIT)
|
||||
#else
|
||||
mov r13, #(PSR_MODE_SYS | PSR_I_BIT)
|
||||
#endif
|
||||
msr cpsr_c, r13 /* Switch to SYS mode */
|
||||
|
||||
/* Create a context structure. First set aside a stack frame
|
||||
* and store r0-r12 into the frame.
|
||||
*/
|
||||
|
||||
sub sp, sp, #XCPTCONTEXT_SIZE
|
||||
stmia sp, {r0-r12} /* Save the SVC mode regs */
|
||||
stmia sp, {r0-r12} /* Save the SYS mode regs */
|
||||
|
||||
#ifdef CONFIG_ARMV7A_DECODEFIQ
|
||||
mov r0, #(PSR_MODE_SVC | PSR_I_BIT | PSR_F_BIT)
|
||||
#else
|
||||
mov r0, #(PSR_MODE_SVC | PSR_I_BIT)
|
||||
#endif
|
||||
msr cpsr_c, r0 /* 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 */
|
||||
|
||||
#ifdef CONFIG_BUILD_PROTECTED
|
||||
/* Did we enter from user mode? If so then we need get the values of
|
||||
* USER mode r13(sp) and r14(lr).
|
||||
*/
|
||||
|
||||
and r1, r4, #PSR_MODE_MASK /* Interrupted mode */
|
||||
cmp r1, #PSR_MODE_USR /* User mode? */
|
||||
bne .Lsvcentersvc /* Branch if not user mode */
|
||||
|
||||
/* ldmia with ^ will return the user mode registers (provided that r15
|
||||
* is not in the register list).
|
||||
*/
|
||||
|
||||
add r0, sp, #(4*REG_SP) /* Offset to sp/lr storage */
|
||||
stmia r0, {r13, r14}^ /* Save user mode r13(sp) and r14(lr) */
|
||||
add r0, sp, #(4*REG_R15) /* Offset to pc/cpsr storage */
|
||||
stmia r0, {r3, r4} /* Save r15(pc), and the CPSR */
|
||||
b .Lsvccontinue
|
||||
|
||||
.Lsvcentersvc:
|
||||
/* Otherwise, get the correct values of SVC 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 */
|
||||
|
||||
add r0, sp, #(4*REG_SP) /* Offset to pc, cpsr storage */
|
||||
stmia r0, {r1-r4}
|
||||
|
||||
.Lsvccontinue:
|
||||
|
||||
#ifdef CONFIG_ARMV7A_DECODEFIQ
|
||||
orr r0, r0, #(PSR_MODE_SYS | PSR_I_BIT | PSR_F_BIT)
|
||||
#else
|
||||
/* Get the correct values of SVC r13(sp) and r14(lr) in r1 and r2 */
|
||||
orr r0, r0, #(PSR_MODE_SYS | PSR_I_BIT)
|
||||
#endif
|
||||
msr cpsr_c, r0
|
||||
|
||||
/* Get the correct values of USR/SYS r13(sp) and r14(lr) in r1 and r2 */
|
||||
|
||||
add r1, sp, #XCPTCONTEXT_SIZE
|
||||
mov r2, r14
|
||||
@ -289,7 +216,6 @@ arm_vectorsvc:
|
||||
|
||||
add r0, sp, #(4*REG_SP) /* Offset to pc, cpsr storage */
|
||||
stmia r0, {r1-r4}
|
||||
#endif
|
||||
|
||||
/* Then call the SVC handler with interrupts disabled.
|
||||
* void arm_syscall(struct xcptcontext *xcp)
|
||||
@ -322,35 +248,12 @@ arm_vectorsvc:
|
||||
* context switch is required.
|
||||
*/
|
||||
|
||||
/* Restore the CPSR, SVC mode registers and return */
|
||||
/* 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 */
|
||||
|
||||
#ifdef CONFIG_BUILD_PROTECTED
|
||||
/* Are we leaving in user mode? If so then we need to restore the
|
||||
* values of USER mode r13(sp) and r14(lr).
|
||||
*/
|
||||
|
||||
and r2, r1, #PSR_MODE_MASK /* Interrupted mode */
|
||||
cmp r2, #PSR_MODE_USR /* User mode? */
|
||||
bne .Lleavesvcsvc /* Branch if not user mode */
|
||||
|
||||
add sp, sp, #XCPTCONTEXT_SIZE /* Restore SVC's sp */
|
||||
|
||||
/* ldmia with ^ will return the user mode registers (provided that r15
|
||||
* is not in the register list).
|
||||
*/
|
||||
|
||||
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 */
|
||||
|
||||
.Lleavesvcsvc:
|
||||
#endif
|
||||
/* Life is simple when everything is SVC mode */
|
||||
/* Life is simple when everything is SYS mode */
|
||||
|
||||
ldmia r0, {r0-r15}^ /* Return */
|
||||
.size arm_vectorsvc, . - arm_vectorsvc
|
||||
@ -378,18 +281,18 @@ arm_vectordata:
|
||||
*/
|
||||
|
||||
#ifdef CONFIG_ARMV7A_DECODEFIQ
|
||||
mov r13, #(PSR_MODE_SVC | PSR_I_BIT | PSR_F_BIT)
|
||||
mov r13, #(PSR_MODE_SYS | PSR_I_BIT | PSR_F_BIT)
|
||||
#else
|
||||
mov r13, #(PSR_MODE_SVC | PSR_I_BIT)
|
||||
mov r13, #(PSR_MODE_SYS | PSR_I_BIT)
|
||||
#endif
|
||||
msr cpsr_c, r13 /* Switch to SVC mode */
|
||||
msr cpsr_c, r13 /* Switch to SYS mode */
|
||||
|
||||
/* Create a context structure. First set aside a stack frame
|
||||
* and store r0-r12 into the frame.
|
||||
*/
|
||||
|
||||
sub sp, sp, #XCPTCONTEXT_SIZE
|
||||
stmia sp, {r0-r12} /* Save the SVC mode regs */
|
||||
stmia sp, {r0-r12} /* Save the SYS mode regs */
|
||||
|
||||
#ifdef CONFIG_ARMV7A_DECODEFIQ
|
||||
mov r0, #(PSR_MODE_ABT | PSR_I_BIT | PSR_F_BIT)
|
||||
@ -403,38 +306,16 @@ arm_vectordata:
|
||||
sub r3, lr, #8
|
||||
mrs r4, spsr
|
||||
|
||||
/* Then switch back to SVC mode */
|
||||
/* Then switch back to SYS mode */
|
||||
|
||||
#ifdef CONFIG_ARMV7A_DECODEFIQ
|
||||
mov r0, #(PSR_MODE_SVC | PSR_I_BIT | PSR_F_BIT)
|
||||
mov r0, #(PSR_MODE_SYS | PSR_I_BIT | PSR_F_BIT)
|
||||
#else
|
||||
mov r0, #(PSR_MODE_SVC | PSR_I_BIT)
|
||||
mov r0, #(PSR_MODE_SYS | PSR_I_BIT)
|
||||
#endif
|
||||
msr cpsr_c, r0
|
||||
|
||||
#ifdef CONFIG_BUILD_PROTECTED
|
||||
/* Did we enter from user mode? If so then we need get the values of
|
||||
* USER mode r13(sp) and r14(lr).
|
||||
*/
|
||||
|
||||
and r1, r4, #PSR_MODE_MASK /* Interrupted mode */
|
||||
cmp r1, #PSR_MODE_USR /* User mode? */
|
||||
bne .Ldabtentersvc /* Branch if not user mode */
|
||||
|
||||
/* ldmia with ^ will return the user mode registers (provided that r15
|
||||
* is not in the register list).
|
||||
*/
|
||||
|
||||
add r0, sp, #(4*REG_SP) /* Offset to sp/lr storage */
|
||||
stmia r0, {r13, r14}^ /* Save user mode r13(sp) and r14(lr) */
|
||||
add r0, sp, #(4*REG_R15) /* Offset to pc/cpsr storage */
|
||||
stmia r0, {r3, r4} /* Save r15(pc), and the CPSR */
|
||||
b .Ldabtcontinue
|
||||
|
||||
.Ldabtentersvc:
|
||||
/* Otherwise, get the correct values of SVC r13(sp) and r14(lr) in r1
|
||||
* and r2.
|
||||
*/
|
||||
/* Get the correct values of USR/SYS r13(sp) and r14(lr) in r1 and r2 */
|
||||
|
||||
add r1, sp, #XCPTCONTEXT_SIZE
|
||||
mov r2, r14
|
||||
@ -444,20 +325,6 @@ arm_vectordata:
|
||||
add r0, sp, #(4*REG_SP) /* Offset to pc, cpsr storage */
|
||||
stmia r0, {r1-r4}
|
||||
|
||||
.Ldabtcontinue:
|
||||
|
||||
#else
|
||||
/* Get the correct values of SVC 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 */
|
||||
|
||||
add r0, sp, #(4*REG_SP) /* Offset to pc, cpsr storage */
|
||||
stmia r0, {r1-r4}
|
||||
#endif
|
||||
|
||||
/* Then call the data abort handler with interrupts disabled.
|
||||
* void arm_dataabort(struct xcptcontext *xcp)
|
||||
*/
|
||||
@ -477,35 +344,12 @@ arm_vectordata:
|
||||
* context switch is required.
|
||||
*/
|
||||
|
||||
/* Restore the CPSR, SVC mode registers and return */
|
||||
/* 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 */
|
||||
|
||||
#ifdef CONFIG_BUILD_PROTECTED
|
||||
/* Are we leaving in user mode? If so then we need to restore the
|
||||
* values of USER mode r13(sp) and r14(lr).
|
||||
*/
|
||||
|
||||
and r2, r1, #PSR_MODE_MASK /* Interrupted mode */
|
||||
cmp r2, #PSR_MODE_USR /* User mode? */
|
||||
bne .Ldabtleavesvc /* Branch if not user mode */
|
||||
|
||||
add sp, sp, #XCPTCONTEXT_SIZE /* Restore SVC's sp */
|
||||
|
||||
/* ldmia with ^ will return the user mode registers (provided that r15
|
||||
* is not in the register list).
|
||||
*/
|
||||
|
||||
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 */
|
||||
|
||||
.Ldabtleavesvc:
|
||||
#endif
|
||||
/* Life is simple when everything is SVC mode */
|
||||
/* Life is simple when everything is SYS mode */
|
||||
|
||||
ldmia r0, {r0-r15}^ /* Return */
|
||||
.size arm_vectordata, . - arm_vectordata
|
||||
@ -532,15 +376,15 @@ arm_vectorprefetch:
|
||||
* r13 and r14
|
||||
*/
|
||||
|
||||
mov r13, #(PSR_MODE_SVC | PSR_I_BIT | PSR_F_BIT)
|
||||
msr cpsr_c, r13 /* Switch to SVC mode */
|
||||
mov r13, #(PSR_MODE_SYS | PSR_I_BIT | PSR_F_BIT)
|
||||
msr cpsr_c, r13 /* Switch to SYS mode */
|
||||
|
||||
/* Create a context structure. First set aside a stack frame
|
||||
* and store r0-r12 into the frame.
|
||||
*/
|
||||
|
||||
sub sp, sp, #XCPTCONTEXT_SIZE
|
||||
stmia sp, {r0-r12} /* Save the SVC mode regs */
|
||||
stmia sp, {r0-r12} /* Save the SYS mode regs */
|
||||
|
||||
mov r0, #(PSR_MODE_ABT | PSR_I_BIT | PSR_F_BIT)
|
||||
msr cpsr_c, r0 /* Switch back ABT mode */
|
||||
@ -550,34 +394,12 @@ arm_vectorprefetch:
|
||||
sub r3, lr, #4
|
||||
mrs r4, spsr
|
||||
|
||||
/* Then switch back to SVC mode */
|
||||
/* Then switch back to SYS mode */
|
||||
|
||||
mov r0, #(PSR_MODE_SVC | PSR_I_BIT | PSR_F_BIT)
|
||||
mov r0, #(PSR_MODE_SYS | PSR_I_BIT | PSR_F_BIT)
|
||||
msr cpsr_c, r0
|
||||
|
||||
#ifdef CONFIG_BUILD_PROTECTED
|
||||
/* Did we enter from user mode? If so then we need get the values of
|
||||
* USER mode r13(sp) and r14(lr).
|
||||
*/
|
||||
|
||||
and r1, r4, #PSR_MODE_MASK /* Interrupted mode */
|
||||
cmp r1, #PSR_MODE_USR /* User mode? */
|
||||
bne .Lpabtentersvc /* Branch if not user mode */
|
||||
|
||||
/* ldmia with ^ will return the user mode registers (provided that r15
|
||||
* is not in the register list).
|
||||
*/
|
||||
|
||||
add r0, sp, #(4*REG_SP) /* Offset to sp/lr storage */
|
||||
stmia r0, {r13, r14}^ /* Save user mode r13(sp) and r14(lr) */
|
||||
add r0, sp, #(4*REG_R15) /* Offset to pc/cpsr storage */
|
||||
stmia r0, {r3, r4} /* Save r15(pc), and the CPSR */
|
||||
b .Lpabtcontinue
|
||||
|
||||
.Lpabtentersvc:
|
||||
/* Otherwise, get the correct values of SVC r13(sp) and r14(lr) in r1
|
||||
* and r2.
|
||||
*/
|
||||
/* Get the correct values of USR/SYS r13(sp) and r14(lr) in r1 and r2 */
|
||||
|
||||
add r1, sp, #XCPTCONTEXT_SIZE
|
||||
mov r2, r14
|
||||
@ -587,20 +409,6 @@ arm_vectorprefetch:
|
||||
add r0, sp, #(4*REG_SP) /* Offset to pc, cpsr storage */
|
||||
stmia r0, {r1-r4}
|
||||
|
||||
.Lpabtcontinue:
|
||||
|
||||
#else
|
||||
/* Get the correct values of SVC 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 */
|
||||
|
||||
add r0, sp, #(4*REG_SP) /* Offset to pc, cpsr storage */
|
||||
stmia r0, {r1-r4}
|
||||
#endif
|
||||
|
||||
/* Then call the prefetch abort handler with interrupts disabled.
|
||||
* void arm_prefetchabort(struct xcptcontext *xcp)
|
||||
*/
|
||||
@ -620,35 +428,12 @@ arm_vectorprefetch:
|
||||
* context switch is required.
|
||||
*/
|
||||
|
||||
/* Restore the CPSR, SVC mode registers and return */
|
||||
/* 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 */
|
||||
|
||||
#ifdef CONFIG_BUILD_PROTECTED
|
||||
/* Are we leaving in user mode? If so then we need to restore the
|
||||
* values of USER mode r13(sp) and r14(lr).
|
||||
*/
|
||||
|
||||
and r2, r1, #PSR_MODE_MASK /* Interrupted mode */
|
||||
cmp r2, #PSR_MODE_USR /* User mode? */
|
||||
bne .Lpabtleavesvc /* Branch if not user mode */
|
||||
|
||||
add sp, sp, #XCPTCONTEXT_SIZE /* Restore SVC's sp */
|
||||
|
||||
/* ldmia with ^ will return the user mode registers (provided that r15
|
||||
* is not in the register list).
|
||||
*/
|
||||
|
||||
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 */
|
||||
|
||||
.Lpabtleavesvc:
|
||||
#endif
|
||||
/* Life is simple when everything is SVC mode */
|
||||
/* Life is simple when everything is SYS mode */
|
||||
|
||||
ldmia r0, {r0-r15}^ /* Return */
|
||||
.size arm_vectorprefetch, . - arm_vectorprefetch
|
||||
@ -673,15 +458,15 @@ arm_vectorundefinsn:
|
||||
* r13 and r14
|
||||
*/
|
||||
|
||||
mov r13, #(PSR_MODE_SVC | PSR_I_BIT | PSR_F_BIT)
|
||||
msr cpsr_c, r13 /* Switch to SVC mode */
|
||||
mov r13, #(PSR_MODE_SYS | PSR_I_BIT | PSR_F_BIT)
|
||||
msr cpsr_c, r13 /* Switch to SYS mode */
|
||||
|
||||
/* Create a context structure. First set aside a stack frame
|
||||
* and store r0-r12 into the frame.
|
||||
*/
|
||||
|
||||
sub sp, sp, #XCPTCONTEXT_SIZE
|
||||
stmia sp, {r0-r12} /* Save the SVC mode regs */
|
||||
stmia sp, {r0-r12} /* Save the SYS mode regs */
|
||||
|
||||
mov r0, #(PSR_MODE_UND | PSR_I_BIT | PSR_F_BIT)
|
||||
msr cpsr_c, r0 /* Switch back UND mode */
|
||||
@ -691,34 +476,12 @@ arm_vectorundefinsn:
|
||||
mov r3, lr
|
||||
mrs r4, spsr
|
||||
|
||||
/* Then switch back to SVC mode */
|
||||
/* Then switch back to SYS mode */
|
||||
|
||||
mov r0, #(PSR_MODE_SVC | PSR_I_BIT | PSR_F_BIT)
|
||||
mov r0, #(PSR_MODE_SYS | PSR_I_BIT | PSR_F_BIT)
|
||||
msr cpsr_c, r0
|
||||
|
||||
#ifdef CONFIG_BUILD_PROTECTED
|
||||
/* Did we enter from user mode? If so then we need get the values of
|
||||
* USER mode r13(sp) and r14(lr).
|
||||
*/
|
||||
|
||||
and r1, r4, #PSR_MODE_MASK /* Interrupted mode */
|
||||
cmp r1, #PSR_MODE_USR /* User mode? */
|
||||
bne .Lundefentersvc /* Branch if not user mode */
|
||||
|
||||
/* ldmia with ^ will return the user mode registers (provided that r15
|
||||
* is not in the register list).
|
||||
*/
|
||||
|
||||
add r0, sp, #(4*REG_SP) /* Offset to sp/lr storage */
|
||||
stmia r0, {r13, r14}^ /* Save user mode r13(sp) and r14(lr) */
|
||||
add r0, sp, #(4*REG_R15) /* Offset to pc/cpsr storage */
|
||||
stmia r0, {r3, r4} /* Save r15(pc), and the CPSR */
|
||||
b .Lundefcontinue
|
||||
|
||||
.Lundefentersvc:
|
||||
/* Otherwise, get the correct values of SVC r13(sp) and r14(lr) in r1
|
||||
* and r2.
|
||||
*/
|
||||
/* Get the correct values of USR/SYS r13(sp) and r14(lr) in r1 and r2 */
|
||||
|
||||
add r1, sp, #XCPTCONTEXT_SIZE
|
||||
mov r2, r14
|
||||
@ -728,20 +491,6 @@ arm_vectorundefinsn:
|
||||
add r0, sp, #(4*REG_SP) /* Offset to pc, cpsr storage */
|
||||
stmia r0, {r1-r4}
|
||||
|
||||
.Lundefcontinue:
|
||||
|
||||
#else
|
||||
/* Get the correct values of SVC 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 */
|
||||
|
||||
add r0, sp, #(4*REG_SP) /* Offset to pc, cpsr storage */
|
||||
stmia r0, {r1-r4}
|
||||
#endif
|
||||
|
||||
/* Then call the undef insn handler with interrupts disabled.
|
||||
* void arm_undefinedinsn(struct xcptcontext *xcp)
|
||||
*/
|
||||
@ -759,35 +508,12 @@ arm_vectorundefinsn:
|
||||
* context switch is required.
|
||||
*/
|
||||
|
||||
/* Restore the CPSR, SVC mode registers and return */
|
||||
/* 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 */
|
||||
|
||||
#ifdef CONFIG_BUILD_PROTECTED
|
||||
/* Are we leaving in user mode? If so then we need to restore the
|
||||
* values of USER mode r13(sp) and r14(lr).
|
||||
*/
|
||||
|
||||
and r2, r1, #PSR_MODE_MASK /* Interrupted mode */
|
||||
cmp r2, #PSR_MODE_USR /* User mode? */
|
||||
bne .Lundefleavesvc /* Branch if not user mode */
|
||||
|
||||
add sp, sp, #XCPTCONTEXT_SIZE /* Restore SVC's sp */
|
||||
|
||||
/* ldmia with ^ will return the user mode registers (provided that r15
|
||||
* is not in the register list).
|
||||
*/
|
||||
|
||||
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 */
|
||||
|
||||
.Lundefleavesvc:
|
||||
#endif
|
||||
/* Life is simple when everything is SVC mode */
|
||||
/* Life is simple when everything is SYS mode */
|
||||
|
||||
ldmia r0, {r0-r15}^ /* Return */
|
||||
.size arm_vectorundefinsn, . - arm_vectorundefinsn
|
||||
@ -813,15 +539,15 @@ arm_vectorfiq:
|
||||
#ifdef CONFIG_ARMV7R_DECODEFIQ
|
||||
/* On entry we are free to use the FIQ mode registers r8 through r14 */
|
||||
|
||||
mov r13, #(PSR_MODE_SVC | PSR_I_BIT | PSR_F_BIT)
|
||||
msr cpsr_c, r13 /* Switch to SVC mode */
|
||||
mov r13, #(PSR_MODE_SYS | PSR_I_BIT | PSR_F_BIT)
|
||||
msr cpsr_c, r13 /* Switch to SYS mode */
|
||||
|
||||
/* Create a context structure. First set aside a stack frame
|
||||
* and store r0-r12 into the frame.
|
||||
*/
|
||||
|
||||
sub sp, sp, #XCPTCONTEXT_SIZE
|
||||
stmia sp, {r0-r12} /* Save the SVC mode regs */
|
||||
stmia sp, {r0-r12} /* Save the SYS mode regs */
|
||||
|
||||
mov r0, #(PSR_MODE_FIQ | PSR_I_BIT | PSR_F_BIT)
|
||||
msr cpsr_c, r0 /* Switch back FIQ mode */
|
||||
@ -831,34 +557,12 @@ arm_vectorfiq:
|
||||
sub r3, lr, #4
|
||||
mrs r4, spsr
|
||||
|
||||
/* Then switch back to SVC mode */
|
||||
/* Then switch back to SYS mode */
|
||||
|
||||
mov r0, #(PSR_MODE_SVC | PSR_I_BIT | PSR_F_BIT)
|
||||
mov r0, #(PSR_MODE_SYS | PSR_I_BIT | PSR_F_BIT)
|
||||
msr cpsr_c, r0
|
||||
|
||||
#ifdef CONFIG_BUILD_PROTECTED
|
||||
/* Did we enter from user mode? If so then we need get the values of
|
||||
* USER mode r13(sp) and r14(lr).
|
||||
*/
|
||||
|
||||
and r1, r4, #PSR_MODE_MASK /* Interrupted mode */
|
||||
cmp r1, #PSR_MODE_USR /* User mode? */
|
||||
bne .Lfiqentersvc /* Branch if not user mode */
|
||||
|
||||
/* ldmia with ^ will return the user mode registers (provided that r15
|
||||
* is not in the register list).
|
||||
*/
|
||||
|
||||
add r0, sp, #(4*REG_SP) /* Offset to sp/lr storage */
|
||||
stmia r0, {r13, r14}^ /* Save user mode r13(sp) and r14(lr) */
|
||||
add r0, sp, #(4*REG_R15) /* Offset to pc/cpsr storage */
|
||||
stmia r0, {r3, r4} /* Save r15(pc), and the CPSR */
|
||||
b .Lfiqcontinue
|
||||
|
||||
.Lfiqentersvc:
|
||||
/* Otherwise, get the correct values of SVC r13(sp) and r14(lr) in r1
|
||||
* and r2.
|
||||
*/
|
||||
/* Get the correct values of USR/SYS r13(sp) and r14(lr) in r1 and r2 */
|
||||
|
||||
add r1, sp, #XCPTCONTEXT_SIZE
|
||||
mov r2, r14
|
||||
@ -868,20 +572,6 @@ arm_vectorfiq:
|
||||
add r0, sp, #(4*REG_SP) /* Offset to pc, cpsr storage */
|
||||
stmia r0, {r1-r4}
|
||||
|
||||
.Lfiqcontinue:
|
||||
|
||||
#else
|
||||
/* Get the correct values of SVC 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 */
|
||||
|
||||
add r0, sp, #(4*REG_SP) /* Offset to pc, cpsr storage */
|
||||
stmia r0, {r1-r4}
|
||||
#endif
|
||||
|
||||
/* Then call the FIQ handler with interrupts disabled. */
|
||||
|
||||
mov fp, #0 /* Init frame pointer */
|
||||
@ -911,35 +601,12 @@ arm_vectorfiq:
|
||||
* context switch is required.
|
||||
*/
|
||||
|
||||
/* Restore the CPSR, SVC mode registers and return */
|
||||
/* 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 */
|
||||
|
||||
#ifdef CONFIG_BUILD_PROTECTED
|
||||
/* Are we leaving in user mode? If so then we need to restore the
|
||||
* values of USER mode r13(sp) and r14(lr).
|
||||
*/
|
||||
|
||||
and r2, r1, #PSR_MODE_MASK /* Interrupted mode */
|
||||
cmp r2, #PSR_MODE_USR /* User mode? */
|
||||
bne .Lfiqleavesvc /* Branch if not user mode */
|
||||
|
||||
add sp, sp, #XCPTCONTEXT_SIZE /* Restore SVC's sp */
|
||||
|
||||
/* ldmia with ^ will return the user mode registers (provided that r15
|
||||
* is not in the register list).
|
||||
*/
|
||||
|
||||
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 */
|
||||
|
||||
.Lfiqleavesvc:
|
||||
#endif
|
||||
/* Life is simple when everything is SVC mode */
|
||||
/* Life is simple when everything is SYS mode */
|
||||
|
||||
ldmia r0, {r0-r15}^ /* Return */
|
||||
|
||||
|
@ -169,7 +169,7 @@ void up_irqinitialize(void)
|
||||
/* And finally, enable interrupts */
|
||||
|
||||
#ifndef CONFIG_SUPPRESS_INTERRUPTS
|
||||
up_irq_restore(PSR_MODE_SVC | PSR_F_BIT);
|
||||
up_irq_restore(PSR_MODE_SYS | PSR_F_BIT);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -85,18 +85,18 @@ arm_vectorirq:
|
||||
mrs lr, spsr
|
||||
str lr, [r13, #4] /* Save spsr_IRQ */
|
||||
|
||||
/* Then switch back to SVC mode */
|
||||
/* Then switch back to SYS mode */
|
||||
|
||||
bic lr, lr, #PSR_MODE_MASK /* Keep F and T bits */
|
||||
orr lr, lr, #(PSR_MODE_SVC | PSR_I_BIT)
|
||||
msr cpsr_c, lr /* Switch to SVC mode */
|
||||
orr lr, lr, #(PSR_MODE_SYS | PSR_I_BIT)
|
||||
msr cpsr_c, lr /* Switch to SYS mode */
|
||||
|
||||
/* Create a context structure. First set aside a stack frame
|
||||
* and store r0-r12 into the frame.
|
||||
*/
|
||||
|
||||
sub sp, sp, #XCPTCONTEXT_SIZE
|
||||
stmia sp, {r0-r12} /* Save the SVC mode regs */
|
||||
stmia sp, {r0-r12} /* Save the SYS mode regs */
|
||||
|
||||
/* Get the correct values of r13(sp) and r14(lr) in r1 and r2 */
|
||||
|
||||
@ -153,9 +153,9 @@ arm_vectorirq:
|
||||
bl arm_doirq /* Call the handler */
|
||||
#endif
|
||||
|
||||
/* Restore the CPSR, SVC mode registers and return */
|
||||
/* Restore the CPSR, SYS mode registers and return */
|
||||
.Lnoirqset:
|
||||
ldr r0, [sp, #(4*REG_CPSR)] /* Setup the SVC mode SPSR */
|
||||
ldr r0, [sp, #(4*REG_CPSR)] /* Setup the SYS mode SPSR */
|
||||
msr spsr_cxsf, r0
|
||||
ldmia sp, {r0-r15}^ /* Return */
|
||||
|
||||
@ -171,7 +171,7 @@ arm_vectorirq:
|
||||
* Function: arm_vectorsvc
|
||||
*
|
||||
* Description:
|
||||
* SWI interrupt. We enter the SWI in SVC mode
|
||||
* SWI interrupt. We enter the SWI in SYS mode
|
||||
****************************************************************************/
|
||||
|
||||
.globl arm_vectorsvc
|
||||
@ -191,7 +191,7 @@ arm_vectorsvc:
|
||||
*/
|
||||
|
||||
sub sp, sp, #XCPTCONTEXT_SIZE
|
||||
stmia sp, {r0-r12} /* Save the SVC mode regs */
|
||||
stmia sp, {r0-r12} /* Save the SYS mode regs */
|
||||
|
||||
/* Get the correct values of r13(sp), r14(lr), r15(pc)
|
||||
* and CPSR in r1-r4 */
|
||||
@ -212,9 +212,9 @@ arm_vectorsvc:
|
||||
mov r0, sp /* Get r0=xcp */
|
||||
bl arm_syscall /* Call the handler */
|
||||
|
||||
/* Restore the CPSR, SVC mode registers and return */
|
||||
/* Restore the CPSR, SYS mode registers and return */
|
||||
|
||||
ldr r0, [sp, #(4*REG_CPSR)] /* Setup the SVC mode SPSR */
|
||||
ldr r0, [sp, #(4*REG_CPSR)] /* Setup the SYS mode SPSR */
|
||||
msr spsr_cxsf, r0
|
||||
ldmia sp, {r0-r15}^ /* Return */
|
||||
|
||||
@ -243,18 +243,18 @@ arm_vectordata:
|
||||
mrs lr, spsr /* Get SPSR */
|
||||
str lr, [r13, #4] /* Save in temp storage */
|
||||
|
||||
/* Then switch back to SVC mode */
|
||||
/* Then switch back to SYS mode */
|
||||
|
||||
bic lr, lr, #PSR_MODE_MASK /* Keep F and T bits */
|
||||
orr lr, lr, #(PSR_MODE_SVC | PSR_I_BIT)
|
||||
msr cpsr_c, lr /* Switch to SVC mode */
|
||||
orr lr, lr, #(PSR_MODE_SYS | PSR_I_BIT)
|
||||
msr cpsr_c, lr /* Switch to SYS mode */
|
||||
|
||||
/* Create a context structure. First set aside a stack frame
|
||||
* and store r0-r12 into the frame.
|
||||
*/
|
||||
|
||||
sub sp, sp, #XCPTCONTEXT_SIZE
|
||||
stmia sp, {r0-r12} /* Save the SVC mode regs */
|
||||
stmia sp, {r0-r12} /* Save the SYS mode regs */
|
||||
|
||||
/* Get the correct values of r13(sp) and r14(lr) in r1 and r2 */
|
||||
|
||||
@ -277,9 +277,9 @@ arm_vectordata:
|
||||
mov r0, sp /* Get r0=xcp */
|
||||
bl arm_dataabort /* Call the handler */
|
||||
|
||||
/* Restore the CPSR, SVC mode registers and return */
|
||||
/* Restore the CPSR, SYS mode registers and return */
|
||||
|
||||
ldr r0, [sp, #(4*REG_CPSR)] /* Setup the SVC mode SPSR */
|
||||
ldr r0, [sp, #(4*REG_CPSR)] /* Setup the SYS mode SPSR */
|
||||
msr spsr_cxsf, r0
|
||||
ldmia sp, {r0-r15}^ /* Return */
|
||||
|
||||
@ -309,18 +309,18 @@ arm_vectorprefetch:
|
||||
mrs lr, spsr /* Get SPSR */
|
||||
str lr, [r13, #4] /* Save in temp storage */
|
||||
|
||||
/* Then switch back to SVC mode */
|
||||
/* Then switch back to SYS mode */
|
||||
|
||||
bic lr, lr, #PSR_MODE_MASK /* Keep F and T bits */
|
||||
orr lr, lr, #(PSR_MODE_SVC | PSR_I_BIT)
|
||||
msr cpsr_c, lr /* Switch to SVC mode */
|
||||
orr lr, lr, #(PSR_MODE_SYS | PSR_I_BIT)
|
||||
msr cpsr_c, lr /* Switch to SYS mode */
|
||||
|
||||
/* Create a context structure. First set aside a stack frame
|
||||
* and store r0-r12 into the frame.
|
||||
*/
|
||||
|
||||
sub sp, sp, #XCPTCONTEXT_SIZE
|
||||
stmia sp, {r0-r12} /* Save the SVC mode regs */
|
||||
stmia sp, {r0-r12} /* Save the SYS mode regs */
|
||||
|
||||
/* Get the correct values of r13(sp) and r14(lr) in r1 and r2 */
|
||||
|
||||
@ -343,9 +343,9 @@ arm_vectorprefetch:
|
||||
mov r0, sp /* Get r0=xcp */
|
||||
bl arm_prefetchabort /* Call the handler */
|
||||
|
||||
/* Restore the CPSR, SVC mode registers and return */
|
||||
/* Restore the CPSR, SYS mode registers and return */
|
||||
|
||||
ldr r0, [sp, #(4*REG_CPSR)] /* Setup the SVC mode SPSR */
|
||||
ldr r0, [sp, #(4*REG_CPSR)] /* Setup the SYS mode SPSR */
|
||||
msr spsr_cxsf, r0
|
||||
ldmia sp, {r0-r15}^ /* Return */
|
||||
|
||||
@ -375,18 +375,18 @@ arm_vectorundefinsn:
|
||||
mrs lr, spsr /* Get SPSR */
|
||||
str lr, [r13, #4] /* Save in temp storage */
|
||||
|
||||
/* Then switch back to SVC mode */
|
||||
/* Then switch back to SYS mode */
|
||||
|
||||
bic lr, lr, #PSR_MODE_MASK /* Keep F and T bits */
|
||||
orr lr, lr, #(PSR_MODE_SVC | PSR_I_BIT)
|
||||
msr cpsr_c, lr /* Switch to SVC mode */
|
||||
orr lr, lr, #(PSR_MODE_SYS | PSR_I_BIT)
|
||||
msr cpsr_c, lr /* Switch to SYS mode */
|
||||
|
||||
/* Create a context structure. First set aside a stack frame
|
||||
* and store r0-r12 into the frame.
|
||||
*/
|
||||
|
||||
sub sp, sp, #XCPTCONTEXT_SIZE
|
||||
stmia sp, {r0-r12} /* Save the SVC mode regs */
|
||||
stmia sp, {r0-r12} /* Save the SYS mode regs */
|
||||
|
||||
/* Get the correct values of r13(sp) and r14(lr) in r1 and r2 */
|
||||
|
||||
@ -409,9 +409,9 @@ arm_vectorundefinsn:
|
||||
mov r0, sp /* Get r0=xcp */
|
||||
bl arm_undefinedinsn /* Call the handler */
|
||||
|
||||
/* Restore the CPSR, SVC mode registers and return */
|
||||
/* Restore the CPSR, SYS mode registers and return */
|
||||
|
||||
ldr r0, [sp, #(4*REG_CPSR)] /* Setup the SVC mode SPSR */
|
||||
ldr r0, [sp, #(4*REG_CPSR)] /* Setup the SYS mode SPSR */
|
||||
msr spsr_cxsf, r0
|
||||
ldmia sp, {r0-r15}^ /* Return */
|
||||
|
||||
|
@ -105,7 +105,7 @@ void up_irqinitialize(void)
|
||||
/* And finally, enable interrupts */
|
||||
|
||||
#ifndef CONFIG_SUPPRESS_INTERRUPTS
|
||||
up_irq_restore(PSR_MODE_SVC | PSR_F_BIT);
|
||||
up_irq_restore(PSR_MODE_SYS | PSR_F_BIT);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -51,9 +51,9 @@
|
||||
.globl up_restart
|
||||
.type up_restart, %function
|
||||
up_restart:
|
||||
/* Make sure that we are in SVC mode with all IRQs disabled */
|
||||
/* Make sure that we are in SYS mode with all IRQs disabled */
|
||||
|
||||
mov r0, #(PSR_MODE_SVC | PSR_I_BIT | PSR_F_BIT)
|
||||
mov r0, #(PSR_MODE_SYS | PSR_I_BIT | PSR_F_BIT)
|
||||
msr cpsr_c, r0
|
||||
|
||||
/* Create identity mapping for first MB section to support
|
||||
|
@ -89,7 +89,7 @@ void up_irqinitialize(void)
|
||||
|
||||
/* And finally, enable interrupts */
|
||||
|
||||
up_irq_restore(PSR_MODE_SVC | PSR_F_BIT);
|
||||
up_irq_restore(PSR_MODE_SYS | PSR_F_BIT);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -494,7 +494,7 @@ _vector_table:
|
||||
__start:
|
||||
/* Setup the initial processor mode */
|
||||
|
||||
mov r0, #(PSR_MODE_SVC | PSR_I_BIT | PSR_F_BIT )
|
||||
mov r0, #(PSR_MODE_SYS | PSR_I_BIT | PSR_F_BIT )
|
||||
msr cpsr, r0
|
||||
|
||||
/* Set up external memory mode (if so selected) */
|
||||
|
@ -100,7 +100,7 @@ void up_irqinitialize(void)
|
||||
/* And finally, enable interrupts */
|
||||
|
||||
#ifndef CONFIG_SUPPRESS_INTERRUPTS
|
||||
up_irq_restore(PSR_MODE_SVC | PSR_F_BIT);
|
||||
up_irq_restore(PSR_MODE_SYS | PSR_F_BIT);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -144,7 +144,7 @@ __start:
|
||||
|
||||
/* First, setup initial processor mode */
|
||||
|
||||
mov r0, #(PSR_MODE_SVC | PSR_I_BIT | PSR_F_BIT )
|
||||
mov r0, #(PSR_MODE_SYS | PSR_I_BIT | PSR_F_BIT )
|
||||
msr cpsr, r0
|
||||
|
||||
/* Configure the uart so that we can get debug output as soon
|
||||
|
@ -117,7 +117,7 @@ void up_irqinitialize(void)
|
||||
/* Enable global ARM interrupts */
|
||||
|
||||
#ifndef CONFIG_SUPPRESS_INTERRUPTS
|
||||
up_irq_restore(PSR_MODE_SVC | PSR_F_BIT);
|
||||
up_irq_restore(PSR_MODE_SYS | PSR_F_BIT);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -113,7 +113,7 @@ void up_irqinitialize(void)
|
||||
#ifndef CONFIG_SUPPRESS_INTERRUPTS
|
||||
/* And finally, enable interrupts */
|
||||
|
||||
up_irq_restore(PSR_MODE_SVC | PSR_F_BIT);
|
||||
up_irq_restore(PSR_MODE_SYS | PSR_F_BIT);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -138,7 +138,7 @@ void up_irqinitialize(void)
|
||||
getreg32(0x98800020));
|
||||
|
||||
#ifndef CONFIG_SUPPRESS_INTERRUPTS
|
||||
up_irq_restore(PSR_MODE_SVC | PSR_F_BIT);
|
||||
up_irq_restore(PSR_MODE_SYS | PSR_F_BIT);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -470,7 +470,7 @@ __flashstart:
|
||||
|
||||
/* Setup the initial processor mode */
|
||||
|
||||
mov r0, #(PSR_MODE_SVC | PSR_I_BIT | PSR_F_BIT )
|
||||
mov r0, #(PSR_MODE_SYS | PSR_I_BIT | PSR_F_BIT )
|
||||
msr cpsr, r0
|
||||
|
||||
/* Initialize the external memory interface (EMI) */
|
||||
|
@ -88,7 +88,7 @@ void up_irqinitialize(void)
|
||||
/* Enable global ARM interrupts */
|
||||
|
||||
#ifndef CONFIG_SUPPRESS_INTERRUPTS
|
||||
up_irq_restore(PSR_MODE_SVC | PSR_F_BIT);
|
||||
up_irq_restore(PSR_MODE_SYS | PSR_F_BIT);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user