Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Interrupt nesting #10057

Merged
merged 9 commits into from
Aug 7, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
arch/armv6-m: Add CONTROL register to xcptcontext.
To simplify the interrupt handling in protected mode.

Signed-off-by: wangming9 <[email protected]>
  • Loading branch information
wangming9 committed Aug 3, 2023
commit 996177f3e916bacc08fec2c8cb9166fcaecd2043
5 changes: 3 additions & 2 deletions arch/arm/include/armv6-m/irq.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 */

Expand Down
12 changes: 7 additions & 5 deletions arch/arm/src/armv6-m/arm_exception.S
Original file line number Diff line number Diff line change
Expand Up @@ -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 */

Expand Down Expand Up @@ -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.
Expand Down
2 changes: 2 additions & 0 deletions arch/arm/src/armv6-m/arm_initialstate.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
5 changes: 5 additions & 0 deletions arch/arm/src/armv6-m/arm_schedulesigaction.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
}
Expand Down Expand Up @@ -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
}
}
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
}

Expand Down Expand Up @@ -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
}
}
Expand Down
20 changes: 20 additions & 0 deletions arch/arm/src/armv6-m/arm_svcall.c
Original file line number Diff line number Diff line change
Expand Up @@ -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:
*/
Expand Down Expand Up @@ -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:
*/
Expand Down Expand Up @@ -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.
*/
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down