1 2 3 4 5 6 7 8 9
10 11 12 13
14
15 package ti.sysbios.knl;
16
17 import xdc.rov.ViewInfo;
18
19 import xdc.runtime.Error;
20 import xdc.runtime.Assert;
21 import xdc.runtime.Diags;
22 import xdc.runtime.Log;
23
24 import ti.sysbios.misc.Queue;
25
26 /*!
27 * ======== Swi ========
28 * Software Interrupt Manager.
29 *
30 * The Swi module manages software interrupt service routines, which are
31 * patterned after hardware interrupt service routines.
32
33 * DSP/BIOS manages four distinct levels of execution threads: hardware
34 * interrupt service routines, software interrupt routines, tasks, and
35 * background idle functions. A software interrupt is an object that
36 * encapsulates a function to be executed and a priority.
37 * Software interrupts are prioritized, preempt tasks, and are preempted
38 * by hardware interrupt service routines.
39 *
40 * Each software interrupt has a priority level. A software interrupt
41 * preempts any lower-priority software interrupt currently executing.
42 *
43 * A target program uses an API call to post a Swi object. This causes the
44 * Swi module to schedule execution of the software interrupt's function.
45 * When a Swi is posted by an API call, the Swi object's function is not
46 * executed immediately. Instead, the function is scheduled for execution.
47 * DSP/BIOS uses the Swi's priority to determine whether to preempt the
48 * thread currently running. Note that if a Swi is posted several times
49 * before it begins running, (because Hwis and higher priority interrupts
50 * are running,) when the Swi does eventually run, it will run only one time.
51 *
52 * Software interrupts can be posted for execution with a call to {@link #post}
53 * or a number of other Swi functions. Each Swi object has a "trigger"
54 * which is used either to determine whether to post the Swi or as a value
55 * that can be evaluated within the Swi's function. {@link #andn} and
56 * {@link #dec}
57 * post the Swi if the trigger value transitions to 0. {@link #or} and
58 * {@link #inc}
59 * also modify the trigger value. ({@link #or} sets bits, and {@link #andn}
60 * clears bits.)
61 *
62 * The {@link #disable} and {@link #restore} operations allow you to post several
63 * Swis and enable them all for execution at the same time. The Swi
64 * priorities then determine which Swi runs first.
65 *
66 * All Swis run to completion; you cannot suspend a Swi while it waits for
67 * something (for example, a device) to be ready. So, you can use the
68 * trigger to tell the Swi when all the devices and other conditions it
69 * relies on are ready. Within a Swi processing function, a call to
70 * Swi_getTrigger returns the value of the trigger when the Swi started running.
71 * Note that the trigger is automatically reset to its original value
72 * when a Swi runs; however, {@link #getTrigger} will return the saved trigger
73 * value from when the Swi started execution.
74 *
75 * All Swis run with interrupts globally enabled (ie GIE = 1).
76 * Therefore, any Swi module API that results in a
77 * Swi being made ready to run (ie {@link #post}, {@link #inc}, {@link #andn},
78 * {@link #or}, {@link #restore}, or {@link #enable})
79 * will subsequently also cause interrupts to be enabled while the
80 * Swi function executes. Upon return from the Swi function,
81 * global interrupts are restored to their previous enabled/disabled
82 * state.
83 *
84 * A Swi preempts any currently running Swi with a lower priority. If two
85 * Swis with the same priority level have been posted, the Swi that was
86 * posted first runs first. Hwis in turn preempt any currently running Swi,
87 * allowing the target to respond quickly to hardware peripherals.
88 *
89 * Swi threads are executed using the ISR (or "Hwi") stack. Thus
90 * they share the ISR stack with Hwi threads.
91 *
92 * {@link #disable} also disables the Task scheduler.
93 * Therefore, Task pre-emption and blocking is disabled while
94 * the Swi scheduler is disabled.
95 * {@link #restore} will re-enable and invoke the Task
96 * scheduler if the Task scheduler was not disabled prior
97 * to invoking {@link #disable}.
98 * The currently ready highest priority task will be immediately
99 * switched to or continue to run when the lowest order {@link #restore}
100 * invocation re-enables the Swi scheduler.
101 *
102 * In the following example, the newly created task is not switched to
103 * until after the Swi_restore() call since Task scheduling is disabled
104 * while Swi scheduling is disabled:
105 *
106 * @p(code)
107 * key = Swi_disable();
108 * // create a task of higher priority than the current task thread
109 * myTaskParams.priority = Task_getPri(Task_self()) + 1;
110 * myTask = Task_create(myTaskFunc, &myTaskParams, NULL);
111 * Swi_restore(key);
112 * @p
113 *
114 * Hook Functions
115 *
116 * Sets of hook functions can be specified for the Swi module. Each set
117 * contains these hook functions:
118 * @p(blist)
119 * -Register: A function called before all statically created swis
120 * are initialized at runtime.
121 * -Create: A function that is called when a swi is created.
122 * This includes swis that are created statically and those
123 * created dynamically using {@link #create}.
124 * -Ready: A function that is called when any swi becomes ready
125 * to run.
126 * -Begin: A function that is called just prior to running a swi.
127 * -End: A function that is called just after a swi finishes.
128 * -Delete: A function that is called when a swi is deleted at
129 * run-time with {@link #delete}.
130 * @p
131 *
132 * Register Function
133 *
134 * The Register function is provided to allow a hook set to store its
135 * hookset ID. This id can be passed to {@link #setHookContext} and
136 * {@link #getHookContext} to set or get hookset-specific context. The
137 * Register function must be specified if the hook implementation
138 * needs to use {@link #setHookContext} or {@link #getHookContext}.
139 * The registerFxn hook function is called during system initialization
140 * before interrupts have been enabled.
141 *
142 * @p(code)
143 * Void myRegisterFxn(Int id);
144 * @p
145 *
146 * Create and Delete Functions
147 *
148 * The create and delete functions are called whenever a Swi is created
149 * or deleted. They are called with interrupts enabled (unless called
150 * at boot time or from main()).
151 *
152 * @p(code)
153 * Void myCreateFxn(Swi_Handle swi, Error_Block *eb);
154 * @p
155 *
156 * @p(code)
157 * Void myDeleteFxn(Swi_Handle swi);
158 * @p
159 *
160 * Ready, Begin, and End Functions
161 *
162 * The ready, begin and end functions are all called with interrupts
163 * enabled. The ready function is called when a Swi is posted and made
164 * ready to run. The begin function is called right before the function
165 * associated with the given Swi is run. The end function is called
166 * right after this function returns.
167 *
168 * @p(code)
169 * Void myReady(Swi_Handle swi);
170 * @p
171 *
172 * @p(code)
173 * Void myBegin(Swi_Handle swi);
174 * @p
175 *
176 * @p(code)
177 * Void myEnd(Swi_Handle swi);
178 * @p
179 *
180 * @p(html)
181 * <h3> Calling Context </h3>
182 * <table border="1" cellpadding="3">
183 * <colgroup span="1"></colgroup> <colgroup span="5" align="center"></colgroup>
184 *
185 * <tr><th> Function </th><th> Hwi </th><th> Swi </th><th> Task </th><th> Main </th><th> Startup </th></tr>
186 * <!-- -->
187 * <tr><td> {@link #create} </td><td> N </td><td> N </td><td> Y </td><td> Y </td><td> N </td></tr>
188 * <tr><td> {@link #disable} </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td><td> N </td></tr>
189 * <tr><td> {@link #getTrigger} </td><td> Y </td><td> Y </td><td> N </td><td> N </td><td> N </td></tr>
190 * <tr><td> {@link #Params_init} </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td></tr>
191 * <tr><td> {@link #restore} </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td><td> N </td></tr>
192 * <tr><td> {@link #self} </td><td> Y </td><td> Y </td><td> N </td><td> N </td><td> N </td></tr>
193 *
194 * <tr><td> {@link #andn} </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td><td> N </td></tr>
195 * <tr><td> {@link #construct} </td><td> N </td><td> N </td><td> Y </td><td> Y </td><td> N </td></tr>
196 * <tr><td> {@link #dec} </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td><td> N </td></tr>
197 * <tr><td> {@link #delete} </td><td> N </td><td> N </td><td> Y </td><td> Y </td><td> N </td></tr>
198 * <tr><td> {@link #destruct} </td><td> N </td><td> N </td><td> Y </td><td> Y </td><td> N </td></tr>
199 * <tr><td> {@link #getHookContext} </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td><td> N </td></tr>
200 * <tr><td> {@link #getPri} </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td><td> N </td></tr>
201 * <tr><td> {@link #inc} </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td><td> N </td></tr>
202 * <tr><td> {@link #or} </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td><td> N </td></tr>
203 * <tr><td> {@link #post} </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td><td> N </td></tr>
204 * <tr><td> {@link #setHookContext} </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td><td> N </td></tr>
205 * <tr><td colspan="6"> Definitions: <br />
206 * <ul>
207 * <li> <b>Hwi</b>: API is callable from a Hwi thread. </li>
208 * <li> <b>Swi</b>: API is callable from a Swi thread. </li>
209 * <li> <b>Task</b>: API is callable from a Task thread. </li>
210 * <li> <b>Main</b>: API is callable during any of these phases: </li>
211 * <ul>
212 * <li> In your module startup after this module is started (e.g. Swi_Module_startupDone() returns TRUE). </li>
213 * <li> During xdc.runtime.Startup.lastFxns. </li>
214 * <li> During main().</li>
215 * <li> During BIOS.startupFxns.</li>
216 * </ul>
217 * <li> <b>Startup</b>: API is callable during any of these phases:</li>
218 * <ul>
219 * <li> During xdc.runtime.Startup.firstFxns.</li>
220 * <li> In your module startup before this module is started (e.g. Swi_Module_startupDone() returns FALSE).</li>
221 * </ul>
222 * </ul>
223 * </td></tr>
224 *
225 * </table>
226 * @p
227 */
228
229 @ModuleStartup
230
231 @InstanceFinalize
232
233 @InstanceInitError
234
235
236 module Swi
237 {
238
239
240
241
242
243 /*! Swi function type definition. */
244 typedef Void (*FuncPtr)(UArg, UArg);
245
246 /*! Swi hook set type definition. */
247 struct HookSet {
248 Void (*registerFxn)(Int);
249 Void (*createFxn)(Handle, Error.Block *);
250 Void (*readyFxn)(Handle);
251 Void (*beginFxn)(Handle);
252 Void (*endFxn)(Handle);
253 Void (*deleteFxn)(Handle);
254 };
255
256 metaonly struct BasicView {
257 String label;
258 String state;
259 UInt priority;
260 String fxn[];
261 UArg arg0;
262 UArg arg1;
263 UInt initTrigger;
264 UInt curTrigger;
265
266 };
267
268 metaonly struct ModuleView {
269 String schedulerState;
270 String readyQMask;
271 Ptr currentSwi;
272 String currentFxn[];
273 };
274
275 /*! @_nodoc */
276 @Facet
277 metaonly config ViewInfo.Instance rovViewInfo =
278 xdc.rov.ViewInfo.create({
279 viewMap: [
280 ['Basic', {type: ViewInfo.INSTANCE, viewInitFxn: 'viewInitBasic', structName: 'BasicView'}],
281 ['Module', {type: ViewInfo.MODULE, viewInitFxn: 'viewInitModule', structName: 'ModuleView'}]
282 ]
283 });
284
285
286
287
288
289 /*! Logged just prior to invoking a Swi's function */
290 config Log.Event LM_begin = {
291 mask: Diags.USER1 | Diags.USER2,
292 msg: "LM_begin: swi: 0x%x, func: 0x%x, preThread: %d"
293 };
294
295 /*! Logged just after returning from a Swi's function */
296 config Log.Event LD_end = {
297 mask: Diags.USER2,
298 msg: "LD_end: swi: 0x%x"
299 };
300
301 /*! Logged when Swi_post() is called */
302 config Log.Event LM_post = {
303 mask: Diags.USER1 | Diags.USER2,
304 msg: "LM_post: swi: 0x%x, func: 0x%x, pri: %d"
305 };
306
307
308
309 /*! Asserted when Swi_create is called when {@link ti.sysbios.BIOS#swiEnabled} is false */
310 config Assert.Id A_swiDisabled = {
311 msg: "A_swiDisabled: Cannot create a Swi when Swi is disabled."
312 };
313
314 /*! Asserted when a Swi priority is not in the range of 0 and numPriorities-1 */
315 config Assert.Id A_badPriority = {
316 msg: "A_badPriority: An invalid Swi priority was used."
317 };
318
319 /*!
320 * Number of Swi priorities supported. Default is 16.
321 *
322 * The maximum number of priorities supported is
323 * target specific and depends on the number of
324 * bits in a UInt data type. For 6x and Arm devices
325 * the maximum number of priorities is therefore 32.
326 * For 28x, 55x, and MSP430 devices, the maximum number of
327 * priorities is 16.
328 */
329 config UInt numPriorities = 16;
330
331 /*!
332 * const array to hold all HookSet objects.
333 */
334 config HookSet hooks[length] = [];
335
336
337
338
339 /*!
340 * ======== addHookSet ========
341 * addHookSet is used in a config file to add a hook set (defined
342 * by struct HookSet).
343 *
344 * HookSet structure elements may be omitted, in which case those
345 * elements will not exist.
346 *
347 * @param(hookSet) structure of type HookSet
348 */
349 metaonly Void addHookSet(HookSet hookSet);
350
351 /*!
352 * @_nodoc
353 * ======== Swi_startup ========
354 * Start the Swi scheduler.
355 * This function is called in BIOS_start() after Hwi_enable().
356 */
357 Void startup();
358
359 /*!
360 * @_nodoc
361 * ======== Swi_enabled ========
362 * Returns TRUE if the Swi scheduler is enabled.
363 */
364 Bool enabled();
365
366 /*!
367 * ======== disable ========
368 * Disable Swi Scheduling.
369 *
370 * {@link #disable} and {@link #restore} control Swi scheduling.
371 * {@link #disable} disables all other Swi functions from running until
372 * {@link #restore} is called. Hardware interrupts can still run.
373 *
374 * {@link #disable} and {@link #restore} allow you to ensure that
375 * statements that must be performed together during critical
376 * processing are not preempted by other Swis or Tasks.
377 *
378 * The value of the key returned is opaque to applications and is meant
379 * to be passed to Swi_restore().
380 *
381 * In the following example, the critical section cannot be preempted
382 * by any Swis.
383 *
384 * @p(code)
385 * key = Swi_disable();
386 * `critical section`
387 * Swi_restore(key);
388 * @p
389 *
390 * @a(constraints)
391 * Swi_disable also disables the Task scheduler.
392 * Swi_restore will re-enable and invoke the Task
393 * scheduler if the Task scheduler was not disabled prior
394 * to invoking Swi_disable().
395 *
396 * @b(returns) opaque key for use with Swi_restore()
397 */
398 UInt disable();
399
400 /*!
401 * @_nodoc
402 * ======== enable ========
403 * Enable Swi Scheduling.
404 *
405 * Swi_enable unconditionally enables Swis and invokes the Swi scheduler
406 * if any Swis are pending.
407 *
408 * @a(constraints)
409 * Swi_enable will also invoke the Task scheduler if the
410 * Task scheduler is not currently disabled.
411 *
412 * The {@link #post} discussion regarding global interrupts applies
413 * to this API.
414 *
415 */
416 Void enable();
417
418 /*!
419 * ======== restore ========
420 * Restore Swi Scheduling state.
421 *
422 * Swi_restore restores the Swi scheduler to the locked/unlocked state
423 * it was in when Swi_disable was called. If the scheduler becomes
424 * unlocked and Swis of sufficient priority have been made ready to
425 * run by any of the posting APIs, then they are run at this time.
426 *
427 * Swi_disable and Swi_restore control software interrupt processing.
428 * Swi_disable disables all other Swi functions from running until
429 * Swi_restore is called. Hardware interrupts can still run.
430 *
431 * Swi_disable and Swi_restore allow you to ensure that statements that
432 * must be performed together during critical processing are not
433 * pre-empted by other Swis.
434 *
435 * In the following example, the critical section can not be preempted
436 * by any Swis:
437 *
438 * @p(code)
439 * key = Swi_disable();
440 * `critical section`
441 * Swi_restore(key);
442 * @p
443 *
444 * @a(constraints)
445 * Swi_restore will also re-enable and invoke the Task
446 * scheduler if the Task scheduler was not disabled prior to
447 * invoking Swi_disable().
448 *
449 * The {@link #post} discussion regarding global interrupts applies
450 * to this API.
451 *
452 * @param(key) key to restore previous Swi scheduler state
453 */
454 Void restore(UInt key);
455
456 /*!
457 * @_nodoc
458 * ======== restoreHwi ========
459 *
460 * Restore Swi Scheduling state.
461 * Optimized version used by Hwi dispatcher.
462 */
463 Void restoreHwi(UInt key);
464
465 /*!
466 * ======== self ========
467 * Return address of currently executing Swi object.
468 *
469 * Swi_self returns the handle of the currently executing Swi.
470 *
471 * @b(returns) handle of currently running Swi
472 */
473 Handle self();
474
475 /*!
476 * ======== getTrigger ========
477 * Return the trigger value of the currently executing Swi.
478 *
479 * Swi_getTrigger returns the value that Swi's trigger had when the Swi
480 * started running. DSP/BIOS saves the trigger value internally so that
481 * Swi_getTrigger can access it at any point within a Swi object's function.
482 * DSP/BIOS then automatically resets the trigger to its initial value.
483 *
484 * Swi_getTrigger should only be called within a function run by a Swi
485 * object.
486 *
487 * When called from within the context of a Swi, the value returned by
488 * Swi_getTrigger is zero if the Swi was posted by a call to Swi_andn,
489 * or Swi_dec. Therefore, Swi_getTrigger provides relevant information
490 * only if the Swi was posted by a call to Swi_inc, Swi_or, Swi_orHook,
491 * or Swi_post.
492 *
493 * @b(returns) trigger value
494 */
495 UInt getTrigger();
496
497 /*!
498 * @_nodoc
499 * ======== raisePri ========
500 *
501 * Raise a Swi's priority. (Provided for legacy compatibility)
502 *
503 * Swi_raisePri is used to raise the priority of the currently running
504 * Swi to the priority passed in as the argument. Swi_raisePri can be used
505 * in conjunction with Swi_restorePri to provide a mutual exclusion
506 * mechanism without disabling Swis.
507 *
508 * Swi_raisePri should be called before a shared resource is accessed, and
509 * Swi_restorePri should be called after the access to the shared resource.
510 *
511 * A call to Swi_raisePri not followed by a Swi_restorePri keeps the Swi's
512 * priority for the rest of the processing at the raised level. A Swi_post
513 * of the Swi posts the Swi at its original priority level.
514 *
515 * A Swi object's execution priority must range from 0 to
516 * Swi_numPriorities - 1
517 *
518 * Swi_raisePri never lowers the current Swi priority.
519 *
520 * Constraints and Calling Context
521 * @p(blist)
522 * - Swi_raisePri must only be called from a Swi context.
523 * @p
524 *
525 * @b(returns) key for use with restorePri()
526 */
527 UInt raisePri(UInt priority);
528
529 /*!
530 * @_nodoc
531 * ======== restorePri ========
532 *
533 * Restore a Swi's priority. (Provided for legacy compatibility)
534 *
535 * Swi_restorePri restores the priority to the Swi's priority prior to the
536 * Swi_raisePri call. Swi_restorePri can be used in
537 * conjunction with Swi_raisePri to provide a mutual exclusion mechanism
538 * without disabling all Swis.
539 *
540 * Swi_raisePri should be called right before the shared resource is
541 * referenced, and Swi_restorePri should be called after the reference to
542 * the shared resource.
543 *
544 * Constraints and Calling Context
545 *
546 * @p(blist)
547 * - Swi_restorePri must only be called from a Swi context.
548 * @p
549 *
550 * @param(key) key returned from Swi_raisePri
551 */
552 Void restorePri(UInt key);
553
554 instance:
555
556 /*!
557 * ======== create ========
558 * Create a software interrupt.
559 *
560 * Swi_create creates a new Swi object.
561 *
562 * @param(fxn) Swi Function
563 */
564 create(FuncPtr fxn);
565
566
567
568 /*! Swi function argument 0. Default is 0. */
569 config UArg arg0 = 0;
570
571 /*! Swi function argument 1. Default is 0. */
572 config UArg arg1 = 0;
573
574 /*!
575 * Swi priority (0 to {@link #numPriorities} - 1).
576 *
577 * Default value of ~0 yields a Swi priority of
578 * (numPriorities - 1).
579 */
580 config UInt priority = ~0;
581
582 /*! Initial Swi trigger value. Default is 0. */
583 config UInt trigger = 0;
584
585
586
587 /*!
588 * ======== andn ========
589 * Clear bits in Swi's trigger; post if trigger becomes 0.
590 *
591 * Swi_andn is used to conditionally post a software interrupt.
592 * Swi_andn clears the bits specified by a mask from Swi's internal
593 * trigger. If the Swi's trigger becomes 0, Swi_andn posts the Swi.
594 * The bitwise logical operation performed is:
595 *
596 * trigger = trigger AND (NOT MASK)
597 *
598 * For example, if multiple conditions that all be met before a
599 * Swi can run, you should use a different bit in the trigger for
600 * each condition. When a condition is met, clear the bit for that
601 * condition.
602 *
603 * Swi_andn results in a context switch if the Swi's trigger becomes
604 * zero and the Swi has higher priority than the currently executing
605 * thread.
606 *
607 * You specify a Swi's initial trigger value in the configuration.
608 * The trigger value is automatically reset when the Swi executes.
609 *
610 * @a(constraints)
611 * The {@link #post} discussion regarding global interrupts applies
612 * to this API.
613 *
614 * @param(mask) inverse value to be ANDed
615 */
616 Void andn(UInt mask);
617
618 /*!
619 * ======== dec ========
620 * Decrement Swi's trigger value; post if trigger becomes 0.
621 *
622 * Swi_dec is used to conditionally post a software interrupt. Swi_dec
623 * decrements the value in Swi's trigger by 1. If Swi's trigger value
624 * becomes 0, Swi_dec posts the Swi. You can increment a trigger value
625 * by using Swi_inc, which always posts the Swi.
626 *
627 * For example, you would use Swi_dec if you wanted to post a Swi after
628 * a number of occurrences of an event.
629 *
630 * You specify a Swi's initial trigger value in the configuration. The
631 * trigger value is automatically reset when the Swi executes.
632 *
633 * Swi_dec results in a context switch if the Swi's trigger becomes
634 * zero and the Swi has higher priority than the currently executing
635 * thread.
636 *
637 * @a(constraints)
638 * The {@link #post} discussion regarding global interrupts applies
639 * to this API.
640 */
641 Void dec();
642
643 /*!
644 * ======== getHookContext ========
645 * Get hook instance's context pointer for a swi.
646 *
647 * @b(returns) hook instance's context pointer for swi
648 */
649 Ptr getHookContext(Int id);
650
651 /*!
652 * ======== setHookContext ========
653 * Set hook instance's context for a swi.
654 *
655 * @param(id) hook instance's ID
656 * @param(hookContext) value to write to context
657 */
658 Void setHookContext(Int id, Ptr hookContext);
659
660 /*!
661 * ======== getPri ========
662 * Return a Swi's priority.
663 *
664 * Swi_getPri returns the priority of the Swi passed in as the
665 * argument.
666 *
667 * @b(returns) Priority of swi
668 */
669 UInt getPri();
670
671 /*!
672 * ======== inc ========
673 * Increment Swi's trigger value and post the Swi.
674 *
675 * Swi_inc increments the value in Swi's trigger by 1 and posts the Swi
676 * regardless of the resulting trigger value. You can decrement a
677 * trigger value using Swi_dec, which only posts the Swi if the
678 * trigger value is 0.
679 *
680 * If a Swi is posted several times before it has a chance to begin
681 * executing (ie: when Hwis or higher priority Swis are running) the Swi
682 * only runs one time. If this situation occurs, you can use Swi_inc to
683 * post the Swi. Within the Swi's function, you could then use
684 * Swi_getTrigger to find out how many times this Swi has been posted
685 * since the last time it was executed.
686 *
687 * You specify a Swi's initial trigger value at Swi creation time.
688 * The trigger value is automatically reset when the Swi executes.
689 * To get the trigger value, use Swi_getTrigger.
690 *
691 * Swi_inc results in a context switch if the Swi is higher priority
692 * than the currently executing thread.
693 *
694 * @a(constraints)
695 * The {@link #post} discussion regarding global interrupts applies
696 * to this API.
697 */
698 Void inc();
699
700 /*!
701 * ======== or ========
702 * Or mask with value contained in Swi's trigger and post the
703 * Swi.
704 *
705 * Swi_or is used to post a software interrupt. Swi_or sets the bits
706 * specified by a mask in Swi's trigger. Swi_or posts the Swi
707 * regardless of the resulting trigger value. The bitwise logical
708 * operation performed on the trigger value is:
709 *
710 * trigger = trigger OR mask
711 *
712 * You specify a Swi's initial trigger value in the configuration.
713 * The trigger value is automatically reset when the Swi executes.
714 * To get the trigger value, use Swi_getTrigger.
715 *
716 * For example, you might use Swi_or to post a Swi if any of three
717 * events should cause a Swi to be executed, but you want the Swi's
718 * function to be able to tell which event occurred. Each event
719 * would correspond to a different bit in the trigger.
720 *
721 * Swi_or results in a context switch if the Swi is higher priority
722 * than the currently executing thread.
723 *
724 * @a(constraints)
725 * The {@link #post} discussion regarding global interrupts applies
726 * to this API.
727 *
728 * @param(mask) value to be ORed
729 */
730 Void or(UInt mask);
731
732 /*!
733 * ======== post ========
734 * Unconditionally post a software interrupt.
735 *
736 * Swi_post is used to post a software interrupt regardless of the
737 * trigger value. No change is made to the Swi object's trigger value.
738 *
739 * Swi_post results in a context switch if the Swi is higher priority
740 * than the currently executing thread.
741 *
742 * @a(constraints)
743 * Swis are ALWAYS run with interrupts enabled.
744 * If a Swi is made ready to run as a consequence of this
745 * API, interrupts will be globally enabled while the Swi function
746 * executes, regardless of the prior globally enabled/disabled state of interrupts.
747 * Upon return from this API, the global interrupt enabled/disabled state
748 * is restored to its previous value.
749 */
750 Void post();
751
752 internal:
753
754 755 756 757 758 759
760 config UInt (*taskDisable)();
761 config Void (*taskRestore)(UInt);
762
763 764 765 766 767 768 769 770
771 Void schedule();
772
773 774 775 776 777 778
779 Void run(Object *swi);
780
781 782 783 784
785 Int postInit(Object *swi, Error.Block *eb);
786
787 /*!
788 * @_nodoc
789 * Number of statically constructed Swi objects.
790 * Shouldn't be set directly by the user's
791 * config (it gets set by instance$static$init).
792 */
793 config UInt numConstructedSwis = 0;
794
795 struct Instance_State {
796 Queue.Elem qElem;
797 FuncPtr fxn;
798 UArg arg0;
799 UArg arg1;
800 UInt priority;
801 UInt mask;
802 Bool posted;
803 UInt initTrigger;
804 UInt trigger;
805 Queue.Handle readyQ;
806 Ptr hookEnv[];
807 };
808
809 struct Module_State {
810 Bool locked;
811 UInt curSet;
812 UInt curTrigger;
813 Handle curSwi;
814 Queue.Handle curQ;
815
816 Queue.Object readyQ[];
817 Handle constructedSwis[];
818
819 };
820 }
821 822 823
824