You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by xi...@apache.org on 2023/08/07 12:43:20 UTC
[nuttx] branch master updated (bfc51d6a87 -> 8d21bbf3be)
This is an automated email from the ASF dual-hosted git repository.
xiaoxiang pushed a change to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git
from bfc51d6a87 boards: cxd56xx: Fix duplicate make target
new 4370487fd6 arch/armv7-m: Add CONTROL register to xcptcontext.
new 816b3fb399 arch/armv7-m: Supports interrupt nesting
new a4b6b158ce arch/armv6-m: By default, add REG_EXC_RETURN to xcptcontext.
new eba9c61cad arch/armv6-m: Add CONTROL register to xcptcontext.
new cedc034d9e arch/tlsr82: Port arm_doirq to tc32_doirq.c
new 2684642a7a arch/armv6-m: Supports interrupt nesting
new f8aaed780a arch/armv8-m: Add CONTROL register to xcptcontext.
new 5cdfa6fec4 arch/armv8-m: Supports interrupt nesting
new 8d21bbf3be arch/armv8-m: Supports interrupt nesting between TEE and REE
The 9 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails. The revisions
listed as "add" were already present in the repository and have only
been added to this reference.
Summary of changes:
arch/arm/include/armv6-m/irq.h | 14 +---
arch/arm/include/armv7-m/irq.h | 5 +-
arch/arm/include/armv8-m/irq.h | 5 +-
arch/arm/include/tlsr82/irq.h | 5 ++
arch/arm/src/armv6-m/arm_doirq.c | 18 ++---
arch/arm/src/armv6-m/arm_exception.S | 74 +++++---------------
arch/arm/src/armv6-m/arm_initialstate.c | 49 ++++++++++++-
arch/arm/src/armv6-m/arm_saveusercontext.S | 8 +--
arch/arm/src/armv6-m/arm_schedulesigaction.c | 17 +++--
arch/arm/src/armv6-m/arm_svcall.c | 40 +++++++----
arch/arm/src/armv6-m/exc_return.h | 16 ++---
arch/arm/src/armv7-m/arm_doirq.c | 18 ++---
arch/arm/src/armv7-m/arm_exception.S | 81 ++++++----------------
arch/arm/src/armv7-m/arm_initialstate.c | 46 +++++++++++-
arch/arm/src/armv7-m/arm_schedulesigaction.c | 17 +++--
arch/arm/src/armv7-m/arm_svcall.c | 47 ++++++++-----
arch/arm/src/armv7-m/exc_return.h | 31 ++++-----
arch/arm/src/armv8-m/arm_doirq.c | 66 ++++++++++++++----
arch/arm/src/armv8-m/arm_exception.S | 100 +++++++--------------------
arch/arm/src/armv8-m/arm_initialstate.c | 67 +++++++++++++++++-
arch/arm/src/armv8-m/arm_schedulesigaction.c | 17 +++--
arch/arm/src/armv8-m/arm_svcall.c | 48 ++++++++-----
arch/arm/src/armv8-m/exc_return.h | 40 +++++------
arch/arm/src/common/arm_initialize.c | 6 ++
arch/arm/src/common/arm_internal.h | 4 ++
arch/arm/src/cxd56xx/chip.h | 19 -----
arch/arm/src/cxd56xx/cxd56_cpustart.c | 6 ++
arch/arm/src/lc823450/chip.h | 18 -----
arch/arm/src/lc823450/lc823450_cpustart.c | 6 ++
arch/arm/src/rp2040/chip.h | 21 ------
arch/arm/src/rp2040/rp2040_cpustart.c | 6 ++
arch/arm/src/tlsr82/tc32/Make.defs | 2 +-
arch/arm/src/tlsr82/tc32/tc32_doirq.c | 57 +++++++++++++++
33 files changed, 548 insertions(+), 426 deletions(-)
[nuttx] 05/09: arch/tlsr82: Port arm_doirq to tc32_doirq.c
Posted by xi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
xiaoxiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git
commit cedc034d9ed40dfb59b6a0da3f9ac08bd735902e
Author: wangming9 <wa...@xiaomi.com>
AuthorDate: Tue Jul 11 20:39:44 2023 +0800
arch/tlsr82: Port arm_doirq to tc32_doirq.c
Solve the dependency on ARMV6M when compiling tlsr8278adk80d:nsh.
Signed-off-by: wangming9 <wa...@xiaomi.com>
---
arch/arm/include/tlsr82/irq.h | 5 +++
arch/arm/src/tlsr82/tc32/Make.defs | 2 +-
arch/arm/src/tlsr82/tc32/tc32_doirq.c | 57 +++++++++++++++++++++++++++++++++++
3 files changed, 63 insertions(+), 1 deletion(-)
diff --git a/arch/arm/include/tlsr82/irq.h b/arch/arm/include/tlsr82/irq.h
index 2ab314c524..d7032bfbb1 100644
--- a/arch/arm/include/tlsr82/irq.h
+++ b/arch/arm/include/tlsr82/irq.h
@@ -231,6 +231,11 @@ static inline void up_enable_irq(int irq)
_IRQ_MASK_REG |= (1 << irq);
}
+static inline uint32_t getcontrol(void)
+{
+ return 0;
+}
+
#endif /* __ASSEMBLY__ */
/****************************************************************************
diff --git a/arch/arm/src/tlsr82/tc32/Make.defs b/arch/arm/src/tlsr82/tc32/Make.defs
index 3226340d62..cee1fc88a4 100644
--- a/arch/arm/src/tlsr82/tc32/Make.defs
+++ b/arch/arm/src/tlsr82/tc32/Make.defs
@@ -46,7 +46,7 @@ CMN_ASRCS := $(filter-out $(TC32_ASRCS_FILTER), $(CMN_ASRCS))
# Common files in arch/arm/src/armv6-m
-CMN_CSRCS += arm_sigdeliver.c arm_doirq.c
+CMN_CSRCS += arm_sigdeliver.c
# Common files in arch/arm/src/tlsr82/tc32
diff --git a/arch/arm/src/tlsr82/tc32/tc32_doirq.c b/arch/arm/src/tlsr82/tc32/tc32_doirq.c
index 5404b7c533..d19cdfbb00 100644
--- a/arch/arm/src/tlsr82/tc32/tc32_doirq.c
+++ b/arch/arm/src/tlsr82/tc32/tc32_doirq.c
@@ -55,6 +55,63 @@
* Private Functions
****************************************************************************/
+uint32_t *arm_doirq(int irq, uint32_t *regs)
+{
+ board_autoled_on(LED_INIRQ);
+#ifdef CONFIG_SUPPRESS_INTERRUPTS
+ PANIC();
+#else
+
+ /* Nested interrupts are not supported in this implementation. If you
+ * want to implement nested interrupts, you would have to (1) change the
+ * way that CURRENT_REGS is handled and (2) the design associated with
+ * CONFIG_ARCH_INTERRUPTSTACK.
+ */
+
+ /* Current regs non-zero indicates that we are processing an interrupt;
+ * CURRENT_REGS is also used to manage interrupt level context switches.
+ */
+
+ if (CURRENT_REGS == NULL)
+ {
+ CURRENT_REGS = regs;
+ regs = NULL;
+ }
+
+ /* Acknowledge the interrupt */
+
+ arm_ack_irq(irq);
+
+ /* Deliver the IRQ */
+
+ irq_dispatch(irq, (uint32_t *)CURRENT_REGS);
+
+ /* If a context switch occurred while processing the interrupt then
+ * CURRENT_REGS may have change value. If we return any value different
+ * from the input regs, then the lower level will know that a context
+ * switch occurred during interrupt processing.
+ */
+
+ if (regs == NULL)
+ {
+ /* Restore the cpu lock */
+
+ if (regs != CURRENT_REGS)
+ {
+ restore_critical_section();
+ regs = (uint32_t *)CURRENT_REGS;
+ }
+
+ /* Update the CURRENT_REGS to NULL. */
+
+ CURRENT_REGS = NULL;
+ }
+#endif
+
+ board_autoled_off(LED_INIRQ);
+ return regs;
+}
+
/****************************************************************************
* Name: tc32_getirq
*
[nuttx] 02/09: arch/armv7-m: Supports interrupt nesting
Posted by xi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
xiaoxiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git
commit 816b3fb39940f5dec41d378a229c15d0f638c84c
Author: wangming9 <wa...@xiaomi.com>
AuthorDate: Wed Jul 5 16:08:52 2023 +0800
arch/armv7-m: Supports interrupt nesting
1、The process stack supports interrupt nesting, Execute in MSP;
2、The interrupt stack supports interrupt nesting;
The thread mode use PSP, and the handle mode use MSP;
3、Adjust arm_doirq、exception_common implementation to meet interrupt nesting
4、Adjust the conditions for returning MSP and PSP;
5、remove setintstack,add arm_initialize_stack;
Signed-off-by: wangming9 <wa...@xiaomi.com>
---
arch/arm/src/armv7-m/arm_doirq.c | 18 ++-------
arch/arm/src/armv7-m/arm_exception.S | 56 +++++++++-------------------
arch/arm/src/armv7-m/arm_initialstate.c | 44 +++++++++++++++++++++-
arch/arm/src/armv7-m/arm_schedulesigaction.c | 12 +++---
arch/arm/src/armv7-m/arm_svcall.c | 10 ++---
arch/arm/src/armv7-m/exc_return.h | 31 ++++++++-------
arch/arm/src/common/arm_initialize.c | 6 +++
arch/arm/src/common/arm_internal.h | 4 ++
arch/arm/src/cxd56xx/chip.h | 19 ----------
arch/arm/src/cxd56xx/cxd56_cpustart.c | 6 +++
arch/arm/src/lc823450/chip.h | 18 ---------
arch/arm/src/lc823450/lc823450_cpustart.c | 6 +++
12 files changed, 113 insertions(+), 117 deletions(-)
diff --git a/arch/arm/src/armv7-m/arm_doirq.c b/arch/arm/src/armv7-m/arm_doirq.c
index 564b903142..e7b6411faa 100644
--- a/arch/arm/src/armv7-m/arm_doirq.c
+++ b/arch/arm/src/armv7-m/arm_doirq.c
@@ -34,6 +34,7 @@
#include <sched/sched.h>
#include "arm_internal.h"
+#include "exc_return.h"
/****************************************************************************
* Public Functions
@@ -46,20 +47,9 @@ uint32_t *arm_doirq(int irq, uint32_t *regs)
PANIC();
#else
- /* Nested interrupts are not supported in this implementation. If you
- * want to implement nested interrupts, you would have to (1) change the
- * way that CURRENT_REGS is handled and (2) the design associated with
- * CONFIG_ARCH_INTERRUPTSTACK.
- */
-
- /* Current regs non-zero indicates that we are processing an interrupt;
- * CURRENT_REGS is also used to manage interrupt level context switches.
- */
-
- if (CURRENT_REGS == NULL)
+ if (regs[REG_EXC_RETURN] & EXC_RETURN_THREAD_MODE)
{
CURRENT_REGS = regs;
- regs = NULL;
}
/* Acknowledge the interrupt */
@@ -68,7 +58,7 @@ uint32_t *arm_doirq(int irq, uint32_t *regs)
/* Deliver the IRQ */
- irq_dispatch(irq, (uint32_t *)CURRENT_REGS);
+ irq_dispatch(irq, regs);
/* If a context switch occurred while processing the interrupt then
* CURRENT_REGS may have change value. If we return any value different
@@ -76,7 +66,7 @@ uint32_t *arm_doirq(int irq, uint32_t *regs)
* switch occurred during interrupt processing.
*/
- if (regs == NULL)
+ if (regs[REG_EXC_RETURN] & EXC_RETURN_THREAD_MODE)
{
/* Restore the cpu lock */
diff --git a/arch/arm/src/armv7-m/arm_exception.S b/arch/arm/src/armv7-m/arm_exception.S
index 6716a9d7f8..de5e8a3852 100644
--- a/arch/arm/src/armv7-m/arm_exception.S
+++ b/arch/arm/src/armv7-m/arm_exception.S
@@ -92,25 +92,6 @@
.thumb
.file "arm_exception.S"
-/****************************************************************************
- * Macro Definitions
- ****************************************************************************/
-
-/****************************************************************************
- * Name: setintstack
- *
- * Description:
- * Set the current stack pointer to the "top" the interrupt stack. Single CPU
- * case. Must be provided by MCU-specific logic in the SMP case.
- *
- ****************************************************************************/
-
-#if !defined(CONFIG_SMP) && CONFIG_ARCH_INTERRUPTSTACK > 7
- .macro setintstack, tmp1, tmp2
- ldr sp, =g_intstacktop
- .endm
-#endif
-
/****************************************************************************
* .text
****************************************************************************/
@@ -151,9 +132,14 @@ exception_common:
tst r14, #EXC_RETURN_PROCESS_STACK /* nonzero if context on process stack */
beq 1f /* Branch if context already on the MSP */
mrs r1, psp /* R1=The process stack pointer (PSP) */
- mov sp, r1 /* Set the MSP to the PSP */
+ b 2f
1:
- mov r2, sp /* R2=Copy of the main/process stack pointer */
+ mrs r1, msp /* R1=The main stack pointer (MSP) */
+ sub r2, r1, #SW_XCPT_SIZE /* Reserved stack space */
+ msr msp, r2
+
+2:
+ mov r2, r1 /* R2=Copy of the main/process stack pointer */
add r2, #HW_XCPT_SIZE /* R2=MSP/PSP before the interrupt was taken */
/* (ignoring the xPSR[9] alignment bit) */
#ifdef CONFIG_ARMV7M_USEBASEPRI
@@ -179,11 +165,11 @@ exception_common:
tst r14, #EXC_RETURN_STD_CONTEXT
ite eq
- vstmdbeq sp!, {s16-s31} /* Save the non-volatile FP context */
- subne sp, #(4*SW_FPU_REGS)
+ vstmdbeq r1!, {s16-s31} /* Save the non-volatile FP context */
+ subne r1, #(4*SW_FPU_REGS)
#endif
- stmdb sp!, {r2-r12,r14} /* Save the remaining registers plus the SP/PRIMASK values */
+ stmdb r1!, {r2-r12,r14} /* Save the remaining registers plus the SP/PRIMASK values */
/* There are two arguments to arm_doirq:
*
@@ -191,19 +177,10 @@ exception_common:
* R1 = The top of the stack points to the saved state
*/
- mov r1, sp
-
-#if CONFIG_ARCH_INTERRUPTSTACK > 7
- /* If CONFIG_ARCH_INTERRUPTSTACK is defined, we will set the MSP to use
- * a special special interrupt stack pointer. The way that this is done
- * here prohibits nested interrupts without some additional logic!
- */
-
- setintstack r2, r3 /* SP = IRQ stack top */
-#else
- /* Otherwise, we will re-use the interrupted thread's stack. That may
- * mean using either MSP or PSP stack for interrupt level processing (in
- * kernel mode).
+#if CONFIG_ARCH_INTERRUPTSTACK < 7
+ /* If CONFIG_ARCH_INTERRUPTSTACK is not defined, we will re-use the
+ * interrupted thread's stack. That may mean using either MSP or PSP
+ * stack for interrupt level processing (in kernel mode).
*/
/* If the interrupt stack is disabled, reserve xcpcontext to ensure
@@ -217,9 +194,12 @@ exception_common:
* also the sp should be restore after arm_doirq()
*/
+ tst r14, #EXC_RETURN_THREAD_MODE /* Nonzero if context on thread mode */
+ beq 3f /* Branch if context already on the handle mode */
sub r2, r1, #XCPTCONTEXT_SIZE /* Reserve signal context */
bic r2, r2, #7 /* Get the stack pointer with 8-byte alignment */
mov sp, r2 /* Instantiate the aligned stack */
+3:
#endif
bl arm_doirq /* R0=IRQ, R1=register save (msp) */
@@ -241,7 +221,7 @@ exception_common:
/* The EXC_RETURN value tells us whether we are returning on the MSP or PSP
*/
- tst r14, #EXC_RETURN_PROCESS_STACK /* nonzero if context on process stack */
+ tst r14, #EXC_RETURN_PROCESS_STACK /* Nonzero if context on process stack */
ite eq /* Next two instructions conditional */
msreq msp, r0 /* R0=The main stack pointer */
msrne psp, r0 /* R0=The process stack pointer */
diff --git a/arch/arm/src/armv7-m/arm_initialstate.c b/arch/arm/src/armv7-m/arm_initialstate.c
index c86390abdc..fe42f23344 100644
--- a/arch/arm/src/armv7-m/arm_initialstate.c
+++ b/arch/arm/src/armv7-m/arm_initialstate.c
@@ -142,7 +142,7 @@ void up_initial_state(struct tcb_s *tcb)
* mode before transferring control to the user task.
*/
- xcp->regs[REG_EXC_RETURN] = EXC_RETURN_PRIVTHR;
+ xcp->regs[REG_EXC_RETURN] = EXC_RETURN_THREAD;
xcp->regs[REG_CONTROL] = getcontrol() & ~CONTROL_NPRIV;
@@ -168,3 +168,45 @@ void up_initial_state(struct tcb_s *tcb)
#endif /* CONFIG_SUPPRESS_INTERRUPTS */
}
+
+#if CONFIG_ARCH_INTERRUPTSTACK > 7
+/****************************************************************************
+ * Name: arm_initialize_stack
+ *
+ * Description:
+ * If interrupt stack is defined, the PSP and MSP need to be reinitialized.
+ *
+ ****************************************************************************/
+
+noinline_function void arm_initialize_stack(void)
+{
+#ifdef CONFIG_SMP
+ uint32_t stack = (uint32_t)arm_intstack_top();
+#else
+ uint32_t stack = (uint32_t)g_intstacktop;
+#endif
+ uint32_t temp = 0;
+
+ __asm__ __volatile__
+ (
+
+ /* Initialize PSP */
+
+ "mov %1, sp\n"
+ "msr psp, %1\n"
+
+ /* Select PSP */
+
+ "mrs %1, CONTROL\n"
+ "orr %1, #2\n"
+ "msr CONTROL, %1\n"
+ "isb sy\n"
+
+ /* Initialize MSP */
+
+ "msr msp, %0\n"
+ :
+ : "r" (stack), "r" (temp)
+ : "memory");
+}
+#endif
diff --git a/arch/arm/src/armv7-m/arm_schedulesigaction.c b/arch/arm/src/armv7-m/arm_schedulesigaction.c
index 127e66fe65..16a05c6f3a 100644
--- a/arch/arm/src/armv7-m/arm_schedulesigaction.c
+++ b/arch/arm/src/armv7-m/arm_schedulesigaction.c
@@ -160,8 +160,8 @@ void up_schedule_sigaction(struct tcb_s *tcb, sig_deliver_t sigdeliver)
#endif
CURRENT_REGS[REG_XPSR] = ARMV7M_XPSR_T;
#ifdef CONFIG_BUILD_PROTECTED
- CURRENT_REGS[REG_LR] = EXC_RETURN_PRIVTHR;
- CURRENT_REGS[REG_EXC_RETURN] = EXC_RETURN_PRIVTHR;
+ CURRENT_REGS[REG_LR] = EXC_RETURN_THREAD;
+ CURRENT_REGS[REG_EXC_RETURN] = EXC_RETURN_THREAD;
CURRENT_REGS[REG_CONTROL] = getcontrol() & ~CONTROL_NPRIV;
#endif
}
@@ -209,7 +209,7 @@ void up_schedule_sigaction(struct tcb_s *tcb, sig_deliver_t sigdeliver)
#endif
tcb->xcp.regs[REG_XPSR] = ARMV7M_XPSR_T;
#ifdef CONFIG_BUILD_PROTECTED
- tcb->xcp.regs[REG_LR] = EXC_RETURN_PRIVTHR;
+ tcb->xcp.regs[REG_LR] = EXC_RETURN_THREAD;
tcb->xcp.regs[REG_CONTROL] = getcontrol() & ~CONTROL_NPRIV;
#endif
}
@@ -320,7 +320,7 @@ void up_schedule_sigaction(struct tcb_s *tcb, sig_deliver_t sigdeliver)
#endif
tcb->xcp.regs[REG_XPSR] = ARMV7M_XPSR_T;
#ifdef CONFIG_BUILD_PROTECTED
- tcb->xcp.regs[REG_LR] = EXC_RETURN_PRIVTHR;
+ tcb->xcp.regs[REG_LR] = EXC_RETURN_THREAD;
tcb->xcp.regs[REG_CONTROL] = getcontrol() & ~CONTROL_NPRIV;
#endif
}
@@ -367,7 +367,7 @@ void up_schedule_sigaction(struct tcb_s *tcb, sig_deliver_t sigdeliver)
#endif
CURRENT_REGS[REG_XPSR] = ARMV7M_XPSR_T;
#ifdef CONFIG_BUILD_PROTECTED
- CURRENT_REGS[REG_LR] = EXC_RETURN_PRIVTHR;
+ CURRENT_REGS[REG_LR] = EXC_RETURN_THREAD;
CURRENT_REGS[REG_CONTROL] = getcontrol() & ~CONTROL_NPRIV;
#endif
}
@@ -430,7 +430,7 @@ void up_schedule_sigaction(struct tcb_s *tcb, sig_deliver_t sigdeliver)
#endif
tcb->xcp.regs[REG_XPSR] = ARMV7M_XPSR_T;
#ifdef CONFIG_BUILD_PROTECTED
- tcb->xcp.regs[REG_LR] = EXC_RETURN_PRIVTHR;
+ tcb->xcp.regs[REG_LR] = EXC_RETURN_THREAD;
tcb->xcp.regs[REG_CONTROL] = getcontrol() & ~CONTROL_NPRIV;
#endif
}
diff --git a/arch/arm/src/armv7-m/arm_svcall.c b/arch/arm/src/armv7-m/arm_svcall.c
index 336a64dfb7..c761a972a6 100644
--- a/arch/arm/src/armv7-m/arm_svcall.c
+++ b/arch/arm/src/armv7-m/arm_svcall.c
@@ -271,7 +271,7 @@ int arm_svcall(int irq, void *context, void *arg)
*/
regs[REG_PC] = (uint32_t)USERSPACE->task_startup & ~1;
- regs[REG_EXC_RETURN] = EXC_RETURN_UNPRIVTHR;
+ regs[REG_EXC_RETURN] = EXC_RETURN_THREAD;
/* Return unprivileged mode */
@@ -308,7 +308,7 @@ int arm_svcall(int irq, void *context, void *arg)
*/
regs[REG_PC] = (uint32_t)regs[REG_R1] & ~1; /* startup */
- regs[REG_EXC_RETURN] = EXC_RETURN_UNPRIVTHR;
+ regs[REG_EXC_RETURN] = EXC_RETURN_THREAD;
/* Return unprivileged mode */
@@ -353,7 +353,7 @@ int arm_svcall(int irq, void *context, void *arg)
*/
regs[REG_PC] = (uint32_t)USERSPACE->signal_handler & ~1;
- regs[REG_EXC_RETURN] = EXC_RETURN_UNPRIVTHR;
+ regs[REG_EXC_RETURN] = EXC_RETURN_THREAD;
/* Return unprivileged mode */
@@ -390,7 +390,7 @@ int arm_svcall(int irq, void *context, void *arg)
DEBUGASSERT(rtcb->xcp.sigreturn != 0);
regs[REG_PC] = rtcb->xcp.sigreturn & ~1;
- regs[REG_EXC_RETURN] = EXC_RETURN_PRIVTHR;
+ regs[REG_EXC_RETURN] = EXC_RETURN_THREAD;
/* Return privileged mode */
@@ -428,7 +428,7 @@ int arm_svcall(int irq, void *context, void *arg)
rtcb->xcp.nsyscalls = index + 1;
regs[REG_PC] = (uint32_t)dispatch_syscall & ~1;
- regs[REG_EXC_RETURN] = EXC_RETURN_PRIVTHR;
+ regs[REG_EXC_RETURN] = EXC_RETURN_THREAD;
/* Return privileged mode */
diff --git a/arch/arm/src/armv7-m/exc_return.h b/arch/arm/src/armv7-m/exc_return.h
index ddac01de57..079bddcd14 100644
--- a/arch/arm/src/armv7-m/exc_return.h
+++ b/arch/arm/src/armv7-m/exc_return.h
@@ -77,29 +77,28 @@
#define EXC_RETURN_HANDLER 0xfffffff1
-/* EXC_RETURN_PRIVTHR: Return to privileged thread mode. Exception return
- * gets state from the main stack. Execution uses MSP after return.
- */
-
#ifdef CONFIG_ARCH_FPU
-# define EXC_RETURN_PRIVTHR (EXC_RETURN_BASE | EXC_RETURN_THREAD_MODE)
+# define EXC_RETURN_FPU 0
#else
-# define EXC_RETURN_PRIVTHR (EXC_RETURN_BASE | EXC_RETURN_STD_CONTEXT | \
- EXC_RETURN_THREAD_MODE)
+# define EXC_RETURN_FPU EXC_RETURN_STD_CONTEXT
#endif
-/* EXC_RETURN_UNPRIVTHR: Return to unprivileged thread mode. Exception return
- * gets state from the process stack. Execution uses PSP after return.
- */
-
-#ifdef CONFIG_ARCH_FPU
-# define EXC_RETURN_UNPRIVTHR (EXC_RETURN_BASE | EXC_RETURN_THREAD_MODE | \
- EXC_RETURN_PROCESS_STACK)
+#if CONFIG_ARCH_INTERRUPTSTACK > 7
+# define EXC_RETURN_STACK EXC_RETURN_PROCESS_STACK
#else
-# define EXC_RETURN_UNPRIVTHR (EXC_RETURN_BASE | EXC_RETURN_STD_CONTEXT | \
- EXC_RETURN_THREAD_MODE | EXC_RETURN_PROCESS_STACK)
+# define EXC_RETURN_STACK 0
#endif
+/* EXC_RETURN_THREAD: Return to thread mode.
+ * If EXC_RETURN_STACK is 0, Return to thread mode.
+ * Execution uses MSP after return.
+ * If EXC_RETURN_STACK is EXC_RETURN_PROCESS_STACK, Return to
+ * thread mode. Execution uses PSP after return.
+ */
+
+#define EXC_RETURN_THREAD (EXC_RETURN_BASE | EXC_RETURN_FPU | \
+ EXC_RETURN_THREAD_MODE | EXC_RETURN_STACK)
+
/****************************************************************************
* Inline Functions
****************************************************************************/
diff --git a/arch/arm/src/common/arm_initialize.c b/arch/arm/src/common/arm_initialize.c
index 2b457ef0f4..65a09495e5 100644
--- a/arch/arm/src/common/arm_initialize.c
+++ b/arch/arm/src/common/arm_initialize.c
@@ -97,6 +97,12 @@ static inline void arm_color_intstack(void)
void up_initialize(void)
{
+#if CONFIG_ARCH_INTERRUPTSTACK > 7
+ /* Reinitializes the stack pointer */
+
+ arm_initialize_stack();
+#endif
+
/* Colorize the interrupt stack */
arm_color_intstack();
diff --git a/arch/arm/src/common/arm_internal.h b/arch/arm/src/common/arm_internal.h
index 75918424c6..ca9517f2ce 100644
--- a/arch/arm/src/common/arm_internal.h
+++ b/arch/arm/src/common/arm_internal.h
@@ -346,6 +346,10 @@ uintptr_t arm_intstack_alloc(void);
uintptr_t arm_intstack_top(void);
#endif
+#if CONFIG_ARCH_INTERRUPTSTACK > 7
+void weak_function arm_initialize_stack(void);
+#endif
+
/* Exception handling logic unique to the Cortex-M family */
#if defined(CONFIG_ARCH_ARMV6M) || defined(CONFIG_ARCH_ARMV7M) || \
diff --git a/arch/arm/src/cxd56xx/chip.h b/arch/arm/src/cxd56xx/chip.h
index c43ff78000..2e6f3e9e08 100644
--- a/arch/arm/src/cxd56xx/chip.h
+++ b/arch/arm/src/cxd56xx/chip.h
@@ -49,24 +49,5 @@
#ifdef __ASSEMBLY__
-/****************************************************************************
- * Name: setintstack
- *
- * Description:
- * Set the current stack pointer to the "top" the correct interrupt stack
- * for the current CPU.
- *
- ****************************************************************************/
-
-#if defined(CONFIG_SMP) && CONFIG_ARCH_INTERRUPTSTACK > 7
- .macro setintstack, tmp1, tmp2
- ldr \tmp1, =CXD56_ADSP_PID
- ldr \tmp1, [\tmp1, 0]
- sub \tmp1, 2 /* tmp1 = getreg32(CXD56_ADSP_PID) - 2 */
- ldr \tmp2, =g_cpu_intstack_top
- ldr sp, [\tmp2, \tmp1, lsl #2] /* sp = g_cpu_intstack_top[tmp1] */
- .endm
-#endif /* CONFIG_SMP && CONFIG_ARCH_INTERRUPTSTACK > 7 */
-
#endif /* __ASSEMBLY__ */
#endif /* __ARCH_ARM_SRC_CXD56XX_CHIP_H */
diff --git a/arch/arm/src/cxd56xx/cxd56_cpustart.c b/arch/arm/src/cxd56xx/cxd56_cpustart.c
index c2071ea718..6f79626b41 100644
--- a/arch/arm/src/cxd56xx/cxd56_cpustart.c
+++ b/arch/arm/src/cxd56xx/cxd56_cpustart.c
@@ -97,6 +97,12 @@ static void appdsp_boot(void)
cpu = up_cpu_index();
DPRINTF("cpu = %d\n", cpu);
+#if CONFIG_ARCH_INTERRUPTSTACK > 7
+ /* Initializes the stack pointer */
+
+ arm_initialize_stack();
+#endif
+
/* Setup NVIC */
up_irqinitialize();
diff --git a/arch/arm/src/lc823450/chip.h b/arch/arm/src/lc823450/chip.h
index 952d6018c8..5a703f6c35 100644
--- a/arch/arm/src/lc823450/chip.h
+++ b/arch/arm/src/lc823450/chip.h
@@ -58,23 +58,5 @@
#ifdef __ASSEMBLY__
-/****************************************************************************
- * Name: setintstack
- *
- * Description:
- * Set the current stack pointer to the "top" the correct interrupt stack
- * for the current CPU.
- *
- ****************************************************************************/
-
-#if defined(CONFIG_SMP) && CONFIG_ARCH_INTERRUPTSTACK > 7
- .macro setintstack, tmp1, tmp2
- ldr \tmp1, =CORE_COREID
- ldr \tmp1, [\tmp1, 0] /* tmp1 = getreg32(CORE_COREID) */
- ldr \tmp2, =g_cpu_intstack_top
- ldr sp, [\tmp2, \tmp1, lsl #2] /* sp = g_cpu_intstack_top[tmp1] */
- .endm
-#endif /* CONFIG_SMP && CONFIG_ARCH_INTERRUPTSTACK > 7 */
-
#endif /* __ASSEMBLY__ */
#endif /* __ARCH_ARM_SRC_LC823450_CHIP_H */
diff --git a/arch/arm/src/lc823450/lc823450_cpustart.c b/arch/arm/src/lc823450/lc823450_cpustart.c
index 5fe44bd671..908eddec82 100644
--- a/arch/arm/src/lc823450/lc823450_cpustart.c
+++ b/arch/arm/src/lc823450/lc823450_cpustart.c
@@ -89,6 +89,12 @@ static void cpu1_boot(void)
DPRINTF("cpu = %d\n", cpu);
+#if CONFIG_ARCH_INTERRUPTSTACK > 7
+ /* Initializes the stack pointer */
+
+ arm_initialize_stack();
+#endif
+
if (cpu == 1)
{
putreg32((uint32_t)_stext, NVIC_VECTAB); /* use CPU0 vectors */
[nuttx] 03/09: arch/armv6-m: By default, add REG_EXC_RETURN to xcptcontext.
Posted by xi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
xiaoxiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git
commit a4b6b158ce7f99ee8d306e2c8ace83a5002d4cfa
Author: wangming9 <wa...@xiaomi.com>
AuthorDate: Fri Jun 30 14:26:02 2023 +0800
arch/armv6-m: By default, add REG_EXC_RETURN to xcptcontext.
Signed-off-by: wangming9 <wa...@xiaomi.com>
---
arch/arm/include/armv6-m/irq.h | 13 ++-----------
arch/arm/src/armv6-m/arm_exception.S | 22 ----------------------
arch/arm/src/armv6-m/arm_initialstate.c | 2 --
arch/arm/src/armv6-m/arm_saveusercontext.S | 8 +++-----
arch/arm/src/armv6-m/arm_svcall.c | 10 ----------
5 files changed, 5 insertions(+), 50 deletions(-)
diff --git a/arch/arm/include/armv6-m/irq.h b/arch/arm/include/armv6-m/irq.h
index f2e59ef39d..b7ea799fc4 100644
--- a/arch/arm/include/armv6-m/irq.h
+++ b/arch/arm/include/armv6-m/irq.h
@@ -69,17 +69,8 @@
#define REG_R9 (7) /* R9 */
#define REG_R10 (8) /* R10 */
#define REG_R11 (9) /* R11 */
-
-/* In the kernel build, we may return to either privileged or unprivileged
- * modes.
- */
-
-#ifdef CONFIG_BUILD_PROTECTED
-# define REG_EXC_RETURN (10) /* EXC_RETURN */
-# define SW_XCPT_REGS (11)
-#else
-# define SW_XCPT_REGS (10)
-#endif
+#define REG_EXC_RETURN (10) /* EXC_RETURN */
+#define SW_XCPT_REGS (11)
/* The total number of registers saved by software */
diff --git a/arch/arm/src/armv6-m/arm_exception.S b/arch/arm/src/armv6-m/arm_exception.S
index 4d8eabbd30..595198b698 100644
--- a/arch/arm/src/armv6-m/arm_exception.S
+++ b/arch/arm/src/armv6-m/arm_exception.S
@@ -114,7 +114,6 @@ exception_common:
* the context is on the MSP or PSP.
*/
-#ifdef CONFIG_BUILD_PROTECTED
mov r0, r14 /* Copy high register to low register */
lsls r0, #(31 - EXC_RETURN_PROCESS_BITNO) /* Move to bit 31 */
bmi 1f /* Test bit 31 */
@@ -123,9 +122,6 @@ exception_common:
1:
mrs r1, psp /* R1=The process stack pointer */
-#else
- mrs r1, msp /* R1=The main stack pointer */
-#endif
/* R1 is the current stack pointer. HW_XCPT_REGS were pushed onto the stack
* when the interrupt was taken so (R1)+HW_XCPT_SIZE is the value of the
@@ -151,12 +147,8 @@ exception_common:
mov r3, r9
mov r4, r10
mov r5, r11
-#ifdef CONFIG_BUILD_PROTECTED
mov r6, r14
stmia r0!, {r2-r6} /* Save the high registers r8-r11 and r14 */
-#else
- stmia r0!, {r2-r5} /* Save the high registers r8-r11 */
-#endif
/* Get the exception number in R0=IRQ, R1=register save area on stack */
@@ -196,20 +188,12 @@ exception_common:
movs r2, #(4*REG_R8) /* R2=Offset to R8 storage */
adds r1, r0, r2 /* R1=Address of R8 storage */
-#ifdef CONFIG_BUILD_PROTECTED
ldmia r1!, {r2-r6} /* Recover R8-R11 and R14 (5 registers)*/
mov r8, r2 /* Move to position in high registers */
mov r9, r3
mov r10, r4
mov r11, r5
mov r14, r6 /* EXEC_RETURN */
-#else
- ldmia r1!, {r2-r5} /* Recover R8-R11 (4 registers)*/
- mov r8, r2 /* Move to position in high registers */
- mov r9, r3
- mov r10, r4
- mov r11, r5
-#endif
/* Recover SP (R2), PRIMASK (R3), and R4-R7. Determine the value of
* the stack pointer as it was on entry to the exception handler.
@@ -223,7 +207,6 @@ exception_common:
* context is on the MSP or PSP.
*/
-#ifdef CONFIG_BUILD_PROTECTED
mov r0, r14 /* Copy high register to low register */
lsls r0, #(31 - EXC_RETURN_PROCESS_BITNO) /* Move to bit 31 */
bmi 3f /* Test bit 31 */
@@ -234,11 +217,6 @@ exception_common:
msr psp, r1 /* R1=The process stack pointer */
4:
-#else
- msr msp, r1 /* R1=The main stack pointer */
- ldr r0, =EXC_RETURN_PRIVTHR /* R0=EXC_RETURN to privileged mode */
- mov r14, r0 /* R14=EXC_RETURN to privileged mode */
-#endif
/* Restore the interrupt state */
diff --git a/arch/arm/src/armv6-m/arm_initialstate.c b/arch/arm/src/armv6-m/arm_initialstate.c
index 2153777318..c7639d26ed 100644
--- a/arch/arm/src/armv6-m/arm_initialstate.c
+++ b/arch/arm/src/armv6-m/arm_initialstate.c
@@ -129,7 +129,6 @@ void up_initial_state(struct tcb_s *tcb)
#endif
#endif /* CONFIG_PIC */
-#ifdef CONFIG_BUILD_PROTECTED
/* All tasks start via a stub function in kernel space. So all
* tasks must start in privileged thread mode. If CONFIG_BUILD_PROTECTED
* is defined, then that stub function will switch to unprivileged
@@ -137,7 +136,6 @@ void up_initial_state(struct tcb_s *tcb)
*/
xcp->regs[REG_EXC_RETURN] = EXC_RETURN_PRIVTHR;
-#endif
/* Enable or disable interrupts, based on user configuration */
diff --git a/arch/arm/src/armv6-m/arm_saveusercontext.S b/arch/arm/src/armv6-m/arm_saveusercontext.S
index 478bdac079..510d0450b8 100644
--- a/arch/arm/src/armv6-m/arm_saveusercontext.S
+++ b/arch/arm/src/armv6-m/arm_saveusercontext.S
@@ -92,14 +92,12 @@ up_saveusercontext:
/* Save r11 and EXC_RETURN */
mov r1, r11
-#ifdef CONFIG_BUILD_PROTECTED
+
/* Save EXC_RETURN to 0xffffffff */
- movs r2, #-1
+ movs r2, #0
+ subs r2, #1
stmia r0!, {r1-r2}
-#else
- stmia r0!, {r1}
-#endif
movs r0, #0
bx lr
diff --git a/arch/arm/src/armv6-m/arm_svcall.c b/arch/arm/src/armv6-m/arm_svcall.c
index 02a609fc55..b9f96459fb 100644
--- a/arch/arm/src/armv6-m/arm_svcall.c
+++ b/arch/arm/src/armv6-m/arm_svcall.c
@@ -138,13 +138,8 @@ int arm_svcall(int irq, void *context, void *arg)
svcinfo(" R8: %08x %08x %08x %08x %08x %08x %08x %08x\n",
regs[REG_R8], regs[REG_R9], regs[REG_R10], regs[REG_R11],
regs[REG_R12], regs[REG_R13], regs[REG_R14], regs[REG_R15]);
-# ifdef CONFIG_BUILD_PROTECTED
svcinfo(" PSR: %08x PRIMASK: %08x EXC_RETURN: %08x\n",
regs[REG_XPSR], regs[REG_PRIMASK], regs[REG_EXC_RETURN]);
-# else
- svcinfo(" PSR: %08x PRIMASK: %08x\n",
- regs[REG_XPSR], regs[REG_PRIMASK]);
-# endif
}
#endif
@@ -446,14 +441,9 @@ int arm_svcall(int irq, void *context, void *arg)
CURRENT_REGS[REG_R10], CURRENT_REGS[REG_R11],
CURRENT_REGS[REG_R12], CURRENT_REGS[REG_R13],
CURRENT_REGS[REG_R14], CURRENT_REGS[REG_R15]);
-# ifdef CONFIG_BUILD_PROTECTED
svcinfo(" PSR: %08x PRIMASK: %08x EXC_RETURN: %08x\n",
CURRENT_REGS[REG_XPSR], CURRENT_REGS[REG_PRIMASK],
CURRENT_REGS[REG_EXC_RETURN]);
-# else
- svcinfo(" PSR: %08x PRIMASK: %08x\n",
- CURRENT_REGS[REG_XPSR], CURRENT_REGS[REG_PRIMASK]);
-# endif
}
# ifdef CONFIG_DEBUG_SVCALL
else
[nuttx] 09/09: arch/armv8-m: Supports interrupt nesting between TEE and REE
Posted by xi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
xiaoxiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git
commit 8d21bbf3be648b3758b888d2fdb569679f9b6d00
Author: wangming9 <wa...@xiaomi.com>
AuthorDate: Thu Jul 27 20:18:45 2023 +0800
arch/armv8-m: Supports interrupt nesting between TEE and REE
The first time interrupt nesting occurs between REE and TEE,
CURRENT_REGS needs to be set.
If TEE nesting REE breaks, then EXC_RETURN.S=0,EXC_RETURN.ES=1;
Conversely, EXC_RETURN.S=1,EXC_RETURN.ES=0;
Interrupt nesting between TEE and REE can be determined based
on the S and ES bits of EXC_RETURN.
Only once nesting between TEE and REE is supported, and cyclic
nesting between TEE and REE is not supported.
Signed-off-by: wangming9 <wa...@xiaomi.com>
---
arch/arm/src/armv8-m/arm_doirq.c | 53 ++++++++++++++++++++++++++++++++++++++--
1 file changed, 51 insertions(+), 2 deletions(-)
diff --git a/arch/arm/src/armv8-m/arm_doirq.c b/arch/arm/src/armv8-m/arm_doirq.c
index 5c5e86a150..0a4a9131b2 100644
--- a/arch/arm/src/armv8-m/arm_doirq.c
+++ b/arch/arm/src/armv8-m/arm_doirq.c
@@ -36,6 +36,55 @@
#include "arm_internal.h"
#include "exc_return.h"
+/****************************************************************************
+ * Inline Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: arm_from_thread
+ *
+ * Description:
+ * If not defined CONFIG_ARCH_HAVE_TRUSTZONE
+ * Return true if interrupt return to thread mode, false otherwise.
+ *
+ * If defined CONFIG_ARCH_HAVE_TRUSTZONE
+ * Return true if interrupt return to thread mode, or if it is the first
+ * interrupt from TEE to REE, or REE to TEE, false otherwise.
+ *
+ * Interrupt nesting between TEE and REE can be determined based
+ * on the S and ES bits of EXC_RETURN
+ * If TEE interrupts REE, then EXC_RETURN.S=0, EXC_RETURN.ES=1;
+ * Conversely, EXC_RETURN.S=1, EXC_RETURN.ES=0.
+ *
+ * But only one level nesting between TEE and REE is supported, and
+ * recursive nesting between TEE and REE is not supported.
+ *
+ ****************************************************************************/
+
+static inline bool arm_from_thread(uint32_t excret)
+{
+ if (excret & EXC_RETURN_THREAD_MODE)
+ {
+ return true;
+ }
+
+#ifdef CONFIG_ARCH_HAVE_TRUSTZONE
+ if (!(excret & EXC_RETURN_SECURE_STACK) &&
+ (excret & EXC_RETURN_EXC_SECURE))
+ {
+ return true;
+ }
+
+ if (!(excret & EXC_RETURN_EXC_SECURE) &&
+ (excret & EXC_RETURN_SECURE_STACK))
+ {
+ return true;
+ }
+#endif
+
+ return false;
+}
+
/****************************************************************************
* Public Functions
****************************************************************************/
@@ -47,7 +96,7 @@ uint32_t *arm_doirq(int irq, uint32_t *regs)
PANIC();
#else
- if (regs[REG_EXC_RETURN] & EXC_RETURN_THREAD_MODE)
+ if (arm_from_thread(regs[REG_EXC_RETURN]))
{
CURRENT_REGS = regs;
}
@@ -66,7 +115,7 @@ uint32_t *arm_doirq(int irq, uint32_t *regs)
* switch occurred during interrupt processing.
*/
- if (regs[REG_EXC_RETURN] & EXC_RETURN_THREAD_MODE)
+ if (arm_from_thread(regs[REG_EXC_RETURN]))
{
/* Restore the cpu lock */
[nuttx] 01/09: arch/armv7-m: Add CONTROL register to xcptcontext.
Posted by xi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
xiaoxiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git
commit 4370487fd689d4a3ddbeada9cbabc9cde287de4f
Author: wangming9 <wa...@xiaomi.com>
AuthorDate: Tue Jul 4 20:39:08 2023 +0800
arch/armv7-m: Add CONTROL register to xcptcontext.
To simplify the interrupt handling in protected mode.
Signed-off-by: wangming9 <wa...@xiaomi.com>
---
arch/arm/include/armv7-m/irq.h | 5 ++--
arch/arm/src/armv7-m/arm_exception.S | 27 ++++----------------
arch/arm/src/armv7-m/arm_initialstate.c | 2 ++
arch/arm/src/armv7-m/arm_schedulesigaction.c | 5 ++++
arch/arm/src/armv7-m/arm_svcall.c | 37 +++++++++++++++++++---------
5 files changed, 40 insertions(+), 36 deletions(-)
diff --git a/arch/arm/include/armv7-m/irq.h b/arch/arm/include/armv7-m/irq.h
index 626072c47d..f77ef08016 100644
--- a/arch/arm/include/armv7-m/irq.h
+++ b/arch/arm/include/armv7-m/irq.h
@@ -72,8 +72,9 @@
#define REG_R9 (7) /* R9 */
#define REG_R10 (8) /* R10 */
#define REG_R11 (9) /* R11 */
-#define REG_EXC_RETURN (10) /* EXC_RETURN */
-#define SW_INT_REGS (11)
+#define REG_CONTROL (10) /* CONTROL */
+#define REG_EXC_RETURN (11) /* EXC_RETURN */
+#define SW_INT_REGS (12)
#ifdef CONFIG_ARCH_FPU
diff --git a/arch/arm/src/armv7-m/arm_exception.S b/arch/arm/src/armv7-m/arm_exception.S
index cc4b59ad8a..6716a9d7f8 100644
--- a/arch/arm/src/armv7-m/arm_exception.S
+++ b/arch/arm/src/armv7-m/arm_exception.S
@@ -142,6 +142,7 @@
exception_common:
mrs r0, ipsr /* R0=exception number */
+ mrs r12, control /* R12=control */
/* Complete the context save */
@@ -182,7 +183,7 @@ exception_common:
subne sp, #(4*SW_FPU_REGS)
#endif
- stmdb sp!, {r2-r11,r14} /* Save the remaining registers plus the SP/PRIMASK values */
+ stmdb sp!, {r2-r12,r14} /* Save the remaining registers plus the SP/PRIMASK values */
/* There are two arguments to arm_doirq:
*
@@ -227,7 +228,7 @@ exception_common:
* array to use for the interrupt return.
*/
- ldmia r0!, {r2-r11,r14} /* Recover R4-R11, r14 + 2 temp values */
+ ldmia r0!, {r2-r12,r14} /* Recover R4-R12, r14 + 2 temp values */
#ifdef CONFIG_ARCH_FPU
/* Switched-in task including volatile FP registers ? */
@@ -240,30 +241,10 @@ exception_common:
/* The EXC_RETURN value tells us whether we are returning on the MSP or PSP
*/
-#ifdef CONFIG_BUILD_PROTECTED
- /* The EXC_RETURN value will be 0xfffffff9 (privileged thread) or 0xfffffff1
- * (handler mode) if the stack is on the MSP. It can only be on the PSP if
- * EXC_RETURN is 0xfffffffd (unprivileged thread)
- */
-
- mrs r2, control /* R2=Contents of the control register */
- tst r14, #EXC_RETURN_PROCESS_STACK /* nonzero if context on process stack */
- beq 2f /* Branch if privileged */
-
- orr r2, r2, #1 /* Unprivileged mode */
- msr psp, r0 /* R0=The process stack pointer */
- b 3f
-2:
- bic r2, r2, #1 /* Privileged mode */
- msr msp, r0 /* R0=The main stack pointer */
-3:
- msr control, r2 /* Save the updated control register */
-#else
tst r14, #EXC_RETURN_PROCESS_STACK /* nonzero if context on process stack */
ite eq /* Next two instructions conditional */
msreq msp, r0 /* R0=The main stack pointer */
msrne psp, r0 /* R0=The process stack pointer */
-#endif
/* Restore the interrupt state */
@@ -273,6 +254,8 @@ exception_common:
msr primask, r3 /* Restore interrupts */
#endif
+ msr control, r12 /* Restore control */
+
/* Always return with R14 containing the special value that will: (1)
* return to thread mode, and (2) select the correct stack.
*/
diff --git a/arch/arm/src/armv7-m/arm_initialstate.c b/arch/arm/src/armv7-m/arm_initialstate.c
index 85ec6fadb4..c86390abdc 100644
--- a/arch/arm/src/armv7-m/arm_initialstate.c
+++ b/arch/arm/src/armv7-m/arm_initialstate.c
@@ -144,6 +144,8 @@ void up_initial_state(struct tcb_s *tcb)
xcp->regs[REG_EXC_RETURN] = EXC_RETURN_PRIVTHR;
+ xcp->regs[REG_CONTROL] = getcontrol() & ~CONTROL_NPRIV;
+
#ifdef CONFIG_ARCH_FPU
xcp->regs[REG_FPSCR] = 0; /* REVISIT: Initial FPSCR should be configurable */
#endif /* CONFIG_ARCH_FPU */
diff --git a/arch/arm/src/armv7-m/arm_schedulesigaction.c b/arch/arm/src/armv7-m/arm_schedulesigaction.c
index 70f90e1be5..127e66fe65 100644
--- a/arch/arm/src/armv7-m/arm_schedulesigaction.c
+++ b/arch/arm/src/armv7-m/arm_schedulesigaction.c
@@ -162,6 +162,7 @@ void up_schedule_sigaction(struct tcb_s *tcb, sig_deliver_t sigdeliver)
#ifdef CONFIG_BUILD_PROTECTED
CURRENT_REGS[REG_LR] = EXC_RETURN_PRIVTHR;
CURRENT_REGS[REG_EXC_RETURN] = EXC_RETURN_PRIVTHR;
+ CURRENT_REGS[REG_CONTROL] = getcontrol() & ~CONTROL_NPRIV;
#endif
}
}
@@ -209,6 +210,7 @@ void up_schedule_sigaction(struct tcb_s *tcb, sig_deliver_t sigdeliver)
tcb->xcp.regs[REG_XPSR] = ARMV7M_XPSR_T;
#ifdef CONFIG_BUILD_PROTECTED
tcb->xcp.regs[REG_LR] = EXC_RETURN_PRIVTHR;
+ tcb->xcp.regs[REG_CONTROL] = getcontrol() & ~CONTROL_NPRIV;
#endif
}
}
@@ -319,6 +321,7 @@ void up_schedule_sigaction(struct tcb_s *tcb, sig_deliver_t sigdeliver)
tcb->xcp.regs[REG_XPSR] = ARMV7M_XPSR_T;
#ifdef CONFIG_BUILD_PROTECTED
tcb->xcp.regs[REG_LR] = EXC_RETURN_PRIVTHR;
+ tcb->xcp.regs[REG_CONTROL] = getcontrol() & ~CONTROL_NPRIV;
#endif
}
else
@@ -365,6 +368,7 @@ void up_schedule_sigaction(struct tcb_s *tcb, sig_deliver_t sigdeliver)
CURRENT_REGS[REG_XPSR] = ARMV7M_XPSR_T;
#ifdef CONFIG_BUILD_PROTECTED
CURRENT_REGS[REG_LR] = EXC_RETURN_PRIVTHR;
+ CURRENT_REGS[REG_CONTROL] = getcontrol() & ~CONTROL_NPRIV;
#endif
}
@@ -427,6 +431,7 @@ void up_schedule_sigaction(struct tcb_s *tcb, sig_deliver_t sigdeliver)
tcb->xcp.regs[REG_XPSR] = ARMV7M_XPSR_T;
#ifdef CONFIG_BUILD_PROTECTED
tcb->xcp.regs[REG_LR] = EXC_RETURN_PRIVTHR;
+ tcb->xcp.regs[REG_CONTROL] = getcontrol() & ~CONTROL_NPRIV;
#endif
}
}
diff --git a/arch/arm/src/armv7-m/arm_svcall.c b/arch/arm/src/armv7-m/arm_svcall.c
index d9f5c0aa00..336a64dfb7 100644
--- a/arch/arm/src/armv7-m/arm_svcall.c
+++ b/arch/arm/src/armv7-m/arm_svcall.c
@@ -146,12 +146,8 @@ int arm_svcall(int irq, void *context, void *arg)
svcinfo(" R8: %08x %08x %08x %08x %08x %08x %08x %08x\n",
regs[REG_R8], regs[REG_R9], regs[REG_R10], regs[REG_R11],
regs[REG_R12], regs[REG_R13], regs[REG_R14], regs[REG_R15]);
-# ifdef REG_EXC_RETURN
- svcinfo(" PSR: %08x EXC_RETURN: %08x\n",
- regs[REG_XPSR], regs[REG_EXC_RETURN]);
-# else
- svcinfo(" PSR: %08x\n", regs[REG_XPSR]);
-# endif
+ svcinfo(" PSR: %08x EXC_RETURN: %08x CONTROL: %08x\n",
+ regs[REG_XPSR], regs[REG_EXC_RETURN], regs[REG_CONTROL]);
}
#endif
@@ -277,6 +273,10 @@ int arm_svcall(int irq, void *context, void *arg)
regs[REG_PC] = (uint32_t)USERSPACE->task_startup & ~1;
regs[REG_EXC_RETURN] = EXC_RETURN_UNPRIVTHR;
+ /* Return unprivileged mode */
+
+ regs[REG_CONTROL] = getcontrol() | CONTROL_NPRIV;
+
/* Change the parameter ordering to match the expectation of struct
* userpace_s task_startup:
*/
@@ -310,6 +310,10 @@ int arm_svcall(int irq, void *context, void *arg)
regs[REG_PC] = (uint32_t)regs[REG_R1] & ~1; /* startup */
regs[REG_EXC_RETURN] = EXC_RETURN_UNPRIVTHR;
+ /* Return unprivileged mode */
+
+ regs[REG_CONTROL] = getcontrol() | CONTROL_NPRIV;
+
/* Change the parameter ordering to match the expectation of the
* user space pthread_startup:
*/
@@ -351,6 +355,10 @@ int arm_svcall(int irq, void *context, void *arg)
regs[REG_PC] = (uint32_t)USERSPACE->signal_handler & ~1;
regs[REG_EXC_RETURN] = EXC_RETURN_UNPRIVTHR;
+ /* Return unprivileged mode */
+
+ regs[REG_CONTROL] = getcontrol() | CONTROL_NPRIV;
+
/* Change the parameter ordering to match the expectation of struct
* userpace_s signal_handler.
*/
@@ -383,6 +391,10 @@ int arm_svcall(int irq, void *context, void *arg)
regs[REG_PC] = rtcb->xcp.sigreturn & ~1;
regs[REG_EXC_RETURN] = EXC_RETURN_PRIVTHR;
+
+ /* Return privileged mode */
+
+ regs[REG_CONTROL] = getcontrol() & ~CONTROL_NPRIV;
rtcb->xcp.sigreturn = 0;
}
break;
@@ -418,6 +430,10 @@ int arm_svcall(int irq, void *context, void *arg)
regs[REG_PC] = (uint32_t)dispatch_syscall & ~1;
regs[REG_EXC_RETURN] = EXC_RETURN_PRIVTHR;
+ /* Return privileged mode */
+
+ regs[REG_CONTROL] = getcontrol() & ~CONTROL_NPRIV;
+
/* Offset R0 to account for the reserved values */
regs[REG_R0] -= CONFIG_SYS_RESERVED;
@@ -454,12 +470,9 @@ int arm_svcall(int irq, void *context, void *arg)
CURRENT_REGS[REG_R10], CURRENT_REGS[REG_R11],
CURRENT_REGS[REG_R12], CURRENT_REGS[REG_R13],
CURRENT_REGS[REG_R14], CURRENT_REGS[REG_R15]);
-# ifdef REG_EXC_RETURN
- svcinfo(" PSR: %08x EXC_RETURN: %08x\n",
- CURRENT_REGS[REG_XPSR], CURRENT_REGS[REG_EXC_RETURN]);
-# else
- svcinfo(" PSR: %08x\n", CURRENT_REGS[REG_XPSR]);
-# endif
+ svcinfo(" PSR: %08x EXC_RETURN: %08x, CONTROL: %08x\n",
+ CURRENT_REGS[REG_XPSR], CURRENT_REGS[REG_EXC_RETURN],
+ CURRENT_REGS[REG_CONTROL]);
}
# ifdef CONFIG_DEBUG_SVCALL
else
[nuttx] 07/09: arch/armv8-m: Add CONTROL register to xcptcontext.
Posted by xi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
xiaoxiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git
commit f8aaed780a2aee158b19327ecfeb065a3d75d59c
Author: wangming9 <wa...@xiaomi.com>
AuthorDate: Thu Jul 6 21:01:54 2023 +0800
arch/armv8-m: Add CONTROL register to xcptcontext.
To simplify the interrupt handling in protected mode.
Signed-off-by: wangming9 <wa...@xiaomi.com>
---
arch/arm/include/armv8-m/irq.h | 5 ++--
arch/arm/src/armv8-m/arm_exception.S | 33 ++++--------------------
arch/arm/src/armv8-m/arm_initialstate.c | 2 ++
arch/arm/src/armv8-m/arm_schedulesigaction.c | 5 ++++
arch/arm/src/armv8-m/arm_svcall.c | 38 +++++++++++++++++++---------
5 files changed, 41 insertions(+), 42 deletions(-)
diff --git a/arch/arm/include/armv8-m/irq.h b/arch/arm/include/armv8-m/irq.h
index 0c1809f13f..ed4620a265 100644
--- a/arch/arm/include/armv8-m/irq.h
+++ b/arch/arm/include/armv8-m/irq.h
@@ -72,8 +72,9 @@
#define REG_R9 (7) /* R9 */
#define REG_R10 (8) /* R10 */
#define REG_R11 (9) /* R11 */
-#define REG_EXC_RETURN (10) /* EXC_RETURN */
-#define SW_INT_REGS (11)
+#define REG_CONTROL (10) /* CONTROL */
+#define REG_EXC_RETURN (11) /* EXC_RETURN */
+#define SW_INT_REGS (12)
#ifdef CONFIG_ARCH_FPU
diff --git a/arch/arm/src/armv8-m/arm_exception.S b/arch/arm/src/armv8-m/arm_exception.S
index bec4f68b31..4ff4ee7fc0 100644
--- a/arch/arm/src/armv8-m/arm_exception.S
+++ b/arch/arm/src/armv8-m/arm_exception.S
@@ -146,6 +146,7 @@
exception_common:
mrs r0, ipsr /* R0=exception number */
+ mrs r12, control /* R12=control */
/* Complete the context save */
@@ -198,7 +199,7 @@ exception_common:
subne sp, #(4*SW_FPU_REGS)
#endif
- stmdb sp!, {r2-r11,r14} /* Save the remaining registers plus the SP/PRIMASK values */
+ stmdb sp!, {r2-r12,r14} /* Save the remaining registers plus the SP/PRIMASK values */
/* There are two arguments to arm_doirq:
*
@@ -243,7 +244,7 @@ exception_common:
* array to use for the interrupt return.
*/
- ldmia r0!, {r2-r11,r14} /* Recover R4-R11, r14 + 2 temp values */
+ ldmia r0!, {r2-r12,r14} /* Recover R4-R12, r14 + 2 temp values */
#ifdef CONFIG_ARCH_FPU
/* Switched-in task including volatile FP registers ? */
@@ -260,31 +261,6 @@ exception_common:
/* The EXC_RETURN value tells us whether we are returning on the MSP or PSP
*/
-#ifdef CONFIG_BUILD_PROTECTED
- /* The EXC_RETURN value will be 0xfffffff9 (privileged thread) or 0xfffffff1
- * (handler mode) if the stack is on the MSP. It can only be on the PSP if
- * EXC_RETURN is 0xfffffffd (unprivileged thread)
- */
-
- mrs r2, control /* R2=Contents of the control register */
- tst r14, #EXC_RETURN_PROCESS_STACK /* nonzero if context on process stack */
- beq 2f /* Branch if privileged */
-
- orr r2, r2, #1 /* Unprivileged mode */
-#ifdef CONFIG_ARMV8M_STACKCHECK_HARDWARE
- msr psplim, r1
-#endif
- msr psp, r0 /* R0=The process stack pointer */
- b 3f
-2:
- bic r2, r2, #1 /* Privileged mode */
-#ifdef CONFIG_ARMV8M_STACKCHECK_HARDWARE
- msr msplim, r1
-#endif
- msr msp, r0 /* R0=The main stack pointer */
-3:
- msr control, r2 /* Save the updated control register */
-#else
tst r14, #EXC_RETURN_PROCESS_STACK /* nonzero if context on process stack */
#ifdef CONFIG_ARMV8M_STACKCHECK_HARDWARE
itete eq
@@ -295,7 +271,6 @@ exception_common:
#endif
msreq msp, r0 /* R0=The main stack pointer */
msrne psp, r0 /* R0=The process stack pointer */
-#endif
/* Restore the interrupt state */
@@ -305,6 +280,8 @@ exception_common:
msr primask, r3 /* Restore interrupts */
#endif
+ msr control, r12
+
/* Always return with R14 containing the special value that will: (1)
* return to thread mode, and (2) select the correct stack.
*/
diff --git a/arch/arm/src/armv8-m/arm_initialstate.c b/arch/arm/src/armv8-m/arm_initialstate.c
index dbaf0d2052..5ad73e3727 100644
--- a/arch/arm/src/armv8-m/arm_initialstate.c
+++ b/arch/arm/src/armv8-m/arm_initialstate.c
@@ -150,6 +150,8 @@ void up_initial_state(struct tcb_s *tcb)
xcp->regs[REG_EXC_RETURN] = EXC_RETURN_PRIVTHR;
+ xcp->regs[REG_CONTROL] = getcontrol() & ~CONTROL_NPRIV;
+
#ifdef CONFIG_ARCH_FPU
xcp->regs[REG_FPSCR] |= ARMV8M_FPSCR_LTPSIZE_NONE;
#endif /* CONFIG_ARCH_FPU */
diff --git a/arch/arm/src/armv8-m/arm_schedulesigaction.c b/arch/arm/src/armv8-m/arm_schedulesigaction.c
index 7459c7b578..0caf5ccbb7 100644
--- a/arch/arm/src/armv8-m/arm_schedulesigaction.c
+++ b/arch/arm/src/armv8-m/arm_schedulesigaction.c
@@ -162,6 +162,7 @@ void up_schedule_sigaction(struct tcb_s *tcb, sig_deliver_t sigdeliver)
#ifdef CONFIG_BUILD_PROTECTED
CURRENT_REGS[REG_LR] = EXC_RETURN_PRIVTHR;
CURRENT_REGS[REG_EXC_RETURN] = EXC_RETURN_PRIVTHR;
+ CURRENT_REGS[REG_CONTROL] = getcontrol() & ~CONTROL_NPRIV;
#endif
}
}
@@ -209,6 +210,7 @@ void up_schedule_sigaction(struct tcb_s *tcb, sig_deliver_t sigdeliver)
tcb->xcp.regs[REG_XPSR] = ARMV8M_XPSR_T;
#ifdef CONFIG_BUILD_PROTECTED
tcb->xcp.regs[REG_LR] = EXC_RETURN_PRIVTHR;
+ tcb->xcp.regs[REG_CONTROL] = getcontrol() & ~CONTROL_NPRIV;
#endif
}
}
@@ -319,6 +321,7 @@ void up_schedule_sigaction(struct tcb_s *tcb, sig_deliver_t sigdeliver)
tcb->xcp.regs[REG_XPSR] = ARMV8M_XPSR_T;
#ifdef CONFIG_BUILD_PROTECTED
tcb->xcp.regs[REG_LR] = EXC_RETURN_PRIVTHR;
+ tcb->xcp.regs[REG_CONTROL] = getcontrol() & ~CONTROL_NPRIV;
#endif
}
else
@@ -365,6 +368,7 @@ void up_schedule_sigaction(struct tcb_s *tcb, sig_deliver_t sigdeliver)
CURRENT_REGS[REG_XPSR] = ARMV8M_XPSR_T;
#ifdef CONFIG_BUILD_PROTECTED
CURRENT_REGS[REG_LR] = EXC_RETURN_PRIVTHR;
+ CURRENT_REGS[REG_CONTROL] = getcontrol() & ~CONTROL_NPRIV;
#endif
}
@@ -431,6 +435,7 @@ void up_schedule_sigaction(struct tcb_s *tcb, sig_deliver_t sigdeliver)
tcb->xcp.regs[REG_XPSR] = ARMV8M_XPSR_T;
#ifdef CONFIG_BUILD_PROTECTED
tcb->xcp.regs[REG_LR] = EXC_RETURN_PRIVTHR;
+ tcb->xcp.regs[REG_CONTROL] = getcontrol() & ~CONTROL_NPRIV;
#endif
}
}
diff --git a/arch/arm/src/armv8-m/arm_svcall.c b/arch/arm/src/armv8-m/arm_svcall.c
index 70fc9643bd..f24ba53a69 100644
--- a/arch/arm/src/armv8-m/arm_svcall.c
+++ b/arch/arm/src/armv8-m/arm_svcall.c
@@ -145,12 +145,8 @@ int arm_svcall(int irq, void *context, void *arg)
svcinfo(" R8: %08x %08x %08x %08x %08x %08x %08x %08x\n",
regs[REG_R8], regs[REG_R9], regs[REG_R10], regs[REG_R11],
regs[REG_R12], regs[REG_R13], regs[REG_R14], regs[REG_R15]);
-# ifdef REG_EXC_RETURN
- svcinfo(" PSR: %08x EXC_RETURN: %08x\n",
- regs[REG_XPSR], regs[REG_EXC_RETURN]);
-# else
- svcinfo(" PSR: %08x\n", regs[REG_XPSR]);
-# endif
+ svcinfo(" PSR: %08x EXC_RETURN: %08x CONTROL: %08x\n",
+ regs[REG_XPSR], regs[REG_EXC_RETURN], regs[REG_CONTROL]);
}
#endif
@@ -276,6 +272,10 @@ int arm_svcall(int irq, void *context, void *arg)
regs[REG_PC] = (uint32_t)USERSPACE->task_startup & ~1;
regs[REG_EXC_RETURN] = EXC_RETURN_UNPRIVTHR;
+ /* Return unprivileged mode */
+
+ regs[REG_CONTROL] = getcontrol() | CONTROL_NPRIV;
+
/* Change the parameter ordering to match the expectation of struct
* userpace_s task_startup:
*/
@@ -310,6 +310,10 @@ int arm_svcall(int irq, void *context, void *arg)
regs[REG_PC] = (uint32_t)regs[REG_R1] & ~1; /* startup */
regs[REG_EXC_RETURN] = EXC_RETURN_UNPRIVTHR;
+ /* Return unprivileged mode */
+
+ regs[REG_CONTROL] = getcontrol() | CONTROL_NPRIV;
+
/* Change the parameter ordering to match the expectation of the
* user space pthread_startup:
*/
@@ -351,6 +355,10 @@ int arm_svcall(int irq, void *context, void *arg)
regs[REG_PC] = (uint32_t)USERSPACE->signal_handler & ~1;
regs[REG_EXC_RETURN] = EXC_RETURN_UNPRIVTHR;
+ /* Return unprivileged mode */
+
+ regs[REG_CONTROL] = getcontrol() | CONTROL_NPRIV;
+
/* Change the parameter ordering to match the expectation of struct
* userpace_s signal_handler.
*/
@@ -383,6 +391,11 @@ int arm_svcall(int irq, void *context, void *arg)
regs[REG_PC] = rtcb->xcp.sigreturn & ~1;
regs[REG_EXC_RETURN] = EXC_RETURN_PRIVTHR;
+
+ /* Return privileged mode */
+
+ regs[REG_CONTROL] = getcontrol() & ~CONTROL_NPRIV;
+
rtcb->xcp.sigreturn = 0;
}
break;
@@ -418,6 +431,10 @@ int arm_svcall(int irq, void *context, void *arg)
regs[REG_PC] = (uint32_t)dispatch_syscall & ~1;
regs[REG_EXC_RETURN] = EXC_RETURN_PRIVTHR;
+ /* Return privileged mode */
+
+ regs[REG_CONTROL] = getcontrol() & ~CONTROL_NPRIV;
+
/* Offset R0 to account for the reserved values */
regs[REG_R0] -= CONFIG_SYS_RESERVED;
@@ -454,12 +471,9 @@ int arm_svcall(int irq, void *context, void *arg)
CURRENT_REGS[REG_R10], CURRENT_REGS[REG_R11],
CURRENT_REGS[REG_R12], CURRENT_REGS[REG_R13],
CURRENT_REGS[REG_R14], CURRENT_REGS[REG_R15]);
-# ifdef REG_EXC_RETURN
- svcinfo(" PSR: %08x EXC_RETURN: %08x\n",
- CURRENT_REGS[REG_XPSR], CURRENT_REGS[REG_EXC_RETURN]);
-# else
- svcinfo(" PSR: %08x\n", CURRENT_REGS[REG_XPSR]);
-# endif
+ svcinfo(" PSR: %08x EXC_RETURN: %08x CONTROL: %08x\n",
+ CURRENT_REGS[REG_XPSR], CURRENT_REGS[REG_EXC_RETURN],
+ CURRENT_REGS[REG_CONTROL]);
}
# ifdef CONFIG_DEBUG_SVCALL
else
[nuttx] 04/09: arch/armv6-m: Add CONTROL register to xcptcontext.
Posted by xi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
xiaoxiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git
commit eba9c61caddfd1a7a731ef75bfca16b134a6812f
Author: wangming9 <wa...@xiaomi.com>
AuthorDate: Wed Jul 5 20:18:28 2023 +0800
arch/armv6-m: Add CONTROL register to xcptcontext.
To simplify the interrupt handling in protected mode.
Signed-off-by: wangming9 <wa...@xiaomi.com>
---
arch/arm/include/armv6-m/irq.h | 5 +++--
arch/arm/src/armv6-m/arm_exception.S | 12 +++++++-----
arch/arm/src/armv6-m/arm_initialstate.c | 2 ++
arch/arm/src/armv6-m/arm_schedulesigaction.c | 5 +++++
arch/arm/src/armv6-m/arm_svcall.c | 20 ++++++++++++++++++++
5 files changed, 37 insertions(+), 7 deletions(-)
diff --git a/arch/arm/include/armv6-m/irq.h b/arch/arm/include/armv6-m/irq.h
index b7ea799fc4..e900b6b1c5 100644
--- a/arch/arm/include/armv6-m/irq.h
+++ b/arch/arm/include/armv6-m/irq.h
@@ -69,8 +69,9 @@
#define REG_R9 (7) /* R9 */
#define REG_R10 (8) /* R10 */
#define REG_R11 (9) /* R11 */
-#define REG_EXC_RETURN (10) /* EXC_RETURN */
-#define SW_XCPT_REGS (11)
+#define REG_CONTROL (10) /* CONTROL */
+#define REG_EXC_RETURN (11) /* EXC_RETURN */
+#define SW_XCPT_REGS (12)
/* The total number of registers saved by software */
diff --git a/arch/arm/src/armv6-m/arm_exception.S b/arch/arm/src/armv6-m/arm_exception.S
index 595198b698..a2c6ce854b 100644
--- a/arch/arm/src/armv6-m/arm_exception.S
+++ b/arch/arm/src/armv6-m/arm_exception.S
@@ -141,14 +141,15 @@ exception_common:
mov r0, r1 /* Copy the context array pointer */
stmia r0!, {r2-r7} /* Save the SP, PRIMASK, and R4-R7 in the context array */
- /* Save R8-R11 and the EXEC_RETURN value in the context array */
+ /* Save R8-R11 control and the EXEC_RETURN value in the context array */
mov r2, r8 /* Copy high registers to low */
mov r3, r9
mov r4, r10
mov r5, r11
- mov r6, r14
- stmia r0!, {r2-r6} /* Save the high registers r8-r11 and r14 */
+ mrs r6, control /* R6=control */
+ mov r7, r14
+ stmia r0!, {r2-r7} /* Save the high registers r8-r11 control and r14 */
/* Get the exception number in R0=IRQ, R1=register save area on stack */
@@ -188,12 +189,13 @@ exception_common:
movs r2, #(4*REG_R8) /* R2=Offset to R8 storage */
adds r1, r0, r2 /* R1=Address of R8 storage */
- ldmia r1!, {r2-r6} /* Recover R8-R11 and R14 (5 registers)*/
+ ldmia r1!, {r2-r7} /* Recover R8-R11 control and R14 (6 registers)*/
mov r8, r2 /* Move to position in high registers */
mov r9, r3
mov r10, r4
mov r11, r5
- mov r14, r6 /* EXEC_RETURN */
+ msr control, r6
+ mov r14, r7 /* EXEC_RETURN */
/* Recover SP (R2), PRIMASK (R3), and R4-R7. Determine the value of
* the stack pointer as it was on entry to the exception handler.
diff --git a/arch/arm/src/armv6-m/arm_initialstate.c b/arch/arm/src/armv6-m/arm_initialstate.c
index c7639d26ed..fa730969c7 100644
--- a/arch/arm/src/armv6-m/arm_initialstate.c
+++ b/arch/arm/src/armv6-m/arm_initialstate.c
@@ -137,6 +137,8 @@ void up_initial_state(struct tcb_s *tcb)
xcp->regs[REG_EXC_RETURN] = EXC_RETURN_PRIVTHR;
+ xcp->regs[REG_CONTROL] = getcontrol() & ~CONTROL_NPRIV;
+
/* Enable or disable interrupts, based on user configuration */
#ifdef CONFIG_SUPPRESS_INTERRUPTS
diff --git a/arch/arm/src/armv6-m/arm_schedulesigaction.c b/arch/arm/src/armv6-m/arm_schedulesigaction.c
index a9c25d883d..f03b9e535b 100644
--- a/arch/arm/src/armv6-m/arm_schedulesigaction.c
+++ b/arch/arm/src/armv6-m/arm_schedulesigaction.c
@@ -157,6 +157,7 @@ void up_schedule_sigaction(struct tcb_s *tcb, sig_deliver_t sigdeliver)
#ifdef CONFIG_BUILD_PROTECTED
CURRENT_REGS[REG_LR] = EXC_RETURN_PRIVTHR;
CURRENT_REGS[REG_EXC_RETURN] = EXC_RETURN_PRIVTHR;
+ CURRENT_REGS[REG_CONTROL] = getcontrol() & ~CONTROL_NPRIV;
#endif
}
}
@@ -200,6 +201,7 @@ void up_schedule_sigaction(struct tcb_s *tcb, sig_deliver_t sigdeliver)
tcb->xcp.regs[REG_XPSR] = ARMV6M_XPSR_T;
#ifdef CONFIG_BUILD_PROTECTED
tcb->xcp.regs[REG_LR] = EXC_RETURN_PRIVTHR;
+ tcb->xcp.regs[REG_CONTROL] = getcontrol() & ~CONTROL_NPRIV;
#endif
}
}
@@ -306,6 +308,7 @@ void up_schedule_sigaction(struct tcb_s *tcb, sig_deliver_t sigdeliver)
tcb->xcp.regs[REG_XPSR] = ARMV6M_XPSR_T;
#ifdef CONFIG_BUILD_PROTECTED
tcb->xcp.regs[REG_LR] = EXC_RETURN_PRIVTHR;
+ tcb->xcp.regs[REG_CONTROL] = getcontrol() & ~CONTROL_NPRIV;
#endif
}
else
@@ -348,6 +351,7 @@ void up_schedule_sigaction(struct tcb_s *tcb, sig_deliver_t sigdeliver)
CURRENT_REGS[REG_XPSR] = ARMV6M_XPSR_T;
#ifdef CONFIG_BUILD_PROTECTED
CURRENT_REGS[REG_LR] = EXC_RETURN_PRIVTHR;
+ CURRENT_REGS[REG_CONTROL] = getcontrol() & ~CONTROL_NPRIV;
#endif
}
@@ -406,6 +410,7 @@ void up_schedule_sigaction(struct tcb_s *tcb, sig_deliver_t sigdeliver)
tcb->xcp.regs[REG_XPSR] = ARMV6M_XPSR_T;
#ifdef CONFIG_BUILD_PROTECTED
tcb->xcp.regs[REG_LR] = EXC_RETURN_PRIVTHR;
+ tcb->xcp.regs[REG_CONTROL] = getcontrol() & ~CONTROL_NPRIV;
#endif
}
}
diff --git a/arch/arm/src/armv6-m/arm_svcall.c b/arch/arm/src/armv6-m/arm_svcall.c
index b9f96459fb..231c796301 100644
--- a/arch/arm/src/armv6-m/arm_svcall.c
+++ b/arch/arm/src/armv6-m/arm_svcall.c
@@ -264,6 +264,10 @@ int arm_svcall(int irq, void *context, void *arg)
regs[REG_PC] = (uint32_t)USERSPACE->task_startup;
regs[REG_EXC_RETURN] = EXC_RETURN_UNPRIVTHR;
+ /* Return unprivileged mode */
+
+ regs[REG_CONTROL] = getcontrol() | CONTROL_NPRIV;
+
/* Change the parameter ordering to match the expectation of struct
* userpace_s task_startup:
*/
@@ -297,6 +301,10 @@ int arm_svcall(int irq, void *context, void *arg)
regs[REG_PC] = (uint32_t)regs[REG_R1]; /* startup */
regs[REG_EXC_RETURN] = EXC_RETURN_UNPRIVTHR;
+ /* Return unprivileged mode */
+
+ regs[REG_CONTROL] = getcontrol() | CONTROL_NPRIV;
+
/* Change the parameter ordering to match the expectation of the
* user space pthread_startup:
*/
@@ -338,6 +346,10 @@ int arm_svcall(int irq, void *context, void *arg)
regs[REG_PC] = (uint32_t)USERSPACE->signal_handler;
regs[REG_EXC_RETURN] = EXC_RETURN_UNPRIVTHR;
+ /* Return unprivileged mode */
+
+ regs[REG_CONTROL] = getcontrol() | CONTROL_NPRIV;
+
/* Change the parameter ordering to match the expectation of struct
* userpace_s signal_handler.
*/
@@ -370,6 +382,10 @@ int arm_svcall(int irq, void *context, void *arg)
regs[REG_PC] = rtcb->xcp.sigreturn;
regs[REG_EXC_RETURN] = EXC_RETURN_PRIVTHR;
+
+ /* Return privileged mode */
+
+ regs[REG_CONTROL] = getcontrol() & ~CONTROL_NPRIV;
rtcb->xcp.sigreturn = 0;
}
break;
@@ -405,6 +421,10 @@ int arm_svcall(int irq, void *context, void *arg)
regs[REG_PC] = (uint32_t)dispatch_syscall;
regs[REG_EXC_RETURN] = EXC_RETURN_PRIVTHR;
+ /* Return privileged mode */
+
+ regs[REG_CONTROL] = getcontrol() & ~CONTROL_NPRIV;
+
/* Offset R0 to account for the reserved values */
regs[REG_R0] -= CONFIG_SYS_RESERVED;
[nuttx] 08/09: arch/armv8-m: Supports interrupt nesting
Posted by xi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
xiaoxiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git
commit 5cdfa6fec46aea89a2c7bb613ad23204311ddcc8
Author: wangming9 <wa...@xiaomi.com>
AuthorDate: Sat Jul 8 19:37:54 2023 +0800
arch/armv8-m: Supports interrupt nesting
1、The process stack supports interrupt nesting, Execute in MSP;
2、The interrupt stack supports interrupt nesting;
The thread mode use PSP, and the handle mode use MSP;
3、Adjust arm_doirq、exception_common implementation to meet interrupt nesting
4、Adjust the conditions for returning MSP and PSP;
5、remove setintstack;
Signed-off-by: wangming9 <wa...@xiaomi.com>
---
arch/arm/src/armv8-m/arm_doirq.c | 17 ++-----
arch/arm/src/armv8-m/arm_exception.S | 69 +++++++++-------------------
arch/arm/src/armv8-m/arm_initialstate.c | 65 +++++++++++++++++++++++++-
arch/arm/src/armv8-m/arm_schedulesigaction.c | 12 ++---
arch/arm/src/armv8-m/arm_svcall.c | 10 ++--
arch/arm/src/armv8-m/exc_return.h | 40 ++++++++--------
6 files changed, 119 insertions(+), 94 deletions(-)
diff --git a/arch/arm/src/armv8-m/arm_doirq.c b/arch/arm/src/armv8-m/arm_doirq.c
index d4e9b29d14..5c5e86a150 100644
--- a/arch/arm/src/armv8-m/arm_doirq.c
+++ b/arch/arm/src/armv8-m/arm_doirq.c
@@ -47,20 +47,9 @@ uint32_t *arm_doirq(int irq, uint32_t *regs)
PANIC();
#else
- /* Nested interrupts are not supported in this implementation. If you
- * want to implement nested interrupts, you would have to (1) change the
- * way that CURRENT_REGS is handled and (2) the design associated with
- * CONFIG_ARCH_INTERRUPTSTACK.
- */
-
- /* Current regs non-zero indicates that we are processing an interrupt;
- * CURRENT_REGS is also used to manage interrupt level context switches.
- */
-
- if (CURRENT_REGS == NULL)
+ if (regs[REG_EXC_RETURN] & EXC_RETURN_THREAD_MODE)
{
CURRENT_REGS = regs;
- regs = NULL;
}
/* Acknowledge the interrupt */
@@ -69,7 +58,7 @@ uint32_t *arm_doirq(int irq, uint32_t *regs)
/* Deliver the IRQ */
- irq_dispatch(irq, (uint32_t *)CURRENT_REGS);
+ irq_dispatch(irq, regs);
/* If a context switch occurred while processing the interrupt then
* CURRENT_REGS may have change value. If we return any value different
@@ -77,7 +66,7 @@ uint32_t *arm_doirq(int irq, uint32_t *regs)
* switch occurred during interrupt processing.
*/
- if (regs == NULL)
+ if (regs[REG_EXC_RETURN] & EXC_RETURN_THREAD_MODE)
{
/* Restore the cpu lock */
diff --git a/arch/arm/src/armv8-m/arm_exception.S b/arch/arm/src/armv8-m/arm_exception.S
index 4ff4ee7fc0..38b025d217 100644
--- a/arch/arm/src/armv8-m/arm_exception.S
+++ b/arch/arm/src/armv8-m/arm_exception.S
@@ -92,29 +92,6 @@
.thumb
.file "arm_exception.S"
-/****************************************************************************
- * Macro Definitions
- ****************************************************************************/
-
-/****************************************************************************
- * Name: setintstack
- *
- * Description:
- * Set the current stack pointer to the "top" the interrupt stack. Single CPU
- * case. Must be provided by MCU-specific logic in the SMP case.
- *
- ****************************************************************************/
-
-#if !defined(CONFIG_SMP) && CONFIG_ARCH_INTERRUPTSTACK > 7
- .macro setintstack, tmp1, tmp2
-#ifdef CONFIG_ARMV8M_STACKCHECK_HARDWARE
- ldr \tmp1, =g_intstackalloc
- msr msplim, \tmp1
-#endif
- ldr sp, =g_intstacktop
- .endm
-#endif
-
/****************************************************************************
* .text
****************************************************************************/
@@ -145,31 +122,34 @@
.type exception_common, function
exception_common:
- mrs r0, ipsr /* R0=exception number */
mrs r12, control /* R12=control */
/* Complete the context save */
/* The EXC_RETURN value tells us whether the context is on the MSP or PSP */
- tst r14, #EXC_RETURN_PROCESS_STACK /* nonzero if context on process stack */
+ tst r14, #EXC_RETURN_PROCESS_STACK /* Nonzero if context on process stack */
beq 1f /* Branch if context already on the MSP */
mrs r1, psp /* R1=The process stack pointer (PSP) */
- mov sp, r1 /* Set the MSP to the PSP */
+ b 2f
1:
- mov r2, sp /* R2=Copy of the main/process stack pointer */
+ mrs r1, msp /* R1=The main stack pointer (MSP) */
+ sub r2, r1, #SW_XCPT_SIZE /* Reserve the stack space */
+ msr msp, r2
+2:
+ mov r2, r1 /* R2=Copy of the main/process stack pointer */
add r2, #HW_XCPT_SIZE /* R2=MSP/PSP before the interrupt was taken */
/* (ignoring the xPSR[9] alignment bit) */
#ifdef CONFIG_ARMV8M_STACKCHECK_HARDWARE
mov r3, #0x0
ittee eq
- mrseq r1, msplim
+ mrseq r0, msplim
msreq msplim, r3
- mrsne r1, psplim
+ mrsne r0, psplim
msrne psplim, r3
- stmdb sp!, {r1}
+ stmdb r1!, {r0}
#endif
#ifdef CONFIG_ARMV8M_USEBASEPRI
@@ -195,11 +175,11 @@ exception_common:
tst r14, #EXC_RETURN_STD_CONTEXT
ite eq
- vstmdbeq sp!, {s16-s31} /* Save the non-volatile FP context */
- subne sp, #(4*SW_FPU_REGS)
+ vstmdbeq r1!, {s16-s31} /* Save the non-volatile FP context */
+ subne r1, #(4*SW_FPU_REGS)
#endif
- stmdb sp!, {r2-r12,r14} /* Save the remaining registers plus the SP/PRIMASK values */
+ stmdb r1!, {r2-r12,r14} /* Save the remaining registers plus the SP/PRIMASK values */
/* There are two arguments to arm_doirq:
*
@@ -207,19 +187,12 @@ exception_common:
* R1 = The top of the stack points to the saved state
*/
- mov r1, sp
+ mrs r0, ipsr
-#if CONFIG_ARCH_INTERRUPTSTACK > 7
- /* If CONFIG_ARCH_INTERRUPTSTACK is defined, we will set the MSP to use
- * a special special interrupt stack pointer. The way that this is done
- * here prohibits nested interrupts without some additional logic!
- */
-
- setintstack r2, r3 /* SP = IRQ stack top */
-#else
- /* Otherwise, we will re-use the interrupted thread's stack. That may
- * mean using either MSP or PSP stack for interrupt level processing (in
- * kernel mode).
+#if CONFIG_ARCH_INTERRUPTSTACK < 7
+ /* If CONFIG_ARCH_INTERRUPTSTACK is not defined, we will re-use the
+ * interrupted thread's stack. That may mean using either MSP or PSP
+ * stack for interrupt level processing (in kernel mode).
*/
/* If the interrupt stack is disabled, reserve xcpcontext to ensure
@@ -232,10 +205,12 @@ exception_common:
* ---------------------- <- SP
* also the sp should be restore after arm_doirq()
*/
-
+ tst r14, #EXC_RETURN_THREAD_MODE /* Nonzero if context on thread mode */
+ beq 3f /* Branch if context already on the handle mode */
sub r2, r1, #XCPTCONTEXT_SIZE /* Reserve signal context */
bic r2, r2, #7 /* Get the stack pointer with 8-byte alignment */
mov sp, r2 /* Instantiate the aligned stack */
+3:
#endif
bl arm_doirq /* R0=IRQ, R1=register save (msp) */
@@ -261,7 +236,7 @@ exception_common:
/* The EXC_RETURN value tells us whether we are returning on the MSP or PSP
*/
- tst r14, #EXC_RETURN_PROCESS_STACK /* nonzero if context on process stack */
+ tst r14, #EXC_RETURN_PROCESS_STACK /* Nonzero if context on process stack */
#ifdef CONFIG_ARMV8M_STACKCHECK_HARDWARE
itete eq
msreq msplim, r1
diff --git a/arch/arm/src/armv8-m/arm_initialstate.c b/arch/arm/src/armv8-m/arm_initialstate.c
index 5ad73e3727..536f464b28 100644
--- a/arch/arm/src/armv8-m/arm_initialstate.c
+++ b/arch/arm/src/armv8-m/arm_initialstate.c
@@ -148,7 +148,7 @@ void up_initial_state(struct tcb_s *tcb)
* mode before transferring control to the user task.
*/
- xcp->regs[REG_EXC_RETURN] = EXC_RETURN_PRIVTHR;
+ xcp->regs[REG_EXC_RETURN] = EXC_RETURN_THREAD;
xcp->regs[REG_CONTROL] = getcontrol() & ~CONTROL_NPRIV;
@@ -174,3 +174,66 @@ void up_initial_state(struct tcb_s *tcb)
#endif /* CONFIG_SUPPRESS_INTERRUPTS */
}
+
+#if CONFIG_ARCH_INTERRUPTSTACK > 7
+/****************************************************************************
+ * Name: arm_initialize_stack
+ *
+ * Description:
+ * If interrupt stack is defined, the PSP and MSP need to be reinitialized.
+ *
+ ****************************************************************************/
+
+noinline_function void arm_initialize_stack(void)
+{
+#ifdef CONFIG_SMP
+ uint32_t stack = (uint32_t)arm_intstack_top();
+#ifdef CONFIG_ARMV8M_STACKCHECK_HARDWARE
+ uint32_t stacklim = (uint32_t)arm_intstack_alloc();
+#endif
+#else
+ uint32_t stack = (uint32_t)g_intstacktop;
+#ifdef CONFIG_ARMV8M_STACKCHECK_HARDWARE
+ uint32_t stacklim = (uint32_t)g_intstackalloc;
+#endif
+#endif
+ uint32_t temp = 0;
+
+ __asm__ __volatile__
+ (
+ "mrs %1, CONTROL\n"
+ "tst %1, #2\n"
+ "bne 1f\n"
+
+ /* Initialize PSP */
+
+ "mrs %1, msp\n"
+ "msr psp, %1\n"
+#ifdef CONFIG_ARMV8M_STACKCHECK_HARDWARE
+ "mrs %1, msplim\n"
+ "msr psplim, %1\n"
+#endif
+
+ /* Select PSP */
+
+ "mrs %1, CONTROL\n"
+ "orr %1, #2\n"
+ "msr CONTROL, %1\n"
+ "isb sy\n"
+
+ /* Initialize MSP */
+
+ "1:\n"
+ "msr msp, %0\n"
+#ifdef CONFIG_ARMV8M_STACKCHECK_HARDWARE
+ "msr msplim, %2\n"
+#endif
+ :
+#ifdef CONFIG_ARMV8M_STACKCHECK_HARDWARE
+ : "r" (stack), "r" (temp), "r" (stacklim)
+#else
+ : "r" (stack), "r" (temp)
+#endif
+ : "memory");
+}
+#endif
diff --git a/arch/arm/src/armv8-m/arm_schedulesigaction.c b/arch/arm/src/armv8-m/arm_schedulesigaction.c
index 0caf5ccbb7..5641b7b430 100644
--- a/arch/arm/src/armv8-m/arm_schedulesigaction.c
+++ b/arch/arm/src/armv8-m/arm_schedulesigaction.c
@@ -160,8 +160,8 @@ void up_schedule_sigaction(struct tcb_s *tcb, sig_deliver_t sigdeliver)
#endif
CURRENT_REGS[REG_XPSR] = ARMV8M_XPSR_T;
#ifdef CONFIG_BUILD_PROTECTED
- CURRENT_REGS[REG_LR] = EXC_RETURN_PRIVTHR;
- CURRENT_REGS[REG_EXC_RETURN] = EXC_RETURN_PRIVTHR;
+ CURRENT_REGS[REG_LR] = EXC_RETURN_THREAD;
+ CURRENT_REGS[REG_EXC_RETURN] = EXC_RETURN_THREAD;
CURRENT_REGS[REG_CONTROL] = getcontrol() & ~CONTROL_NPRIV;
#endif
}
@@ -209,7 +209,7 @@ void up_schedule_sigaction(struct tcb_s *tcb, sig_deliver_t sigdeliver)
#endif
tcb->xcp.regs[REG_XPSR] = ARMV8M_XPSR_T;
#ifdef CONFIG_BUILD_PROTECTED
- tcb->xcp.regs[REG_LR] = EXC_RETURN_PRIVTHR;
+ tcb->xcp.regs[REG_LR] = EXC_RETURN_THREAD;
tcb->xcp.regs[REG_CONTROL] = getcontrol() & ~CONTROL_NPRIV;
#endif
}
@@ -320,7 +320,7 @@ void up_schedule_sigaction(struct tcb_s *tcb, sig_deliver_t sigdeliver)
#endif
tcb->xcp.regs[REG_XPSR] = ARMV8M_XPSR_T;
#ifdef CONFIG_BUILD_PROTECTED
- tcb->xcp.regs[REG_LR] = EXC_RETURN_PRIVTHR;
+ tcb->xcp.regs[REG_LR] = EXC_RETURN_THREAD;
tcb->xcp.regs[REG_CONTROL] = getcontrol() & ~CONTROL_NPRIV;
#endif
}
@@ -367,7 +367,7 @@ void up_schedule_sigaction(struct tcb_s *tcb, sig_deliver_t sigdeliver)
#endif
CURRENT_REGS[REG_XPSR] = ARMV8M_XPSR_T;
#ifdef CONFIG_BUILD_PROTECTED
- CURRENT_REGS[REG_LR] = EXC_RETURN_PRIVTHR;
+ CURRENT_REGS[REG_LR] = EXC_RETURN_THREAD;
CURRENT_REGS[REG_CONTROL] = getcontrol() & ~CONTROL_NPRIV;
#endif
}
@@ -434,7 +434,7 @@ void up_schedule_sigaction(struct tcb_s *tcb, sig_deliver_t sigdeliver)
#endif
tcb->xcp.regs[REG_XPSR] = ARMV8M_XPSR_T;
#ifdef CONFIG_BUILD_PROTECTED
- tcb->xcp.regs[REG_LR] = EXC_RETURN_PRIVTHR;
+ tcb->xcp.regs[REG_LR] = EXC_RETURN_THREAD;
tcb->xcp.regs[REG_CONTROL] = getcontrol() & ~CONTROL_NPRIV;
#endif
}
diff --git a/arch/arm/src/armv8-m/arm_svcall.c b/arch/arm/src/armv8-m/arm_svcall.c
index f24ba53a69..1d384392e5 100644
--- a/arch/arm/src/armv8-m/arm_svcall.c
+++ b/arch/arm/src/armv8-m/arm_svcall.c
@@ -270,7 +270,7 @@ int arm_svcall(int irq, void *context, void *arg)
*/
regs[REG_PC] = (uint32_t)USERSPACE->task_startup & ~1;
- regs[REG_EXC_RETURN] = EXC_RETURN_UNPRIVTHR;
+ regs[REG_EXC_RETURN] = EXC_RETURN_THREAD;
/* Return unprivileged mode */
@@ -308,7 +308,7 @@ int arm_svcall(int irq, void *context, void *arg)
*/
regs[REG_PC] = (uint32_t)regs[REG_R1] & ~1; /* startup */
- regs[REG_EXC_RETURN] = EXC_RETURN_UNPRIVTHR;
+ regs[REG_EXC_RETURN] = EXC_RETURN_THREAD;
/* Return unprivileged mode */
@@ -353,7 +353,7 @@ int arm_svcall(int irq, void *context, void *arg)
*/
regs[REG_PC] = (uint32_t)USERSPACE->signal_handler & ~1;
- regs[REG_EXC_RETURN] = EXC_RETURN_UNPRIVTHR;
+ regs[REG_EXC_RETURN] = EXC_RETURN_THREAD;
/* Return unprivileged mode */
@@ -390,7 +390,7 @@ int arm_svcall(int irq, void *context, void *arg)
DEBUGASSERT(rtcb->xcp.sigreturn != 0);
regs[REG_PC] = rtcb->xcp.sigreturn & ~1;
- regs[REG_EXC_RETURN] = EXC_RETURN_PRIVTHR;
+ regs[REG_EXC_RETURN] = EXC_RETURN_THREAD;
/* Return privileged mode */
@@ -429,7 +429,7 @@ int arm_svcall(int irq, void *context, void *arg)
rtcb->xcp.nsyscalls = index + 1;
regs[REG_PC] = (uint32_t)dispatch_syscall & ~1;
- regs[REG_EXC_RETURN] = EXC_RETURN_PRIVTHR;
+ regs[REG_EXC_RETURN] = EXC_RETURN_THREAD;
/* Return privileged mode */
diff --git a/arch/arm/src/armv8-m/exc_return.h b/arch/arm/src/armv8-m/exc_return.h
index f415558a7c..d88c62355a 100644
--- a/arch/arm/src/armv8-m/exc_return.h
+++ b/arch/arm/src/armv8-m/exc_return.h
@@ -91,9 +91,9 @@
/* EXC_RETURN_BASE: Bits that are always set in an EXC_RETURN value. */
#ifdef CONFIG_ARCH_TRUSTZONE_NONSECURE
-#define EXC_RETURN_BASE (0xffffff80)
+# define EXC_RETURN_BASE (0xffffff80)
#else
-#define EXC_RETURN_BASE (0xffffff80 | EXC_RETURN_EXC_SECURE | \
+# define EXC_RETURN_BASE (0xffffff80 | EXC_RETURN_EXC_SECURE | \
EXC_RETURN_SECURE_STACK)
#endif
@@ -104,35 +104,33 @@
#define EXC_RETURN_HANDLER (EXC_RETURN_BASE | EXC_RETURN_DEF_STACKING | \
EXC_RETURN_STD_CONTEXT)
-/* EXC_RETURN_PRIVTHR: Return to privileged thread mode. Exception return
- * gets state from the main stack. Execution uses MSP after return.
- */
-
#ifdef CONFIG_ARCH_FPU
-# define EXC_RETURN_PRIVTHR (EXC_RETURN_BASE | EXC_RETURN_THREAD_MODE | \
- EXC_RETURN_DEF_STACKING)
+# define EXC_RETURN_FPU 0
#else
-# define EXC_RETURN_PRIVTHR (EXC_RETURN_BASE | EXC_RETURN_STD_CONTEXT | \
- EXC_RETURN_THREAD_MODE | EXC_RETURN_DEF_STACKING)
+# define EXC_RETURN_FPU EXC_RETURN_STD_CONTEXT
#endif
-/* EXC_RETURN_UNPRIVTHR: Return to unprivileged thread mode. Exception return
- * gets state from the process stack. Execution uses PSP after return.
+#if CONFIG_ARCH_INTERRUPTSTACK > 7
+# define EXC_RETURN_STACK EXC_RETURN_PROCESS_STACK
+#else
+# define EXC_RETURN_STACK 0
+#endif
+
+/* EXC_RETURN_THREAD: Return to thread mode.
+ * If EXC_RETURN_STACK is 0, Return to thread mode.
+ * Execution uses MSP after return.
+ * If EXC_RETURN_STACK is EXC_RETURN_PROCESS_STACK, Return to
+ * thread mode. Execution uses PSP after return.
*/
-#ifdef CONFIG_ARCH_FPU
-# define EXC_RETURN_UNPRIVTHR (EXC_RETURN_BASE | EXC_RETURN_THREAD_MODE | \
- EXC_RETURN_PROCESS_STACK | EXC_RETURN_DEF_STACKING)
-#else
-# define EXC_RETURN_UNPRIVTHR (EXC_RETURN_BASE | EXC_RETURN_STD_CONTEXT | \
- EXC_RETURN_THREAD_MODE | EXC_RETURN_PROCESS_STACK | \
+#define EXC_RETURN_THREAD (EXC_RETURN_BASE | EXC_RETURN_FPU | \
+ EXC_RETURN_THREAD_MODE | EXC_RETURN_STACK | \
EXC_RETURN_DEF_STACKING)
-#endif
#ifdef CONFIG_ARCH_FPU
-#define EXC_INTEGRITY_SIGNATURE (0xfefa125a)
+# define EXC_INTEGRITY_SIGNATURE (0xfefa125a)
#else
-#define EXC_INTEGRITY_SIGNATURE (0xfefa125b)
+# define EXC_INTEGRITY_SIGNATURE (0xfefa125b)
#endif
/* FUNC_RETURN_EXC_SECURE: Exception Secure. The security domain the
[nuttx] 06/09: arch/armv6-m: Supports interrupt nesting
Posted by xi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
xiaoxiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git
commit 2684642a7a846ed367bdd4e57e9cfb060cfe0411
Author: wangming9 <wa...@xiaomi.com>
AuthorDate: Wed Jul 5 21:37:14 2023 +0800
arch/armv6-m: Supports interrupt nesting
1、The process stack supports interrupt nesting, Execute in MSP;
2、The interrupt stack supports interrupt nesting;
The thread mode use PSP, and the handle mode use MSP;
3、Adjust arm_doirq、exception_common implementation to meet interrupt nesting
4、Adjust the conditions for returning MSP and PSP;
5、remove setintstack;
Signed-off-by: wangming9 <wa...@xiaomi.com>
---
arch/arm/src/armv6-m/arm_doirq.c | 18 +++--------
arch/arm/src/armv6-m/arm_exception.S | 40 ++++++++-----------------
arch/arm/src/armv6-m/arm_initialstate.c | 45 +++++++++++++++++++++++++++-
arch/arm/src/armv6-m/arm_schedulesigaction.c | 12 ++++----
arch/arm/src/armv6-m/arm_svcall.c | 10 +++----
arch/arm/src/armv6-m/exc_return.h | 16 +++++-----
arch/arm/src/rp2040/chip.h | 21 -------------
arch/arm/src/rp2040/rp2040_cpustart.c | 6 ++++
8 files changed, 85 insertions(+), 83 deletions(-)
diff --git a/arch/arm/src/armv6-m/arm_doirq.c b/arch/arm/src/armv6-m/arm_doirq.c
index 7abd54145f..80b076636f 100644
--- a/arch/arm/src/armv6-m/arm_doirq.c
+++ b/arch/arm/src/armv6-m/arm_doirq.c
@@ -34,6 +34,7 @@
#include <sched/sched.h>
#include "arm_internal.h"
+#include "exc_return.h"
/****************************************************************************
* Public Functions
@@ -46,20 +47,9 @@ uint32_t *arm_doirq(int irq, uint32_t *regs)
PANIC();
#else
- /* Nested interrupts are not supported in this implementation. If you
- * want to implement nested interrupts, you would have to (1) change the
- * way that CURRENT_REGS is handled and (2) the design associated with
- * CONFIG_ARCH_INTERRUPTSTACK.
- */
-
- /* Current regs non-zero indicates that we are processing an interrupt;
- * CURRENT_REGS is also used to manage interrupt level context switches.
- */
-
- if (CURRENT_REGS == NULL)
+ if (regs[REG_EXC_RETURN] & EXC_RETURN_THREAD_MODE)
{
CURRENT_REGS = regs;
- regs = NULL;
}
/* Acknowledge the interrupt */
@@ -68,7 +58,7 @@ uint32_t *arm_doirq(int irq, uint32_t *regs)
/* Deliver the IRQ */
- irq_dispatch(irq, (uint32_t *)CURRENT_REGS);
+ irq_dispatch(irq, regs);
/* If a context switch occurred while processing the interrupt then
* CURRENT_REGS may have change value. If we return any value different
@@ -76,7 +66,7 @@ uint32_t *arm_doirq(int irq, uint32_t *regs)
* switch occurred during interrupt processing.
*/
- if (regs == NULL)
+ if (regs[REG_EXC_RETURN] & EXC_RETURN_THREAD_MODE)
{
/* Restore the cpu lock */
diff --git a/arch/arm/src/armv6-m/arm_exception.S b/arch/arm/src/armv6-m/arm_exception.S
index a2c6ce854b..6408d4d1f1 100644
--- a/arch/arm/src/armv6-m/arm_exception.S
+++ b/arch/arm/src/armv6-m/arm_exception.S
@@ -58,26 +58,6 @@
.globl exception_common
.file "arm_exception.S"
-/****************************************************************************
- * Macro Definitions
- ****************************************************************************/
-
-/****************************************************************************
- * Name: setintstack
- *
- * Description:
- * Set the current stack pointer to the "top" the interrupt stack. Single CPU
- * case. Must be provided by MCU-specific logic in the SMP case.
- *
- ****************************************************************************/
-
-#if !defined(CONFIG_SMP) && CONFIG_ARCH_INTERRUPTSTACK > 3
- .macro setintstack, tmp1, tmp2
- ldr \tmp1, =g_intstacktop
- mov sp, \tmp1
- .endm
-#endif
-
/****************************************************************************
* .text
****************************************************************************/
@@ -118,10 +98,13 @@ exception_common:
lsls r0, #(31 - EXC_RETURN_PROCESS_BITNO) /* Move to bit 31 */
bmi 1f /* Test bit 31 */
mrs r1, msp /* R1=The main stack pointer */
+ subs r1, #SW_XCPT_SIZE /* R1=Beginning of context array on the stack */
+ msr msp, r1 /* Reserved stack space */
b 2f
1:
mrs r1, psp /* R1=The process stack pointer */
+ subs r1, #SW_XCPT_SIZE /* R1=Beginning of context array on the stack */
/* R1 is the current stack pointer. HW_XCPT_REGS were pushed onto the stack
* when the interrupt was taken so (R1)+HW_XCPT_SIZE is the value of the
@@ -133,7 +116,6 @@ exception_common:
2:
/* Save SP, PRIMASK, and R4-R7 in the context array */
- subs r1, #SW_XCPT_SIZE /* R1=Beginning of context array on the stack */
movs r2, #XCPTCONTEXT_SIZE /* R2=Size of the context array */
add r2, r1 /* R2=MSP/PSP before the interrupt was taken */
/* (ignoring the xPSR[9] alignment bit) */
@@ -160,9 +142,7 @@ exception_common:
* Otherwise, we will use the stack that was current when the interrupt was taken.
*/
-#if CONFIG_ARCH_INTERRUPTSTACK > 3
- setintstack r7, r6 /* SP = IRQ stack top */
-#else
+#if CONFIG_ARCH_INTERRUPTSTACK < 3
/* If the interrupt stack is disabled, reserve xcpcontext to ensure
* that signal processing can have a separate xcpcontext to handle
* signal context (reference: arm_schedulesigaction.c):
@@ -174,9 +154,13 @@ exception_common:
* also the sp should be restore after arm_doirq()
*/
+ mov r2, r14
+ lsls r2, #(31 - EXC_RETURN_THREAD_BITNO) /* Move to bit 31 */
+ bpl 3f /* Test bit 31 */
mov r2, r1 /* Reserve signal context */
subs r2, r2, #XCPTCONTEXT_SIZE
msr msp, r2 /* We are using the main stack pointer */
+3:
#endif
bl arm_doirq /* R0=IRQ, R1=register save area on stack */
@@ -211,14 +195,14 @@ exception_common:
mov r0, r14 /* Copy high register to low register */
lsls r0, #(31 - EXC_RETURN_PROCESS_BITNO) /* Move to bit 31 */
- bmi 3f /* Test bit 31 */
+ bmi 4f /* Test bit 31 */
msr msp, r1 /* R1=The main stack pointer */
- b 4f
+ b 5f
-3:
+4:
msr psp, r1 /* R1=The process stack pointer */
-4:
+5:
/* Restore the interrupt state */
diff --git a/arch/arm/src/armv6-m/arm_initialstate.c b/arch/arm/src/armv6-m/arm_initialstate.c
index fa730969c7..b52c8f3f9b 100644
--- a/arch/arm/src/armv6-m/arm_initialstate.c
+++ b/arch/arm/src/armv6-m/arm_initialstate.c
@@ -135,7 +135,7 @@ void up_initial_state(struct tcb_s *tcb)
* mode before transferring control to the user task.
*/
- xcp->regs[REG_EXC_RETURN] = EXC_RETURN_PRIVTHR;
+ xcp->regs[REG_EXC_RETURN] = EXC_RETURN_THREAD;
xcp->regs[REG_CONTROL] = getcontrol() & ~CONTROL_NPRIV;
@@ -145,3 +145,46 @@ void up_initial_state(struct tcb_s *tcb)
xcp->regs[REG_PRIMASK] = 1;
#endif /* CONFIG_SUPPRESS_INTERRUPTS */
}
+
+#if CONFIG_ARCH_INTERRUPTSTACK > 3
+/****************************************************************************
+ * Name: arm_initialize_stack
+ *
+ * Description:
+ * If interrupt stack is defined, the PSP and MSP need to be reinitialized.
+ *
+ ****************************************************************************/
+
+noinline_function void arm_initialize_stack(void)
+{
+#ifdef CONFIG_SMP
+ uint32_t stack = (uint32_t)arm_intstack_top();
+#else
+ uint32_t stack = (uint32_t)g_intstacktop;
+#endif
+ uint32_t tempa = 0;
+ uint32_t tempb = 2;
+
+ __asm__ __volatile__
+ (
+
+ /* Initialize PSP */
+
+ "mov %1, sp\n"
+ "msr psp, %1\n"
+
+ /* Select PSP */
+
+ "mrs %1, CONTROL\n"
+ "orr %1, %2\n"
+ "msr CONTROL, %1\n"
+ "isb sy\n"
+
+ /* Initialize MSP */
+
+ "msr msp, %0\n"
+ :
+ : "r" (stack), "r" (tempa), "r" (tempb)
+ : "memory");
+}
+#endif
diff --git a/arch/arm/src/armv6-m/arm_schedulesigaction.c b/arch/arm/src/armv6-m/arm_schedulesigaction.c
index f03b9e535b..000c2e866c 100644
--- a/arch/arm/src/armv6-m/arm_schedulesigaction.c
+++ b/arch/arm/src/armv6-m/arm_schedulesigaction.c
@@ -155,8 +155,8 @@ void up_schedule_sigaction(struct tcb_s *tcb, sig_deliver_t sigdeliver)
CURRENT_REGS[REG_PRIMASK] = 1;
CURRENT_REGS[REG_XPSR] = ARMV6M_XPSR_T;
#ifdef CONFIG_BUILD_PROTECTED
- CURRENT_REGS[REG_LR] = EXC_RETURN_PRIVTHR;
- CURRENT_REGS[REG_EXC_RETURN] = EXC_RETURN_PRIVTHR;
+ CURRENT_REGS[REG_LR] = EXC_RETURN_THREAD;
+ CURRENT_REGS[REG_EXC_RETURN] = EXC_RETURN_THREAD;
CURRENT_REGS[REG_CONTROL] = getcontrol() & ~CONTROL_NPRIV;
#endif
}
@@ -200,7 +200,7 @@ void up_schedule_sigaction(struct tcb_s *tcb, sig_deliver_t sigdeliver)
tcb->xcp.regs[REG_PRIMASK] = 1;
tcb->xcp.regs[REG_XPSR] = ARMV6M_XPSR_T;
#ifdef CONFIG_BUILD_PROTECTED
- tcb->xcp.regs[REG_LR] = EXC_RETURN_PRIVTHR;
+ tcb->xcp.regs[REG_LR] = EXC_RETURN_THREAD;
tcb->xcp.regs[REG_CONTROL] = getcontrol() & ~CONTROL_NPRIV;
#endif
}
@@ -307,7 +307,7 @@ void up_schedule_sigaction(struct tcb_s *tcb, sig_deliver_t sigdeliver)
tcb->xcp.regs[REG_PRIMASK] = 1;
tcb->xcp.regs[REG_XPSR] = ARMV6M_XPSR_T;
#ifdef CONFIG_BUILD_PROTECTED
- tcb->xcp.regs[REG_LR] = EXC_RETURN_PRIVTHR;
+ tcb->xcp.regs[REG_LR] = EXC_RETURN_THREAD;
tcb->xcp.regs[REG_CONTROL] = getcontrol() & ~CONTROL_NPRIV;
#endif
}
@@ -350,7 +350,7 @@ void up_schedule_sigaction(struct tcb_s *tcb, sig_deliver_t sigdeliver)
CURRENT_REGS[REG_PRIMASK] = 1;
CURRENT_REGS[REG_XPSR] = ARMV6M_XPSR_T;
#ifdef CONFIG_BUILD_PROTECTED
- CURRENT_REGS[REG_LR] = EXC_RETURN_PRIVTHR;
+ CURRENT_REGS[REG_LR] = EXC_RETURN_THREAD;
CURRENT_REGS[REG_CONTROL] = getcontrol() & ~CONTROL_NPRIV;
#endif
}
@@ -409,7 +409,7 @@ void up_schedule_sigaction(struct tcb_s *tcb, sig_deliver_t sigdeliver)
tcb->xcp.regs[REG_PRIMASK] = 1;
tcb->xcp.regs[REG_XPSR] = ARMV6M_XPSR_T;
#ifdef CONFIG_BUILD_PROTECTED
- tcb->xcp.regs[REG_LR] = EXC_RETURN_PRIVTHR;
+ tcb->xcp.regs[REG_LR] = EXC_RETURN_THREAD;
tcb->xcp.regs[REG_CONTROL] = getcontrol() & ~CONTROL_NPRIV;
#endif
}
diff --git a/arch/arm/src/armv6-m/arm_svcall.c b/arch/arm/src/armv6-m/arm_svcall.c
index 231c796301..2775079dca 100644
--- a/arch/arm/src/armv6-m/arm_svcall.c
+++ b/arch/arm/src/armv6-m/arm_svcall.c
@@ -262,7 +262,7 @@ int arm_svcall(int irq, void *context, void *arg)
*/
regs[REG_PC] = (uint32_t)USERSPACE->task_startup;
- regs[REG_EXC_RETURN] = EXC_RETURN_UNPRIVTHR;
+ regs[REG_EXC_RETURN] = EXC_RETURN_THREAD;
/* Return unprivileged mode */
@@ -299,7 +299,7 @@ int arm_svcall(int irq, void *context, void *arg)
*/
regs[REG_PC] = (uint32_t)regs[REG_R1]; /* startup */
- regs[REG_EXC_RETURN] = EXC_RETURN_UNPRIVTHR;
+ regs[REG_EXC_RETURN] = EXC_RETURN_THREAD;
/* Return unprivileged mode */
@@ -344,7 +344,7 @@ int arm_svcall(int irq, void *context, void *arg)
*/
regs[REG_PC] = (uint32_t)USERSPACE->signal_handler;
- regs[REG_EXC_RETURN] = EXC_RETURN_UNPRIVTHR;
+ regs[REG_EXC_RETURN] = EXC_RETURN_THREAD;
/* Return unprivileged mode */
@@ -381,7 +381,7 @@ int arm_svcall(int irq, void *context, void *arg)
DEBUGASSERT(rtcb->xcp.sigreturn != 0);
regs[REG_PC] = rtcb->xcp.sigreturn;
- regs[REG_EXC_RETURN] = EXC_RETURN_PRIVTHR;
+ regs[REG_EXC_RETURN] = EXC_RETURN_THREAD;
/* Return privileged mode */
@@ -419,7 +419,7 @@ int arm_svcall(int irq, void *context, void *arg)
rtcb->xcp.nsyscalls = index + 1;
regs[REG_PC] = (uint32_t)dispatch_syscall;
- regs[REG_EXC_RETURN] = EXC_RETURN_PRIVTHR;
+ regs[REG_EXC_RETURN] = EXC_RETURN_THREAD;
/* Return privileged mode */
diff --git a/arch/arm/src/armv6-m/exc_return.h b/arch/arm/src/armv6-m/exc_return.h
index 007cb22f21..9572afdf17 100644
--- a/arch/arm/src/armv6-m/exc_return.h
+++ b/arch/arm/src/armv6-m/exc_return.h
@@ -71,17 +71,17 @@
#define EXC_RETURN_HANDLER 0xfffffff1
-/* EXC_RETURN_PRIVTHR: Return to privileged thread mode. Exception return
- * gets state from the main stack. Execution uses MSP after return.
- */
+#if CONFIG_ARCH_INTERRUPTSTACK > 3
-#define EXC_RETURN_PRIVTHR 0xfffffff9
+/* Execution uses PSP after return */
-/* EXC_RETURN_UNPRIVTHR: Return to unprivileged thread mode. Exception return
- * gets state from the process stack. Execution uses PSP after return.
- */
+# define EXC_RETURN_THREAD 0xfffffffd
+#else
+
+/* Execution uses MSP after return */
-#define EXC_RETURN_UNPRIVTHR 0xfffffffd
+# define EXC_RETURN_THREAD 0xfffffff9
+#endif
/****************************************************************************
* Inline Functions
diff --git a/arch/arm/src/rp2040/chip.h b/arch/arm/src/rp2040/chip.h
index 480f623ddb..0274144dbc 100644
--- a/arch/arm/src/rp2040/chip.h
+++ b/arch/arm/src/rp2040/chip.h
@@ -57,26 +57,5 @@
#ifdef __ASSEMBLY__
-/****************************************************************************
- * Name: setintstack
- *
- * Description:
- * Set the current stack pointer to the "top" the correct interrupt stack
- * for the current CPU.
- *
- ****************************************************************************/
-
-#if defined(CONFIG_SMP) && CONFIG_ARCH_INTERRUPTSTACK > 3
- .macro setintstack, tmp1, tmp2
- ldr \tmp1, =RP2040_SIO_CPUID
- ldr \tmp1, [\tmp1, #0]
- lsls \tmp1, \tmp1, #2
- ldr \tmp2, =g_cpu_intstack_top
- add \tmp2, \tmp2, \tmp1
- ldr \tmp2, [\tmp2, #0]
- mov sp, \tmp2 /* sp = g_cpu_intstack_top[cpuid] */
- .endm
-#endif /* CONFIG_SMP && CONFIG_ARCH_INTERRUPTSTACK > 7 */
-
#endif /* __ASSEMBLY__ */
#endif /* __ARCH_ARM_SRC_RP2040_CHIP_H */
diff --git a/arch/arm/src/rp2040/rp2040_cpustart.c b/arch/arm/src/rp2040/rp2040_cpustart.c
index 977dad7e6d..230246497e 100644
--- a/arch/arm/src/rp2040/rp2040_cpustart.c
+++ b/arch/arm/src/rp2040/rp2040_cpustart.c
@@ -137,6 +137,12 @@ static int fifo_comm(uint32_t msg)
static void core1_boot(void)
{
+#if CONFIG_ARCH_INTERRUPTSTACK > 3
+ /* Initializes the stack pointer */
+
+ arm_initialize_stack();
+#endif
+
fifo_drain();
/* Setup NVIC */