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