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.gic;
36
37 import xdc.rov.ViewInfo;
38
39 import xdc.runtime.Diags;
40 import xdc.runtime.Log;
41 import xdc.runtime.Error;
42
43 import ti.sysbios.BIOS;
44 import ti.sysbios.interfaces.IHwi;
45
46 /*!
47 * ======== Hwi ========
48 * Hardware Interrupt Support Module.
49 *
50 * This Hwi module provides ARM cortex-A Generic Interrupt Controller(GIC) v2.0
51 * specific implementations and extensions of the APIs defined in
52 * {@link ti.sysbios.interfaces.IHwi IHwi}.
53 *
54 * The GIC is logically partitioned into 2 blocks, the Distributor block
55 * and CPU interface block. The Distributor block interfaces with the interrupt
56 * sources, prioritizes interrupts and distributes them to the CPU interface
57 * block. The CPU interface block connects to the processors in the system
58 * and is responsible for priority masking and preemption handling for
59 * the processor it is connected to.
60 *
61 * The GIC can implement up to 8 CPU interfaces with each CPU interface
62 * being able to see up to 1020 interrupts. The GIC assigns interrupt ID
63 * numbers 0-1019 as follows:
64 * - Interrupt numbers 0-31 are used for interrupts private to a
65 * CPU interface. These private interrupts are banked in the Distributor.
66 * - Banked interrupt number 0-15 are used for Software Generated Interrupts
67 * or SGIs.
68 * - Banked interrupt number 16-31 are used for Private Peripheral Interrupts
69 * or PPIs.
70 * - Interrupt numbers 32-1019 are used for Shared Peripheral Interrupts
71 * or SPIs.
72 * - Interrupt numbers 1020-1023 are reserved.
73 *
74 * @a(NOTE)
75 * In the SoC Technical Reference Manual, the MPU IRQs 0 to N map to
76 * GIC interrupt numbers 32 to (N+32) where (N+1) is the total number of
77 * Shared Peripheral Interrupts implemented.
78 * For instance on OMAP5430, MPU IRQ 0 to 159 maps to GIC interrupt number
79 * 32 to 191.
80 *
81 * @a(INTERRUPT GROUPING)
82 * GIC allows configuring an interrupt as a Group 0 or a Group 1 interrupt.
83 * Group 0 interrupts are Secure interrupts and Group 1 interrupts are
84 * Non-secure interrupts.
85 *
86 * If {@link #enableSecureMode} is set to true, this module supports both
87 * Group0 and Group 1 interrupts. Group 0 interrupts are delivered to the CPU
88 * using FIQ signal whereas Group 1 interrupts are delivered using IRQ signal.
89 *
90 * If {@link #enableSecureMode} is set to false, this module only supports
91 * Group 1 interrupts which are delivered to the target CPU using IRQ signal.
92 *
93 * @a(INTERRUPT PRIORITIES)
94 * In general GIC supports priority values 0 thru 255.
95 *
96 * In practice valid priority values depend on the particular device used,
97 * security mode and the Binary Point Register (see {@link #BPR} and
98 * {@link #ABPR}) value.
99 *
100 * The device implementation and security mode decide the number of priority
101 * bits that are implemented (see {@link #NUM_PRIORITY_BITS}). Group 0
102 * interrupts always implement one more priority bit than Group 1 interrupts.
103 *
104 * In GIC, interrupts with lower priority numbers have higher priority.
105 *
106 * @a(NOTE)
107 * In this Hwi module implementation, the instance config parameter value
108 * {@link #MaskingOption_LOWER} is equivalent to {@link #MaskingOption_SELF}.
109 * Statically configuring a Hwi object's {@link #Params.maskSetting} to
110 * {@link #MaskingOption_LOWER} will result in the generation of a benign
111 * build warning. Dynamic usages of {@link #MaskingOption_LOWER} will be
112 * silently converted to {@link #MaskingOption_SELF}.
113 *
114 * @a(ZERO LATENCY INTERRUPTS)
115 * On Keystone2 devices, this module supports zero-latency interrupts. A
116 * zero-latency interrupt does not go through the SYS/BIOS dispatcher and
117 * thus has a faster response time. Since zero-latency interrupts bypass the
118 * dispatcher, their handler function cannot call any SYS/BIOS APIs.
119 *
120 * This module implements zero-latency interrupts by forwarding the interrupt
121 * to the target CPU using FIQ signal. Therefore, in order to configure an
122 * interrupt as a zero-latency interrupt, the Hwi type needs to be changed
123 * to FIQ when creating or constructing a Hwi.
124 *
125 * Example showing how to create a zero-latency Hwi:
126 * @p(code)
127 * Void main(Void)
128 * {
129 * Hwi_Params hwiParams;
130 * Hwi_Params_init(&hwiParams);
131 * // Default Hwi type is IRQ
132 * hwiParams.type = Hwi_Type_FIQ;
133 * Hwi_create(INT_NUM_FIQ, myIsrFIQ, &hwiParams, NULL);
134 * ...
135 * }
136 * @p
137 *
138 * FIQs run on their own stack. See {@link #fiqStack} and {@link #fiqStackSize}
139 * for more info on how to control the FIQ stack.
140 *
141 * @a(NOTE)
142 * This module is written for GIC v2.0, however it is backwards compatible
143 * with GIC v1.0
144 */
145
146 @Template("./Hwi.xdt")
147 @ModuleStartup
148 @InstanceInitStatic
149 @CustomHeader
150
151 module Hwi inherits ti.sysbios.interfaces.IHwi
152 {
153
154
155 /*!
156 * ======== enableDataAbortHandling ========
157 * Unmask CPSR.A bit to allow handling of Data Abort.
158 */
159 config Bool enableDataAbort= false;
160
161 /*!
162 * ======== enableSecureMode ========
163 * Security Mode
164 *
165 * This field specifies the MPU's security mode. The MPU's security mode
166 * determines the type of accesses to the GIC i.e. if the MPU is in secure
167 * mode, all accesses to the GIC are secure and if the MPU is in non-secure
168 * mode, all accesses to the GIC are non-secure.
169 *
170 * An exception to the above rule can be seen on certain devices like
171 * Keystone 2, where all GIC acceses are secure irrespective of the MPU's
172 * security state. {@link #enableSecureMode} should be set to true for such
173 * devices.
174 */
175 config Bool enableSecureMode = false;
176
177 /*!
178 * Number of interrupts implemented in GIC
179 *
180 * On OMAP543x GIC implements 192 interrupts.
181 *
182 * See the OMAP543x_ES1 Technical Reference Manual pg 5280 for more
183 * details.
184 */
185 config UInt NUM_INTERRUPTS;
186
187 /*!
188 * Number of Priority bits implemented.
189 *
190 * On OMAP543x running in non-secure mode, only most significant 4
191 * priority bits are available for use. The least significant 4 bits
192 * are always 0.
193 */
194 config UInt NUM_PRIORITY_BITS;
195
196 /*!
197 * Minimum Interrupt Priority.
198 */
199 config UInt MIN_INT_PRIORITY;
200
201 /*!
202 * Default Interrupt Priority.
203 *
204 * Set to one level higher than minimum supported priority.
205 */
206 config UInt DEFAULT_INT_PRIORITY;
207
208 /*!
209 * ======== BPR ========
210 * GIC Binary Point Register value
211 *
212 * Defines the point at which the priority value fields split into
213 * two parts, the group priority field and the sub-priority field.
214 * When running in SECURE mode, BPR applies to Group 0 interrupts
215 * and when running in NON-SECURE mode, BPR applies to Group 1
216 * interrupts.
217 *
218 * The group priority field determines interrupt preemption in case
219 * of nested interrupts whereas sub-priority field is used to determine
220 * priority within a group when multiple interrrupts belonging to the
221 * same group are pending.
222 *
223 * Valid BPR values are from 0-7 with the minimum value supported being
224 * implementation defined and in the range 0-3.
225 *
226 * @p(code)
227 * -------------------------------------------------------
228 * | BPR value | Group priority field | Sub-priority field |
229 * -------------------------------------------------------
230 * | 0 | [7:1] | [0] |
231 * | 1 | [7:2] | [1:0] |
232 * | 2 | [7:3] | [2:0] |
233 * | 3 | [7:4] | [3:0] |
234 * | 4 | [7:5] | [4:0] |
235 * | 5 | [7:6] | [5:0] |
236 * | 6 | [7] | [6:0] |
237 * | 7 | No preemption | [7:0] |
238 * -------------------------------------------------------
239 * @p
240 *
241 */
242 config UInt BPR;
243
244 /*!
245 * ======== ABPR ========
246 * GIC Aliased Binary Point Register value for Grourp 1 interrupts
247 *
248 * Defines the point at which the priority value fields split into
249 * two parts, the group priority field and the sub-priority field.
250 * ABPR is used only when {@link #enableSecureMode} set to true and
251 * is ignored when security mode is set to false. ABPR applies to
252 * Group 1 interrupts.
253 *
254 * The group priority field determines interrupt preemption in case
255 * of nested interrupts whereas sub-priority field is used to determine
256 * priority within a group when multiple interrrupts belonging to the
257 * same group are pending.
258 *
259 * Valid ABPR values are from 1-7 with the minimum value supported being
260 * implementation defined and in the range 1-4. Minimum ABPR value is
261 * 1 more than the minimum BPR value.
262 *
263 * @p(code)
264 * --------------------------------------------------------
265 * | ABPR value | Group priority field | Sub-priority field |
266 * --------------------------------------------------------
267 * | 0 | -- | -- |
268 * | 1 | [7:1] | [0] |
269 * | 2 | [7:2] | [1:0] |
270 * | 3 | [7:3] | [2:0] |
271 * | 4 | [7:4] | [3:0] |
272 * | 5 | [7:5] | [4:0] |
273 * | 6 | [7:6] | [5:0] |
274 * | 7 | [7] | [6:0] |
275 * --------------------------------------------------------
276 * @p
277 *
278 */
279 config UInt ABPR;
280
281 /*!
282 * ======== Type ========
283 * Interrupt type. IRQ or FIQ
284 */
285 enum Type {
286 Type_IRQ, /*! IRQ interrupt. */
287 Type_FIQ /*! FIQ interrupt. */
288 };
289
290
291
292 /*! Hwi vector function type definition. */
293 typedef Void (*VectorFuncPtr)(void);
294
295 /*!
296 * ======== BasicView ========
297 * @_nodoc
298 */
299 metaonly struct BasicView {
300 Ptr halHwiHandle;
301 String label;
302 Int intNum;
303 String absolutePriority;
304 UInt relativeGrpPriority;
305 UInt relativeSubPriority;
306 String fxn;
307 UArg arg;
308 };
309
310 /*!
311 * ======== DetailedView ========
312 * @_nodoc
313 */
314 metaonly struct DetailedView {
315 Ptr halHwiHandle;
316 String label;
317 Int intNum;
318 String absolutePriority;
319 UInt relativeGrpPriority;
320 UInt relativeSubPriority;
321 String fxn;
322 UArg arg;
323 Ptr irp;
324 Bool enabled;
325 Bool pending;
326 String triggerSensitivity;
327 String targetProcList;
328 };
329
330 /*!
331 * ======== ModuleView ========
332 * @_nodoc
333 */
334 metaonly struct ModuleView {
335 String options[4];
336 UInt spuriousInterrupts;
337 UInt lastSpuriousInterrupt;
338 String hwiStackPeak;
339 SizeT hwiStackSize;
340 Ptr hwiStackBase;
341 };
342
343 /*!
344 * ======== rovViewInfo ========
345 * @_nodoc
346 */
347 @Facet
348 metaonly config ViewInfo.Instance rovViewInfo =
349 ViewInfo.create({
350 viewMap: [
351 [
352 'Basic',
353 {
354 type: ViewInfo.INSTANCE,
355 viewInitFxn: 'viewInitBasic',
356 structName: 'BasicView'
357 }
358 ],
359 [
360 'Detailed',
361 {
362 type: ViewInfo.INSTANCE,
363 viewInitFxn: 'viewInitDetailed',
364 structName: 'DetailedView'
365 }
366 ],
367 [
368 'Module',
369 {
370 type: ViewInfo.MODULE,
371 viewInitFxn: 'viewInitModule',
372 structName: 'ModuleView'
373 }
374 ]
375 ]
376 });
377
378 /*!
379 * Generic Interrupt Controller Distributor. Symbol "Hwi_gicd" is
380 * a physical device
381 */
382 struct Gicd {
383 UInt32 CTLR; /*! 0x000 Distributor Control Register */
384 UInt32 TYPER; /*! 0x004 Interrupt Controller Type Register */
385 UInt32 IIDR; /*! 0x008 Distributor Implementor Id Register */
386 UInt32 hole0[29]; /*! 0x00C-0x07C */
387 UInt32 IGROUPR[32]; /*! 0x080 Interrupt Group Registers */
388 UInt32 ISENABLER[32]; /*! 0x100 Interrupt Set-Enable Registers */
389 UInt32 ICENABLER[32]; /*! 0x180 Interrupt Clear-Enable Registers */
390 UInt32 ISPENDR[32]; /*! 0x200 Interrupt Set-Pending Registers */
391 UInt32 ICPENDR[32]; /*! 0x280 Interrupt Clear-Pending Registers */
392 UInt32 ISACTIVER[32]; /*! 0x300 Interrupt Set-Active Registers */
393 UInt32 ICACTIVER[32]; /*! 0x380 Interrupt Clear-Active Registers */
394 UInt32 IPRIORITYR[255]; /*! 0x400 Interrupt Priority Registers */
395 UInt32 hole1[1]; /*! 0x7FC */
396 UInt32 ITARGETSR[255]; /*! 0x800 Interrupt Processor Targets Register */
397 UInt32 hole2[1]; /*! 0xBFC */
398 UInt32 ICFGR[64]; /*! 0xC00 Interrupt Configuration Registers */
399 UInt32 PPISR; /*! 0xD00 PPI Status Register */
400 UInt32 SPISR[7]; /*! 0xD04 SPI Status Registers */
401 UInt32 hole3[120]; /*! 0xD20-0xEFC */
402 UInt32 SGIR; /*! 0xF00 Software Generated Interrupt
403 Registers */
404 UInt32 hole4[3]; /*! 0xF04-0xF0C */
405 UInt32 CPENDSGIR[4]; /*! 0xF10 SGI Clear-Pending Registers */
406 UInt32 SPENDSGIR[4]; /*! 0xF20 SGI Set-Pending Registers */
407 UInt32 hole5[40]; /*! 0xF30-0xFCC */
408 UInt32 PIDR4; /*! 0xFD0 Peripheral ID4 Register */
409 UInt32 PIDR5; /*! 0xFD4 Peripheral ID5 Register */
410 UInt32 PIDR6; /*! 0xFD8 Peripheral ID6 Register */
411 UInt32 PIDR7; /*! 0xFDC Peripheral ID7 Register */
412 UInt32 PIDR0; /*! 0xFE0 Peripheral ID0 Register */
413 UInt32 PIDR1; /*! 0xFE4 Peripheral ID1 Register */
414 UInt32 PIDR2; /*! 0xFE8 Peripheral ID2 Register */
415 UInt32 PIDR3; /*! 0xFEC Peripheral ID3 Register */
416 UInt32 CIDR0; /*! 0xFF0 Component ID0 Register */
417 UInt32 CIDR1; /*! 0xFF4 Component ID1 Register */
418 UInt32 CIDR2; /*! 0xFF8 Component ID2 Register */
419 UInt32 CIDR3; /*! 0xFFC Component ID3 Register */
420 };
421
422 extern volatile Gicd gicd;
423
424 /*!
425 * Generic Interrupt Controller CPU Interface. Symbol "Hwi_gicc" is
426 * a physical device.
427 */
428 struct Gicc {
429 UInt32 CTLR; /*! 0x0000 CPU Interface Control Register */
430 UInt32 PMR; /*! 0x0004 Interrupt Priority Mask Register */
431 UInt32 BPR; /*! 0x0008 Binary Point Register */
432 UInt32 IAR; /*! 0x000C Interrupt Acknowledge Register */
433 UInt32 EOIR; /*! 0x0010 End Of Interrupt Register */
434 UInt32 RPR; /*! 0x0014 Running Priority Register */
435 UInt32 HPPIR; /*! 0x0018 Highest Priority Pending Interrupt
436 Register */
437 UInt32 ABPR; /*! 0x001C Aliased Binary Point Register */
438 UInt32 AIAR; /*! 0x0020 Aliased IAR Register */
439 UInt32 AEOIR; /*! 0x0024 Aliased EOI Register */
440 UInt32 AHPPIR; /*! 0x0028 Aliased HPPI Register */
441 UInt32 hole0[41]; /*! 0x002C-0x00CC */
442 UInt32 APR0; /*! 0x00D0 Active Priority Register */
443 UInt32 hole1[3]; /*! 0x00D4-0x00DC */
444 UInt32 NSAPR0; /*! 0x00E0 Non-secure Active Priority Register */
445 UInt32 hole2[6]; /*! 0x00E4-0x00F8 */
446 UInt32 IIDR; /*! 0x00FC CPU Interface Id Register */
447 UInt32 hole3[960]; /*! 0x0100-0x0FFC */
448 UInt32 DIR; /*! 0x1000 Deactivate Interrupt Register */
449 };
450
451 extern volatile Gicc gicc;
452
453
454
455 /*! Reset Handler. Default is _c_int00 */
456 metaonly config VectorFuncPtr resetFunc;
457
458 /*!
459 * Undefined instruction exception handler.
460 * Default is an internal exception handler.
461 */
462 metaonly config VectorFuncPtr undefinedInstFunc;
463
464 /*!
465 * SVC Handler. Supervisor Call exception handler.
466 * (previously called Software Interrupt or SWI)
467 * Default is an internal exception handler.
468 */
469 metaonly config VectorFuncPtr svcFunc;
470
471 /*!
472 * Prefetch abort exception handler.
473 * Default is an internal exception handler.
474 */
475 metaonly config VectorFuncPtr prefetchAbortFunc;
476
477 /*!
478 * Data abort exception handler.
479 * Default is an internal exception handler.
480 */
481 metaonly config VectorFuncPtr dataAbortFunc;
482
483 /*!
484 * Reserved exception handler.
485 * Default is an internal exception handler.
486 */
487 metaonly config VectorFuncPtr reservedFunc;
488
489 /*! IRQ interrupt handler.
490 * Default is internal IRQ dispatcher
491 */
492 metaonly config VectorFuncPtr irqFunc;
493
494 /*! FIQ interrupt handler.
495 * Default is internal exception handler.
496 */
497 metaonly config VectorFuncPtr fiqFunc;
498
499 /*!
500 * @_nodoc
501 * ======== enableAsidTagging ========
502 * Flag to enable/disable ASID tagging
503 *
504 * If ASID tagging is enabled, the Hwi dispatcher will switch
505 * to ASID 0 (and change the MMU table base address to match
506 * kernel MMU table address) in the Hwi dispatcher prolog
507 * and restore the ASID (and MMU table base address) in the
508 * Hwi dispatcher epilog.
509 */
510 config Bool enableAsidTagging = false;
511
512 /*!
513 * ======== initGicd ========
514 * Initialize all GIC Distributor registers. True by default.
515 *
516 * Flag determines whether to initialize certain global GIC distributor
517 * registers. It is set to false when running under a hypervisor and
518 * should be true if not running under a hypervisor.
519 */
520 config Bool initGicd = true;
521
522 /*!
523 * @_nodoc
524 * ======== irqStackSection ========
525 * Memory section used for IRQ stack on each core
526 * Default is null.
527 */
528 metaonly config String irqStackSection = null;
529
530 /*!
531 * @_nodoc
532 * ======== fiqStack ========
533 * FIQ stack pointer. Default = null.
534 * (Indicates that stack is to be created internally)
535 *
536 * @a(Note)
537 * If running in SMP mode and both fiqStack and fiqStacks[0]
538 * are set, then fiqStack is used on Core0.
539 */
540 metaonly config Ptr fiqStack = null;
541 metaonly config Ptr fiqStacks[];
542
543 /*!
544 * ======== fiqStackSize ========
545 * FIQ stack size in MAUs.
546 * Default is 1024 bytes.
547 *
548 * If running in SMP mode, the FIQ stacks on all cores are
549 * set to this size.
550 */
551 metaonly config SizeT fiqStackSize = 1024;
552
553 /*!
554 * ======== fiqStackSection ========
555 * Memory section used for FIQ stack
556 * Default is null.
557 */
558 metaonly config String fiqStackSection = null;
559
560 /*!
561 * ======== A_badSGIIntNum ========
562 * Assert raised when an interrupt number >= 16 is
563 * passed to Hwi_raiseSGI() function.
564 */
565 config xdc.runtime.Assert.Id A_badSGIIntNum = {
566 msg: "A_badSGIIntNum: SGI intNum should be <= 15."
567 };
568
569 /*!
570 * Error raised when an attempt is made to create a Hwi
571 * that has already been created.
572 */
573 config Error.Id E_alreadyDefined = {
574 msg: "E_alreadyDefined: Hwi already defined, intnum: %d"
575 };
576
577 /*!
578 * Error raised when Hwi handle referenced in Hwi_delete()
579 * is not found in the Hwi dispatch table
580 */
581 config Error.Id E_handleNotFound = {
582 msg: "E_handleNotFound: Hwi handle not found: 0x%x"
583 };
584
585 /*!
586 * Error raised when an undefined interrupt has fired.
587 */
588 config Error.Id E_undefined = {
589 msg: "E_undefined: Hwi undefined, intnum: %d"
590 };
591
592 /*!
593 * Error raised if an attempt is made to create a Hwi
594 * with an interrupt number greater than Hwi_NUM_INTERRUPTS - 1.
595 */
596 config Error.Id E_badIntNum = {
597 msg: "E_badIntNum, intnum: %d is out of range"
598 };
599
600 /*!
601 * Issued just prior to Hwi function invocation (with interrupts disabled)
602 */
603 config Log.Event LM_begin = {
604 mask: Diags.USER1 | Diags.USER2,
605 msg: "LM_begin: hwi: 0x%x, func: 0x%x, preThread: %d, intNum: %d, irp: 0x%x"
606 };
607
608 /*!
609 * Issued just after return from Hwi function (with interrupts disabled)
610 */
611 config Log.Event LD_end = {
612 mask: Diags.USER2,
613 msg: "LD_end: hwi: 0x%x"
614 };
615
616
617
618
619 /*!
620 * ======== disable ========
621 * Globally disable interrupts.
622 *
623 * Hwi_disable globally disables hardware interrupts and returns an
624 * opaque key indicating whether interrupts were globally enabled or
625 * disabled on entry to Hwi_disable().
626 * The actual value of the key is target/device specific and is meant
627 * to be passed to Hwi_restore().
628 *
629 * Call Hwi_disable before a portion of a function that needs
630 * to run without interruption. When critical processing is complete, call
631 * Hwi_restore or Hwi_enable to reenable hardware interrupts.
632 *
633 * Servicing of interrupts that occur while interrupts are disabled is
634 * postponed until interrupts are reenabled. However, if the same type
635 * of interrupt occurs several times while interrupts are disabled,
636 * the interrupt's function is executed only once when interrupts are
637 * reenabled.
638 *
639 * A context switch can occur when calling Hwi_enable or Hwi_restore if
640 * an enabled interrupt occurred while interrupts are disabled.
641 *
642 * Hwi_disable may be called from main(). However, since Hwi interrupts
643 * are already disabled in main(), such a call has no effect.
644 *
645 * @a(NOTE)
646 * Disables only IRQ interrupts
647 *
648 * @a(constraints)
649 * If a Task switching API such as
650 * {@link ti.sysbios.knl.Semaphore#pend Semaphore_pend()},
651 * {@link ti.sysbios.knl.Semaphore#post Semaphore_post()},
652 * {@link ti.sysbios.knl.Task#sleep Task_sleep()}, or
653 * {@link ti.sysbios.knl.Task#yield Task_yield()}
654 * is invoked which results in a context switch while
655 * interrupts are disabled, an embedded call to
656 * {@link #enable Hwi_enable} occurs
657 * on the way to the new thread context which unconditionally re-enables
658 * interrupts. Interrupts will remain enabled until a subsequent
659 * {@link #disable Hwi_disable}
660 * invocation.
661 *
662 * Swis always run with interrupts enabled.
663 * See {@link ti.sysbios.knl.Swi#post Swi_post()} for a discussion Swis and
664 * interrupts.
665 *
666 * @b(returns) opaque key for use by Hwi_restore()
667 */
668 @Macro
669 override UInt disable();
670
671 /*!
672 * ======== enable ========
673 *
674 * @a(NOTE)
675 * Enables only IRQ interrupts
676 */
677 @Macro
678 override UInt enable();
679
680 /*!
681 * ======== restore ========
682 *
683 * @a(NOTE)
684 * Restores only IRQ interrupts
685 */
686 @Macro
687 override Void restore(UInt key);
688
689 /*!
690 * ======== enableIRQ ========
691 * Enable IRQ interrupts.
692 *
693 * @a(NOTE)
694 * Same as Hwi_enable()
695 *
696 * @b(returns) previous IRQ interrupt enable/disable state
697 */
698 @Macro
699 UInt enableIRQ();
700
701 /*!
702 * ======== disableIRQ ========
703 * Disable IRQ interrupts.
704 *
705 * @a(NOTE)
706 * Same as Hwi_disable()
707 *
708 * @b(returns) previous IRQ interrupt enable/disable state
709 */
710 @Macro
711 UInt disableIRQ();
712
713 /*!
714 * ======== restoreIRQ ========
715 * Restore IRQ interrupts.
716 *
717 * @a(NOTE)
718 * Same as Hwi_restore()
719 *
720 * @param(key) enable/disable state to restore
721 */
722 @Macro
723 Void restoreIRQ(UInt key);
724
725 /*!
726 * ======== enableFIQ ========
727 * Enable FIQ interrupts.
728 *
729 * @b(returns) previous FIQ interrupt enable/disable state
730 */
731 @Macro
732 UInt enableFIQ();
733
734 /*!
735 * ======== disableFIQ ========
736 * Disable FIQ interrupts.
737 *
738 * @b(returns) previous FIQ interrupt enable/disable state
739 */
740 @Macro
741 UInt disableFIQ();
742
743 /*!
744 * ======== restoreFIQ ========
745 * Restore FIQ interrupts.
746 *
747 * @param(key) enable/disable state to restore
748 */
749 @Macro
750 Void restoreFIQ(UInt key);
751
752 /*!
753 * @_nodoc
754 * ======== disableFxn ========
755 * function call implementation
756 */
757 UInt disableFxn();
758
759 /*!
760 * @_nodoc
761 * ======== enableFxn ========
762 * function call implementation
763 */
764 UInt enableFxn();
765
766 /*!
767 * @_nodoc
768 * ======== restoreFxn ========
769 * function call implementation
770 */
771 Void restoreFxn(UInt key);
772
773 /*!
774 * ======== getHandle ========
775 * Returns Hwi_Handle associated with intNum
776 *
777 * @param(intNum) interrupt number
778 */
779 Handle getHandle(UInt intNum);
780
781 /*!
782 * @_nodoc
783 * ======== init ========
784 * assembly code mode registers setup
785 */
786 Void init();
787
788 /*!
789 * @_nodoc
790 * ======== initIntControllerCoreX ========
791 */
792 Void initIntControllerCoreX();
793
794 /*!
795 * ======== intAffinity ========
796 * SMP Interrupt affinity mappings
797 *
798 * In SMP mode, this array maps an interrupt number to the
799 * coreId it is to be tied to. By default, all ints are mapped to
800 * core 0.
801 *
802 * For example, to make Timer 1 from the ti.sysbios.timers.dmtimer.Timer
803 * module interrupt on core 1 rather than core 0, add the following to
804 * your config file:
805 *
806 * @p(code)
807 * var Hwi = xdc.useModule('ti.sysbios.family.arm.gic.Hwi');
808 * Hwi.intAffinity[<intNum>] = 1;
809 * @p
810 *
811 * @a(constraints)
812 * Interrupt numbers below 32 are ignored. This config param only
813 * allows routing interrupt numbers greater than or equal to #32.
814 */
815 metaonly config UInt8 intAffinity[];
816
817 /*!
818 * @_nodoc
819 * ======== raiseSGI ========
820 */
821 Void raiseSGI(UInt mask, UInt intNum);
822
823 /*!
824 * ======== setPriority ========
825 * Set an interrupt's priority.
826 *
827 * Not an instance function so that it can be used
828 * with non-dispatched interrupts.
829 *
830 * @param(intNum) ID of interrupt
831 * @param(priority) priority
832 */
833 Void setPriority(UInt intNum, UInt priority);
834
835 instance:
836
837 /*!
838 * ======== type ========
839 * Interrupt type (IRQ/FIQ). Default is IRQ.
840 *
841 * @a(NOTE)
842 * FIQs are only supported when {@link #enableSecureMode} is set to
843 * true.
844 */
845 config Type type = Type_IRQ;
846
847 /*!
848 * ======== triggerSensitivity ========
849 * Set an interrupt's trigger sensitivity
850 *
851 * 2-bit field that configures the trigger sensitivity of an
852 * interrupt.
853 *
854 * On the Cortex-A15, all software generated interrupts (SGI)
855 * are edge-triggered (b10) and all private peripheral interrupts (PPI)
856 * are level-sensitive (b01). The trigger sensitivity of these
857 * interrupt types cannot be changed.
858 *
859 * For shared peripheral interrupts (SPI), the LSB of the bit-pair
860 * is read only and is always 1. The MSB of the bit-pair can be
861 * altered to change trigger sensitivity.
862 *
863 * Possible bit-pair encodings for Cortex-A15 SPIs:
864 * b01 Interrupt is active-High level-sensitive (default)
865 * b11 Interrupt is rising edge-sensitive
866 *
867 * For more information please refer section 4.3.13 on
868 * Interrupt Configuration Registers (GICD_ICFGRn) in
869 * ARM Generic Interrupt Controller Architecure Spec v2.0
870 */
871 config UInt triggerSensitivity = ~(0);
872
873 /*!
874 * ======== targetProcList ========
875 * Set an interrupt's target processor list.
876 *
877 * This is an 8-bit CPU targets field that stores the list of target
878 * processors for the interrupt. That is, it holds the list of CPU
879 * interfaces to which the GIC Distributor will forward the interrupt
880 * if it is asserted and has sufficient priority.
881 *
882 * Each bit in targetProcList refers to the corresponding processor.
883 * For instance, a value of 0x3 means the pending interrupt is
884 * forwarded to processor 0 and 1.
885 *
886 * For more information please refer section 4.3.12 on
887 * Interrupt Processor Targets Registers (GICD_ITARGETSRn) in
888 * ARM Generic Interrupt Controller Architecure Spec v2.0
889 *
890 * If running in {@link ti.sysbios.BIOS#smpEnabled SMP mode}
891 * and both the targetProcList Hwi param as well as the
892 * {@link #intAffinity}[] array entry for the intNum are set,
893 * targetProcList is given precedence and is used to configure
894 * the interrupt's target processors.
895 *
896 * @a(NOTE)
897 * Target processor list is read-only for the first 32 interrupts.
898 * Therefore, this field will have no effect for interrupt numbers
899 * less than 32 (intNum 0-31).
900 */
901 config UInt targetProcList = 0x0;
902
903 /*!
904 * ======== Interrupt priority ========
905 * Hwi instance interrupt priority.
906 *
907 * Valid priorities are device dependent and their
908 * nesting behaviors depend on the {@link #BPR} setting.
909 *
910 * See the ARM GIC Architecture Specification v2.0 document for more
911 * details.
912 */
913 override config Int priority = -1;
914
915 /*! The interrupt controller is designed for priority based interrupts */
916 override config IHwi.MaskingOption maskSetting = IHwi.MaskingOption_LOWER;
917
918 /*!
919 * ======== reconfig ========
920 * Reconfigure a dispatched interrupt.
921 */
922 Void reconfig(FuncPtr fxn, const Params *params);
923
924 internal:
925
926 /*!
927 * ======== inUseMeta ========
928 * @_nodoc
929 * Check for Hwi already in use.
930 * For internal SYS/BIOS use only.
931 * Should be called prior to any internal Hwi.create().
932 *
933 * @param(intNum) interrupt number
934 */
935 metaonly Bool inUseMeta(UInt intNum);
936
937 938 939 940 941 942
943 config UInt (*swiDisable)();
944 config Void (*swiRestoreHwi)(UInt);
945 config UInt (*taskDisable)();
946 config Void (*taskRestoreHwi)(UInt);
947
948 949 950 951
952 Int postInit(Object *hwi, Error.Block *eb);
953
954 955 956
957 Void initIntControllerCore0();
958
959
960 Void initFIQStack(Ptr fiqStack);
961
962
963 Void dispatchFIQC();
964
965
966 Void dispatchIRQ();
967
968
969 Void dispatchIRQC(Irp irp);
970
971
972 Void nonPluggedHwiHandler(UArg arg);
973
974 /*!
975 * const array to hold all HookSet objects.
976 */
977 config HookSet hooks[length] = [];
978
979 /*! Meta World Only Hwi Configuration Object. */
980 metaonly struct InterruptObj {
981 Bool used;
982 FuncPtr fxn;
983 };
984
985 /*!
986 * Meta-only array of interrupt objects.
987 * This meta-only array of Hwi config objects is initialized
988 * in Hwi.xs:module$meta$init().
989 */
990 metaonly config InterruptObj interrupt[];
991
992 /*!
993 * GIC Distributor base address
994 */
995 metaonly config Ptr gicdBaseAddress;
996
997 /*!
998 * GIC cpu interface base address
999 */
1000 metaonly config Ptr giccBaseAddress;
1001
1002 struct Instance_State {
1003 Type type;
1004 UInt priority;
1005 UArg arg;
1006 FuncPtr fxn;
1007 Irp irp;
1008 Ptr hookEnv[];
1009 UInt triggerSensitivity;
1010 UInt targetProcList;
1011 };
1012
1013 struct Module_State {
1014 Char *taskSP[];
1015
1016 Char *isrStack[];
1017 Char hwiStack[][];
1018 Ptr isrStackSize;
1019
1020
1021
1022
1023 UInt32 iser[32];
1024 UInt32 icfgr[];
1025 UInt32 itargetsr[];
1026 UInt spuriousInts;
1027 UInt lastSpuriousInt;
1028 UInt irp;
1029 Ptr isrStackBase;
1030 Hwi.Object nonPluggedHwi;
1031 Handle dispatchTable[];
1032 volatile UInt curIntId;
1033 UInt32 igroupr[];
1034 Char fiqStack[][];
1035 SizeT fiqStackSize;
1036 UInt8 intAffinity[];
1037 };
1038 }