• R/O
  • SSH
  • HTTPS

chibios: Commit


Commit MetaInfo

Revision15621 (tree)
Time2022-05-09 22:38:58
Authorgdisirio

Log Message

More virtual IRQs code.

Change Summary

Incremental Difference

--- trunk/os/sb/host/sb.h (revision 15620)
+++ trunk/os/sb/host/sb.h (revision 15621)
@@ -32,6 +32,8 @@
3232 #include "vfs.h"
3333 #include "errcodes.h"
3434
35+#include "sbhdr.h"
36+
3537 /*===========================================================================*/
3638 /* Module constants. */
3739 /*===========================================================================*/
@@ -155,6 +157,11 @@
155157 /*===========================================================================*/
156158
157159 /**
160+ * @brief Type of a mask of Virtual IRQs.
161+ */
162+typedef uint32_t sb_vrqmask_t;
163+
164+/**
158165 * @brief Type of a sandbox manager global structure.
159166 */
160167 typedef struct {
@@ -244,6 +251,10 @@
244251 * @brief Thread running in the sandbox.
245252 */
246253 thread_t *tp;
254+ /**
255+ * @brief Pointer to the image header.
256+ */
257+ const sb_header_t *sbhp;
247258 #if (CH_CFG_USE_MESSAGES == TRUE) || defined(__DOXYGEN__)
248259 /**
249260 * @brief Thread sending a message to the sandbox.
@@ -256,6 +267,20 @@
256267 */
257268 event_source_t es;
258269 #endif
270+#if (SB_CFG_ENABLE_VRQ == TRUE) || defined(__DOXYGEN__)
271+ /**
272+ * @brief Global virtual IRQ status register.
273+ */
274+ uint32_t vrq_isr;
275+ /**
276+ * @brief Mask of enabled virtual IRQ flags.
277+ */
278+ sb_vrqmask_t vrq_enmask;
279+ /**
280+ * @brief Mask of pending virtual IRQ flags.
281+ */
282+ sb_vrqmask_t vrq_wtmask;
283+#endif
259284 #if (SB_CFG_ENABLE_VFS == TRUE) || defined(__DOXYGEN__)
260285 /**
261286 * @brief VFS bindings for Posix API.
@@ -289,7 +314,6 @@
289314 #include "sbelf.h"
290315 #include "sbposix.h"
291316 #include "sbapi.h"
292-#include "sbhdr.h"
293317 #include "sbhost.h"
294318
295319 #endif /* SBHOST_H */
--- trunk/os/sb/host/sbapi.c (revision 15620)
+++ trunk/os/sb/host/sbapi.c (revision 15621)
@@ -71,6 +71,18 @@
7171 #define SB_SVC12_HANDLER sb_api_loadelf
7272 /** @} */
7373
74+/**
75+ * @name Standard API handlers
76+ * @{
77+ */
78+#if (SB_CFG_ENABLE_VRQ == TRUE) || defined(__DOXYGEN__)
79+#define SB_SVC252_HANDLER sb_vrq_disable
80+#define SB_SVC253_HANDLER sb_vrq_enable
81+#define SB_SVC254_HANDLER sb_vrq_getisr
82+#define SB_SVC255_HANDLER sb_vrq_return
83+#endif
84+/** @} */
85+
7486 #define __SVC(x) asm volatile ("svc " #x)
7587
7688 /*
@@ -958,7 +970,6 @@
958970 return tp;
959971 }
960972
961-
962973 static void sb_cleanup(void) {
963974 #if SB_CFG_ENABLE_VFS == TRUE
964975 sb_class_t *sbp = (sb_class_t *)chThdGetSelfX()->ctx.syscall.p;
--- trunk/os/sb/host/sbapi.h (revision 15620)
+++ trunk/os/sb/host/sbapi.h (revision 15621)
@@ -60,7 +60,7 @@
6060 #ifdef __cplusplus
6161 extern "C" {
6262 #endif
63-
63+ void __sb_abort(msg_t msg);
6464 #ifdef __cplusplus
6565 }
6666 #endif
--- trunk/os/sb/host/sbhost.c (revision 15620)
+++ trunk/os/sb/host/sbhost.c (revision 15621)
@@ -25,6 +25,8 @@
2525 * @{
2626 */
2727
28+#include <string.h>
29+
2830 #include "ch.h"
2931 #include "sb.h"
3032
@@ -194,14 +196,8 @@
194196 */
195197 void sbObjectInit(sb_class_t *sbp, const sb_config_t *config) {
196198
199+ memset((void *)sbp, 0, sizeof (sb_class_t));
197200 sbp->config = config;
198- sbp->tp = NULL;
199-#if CH_CFG_USE_MESSAGES == TRUE
200- sbp->msg_tp = NULL;
201-#endif
202-#if CH_CFG_USE_EVENTS == TRUE
203- chEvtObjectInit(&sbp->es);
204-#endif
205201 }
206202
207203 /**
@@ -221,7 +217,6 @@
221217 void *wsp, size_t size, tprio_t prio,
222218 const char *argv[], const char *envp[]) {
223219 thread_t *utp;
224- const sb_header_t *sbhp;
225220 const sb_config_t *config = sbp->config;
226221 void *usp, *uargv, *uenvp;
227222 size_t envsize, argsize, parsize;
@@ -228,22 +223,22 @@
228223 int uargc, uenvc;
229224
230225 /* Header location.*/
231- sbhp = (const sb_header_t *)(void *)config->regions[config->code_region].area.base;
226+ sbp->sbhp = (const sb_header_t *)(void *)config->regions[config->code_region].area.base;
232227
233228 /* Checking header magic numbers.*/
234- if ((sbhp->hdr_magic1 != SB_HDR_MAGIC1) ||
235- (sbhp->hdr_magic2 != SB_HDR_MAGIC2)) {
229+ if ((sbp->sbhp->hdr_magic1 != SB_HDR_MAGIC1) ||
230+ (sbp->sbhp->hdr_magic2 != SB_HDR_MAGIC2)) {
236231 return NULL;
237232 }
238233
239234 /* Checking header size and alignment.*/
240- if (sbhp->hdr_size != sizeof (sb_header_t)) {
235+ if (sbp->sbhp->hdr_size != sizeof (sb_header_t)) {
241236 return NULL;
242237 }
243238
244239 /* Checking header entry point.*/
245240 if (!chMemIsSpaceWithinX(&config->regions[config->code_region].area,
246- (const void *)sbhp->hdr_entry,
241+ (const void *)sbp->sbhp->hdr_entry,
247242 (size_t)2)) {
248243 return NULL;
249244 }
@@ -290,7 +285,7 @@
290285 .wbase = (stkalign_t *)wsp,
291286 .wend = (stkalign_t *)wsp + (size / sizeof (stkalign_t)),
292287 .prio = prio,
293- .u_pc = sbhp->hdr_entry,
288+ .u_pc = sbp->sbhp->hdr_entry,
294289 .u_psp = (uint32_t)usp,
295290 .arg = (void *)sbp
296291 };
@@ -303,7 +298,7 @@
303298 utp = chThdCreateUnprivileged(&utd);
304299
305300 /* For messages exchange.*/
306- sbp->tp = utp;
301+ sbp->tp = utp;
307302
308303 return utp;
309304 }
@@ -345,7 +340,6 @@
345340 const char *argv[], const char *envp[]) {
346341 const sb_config_t *config = sbp->config;
347342 memory_area_t ma = config->regions[0].area;
348- const sb_header_t *sbhp;
349343 msg_t ret;
350344 void *usp, *uargv, *uenvp;
351345 size_t envsize, argsize, parsize;
@@ -396,21 +390,21 @@
396390 CH_RETURN_ON_ERROR(ret);
397391
398392 /* Header location.*/
399- sbhp = (const sb_header_t *)(void *)ma.base;
393+ sbp->sbhp = (const sb_header_t *)(void *)ma.base;
400394
401395 /* Checking header magic numbers.*/
402- if ((sbhp->hdr_magic1 != SB_HDR_MAGIC1) ||
403- (sbhp->hdr_magic2 != SB_HDR_MAGIC2)) {
396+ if ((sbp->sbhp->hdr_magic1 != SB_HDR_MAGIC1) ||
397+ (sbp->sbhp->hdr_magic2 != SB_HDR_MAGIC2)) {
404398 return CH_RET_ENOEXEC;
405399 }
406400
407401 /* Checking header size.*/
408- if (sbhp->hdr_size != sizeof (sb_header_t)) {
402+ if (sbp->sbhp->hdr_size != sizeof (sb_header_t)) {
409403 return CH_RET_ENOEXEC;
410404 }
411405
412406 /* Checking header entry point.*/
413- if (!chMemIsSpaceWithinX(&ma, (const void *)sbhp->hdr_entry, (size_t)2)) {
407+ if (!chMemIsSpaceWithinX(&ma, (const void *)sbp->sbhp->hdr_entry, (size_t)2)) {
414408 return CH_RET_EFAULT;
415409 }
416410
@@ -420,7 +414,7 @@
420414 .wbase = (stkalign_t *)wsp,
421415 .wend = (stkalign_t *)wsp + (size / sizeof (stkalign_t)),
422416 .prio = prio,
423- .u_pc = sbhp->hdr_entry,
417+ .u_pc = sbp->sbhp->hdr_entry,
424418 .u_psp = (uint32_t)usp,
425419 .arg = (void *)sbp
426420 };
--- trunk/os/sb/host/sbvrq.c (revision 15620)
+++ trunk/os/sb/host/sbvrq.c (revision 15621)
@@ -51,12 +51,29 @@
5151 /* Module local functions. */
5252 /*===========================================================================*/
5353
54+__STATIC_FORCEINLINE void vfq_makectx(sb_class_t *sbp,
55+ struct port_extctx *ectxp,
56+ uint32_t active_mask) {
57+ uint32_t irqn = __CLZ(active_mask);
58+ sbp->vrq_wtmask &= ~(1U << irqn);
59+
60+ /* Building the return context.*/
61+ ectxp->r0 = irqn;
62+ ectxp->pc = sbp->sbhp->hdr_vfq; /* TODO validate or let it eventually crash? */
63+ ectxp->xpsr = 0x01000000U;
64+#if CORTEX_USE_FPU == TRUE
65+ ectxp->fpscr = FPU->FPDSCR;
66+#endif
67+}
68+
5469 /*===========================================================================*/
5570 /* Module exported functions. */
5671 /*===========================================================================*/
5772
5873 /**
59- * @brief Activates VRQs on the specified sandbox.
74+ * @brief Triggers VRQs on the specified sandbox.
75+ * @note This function must be called from IRQ context because
76+ * it manipulates exception stack frames.
6077 *
6178 * @param[in] sbp pointer to a @p sb_class_t structure
6279 * @param[in] vmask mask of VRQs to be activated
@@ -63,43 +80,128 @@
6380 * @return The operation status.
6481 * @retval false if the activation has succeeded.
6582 * @retval true in case of sandbox stack overflow.
83+ *
84+ * @special
6685 */
67-bool sbVRQSignalMaskI(sb_class_t *sbp, sb_vrqmask_t vmask) {
86+bool sbVRQTriggerFromISR(sb_class_t *sbp, sb_vrqmask_t vmask) {
6887 struct port_extctx *ectxp;
69- const sb_header_t *sbhp;
7088
71- /* This IRQ could have preempted the sandbox itself or some other thread,
72- handling is different.*/
73- if (sbp->tp->state == CH_STATE_CURRENT) {
74- /* Sandbox case, getting the current exception frame.*/
75- ectxp = (struct port_extctx *)__get_PSP() - 1;
89+ chSysLockFromISR();
7690
77- /* Checking if the new frame is within the sandbox else failure.*/
78- if (!sb_is_valid_write_range(sbp,
79- (void *)ectxp,
80- sizeof (struct port_extctx))) {
81- return true;
91+ /* Adding VRQ mask to the pending mask.*/
92+ sbp->vrq_wtmask |= vmask;
93+
94+ /* Triggering the VRQ if required.*/
95+ if (sbp->vrq_isr == 0U) {
96+ sb_vrqmask_t active_mask = sbp->vrq_wtmask & sbp->vrq_enmask;
97+
98+ if (active_mask != 0U) {
99+
100+ /* This IRQ could have preempted the sandbox itself or some other thread,
101+ handling is different.*/
102+ if (sbp->tp->state == CH_STATE_CURRENT) {
103+ /* Sandbox case, getting the current exception frame.*/
104+ ectxp = (struct port_extctx *)__get_PSP() - 1;
105+
106+ /* Checking if the new frame is within the sandbox else failure.*/
107+ if (!sb_is_valid_write_range(sbp,
108+ (void *)ectxp,
109+ sizeof (struct port_extctx))) {
110+ chSysUnlockFromISR();
111+
112+ return true;
113+ }
114+ }
115+ else {
116+ ectxp = sbp->tp->ctx.sp - 1;
117+
118+ /* Checking if the new frame is within the sandbox else failure.*/
119+ if (!sb_is_valid_write_range(sbp,
120+ (void *)ectxp,
121+ sizeof (struct port_extctx))) {
122+ chSysUnlockFromISR();
123+
124+ return true;
125+ }
126+
127+ /* Preventing leakage of information, clearing all register values, those
128+ would come from outside the sandbox.*/
129+ memset((void *)ectxp, 0, sizeof (struct port_extctx));
130+ }
131+
132+ /* Building the return context.*/
133+ vfq_makectx(sbp, ectxp, active_mask);
82134 }
83135 }
84- else {
85- ectxp = sbp->tp->ctx.sp - 1;
86136
87- /* Checking if the new frame is within the sandbox else failure.*/
88- if (!sb_is_valid_write_range(sbp,
89- (void *)ectxp,
90- sizeof (struct port_extctx))) {
91- return true;
137+ chSysUnlockFromISR();
138+
139+ return false;
140+}
141+
142+void sb_vrq_disable(struct port_extctx *ectxp) {
143+ sb_class_t *sbp = (sb_class_t *)chThdGetSelfX()->ctx.syscall.p;
144+
145+ ectxp->r0 = sbp->vrq_isr;
146+ sbp->vrq_isr |= SB_VRQ_ISR_DISABLED;
147+}
148+
149+void sb_vrq_enable(struct port_extctx *ectxp) {
150+ sb_class_t *sbp = (sb_class_t *)chThdGetSelfX()->ctx.syscall.p;
151+
152+ ectxp->r0 = sbp->vrq_isr;
153+ sbp->vrq_isr &= ~SB_VRQ_ISR_DISABLED;
154+
155+ /* Re-triggering the VRQ if required.*/
156+ if (sbp->vrq_isr == 0U) {
157+ sb_vrqmask_t active_mask = sbp->vrq_wtmask & sbp->vrq_enmask;
158+
159+ if (active_mask != 0U) {
160+ /* Creating a context for return.*/
161+ ectxp--;
162+
163+ /* Checking if the new frame is within the sandbox else failure.*/
164+ if (!sb_is_valid_write_range(sbp,
165+ (void *)ectxp,
166+ sizeof (struct port_extctx))) {
167+ __sb_abort(CH_RET_EFAULT);
168+ }
169+
170+ /* Building the return context.*/
171+ vfq_makectx(sbp, ectxp, active_mask);
92172 }
173+ }
174+}
93175
94- /* Preventing leakage of information, clearing all register values, those
95- would come from outside the sandbox.*/
96- memset((void *)ectxp, 0, sizeof (struct port_extctx));
176+void sb_vrq_getisr(struct port_extctx *ectxp) {
177+ sb_class_t *sbp = (sb_class_t *)chThdGetSelfX()->ctx.syscall.p;
178+
179+ ectxp->r0 = sbp->vrq_isr;
180+}
181+
182+void sb_vrq_return(struct port_extctx *ectxp) {
183+ sb_class_t *sbp = (sb_class_t *)chThdGetSelfX()->ctx.syscall.p;
184+
185+ if (((sbp->vrq_isr & SB_VRQ_ISR_IRQMODE) == 0U)) {
186+ __sb_abort(CH_RET_EFAULT);
97187 }
98188
99- /* Header location.*/
100- sbhp = (const sb_header_t *)(void *)sbp->config->regions[sbp->config->code_region].area.base;
189+ /* Re-triggering the VRQ if required.*/
190+ if (sbp->vrq_isr == 0U) {
191+ sb_vrqmask_t active_mask = sbp->vrq_wtmask & sbp->vrq_enmask;
101192
102- return false;
193+ if (active_mask != 0U) {
194+ /* Building the return context, reusing the current context structure.*/
195+ vfq_makectx(sbp, ectxp, active_mask);
196+ }
197+ }
198+ else {
199+ /* Ending IRQ mode.*/
200+ sbp->vrq_isr &= ~SB_VRQ_ISR_IRQMODE;
201+
202+ /* Discarding the return current context, returning on the previous one.*/
203+ ectxp++;
204+ }
103205 }
104206
105207 #endif /* SB_CFG_ENABLE_VRQ == TRUE */
--- trunk/os/sb/host/sbvrq.h (revision 15620)
+++ trunk/os/sb/host/sbvrq.h (revision 15621)
@@ -34,6 +34,14 @@
3434 /* Module constants. */
3535 /*===========================================================================*/
3636
37+/**
38+ * @name Virtual ISR register bit definitions
39+ * @{
40+ */
41+#define SB_VRQ_ISR_DISABLED 1U
42+#define SB_VRQ_ISR_IRQMODE 2U
43+/** @} */
44+
3745 /*===========================================================================*/
3846 /* Module pre-compile time settings. */
3947 /*===========================================================================*/
@@ -46,11 +54,6 @@
4654 /* Module data structures and types. */
4755 /*===========================================================================*/
4856
49-/**
50- * @brief Type of a mask of Virtual IRQs.
51- */
52-typedef uint32_t sb_vrqmask_t;
53-
5457 /*===========================================================================*/
5558 /* Module macros. */
5659 /*===========================================================================*/
@@ -62,7 +65,11 @@
6265 #ifdef __cplusplus
6366 extern "C" {
6467 #endif
65- bool sbVRQSignalMaskI(sb_class_t *sbp, sb_vrqmask_t vmask);
68+ bool sbVRQTriggerFromISR(sb_class_t *sbp, sb_vrqmask_t vmask);
69+ void sb_vrq_disable(struct port_extctx *ectxp);
70+ void sb_vrq_enable(struct port_extctx *ectxp);
71+ void sb_vrq_getisr(struct port_extctx *ectxp);
72+ void sb_vrq_return(struct port_extctx *ectxp);
6673 #ifdef __cplusplus
6774 }
6875 #endif
Show on old repository browser