More syscall-related code.

git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@14876 27425a3e-05d8-49a3-a47f-9c15f0e5edd8
This commit is contained in:
Giovanni Di Sirio 2021-10-06 13:21:33 +00:00
parent 86bd1a948e
commit dd5e10df69
3 changed files with 50 additions and 26 deletions

View File

@ -58,24 +58,45 @@
/*===========================================================================*/ /*===========================================================================*/
#if (PORT_USE_SYSCALL == TRUE) || defined(__DOXYGEN__) #if (PORT_USE_SYSCALL == TRUE) || defined(__DOXYGEN__)
CC_NO_INLINE void __port_syslock_noinline(void) {
port_lock();
__stats_start_measure_crit_thd();
__dbg_check_lock();
}
uint32_t __port_get_s_psp(void) {
return (uint32_t)__sch_get_currthread()->ctx.syscall.s_psp;
}
CC_WEAK void port_syscall(struct port_extctx *ctxp, uint32_t n) { CC_WEAK void port_syscall(struct port_extctx *ctxp, uint32_t n) {
(void)ctxp; (void)ctxp;
(void)n; (void)n;
chSysHalt("svc"); while (true) {
/* In unprivileged mode but nothing to do.*/;
}
}
CC_WEAK void __port_do_syscall_entry(uint32_t n) {
thread_t *tp = __sch_get_currthread();
struct port_extctx *ectxp, *newctxp;
uint32_t u_psp;
/* Caller context in unprivileged memory.*/
u_psp = __get_PSP();
tp->ctx.syscall.u_psp = u_psp;
ectxp = (struct port_extctx *)u_psp;
/* Return context for change in privileged mode.*/
newctxp = ((struct port_extctx *)tp->ctx.syscall.s_psp) - 1;
/* Creating context for return in privileged mode.*/
newctxp->r0 = (uint32_t)ectxp;
newctxp->r1 = n;
newctxp->pc = (uint32_t)port_syscall;
newctxp->xpsr = 0x01000000U;
#if CORTEX_USE_FPU == TRUE
newctxp->fpscr = FPU->FPDSCR;
#endif
/* Switching PSP to the privileged mode PSP.*/
__set_PSP((uint32_t)newctxp);
}
CC_WEAK void __port_do_syscall_return(void) {
__set_PSP(__sch_get_currthread()->ctx.syscall.u_psp);
} }
void port_unprivileged_jump(uint32_t u_pc, uint32_t u_psp) { void port_unprivileged_jump(uint32_t u_pc, uint32_t u_psp) {
@ -86,8 +107,9 @@ void port_unprivileged_jump(uint32_t u_pc, uint32_t u_psp) {
will be used for system calls processing,*/ will be used for system calls processing,*/
tp->ctx.syscall.s_psp = __get_PSP(); tp->ctx.syscall.s_psp = __get_PSP();
/* Creating a port_extctx context for user mode entry.*/ /* Creating a port_extctx context for unprivileged mode entry.*/
u_psp -= sizeof (struct port_extctx); u_psp -= sizeof (struct port_extctx);
tp->ctx.syscall.u_psp = u_psp;
ectxp = (struct port_extctx *)u_psp; ectxp = (struct port_extctx *)u_psp;
/* Initializing the user mode entry context.*/ /* Initializing the user mode entry context.*/
@ -98,11 +120,8 @@ void port_unprivileged_jump(uint32_t u_pc, uint32_t u_psp) {
ectxp->fpscr = __get_FPSCR(); ectxp->fpscr = __get_FPSCR();
#endif #endif
/* Setting up the new PSP into the unprivileged area.*/ /* Jump with no return to the context saved at "u_psp". */
__set_PSP(u_psp); asm volatile ("svc #1");
/* Jump with no return. */
asm volatile ("svc 1");
chSysHalt("svc"); chSysHalt("svc");
} }
#endif /* PORT_USE_SYSCALL == TRUE */ #endif /* PORT_USE_SYSCALL == TRUE */

View File

@ -486,6 +486,7 @@ struct port_context {
#if (PORT_USE_SYSCALL == TRUE) || defined(__DOXYGEN__) #if (PORT_USE_SYSCALL == TRUE) || defined(__DOXYGEN__)
struct { struct {
uint32_t s_psp; uint32_t s_psp;
uint32_t u_psp;
const void *p; const void *p;
} syscall; } syscall;
#endif #endif

View File

@ -207,25 +207,29 @@ SVC_Handler:
#if PORT_USE_SYSCALL #if PORT_USE_SYSCALL
mrs r3, PSP mrs r3, PSP
ldr r3, [r3, #24] /* PC position. */ ldr r3, [r3, #24] /* PC position. */
ldrh r3, [r3, #-2] /* SVC opcode. */
mrs r2, CONTROL mrs r2, CONTROL
tst r2, #1 tst r2, #1
beq frompriv beq frompriv
/* SVC called from non-privileged mode, it is a syscall.*/ /* SVC called from non-privileged mode for a syscall.*/
bic r2, #1
msr CONTROL, r2
/* Note, LR already contains the return address.*/
ldrh r0, [r3, #-2] /* SVC opcode. */
and r0, #255
b __port_do_syscall_entry
frompriv: frompriv:
/* SVC called from privileged mode.*/ /* SVC called from privileged mode for unprivileged return.*/
ldrh r3, [r3, #-2] /* SVC opcode. */
ands r3, #255 ands r3, #255
beq ctxswitch beq ctxswitch
/* Called for non-privileged mode change.*/ /* Called for non-privileged mode change.*/
msr PSP, r0 /* Discarding SVC context. */
orr r2, #1 orr r2, #1
msr CONTROL, r2 /* Switching to non-privileged. */ msr CONTROL, r2 /* Switching to non-privileged. */
bx lr b __port_do_syscall_return
ctxswitch: ctxswitch:
/* Called for context switch.*/ /* SVC called from privilege mode for context switch.*/
#endif #endif
/* Context store for old thread.*/ /* Context store for old thread.*/
adds r1, #CONTEXT_OFFSET adds r1, #CONTEXT_OFFSET