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
36 package ti.sysbios.family.arm.gic;
37
38 import xdc.rov.ViewInfo;
39
40 import xdc.runtime.Diags;
41 import xdc.runtime.Log;
42 import xdc.runtime.Error;
43
44 import ti.sysbios.BIOS;
45 import ti.sysbios.interfaces.IHwi;
46
47 /*!
48 * ======== Hwi ========
49 * Hardware Interrupt Support Module.
50 *
51 * This Hwi module provides ARM cortex-A Generic Interrupt Controller(GIC) v2.0
52 * specific implementations and extensions of the APIs defined in
53 * {@link ti.sysbios.interfaces.IHwi IHwi}.
54 *
55 * The GIC is logically partitioned into 2 blocks, the Distributor block
56 * and CPU interface block. The Distributor block interfaces with the interrupt
57 * sources, prioritizes interrupts and distributes them to the CPU interface
58 * block. The CPU interface block connects to the processors in the system
59 * and is responsible for priority masking and preemption handling for
60 * the processor it is connected to.
61 *
62 * The GIC can implement up to 8 CPU interfaces with each CPU interface
63 * being able to see up to 1020 interrupts. The GIC assigns interrupt ID
64 * numbers 0-1019 as follows:
65 * - Interrupt numbers 0-31 are used for interrupts private to a
66 * CPU interface. These private interrupts are banked in the Distributor.
67 * - Banked interrupt number 0-15 are used for Software Generated Interrupts
68 * or SGIs.
69 * - Banked interrupt number 16-31 are used for Private Peripheral Interrupts
70 * or PPIs.
71 * - Interrupt numbers 32-1019 are used for Shared Peripheral Interrupts
72 * or SPIs.
73 * - Interrupt numbers 1020-1023 are reserved.
74 *
75 * @a(NOTE)
76 * In the OMAP5 SoC Technical Reference Manual, the MPU IRQs 0 to N map to
77 * GIC interrupt numbers 32 to (N+32) where (N+1) is the total number of
78 * Shared Peripheral Interrupts implemented.
79 * On OMAP5430, MPU IRQ 0 to 159 maps to GIC interrupt number 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. SYS/BIOS only supports non-secure mode and hence
85 * only Group 1 interrupts can be controlled using this module.
86 *
87 * @a(INTERRUPT PRIORITIES)
88 * In general GIC supports priority values 0 thru 255.
89 *
90 * In practice valid priority values depend on the particular device used,
91 * security mode and the Binary Point Register (see {@link #BPR}) value.
92 *
93 * The device implementation and security mode decide the number of priority
94 * bits that are implemented (see {@link #NUM_PRIORITY_BITS}). Group 0
95 * interrupts always implemente one more priority bit than Group 1 interrupts.
96 *
97 * In GIC, interrupts with lower priority numbers have higher priority.
98 *
99 * @a(NOTE)
100 * In this Hwi module implementation, the instance config parameter value
101 * {@link #MaskingOption_LOWER} is equivalent to {@link #MaskingOption_SELF}.
102 * Statically configuring a Hwi object's {@link #Params.maskSetting} to
103 * {@link #MaskingOption_LOWER} will result in the generation of a benign
104 * build warning. Dynamic usages of {@link #MaskingOption_LOWER} will be
105 * silently converted to {@link #MaskingOption_SELF}.
106 *
107 * @a(NOTE)
108 * This module is written for GIC v2.0, however it is backwards compatible
109 * with GIC v1.0
110 */
111
112 @Template("./Hwi.xdt")
113 @ModuleStartup
114
115 module Hwi inherits ti.sysbios.interfaces.IHwi
116 {
117
118
119
120 /*!
121 * Number of interrupts implemented in GIC
122 *
123 * On OMAP543x GIC implements 192 interrupts.
124 *
125 * See the OMAP543x_ES1 Technical Reference Manual pg 5280 for more
126 * details.
127 */
128 config UInt NUM_INTERRUPTS;
129
130 /*!
131 * Number of Priority bits implemented.
132 *
133 * On OMAP543x running in non-secure mode, only most significant 4
134 * priority bits are available for use. The least significant 4 bits
135 * are always 0.
136 */
137 config UInt NUM_PRIORITY_BITS;
138
139 /*!
140 * Minimum Interrupt Priority.
141 */
142 config UInt MIN_INT_PRIORITY;
143
144 /*!
145 * Default Interrupt Priority.
146 *
147 * Set to one level higher than minimum supported priority.
148 */
149 config UInt DEFAULT_INT_PRIORITY;
150
151 /*!
152 * GIC Binary Point Register value
153 *
154 * Defines the point at which the priority value fields split into
155 * two parts, the group priority field and the sub-priority field.
156 *
157 * The group priority field determines interrupt preemption in case
158 * of nested interrupts whereas sub-priority field is used to determine
159 * priority within a group when multiple interrrupts belonging to the
160 * same group are pending.
161 *
162 * @a(constraints)
163 * SYS/BIOS currently only supports non-secure mode of operation. In
164 * this mode, the minimum value that can be assigned to BPR is 3.
165 */
166 config UInt BPR = 3;
167
168 /*! @_nodoc
169 * Interrupt type. IRQ or FIQ
170 */
171 enum Type {
172 Type_IRQ, /*! IRQ interrupt. */
173 Type_FIQ /*! FIQ interrupt. */
174 };
175
176
177
178 /*! Hwi vector function type definition. */
179 typedef Void (*VectorFuncPtr)(void);
180
181 /*!
182 * ======== BasicView ========
183 * @_nodoc
184 */
185 metaonly struct BasicView {
186 Ptr halHwiHandle;
187 String label;
188 Int intNum;
189 String absolutePriority;
190 UInt relativeGrpPriority;
191 UInt relativeSubPriority;
192 String fxn;
193 UArg arg;
194 };
195
196 /*!
197 * ======== DetailedView ========
198 * @_nodoc
199 */
200 metaonly struct DetailedView {
201 Ptr halHwiHandle;
202 String label;
203 Int intNum;
204 String absolutePriority;
205 UInt relativeGrpPriority;
206 UInt relativeSubPriority;
207 String fxn;
208 UArg arg;
209 Ptr irp;
210 Bool enabled;
211 Bool pending;
212 String triggerSensitivity;
213 String targetProcList;
214 };
215
216 /*!
217 * ======== ModuleView ========
218 * @_nodoc
219 */
220 metaonly struct ModuleView {
221 String options[4];
222 UInt spuriousInterrupts;
223 UInt lastSpuriousInterrupt;
224 SizeT hwiStackPeak;
225 SizeT hwiStackSize;
226 Ptr hwiStackBase;
227 };
228
229 /*!
230 * ======== rovViewInfo ========
231 * @_nodoc
232 */
233 @Facet
234 metaonly config ViewInfo.Instance rovViewInfo =
235 ViewInfo.create({
236 viewMap: [
237 [
238 'Basic',
239 {
240 type: ViewInfo.INSTANCE,
241 viewInitFxn: 'viewInitBasic',
242 structName: 'BasicView'
243 }
244 ],
245 [
246 'Detailed',
247 {
248 type: ViewInfo.INSTANCE,
249 viewInitFxn: 'viewInitDetailed',
250 structName: 'DetailedView'
251 }
252 ],
253 [
254 'Module',
255 {
256 type: ViewInfo.MODULE,
257 viewInitFxn: 'viewInitModule',
258 structName: 'ModuleView'
259 }
260 ]
261 ]
262 });
263
264 /*!
265 * Generic Interrupt Controller Distributor. Symbol "Hwi_gicd" is
266 * a physical device
267 */
268 struct Gicd {
269 UInt32 CTLR; /*! 0x000 Distributor Control Register */
270 UInt32 TYPER; /*! 0x004 Interrupt Controller Type Register */
271 UInt32 IIDR; /*! 0x008 Distributor Implementor Id Register */
272 UInt32 hole0[29]; /*! 0x00C-0x07C */
273 UInt32 IGROUPR[32]; /*! 0x080 Interrupt Group Registers */
274 UInt32 ISENABLER[32]; /*! 0x100 Interrupt Set-Enable Registers */
275 UInt32 ICENABLER[32]; /*! 0x180 Interrupt Clear-Enable Registers */
276 UInt32 ISPENDR[32]; /*! 0x200 Interrupt Set-Pending Registers */
277 UInt32 ICPENDR[32]; /*! 0x280 Interrupt Clear-Pending Registers */
278 UInt32 ISACTIVER[32]; /*! 0x300 Interrupt Set-Active Registers */
279 UInt32 ICACTIVER[32]; /*! 0x380 Interrupt Clear-Active Registers */
280 UInt32 IPRIORITYR[255]; /*! 0x400 Interrupt Priority Registers */
281 UInt32 hole1[1]; /*! 0x7FC */
282 UInt32 ITARGETSR[255]; /*! 0x800 Interrupt Processor Targets Register */
283 UInt32 hole2[1]; /*! 0xBFC */
284 UInt32 ICFGR[64]; /*! 0xC00 Interrupt Configuration Registers */
285 UInt32 PPISR; /*! 0xD00 PPI Status Register */
286 UInt32 SPISR[7]; /*! 0xD04 SPI Status Registers */
287 UInt32 hole3[120]; /*! 0xD20-0xEFC */
288 UInt32 SGIR; /*! 0xF00 Software Generated Interrupt
289 Registers */
290 UInt32 hole4[3]; /*! 0xF04-0xF0C */
291 UInt32 CPENDSGIR[4]; /*! 0xF10 SGI Clear-Pending Registers */
292 UInt32 SPENDSGIR[4]; /*! 0xF20 SGI Set-Pending Registers */
293 UInt32 hole5[40]; /*! 0xF30-0xFCC */
294 UInt32 PIDR4; /*! 0xFD0 Peripheral ID4 Register */
295 UInt32 PIDR5; /*! 0xFD4 Peripheral ID5 Register */
296 UInt32 PIDR6; /*! 0xFD8 Peripheral ID6 Register */
297 UInt32 PIDR7; /*! 0xFDC Peripheral ID7 Register */
298 UInt32 PIDR0; /*! 0xFE0 Peripheral ID0 Register */
299 UInt32 PIDR1; /*! 0xFE4 Peripheral ID1 Register */
300 UInt32 PIDR2; /*! 0xFE8 Peripheral ID2 Register */
301 UInt32 PIDR3; /*! 0xFEC Peripheral ID3 Register */
302 UInt32 CIDR0; /*! 0xFF0 Component ID0 Register */
303 UInt32 CIDR1; /*! 0xFF4 Component ID1 Register */
304 UInt32 CIDR2; /*! 0xFF8 Component ID2 Register */
305 UInt32 CIDR3; /*! 0xFFC Component ID3 Register */
306 };
307
308 extern volatile Gicd gicd;
309
310 /*!
311 * Generic Interrupt Controller CPU Interface. Symbol "Hwi_gicc" is
312 * a physical device.
313 */
314 struct Gicc {
315 UInt32 CTLR; /*! 0x0000 CPU Interface Control Register */
316 UInt32 PMR; /*! 0x0004 Interrupt Priority Mask Register */
317 UInt32 BPR; /*! 0x0008 Binary Point Register */
318 UInt32 IAR; /*! 0x000C Interrupt Acknowledge Register */
319 UInt32 EOIR; /*! 0x0010 End Of Interrupt Register */
320 UInt32 RPR; /*! 0x0014 Running Priority Register */
321 UInt32 HPPIR; /*! 0x0018 Highest Priority Pending Interrupt
322 Register */
323 UInt32 ABPR; /*! 0x001C Aliased Binary Point Register */
324 UInt32 AIAR; /*! 0x0020 Aliased IAR Register */
325 UInt32 AEOIR; /*! 0x0024 Aliased EOI Register */
326 UInt32 AHPPIR; /*! 0x0028 Aliased HPPI Register */
327 UInt32 hole0[41]; /*! 0x002C-0x00CC */
328 UInt32 APR0; /*! 0x00D0 Active Priority Register */
329 UInt32 hole1[3]; /*! 0x00D4-0x00DC */
330 UInt32 NSAPR0; /*! 0x00E0 Non-secure Active Priority Register */
331 UInt32 hole2[6]; /*! 0x00E4-0x00F8 */
332 UInt32 IIDR; /*! 0x00FC CPU Interface Id Register */
333 UInt32 hole3[960]; /*! 0x0100-0x0FFC */
334 UInt32 DIR; /*! 0x1000 Deactivate Interrupt Register */
335 };
336
337 extern volatile Gicc gicc;
338
339
340
341 /*! Reset Handler. Default is _c_int00 */
342 metaonly config VectorFuncPtr resetFunc;
343
344 /*!
345 * Undefined instruction exception handler.
346 * Default is an internal exception handler.
347 */
348 metaonly config VectorFuncPtr undefinedInstFunc;
349
350 /*!
351 * SVC Handler. Supervisor Call exception handler.
352 * (previously called Software Interrupt or SWI)
353 * Default is an internal exception handler.
354 */
355 metaonly config VectorFuncPtr svcFunc;
356
357 /*!
358 * Prefetch abort exception handler.
359 * Default is an internal exception handler.
360 */
361 metaonly config VectorFuncPtr prefetchAbortFunc;
362
363 /*!
364 * Data abort exception handler.
365 * Default is an internal exception handler.
366 */
367 metaonly config VectorFuncPtr dataAbortFunc;
368
369 /*!
370 * Reserved exception handler.
371 * Default is an internal exception handler.
372 */
373 metaonly config VectorFuncPtr reservedFunc;
374
375 /*! IRQ interrupt handler.
376 * Default is internal IRQ dispatcher
377 */
378 metaonly config VectorFuncPtr irqFunc;
379
380 /*! FIQ interrupt handler.
381 * Default is internal exception handler.
382 */
383 metaonly config VectorFuncPtr fiqFunc;
384
385 /*!
386 * Error raised when an attempt is made to create a Hwi
387 * that has already been created.
388 */
389 config Error.Id E_alreadyDefined = {
390 msg: "E_alreadyDefined: Hwi already defined, intnum: %d"
391 };
392
393 /*!
394 * Error raised when Hwi handle referenced in Hwi_delete()
395 * is not found in the Hwi dispatch table
396 */
397 config Error.Id E_handleNotFound = {
398 msg: "E_handleNotFound: Hwi handle not found: 0x%x"
399 };
400
401 /*!
402 * Error raised when an undefined interrupt has fired.
403 */
404 config Error.Id E_undefined = {
405 msg: "E_undefined: Hwi undefined, intnum: %d"
406 };
407
408 /*!
409 * Error raised if an attempt is made to create a Hwi
410 * with an interrupt number greater than Hwi_NUM_INTERRUPTS - 1.
411 */
412 config Error.Id E_badIntNum = {
413 msg: "E_badIntNum, intnum: %d is out of range"
414 };
415
416 /*!
417 * Issued just prior to Hwi function invocation (with interrupts disabled)
418 */
419 config Log.Event LM_begin = {
420 mask: Diags.USER1 | Diags.USER2,
421 msg: "LM_begin: hwi: 0x%x, func: 0x%x, preThread: %d, intNum: %d, irp: 0x%x"
422 };
423
424 /*!
425 * Issued just after return from Hwi function (with interrupts disabled)
426 */
427 config Log.Event LD_end = {
428 mask: Diags.USER2,
429 msg: "LD_end: hwi: 0x%x"
430 };
431
432
433
434
435 /*!
436 * ======== disable ========
437 */
438 @Macro
439 override UInt disable();
440
441 /*!
442 * ======== enable ========
443 */
444 @Macro
445 override UInt enable();
446
447 /*!
448 * ======== restore ========
449 */
450 @Macro
451 override Void restore(UInt key);
452
453 /*!
454 * ======== getHandle ========
455 * Returns Hwi_Handle associated with intNum
456 *
457 * @param(intNum) interrupt number
458 */
459 @DirectCall
460 Handle getHandle(UInt intNum);
461
462 /*!
463 * ======== setPriority ========
464 * Set an interrupt's priority.
465 *
466 * Not an instance function so that it can be used
467 * with non-dispatched interrupts.
468 *
469 * @param(intNum) ID of interrupt
470 * @param(priority) priority
471 */
472 @DirectCall
473 Void setPriority(UInt intNum, UInt priority);
474
475 instance:
476
477 /*! @_nodoc
478 * Interrupt type (IRQ/FIQ). Default is IRQ.
479 */
480 config Type type = Type_IRQ;
481
482 /*!
483 * ======== triggerSensitivity ========
484 * Set an interrupt's trigger sensitivity
485 *
486 * 2-bit field that configures the trigger sensitivity of an
487 * interrupt.
488 *
489 * On the Cortex-A15, all software generated interrupts (SGI)
490 * are edge-triggered (b10) and all private peripheral interrupts (PPI)
491 * are level-sensitive (b01). The trigger sensitivity of these
492 * interrupt types cannot be changed.
493 *
494 * For shared peripheral interrupts (SPI), the LSB of the bit-pair
495 * is read only and is always 1. The MSB of the bit-pair can be
496 * altered to change trigger sensitivity.
497 *
498 * Possible bit-pair encodings for Cortex-A15 SPIs:
499 * b01 Interrupt is active-High level-sensitive (default)
500 * b11 Interrupt is rising edge-sensitive
501 *
502 * For more information please refer section 4.3.13 on
503 * Interrupt Configuration Registers (GICD_ICFGRn) in
504 * ARM Generic Interrupt Controller Architecure Spec v2.0
505 */
506 config UInt triggerSensitivity = 0x1;
507
508 /*!
509 * ======== targetProcList ========
510 * Set an interrupt's target processor list.
511 *
512 * This is an 8-bit CPU targets field that stores the list of target
513 * processors for the interrupt. That is, it holds the list of CPU
514 * interfaces to which the GIC Distributor will forward the interrupt
515 * if it is asserted and has sufficient priority.
516 *
517 * Each bit in targetProcList refers to the corresponding processor.
518 * For instance, a value of 0x3 means the pending interrupt is
519 * forwarded to processor 0 and 1.
520 *
521 * For more information please refer section 4.3.12 on
522 * Interrupt Processor Targets Registers (GICD_ITARGETSRn) in
523 * ARM Generic Interrupt Controller Architecure Spec v2.0
524 *
525 * @a(NOTE)
526 * Target processor list is read-only for the first 32 interrupts.
527 * Therefore, this field will have no effect for interrupt numbers
528 * less than 32 (intNum 0-31).
529 */
530 config UInt targetProcList = 0x01;
531
532 /*!
533 * ======== Interrupt priority ========
534 * Hwi instance interrupt priority.
535 *
536 * Valid priorities are device dependent and their
537 * nesting behaviors depend on the {@link #BPR} setting.
538 *
539 * See the ARM GIC Architecture Specification v2.0 document for more
540 * details.
541 */
542 override config Int priority = -1;
543
544 /*! The interrupt controller is designed for priority based interrupts */
545 override config IHwi.MaskingOption maskSetting = IHwi.MaskingOption_LOWER;
546
547 /*!
548 * ======== reconfig ========
549 * Reconfigure a dispatched interrupt.
550 */
551 @DirectCall
552 Void reconfig(FuncPtr fxn, const Params *params);
553
554 internal:
555
556 /*!
557 * ======== inUseMeta ========
558 * @_nodoc
559 * Check for Hwi already in use.
560 * For internal SYS/BIOS use only.
561 * Should be called prior to any internal Hwi.create().
562 *
563 * @param(intNum) interrupt number
564 */
565 metaonly Bool inUseMeta(UInt intNum);
566
567 568 569 570 571 572
573 config UInt (*swiDisable)();
574 config Void (*swiRestoreHwi)(UInt);
575 config UInt (*taskDisable)();
576 config Void (*taskRestoreHwi)(UInt);
577
578 579 580 581
582 Int postInit(Object *hwi, Error.Block *eb);
583
584 585 586
587 Void initIntController();
588
589
590 Void init();
591
592
593 Void dispatch();
594
595
596 Void dispatchC(Irp irp);
597
598
599 Void nonPluggedHwiHandler(UArg arg);
600
601 /*!
602 * const array to hold all HookSet objects.
603 */
604 config HookSet hooks[length] = [];
605
606 /*! Meta World Only Hwi Configuration Object. */
607 metaonly struct InterruptObj {
608 Bool used;
609 FuncPtr fxn;
610 };
611
612 /*!
613 * Meta-only array of interrupt objects.
614 * This meta-only array of Hwi config objects is initialized
615 * in Hwi.xs:module$meta$init().
616 */
617 metaonly config InterruptObj interrupt[];
618
619 /*!
620 * GIC Distributor base address
621 */
622 metaonly config Ptr gicdBaseAddress;
623
624 /*!
625 * GIC cpu interface base address
626 */
627 metaonly config Ptr giccBaseAddress;
628
629 struct Instance_State {
630 Type type;
631 UInt priority;
632 UArg arg;
633 FuncPtr fxn;
634 Irp irp;
635 Ptr hookEnv[];
636 UInt triggerSensitivity;
637 UInt targetProcList;
638 };
639
640 struct Module_State {
641 Char *taskSP;
642
643 Char *isrStack;
644 UInt32 iser[32];
645 UInt32 icfgr[];
646 UInt32 itargetsr[];
647 UInt spuriousInts;
648 UInt lastSpuriousInt;
649 UInt irp;
650 Ptr isrStackBase;
651 Ptr isrStackSize;
652 Hwi.Object nonPluggedHwi;
653 Handle dispatchTable[];
654 volatile UInt curIntId;
655 };
656 }
657