arch/armv6-m: Add CONTROL register to xcptcontext.
To simplify the interrupt handling in protected mode. Signed-off-by: wangming9 <wangming9@xiaomi.com>
This commit is contained in:
parent
a4b6b158ce
commit
eba9c61cad
@ -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 */
|
||||
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
Loading…
x
Reference in New Issue
Block a user