From eeb8931c04b3bf601a187076ec732a6cfa2f8865 Mon Sep 17 00:00:00 2001 From: Xiang Xiao Date: Mon, 5 Apr 2021 23:43:27 +0800 Subject: [PATCH] arch/arm: align arm vector related code with armv7-a commit 3c30c8b90b1dc48e4b9e0c18aaeb3989fb168ae9 Author: Xiang Xiao Date: Tue Apr 6 15:47:27 2021 +0800 arch/arm: Remove g_irqtmp, g_undeftmp and g_aborttmp to avoid multiple CPU access them concurrently in SMP case Signed-off-by: Xiang Xiao --- arch/arm/src/arm/arm_fullcontextrestore.S | 4 +- arch/arm/src/arm/arm_saveusercontext.S | 4 +- arch/arm/src/arm/arm_vectors.S | 213 ++++++++++------------ arch/arm/src/arm/arm_vectortab.S | 8 +- arch/arm/src/c5471/c5471_irq.c | 2 +- arch/arm/src/c5471/c5471_vectors.S | 8 +- arch/arm/src/common/arm_internal.h | 2 +- arch/arm/src/lpc214x/lpc214x_head.S | 4 +- arch/arm/src/lpc2378/lpc23xx_head.S | 4 +- arch/arm/src/moxart/moxart_head.S | 2 +- arch/arm/src/str71x/str71x_head.S | 4 +- 11 files changed, 121 insertions(+), 134 deletions(-) diff --git a/arch/arm/src/arm/arm_fullcontextrestore.S b/arch/arm/src/arm/arm_fullcontextrestore.S index 8b37f271a6..97cc179a14 100644 --- a/arch/arm/src/arm/arm_fullcontextrestore.S +++ b/arch/arm/src/arm/arm_fullcontextrestore.S @@ -89,9 +89,7 @@ arm_fullcontextrestore: ldr r1, [r0, #(4*REG_CPSR)] /* Fetch the stored CPSR value */ msr cpsr, r1 /* Set the CPSR */ - /* Now recover r0 and r1. Then return to the address at the stop of - * the stack, destroying the stack frame - */ + /* Now recover r0-r1 and pc, destroying the stack frame */ ldmia sp!, {r0-r1, r15} diff --git a/arch/arm/src/arm/arm_saveusercontext.S b/arch/arm/src/arm/arm_saveusercontext.S index a3378ffd83..fe16a3a4b6 100644 --- a/arch/arm/src/arm/arm_saveusercontext.S +++ b/arch/arm/src/arm/arm_saveusercontext.S @@ -92,9 +92,9 @@ arm_saveusercontext: add r1, r0, #(4*REG_PC) str lr, [r1] - /* Return 0 */ + /* Return 0 now indicating that this return is not a context switch */ mov r0, #0 /* Return value == 0 */ - mov pc, lr /* Return */ + bx lr /* Return */ .size arm_saveusercontext, .-arm_saveusercontext .end diff --git a/arch/arm/src/arm/arm_vectors.S b/arch/arm/src/arm/arm_vectors.S index 5616988ef6..2f16255aab 100644 --- a/arch/arm/src/arm/arm_vectors.S +++ b/arch/arm/src/arm/arm_vectors.S @@ -37,19 +37,6 @@ * Private Data ****************************************************************************/ - .data -g_irqtmp: - .word 0 /* Saved lr */ - .word 0 /* Saved spsr */ - -g_undeftmp: - .word 0 /* Saved lr */ - .word 0 /* Saved spsr */ - -g_aborttmp: - .word 0 /* Saved lr */ - .word 0 /* Saved spsr */ - /**************************************************************************** * Assembly Macros ****************************************************************************/ @@ -81,17 +68,8 @@ arm_vectorirq: * and r14. */ - ldr r13, .Lirqtmp - sub lr, lr, #4 - str lr, [r13] /* Save lr_IRQ */ - mrs lr, spsr - str lr, [r13, #4] /* Save spsr_IRQ */ - - /* Then switch back to SVC 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 */ + mov r13, #(PSR_MODE_SVC | PSR_I_BIT) + msr cpsr_c, r13 /* Switch to SVC mode */ /* Create a context structure. First set aside a stack frame * and store r0-r12 into the frame. @@ -100,15 +78,25 @@ arm_vectorirq: sub sp, sp, #XCPTCONTEXT_SIZE stmia sp, {r0-r12} /* Save the SVC mode regs */ - /* Get the correct values of r13(sp) and r14(lr) in r1 and r2 */ + mov r0, #(PSR_MODE_IRQ | PSR_I_BIT) + msr cpsr_c, r0 /* Switch back IRQ mode */ + + /* Get the values for r15(pc) and CPSR in r3 and r4 */ + + sub r3, lr, #4 + mrs r4, spsr + + /* Then switch back to SVC mode */ + + orr r0, r0, #(PSR_MODE_SVC | PSR_I_BIT) + msr cpsr_c, r0 + + /* Get the correct values of SVC r13(sp) and r14(lr) in r1 and r2 */ add r1, sp, #XCPTCONTEXT_SIZE mov r2, r14 - /* Get the values for r15(pc) and CPSR in r3 and r4 */ - - ldr r0, .Lirqtmp /* Points to temp storage */ - ldmia r0, {r3, r4} /* Recover r3=lr_IRQ, r4=spsr_IRQ */ + /* 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} @@ -119,44 +107,45 @@ arm_vectorirq: mov r0, sp /* Get r0=xcp */ #if CONFIG_ARCH_INTERRUPTSTACK > 3 + /* Call arm_decodeirq() on the interrupt stack */ + ldr sp, .Lirqstackbase /* SP = interrupt stack base */ str r0, [sp, #-4]! /* Save the xcp address at SP-4 then update SP */ bl arm_decodeirq /* Call the handler */ ldr sp, [sp] /* Restore the user stack pointer */ #else + /* Call arm_decodeirq() on the user stack */ + bl arm_decodeirq /* Call the handler */ #endif /* Restore the CPSR, SVC mode registers and return */ -.Lnoirqset: - ldr r0, [sp, #(4*REG_CPSR)] /* Setup the SVC mode SPSR */ - msr spsr, r0 - ldmia sp, {r0-r15}^ /* Return */ -.Lirqtmp: - .word g_irqtmp + ldr r0, [sp, #(4*REG_CPSR)] /* Fetch the return SPSR */ + msr spsr, r0 /* Set the return mode SPSR */ + ldmia sp, {r0-r15}^ /* Return */ #if CONFIG_ARCH_INTERRUPTSTACK > 3 .Lirqstackbase: .word g_intstackbase #endif - .size arm_vectorirq, . - arm_vectorirq + .align 5 /**************************************************************************** - * Function: arm_vectorswi + * Function: arm_vectorsvc * * Description: - * SWI interrupt. We enter the SWI in SVC mode. + * SVC interrupt. We enter the SVC in SVC mode. * ****************************************************************************/ .globl arm_syscall - .globl arm_vectorswi - .type arm_vectorswi, %function + .globl arm_vectorsvc + .type arm_vectorsvc, %function -arm_vectorswi: +arm_vectorsvc: /* Create a context structure. First set aside a stack frame * and store r0-r12 into the frame. @@ -165,18 +154,22 @@ arm_vectorswi: sub sp, sp, #XCPTCONTEXT_SIZE stmia sp, {r0-r12} /* Save the SVC mode regs */ - /* Get the correct values of r13(sp), r14(lr), r15(pc) - * and CPSR in r1-r4 */ + /* Get the values for r15(pc) and CPSR in r3 and r4 */ - add r1, sp, #XCPTCONTEXT_SIZE - mov r2, r14 /* R14 is altered on return from SWI */ mov r3, r14 /* Save r14 as the PC as well */ mrs r4, spsr /* Get the saved CPSR */ + /* 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} - /* Then call the SWI handler with interrupts disabled. + /* Then call the SVC handler with interrupts disabled. * void arm_syscall(struct xcptcontext *xcp) */ @@ -186,10 +179,10 @@ arm_vectorswi: /* Restore the CPSR, SVC mode registers and return */ - ldr r0, [sp, #(4*REG_CPSR)] /* Setup the SVC mode SPSR */ - msr spsr, r0 + ldr r0, [sp, #(4*REG_CPSR)] /* Fetch the return SPSR */ + msr spsr, r0 /* Set the return mode SPSR */ ldmia sp, {r0-r15}^ /* Return */ - .size arm_vectorswi, . - arm_vectorswi + .size arm_vectorsvc, . - arm_vectorsvc .align 5 @@ -213,17 +206,8 @@ arm_vectordata: * r13 and r14 */ - ldr r13, .Ldaborttmp /* Points to temp storage */ - sub lr, lr, #8 /* Fixup return */ - str lr, [r13] /* Save in temp storage */ - mrs lr, spsr /* Get SPSR */ - str lr, [r13, #4] /* Save in temp storage */ - - /* Then switch back to SVC 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 */ + mov r13, #(PSR_MODE_SVC | PSR_I_BIT) + msr cpsr_c, r13 /* Switch to SVC mode */ /* Create a context structure. First set aside a stack frame * and store r0-r12 into the frame. @@ -232,15 +216,25 @@ arm_vectordata: sub sp, sp, #XCPTCONTEXT_SIZE stmia sp, {r0-r12} /* Save the SVC mode regs */ - /* Get the correct values of r13(sp) and r14(lr) in r1 and r2 */ + mov r0, #(PSR_MODE_ABT | PSR_I_BIT) + msr cpsr_c, r0 /* Switch back ABT mode */ + + /* Get the values for r15(pc) and CPSR in r3 and r4 */ + + sub r3, lr, #8 + mrs r4, spsr + + /* Then switch back to SVC mode */ + + mov r0, #(PSR_MODE_SVC | PSR_I_BIT) + msr cpsr_c, r0 + + /* Get the correct values of SVC r13(sp) and r14(lr) in r1 and r2 */ add r1, sp, #XCPTCONTEXT_SIZE mov r2, r14 - /* Get the values for r15(pc) and CPSR in r3 and r4 */ - - ldr r0, .Ldaborttmp /* Points to temp storage */ - ldmia r0, {r3, r4} /* Recover r3=lr_IRQ, r4=spsr_IRQ */ + /* 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} @@ -252,19 +246,16 @@ arm_vectordata: mov fp, #0 /* Init frame pointer */ mov r0, sp /* Get r0=xcp */ #ifdef CONFIG_PAGING - mrc p15, 0, r2, c5, c0, 0 /* Get r2=FSR */ mrc p15, 0, r1, c6, c0, 0 /* Get R1=FAR */ + mrc p15, 0, r2, c5, c0, 0 /* Get r2=FSR */ #endif bl arm_dataabort /* Call the handler */ /* Restore the CPSR, SVC mode registers and return */ - ldr r0, [sp, #(4*REG_CPSR)] /* Setup the SVC mode SPSR */ - msr spsr, r0 + ldr r0, [sp, #(4*REG_CPSR)] /* Fetch the return SPSR */ + msr spsr, r0 /* Set the return mode SPSR */ ldmia sp, {r0-r15}^ /* Return */ - -.Ldaborttmp: - .word g_aborttmp .size arm_vectordata, . - arm_vectordata .align 5 @@ -289,17 +280,8 @@ arm_vectorprefetch: * r13 and r14 */ - ldr r13, .Lpaborttmp /* Points to temp storage */ - sub lr, lr, #4 /* Fixup return */ - str lr, [r13] /* Save in temp storage */ - mrs lr, spsr /* Get SPSR */ - str lr, [r13, #4] /* Save in temp storage */ - - /* Then switch back to SVC 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 */ + mov r13, #(PSR_MODE_SVC | PSR_I_BIT) + msr cpsr_c, r13 /* Switch to SVC mode */ /* Create a context structure. First set aside a stack frame * and store r0-r12 into the frame. @@ -308,15 +290,25 @@ arm_vectorprefetch: sub sp, sp, #XCPTCONTEXT_SIZE stmia sp, {r0-r12} /* Save the SVC mode regs */ - /* Get the correct values of r13(sp) and r14(lr) in r1 and r2 */ + mov r0, #(PSR_MODE_ABT | PSR_I_BIT) + msr cpsr_c, r0 /* Switch back ABT mode */ + + /* Get the values for r15(pc) and CPSR in r3 and r4 */ + + sub r3, lr, #4 + mrs r4, spsr + + /* Then switch back to SVC mode */ + + mov r0, #(PSR_MODE_SVC | PSR_I_BIT) + msr cpsr_c, r0 + + /* Get the correct values of SVC r13(sp) and r14(lr) in r1 and r2 */ add r1, sp, #XCPTCONTEXT_SIZE mov r2, r14 - /* Get the values for r15(pc) and CPSR in r3 and r4 */ - - ldr r0, .Lpaborttmp /* Points to temp storage */ - ldmia r0, {r3, r4} /* Recover r3=lr_IRQ, r4=spsr_IRQ */ + /* 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} @@ -331,12 +323,9 @@ arm_vectorprefetch: /* Restore the CPSR, SVC mode registers and return */ - ldr r0, [sp, #(4*REG_CPSR)] /* Setup the SVC mode SPSR */ - msr spsr, r0 + ldr r0, [sp, #(4*REG_CPSR)] /* Fetch the return SPSR */ + msr spsr, r0 /* Set the return mode SPSR */ ldmia sp, {r0-r15}^ /* Return */ - -.Lpaborttmp: - .word g_aborttmp .size arm_vectorprefetch, . - arm_vectorprefetch .align 5 @@ -359,16 +348,8 @@ arm_vectorundefinsn: * r13 and r14 */ - ldr r13, .Lundeftmp /* Points to temp storage */ - str lr, [r13] /* Save in temp storage */ - mrs lr, spsr /* Get SPSR */ - str lr, [r13, #4] /* Save in temp storage */ - - /* Then switch back to SVC 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 */ + mov r13, #(PSR_MODE_SVC | PSR_I_BIT) + msr cpsr_c, r13 /* Switch to SVC mode */ /* Create a context structure. First set aside a stack frame * and store r0-r12 into the frame. @@ -377,15 +358,25 @@ arm_vectorundefinsn: sub sp, sp, #XCPTCONTEXT_SIZE stmia sp, {r0-r12} /* Save the SVC mode regs */ - /* Get the correct values of r13(sp) and r14(lr) in r1 and r2 */ + mov r0, #(PSR_MODE_UND | PSR_I_BIT) + msr cpsr_c, r0 /* Switch back UND mode */ + + /* Get the values for r15(pc) and CPSR in r3 and r4 */ + + mov r3, lr + mrs r4, spsr + + /* Then switch back to SVC mode */ + + mov r0, #(PSR_MODE_SVC | PSR_I_BIT) + msr cpsr_c, r0 + + /* Get the correct values of SVC r13(sp) and r14(lr) in r1 and r2 */ add r1, sp, #XCPTCONTEXT_SIZE mov r2, r14 - /* Get the values for r15(pc) and CPSR in r3 and r4 */ - - ldr r0, .Lundeftmp /* Points to temp storage */ - ldmia r0, {r3, r4} /* Recover r3=lr_IRQ, r4=spsr_IRQ */ + /* 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} @@ -400,12 +391,9 @@ arm_vectorundefinsn: /* Restore the CPSR, SVC mode registers and return */ - ldr r0, [sp, #(4*REG_CPSR)] /* Setup the SVC mode SPSR */ - msr spsr, r0 + ldr r0, [sp, #(4*REG_CPSR)] /* Fetch the return SPSR */ + msr spsr, r0 /* Set the return mode SPSR */ ldmia sp, {r0-r15}^ /* Return */ - -.Lundeftmp: - .word g_undeftmp .size arm_vectorundefinsn, . - arm_vectorundefinsn .align 5 @@ -444,5 +432,6 @@ g_intstackbase: .skip 4 .size g_intstackbase, 4 .size g_intstackalloc, (CONFIG_ARCH_INTERRUPTSTACK & ~3) + #endif .end diff --git a/arch/arm/src/arm/arm_vectortab.S b/arch/arm/src/arm/arm_vectortab.S index d2342907de..b2f6be8ce3 100644 --- a/arch/arm/src/arm/arm_vectortab.S +++ b/arch/arm/src/arm/arm_vectortab.S @@ -55,7 +55,7 @@ _vector_start: ldr pc, .Lresethandler /* 0x00: Reset */ ldr pc, .Lundefinedhandler /* 0x04: Undefined instruction */ - ldr pc, .Lswihandler /* 0x08: Software interrupt */ + ldr pc, .Lsvchandler /* 0x08: Software interrupt */ ldr pc, .Lprefetchaborthandler /* 0x0c: Prefetch abort */ ldr pc, .Ldataaborthandler /* 0x10: Data abort */ ldr pc, .Laddrexcptnhandler /* 0x14: Address exception (reserved) */ @@ -64,7 +64,7 @@ _vector_start: .globl __start .globl arm_vectorundefinsn - .globl arm_vectorswi + .globl arm_vectorsvc .globl arm_vectorprefetch .globl arm_vectordata .globl arm_vectoraddrexcptn @@ -75,8 +75,8 @@ _vector_start: .long __start .Lundefinedhandler: .long arm_vectorundefinsn -.Lswihandler: - .long arm_vectorswi +.Lsvchandler: + .long arm_vectorsvc .Lprefetchaborthandler: .long arm_vectorprefetch .Ldataaborthandler: diff --git a/arch/arm/src/c5471/c5471_irq.c b/arch/arm/src/c5471/c5471_irq.c index d5a0b19db8..522e5a345f 100644 --- a/arch/arm/src/c5471/c5471_irq.c +++ b/arch/arm/src/c5471/c5471_irq.c @@ -70,7 +70,7 @@ static up_vector_t g_vectorinittab[] = { (up_vector_t)NULL, arm_vectorundefinsn, - arm_vectorswi, + arm_vectorsvc, arm_vectorprefetch, arm_vectordata, arm_vectoraddrexcptn, diff --git a/arch/arm/src/c5471/c5471_vectors.S b/arch/arm/src/c5471/c5471_vectors.S index 10f369f04f..bc65435fcf 100644 --- a/arch/arm/src/c5471/c5471_vectors.S +++ b/arch/arm/src/c5471/c5471_vectors.S @@ -168,15 +168,15 @@ arm_vectorirq: .align 5 /**************************************************************************** - * Function: arm_vectorswi + * Function: arm_vectorsvc * * Description: * SWI interrupt. We enter the SWI in SVC mode ****************************************************************************/ - .globl arm_vectorswi - .type arm_vectorswi, %function -arm_vectorswi: + .globl arm_vectorsvc + .type arm_vectorsvc, %function +arm_vectorsvc: /* The c547x rrload bootloader intemediates all * interrupts. For the* case of the SWI, it mucked diff --git a/arch/arm/src/common/arm_internal.h b/arch/arm/src/common/arm_internal.h index 18abc47b1f..e834972a68 100644 --- a/arch/arm/src/common/arm_internal.h +++ b/arch/arm/src/common/arm_internal.h @@ -393,7 +393,7 @@ void arm_undefinedinsn(uint32_t *regs); #endif /* CONFIG_ARCH_ARMV[6-8]M */ void arm_vectorundefinsn(void); -void arm_vectorswi(void); +void arm_vectorsvc(void); void arm_vectorprefetch(void); void arm_vectordata(void); void arm_vectoraddrexcptn(void); diff --git a/arch/arm/src/lpc214x/lpc214x_head.S b/arch/arm/src/lpc214x/lpc214x_head.S index 637e7c52b6..0c12c09313 100644 --- a/arch/arm/src/lpc214x/lpc214x_head.S +++ b/arch/arm/src/lpc214x/lpc214x_head.S @@ -457,7 +457,7 @@ _vector_table: .globl __start .globl arm_vectorundefinsn - .globl arm_vectorswi + .globl arm_vectorsvc .globl arm_vectorprefetch .globl arm_vectordata .globl arm_vectorirq @@ -468,7 +468,7 @@ _vector_table: .Lundefinedhandler: .long arm_vectorundefinsn .Lswihandler: - .long arm_vectorswi + .long arm_vectorsvc .Lprefetchaborthandler: .long arm_vectorprefetch .Ldataaborthandler: diff --git a/arch/arm/src/lpc2378/lpc23xx_head.S b/arch/arm/src/lpc2378/lpc23xx_head.S index 47e02d7593..3042631580 100644 --- a/arch/arm/src/lpc2378/lpc23xx_head.S +++ b/arch/arm/src/lpc2378/lpc23xx_head.S @@ -100,7 +100,7 @@ _vector_table: .globl __start .globl arm_vectorundefinsn - .globl arm_vectorswi + .globl arm_vectorsvc .globl arm_vectorprefetch .globl arm_vectordata .globl arm_vectorirq @@ -111,7 +111,7 @@ _vector_table: .Lundefinedhandler: .long arm_vectorundefinsn .Lswihandler: - .long arm_vectorswi + .long arm_vectorsvc .Lprefetchaborthandler: .long arm_vectorprefetch .Ldataaborthandler: diff --git a/arch/arm/src/moxart/moxart_head.S b/arch/arm/src/moxart/moxart_head.S index 32dd36ada8..10cd3f176c 100644 --- a/arch/arm/src/moxart/moxart_head.S +++ b/arch/arm/src/moxart/moxart_head.S @@ -47,7 +47,7 @@ _undef_instr: b arm_vectorundefinsn _sw_interr: - b arm_vectorswi + b arm_vectorsvc _prefetch_abort: b arm_vectorprefetch _data_abort: diff --git a/arch/arm/src/str71x/str71x_head.S b/arch/arm/src/str71x/str71x_head.S index 0e92efb68b..6a404f6822 100644 --- a/arch/arm/src/str71x/str71x_head.S +++ b/arch/arm/src/str71x/str71x_head.S @@ -421,7 +421,7 @@ _vector_table: .globl __start .globl arm_vectorundefinsn - .globl arm_vectorswi + .globl arm_vectorsvc .globl arm_vectorprefetch .globl arm_vectordata .globl arm_vectorirq @@ -432,7 +432,7 @@ _vector_table: .Lundefinedhandler: .long arm_vectorundefinsn .Lswihandler: - .long arm_vectorswi + .long arm_vectorsvc .Lprefetchaborthandler: .long arm_vectorprefetch .Ldataaborthandler: