1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
32 33 34 35
36
37 import xdc.runtime.Error;
38
39
40 /*!
41 * ======== Hwi ========
42 * Hardware Interrupt Support Module.
43 *
44 * The IHwi interface specifies APIs for globally enabling, disabling, and
45 * restoring interrupts.
46 *
47 * Additionally, management of individual, device-specific hardware
48 * interrupts is provided.
49 *
50 * The user can statically or dynamically assign routines that run when
51 * specific hardware interrupts occur.
52 *
53 * Dynamic assignment of Hwi routines to interrupts at run-time is done
54 * using the Hwi_create function.
55 *
56 * Interrupt routines can be written completely in C, completely in
57 * assembly, or in a mix of C and assembly. In order to support interrupt
58 * routines
59 * written completely in C, an interrupt dispatcher is provided that performs
60 * the requisite prolog and epilog for an interrupt routine.
61 *
62 * Some routines are assigned to interrupts by the other SYS/BIOS
63 * modules. For example, the Clock module configures its own timer interrupt
64 * handler. See the Clock Module for more details.
65 *
66 * @a(Runtime Hwi Creation)
67 *
68 * Below is an example of configuring an interrupt at runtime.
69 * Usually this code would be placed in main().
70 *
71 * @p(code)
72 * #include <xdc/runtime/Error.h>
73 * #include <ti/sysbios/hal/Hwi.h>
74 *
75 * Hwi_Handle myHwi;
76 *
77 * Int main(Int argc, char* argv[])
78 * {
79 * Hwi_Params hwiParams;
80 * Error_Block eb;
81 *
82 * Hwi_Params_init(&hwiParams);
83 * Error_init(&eb);
84 *
85 * // set the argument you want passed to your ISR function
86 * hwiParams.arg = 1;
87 *
88 * // set the event id of the peripheral assigned to this interrupt
89 * hwiParams.eventId = 10;
90 *
91 * // don't allow this interrupt to nest itself
92 * hwiParams.maskSetting = Hwi_MaskingOption_SELF;
93 *
94 * //
95 * // Configure interrupt 5 to invoke "myIsr".
96 * // Automatically enables interrupt 5 by default
97 * // set params.enableInt = FALSE if you want to control
98 * // when the interrupt is enabled using Hwi_enableInterrupt()
99 * //
100 *
101 * myHwi = Hwi_create(5, myIsr, &hwiParams, &eb);
102 *
103 * if (Error_check(&eb)) {
104 * // handle the error
105 * }
106 * }
107 *
108 * Void myIsr(UArg arg)
109 * {
110 * // here when interrupt #5 goes off
111 * }
112 * @p
113 *
114 * @a(Hook Functions)
115 *
116 * Sets of hook functions can be specified for the Hwi module
117 * using the configuration tool. Each set contains these hook
118 * functions:
119 * @p(blist)
120 * -Register: A function called before any statically-created Hwis
121 * are initialized at runtime. The register hook is called at boot time
122 * before main() and before interrupts are enabled.
123 * -Create: A function that is called when a Hwi is created.
124 * This includes hwis that are created statically and those
125 * created dynamically using {@link #create Hwi_create}.
126 * -Begin: A function that is called just prior to running a Hwi.
127 * -End: A function that is called just after a Hwi finishes.
128 * -Delete: A function that is called when a Hwi is deleted at
129 * run-time with {@link #delete Hwi_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
136 * {@link #setHookContext Hwi_setHookContext} and
137 * {@link #getHookContext Hwi_getHookContext} to set or get
138 * hookset-specific context. The
139 * Register function must be specified if the hook implementation
140 * needs to use {@link #setHookContext Hwi_setHookContext} or
141 * {@link #getHookContext Hwi_getHookContext}.
142 * The registerFxn hook function is called during system initialization
143 * before interrupts have been enabled.
144 *
145 * @p(code)
146 * Void myRegisterFxn(Int id);
147 * @p
148 *
149 * Create and Delete Functions
150 *
151 * The create and delete functions are called whenever a Hwi is created
152 * or deleted. They are called with interrupts enabled (unless called
153 * at boot time or from main()).
154 *
155 * @p(code)
156 * Void myCreateFxn(Hwi_Handle hwi, Error_Block *eb);
157 * @p
158 *
159 * @p(code)
160 * Void myDeleteFxn(Hwi_Handle hwi);
161 * @p
162 *
163 * Begin and End Functions
164 *
165 * The beginFxn and endFxn function hooks are called with interrupts
166 * globally disabled, therefore any hook processing function will contribute
167 * to the overall system interrupt response latency. In order to minimize
168 * this impact, carefully consider the processing time spent in an Hwi
169 * beginFxn or endFxn function hook.
170 *
171 * @p(code)
172 * Void myBeginFxn(Hwi_Handle hwi);
173 * @p
174 *
175 * @p(code)
176 * Void myEndFxn(Hwi_Handle hwi);
177 * @p
178 *
179 * Hook functions can only be configured statically.
180 */
181
182 @DirectCall
183
184 @InstanceFinalize
185 @InstanceInitError
186
187 interface IHwi {
188
189
190
191 /*! Hwi create function type definition. */
192 typedef Void (*FuncPtr)(UArg);
193
194 /*!
195 * Interrupt Return Pointer.
196 *
197 * This is the address of the interrupted instruction.
198 */
199 typedef UArg Irp;
200
201 /*!
202 * Hwi hook set type definition.
203 *
204 * The functions that make up a hookSet have certain restrictions. They
205 * cannot call any Hwi instance functions other than Hwi_getHookContext()
206 * and Hwi_setHookContext(). For all practical purposes, they should treat
207 * the Hwi_Handle passed to these functions as an opaque handle.
208 */
209 struct HookSet {
210 Void (*registerFxn)(Int);
211 Void (*createFxn)(Handle, Error.Block *);
212 Void (*beginFxn)(Handle);
213 Void (*endFxn)(Handle);
214 Void (*deleteFxn)(Handle);
215 };
216
217 /*!
218 * ======== MaskingOption ========
219 * Shorthand interrupt masking options
220 *
221 * @value(MaskingOption_NONE) No interrupts are disabled
222 *
223 * @value(MaskingOption_ALL) All interrupts are disabled
224 *
225 * @value(MaskingOption_SELF) Only this interrupt is disabled
226 *
227 * @value(MaskingOption_BITMASK) User supplies interrupt enable masks
228 *
229 * @value(MaskingOption_LOWER) All current and lower priority
230 * interrupts are disabled.
231 *
232 * Only a few targets/devices truly
233 * support this masking option. For those
234 * that don't, this setting is treated
235 * the same as MaskingOption_SELF.
236 */
237 enum MaskingOption {
238 MaskingOption_NONE,
239 MaskingOption_ALL,
240 MaskingOption_SELF,
241 MaskingOption_BITMASK,
242 MaskingOption_LOWER
243 };
244
245 /*!
246 * ======== StackInfo ========
247 * Structure contains Hwi stack usage info
248 *
249 * Used by getStackInfo() and viewGetStackInfo() functions
250 */
251 struct StackInfo {
252 SizeT hwiStackPeak;
253 SizeT hwiStackSize;
254 Ptr hwiStackBase;
255 };
256
257
258
259 /*!
260 * Include interrupt nesting logic in interrupt dispatcher?
261 *
262 * Default is true.
263 *
264 * This option provides the user with the ability to optimize
265 * interrupt dispatcher performance when support for interrupt
266 * nesting is not required.
267 *
268 * Setting this parameter to false will disable the logic in
269 * the interrupt dispatcher that manipulates interrupt mask
270 * registers and enables and disables interrupts before and
271 * after invoking the user's Hwi function.
272 *
273 * Set this parameter to false if you don't need interrupts
274 * enabled during the execution of your Hwi functions.
275 */
276 config Bool dispatcherAutoNestingSupport = true;
277
278 /*!
279 * Include Swi scheduling logic in interrupt dispatcher?
280 *
281 * Default is inherited from {@link ti.sysbios.BIOS#swiEnabled
282 * BIOS.swiEnabled}, which is true by default.
283 *
284 * This option provides the user with the ability to optimize
285 * interrupt dispatcher performance when it is known that Swis
286 * will not be posted from any of their Hwi threads.
287 *
288 * @a(Warning)
289 * Setting this parameter to false will disable the logic in
290 * the interrupt dispatcher that invokes the Swi scheduler
291 * prior to returning from an interrupt.
292 * With this setting, Swis MUST NOT be posted from Hwi functions!
293 */
294 config Bool dispatcherSwiSupport;
295
296 /*!
297 * Include Task scheduling logic in interrupt dispatcher?
298 *
299 * Default is inherited from {@link ti.sysbios.BIOS#taskEnabled
300 * BIOS.taskEnabled}, which is true by default.
301 *
302 * This option provides the user with the ability to optimize
303 * interrupt dispatcher performance when it is known that no
304 * Task scheduling APIs (ie {@link ti.sysbios.knl.Semaphore#post
305 * Semaphore_post()}) will be executed from any of their Hwi threads.
306 *
307 * Setting this parameter to false will disable the logic in
308 * the interrupt dispatcher that invokes the Task scheduler
309 * prior to returning from an interrupt.
310 */
311 config Bool dispatcherTaskSupport;
312
313 /*!
314 * Controls whether the
315 * dispatcher retains the interrupted thread's return address.
316 *
317 * This option is enabled by default.
318 *
319 * Setting this parameter to false will disable the logic in
320 * the interrupt dispatcher that keeps track of the interrupt's
321 * return address and provide a small savings in interrupt latency.
322 *
323 * The application can get an interrupt's most recent return
324 * address using the {@link #getIrp} API.
325 */
326 config Bool dispatcherIrpTrackingSupport = true;
327
328
329
330 /*!
331 * ======== addHookSet ========
332 * addHookSet is used in a config file to add a hook set (defined
333 * by struct HookSet).
334 *
335 * HookSet structure elements may be omitted, in which case those
336 * elements will not exist.
337 *
338 * @param(hook) structure of type HookSet
339 */
340 metaonly Void addHookSet(HookSet hook);
341
342 /*!
343 * ======== viewGetStackInfo ========
344 * @_nodoc
345 * Returns the Hwi stack usage info. Used at ROV time.
346 *
347 * @b(returns) Hwi stack base, size, peak
348 */
349 metaonly StackInfo viewGetStackInfo();
350
351 /*!
352 * ======== getStackInfo ========
353 * Get Hwi stack usage Info.
354 *
355 * getStackInfo returns the Hwi stack usage info to its calling
356 * function by filling stack base address, stack size and stack
357 * peak fields in the {@link #StackInfo} structure.
358 *
359 * getStackInfo accepts two arguments, a pointer to a structure
360 * of type {@link #StackInfo} and a boolean. If the boolean is set
361 * to true, the function computes the stack depth and fills the
362 * stack peak field in the StackInfo structure. If a stack overflow
363 * is detected, the stack depth is not computed. If the boolean is
364 * set to false, the function only checks for a stack overflow.
365 *
366 * The isr stack is always checked for an overflow and a boolean
367 * is returned to indicate whether an overflow occured.
368 *
369 * Below is an example of calling getStackInfo() API:
370 *
371 * @p(code)
372 * #include <ti/sysbios/BIOS.h>
373 * #include <ti/sysbios/hal/Hwi.h>
374 * #include <ti/sysbios/knl/Swi.h>
375 * #include <ti/sysbios/knl/Task.h>
376 *
377 * Swi_Handle swi0;
378 * volatile Bool swiStackOverflow = FALSE;
379 *
380 * Void swi0Fxn(UArg arg1, UArg arg2)
381 * {
382 * Hwi_StackInfo stkInfo;
383 *
384 * // Request stack depth
385 * swiStackOverflow = Hwi_getStackInfo(&stkInfo, TRUE);
386 *
387 * // Alternately, we can omit the request for stack depth and
388 * // request only the stack base and stack size (the check for
389 * // stack overflow is always performed):
390 * //
391 * // swiStackOverflow = Hwi_getStackInfo(&stkInfo, FALSE);
392 *
393 * if (swiStackOverflow) {
394 * // isr Stack Overflow detected
395 * }
396 * }
397 *
398 * Void idleTask()
399 * {
400 * Swi_post(swi0);
401 * }
402 *
403 * Int main(Int argc, char* argv[])
404 * {
405 * swi0 = Swi_create(swi0Fxn, NULL, NULL);
406 *
407 * BIOS_start();
408 * return (0);
409 * }
410 * @p
411 *
412 * @param(stkInfo) pointer to structure of type {@link #StackInfo}
413 * @param(computeStackDepth) decides whether to compute stack depth
414 *
415 * @b(returns) boolean to indicate a stack overflow
416 */
417 Bool getStackInfo(StackInfo *stkInfo, Bool computeStackDepth);
418
419 /*!
420 * ======== getCoreStackInfo ========
421 * Get Hwi stack usage Info for the specified coreId.
422 *
423 * getCoreStackInfo returns the Hwi stack usage info for the specified
424 * coreId to its calling function by filling stack base address,
425 * stack size and stack peak fields in the {@link #StackInfo} structure.
426 *
427 * This function should be used only in applications built with
428 * {@link ti.sysbios.BIOS#smpEnabled} set to true.
429 *
430 * getCoreStackInfo accepts three arguments, a pointer to a structure
431 * of type {@link #StackInfo}, a boolean and a coreId. If the boolean
432 * is set to true, the function computes the stack depth and fills the
433 * stack peak field in the StackInfo structure. If a stack overflow
434 * is detected, the stack depth is not computed. If the boolean is
435 * set to false, the function only checks for a stack overflow.
436 *
437 * The isr stack is always checked for an overflow and a boolean
438 * is returned to indicate whether an overflow occured.
439 *
440 * Below is an example of calling getCoreStackInfo() API:
441 *
442 * @p(code)
443 * #include <ti/sysbios/BIOS.h>
444 * #include <ti/sysbios/hal/Hwi.h>
445 * #include <ti/sysbios/hal/Core.h>
446 * #include <ti/sysbios/knl/Task.h>
447 *
448 * ...
449 *
450 * Void idleTask()
451 * {
452 * UInt idx;
453 * Hwi_StackInfo stkInfo;
454 * Bool stackOverflow = FALSE;
455 *
456 * // Request stack depth for each core's Hwi stack and check for
457 * // overflow
458 * for (idx = 0; idx < Core_numCores; idx++) {
459 * stackOverflow = Hwi_getCoreStackInfo(&stkInfo, TRUE, idx);
460 *
461 * // Alternately, we can omit the request for stack depth and
462 * // request only the stack base and stack size (the check for
463 * // stack overflow is always performed):
464 * //
465 * // stackOverflow = Hwi_getCoreStackInfo(&stkInfo, FALSE, idx);
466 *
467 * if (stackOverflow) {
468 * // isr Stack Overflow detected
469 * }
470 * }
471 * }
472 *
473 * Int main(Int argc, char* argv[])
474 * {
475 * ...
476 * BIOS_start();
477 * return (0);
478 * }
479 * @p
480 *
481 * @param(stkInfo) pointer to structure of type {@link #StackInfo}
482 * @param(computeStackDepth) decides whether to compute stack depth
483 * @param(coreId) core whose stack info needs to be retrieved
484 *
485 * @b(returns) boolean to indicate a stack overflow
486 */
487 Bool getCoreStackInfo(StackInfo *stkInfo, Bool computeStackDepth,
488 UInt coreId);
489
490 /*!
491 * ======== startup ========
492 * Initially enable interrupts
493 *
494 * Called within BIOS_start
495 */
496 Void startup();
497
498 /*!
499 * ======== disable ========
500 */
501
502 UInt disable();
503
504 /*!
505 * ======== enable ========
506 * Globally enable interrupts.
507 *
508 * Hwi_enable globally enables hardware interrupts and returns an
509 * opaque key indicating whether interrupts were globally enabled or
510 * disabled on entry to Hwi_enable().
511 * The actual value of the key is target/device specific and is meant
512 * to be passed to Hwi_restore().
513 *
514 *
515 * This function is
516 * called as part of SYS/BIOS Startup_POST_APP_MAIN phase.
517 *
518 * Hardware interrupts are enabled unless a call to Hwi_disable disables
519 * them.
520 *
521 * Servicing of interrupts that occur while interrupts are disabled is
522 * postponed until interrupts are reenabled. However, if the same type
523 * of interrupt occurs several times while interrupts are disabled,
524 * the interrupt's function is executed only once when interrupts are
525 * reenabled.
526 *
527 * A context switch can occur when calling Hwi_enable or Hwi_restore if
528 * an enabled interrupt occurred while interrupts are disabled.
529 *
530 * Any call to Hwi_enable enables interrupts, even if Hwi_disable has
531 * been called several times.
532 *
533 * Hwi_enable must not be called from main().
534 *
535 * @b(returns) opaque key for use by Hwi_restore()
536 */
537
538 UInt enable();
539
540 /*!
541 * ======== restore ========
542 * Globally restore interrupts.
543 *
544 * Hwi_restore globally restores interrupts to the state determined
545 * by the key argument provided by a previous invocation of Hwi_disable.
546 *
547 * A context switch may occur when calling Hwi_restore if Hwi_restore
548 * reenables interrupts and another Hwi occurred while interrupts were
549 * disabled.
550 *
551 * Hwi_restore may be called from main(). However, since Hwi_enable
552 * cannot be called from main(), interrupts are always disabled in
553 * main(), and a call to Hwi_restore has no effect.
554 *
555 * @param(key) enable/disable state to restore
556 */
557
558 Void restore(UInt key);
559
560 /*!
561 * @_nodoc
562 * ======== switchFromBootStack ========
563 * Indicate that we are leaving the boot stack and
564 * are about to switch to a task stack.
565 * Used by Task_startup()
566 */
567 Void switchFromBootStack();
568
569 /*!
570 * ======== post ========
571 * Generate an interrupt for test purposes.
572 *
573 * @param(intNum) ID of interrupt to generate
574 */
575 Void post(UInt intNum);
576
577 /*!
578 * @_nodoc
579 * ======== getTaskSP ========
580 * retrieve interrupted task's SP
581 *
582 * Used for benchmarking the SYS/BIOS Hwi dispatcher's task
583 * stack utilization.
584 *
585 * @b(returns) interrupted task's SP
586 */
587 Char *getTaskSP();
588
589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606
607
608 609 610 611 612 613 614 615 616 617 618 619 620 621 622
623
624
625 626 627 628 629 630 631 632 633 634 635 636 637
638
639
640 641 642 643 644 645 646 647 648 649 650 651 652 653
654
655
656 /*!
657 * ======== disableInterrupt ========
658 * Disable a specific interrupt.
659 *
660 * Disable a specific interrupt identified by an interrupt number.
661 *
662 * @param(intNum) interrupt number to disable
663 * @b(returns) key to restore previous enable/disable state
664 */
665
666 UInt disableInterrupt(UInt intNum);
667
668 /*!
669 * ======== enableInterrupt ========
670 * Enable a specific interrupt.
671 *
672 * Enables a specific interrupt identified by an interrupt number.
673 *
674 * @param(intNum) interrupt number to enable
675 * @b(returns) key to restore previous enable/disable state
676 */
677
678 UInt enableInterrupt(UInt intNum);
679
680 /*!
681 * ======== restoreInterrupt ========
682 * Restore a specific interrupt's enabled/disabled state.
683 *
684 * Restores a specific interrupt identified by an interrupt number.
685 * restoreInterrupt is generally used to restore an interrupt to its state
686 * before {@link #disableInterrupt} or {@link #enableInterrupt} was
687 * invoked
688 *
689 * @param(intNum) interrupt number to restore
690 * @param(key) key returned from enableInt or disableInt
691 */
692
693 Void restoreInterrupt(UInt intNum, UInt key);
694
695 /*!
696 * ======== clearInterrupt ========
697 * Clear a specific interrupt.
698 *
699 * Clears a specific interrupt's pending status.
700 * The implementation is family-specific.
701 *
702 * @param(intNum) interrupt number to clear
703 */
704
705 Void clearInterrupt(UInt intNum);
706
707 instance:
708
709 /*!
710 * Create a dispatched interrupt.
711 *
712 * A Hwi dispatcher table entry is created and filled with the
713 * function specified by the fxn parameter and the attributes
714 * specified by the params parameter.
715 *
716 * If params is NULL, the Hwi's dispatcher properties are assigned a
717 * default set of values. Otherwise, the following properties
718 * are specified by a structure of type Hwi_Params.
719 *
720 * @p(blist)
721 * - The arg element is a generic argument that is passed to the plugged
722 * function as its only parameter. The default value is 0.
723 * - The enableInt element determines whether the interrupt should be
724 * enabled in the IER by create.
725 * - The maskSetting element defines the dispatcherAutoNestingSupport
726 * behavior of the interrupt.
727 * @p
728 *
729 * Hwi_create returns a pointer to the created Hwi object.
730 *
731 * @param(intNum) interrupt number
732 * @param(hwiFxn) pointer to ISR function
733 *
734 */
735 create(Int intNum, FuncPtr hwiFxn);
736
737
738
739 /*! maskSetting. Default is {@link #MaskingOption Hwi_MaskingOption_SELF} */
740 config MaskingOption maskSetting = MaskingOption_SELF;
741
742 /*! ISR function argument. Default is 0. */
743 config UArg arg = 0;
744
745 /*! Enable this interrupt when object is created? Default is true. */
746 config Bool enableInt = true;
747
748 /*!
749 * Interrupt event ID (Interrupt Selection Number)
750 *
751 * Default is -1.
752 * Not all targets/devices support this instance parameter.
753 * On those that don't, this parameter is ignored.
754 */
755 config Int eventId = -1;
756
757 /*!
758 * Interrupt priority.
759 *
760 * The default value of -1 is used as a flag to indicate
761 * the lowest (logical) device-specific priority value.
762 *
763 * Not all targets/devices support this instance parameter.
764 * On those that don't, this parameter is ignored.
765 */
766 config Int priority = -1;
767
768 /*!
769 * ======== getFunc ========
770 * Get Hwi function and arg
771 *
772 * @param(arg) pointer for returning hwi's ISR function argument
773 * @b(returns) hwi's ISR function
774 */
775 FuncPtr getFunc(UArg *arg);
776
777 /*!
778 * ======== setFunc ========
779 * Overwrite Hwi function and arg
780 *
781 * Replaces a Hwi object's hwiFxn function originally
782 * provided in {@link #create}.
783 *
784 * @a(constraints)
785 * Hwi_setFunc() is not thread safe. This means that the new value for
786 * for 'fxn' may be temporarily paired with the previous value for 'arg'
787 * if pre-emption occurs within the execution of Hwi_setFunc().
788 *
789 * To guard against this condition, surround the Hwi_setFunc() call with
790 * calls to Hwi_disable() and Hwi_restore():
791 *
792 * @p(code)
793 * key = Hwi_disable();
794 *
795 * Hwi_setFunc(newFunc, newArg);
796 *
797 * Hwi_restore(key);
798 * @p
799 *
800 * @param(fxn) pointer to ISR function
801 * @param(arg) argument to ISR function
802 */
803 Void setFunc(FuncPtr fxn, UArg arg);
804
805 /*!
806 * ======== getHookContext ========
807 * Get hook instance's context for a Hwi.
808 *
809 * @b(returns) hook instance's context for hwi
810 */
811 Ptr getHookContext(Int id);
812
813 /*!
814 * ======== setHookContext ========
815 * Set hook instance's context for a Hwi.
816 *
817 * @param(id) hook instance's ID
818 * @param(hookContext) value to write to context
819 */
820 Void setHookContext(Int id, Ptr hookContext);
821
822 /*!
823 * ======== getIrp ========
824 * Get address of interrupted instruction.
825 *
826 * @b(returns) most current IRP of a Hwi
827 */
828 Irp getIrp();
829 }