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.a8.intcps;
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 family-specific implementations of the
52 * APIs defined in {@link ti.sysbios.interfaces.IHwi IHwi}.
53 *
54 * Additional ARM device-specific APIs are also provided.
55 *
56 * @a(NOTE)
57 * In this Hwi module implementation, the instance config parameter value
58 * {@link #MaskingOption_LOWER} is equivalent to {@link #MaskingOption_SELF}.
59 * Statically configuring a Hwi object's {@link #Params.maskSetting} to
60 * {@link #MaskingOption_LOWER} will result in the generation of a benign
61 * build warning. Dynamic usages of {@link #MaskingOption_LOWER} will be
62 * silently converted to {@link #MaskingOption_SELF}.
63 *
64 */
65
66 @Template("./Hwi.xdt")
67 @ModuleStartup
68 @InstanceInitStatic
69
70 module Hwi inherits ti.sysbios.interfaces.IHwi
71 {
72
73
74
75 /*! intcps supports 128 interrupts. */
76 const Int NUM_INTERRUPTS = 128;
77
78 /*!
79 * The device-specific number of priorities supported.
80 *
81 * The actual number supported is device specific and provided by
82 * the catalog device specification.
83 */
84 config Int NUM_PRIORITIES;
85
86
87
88 /*! Hwi vector function type definition. */
89 typedef Void (*VectorFuncPtr)(void);
90
91 /*!
92 * ======== BasicView ========
93 * @_nodoc
94 */
95 metaonly struct BasicView {
96 Ptr halHwiHandle;
97 String label;
98 Int intNum;
99 UInt priority;
100 String fxn;
101 UArg arg;
102 };
103
104 /*!
105 * ======== DetailedView ========
106 * @_nodoc
107 */
108 metaonly struct DetailedView {
109 Ptr halHwiHandle;
110 String label;
111 Int intNum;
112 UInt priority;
113 String fxn;
114 UArg arg;
115 Ptr irp;
116 Bool enabled;
117 Bool pending;
118 };
119
120 /*!
121 * ======== ModuleView ========
122 * @_nodoc
123 */
124 metaonly struct ModuleView {
125 String options[4];
126 UInt spuriousInterrupts;
127 UInt lastSpuriousInterrupt;
128 String hwiStackPeak;
129 SizeT hwiStackSize;
130 Ptr hwiStackBase;
131 };
132
133 /*!
134 * ======== rovViewInfo ========
135 * @_nodoc
136 */
137 @Facet
138 metaonly config ViewInfo.Instance rovViewInfo =
139 ViewInfo.create({
140 viewMap: [
141 ['Basic', {type: ViewInfo.INSTANCE, viewInitFxn: 'viewInitBasic', structName: 'BasicView'}],
142 ['Detailed', {type: ViewInfo.INSTANCE, viewInitFxn: 'viewInitDetailed', structName: 'DetailedView'}],
143 ['Module', {type: ViewInfo.MODULE, viewInitFxn: 'viewInitModule', structName: 'ModuleView'}]
144 ]
145 });
146
147 /*! Interrupt type. IRQ or FIQ */
148 enum Type {
149 Type_IRQ, /*! IRQ interrupt. */
150 Type_FIQ /*! FIQ interrupt. */
151 };
152
153 /*! Interrupt Controller. Symbol "Hwi_intc" is physical device */
154 struct Intc {
155 UInt32 REVISION; /*! 0x00 Config Register */
156
157 UInt32 hole0[3]; /*! 0x04-0x0C */
158
159 UInt32 SYSCONFIG; /*! 0x10 Config Register */
160 UInt32 SYSSTATUS; /*! 0x14 Status Register */
161
162 UInt32 hole1[10]; /*! 0x18-0x3c */
163
164 UInt32 SIR_IRQ; /*! 0x40 Source IRQ Register */
165 UInt32 SIR_FIQ; /*! 0x44 Source FIQ Register */
166 UInt32 CONTROL; /*! 0x48 Control Register */
167 UInt32 PROTECTION; /*! 0x4C Protection Register */
168 UInt32 IDLE; /*! 0x50 Idle Register */
169
170 UInt32 hole2[3]; /*! 0x54-0x5C */
171
172 UInt32 IRQ_PRIORITY; /*! 0x60 IRQ Priority Register */
173 UInt32 FIQ_PRIORITY; /*! 0x64 IRQ Priority Register */
174 UInt32 THRESHOLD; /*! 0x68 Threshold Register */
175
176 UInt32 hole3[5]; /*! 0x6C-0x7C */
177
178 UInt32 ITR0; /*! 0x80 Interrupt Input Register */
179 UInt32 MIR0; /*! 0x84 Mask Interrupt Register */
180 UInt32 MIR_CLEAR0; /*! 0x88 MIR Clear Register */
181 UInt32 MIR_SET0; /*! 0x8C MIR Set Register */
182 UInt32 ISR_SET0; /*! 0x90 Interrupt Set Register */
183 UInt32 ISR_CLEAR0; /*! 0x94 Interrupt Clear Register */
184 UInt32 PENDING_IRQ0; /*! 0x98 Pending IRQ Register */
185 UInt32 PENDING_FIQ0; /*! 0x9C Pending FIQ Register */
186
187 UInt32 ITR1; /*! 0xA0 Interrupt Input Register */
188 UInt32 MIR1; /*! 0xA4 Mask Interrupt Register */
189 UInt32 MIR_CLEAR1; /*! 0xA8 MIR Clear Register */
190 UInt32 MIR_SET1; /*! 0xAC MIR Set Register */
191 UInt32 ISR_SET1; /*! 0xB0 Interrupt Set Register */
192 UInt32 ISR_CLEAR1; /*! 0xB4 Interrupt Clear Register */
193 UInt32 PENDING_IRQ1; /*! 0xB8 Pending IRQ Register */
194 UInt32 PENDING_FIQ1; /*! 0xBC Pending FIQ Register */
195
196 UInt32 ITR2; /*! 0xC0 Interrupt Input Register */
197 UInt32 MIR2; /*! 0xC4 Mask Interrupt Register */
198 UInt32 MIR_CLEAR2; /*! 0xC8 MIR Clear Register */
199 UInt32 MIR_SET2; /*! 0xCC MIR Set Register */
200 UInt32 ISR_SET2; /*! 0xD0 Interrupt Set Register */
201 UInt32 ISR_CLEAR2; /*! 0xD4 Interrupt Clear Register */
202 UInt32 PENDING_IRQ2; /*! 0xD8 Pending IRQ Register */
203 UInt32 PENDING_FIQ2; /*! 0xDC Pending FIQ Register */
204
205 UInt32 ITR3; /*! 0xE0 Interrupt Input Register */
206 UInt32 MIR3; /*! 0xE4 Mask Interrupt Register */
207 UInt32 MIR_CLEAR3; /*! 0xE8 MIR Clear Register */
208 UInt32 MIR_SET3; /*! 0xEC MIR Set Register */
209 UInt32 ISR_SET3; /*! 0xF0 Interrupt Set Register */
210 UInt32 ISR_CLEAR3; /*! 0xF4 Interrupt Clear Register */
211 UInt32 PENDING_IRQ3; /*! 0xF8 Pending IRQ Register */
212 UInt32 PENDING_FIQ3; /*! 0xFC Pending FIQ Register */
213
214 UInt32 ILR[128]; /*! 0x100 thru 0x2FC */
215 };
216
217 extern volatile Intc intc;
218
219
220
221 /*! Reset Handler. Default is c_int00 */
222 metaonly config VectorFuncPtr resetFunc;
223
224 /*!
225 * Undefined instruction exception handler.
226 * Default is an internal exception handler.
227 */
228 metaonly config VectorFuncPtr undefinedInstFunc;
229
230 /*!
231 * SWI Handler. Default is internal SWI handler.
232 * Default is an internal exception handler.
233 */
234 metaonly config VectorFuncPtr swiFunc;
235
236 /*!
237 * Prefetch abort exception handler.
238 * Default is an internal exception handler.
239 */
240 metaonly config VectorFuncPtr prefetchAbortFunc;
241
242 /*!
243 * Data abort exception handler.
244 * Default is an internal exception handler.
245 */
246 metaonly config VectorFuncPtr dataAbortFunc;
247
248 /*!
249 * Reserved exception handler.
250 * Default is an internal exception handler.
251 */
252 metaonly config VectorFuncPtr reservedFunc;
253
254 /*! IRQ interrupt handler. Default is internal IRQ dispatcher */
255 metaonly config VectorFuncPtr irqFunc;
256
257 /*! FIQ interrupt handler. Default is internal FIQ dispatcher */
258 metaonly config VectorFuncPtr fiqFunc;
259
260 /*!
261 * FIQ stack pointer. Default = null.
262 * (Indicates that stack is to be created internally)
263 */
264 config Ptr fiqStack = null;
265
266 /*!
267 * FIQ stack size in MAUs.
268 * Default is 1024 bytes.
269 */
270 metaonly config SizeT fiqStackSize = 1024;
271
272 /*!
273 * Memory section used for FIQ stack
274 * Default is null.
275 */
276 metaonly config String fiqStackSection = null;
277
278 /*! Initial MIR0 Interrupt Mask. Default is 0xffffffff */
279 config Bits32 mir0Mask = 0xffffffff;
280
281 /*! Initial MIR1 Interrupt Mask. Default is 0xffffffff */
282 config Bits32 mir1Mask = 0xffffffff;
283
284 /*! Initial MIR2 Interrupt Mask. Default is 0xffffffff */
285 config Bits32 mir2Mask = 0xffffffff;
286
287 /*! Initial MIR3 Interrupt Mask. Default is 0xffffffff */
288 config Bits32 mir3Mask = 0xffffffff;
289
290 /*!
291 * @_nodoc
292 * ======== enableAsidTagging ========
293 * Flag to enable/disable ASID tagging
294 *
295 * If ASID tagging is enabled, the Hwi dispatcher will switch
296 * to ASID 0 (and change the MMU table base address to match
297 * kernel MMU table address) in the Hwi dispatcher prolog
298 * and restore the ASID (and MMU table base address) in the
299 * Hwi dispatcher epilog.
300 */
301 config Bool enableAsidTagging = false;
302
303 /*!
304 * Error raised when an attempt is made to create a Hwi
305 * that has already been created.
306 */
307 config Error.Id E_alreadyDefined = {
308 msg: "E_alreadyDefined: Hwi already defined, intnum: %d"
309 };
310
311 /*!
312 * Error raised when Hwi handle referenced in Hwi_delete()
313 * is not found in the Hwi dispatch table
314 */
315 config Error.Id E_handleNotFound = {
316 msg: "E_handleNotFound: Hwi handle not found: 0x%x"
317 };
318
319 /*!
320 * Error raised when an undefined interrupt has fired.
321 */
322 config Error.Id E_undefined = {
323 msg: "E_undefined: Hwi undefined, intnum: %d"
324 };
325
326 /*!
327 * Error raised if an attempt is made to create a Hwi
328 * with an interrupt number greater than NUM_INTERRUPTS - 1.
329 */
330 config Error.Id E_badIntNum = {
331 msg: "E_badIntNum, intnum: %d is out of range"
332 };
333
334 /*!
335 * Error raised if an attempt is made to create a Hwi
336 * with a priority of 0
337 */
338 config Error.Id E_invalidPriority = {
339 msg: "E_invalidPriority, priority: %d is either invalid or not supported"
340 };
341
342 /*!
343 * Issued just prior to Hwi function invocation (with interrupts disabled)
344 */
345 config Log.Event LM_begin = {
346 mask: Diags.USER1 | Diags.USER2,
347 msg: "LM_begin: hwi: 0x%x, func: 0x%x, preThread: %d, intNum: %d, irp: 0x%x"
348 };
349
350 /*!
351 * Issued just after return from Hwi function (with interrupts disabled)
352 */
353 config Log.Event LD_end = {
354 mask: Diags.USER2,
355 msg: "LD_end: hwi: 0x%x"
356 };
357
358
359
360
361 /*!
362 * ======== disable ========
363 * Globally disable interrupts.
364 *
365 * Hwi_disable globally disables hardware interrupts and returns an
366 * opaque key indicating whether interrupts were globally enabled or
367 * disabled on entry to Hwi_disable().
368 * The actual value of the key is target/device specific and is meant
369 * to be passed to Hwi_restore().
370 *
371 * Call Hwi_disable before a portion of a function that needs
372 * to run without interruption. When critical processing is complete, call
373 * Hwi_restore or Hwi_enable to reenable hardware interrupts.
374 *
375 * Servicing of interrupts that occur while interrupts are disabled is
376 * postponed until interrupts are reenabled. However, if the same type
377 * of interrupt occurs several times while interrupts are disabled,
378 * the interrupt's function is executed only once when interrupts are
379 * reenabled.
380 *
381 * A context switch can occur when calling Hwi_enable or Hwi_restore if
382 * an enabled interrupt occurred while interrupts are disabled.
383 *
384 * Hwi_disable may be called from main(). However, since Hwi interrupts
385 * are already disabled in main(), such a call has no effect.
386 *
387 * @a(constraints)
388 * If a Task switching API such as
389 * {@link ti.sysbios.knl.Semaphore#pend Semaphore_pend()},
390 * {@link ti.sysbios.knl.Semaphore#post Semaphore_post()},
391 * {@link ti.sysbios.knl.Task#sleep Task_sleep()}, or
392 * {@link ti.sysbios.knl.Task#yield Task_yield()}
393 * is invoked which results in a context switch while
394 * interrupts are disabled, an embedded call to
395 * {@link #enable Hwi_enable} occurs
396 * on the way to the new thread context which unconditionally re-enables
397 * interrupts. Interrupts will remain enabled until a subsequent
398 * {@link #disable Hwi_disable}
399 * invocation.
400 *
401 * Swis always run with interrupts enabled.
402 * See {@link ti.sysbios.knl.Swi#post Swi_post()} for a discussion Swis and
403 * interrupts.
404 *
405 * @b(returns) opaque key for use by Hwi_restore()
406 */
407 @Macro
408 override UInt disable();
409
410 /*!
411 * ======== enable ========
412 */
413 @Macro
414 override UInt enable();
415
416 /*!
417 * ======== restore ========
418 * @a(NOTE)
419 * When using TI compiler, Hwi_restore() uses the key to restore all
420 * the bits in the processor status register. This has the effect that
421 * both IRQ and FIQ interrupts are restored to their original status.
422 * Therefore, if FIQ interrupts are disabled but a key obtained when
423 * FIQ interrupts were still enabled is passed to Hwi_restore(), FIQ
424 * interrupts will be re-enabled. Care must be taken to avoid this.
425 *
426 * @a(NOTE)
427 * When using GCC compiler, Hwi_restore() only toggles the control bits
428 * corresponding to IRQ interrupts and therefore, FIQ interrupts are not
429 * affected.
430 */
431 @Macro
432 override Void restore(UInt key);
433
434 /*!
435 * ======== post ========
436 * Generate an interrupt for test purposes.
437 *
438 * The INTCPS ISR_SETx registers are used
439 * to trigger a software generated interrupt.
440 *
441 * To clear a software generated interrupt, the user
442 * must call {@link #clearPostedInterrupt Hwi_clearPostedInterrupt(intNum)}.
443 *
444 * @param(intNum) ID of interrupt to generate
445 */
446 @DirectCall
447 override Void post(UInt intNum);
448
449 /*!
450 * ======== clearPostedInterrupt ========
451 * Clear a specific software generated interrupt
452 * triggered by {@link #post Hwi_post(intNum)};
453 *
454 * @param(intNum) interrupt number to clear
455 */
456 @DirectCall
457 Void clearPostedInterrupt(UInt intNum);
458
459 /*!
460 * ======== inUseMeta ========
461 * @_nodoc
462 * Check for Hwi already in use.
463 * For internal SYS/BIOS use only.
464 * Should be called prior to any internal Hwi.create().
465 *
466 * @param(intNum) interrupt number
467 */
468 metaonly Bool inUseMeta(UInt intNum);
469
470 /*!
471 * ======== getHandle ========
472 * Returns Hwi_Handle associated with intNum
473 *
474 * @param(intNum) interrupt number
475 */
476 Handle getHandle(UInt intNum);
477
478 /*!
479 * ======== enableFIQ ========
480 * Enable FIQ interrupts.
481 *
482 * @b(returns) previous FIQ interrupt enable/disable state
483 */
484 UInt enableFIQ();
485
486 /*!
487 * ======== disableFIQ ========
488 * Disable FIQ interrupts.
489 *
490 * @b(returns) previous FIQ interrupt enable/disable state
491 */
492 UInt disableFIQ();
493
494 /*!
495 * ======== restoreFIQ ========
496 * Restore FIQ interrupts.
497 *
498 * @param(key) enable/disable state to restore
499 */
500 Void restoreFIQ(UInt key);
501
502 /*!
503 * ======== enableIRQ ========
504 * Enable IRQ interrupts.
505 *
506 * @param(key) enable/disable state to restore
507 */
508 UInt enableIRQ();
509
510 /*!
511 * ======== disableIRQ ========
512 * Disable IRQ interrupts.
513 *
514 * @b(returns) previous IRQ interrupt enable/disable state
515 */
516 UInt disableIRQ();
517
518 /*!
519 * ======== restoreIRQ ========
520 * Restore IRQ interrupts.
521 *
522 * @param(key) enable/disable state to restore
523 */
524 Void restoreIRQ(UInt key);
525
526 /*!
527 * ======== disableMIR0 ========
528 * Disable specific interrupts.
529 *
530 * Disables specific interrupts by setting the bits specified by
531 * mask in the Mask Interrupts Register (MIR).
532 *
533 * @param(mask) bitmask of interrupts to disable
534 * @b(returns) previous MIR0 settings bitmask
535 */
536 Bits32 disableMIR0(Bits32 mask);
537 Bits32 disableMIR1(Bits32 mask);
538 Bits32 disableMIR2(Bits32 mask);
539 Bits32 disableMIR3(Bits32 mask);
540
541 /*!
542 * ======== enableMIR ========
543 * Enable specific interrupts.
544 *
545 * Enables specific interrupts by clearing the bits specified by
546 * mask in the Mask Interrupts Register (MIR).
547 *
548 * @param(mask) bitmask of interrupts to enable
549 * @b(returns) previous MIR settings bitmask
550 */
551 Bits32 enableMIR0(Bits32 mask);
552 Bits32 enableMIR1(Bits32 mask);
553 Bits32 enableMIR2(Bits32 mask);
554 Bits32 enableMIR3(Bits32 mask);
555
556 /*!
557 * ======== restoreMIR0 ========
558 * Restore maskable interrupts to the state they were in
559 * when either disableMIR0() or enableMIR0() was called.
560 *
561 * Simply writes mask to the MIR register.
562 *
563 * @param(mask) bitmask of interrupts to restore
564 * @b(returns) previous MIR0 settings bitmask
565 */
566 Bits32 restoreMIR0(Bits32 mask);
567 Bits32 restoreMIR1(Bits32 mask);
568 Bits32 restoreMIR2(Bits32 mask);
569 Bits32 restoreMIR3(Bits32 mask);
570
571 /*!
572 * ======== setPriority ========
573 * Set an interrupt's priority.
574 *
575 * Valid priority values range from 0 to
576 * ({@link #NUM_PRIORITIES} - 1),
577 * 0 is the highest priority.
578 *
579 * @param(intNum) ID of interrupt
580 * @param(priority) priority
581 */
582 Void setPriority(UInt intNum, UInt priority);
583
584 /*!
585 * ======== setType ========
586 * Set an interrupt's type (FIQ/IRQ).
587 *
588 * @param(intNum) ID of interrupt
589 * @param(type) type = FIQ/IRQ
590 */
591 Void setType(UInt intNum, Type type);
592
593 instance:
594
595 /*! Interrupt type (IRQ/FIQ). Default is IRQ. */
596 config Type type = Type_IRQ;
597
598 599 600 601 602 603 604 605 606 607 608
609 override config Int priority = -1;
610
611 /*!
612 * The maskSetting parameter is ignored.
613 * Only Hwi_MaskingOption_LOWER is supported.
614 *
615 * The interrupt controller is designed for priority based interrupts
616 */
617 override config IHwi.MaskingOption maskSetting = IHwi.MaskingOption_LOWER;
618
619 /*!
620 * ======== reconfig ========
621 * Reconfigure a dispatched interrupt.
622 */
623 Void reconfig(FuncPtr fxn, const Params *params);
624
625 internal:
626
627 628 629 630 631 632
633 config UInt (*swiDisable)();
634 config Void (*swiRestoreHwi)(UInt);
635 config UInt (*taskDisable)();
636 config Void (*taskRestoreHwi)(UInt);
637
638 639 640 641
642 Int postInit(Object *hwi, Error.Block *eb);
643
644 645 646
647 Void initIntController();
648
649
650 Void init(Ptr fiqStack);
651
652
653 Void initVbar();
654
655
656 Void dispatchIRQ();
657
658
659 Void dispatchIRQC(Irp irp);
660
661
662 Void dispatchFIQC();
663
664
665 Void nonPluggedHwiHandler(UArg arg);
666
667 /*!
668 * const array to hold all HookSet objects.
669 */
670 config HookSet hooks[length] = [];
671
672 /*! Meta World Only Hwi Configuration Object. */
673 metaonly struct InterruptObj {
674 Bool used;
675 FuncPtr fxn;
676 };
677
678 /*!
679 * Meta-only array of interrupt objects.
680 * This meta-only array of Hwi config objects is initialized
681 * in Hwi.xs:module$meta$init().
682 */
683 metaonly config InterruptObj interrupt[NUM_INTERRUPTS];
684
685 struct Instance_State {
686 Type type;
687 UInt priority;
688 UArg arg;
689 FuncPtr fxn;
690 Irp irp;
691 Ptr hookEnv[];
692 };
693
694 struct Module_State {
695 Char *taskSP;
696
697 Char *isrStack;
698
699
700
701 Bits32 mir0Mask;
702 Bits32 mir1Mask;
703 Bits32 mir2Mask;
704 Bits32 mir3Mask;
705 UInt spuriousInts;
706 UInt lastSpuriousInt;
707 UInt irp;
708 Ptr isrStackBase;
709 Ptr isrStackSize;
710 Char fiqStack[];
711 SizeT fiqStackSize;
712 Hwi.Object nonPluggedHwi;
713 Handle dispatchTable[NUM_INTERRUPTS];
714
715 };
716 }
717