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 @InstanceFinalize
183 @InstanceInitError
184
185 interface IHwi {
186
187
188
189 /*! Hwi create function type definition. */
190 typedef Void (*FuncPtr)(UArg);
191
192 /*!
193 * Interrupt Return Pointer.
194 *
195 * This is the address of the interrupted instruction.
196 */
197 typedef UArg Irp;
198
199 /*!
200 * Hwi hook set type definition.
201 *
202 * The functions that make up a hookSet have certain restrictions. They
203 * cannot call any Hwi instance functions other than Hwi_getHookContext()
204 * and Hwi_setHookContext(). For all practical purposes, they should treat
205 * the Hwi_Handle passed to these functions as an opaque handle.
206 */
207 struct HookSet {
208 Void (*registerFxn)(Int);
209 Void (*createFxn)(Handle, Error.Block *);
210 Void (*beginFxn)(Handle);
211 Void (*endFxn)(Handle);
212 Void (*deleteFxn)(Handle);
213 };
214
215 /*!
216 * ======== MaskingOption ========
217 * Shorthand interrupt masking options
218 *
219 * @value(MaskingOption_NONE) No interrupts are disabled
220 *
221 * @value(MaskingOption_ALL) All interrupts are disabled
222 *
223 * @value(MaskingOption_SELF) Only this interrupt is disabled
224 *
225 * @value(MaskingOption_BITMASK) User supplies interrupt enable masks
226 *
227 * @value(MaskingOption_LOWER) All current and lower priority
228 * interrupts are disabled.
229 *
230 * Only a few targets/devices truly
231 * support this masking option. For those
232 * that don't, this setting is treated
233 * the same as MaskingOption_SELF.
234 */
235 enum MaskingOption {
236 MaskingOption_NONE,
237 MaskingOption_ALL,
238 MaskingOption_SELF,
239 MaskingOption_BITMASK,
240 MaskingOption_LOWER
241 };
242
243 /*!
244 * @_nodoc
245 * returned by viewGetStackInfo()
246 */
247 metaonly struct StackInfo {
248 SizeT hwiStackPeak;
249 SizeT hwiStackSize;
250 Ptr hwiStackBase;
251 };
252
253
254
255 /*!
256 * Include interrupt nesting logic in interrupt dispatcher?
257 *
258 * Default is true.
259 *
260 * This option provides the user with the ability to optimize
261 * interrupt dispatcher performance when support for interrupt
262 * nesting is not required.
263 *
264 * Setting this parameter to false will disable the logic in
265 * the interrupt dispatcher that manipulates interrupt mask
266 * registers and enables and disables interrupts before and
267 * after invoking the user's Hwi function.
268 *
269 * Set this parameter to false if you don't need interrupts
270 * enabled during the execution of your Hwi functions.
271 */
272 config Bool dispatcherAutoNestingSupport = true;
273
274 /*!
275 * Include Swi scheduling logic in interrupt dispatcher?
276 *
277 * Default is inherited from {@link ti.sysbios.BIOS#swiEnabled
278 * BIOS.swiEnabled}, which is true by default.
279 *
280 * This option provides the user with the ability to optimize
281 * interrupt dispatcher performance when it is known that Swis
282 * will not be posted from any of their Hwi threads.
283 *
284 * Setting this parameter to false will disable the logic in
285 * the interrupt dispatcher that invokes the Swi scheduler
286 * prior to returning from an interrupt.
287 */
288 config Bool dispatcherSwiSupport;
289
290 /*!
291 * Include Task scheduling logic in interrupt dispatcher?
292 *
293 * Default is inherited from {@link ti.sysbios.BIOS#taskEnabled
294 * BIOS.taskEnabled}, which is true by default.
295 *
296 * This option provides the user with the ability to optimize
297 * interrupt dispatcher performance when it is known that no
298 * Task scheduling APIs (ie {@link ti.sysbios.knl.Semaphore#post
299 * Semaphore_post()}) will be executed from any of their Hwi threads.
300 *
301 * Setting this parameter to false will disable the logic in
302 * the interrupt dispatcher that invokes the Task scheduler
303 * prior to returning from an interrupt.
304 */
305 config Bool dispatcherTaskSupport;
306
307 /*!
308 * Controls whether the
309 * dispatcher retains the interrupted thread's return address.
310 *
311 * This option is enabled by default.
312 *
313 * Setting this parameter to false will disable the logic in
314 * the interrupt dispatcher that keeps track of the interrupt's
315 * return address and provide a small savings in interrupt latency.
316 *
317 * The application can get an interrupt's most recent return
318 * address using the {@link #getIrp} API.
319 */
320 config Bool dispatcherIrpTrackingSupport = true;
321
322
323
324 /*!
325 * ======== addHookSet ========
326 * addHookSet is used in a config file to add a hook set (defined
327 * by struct HookSet).
328 *
329 * HookSet structure elements may be omitted, in which case those
330 * elements will not exist.
331 *
332 * @param(hook) structure of type HookSet
333 */
334 metaonly Void addHookSet(HookSet hook);
335
336 /*!
337 * ======== viewGetStackInfo ========
338 * @_nodoc
339 * Returns the Hwi stack usage info. Used at ROV time.
340 *
341 * @b(returns) Hwi stack base, size, peak
342 */
343 metaonly StackInfo viewGetStackInfo();
344
345 /*!
346 * ======== startup ========
347 * Initially enable interrupts
348 *
349 * Called within BIOS_start
350 */
351 @DirectCall
352 Void startup();
353
354 /*!
355 * ======== disable ========
356 * Globally disable interrupts.
357 *
358 * Hwi_disable globally disables hardware interrupts and returns an
359 * opaque key indicating whether interrupts were globally enabled or
360 * disabled on entry to Hwi_disable().
361 * The actual value of the key is target/device specific and is meant
362 * to be passed to Hwi_restore().
363 *
364 * Call Hwi_disable before a portion of a function that needs
365 * to run without interruption. When critical processing is complete, call
366 * Hwi_restore or Hwi_enable to reenable hardware interrupts.
367 *
368 * Servicing of interrupts that occur while interrupts are disabled is
369 * postponed until interrupts are reenabled. However, if the same type
370 * of interrupt occurs several times while interrupts are disabled,
371 * the interrupt's function is executed only once when interrupts are
372 * reenabled.
373 *
374 * A context switch can occur when calling Hwi_enable or Hwi_restore if
375 * an enabled interrupt occurred while interrupts are disabled.
376 *
377 * Hwi_disable may be called from main(). However, since Hwi interrupts
378 * are already disabled in main(), such a call has no effect.
379 *
380 * @a(constraints)
381 * If a Task switching API such as
382 * {@link ti.sysbios.knl.Semaphore#pend Semaphore_pend()},
383 * {@link ti.sysbios.knl.Semaphore#post Semaphore_post()},
384 * {@link ti.sysbios.knl.Task#sleep Task_sleep()}, or
385 * {@link ti.sysbios.knl.Task#yield Task_yield()}
386 * is invoked which results in a context switch while
387 * interrupts are disabled, an embedded call to
388 * {@link #enable Hwi_enable} occurs
389 * on the way to the new thread context which unconditionally re-enables
390 * interrupts. Interrupts will remain enabled until a subsequent
391 * {@link #disable Hwi_disable}
392 * invocation.
393 *
394 * Swis always run with interrupts enabled.
395 * See {@link ti.sysbios.knl.Swi#post Swi_post()} for a discussion Swis and
396 * interrupts.
397 *
398 * @b(returns) opaque key for use by Hwi_restore()
399 */
400 UInt disable();
401
402 /*!
403 * ======== enable ========
404 * Globally enable interrupts.
405 *
406 * Hwi_enable globally enables hardware interrupts and returns an
407 * opaque key indicating whether interrupts were globally enabled or
408 * disabled on entry to Hwi_enable().
409 * The actual value of the key is target/device specific and is meant
410 * to be passed to Hwi_restore().
411 *
412 *
413 * This function is
414 * called as part of SYS/BIOS Startup_POST_APP_MAIN phase.
415 *
416 * Hardware interrupts are enabled unless a call to Hwi_disable disables
417 * them.
418 *
419 * Servicing of interrupts that occur while interrupts are disabled is
420 * postponed until interrupts are reenabled. However, if the same type
421 * of interrupt occurs several times while interrupts are disabled,
422 * the interrupt's function is executed only once when interrupts are
423 * reenabled.
424 *
425 * A context switch can occur when calling Hwi_enable or Hwi_restore if
426 * an enabled interrupt occurred while interrupts are disabled.
427 *
428 * Any call to Hwi_enable enables interrupts, even if Hwi_disable has
429 * been called several times.
430 *
431 * Hwi_enable must not be called from main().
432 *
433 * @b(returns) opaque key for use by Hwi_restore()
434 */
435 UInt enable();
436
437 /*!
438 * ======== restore ========
439 * Globally restore interrupts.
440 *
441 * Hwi_restore globally restores interrupts to the state determined
442 * by the key argument provided by a previous invocation of Hwi_disable.
443 *
444 * A context switch may occur when calling Hwi_restore if Hwi_restore
445 * reenables interrupts and another Hwi occurred while interrupts were
446 * disabled.
447 *
448 * Hwi_restore may be called from main(). However, since Hwi_enable
449 * cannot be called from main(), interrupts are always disabled in
450 * main(), and a call to Hwi_restore has no effect.
451 *
452 * @param(key) enable/disable state to restore
453 */
454 Void restore(UInt key);
455
456 /*!
457 * @_nodoc
458 * ======== switchFromBootStack ========
459 * Indicate that we are leaving the boot stack and
460 * are about to switch to a task stack.
461 * Used by Task_startup()
462 */
463 @DirectCall
464 Void switchFromBootStack();
465
466 /*!
467 * @_nodoc
468 * ======== post ========
469 * Generate an interrupt for test purposes.
470 *
471 * @param(intNum) ID of interrupt to generate
472 */
473 @DirectCall
474 Void post(UInt intNum);
475
476 /*!
477 * @_nodoc
478 * ======== getTaskSP ========
479 * retrieve interrupted task's SP
480 *
481 * Used for benchmarking the SYS/BIOS Hwi dispatcher's task
482 * stack utilization.
483 *
484 * @b(returns) interrupted task's SP
485 */
486 @DirectCall
487 Char *getTaskSP();
488
489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506
507
508 509 510 511 512 513 514 515 516 517 518 519 520
521
522
523 524 525 526 527 528 529 530 531 532 533 534 535 536
537
538
539 /*!
540 * ======== disableInterrupt ========
541 * Disable a specific interrupt.
542 *
543 * Disable a specific interrupt identified by an interrupt number.
544 *
545 * @param(intNum) interrupt number to disable
546 * @b(returns) key to restore previous enable/disable state
547 */
548 @DirectCall
549 UInt disableInterrupt(UInt intNum);
550
551 /*!
552 * ======== enableInterrupt ========
553 * Enable a specific interrupt.
554 *
555 * Enables a specific interrupt identified by an interrupt number.
556 *
557 * @param(intNum) interrupt number to enable
558 * @b(returns) key to restore previous enable/disable state
559 */
560 @DirectCall
561 UInt enableInterrupt(UInt intNum);
562
563 /*!
564 * ======== restoreInterrupt ========
565 * Restore a specific interrupt's enabled/disabled state.
566 *
567 * Restores a specific interrupt identified by an interrupt number.
568 * restoreInterrupt is generally used to restore an interrupt to its state
569 * before {@link #disableInterrupt} or {@link #enableInterrupt} was
570 * invoked
571 *
572 * @param(intNum) interrupt number to restore
573 * @param(key) key returned from enableInt or disableInt
574 */
575 @DirectCall
576 Void restoreInterrupt(UInt intNum, UInt key);
577
578 /*!
579 * ======== clearInterrupt ========
580 * Clear a specific interrupt.
581 *
582 * Clears a specific interrupt's pending status.
583 * The implementation is family-specific.
584 *
585 * @param(intNum) interrupt number to clear
586 */
587 @DirectCall
588 Void clearInterrupt(UInt intNum);
589
590 instance:
591
592 /*!
593 * Create a dispatched interrupt.
594 *
595 * A Hwi dispatcher table entry is created and filled with the
596 * function specified by the fxn parameter and the attributes
597 * specified by the params parameter.
598 *
599 * If params is NULL, the Hwi's dispatcher properties are assigned a
600 * default set of values. Otherwise, the following properties
601 * are specified by a structure of type Hwi_Params.
602 *
603 * @p(blist)
604 * - The arg element is a generic argument that is passed to the plugged
605 * function as its only parameter. The default value is 0.
606 * - The enableInt element determines whether the interrupt should be
607 * enabled in the IER by create.
608 * - The maskSetting element defines the dispatcherAutoNestingSupport
609 * behavior of the interrupt.
610 * @p
611 *
612 * Hwi_create returns a pointer to the created Hwi object.
613 *
614 * @param(intNum) interrupt number
615 * @param(hwiFxn) pointer to ISR function
616 *
617 */
618 @DirectCall
619 create(Int intNum, FuncPtr hwiFxn);
620
621 /*! maskSetting. Default is {@link #MaskingOption Hwi_MaskingOption_SELF} */
622 config MaskingOption maskSetting = MaskingOption_SELF;
623
624 /*! ISR function argument. Default is 0. */
625 config UArg arg = 0;
626
627 /*! Enable this interrupt now? Default is true. */
628 config Bool enableInt = true;
629
630 /*!
631 * Interrupt event ID (Interrupt Selection Number)
632 *
633 * Default is -1.
634 * Not all targets/devices support this instance parameter.
635 * On those that don't, this parameter is ignored.
636 */
637 config Int eventId = -1;
638
639 /*!
640 * Interrupt priority.
641 *
642 * Default is -1.
643 * Not all targets/devices support this instance parameter.
644 * On those that don't, this parameter is ignored.
645 */
646 config Int priority = -1;
647
648 /*!
649 * ======== getFunc ========
650 * Get Hwi function and arg
651 *
652 * @param(arg) pointer for returning hwi's ISR function argument
653 * @b(returns) hwi's ISR function
654 */
655 @DirectCall
656 FuncPtr getFunc(UArg *arg);
657
658 /*!
659 * ======== setFunc ========
660 * Overwrite Hwi function and arg
661 *
662 * Replaces a Hwi object's hwiFxn function originally
663 * provided in {@link #create}.
664 *
665 * @param(fxn) pointer to ISR function
666 * @param(arg) argument to ISR function
667 */
668 @DirectCall
669 Void setFunc(FuncPtr fxn, UArg arg);
670
671 /*!
672 * ======== getHookContext ========
673 * Get hook instance's context for a Hwi.
674 *
675 * @b(returns) hook instance's context for hwi
676 */
677 @DirectCall
678 Ptr getHookContext(Int id);
679
680 /*!
681 * ======== setHookContext ========
682 * Set hook instance's context for a Hwi.
683 *
684 * @param(id) hook instance's ID
685 * @param(hookContext) value to write to context
686 */
687 @DirectCall
688 Void setHookContext(Int id, Ptr hookContext);
689
690 /*!
691 * ======== getIrp ========
692 * Get address of interrupted instruction.
693 *
694 * @b(returns) most current IRP of a Hwi
695 */
696 @DirectCall
697 Irp getIrp();
698 }
699 700 701 702
703