1 2 3 4 5 6 7 8 9
10 11 12 13
14
15 import xdc.runtime.Error;
16
17
18 /*!
19 * ======== Hwi ========
20 * Hardware Interrupt Support Module.
21 *
22 * The IHwi interface specifies APIs for globally enabling, disabling, and
23 * restoring interrupts.
24 *
25 * Additionally, management of individual, device specific hardware
26 * interrupts is provided.
27 *
28 * The user can statically or dynamically assign routines that run when
29 * specific hardware interrupts occur.
30 *
31 * Dynamic assignment of Hwi routines to interrupts at run-time is done
32 * using the Hwi_create function.
33 *
34 * Interrupt routines can be written completely in assembly, completely in
35 * C, or in a mix of assembly and C. In order to support interrupt routines
36 * written completely in C, an interrupt dispatcher is provided that performs
37 * the requisite prolog and epilog for an interrupt routine.
38 *
39 * Some routines are assigned to interrupts by the other BIOS
40 * modules. For example, the Clock module configures its own timer interrupt
41 * handler. See the Clock Module for more details.
42 *
43 * Hook Functions
44 *
45 * Sets of hook functions can be specified for the Hwi module
46 * using the configuration tool. Each set contains these hook
47 * functions:
48 * @p(blist)
49 * -Register: A function called before any statically created hwis
50 * are initialized at runtime. The register hook is called at boot time
51 * before main() and before interrupts are enabled.
52 * -Create: A function that is called when a hwi is created.
53 * This includes hwis that are created statically and those
54 * created dynamically using {@link #create Hwi_create}.
55 * -Begin: A function that is called just prior to running a hwi.
56 * -End: A function that is called just after a hwi finishes.
57 * -Delete: A function that is called when a hwi is deleted at
58 * run-time with {@link #delete Hwi_delete}.
59 * @p
60 *
61 * Register Function
62 *
63 * The Register function is provided to allow a hook set to store its
64 * hookset ID. This id can be passed to {@link #setHookContext Hwi_setHookContext} and
65 * {@link #getHookContext Hwi_getHookContext} to set or get hookset-specific context. The
66 * Register function must be specified if the hook implementation
67 * needs to use {@link #setHookContext Hwi_setHookContext} or {@link #getHookContext Hwi_getHookContext}.
68 * The registerFxn hook function is called during system initialization
69 * before interrupts have been enabled.
70 *
71 * @p(code)
72 * Void myRegisterFxn(Int id);
73 * @p
74 *
75 * Create and Delete Functions
76 *
77 * The create and delete functions are called whenever a Hwi is created
78 * or deleted. They are called with interrupts enabled (unless called
79 * at boot time or from main()).
80 *
81 * @p(code)
82 * Void myCreateFxn(Hwi_Handle hwi, Error_Block *eb);
83 * @p
84 *
85 * @p(code)
86 * Void myDeleteFxn(Hwi_Handle hwi);
87 * @p
88 *
89 * Begin and End Functions
90 *
91 * The beginFxn and endFxn function hooks are called with interrupts
92 * globally disabled, therefore any hook processing function will contribute
93 * to the overall system interrupt response latency. In order to minimize
94 * this impact, carefully consider the processing time spent in an Hwi
95 * beginFxn or endFxn function hook.
96 *
97 * @p(code)
98 * Void myBeginFxn(Hwi_Handle hwi);
99 * @p
100 *
101 * @p(code)
102 * Void myEndFxn(Hwi_Handle hwi);
103 * @p
104 *
105 * Hook functions can only be configured statically.
106 */
107
108 @InstanceFinalize
109 @InstanceInitError
110
111 interface IHwi {
112
113
114
115 /*! Hwi create function type definition. */
116 typedef Void (*FuncPtr)(UArg);
117
118 /*!
119 * Interrupt Return Pointer.
120 * This is the address of the interrupted instruction.
121 */
122 typedef UArg Irp;
123
124 /*! Hwi hook set type definition. */
125 struct HookSet {
126 Void (*registerFxn)(Int);
127 Void (*createFxn)(Handle, Error.Block *);
128 Void (*beginFxn)(Handle);
129 Void (*endFxn)(Handle);
130 Void (*deleteFxn)(Handle);
131 };
132
133 /*! Shorthand interrupt masking options. */
134 enum MaskingOption {
135 MaskingOption_NONE, /*! No interrupts are disabled. */
136 MaskingOption_ALL, /*! All interrupts are disabled. */
137 MaskingOption_SELF, /*! Only this interrupt is disabled. */
138 MaskingOption_BITMASK, /*! User supplies IER masks. */
139 MaskingOption_LOWER /*! All current and lower priority
140 interrupts are disabled. Only a few
141 targets/devices truly support this
142 masking option. For those that don't,
143 this setting is treated the same as
144 MaskingOption_SELF */
145 };
146
147 /*!
148 * @_nodoc
149 * returned by getStackInfo()
150 */
151 metaonly struct StackInfo {
152 SizeT hwiStackPeak;
153 SizeT hwiStackSize;
154 Ptr hwiStackBase;
155 };
156
157
158
159 /*!
160 * Include interrupt nesting logic in interrupt dispatcher?
161 * Default is true.
162 *
163 * This option provides the user with the ability to optimize
164 * interrupt dispatcher performance when support for interrupt
165 * nesting is not required.
166 *
167 * Setting this parameter to false will disable the logic in
168 * the interrupt dispatcher that manipulates interrupt mask
169 * registers and enables and disables interrupts before and
170 * after invoking the user's Hwi function.
171 *
172 * Set this parameter to false if you don't need interrupts
173 * enabled during the execution of your Hwi functions.
174 */
175 config Bool dispatcherAutoNestingSupport = true;
176
177 /*!
178 * Include Swi scheduling logic in interrupt dispatcher?
179 * Default is inherited from {@link ti.sysbios.BIOS#swiEnabled
180 * BIOS.swiEnabled}, which is true by default.
181 *
182 * This option provides the user with the ability to optimize
183 * interrupt dispatcher performance when it is known that Swi's
184 * will not be posted from any of their Hwi threads.
185 *
186 * Setting this parameter to false will disable the logic in
187 * the interrupt dispatcher that invokes the Swi scheduler
188 * prior to returning from an interrupt.
189 */
190 config Bool dispatcherSwiSupport;
191
192 /*!
193 * Include Task scheduling logic in interrupt dispatcher?
194 * Default is inherited from {@link ti.sysbios.BIOS#taskEnabled
195 * BIOS.taskEnabled}, which is true by default.
196 *
197 * This option provides the user with the ability to optimize
198 * interrupt dispatcher performance when it is known that no
199 * Task scheduling APIs (ie {@link ti.sysbios.ipc.Semaphore#post
200 * Semaphore_post()}) will be executed from any of their Hwi threads.
201 *
202 * Setting this parameter to false will disable the logic in
203 * the interrupt dispatcher that invokes the Task scheduler
204 * prior to returning from an interrupt.
205 */
206 config Bool dispatcherTaskSupport;
207
208 /*!
209 * This dispatcher configuration option controls whether the
210 * dispatcher retains the interrupted thread's return address.
211 * This option is enabled by default.
212 *
213 * Setting this parameter to false will disable the logic in
214 * the interrupt dispatcher that keeps track of the interrupt's
215 * return address and provide a small savings in interrupt latency.
216 *
217 * The application can get an interrupt's most recent return
218 * address using the {@link #getIrp} API.
219 */
220 config Bool dispatcherIrpTrackingSupport = true;
221
222
223
224 /*!
225 * ======== addHookSet ========
226 * addHookSet is used in a config file to add a hook set (defined
227 * by struct HookSet).
228 *
229 * HookSet structure elements may be omitted, in which case those
230 * elements will not exist.
231 *
232 * @param(hook) structure of type HookSet
233 */
234 metaonly Void addHookSet(HookSet hook);
235
236 /*!
237 * ======== getStackInfo ========
238 * @_nodoc
239 * Returns the Hwi stack usage info. Used at ROV time.
240 *
241 * @b(returns) Hwi stack base, size, peak
242 */
243 metaonly StackInfo getStackInfo();
244
245 /*!
246 * ======== startup ========
247 * Initially enable interrupts
248 *
249 * Called within BIOS_start
250 */
251 @DirectCall
252 Void startup();
253
254 /*!
255 * ======== disable ========
256 * Globally disable interrupts.
257 *
258 * Hwi_disable globally disables hardware interrupts and returns an
259 * opaque key indicating whether interrupts were globally enabled or
260 * disabled on entry to Hwi_disable().
261 * The actual value of the key is target/device specific and is meant
262 * to be passed to Hwi_restore().
263 *
264 * Call Hwi_disable before a portion of a function that needs
265 * to run without interruption. When critical processing is complete, call
266 * Hwi_restore or Hwi_enable to reenable hardware interrupts.
267 *
268 * Servicing of interrupts that occur while interrupts are disabled is
269 * postponed until interrupts are reenabled. However, if the same type
270 * of interrupt occurs several times while interrupts are disabled,
271 * the interrupt's function is executed only once when interrupts are
272 * reenabled.
273 *
274 * A context switch can occur when calling Hwi_enable or Hwi_restore if
275 * an enabled interrupt occurred while interrupts are disabled.
276 *
277 * Hwi_disable may be called from main(). However, since Hwi interrupts
278 * are already disabled in main(), such a call has no effect.
279 *
280 * @a(constraints)
281 * If a Task switching API such as
282 * {@link ti.sysbios.ipc.Semaphore#pend Semaphore_pend()},
283 * {@link ti.sysbios.ipc.Semaphore#post Semaphore_post()},
284 * {@link ti.sysbios.knl.Task#sleep Task_sleep()}, or
285 * {@link ti.sysbios.knl.Task#yield Task_yield()}
286 * is invoked which results in a context switch while
287 * interrupts are disabled, an embedded call to {@link #enable Hwi_enable} occurs
288 * on the way to the new thread context which unconditionally re-enables
289 * interrupts. Interrupts will remain enabled until a subsequent {@link #disable Hwi_disable}
290 * invocation.
291 *
292 * Swis always run with interrupts enabled.
293 * See {@link ti.sysbios.knl.Swi#post Swi_post()} for a discussion Swis and
294 * interrupts.
295 *
296 * @b(returns) opaque key for use by Hwi_restore()
297 */
298 UInt disable();
299
300 /*!
301 * ======== enable ========
302 * Globally enable interrupts.
303 *
304 * Hwi_enable globally enables hardware interrupts and returns an
305 * opaque key indicating whether interrupts were globally enabled or
306 * disabled on entry to Hwi_enable().
307 * The actual value of the key is target/device specific and is meant
308 * to be passed to Hwi_restore().
309 *
310 *
311 * This function is
312 * called as part of BIOS Startup_POST_APP_MAIN phase.
313 *
314 * Hardware interrupts are enabled unless a call to Hwi_disable disables
315 * them.
316 *
317 * Servicing of interrupts that occur while interrupts are disabled is
318 * postponed until interrupts are reenabled. However, if the same type
319 * of interrupt occurs several times while interrupts are disabled,
320 * the interrupt's function is executed only once when interrupts are
321 * reenabled.
322 *
323 * A context switch can occur when calling Hwi_enable or Hwi_restore if
324 * an enabled interrupt occurred while interrupts are disabled.
325 *
326 * Any call to Hwi_enable enables interrupts, even if Hwi_disable has
327 * been called several times.
328 *
329 * Hwi_enable must not be called from main().
330 *
331 * @b(returns) opaque key for use by Hwi_restore()
332 */
333 UInt enable();
334
335 /*!
336 * ======== restore ========
337 * Globally restore interrupts.
338 *
339 * Hwi_restore globally restores interrupts to the state determined
340 * by the key argument provided by a previous invocation of Hwi_disable.
341 *
342 * A context switch may occur when calling Hwi_restore if Hwi_restore
343 * reenables interrupts and another Hwi occurred while interrupts were
344 * disabled.
345 *
346 * Hwi_restore may be called from main(). However, since Hwi_enable
347 * cannot be called from main(), interrupts are always disabled in
348 * main(), and a call to Hwi_restore has no effect.
349 *
350 * @param(key) enable/disable state to restore
351 */
352 Void restore(UInt key);
353
354 /*!
355 * @_nodoc
356 * ======== switchFromBootStack ========
357 * Indicate that we are leaving the boot stack and
358 * are about to switch to a task stack.
359 * Used by Task_startup()
360 */
361 Void switchFromBootStack();
362
363 /*!
364 * @_nodoc
365 * ======== post ========
366 * Generate an interrupt for test purposes.
367 *
368 * @param(intNum) ID of interrupt to generate
369 */
370 Void post(UInt intNum);
371
372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389
390
391 392 393 394 395 396 397 398 399 400 401 402 403
404
405
406 407 408 409 410 411 412 413 414 415 416 417 418 419
420
421
422 /*!
423 * ======== disableInterrupt ========
424 * Disable a specific interrupt.
425 *
426 * Disable a specific interrupt identified by an interrupt number.
427 *
428 * @param(intNum) interrupt number to disable
429 * @b(returns) key to restore previous enable/disable state
430 */
431 UInt disableInterrupt(UInt intNum);
432
433 /*!
434 * ======== enableInterrupt ========
435 * Enable a specific interrupt.
436 *
437 * Enables a specific interrupt identified by an interrupt number.
438 *
439 * @param(intNum) interrupt number to enable
440 * @b(returns) key to restore previous enable/disable state
441 */
442 UInt enableInterrupt(UInt intNum);
443
444 /*!
445 * ======== restoreInterrupt ========
446 * Restore a specific interrupt's enabled/disabled state.
447 *
448 * Restores a specific interrupt identified by an interrupt number.
449 * restoreInterrupt is generally used to restore an interrupt to its state
450 * before {@link #disableInterrupt} or {@link #enableInterrupt} was
451 * invoked
452 *
453 * @param(intNum) interrupt number to restore
454 * @param(key) key returned from enableInt or disableInt
455 */
456 Void restoreInterrupt(UInt intNum, UInt key);
457
458 /*!
459 * ======== clearInterrupt ========
460 * Clear a specific interrupt.
461 *
462 * Clears a specific interrupt's pending status.
463 * The implementation is family specific.
464 *
465 * @param(intNum) interrupt number to enable
466 */
467 Void clearInterrupt(UInt intNum);
468
469 instance:
470
471 /*!
472 * ======== create ========
473 * Create a dispatched interrupt.
474 *
475 * A Hwi dispatcher table entry is created and filled with the
476 * function specified by the fxn parameter and the attributes
477 * specified by the params parameter.
478 *
479 * If params is NULL, the Hwi's dispatcher properties are assigned a
480 * default set of values. Otherwise, the Hwi's dispatcher properties
481 * are specified by a structure of type Hwi_Params.
482 *
483 * The maskSetting element defines the dispatcherAutoNestingSupport
484 * behavior of the interrupt.
485 *
486 * The arg element is a generic argument that is passed to the plugged
487 * function as its only parameter. The default value is 0.
488 *
489 * The enableInt element determines whether the interrupt should be
490 * enabled in the IER by create.
491 *
492 * Hwi_create returns a pointer to the created Hwi object.
493 *
494 * @param(intNum) interrupt number
495 * @param(hwiFxn) pointer to ISR function
496 */
497 create(Int intNum, FuncPtr hwiFxn);
498
499 /*! maskSetting. Default is {@link #MaskingOption Hwi_MaskingOption_SELF}. */
500 config MaskingOption maskSetting = MaskingOption_SELF;
501
502 /*! ISR function argument. Default is 0. */
503 config UArg arg = 0;
504
505 /*! Enable this interrupt now? Default is true. */
506 config Bool enableInt = true;
507
508 /*!
509 * Interrupt event ID (Interrupt Selection Number)
510 * Default is -1.
511 * Not all targets/devices support this instance parameter.
512 * On those that don't, this parameter is ignored.
513 */
514 config Int eventId = -1;
515
516 /*!
517 * Interrupt priority.
518 * Default is -1.
519 * Not all targets/devices support this instance parameter.
520 * On those that don't, this parameter is ignored.
521 */
522 config Int priority = -1;
523
524 /*!
525 * ======== getFunc ========
526 * Get Hwi function and arg
527 *
528 * @param(arg) pointer for returning hwi's ISR function argument
529 * @b(returns) hwi's ISR function
530 */
531 FuncPtr getFunc(UArg *arg);
532
533 /*!
534 * ======== setFunc ========
535 * Overwrite Hwi function and arg
536 *
537 * Replaces a Hwi object's hwiFxn function originally
538 * provided in {@link #create}.
539 *
540 * @param(fxn) pointer to ISR function
541 * @param(arg) argument to ISR function
542 */
543 Void setFunc(FuncPtr fxn, UArg arg);
544
545 /*!
546 * ======== getHookContext ========
547 * Get hook instance's context for a hwi.
548 *
549 * @b(returns) hook instance's context for hwi
550 */
551 Ptr getHookContext(Int id);
552
553 /*!
554 * ======== setHookContext ========
555 * Set hook instance's context for a hwi.
556 *
557 * @param(id) hook instance's ID
558 * @param(hookContext) value to write to context
559 */
560 Void setHookContext(Int id, Ptr hookContext);
561
562 /*!
563 * ======== getIrp ========
564 * Get address of interrupted instruction.
565 *
566 * @b(returns) most current IRP of a hwi
567 */
568 Irp getIrp();
569 }
570 571 572
573