From 66ee9ca5062cbf383db97a304ac50885c0efbb4c Mon Sep 17 00:00:00 2001 From: Giovanni Di Sirio Date: Sun, 10 Oct 2021 10:45:17 +0000 Subject: [PATCH] SB support in ARMv7-M-ALT port, work in progress. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@14888 27425a3e-05d8-49a3-a47f-9c15f0e5edd8 --- os/common/ports/ARMv7-M-ALT/chcore.c | 28 -------- os/common/ports/ARMv7-M-ALT/chcore.h | 8 +-- os/common/ports/ARMv7-M-ALT/chcoreapi.c | 64 ++++++++++++++++++- .../ARMv7-M-ALT/compilers/GCC/mk/port.mk | 3 +- 4 files changed, 66 insertions(+), 37 deletions(-) diff --git a/os/common/ports/ARMv7-M-ALT/chcore.c b/os/common/ports/ARMv7-M-ALT/chcore.c index bb2f31cbb..1f0b96097 100644 --- a/os/common/ports/ARMv7-M-ALT/chcore.c +++ b/os/common/ports/ARMv7-M-ALT/chcore.c @@ -25,8 +25,6 @@ * @{ */ -#include - #include "ch.h" /*===========================================================================*/ @@ -96,32 +94,6 @@ 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) { - thread_t *tp = chThdGetSelfX(); - struct port_extctx *ectxp; - - /* Storing the current PSP position in the thread context, this position - will be used for system calls processing,*/ - tp->ctx.syscall.s_psp = __get_PSP(); - - /* Creating a port_extctx context for unprivileged mode entry.*/ - u_psp -= sizeof (struct port_extctx); - tp->ctx.syscall.u_psp = u_psp; - ectxp = (struct port_extctx *)u_psp; - - /* Initializing the user mode entry context.*/ - memset((void *)ectxp, 0, sizeof (struct port_extctx)); - ectxp->pc = u_pc; - ectxp->xpsr = 0x01000000U; -#if CORTEX_USE_FPU == TRUE - ectxp->fpscr = __get_FPSCR(); -#endif - - /* Jump with no return to the context saved at "u_psp". */ - asm volatile ("svc #1"); - chSysHalt("svc"); -} #endif /* PORT_USE_SYSCALL == TRUE */ #if (PORT_ENABLE_GUARD_PAGES == TRUE) || defined(__DOXYGEN__) diff --git a/os/common/ports/ARMv7-M-ALT/chcore.h b/os/common/ports/ARMv7-M-ALT/chcore.h index 31422cc97..16d860228 100644 --- a/os/common/ports/ARMv7-M-ALT/chcore.h +++ b/os/common/ports/ARMv7-M-ALT/chcore.h @@ -725,11 +725,8 @@ struct port_context { #ifdef __cplusplus extern "C" { #endif -void port_init(os_instance_t *oip); -void __port_thread_start(void); -#if PORT_USE_SYSCALL == TRUE - void port_unprivileged_jump(uint32_t pc, uint32_t psp); -#endif + void port_init(os_instance_t *oip); + void __port_thread_start(void); #ifdef __cplusplus } #endif @@ -893,6 +890,7 @@ __STATIC_FORCEINLINE rtcnt_t port_rt_get_counter_value(void) { #if CH_CFG_ST_TIMEDELTA > 0 #include "chcore_timer.h" #endif /* CH_CFG_ST_TIMEDELTA > 0 */ +#include "chcoreapi.h" #endif /* !defined(_FROM_ASM_) */ diff --git a/os/common/ports/ARMv7-M-ALT/chcoreapi.c b/os/common/ports/ARMv7-M-ALT/chcoreapi.c index 2fec4b12e..5a72e124c 100644 --- a/os/common/ports/ARMv7-M-ALT/chcoreapi.c +++ b/os/common/ports/ARMv7-M-ALT/chcoreapi.c @@ -25,6 +25,8 @@ * @{ */ +#include + #include "ch.h" /*===========================================================================*/ @@ -47,6 +49,39 @@ /* Module local functions. */ /*===========================================================================*/ +#if (PORT_USE_SYSCALL == TRUE) || defined(__DOXYGEN__) +static THD_FUNCTION(unprivileged_handler, arg) { + unprivileged_thread_descriptor_t *utdp = (unprivileged_thread_descriptor_t *)arg; + thread_t *utp = chThdGetSelfX(); + uint32_t u_psp = utdp->u_psp; + struct port_extctx *ectxp; + + /* Persistent thread parameter.*/ + utp->ctx.syscall.p = utdp->arg; + + /* Storing the current PSP position in the thread context, this position + will be used for system calls processing,*/ + utp->ctx.syscall.s_psp = __get_PSP(); + + /* Creating a port_extctx context for unprivileged mode entry.*/ + u_psp -= sizeof (struct port_extctx); + utp->ctx.syscall.u_psp = u_psp; + ectxp = (struct port_extctx *)u_psp; + + /* Initializing the user mode entry context.*/ + memset((void *)ectxp, 0, sizeof (struct port_extctx)); + ectxp->pc = utdp->u_pc; + ectxp->xpsr = 0x01000000U; +#if CORTEX_USE_FPU == TRUE + ectxp->fpscr = __get_FPSCR(); +#endif + + /* Jump with no return to the context saved at "u_psp". */ + asm volatile ("svc #1"); + chSysHalt("svc"); +} +#endif + /*===========================================================================*/ /* Module interrupt handlers. */ /*===========================================================================*/ @@ -56,10 +91,33 @@ /*===========================================================================*/ #if (PORT_USE_SYSCALL == TRUE) || defined(__DOXYGEN__) -thread_t *chThdCreateStaticUnprivileged(void *wsp, size_t size, tprio_t prio, - uint32_t u_pc, uint32_t u_psp) { +thread_t *chThdCreateUnprivileged(const unprivileged_thread_descriptor_t *utdp) { + thread_t *utp; - return NULL; + /* Creating a thread on the unprivileged handler.*/ + thread_descriptor_t td = { + .name = utdp->name, + .wbase = utdp->wbase, + .wend = utdp->wend, + .prio = utdp->prio, + .funcp = unprivileged_handler, + .arg = (void *)utdp, +#if CH_CFG_SMP_MODE != FALSE + .instance = NULL +#endif + }; + utp = chThdCreateSuspended(&td); + +#if PORT_SWITCHED_REGIONS_NUMBER > 0 + /* Regions for the unprivileged thread, will be set up on switch-in.*/ + for (unsigned i = 0U; i < PORT_SWITCHED_REGIONS_NUMBER; i++) { + utp->ctx.regions[i].rasr = utdp->regions[i].rasr; + utp->ctx.regions[i].rbar = utdp->regions[i].rbar; + } +#endif + + /* Starting the thread.*/ + return chThdStart(utp); } #endif /* PORT_USE_SYSCALL == TRUE */ diff --git a/os/common/ports/ARMv7-M-ALT/compilers/GCC/mk/port.mk b/os/common/ports/ARMv7-M-ALT/compilers/GCC/mk/port.mk index 78e9a0f71..7dc192c17 100644 --- a/os/common/ports/ARMv7-M-ALT/compilers/GCC/mk/port.mk +++ b/os/common/ports/ARMv7-M-ALT/compilers/GCC/mk/port.mk @@ -1,5 +1,6 @@ # List of the ChibiOS/RT ARMv7M generic port files. -PORTSRC = $(CHIBIOS)/os/common/ports/ARMv7-M-ALT/chcore.c +PORTSRC = $(CHIBIOS)/os/common/ports/ARMv7-M-ALT/chcore.c \ + $(CHIBIOS)/os/common/ports/ARMv7-M-ALT/chcoreapi.c PORTASM = $(CHIBIOS)/os/common/ports/ARMv7-M-ALT/compilers/GCC/chcoreasm.S