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 package ti.sysbios.family.arm.v7r.vim;
36
37 import xdc.runtime.Diags;
38 import xdc.runtime.Error;
39 import xdc.runtime.Log;
40 import xdc.rov.ViewInfo;
41
42 import ti.sysbios.interfaces.IHwi;
43
44 /*!
45 * ======== Hwi ========
46 * Hardware Interrupt Support Module.
47 *
48 * This Hwi module provides Hercules VIM specific implementations of the
49 * APIs defined in {@link ti.sysbios.interfaces.IHwi IHwi}.
50 *
51 * Additional ARM device-specific APIs are also provided.
52 *
53 * @a(Minimal Latency Interrupts)
54 * For applications requiring extremely low interrupt latency, this Hwi module
55 * allows the user to create FIQ interrupts that bypass the SYS/BIOS interrupt
56 * dispatcher. Though not a precisely correct classification, these interrupts
57 * are referred to as "Zero latency" interrupts.
58 *
59 * "FIQ" aka "Zero latency" interrupts can be created by setting the Hwi_Param
60 * {@link #type} to Hwi_Type_FIQ. FIQ interrupts offer low interrupt latency
61 * as they do not have to pass through the regular SYS/BIOS interrupt
62 * dispatcher and are always enabled. When auto nesting is enabled and masking
63 * option ALL or LOWER is used, some or all of the VIM interrupt channels will
64 * be disabled while the interrupt is being serviced. However, none of the
65 * channels corresponding to "Zero latency" interrupts are disabled (masked).
66 *
67 * The ISR handler function for a "Zero latency" interrupt must use the
68 * "interrupt" keyword in the function definition and should have no
69 * parameters. Using the "interrupt" keyword will ensure that the necessary
70 * registers are saved on entry into the interrupt routine and are restored
71 * upon exit from the interrupt routine.
72 *
73 * Since the function pointer passed to Hwi_create()/Hwi_construct() has a
74 * different function signature (i.e. it accepts an argument), the
75 * "Zero latency" function must be type-casted to {@link #FuncPtr Hwi_FuncPtr}
76 * type before being passed to Hwi_create()/Hwi_construct() in order to avoid
77 * any compiler warnings.
78 *
79 * Unlike regular IRQ interrupts, FIQ interrupts do not run on the System stack
80 * but on their own FIQ stack. The stack pointer, size and section name for the
81 * FIQ stack can be set using the {@link #fiqStack}, {@link #fiqStackSize}
82 * and {@link #fiqStackSection} module wide configuration params.
83 *
84 * @a(Constraints of using "FIQ" aka "Zero latency" interrupts)
85 * Interrupts configured to bypass the dispatcher are not allowed
86 * to call ANY SYS/BIOS APIs that effect thread scheduling. Examples
87 * of API that should no be invoked are:
88 *
89 * @p(dlist)
90 * - Swi_post(),
91 * - Semaphore_post(),
92 * - Event_post(),
93 * - Task_yield()
94 * @p
95 *
96 * Here's an example showing how to create a Hwi of FIQ type:
97 * @p(code)
98 * *.cfg:
99 * var Hwi = xdc.useModule('ti.sysbios.family.arm.v7r.vim.Hwi');
100 * Hwi.fiqStackSize = 2048;
101 * Hwi.fiqStackSection = ".myFiqStack"
102 * Program.sectMap[".myFiqStack"] = "RAM";
103 *
104 * *.c:
105 * #include <xdc/std.h>
106 * #include <xdc/runtime/System.h>
107 *
108 * #include <ti/sysbios/BIOS.h>
109 * #include <ti/sysbios/family/arm/v7r/vim/Hwi.h>
110 *
111 * #include <xdc/cfg/global.h>
112 *
113 * Void interrupt myIsrFIQ()
114 * {
115 * ...
116 * }
117 *
118 * Void main(Void)
119 * {
120 * Hwi_Params hwiParams;
121 *
122 * Hwi_Params_init(&hwiParams);
123 * hwiParams.type = Hwi_Type_FIQ;
124 * Hwi_create(INT_NUM_FIQ, (Hwi_FuncPtr)myIsrFIQ, &hwiParams, NULL);
125 * ...
126 *
127 * BIOS_start();
128 * }
129 * @p
130 *
131 * @a(Interrupt Channel configuration)
132 * Each VIM interrupt request (source) can be mapped to any of the interrupt
133 * channels (same as intNums). Lower numbered channels in each FIQ and IRQ
134 * have higher priority. Therefore, channel mapping provides a mechanism for
135 * prioritizing the interrupt requests.
136 *
137 * Additionally, it is possible to configure a channel interrupt as a wakeup
138 * interrupt so it can bring the core out of low power mode (LPM).
139 *
140 * This module has a {@link #configChannelMeta Hwi.configChannelMeta()}
141 * function that can be invoked from the cfg script to statically
142 * (at build time) change the channel mapping and wakeup functionality of a
143 * channel interrupt.
144 *
145 * By default, all interrupt request sources are direct mapped to channels
146 * (i.e. interrupt request N is mapped to channel N) and wakeup feature is
147 * enabled for all interrupts.
148 *
149 * Here's an example showing how to use this function:
150 * @p(code)
151 * *.cfg:
152 * var Hwi = xdc.useModule('ti.sysbios.family.arm.v7r.vim.Hwi');
153 *
154 * // Map interrupt request line 86 to channel 2 (i.e. intNum 2) and disable
155 * // wakeup feature
156 * Hwi.configChannelMeta(2, 86, false);
157 * @p
158 *
159 * @a(More Hwi examples)
160 * Here's an example showing how to construct a Hwi at runtime:
161 * @p(code)
162 * *.c:
163 * #include <ti/sysbios/family/arm/v7r/vim/Hwi.h>
164 *
165 * Hwi_Struct hwiStruct;
166 *
167 * Void myIsrIRQ(UArg arg)
168 * {
169 * ...
170 * }
171 *
172 * Void main(Void)
173 * {
174 * Hwi_Params hwiParams;
175 *
176 * Hwi_Params_init(&hwiParams);
177 * Hwi_construct(&hwiStruct, INT_NUM_IRQ, myIsrIRQ, &hwiParams, NULL);
178 * ...
179 * BIOS_start();
180 * }
181 * @p
182 *
183 * @p(html)
184 * <h3> Calling Context </h3>
185 * <table border="1" cellpadding="3">
186 * <colgroup span="1"></colgroup> <colgroup span="5" align="center"></colgroup>
187 *
188 * <tr><th> Function </th><th> Hwi </th><th> Swi </th><th> Task </th><th> Main </th><th> Startup </th></tr>
189 * <!-- -->
190 * <tr><td> {@link #clearInterrupt} </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td></tr>
191 * <tr><td> {@link #create} </td><td> N </td><td> N </td><td> Y </td><td> Y </td><td> N </td></tr>
192 * <tr><td> {@link #disable} </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td></tr>
193 * <tr><td> {@link #disableInterrupt} </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td><td> N </td></tr>
194 * <tr><td> {@link #disableIRQ} </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td></tr>
195 * <tr><td> {@link #enable} </td><td> Y </td><td> Y </td><td> Y </td><td> N </td><td> N </td></tr>
196 * <tr><td> {@link #enableInterrupt} </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td><td> N </td></tr>
197 * <tr><td> {@link #enableIRQ} </td><td> Y </td><td> Y </td><td> Y </td><td> N </td><td> N </td></tr>
198 * <tr><td> {@link #getHandle} </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td><td> N </td></tr>
199 * <tr><td> {@link #Params_init} </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td></tr>
200 * <tr><td> {@link #restore} </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td></tr>
201 * <tr><td> {@link #restoreInterrupt} </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td></tr>
202 * <tr><td> {@link #restoreIRQ} </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td></tr>
203 * <tr><td> {@link #construct} </td><td> N </td><td> N </td><td> Y </td><td> Y </td><td> N </td></tr>
204 * <tr><td> {@link #delete} </td><td> N </td><td> N </td><td> Y </td><td> Y </td><td> N </td></tr>
205 * <tr><td> {@link #destruct} </td><td> N </td><td> N </td><td> Y </td><td> Y </td><td> N </td></tr>
206 * <tr><td> {@link #getHookContext} </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td><td> N </td></tr>
207 * <tr><td> {@link #reconfig} </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td><td> N </td></tr>
208 * <tr><td> {@link #setFunc} </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td><td> N </td></tr>
209 * <tr><td> {@link #setHookContext} </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td><td> N </td></tr>
210 * <tr><td colspan="6"> Definitions: <br />
211 * <ul>
212 * <li> <b>Hwi</b>: API is callable from a Hwi thread. </li>
213 * <li> <b>Swi</b>: API is callable from a Swi thread. </li>
214 * <li> <b>Task</b>: API is callable from a Task thread. </li>
215 * <li> <b>Main</b>: API is callable during any of these phases: </li>
216 * <ul>
217 * <li> In your module startup after this module is started (e.g. Hwi_Module_startupDone() returns TRUE). </li>
218 * <li> During xdc.runtime.Startup.lastFxns. </li>
219 * <li> During main().</li>
220 * <li> During BIOS.startupFxns.</li>
221 * </ul>
222 * <li> <b>Startup</b>: API is callable during any of these phases:</li>
223 * <ul>
224 * <li> During xdc.runtime.Startup.firstFxns.</li>
225 * <li> In your module startup before this module is started (e.g. Hwi_Module_startupDone() returns FALSE).</li>
226 * </ul>
227 * </ul>
228 * </td></tr>
229 *
230 *
231 * </table>
232 * @p
233 */
234
235 @Template("./Hwi.xdt")
236 @ModuleStartup
237 @InstanceInitStatic
238 @CustomHeader
239
240 module Hwi inherits ti.sysbios.interfaces.IHwi
241 {
242
243
244
245 config UInt NUM_INTERRUPTS;
246
247
248
249 /*! Hwi vector function type definition. */
250 typedef Void (*VectorFuncPtr)(void);
251
252 /*! @_nodoc Hwi plug function type definition. */
253 typedef Void (*PlugFuncPtr)(void);
254
255 /*! Interrupt type. IRQ or FIQ */
256 enum Type {
257 Type_IRQ, /*! IRQ interrupt. */
258 Type_FIQ /*! FIQ interrupt. */
259 };
260
261 /*!
262 * @_nodoc
263 * Vectored Interrupt Manager (VIM) Registers
264 */
265 struct VIM {
266 UInt32 ECCSTAT; /*! VIM RAM ECC Status Register */
267 UInt32 ECCCTL; /*! VIM RAM ECC Control Register */
268 UInt32 UERRADDR; /*! Uncorrectable Error Address Register */
269 UInt32 FBVECADDR; /*! Fallback Vector Address Register */
270 UInt32 SBERRADDR; /*! Single Bit Error Address Register */
271
272 UInt32 IRQINDEX; /*! IRQ Index Offset Vector Register */
273 UInt32 FIQINDEX; /*! FIQ Index Offset Vector Register */
274 UInt32 RES00[2]; /*! Reserved */
275
276 UInt32 FIRQPR[4]; /*! FIQ/IRQ Program Control Registers */
277 UInt32 INTREQ[4]; /*! Pending Interrupt Read Location Registers */
278
279 UInt32 REQENASET[4]; /*! Interrupt Enable Set Registers */
280 UInt32 REQENACLR[4]; /*! Interrupt Enable Clear Registers */
281
282 UInt32 WAKEENASET[4]; /*! Wake-up Enable Set Registers */
283 UInt32 WAKEENACLR[4]; /*! Wake-up Enable Clear Registers */
284
285 UInt32 IRQVECREG; /*! IRQ Interrupt Vector Register */
286 UInt32 FIQVECREG; /*! FIQ Interrupt Vector Register */
287
288 UInt32 CAPEVT; /*! Capture Event Register */
289 UInt32 RES01; /*! Reserved */
290
291 UInt8 CHANCTRL[128]; /*! VIM Interrupt Control Registers */
292 };
293
294 /*!
295 * @_nodoc
296 * Symbol "Hwi_vim" is a physical device
297 */
298 extern volatile VIM vim;
299
300 /*! @_nodoc */
301 metaonly struct BasicView {
302 Ptr halHwiHandle;
303 String label;
304 String type;
305 Int intNum;
306 String fxn;
307 UArg arg;
308 Ptr irp;
309 String status;
310 };
311
312 /*! @_nodoc */
313 metaonly struct ChannelMapView {
314 UInt channelId;
315 UInt interruptRequestId;
316 };
317
318 /*! @_nodoc */
319 metaonly struct ModuleView {
320 String options[4];
321 UInt spuriousInterrupts;
322 SizeT hwiStackPeak;
323 SizeT hwiStackSize;
324 Ptr hwiStackBase;
325 };
326
327 /*! @_nodoc */
328 @Facet
329 metaonly config ViewInfo.Instance rovViewInfo =
330 ViewInfo.create({
331 viewMap: [
332 ['Basic', {type: ViewInfo.INSTANCE, viewInitFxn: 'viewInitBasic', structName: 'BasicView'}],
333 ['ChannelMap', {type: ViewInfo.MODULE_DATA, viewInitFxn: 'viewChannelMap', structName: 'ChannelMapView'}],
334 ['Module', {type: ViewInfo.MODULE, viewInitFxn: 'viewInitModule', structName: 'ModuleView'}]
335 ]
336 });
337
338
339
340 /*!
341 * ======== core0VectorTableAddress ========
342 * Determines the location of Core0's Interrupt Vector Table on a
343 * Dual-Core device. Default is device dependent.
344 *
345 * On Dual-Core devices, both Cortex-R5 cores share a common reset
346 * vector table. In order to allow the 2 cores to register their own
347 * exception handlers, each core generates its own clone of the reset
348 * vector table and initializes it with its own exception handler
349 * addresses. The core specific vector tables are placed at fixed
350 * addresses so that the exception handler functions called by the
351 * common reset vector table known each core's vector table address
352 * and are able to reference it once they detect which core the
353 * application is currently running on.
354 *
355 * The address of Core0's vector table is determined by this parameter.
356 *
357 * Here are the default Core0 vector table addresses for all supported
358 * Dual-Core devices:
359 * @p(code)
360 * ----------------------------------------------------
361 * | Device name | Core0's default vector table address |
362 * ----------------------------------------------------
363 * | RM57D8xx | 0x100 |
364 * ----------------------------------------------------
365 * @p
366 *
367 * @a(Note)
368 * If changing Core0's vector table address, it is not necessary to
369 * rebuild Core1's application as it does not need to know the location
370 * of Core0's vector table.
371 */
372 config Ptr core0VectorTableAddress;
373
374 /*!
375 * ======== core1VectorTableAddress ========
376 * Determines the location of Core1's Interrupt Vector Table on a
377 * Dual-Core device. Default is device dependent.
378 *
379 * On Dual-Core devices, both Cortex-R5 cores share a common reset
380 * vector table. In order to allow the 2 cores to register their own
381 * exception handlers, each core generates its own clone of the reset
382 * vector table and initializes it with its own exception handler
383 * addresses. The core specific vector tables are placed at fixed
384 * addresses so that the exception handler functions called by the
385 * common reset vector table known each core's vector table address
386 * and are able to reference it once they detect which core the
387 * application is currently running on.
388 *
389 * Core0's vector table is always placed at 0x100 while the address of
390 * Core1's vector table is determined by this parameter.
391 *
392 * Here are the default Core1 vector table addresses for all supported
393 * Dual-Core devices:
394 * @p(code)
395 * ----------------------------------------------------
396 * | Device name | Core1's default vector table address |
397 * ----------------------------------------------------
398 * | RM57D8xx | 0x200000 |
399 * ----------------------------------------------------
400 * @p
401 *
402 * @a(Note)
403 * If changing Core1's vector table address, it is important to rebuild
404 * Core0's application with the same change as Core0 owns the common
405 * reset vector table and the common exception handler functions need
406 * to know Core1's vector table address so they can determine the
407 * address of the handler function they need to jump to.
408 */
409 config Ptr core1VectorTableAddress;
410
411 /*! Reset Handler. Default is c_int00 */
412 metaonly config VectorFuncPtr resetFunc;
413
414 /*!
415 * Undefined instruction exception handler.
416 * Default is set to an internal exception handler.
417 */
418 metaonly config VectorFuncPtr undefinedInstFunc;
419
420 /*! SWI Handler. Default is internal SWI handler */
421 metaonly config VectorFuncPtr swiFunc;
422
423 /*!
424 * Prefetch abort exception handler.
425 * Default is set to an internal exception handler.
426 */
427 metaonly config VectorFuncPtr prefetchAbortFunc;
428
429 /*!
430 * Data abort exception handler.
431 * Default is set to an internal exception handler.
432 */
433 metaonly config VectorFuncPtr dataAbortFunc;
434
435 /*!
436 * Reserved exception handler.
437 * Default is set to an internal exception handler.
438 */
439 metaonly config VectorFuncPtr reservedFunc;
440
441 /*!
442 * IRQ exception handler.
443 * Default is set to internal IRQ dispatcher.
444 */
445 metaonly config VectorFuncPtr irqFunc;
446
447 /*!
448 * Phantom interrupt handler.
449 * Default is set to internal phantom interrupt handler.
450 */
451 config VectorFuncPtr phantomFunc;
452
453 /*!
454 * FIQ stack pointer. Default = null.
455 * (Indicates that stack is to be created using
456 * staticPlace())
457 */
458 config Ptr fiqStack = null;
459
460 /*!
461 * FIQ stack size in MAUs.
462 * Default is 1024 bytes.
463 */
464 metaonly config SizeT fiqStackSize = 1024;
465
466 /*!
467 * Memory section used for FIQ stack
468 * Default is null.
469 */
470 metaonly config String fiqStackSection = null;
471
472 /*!
473 * @_nodoc
474 * VIM base address
475 */
476 metaonly config Ptr vimBaseAddress;
477
478 /*!
479 * ======== errataInitESM ========
480 * Clear ESM errors for AR1xxx devices. Default is true for AR1xxx devices.
481 *
482 * Errata brief description:
483 * Cortex-R4 on AR14xx devices generates a VIM RAM compare error
484 * during startup due to a ROM code bug. This error needs to be cleared
485 * before SYS/BIOS is started and interrupts are enabled.
486 */
487 config Bool errataInitEsm = false;
488
489 /*!
490 * ======== resetVIM ========
491 * Reset VIM hardware. Default is true for AR1xxx devices.
492 *
493 * This feature is available only on certain devices.
494 */
495 config Bool resetVIM = false;
496
497 /*!
498 * ======== A_badChannelId ========
499 * Assert raised when an invalid channelId is passed to Hwi_mapChannel()
500 * function.
501 */
502 config xdc.runtime.Assert.Id A_badChannelId = {
503 msg: "A_badChannelId: ChannelId is either not re-mappable or invalid."
504 };
505
506 /*!
507 * Error raised when Hwi is already defined
508 */
509 config Error.Id E_alreadyDefined = {
510 msg: "E_alreadyDefined: Hwi already defined: intr# %d"
511 };
512
513 /*!
514 * Error raised if an attempt is made to create a Hwi
515 * with an interrupt number greater than Hwi_NUM_INTERRUPTS - 1.
516 */
517 config Error.Id E_badIntNum = {
518 msg: "E_badIntNum, intnum: %d is out of range"
519 };
520
521 /*!
522 * Error raised when an undefined interrupt has fired.
523 */
524 config Error.Id E_undefined = {
525 msg: "E_undefined: Hwi undefined, intnum: %d"
526 };
527
528 /*!
529 * Error raised when an unsupported Hwi.MaskingOption used.
530 */
531 config Error.Id E_unsupportedMaskingOption = {
532 msg: "E_unsupportedMaskingOption: Unsupported masking option passed."
533 };
534
535 /*!
536 * Error raised when a phantom interrupt occurs.
537 */
538 config Error.Id E_phantomInterrupt = {
539 msg: "E_phantomInterrupt: A phantom interrupt has occurred."
540 };
541
542 /*!
543 * Issued just prior to Hwi function invocation (with interrupts disabled)
544 */
545 config Log.Event LM_begin = {
546 mask: Diags.USER1 | Diags.USER2,
547 msg: "LM_begin: hwi: 0x%x, func: 0x%x, preThread: %d, intNum: %d, irp: 0x%x"
548 };
549
550 /*!
551 * Issued just after return from Hwi function (with interrupts disabled)
552 */
553 config Log.Event LD_end = {
554 mask: Diags.USER2,
555 msg: "LD_end: hwi: 0x%x"
556 };
557
558
559
560
561 /*!
562 * ======== disable ========
563 * Globally disable interrupts.
564 *
565 * Hwi_disable globally disables hardware interrupts and returns an
566 * opaque key indicating whether interrupts were globally enabled or
567 * disabled on entry to Hwi_disable().
568 * The actual value of the key is target/device specific and is meant
569 * to be passed to Hwi_restore().
570 *
571 * Call Hwi_disable before a portion of a function that needs
572 * to run without interruption. When critical processing is complete, call
573 * Hwi_restore or Hwi_enable to reenable hardware interrupts.
574 *
575 * Servicing of interrupts that occur while interrupts are disabled is
576 * postponed until interrupts are reenabled. However, if the same type
577 * of interrupt occurs several times while interrupts are disabled,
578 * the interrupt's function is executed only once when interrupts are
579 * reenabled.
580 *
581 * A context switch can occur when calling Hwi_enable or Hwi_restore if
582 * an enabled interrupt occurred while interrupts are disabled.
583 *
584 * Hwi_disable may be called from main(). However, since Hwi interrupts
585 * are already disabled in main(), such a call has no effect.
586 *
587 * @a(constraints)
588 * If a Task switching API such as
589 * {@link ti.sysbios.knl.Semaphore#pend Semaphore_pend()},
590 * {@link ti.sysbios.knl.Semaphore#post Semaphore_post()},
591 * {@link ti.sysbios.knl.Task#sleep Task_sleep()}, or
592 * {@link ti.sysbios.knl.Task#yield Task_yield()}
593 * is invoked which results in a context switch while
594 * interrupts are disabled, an embedded call to
595 * {@link #enable Hwi_enable} occurs
596 * on the way to the new thread context which unconditionally re-enables
597 * interrupts. Interrupts will remain enabled until a subsequent
598 * {@link #disable Hwi_disable}
599 * invocation.
600 *
601 * Swis always run with interrupts enabled.
602 * See {@link ti.sysbios.knl.Swi#post Swi_post()} for a discussion Swis and
603 * interrupts.
604 *
605 * @b(returns) opaque key for use by Hwi_restore()
606 */
607 @Macro
608 override UInt disable();
609
610 /*!
611 * ======== enable ========
612 */
613 @Macro
614 override UInt enable();
615
616 /*!
617 * ======== restore ========
618 */
619 @Macro
620 override Void restore(UInt key);
621
622 /*!
623 * @_nodoc
624 * ======== inUseMeta ========
625 * Check for Hwi already in use.
626 * For internal SYS/BIOS use only.
627 * Should be called prior to any internal Hwi.create().
628 *
629 * @param(intNum) interrupt number
630 */
631 metaonly Bool inUseMeta(UInt intNum);
632
633 /*!
634 * ======== getHandle ========
635 * Returns pointer to Hwi instance object.
636 *
637 * @param(intNum) interrupt number
638 */
639 Object *getHandle(UInt intNum);
640
641 /*!
642 * ======== enableIRQ ========
643 * Enable IRQ interrupts.
644 *
645 * @param(key) enable/disable state to restore
646 */
647 UInt enableIRQ();
648
649 /*!
650 * ======== disableIRQ ========
651 * Disable IRQ interrupts.
652 *
653 * @b(returns) previous IRQ interrupt enable/disable state
654 */
655 UInt disableIRQ();
656
657 /*!
658 * ======== restoreIRQ ========
659 * Restore IRQ interrupts.
660 *
661 * @param(key) enable/disable state to restore
662 */
663 Void restoreIRQ(UInt key);
664
665 /*!
666 * ======== configChannelMeta ========
667 * Configure which VIM interrupt request this channel maps to and
668 * whether this channel's interrupt is a wakeup interrupt
669 *
670 * Each VIM interrupt request (source) can be mapped to any of
671 * the interrupt channels. Lower numbered channels in each FIQ
672 * and IRQ have higher priority. Therefore, channel mapping
673 * provides a mechanism for prioritizing the interrupt requests.
674 *
675 * A channel interrupt can also be configured to be a wakeup interrupt
676 * so it can bring the core out of low power mode (LPM).
677 *
678 * @param(channelId) Channel number (intNum)
679 * @param(intRequestId) VIM Interrupt request (source) number
680 * @param(wakeupEnable) Enable wakeup interrupt functionality ?
681 */
682 metaonly Void configChannelMeta(UInt channelId, UInt intRequestId,
683 Bool wakeupEnable);
684
685 /*!
686 * @_nodoc
687 * ======== setType ========
688 * Set an interrupt's type (FIQ/IRQ).
689 *
690 * Not an instance function so that it can be used
691 * with non-dispatched interrupts.
692 *
693 * @param(intNum) ID of interrupt
694 * @param(type) type = FIQ/IRQ
695 */
696 Void setType(UInt intNum, Type type);
697
698 instance:
699
700 /*! Interrupt type (IRQ/FIQ. Default is IRQ. */
701 config Type type = Type_IRQ;
702
703 /*!
704 * Default setting for this Hwi module is IHwi.MaskingOption_LOWER
705 */
706 override config IHwi.MaskingOption maskSetting = IHwi.MaskingOption_LOWER;
707
708 /*!
709 * ======== reconfig ========
710 * Reconfigure a dispatched interrupt.
711 */
712 Void reconfig(FuncPtr fxn, const Params *params);
713
714 internal:
715
716 metaonly config Bool lockstepDevice;
717
718 719 720
721 config UInt8 channelMap[];
722
723 724 725 726
727 config UInt32 intReqEnaSet[];
728
729 730 731 732
733 config UInt32 wakeEnaSet[];
734
735 736 737 738 739 740
741 config UInt (*swiDisable)();
742 config Void (*swiRestoreHwi)(UInt);
743 config UInt (*taskDisable)();
744 config Void (*taskRestoreHwi)(UInt);
745
746 747 748
749 Void initEsm();
750
751 752 753 754
755 Int postInit(Object *hwi, Error.Block *eb);
756
757 758 759
760 Void initIntController();
761
762
763 Void init();
764
765
766 Void dispatchIRQ();
767
768
769 Void dispatchIRQC(Irp irp);
770
771
772 Void phantomIntHandler();
773
774 775 776 777 778 779 780
781 Void mapChannel(UInt channelId, UInt intRequestId);
782
783
784 Void nonPluggedHwiHandler(UArg arg);
785
786 787 788 789 790 791 792
793 Void plug(UInt intNum, PlugFuncPtr fxn);
794
795 /*!
796 * const array to hold all HookSet objects.
797 */
798 config HookSet hooks[length] = [];
799
800 /*! Meta World Only Hwi Configuration Object. */
801 metaonly struct InterruptObj {
802 Bool used;
803 FuncPtr fxn;
804 };
805
806 /*!
807 * Meta-only array of interrupt objects.
808 * This meta-only array of Hwi config objects is initialized
809 * in Hwi.xs:module$meta$init().
810 */
811 metaonly config InterruptObj interrupt[];
812
813 struct Instance_State {
814 Type type;
815 UArg arg;
816 FuncPtr fxn;
817 Int intNum;
818 Irp irp;
819 Ptr hookEnv[];
820 UInt disableMask[4];
821 };
822
823 struct Module_State {
824 Char *taskSP;
825
826 Char *isrStack;
827 Ptr isrStackBase;
828 Ptr isrStackSize;
829 Char fiqStack[];
830 SizeT fiqStackSize;
831 UInt *vimRam;
832 Handle dispatchTable[];
833 UInt zeroLatencyFIQMask[4];
834 UInt spuriousInts;
835 };
836 }