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.gicv3;
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 @ModuleStartup
147 @InstanceInitStatic
148 @CustomHeader
149
150 module Hwi inherits ti.sysbios.interfaces.IHwi
151 {
152
153
154 /*!
155 * Number of interrupts implemented in GIC
156 */
157 const UInt NUM_INTERRUPTS = 992;
158
159 /*!
160 * ======== enableSecureMode ========
161 * Security Mode
162 *
163 * This field specifies the MPU's security mode. The MPU's security mode
164 * determines the type of accesses to the GIC i.e. if the MPU is in secure
165 * mode, all accesses to the GIC are secure and if the MPU is in non-secure
166 * mode, all accesses to the GIC are non-secure.
167 *
168 * An exception to the above rule can be seen on certain devices like
169 * Keystone 2, where all GIC acceses are secure irrespective of the MPU's
170 * security state. {@link #enableSecureMode} should be set to true for such
171 * devices.
172 */
173 config Bool enableSecureMode = false;
174
175 /*!
176 * Number of Priority bits implemented.
177 *
178 * On OMAP543x running in non-secure mode, only most significant 4
179 * priority bits are available for use. The least significant 4 bits
180 * are always 0.
181 */
182 config UInt NUM_PRIORITY_BITS;
183
184 /*!
185 * Minimum Interrupt Priority.
186 */
187 config UInt MIN_INT_PRIORITY;
188
189 /*!
190 * Default Interrupt Priority.
191 *
192 * Set to one level higher than minimum supported priority.
193 */
194 config UInt DEFAULT_INT_PRIORITY;
195
196 /*!
197 * ======== BPR ========
198 * GIC Binary Point Register value
199 *
200 * Defines the point at which the priority value fields split into
201 * two parts, the group priority field and the sub-priority field.
202 * When running in SECURE mode, BPR applies to Group 0 interrupts
203 * and when running in NON-SECURE mode, BPR applies to Group 1
204 * interrupts.
205 *
206 * The group priority field determines interrupt preemption in case
207 * of nested interrupts whereas sub-priority field is used to determine
208 * priority within a group when multiple interrrupts belonging to the
209 * same group are pending.
210 *
211 * Valid BPR values are from 0-7 with the minimum value supported being
212 * implementation defined and in the range 0-3.
213 *
214 * @p(code)
215 * -------------------------------------------------------
216 * | BPR value | Group priority field | Sub-priority field |
217 * -------------------------------------------------------
218 * | 0 | [7:1] | [0] |
219 * | 1 | [7:2] | [1:0] |
220 * | 2 | [7:3] | [2:0] |
221 * | 3 | [7:4] | [3:0] |
222 * | 4 | [7:5] | [4:0] |
223 * | 5 | [7:6] | [5:0] |
224 * | 6 | [7] | [6:0] |
225 * | 7 | No preemption | [7:0] |
226 * -------------------------------------------------------
227 * @p
228 *
229 */
230 config UInt BPR;
231
232
233 enum ExcType {
234 ExcType_Synchronous,
235 ExcType_SError
236 };
237
238 /*!
239 * ======== Type ========
240 * Interrupt type. IRQ or FIQ
241 */
242 enum Type {
243 Type_IRQ, /*! IRQ interrupt. */
244 Type_FIQ /*! FIQ interrupt. */
245 };
246
247 /*!
248 * ======== RoutingMode ========
249 * Routing mode. ANY or NODE
250 */
251 enum RoutingMode {
252 RoutingMode_NODE, /*! Route interrupt to node specified by
253 affinity fields. */
254 RoutingMode_ALL /*! Route interrupt to all nodes. */
255 };
256
257 /*!
258 * ======== IntAffinity ========
259 * Interrupt affinity type. Stores the hierarchical address (composed
260 * of different affinity levels) that uniquely identifies the core or
261 * processing element (PE) an interrupt is routed to.
262 *
263 * The routingMode field determines whether an interrupt is routed to
264 * all nodes or a node identified by the affinity fields. This field
265 * takes the value Hwi_RoutingMode_ANY and Hwi_RoutingMode_NODE.
266 *
267 * If {@link ti.sysbios.BIOS#smpEnabled BIOS.smpEnabled} is true then,
268 * all interrupts are forwarded to core 0 by default.
269 * If {@link ti.sysbios.BIOS#smpEnabled BIOS.smpEnabled} is false then,
270 * all interrupts are forwarded to all participating nodes.
271 *
272 * @a(constraints)
273 * This config param is ignored if
274 * {@link ti.sysbios.family.arm.v8a.Core#bootMaster Core.bootMaster} is
275 * set to false.
276 */
277 struct IntAffinity {
278 UInt8 aff0; /*! Affinity level 0 - CoreId within cluster */
279 UInt8 aff1; /*! Affinity level 1 - Cluster Id */
280 RoutingMode routingMode; /*! Routing Mode - ALL or particular NODE */
281 };
282
283 /*!
284 * ======== SgiIntAffinity ========
285 * Sgi interrupt affinity type. Stores affinity and routing mode
286 * information that is used to determine which cores will the generated
287 * SGI be routed to.
288 *
289 * The routingMode field determines whether a generated SGI is routed to
290 * all cores except the core generating the SGI (Hwi_RoutingMode_ALL) or
291 * to list of target cores identified by the "targetList" and "aff1"
292 * fields (Hwi_RoutingMode_NODE).
293 */
294 struct SgiIntAffinity {
295 UInt8 targetList; /*! Bit map of target cores */
296 UInt8 aff1; /*! Identifies the target cluster */
297 RoutingMode routingMode; /*! Routing Mode - ALL or NODE target list */
298 };
299
300
301
302 /*! Exception hook function type definition. */
303 typedef Void (*ExceptionHookFuncPtr)(ExcContext *);
304
305 /*!
306 * ======== BasicView ========
307 * @_nodoc
308 */
309 metaonly struct BasicView {
310 Ptr halHwiHandle;
311 String label;
312 Int intNum;
313 String absPri;
314 UInt relGrpPri;
315 UInt relSubPri;
316 String fxn;
317 UArg arg;
318 };
319
320 /*!
321 * ======== DetailedView ========
322 * @_nodoc
323 */
324 metaonly struct DetailedView {
325 Ptr halHwiHandle;
326 String label;
327 Int intNum;
328 String absPri;
329 UInt relGrpPri;
330 UInt relSubPri;
331 String fxn;
332 UArg arg;
333 Ptr irp;
334 String enabled;
335 String pending;
336 String active;
337 String triggerSensitivity;
338 };
339
340 /*!
341 * ======== ModuleView ========
342 * @_nodoc
343 */
344 metaonly struct ModuleView {
345 String options[4];
346 UInt spuriousInterrupts;
347 UInt lastSpuriousInterrupt;
348 String hwiStackPeak;
349 SizeT hwiStackSize;
350 Ptr hwiStackBase;
351 };
352
353 /*!
354 * ======== rovViewInfo ========
355 * @_nodoc
356 */
357 @Facet
358 metaonly config ViewInfo.Instance rovViewInfo =
359 ViewInfo.create({
360 viewMap: [
361 [
362 'Basic',
363 {
364 type: ViewInfo.INSTANCE,
365 viewInitFxn: 'viewInitBasic',
366 structName: 'BasicView'
367 }
368 ],
369 [
370 'Detailed',
371 {
372 type: ViewInfo.INSTANCE,
373 viewInitFxn: 'viewInitDetailed',
374 structName: 'DetailedView'
375 }
376 ],
377 [
378 'Module',
379 {
380 type: ViewInfo.MODULE,
381 viewInitFxn: 'viewInitModule',
382 structName: 'ModuleView'
383 }
384 ]
385 ]
386 });
387
388 /*!
389 * Exception Context - Register contents at the time of an exception.
390 */
391 struct ExcContext {
392
393 BIOS.ThreadType threadType;
394
395 Ptr threadHandle;
396
397 Ptr threadStack;
398
399
400 SizeT threadStackSize;
401 ExcType type;
402
403
404 Ptr x0;
405 Ptr x1;
406 Ptr x2;
407 Ptr x3;
408 Ptr x4;
409 Ptr x5;
410 Ptr x6;
411 Ptr x7;
412 Ptr x8;
413 Ptr x9;
414 Ptr x10;
415 Ptr x11;
416 Ptr x12;
417 Ptr x13;
418 Ptr x14;
419 Ptr x15;
420 Ptr x16;
421 Ptr x17;
422 Ptr x18;
423 Ptr x19;
424 Ptr x20;
425 Ptr x21;
426 Ptr x22;
427 Ptr x23;
428 Ptr x24;
429 Ptr x25;
430 Ptr x26;
431 Ptr x27;
432 Ptr x28;
433 Ptr x29;
434 Ptr x30;
435 Ptr sp;
436 Ptr elr;
437 Ptr spsr;
438
439
440 Ptr esr;
441 }
442
443 /*!
444 * Generic Interrupt Controller Distributor. Symbol "Hwi_gicd" is
445 * a physical device
446 */
447 struct Gicd {
448 UInt32 CTLR; /*! 0x0000 Distributor Control Register */
449 UInt32 TYPER; /*! 0x0004 Interrupt Controller Type Register */
450 UInt32 IIDR; /*! 0x0008 Distributor Implementor Id Register */
451 UInt32 hole0[13]; /*! 0x000C-0x03C */
452 UInt32 SETSPI_NSR; /*! 0x0040 Set SPI Register */
453 UInt32 hole1; /*! 0x0044 */
454 UInt32 CLRSPI_NSR; /*! 0x0048 Clear SPI Register */
455 UInt32 hole2; /*! 0x004C */
456 UInt32 SETSPI_SR; /*! 0x0050 Set SPI Register */
457 UInt32 hole3; /*! 0x0054 */
458 UInt32 CLRSPI_SR; /*! 0x0058 Clear SPI Register */
459 UInt32 hole4[9]; /*! 0x005C-0x007C */
460 UInt32 IGROUPR[32]; /*! 0x0080 Interrupt Group Registers */
461 UInt32 ISENABLER[32]; /*! 0x0100 Interrupt Set-Enable Registers */
462 UInt32 ICENABLER[32]; /*! 0x0180 Interrupt Clear-Enable Registers */
463 UInt32 ISPENDR[32]; /*! 0x0200 Interrupt Set-Pending Registers */
464 UInt32 ICPENDR[32]; /*! 0x0280 Interrupt Clear-Pending Registers */
465 UInt32 ISACTIVER[32]; /*! 0x0300 Interrupt Set-Active Registers */
466 UInt32 ICACTIVER[32]; /*! 0x0380 Interrupt Clear-Active Registers */
467 UInt8 IPRIORITYR[992]; /*! 0x0400 Interrupt Priority Registers */
468 UInt32 hole5[8]; /*! 0x07E0-0x07FC */
469 UInt32 ITARGETSR[8]; /*! 0x0800 Interrupt Processor Targets
470 Register */
471 UInt32 hole6[248]; /*! 0x0820-0x0BFC */
472 UInt32 ICFGR[64]; /*! 0x0C00 Interrupt Configuration Registers */
473 UInt32 IGRPMODR[32]; /*! 0x0D00 Interrupt Group Modifier Registers */
474 UInt32 hole7[32]; /*! 0x0D80-0x0DFC */
475 UInt32 NSACR[64]; /*! 0x0E00 NonSecure Access Control Registers */
476 UInt32 SGIR; /*! 0x0F00 Software Generated Interrupt
477 Register */
478 UInt32 hole8[3]; /*! 0x0F04-0x0F0C */
479 UInt32 CPENDSGIR[4]; /*! 0x0F10 SGI Clear-Pending Registers */
480 UInt32 SPENDSGIR[4]; /*! 0x0F20 SGI Set-Pending Registers */
481 UInt32 hole9[5172]; /*! 0x0F30-0x5FFC */
482 UInt64 IROUTER[992]; /*! 0x6000 Interrupt Routing Registers */
483 UInt32 hole10[4160]; /*! 0x7F00-0xBFFC */
484 UInt32 ESTATUSR; /*! 0xC000 Extended Status Register */
485 UInt32 ERRTESTR; /*! 0xC004 Error Test Register */
486 UInt32 hole11[31]; /*! 0xC008-0xC080 */
487 UInt32 SPISR[30]; /*! 0xC084 SPI Status Registers */
488 UInt32 hole12[4021]; /*! 0xC0FC-0xFFCC */
489 UInt32 PIDR4; /*! 0xFFD0 Peripheral ID4 Register */
490 UInt32 PIDR5; /*! 0xFFD4 Peripheral ID5 Register */
491 UInt32 PIDR6; /*! 0xFFD8 Peripheral ID6 Register */
492 UInt32 PIDR7; /*! 0xFFDC Peripheral ID7 Register */
493 UInt32 PIDR0; /*! 0xFFE0 Peripheral ID0 Register */
494 UInt32 PIDR1; /*! 0xFFE4 Peripheral ID1 Register */
495 UInt32 PIDR2; /*! 0xFFE8 Peripheral ID2 Register */
496 UInt32 PIDR3; /*! 0xFFEC Peripheral ID3 Register */
497 UInt32 CIDR0; /*! 0xFFF0 Component ID0 Register */
498 UInt32 CIDR1; /*! 0xFFF4 Component ID1 Register */
499 UInt32 CIDR2; /*! 0xFFF8 Component ID2 Register */
500 UInt32 CIDR3; /*! 0xFFFC Component ID3 Register */
501 };
502
503 extern volatile Gicd gicd;
504
505 /*!
506 * Generic Interrupt Controller Redistributor Interface (RD_base).
507 * Symbol "Hwi_gicr" is a physical device.
508 */
509 struct Gicr {
510 UInt32 CTLR; /*! 0x0000 Redistributor Control Register */
511 UInt32 IIDR; /*! 0x0004 Implementor Id Register */
512 UInt32 TYPER[2]; /*! 0x0008 Redistributor Type Register */
513 UInt32 hole0; /*! 0x0010 */
514 UInt32 WAKER; /*! 0x0014 Power Management Control Register */
515 UInt32 hole1[22]; /*! 0x0018-0x006C */
516 UInt32 PROPBASER[2]; /*! 0x0070 LPI Config Table Base Register */
517 UInt32 PENDBASER[2]; /*! 0x0078 LPI Pending Table Base Register */
518 };
519
520 /*!
521 * Generic Interrupt Controller Redistributor Interface (SGI_base).
522 * Symbol "Hwi_gics" is a physical device.
523 */
524 struct Gics {
525 UInt32 hole0[32]; /*! 0x0000-0x007C */
526 UInt32 IGROUPR0; /*! 0x0080 Interrupt Group Register */
527 UInt32 hole1[31]; /*! 0x0084-0x00FC */
528 UInt32 ISENABLER0; /*! 0x0100 Interrupt Set-Enable Register */
529 UInt32 hole2[31]; /*! 0x0104-0x017C */
530 UInt32 ICENABLER0; /*! 0x0180 Interrupt Set-Enable Register */
531 UInt32 hole3[31]; /*! 0x0184-0x01FC */
532 UInt32 ISPENDR0; /*! 0x0200 Interrupt Set-Enable Register */
533 UInt32 hole4[31]; /*! 0x0204-0x027C */
534 UInt32 ICPENDR0; /*! 0x0280 Interrupt Set-Enable Register */
535 UInt32 hole5[31]; /*! 0x0284-0x02FC */
536 UInt32 ISACTIVER0; /*! 0x0300 Interrupt Set-Enable Register */
537 UInt32 hole6[31]; /*! 0x0304-0x037C */
538 UInt32 ICACTIVER0; /*! 0x0380 Interrupt Set-Enable Register */
539 UInt32 hole7[31]; /*! 0x0384-0x03FC */
540 UInt8 IPRIORITYR[32]; /*! 0x0400 Interrupt Priority Registers */
541 UInt32 hole8[504]; /*! 0x0420-0x0BFC */
542 UInt32 ICFGR[2]; /*! 0x0C00 Interrupt Configuration Registers */
543 UInt32 hole9[62]; /*! 0x0C08-0x0CFC */
544 UInt32 IGRPMODR0; /*! 0x0D00 Interrupt Group Modifier Register */
545 UInt32 hole10[63]; /*! 0x0D04-0x0DFC */
546 UInt32 NSACR; /*! 0x0E00 NonSecure Access Control Register */
547 };
548
549 /*!
550 * Generic Interrupt Controller CPU Interface. Symbol "Hwi_gicc" is
551 * a physical device.
552 */
553 struct Gicc {
554 UInt32 CTLR; /*! 0x0000 CPU Interface Control Register */
555 UInt32 PMR; /*! 0x0004 Interrupt Priority Mask Register */
556 UInt32 BPR; /*! 0x0008 Binary Point Register */
557 UInt32 IAR; /*! 0x000C Interrupt Acknowledge Register */
558 UInt32 EOIR; /*! 0x0010 End Of Interrupt Register */
559 UInt32 RPR; /*! 0x0014 Running Priority Register */
560 UInt32 HPPIR; /*! 0x0018 Highest Priority Pending Interrupt
561 Register */
562 UInt32 ABPR; /*! 0x001C Aliased Binary Point Register */
563 UInt32 AIAR; /*! 0x0020 Aliased IAR Register */
564 UInt32 AEOIR; /*! 0x0024 Aliased EOI Register */
565 UInt32 AHPPIR; /*! 0x0028 Aliased HPPI Register */
566 UInt32 hole0[41]; /*! 0x002C-0x00CC */
567 UInt32 APR0; /*! 0x00D0 Active Priority Register */
568 UInt32 hole1[3]; /*! 0x00D4-0x00DC */
569 UInt32 NSAPR0; /*! 0x00E0 Non-secure Active Priority Register */
570 UInt32 hole2[6]; /*! 0x00E4-0x00F8 */
571 UInt32 IIDR; /*! 0x00FC CPU Interface Id Register */
572 UInt32 hole3[960]; /*! 0x0100-0x0FFC */
573 UInt32 DIR; /*! 0x1000 Deactivate Interrupt Register */
574 };
575
576
577
578 /*!
579 * Enable full exception decoding, default is true.
580 *
581 * When enabled, the exception handler will fully
582 * decode an exception and dump the registers to the
583 * system console.
584 *
585 * When set to false, only an Error is printed on the console.
586 *
587 * In either case, the full exception context is always
588 * saved and visible with ROV.
589 */
590 config Bool enableDecode = true;
591
592 /*!
593 * User Exception Context Buffer Address
594 *
595 * By default, when an exception occurs, an {@link #ExcContext}
596 * structure is allocated on the ISR stack and filled in within the
597 * exception handler.
598 *
599 * If {@link #excContextBuffer} is initialized by the user, the
600 * {@link #ExcContext} structure will be placed at that address instead.
601 *
602 * The buffer must be large enough to contain an {@link #ExcContext}
603 * structure.
604 */
605 metaonly config Ptr excContextBuffer[];
606
607 /*!
608 * User Synchronous Exception hook function.
609 *
610 * Called just after the exception context has been initialized.
611 *
612 * This function will be run on the ISR stack.
613 *
614 * This function must run to completion.
615 *
616 * It is called without any Task or Swi scheduling protection
617 * and therefore can not call any functions that may cause a Swi or Task
618 * scheduling operation (Swi_post(), Semaphore_post(), Event_post(), etc).
619 */
620 config ExceptionHookFuncPtr syncExcHookFunc[];
621
622 /*!
623 * User SError Exception hook function.
624 *
625 * Called just after the exception context has been initialized.
626 *
627 * This function will be run on the ISR stack.
628 *
629 * This function must run to completion.
630 *
631 * It is called without any Task or Swi scheduling protection
632 * and therefore can not call any functions that may cause a Swi or Task
633 * scheduling operation (Swi_post(), Semaphore_post(), Event_post(), etc).
634 */
635 config ExceptionHookFuncPtr sErrorExcHookFunc[];
636
637 /*!
638 * @_nodoc
639 * ======== irqStackSection ========
640 * Memory section used for IRQ stack on each core
641 * Default is null.
642 */
643 metaonly config String irqStackSection = null;
644
645 /*!
646 * ======== A_badSGIIntNum ========
647 * Assert raised when an interrupt number >= 16 is
648 * passed to Hwi_raiseSGI() function.
649 */
650 config xdc.runtime.Assert.Id A_badSGIIntNum = {
651 msg: "A_badSGIIntNum: SGI intNum should be <= 15."
652 };
653
654 /*!
655 * Error raised when an attempt is made to create a Hwi
656 * that has already been created.
657 */
658 config Error.Id E_alreadyDefined = {
659 msg: "E_alreadyDefined: Hwi already defined, intnum: %d"
660 };
661
662 /*!
663 * Error raised when Hwi handle referenced in Hwi_delete()
664 * is not found in the Hwi dispatch table
665 */
666 config Error.Id E_handleNotFound = {
667 msg: "E_handleNotFound: Hwi handle not found: 0x%x"
668 };
669
670 /*!
671 * Error raised when an undefined interrupt has fired.
672 */
673 config Error.Id E_undefined = {
674 msg: "E_undefined: Hwi undefined, intnum: %d"
675 };
676
677 /*!
678 * Error raised if an attempt is made to create a Hwi
679 * with an interrupt number greater than Hwi_NUM_INTERRUPTS - 1.
680 */
681 config Error.Id E_badIntNum = {
682 msg: "E_badIntNum, intnum: %d is out of range"
683 };
684
685 /*!
686 * Error raised when an exception occurs.
687 */
688 config Error.Id E_exception = {
689 msg: "E_exception: A hardware exception has occurred."
690 };
691
692 /*!
693 * Issued just prior to Hwi function invocation (with interrupts disabled)
694 */
695 config Log.Event LM_begin = {
696 mask: Diags.USER1 | Diags.USER2,
697 msg: "LM_begin: hwi: 0x%x, func: 0x%x, preThread: %d, intNum: %d, irp: 0x%x"
698 };
699
700 /*!
701 * Issued just after return from Hwi function (with interrupts disabled)
702 */
703 config Log.Event LD_end = {
704 mask: Diags.USER2,
705 msg: "LD_end: hwi: 0x%x"
706 };
707
708
709
710
711 /*!
712 * ======== disable ========
713 * Globally disable interrupts.
714 *
715 * Hwi_disable globally disables hardware interrupts and returns an
716 * opaque key indicating whether interrupts were globally enabled or
717 * disabled on entry to Hwi_disable().
718 * The actual value of the key is target/device specific and is meant
719 * to be passed to Hwi_restore().
720 *
721 * Call Hwi_disable before a portion of a function that needs
722 * to run without interruption. When critical processing is complete, call
723 * Hwi_restore or Hwi_enable to reenable hardware interrupts.
724 *
725 * Servicing of interrupts that occur while interrupts are disabled is
726 * postponed until interrupts are reenabled. However, if the same type
727 * of interrupt occurs several times while interrupts are disabled,
728 * the interrupt's function is executed only once when interrupts are
729 * reenabled.
730 *
731 * A context switch can occur when calling Hwi_enable or Hwi_restore if
732 * an enabled interrupt occurred while interrupts are disabled.
733 *
734 * Hwi_disable may be called from main(). However, since Hwi interrupts
735 * are already disabled in main(), such a call has no effect.
736 *
737 * @a(NOTE)
738 * Disables only IRQ interrupts
739 *
740 * @a(constraints)
741 * If a Task switching API such as
742 * {@link ti.sysbios.knl.Semaphore#pend Semaphore_pend()},
743 * {@link ti.sysbios.knl.Semaphore#post Semaphore_post()},
744 * {@link ti.sysbios.knl.Task#sleep Task_sleep()}, or
745 * {@link ti.sysbios.knl.Task#yield Task_yield()}
746 * is invoked which results in a context switch while
747 * interrupts are disabled, an embedded call to
748 * {@link #enable Hwi_enable} occurs
749 * on the way to the new thread context which unconditionally re-enables
750 * interrupts. Interrupts will remain enabled until a subsequent
751 * {@link #disable Hwi_disable}
752 * invocation.
753 *
754 * Swis always run with interrupts enabled.
755 * See {@link ti.sysbios.knl.Swi#post Swi_post()} for a discussion Swis and
756 * interrupts.
757 *
758 * @b(returns) opaque key for use by Hwi_restore()
759 */
760 @Macro
761 override UInt disable();
762
763 /*!
764 * ======== enable ========
765 *
766 * @a(NOTE)
767 * Enables only IRQ interrupts
768 */
769 @Macro
770 override UInt enable();
771
772 /*!
773 * ======== restore ========
774 *
775 * @a(NOTE)
776 * Restores only IRQ interrupts
777 */
778 @Macro
779 override Void restore(UInt key);
780
781 /*!
782 * ======== enableIRQ ========
783 * Enable IRQ interrupts.
784 *
785 * @a(NOTE)
786 * Same as Hwi_enable()
787 *
788 * @b(returns) previous IRQ interrupt enable/disable state
789 */
790 @Macro
791 UInt enableIRQ();
792
793 /*!
794 * ======== disableIRQ ========
795 * Disable IRQ interrupts.
796 *
797 * @a(NOTE)
798 * Same as Hwi_disable()
799 *
800 * @b(returns) previous IRQ interrupt enable/disable state
801 */
802 @Macro
803 UInt disableIRQ();
804
805 /*!
806 * ======== restoreIRQ ========
807 * Restore IRQ interrupts.
808 *
809 * @a(NOTE)
810 * Same as Hwi_restore()
811 *
812 * @param(key) enable/disable state to restore
813 */
814 @Macro
815 Void restoreIRQ(UInt key);
816
817 /*!
818 * @_nodoc
819 * ======== disableFxn ========
820 * function call implementation
821 */
822 UInt disableFxn();
823
824 /*!
825 * @_nodoc
826 * ======== enableFxn ========
827 * function call implementation
828 */
829 UInt enableFxn();
830
831 /*!
832 * @_nodoc
833 * ======== restoreFxn ========
834 * function call implementation
835 */
836 Void restoreFxn(UInt key);
837
838 /*!
839 * ======== getHandle ========
840 * Returns Hwi_Handle associated with intNum
841 *
842 * @param(intNum) interrupt number
843 */
844 Handle getHandle(UInt intNum);
845
846 /*!
847 * @_nodoc
848 * ======== init ========
849 * assembly code mode registers setup
850 */
851 Void init();
852
853 /*!
854 * @_nodoc
855 * ======== initIntControllerCoreX ========
856 */
857 Void initIntControllerCoreX();
858
859 /*!
860 * ======== intAffinity ========
861 * SMP Interrupt affinity mappings
862 *
863 * In SMP mode, this array maps the interrupt number to the
864 * core it is to be tied to. By default, all interrupts
865 * are routed to Core0.
866 *
867 * For example, to route Timer 1 (from the ti.sysbios.timers.dmtimer.Timer)
868 * module interrupt to core 1 rather than core 0, add the following to
869 * your config file:
870 *
871 * @p(code)
872 * var Hwi = xdc.useModule('ti.sysbios.family.arm.gicv3.Hwi');
873 * Hwi.intAffinity[<intNum>] = 1;
874 * @p
875 *
876 * @a(constraints)
877 * Interrupt numbers below 32 are ignored. This config param only
878 * allows routing interrupt numbers greater than or equal to #32.
879 */
880 metaonly config UInt8 intAffinity[];
881
882 /*!
883 * ======== intRouting ========
884 * SMP Interrupt routing mappings
885 *
886 * In SMP mode, this array maps the interrupt number to the
887 * core or cores it is to be tied to. By default, all interrupts
888 * are routed to Core0.
889 *
890 * For example, to route Timer 1 (from the ti.sysbios.timers.dmtimer.Timer)
891 * module interrupt to core 1 rather than core 0, add the following to
892 * your config file:
893 *
894 * @p(code)
895 * var Hwi = xdc.useModule('ti.sysbios.family.arm.gicv3.Hwi');
896 * Hwi.intRouting[<intNum>] = {aff0: 1, aff1: 0,
897 routingMode: Hwi.RoutingMode_NODE};
898 * @p
899 *
900 * @a(constraints)
901 * Interrupt numbers below 32 are ignored. This config param only
902 * allows routing interrupt numbers greater than or equal to #32.
903 */
904 metaonly config IntAffinity intRouting[];
905
906 /*!
907 * @_nodoc
908 * ======== raiseSGI ========
909 * Generate an SGI interrupt and route it to CPUs specified by the
910 * affinity field.
911 *
912 * @param(affinity) If the "routingMode" field is set to
913 * Hwi_RoutingMode_ANY, then the interrupt is routed to
914 * all cores except this core. Else, if "routingMode"
915 * is set to Hwi_RoutingMode_NODE, the affinity fields
916 * are used to determine which cores the interrupt
917 * should be routed to. "aff0" field is a bit mapped
918 * target list identifying all cores within the cluster
919 * identified by "aff1".
920 * @param(intNum) Interrupt number
921 */
922 Void raiseSGI(SgiIntAffinity affinity, UInt intNum);
923
924 /*!
925 * ======== setPriority ========
926 * Set an interrupt's priority.
927 *
928 * Not an instance function so that it can be used
929 * with non-dispatched interrupts.
930 *
931 * @param(intNum) ID of interrupt
932 * @param(priority) priority
933 */
934 Void setPriority(UInt intNum, UInt priority);
935
936 instance:
937
938 /*!
939 * ======== type ========
940 * Interrupt type (IRQ/FIQ). Default is IRQ.
941 *
942 * @a(NOTE)
943 * FIQs are only supported when {@link #enableSecureMode} is set to
944 * true.
945 */
946 config Type type = Type_IRQ;
947
948 /*!
949 * ======== triggerSensitivity ========
950 * Set an interrupt's trigger sensitivity
951 *
952 * 2-bit field that configures the trigger sensitivity of an
953 * interrupt.
954 *
955 * On the Cortex-A15, all software generated interrupts (SGI)
956 * are edge-triggered (b10) and all private peripheral interrupts (PPI)
957 * are level-sensitive (b01). The trigger sensitivity of these
958 * interrupt types cannot be changed.
959 *
960 * For shared peripheral interrupts (SPI), the LSB of the bit-pair
961 * is read only and is always 1. The MSB of the bit-pair can be
962 * altered to change trigger sensitivity.
963 *
964 * Possible bit-pair encodings for Cortex-A15 SPIs:
965 * b01 Interrupt is active-High level-sensitive (default)
966 * b11 Interrupt is rising edge-sensitive
967 *
968 * For more information please refer section 4.3.13 on
969 * Interrupt Configuration Registers (GICD_ICFGRn) in
970 * ARM Generic Interrupt Controller Architecure Spec v2.0
971 *
972 * @a(constraints)
973 * This Hwi param is ignored if
974 * {@link ti.sysbios.family.arm.v8a.Core#bootMaster Core.bootMaster} is
975 * set to false.
976 */
977 config UInt triggerSensitivity = ~(0);
978
979 /*!
980 * ======== Interrupt priority ========
981 * Hwi instance interrupt priority.
982 *
983 * Valid priorities are device dependent and their
984 * nesting behaviors depend on the {@link #BPR} setting.
985 *
986 * See the ARM GIC Architecture Specification v2.0 document for more
987 * details.
988 */
989 override config Int priority = -1;
990
991 /*! The interrupt controller is designed for priority based interrupts */
992 override config IHwi.MaskingOption maskSetting = IHwi.MaskingOption_LOWER;
993
994 /*!
995 * ======== reconfig ========
996 * Reconfigure a dispatched interrupt.
997 */
998 Void reconfig(FuncPtr fxn, const Params *params);
999
1000 internal:
1001
1002 struct GicRegisterMap {
1003 volatile Gicr *gicr;
1004 volatile Gics *gics;
1005 };
1006
1007 config GicRegisterMap gicMap[];
1008
1009 1010 1011
1012 config UInt NUM_GICD_ENABLE_REGS;
1013
1014 config SizeT isrStackSize;
1015
1016 1017 1018 1019 1020
1021 config Bool initGicd = true;
1022
1023 1024 1025 1026 1027 1028 1029 1030 1031
1032 metaonly Bool inUseMeta(UInt intNum);
1033
1034 1035 1036 1037 1038 1039
1040 config UInt (*swiDisable)();
1041 config Void (*swiRestoreHwi)(UInt);
1042 config UInt (*taskDisable)();
1043 config Void (*taskRestoreHwi)(UInt);
1044
1045 1046 1047 1048
1049 Void dispatchIRQ(Bool usingEL0Stack);
1050
1051 1052 1053 1054
1055 Void dispatchIRQC(Irp irp, Bool rootISR, Char *taskSP);
1056
1057 /*!
1058 * ======== excDumpContext ========
1059 */
1060 Void excDumpContext();
1061
1062 1063 1064
1065 Void excHandler(UInt64 *excStack, ExcType excType);
1066
1067 1068 1069
1070 Void initIntControllerCore0();
1071
1072 1073 1074 1075
1076 Void initStacks(Ptr hwiStack);
1077
1078 1079 1080 1081
1082 Void nonPluggedHwiHandler();
1083
1084 1085 1086 1087
1088 Int postInit(Object *hwi, Error.Block *eb);
1089
1090 /*!
1091 * const array to hold all HookSet objects.
1092 */
1093 config HookSet hooks[length] = [];
1094
1095 /*! Meta World Only Hwi Configuration Object. */
1096 metaonly struct InterruptObj {
1097 Bool used;
1098 FuncPtr fxn;
1099 };
1100
1101 /*!
1102 * Meta-only array of interrupt objects.
1103 * This meta-only array of Hwi config objects is initialized
1104 * in Hwi.xs:module$meta$init().
1105 */
1106 metaonly config InterruptObj interrupt[];
1107
1108 /*!
1109 * GIC Distributor base address
1110 */
1111 metaonly config Ptr gicdBaseAddress;
1112
1113 /*!
1114 * GIC Redistributor base address
1115 */
1116 metaonly config Ptr gicrBaseAddress;
1117
1118 struct Instance_State {
1119 Type type;
1120 UInt priority;
1121 UArg arg;
1122 FuncPtr fxn;
1123 Irp irp;
1124 Ptr hookEnv[];
1125 UInt triggerSensitivity;
1126 };
1127
1128 struct Module_State {
1129 Char *isrStack[];
1130 Char hwiStack[][];
1131 UInt irp[];
1132 Char *taskSP[];
1133 Ptr isrStackSize;
1134 1135 1136 1137 1138 1139
1140 UInt32 iser[32];
1141 UInt32 icfgr[];
1142 UInt spuriousInts;
1143 UInt lastSpuriousInt;
1144 Ptr isrStackBase;
1145 Handle dispatchTable[];
1146 volatile UInt curIntId;
1147 IntAffinity intAffinity[];
1148 Bool excActive[];
1149 ExcContext *excContext[];
1150 };
1151 }