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 * Issued just prior to Hwi function invocation (with interrupts disabled)
336 */
337 config Log.Event LM_begin = {
338 mask: Diags.USER1 | Diags.USER2,
339 msg: "LM_begin: hwi: 0x%x, func: 0x%x, preThread: %d, intNum: %d, irp: 0x%x"
340 };
341
342 /*!
343 * Issued just after return from Hwi function (with interrupts disabled)
344 */
345 config Log.Event LD_end = {
346 mask: Diags.USER2,
347 msg: "LD_end: hwi: 0x%x"
348 };
349
350
351
352
353 /*!
354 * ======== disable ========
355 * Globally disable interrupts.
356 *
357 * Hwi_disable globally disables hardware interrupts and returns an
358 * opaque key indicating whether interrupts were globally enabled or
359 * disabled on entry to Hwi_disable().
360 * The actual value of the key is target/device specific and is meant
361 * to be passed to Hwi_restore().
362 *
363 * Call Hwi_disable before a portion of a function that needs
364 * to run without interruption. When critical processing is complete, call
365 * Hwi_restore or Hwi_enable to reenable hardware interrupts.
366 *
367 * Servicing of interrupts that occur while interrupts are disabled is
368 * postponed until interrupts are reenabled. However, if the same type
369 * of interrupt occurs several times while interrupts are disabled,
370 * the interrupt's function is executed only once when interrupts are
371 * reenabled.
372 *
373 * A context switch can occur when calling Hwi_enable or Hwi_restore if
374 * an enabled interrupt occurred while interrupts are disabled.
375 *
376 * Hwi_disable may be called from main(). However, since Hwi interrupts
377 * are already disabled in main(), such a call has no effect.
378 *
379 * @a(constraints)
380 * If a Task switching API such as
381 * {@link ti.sysbios.knl.Semaphore#pend Semaphore_pend()},
382 * {@link ti.sysbios.knl.Semaphore#post Semaphore_post()},
383 * {@link ti.sysbios.knl.Task#sleep Task_sleep()}, or
384 * {@link ti.sysbios.knl.Task#yield Task_yield()}
385 * is invoked which results in a context switch while
386 * interrupts are disabled, an embedded call to
387 * {@link #enable Hwi_enable} occurs
388 * on the way to the new thread context which unconditionally re-enables
389 * interrupts. Interrupts will remain enabled until a subsequent
390 * {@link #disable Hwi_disable}
391 * invocation.
392 *
393 * Swis always run with interrupts enabled.
394 * See {@link ti.sysbios.knl.Swi#post Swi_post()} for a discussion Swis and
395 * interrupts.
396 *
397 * @b(returns) opaque key for use by Hwi_restore()
398 */
399 @Macro
400 override UInt disable();
401
402 /*!
403 * ======== enable ========
404 */
405 @Macro
406 override UInt enable();
407
408 /*!
409 * ======== restore ========
410 * @a(NOTE)
411 * When using TI compiler, Hwi_restore() uses the key to restore all
412 * the bits in the processor status register. This has the effect that
413 * both IRQ and FIQ interrupts are restored to their original status.
414 * Therefore, if FIQ interrupts are disabled but a key obtained when
415 * FIQ interrupts were still enabled is passed to Hwi_restore(), FIQ
416 * interrupts will be re-enabled. Care must be taken to avoid this.
417 *
418 * @a(NOTE)
419 * When using GCC compiler, Hwi_restore() only toggles the control bits
420 * corresponding to IRQ interrupts and therefore, FIQ interrupts are not
421 * affected.
422 */
423 @Macro
424 override Void restore(UInt key);
425
426 /*!
427 * ======== post ========
428 * Generate an interrupt for test purposes.
429 *
430 * The INTCPS ISR_SETx registers are used
431 * to trigger a software generated interrupt.
432 *
433 * To clear a software generated interrupt, the user
434 * must call {@link #clearPostedInterrupt Hwi_clearPostedInterrupt(intNum)}.
435 *
436 * @param(intNum) ID of interrupt to generate
437 */
438 @DirectCall
439 override Void post(UInt intNum);
440
441 /*!
442 * ======== clearPostedInterrupt ========
443 * Clear a specific software generated interrupt
444 * triggered by {@link #post Hwi_post(intNum)};
445 *
446 * @param(intNum) interrupt number to clear
447 */
448 @DirectCall
449 Void clearPostedInterrupt(UInt intNum);
450
451 /*!
452 * ======== inUseMeta ========
453 * @_nodoc
454 * Check for Hwi already in use.
455 * For internal SYS/BIOS use only.
456 * Should be called prior to any internal Hwi.create().
457 *
458 * @param(intNum) interrupt number
459 */
460 metaonly Bool inUseMeta(UInt intNum);
461
462 /*!
463 * ======== getHandle ========
464 * Returns Hwi_Handle associated with intNum
465 *
466 * @param(intNum) interrupt number
467 */
468 Handle getHandle(UInt intNum);
469
470 /*!
471 * ======== enableFIQ ========
472 * Enable FIQ interrupts.
473 *
474 * @b(returns) previous FIQ interrupt enable/disable state
475 */
476 UInt enableFIQ();
477
478 /*!
479 * ======== disableFIQ ========
480 * Disable FIQ interrupts.
481 *
482 * @b(returns) previous FIQ interrupt enable/disable state
483 */
484 UInt disableFIQ();
485
486 /*!
487 * ======== restoreFIQ ========
488 * Restore FIQ interrupts.
489 *
490 * @param(key) enable/disable state to restore
491 */
492 Void restoreFIQ(UInt key);
493
494 /*!
495 * ======== enableIRQ ========
496 * Enable IRQ interrupts.
497 *
498 * @param(key) enable/disable state to restore
499 */
500 UInt enableIRQ();
501
502 /*!
503 * ======== disableIRQ ========
504 * Disable IRQ interrupts.
505 *
506 * @b(returns) previous IRQ interrupt enable/disable state
507 */
508 UInt disableIRQ();
509
510 /*!
511 * ======== restoreIRQ ========
512 * Restore IRQ interrupts.
513 *
514 * @param(key) enable/disable state to restore
515 */
516 Void restoreIRQ(UInt key);
517
518 /*!
519 * ======== disableMIR0 ========
520 * Disable specific interrupts.
521 *
522 * Disables specific interrupts by setting the bits specified by
523 * mask in the Mask Interrupts Register (MIR).
524 *
525 * @param(mask) bitmask of interrupts to disable
526 * @b(returns) previous MIR0 settings bitmask
527 */
528 Bits32 disableMIR0(Bits32 mask);
529 Bits32 disableMIR1(Bits32 mask);
530 Bits32 disableMIR2(Bits32 mask);
531 Bits32 disableMIR3(Bits32 mask);
532
533 /*!
534 * ======== enableMIR ========
535 * Enable specific interrupts.
536 *
537 * Enables specific interrupts by clearing the bits specified by
538 * mask in the Mask Interrupts Register (MIR).
539 *
540 * @param(mask) bitmask of interrupts to enable
541 * @b(returns) previous MIR settings bitmask
542 */
543 Bits32 enableMIR0(Bits32 mask);
544 Bits32 enableMIR1(Bits32 mask);
545 Bits32 enableMIR2(Bits32 mask);
546 Bits32 enableMIR3(Bits32 mask);
547
548 /*!
549 * ======== restoreMIR0 ========
550 * Restore maskable interrupts to the state they were in
551 * when either disableMIR0() or enableMIR0() was called.
552 *
553 * Simply writes mask to the MIR register.
554 *
555 * @param(mask) bitmask of interrupts to restore
556 * @b(returns) previous MIR0 settings bitmask
557 */
558 Bits32 restoreMIR0(Bits32 mask);
559 Bits32 restoreMIR1(Bits32 mask);
560 Bits32 restoreMIR2(Bits32 mask);
561 Bits32 restoreMIR3(Bits32 mask);
562
563 /*!
564 * ======== setPriority ========
565 * Set an interrupt's priority.
566 *
567 * Valid priority values range from 0 to
568 * ({@link #NUM_PRIORITIES} - 1),
569 * 0 is the highest priority.
570 *
571 * @param(intNum) ID of interrupt
572 * @param(priority) priority
573 */
574 Void setPriority(UInt intNum, UInt priority);
575
576 /*!
577 * ======== setType ========
578 * Set an interrupt's type (FIQ/IRQ).
579 *
580 * @param(intNum) ID of interrupt
581 * @param(type) type = FIQ/IRQ
582 */
583 Void setType(UInt intNum, Type type);
584
585 instance:
586
587 /*! Interrupt type (IRQ/FIQ). Default is IRQ. */
588 config Type type = Type_IRQ;
589
590 591 592 593 594 595 596 597 598 599 600
601 override config Int priority = -1;
602
603 /*!
604 * The maskSetting parameter is ignored.
605 * Only Hwi_MaskingOption_LOWER is supported.
606 *
607 * The interrupt controller is designed for priority based interrupts
608 */
609 override config IHwi.MaskingOption maskSetting = IHwi.MaskingOption_LOWER;
610
611 /*!
612 * ======== reconfig ========
613 * Reconfigure a dispatched interrupt.
614 */
615 Void reconfig(FuncPtr fxn, const Params *params);
616
617 internal:
618
619 620 621 622 623 624
625 config UInt (*swiDisable)();
626 config Void (*swiRestoreHwi)(UInt);
627 config UInt (*taskDisable)();
628 config Void (*taskRestoreHwi)(UInt);
629
630 631 632 633
634 Int postInit(Object *hwi, Error.Block *eb);
635
636 637 638
639 Void initIntController();
640
641
642 Void init(Ptr fiqStack);
643
644
645 Void initVbar();
646
647
648 Void dispatchIRQ();
649
650
651 Void dispatchIRQC(Irp irp);
652
653
654 Void dispatchFIQC();
655
656
657 Void nonPluggedHwiHandler(UArg arg);
658
659 /*!
660 * const array to hold all HookSet objects.
661 */
662 config HookSet hooks[length] = [];
663
664 /*! Meta World Only Hwi Configuration Object. */
665 metaonly struct InterruptObj {
666 Bool used;
667 FuncPtr fxn;
668 };
669
670 /*!
671 * Meta-only array of interrupt objects.
672 * This meta-only array of Hwi config objects is initialized
673 * in Hwi.xs:module$meta$init().
674 */
675 metaonly config InterruptObj interrupt[NUM_INTERRUPTS];
676
677 struct Instance_State {
678 Type type;
679 UInt priority;
680 UArg arg;
681 FuncPtr fxn;
682 Irp irp;
683 Ptr hookEnv[];
684 };
685
686 struct Module_State {
687 Char *taskSP;
688
689 Char *isrStack;
690
691
692
693 Bits32 mir0Mask;
694 Bits32 mir1Mask;
695 Bits32 mir2Mask;
696 Bits32 mir3Mask;
697 UInt spuriousInts;
698 UInt lastSpuriousInt;
699 UInt irp;
700 Ptr isrStackBase;
701 Ptr isrStackSize;
702 Char fiqStack[];
703 SizeT fiqStackSize;
704 Hwi.Object nonPluggedHwi;
705 Handle dispatchTable[NUM_INTERRUPTS];
706
707 };
708 }
709