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.da830;
37
38 import xdc.runtime.Diags;
39 import xdc.runtime.Log;
40 import xdc.runtime.Assert;
41 import xdc.rov.ViewInfo;
42 import xdc.runtime.Error;
43
44 /*!
45 * ======== Hwi ========
46 * Hardware Interrupt Support Module.
47 *
48 * This Hwi module provides ARM family-specific implementations of the
49 * APIs defined in {@link ti.sysbios.interfaces.IHwi IHwi}.
50 *
51 * Additional ARM device-specific APIs are also provided.
52 *
53 * IRQ Interrupts are nestable and can invoke SYS/BIOS functions.
54 * FIQ Interrupts are non-nestable and cannot invoke SYS/BIOS functions.
55 *
56 * The IRQ dispatcher re-enables IRQ interrupts prior to invoking the
57 * ISR function associated with an interrupt but uses the CP INTC's
58 * Host Interrupt Nesting Level Register (HINLR) to suppress lower
59 * priority interrupts while the interrupt is being serviced.
60 *
61 * The default FIQ handler does not re-enable FIQ interrupts nor
62 * use the HINLR. It simply calls the registered FIQ ISR and returns.
63 *
64 * To statically configure a non-dispatched interrupt:
65 * To dynamically configure a non-dispatched interrupt:
66 *
67 * @p(html)
68 * <h3> Calling Context </h3>
69 * <table border="1" cellpadding="3">
70 * <colgroup span="1"></colgroup> <colgroup span="5" align="center"></colgroup>
71 *
72 * <tr><th> Function </th><th> Hwi </th><th> Swi </th><th> Task </th><th> Main </th><th> Startup </th></tr>
73 * <!-- -->
74 * <tr><td> {@link #clearInterrupt} </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td></tr>
75 * <tr><td> {@link #create} </td><td> N </td><td> N </td><td> Y </td><td> Y </td><td> N </td></tr>
76 * <tr><td> {@link #disable} </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td></tr>
77 * <tr><td> {@link #disableFIQ} </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td></tr>
78 * <tr><td> {@link #disableInterrupt} </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td><td> N </td></tr>
79 * <tr><td> {@link #disableIRQ} </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td></tr>
80 * <tr><td> {@link #enable} </td><td> Y </td><td> Y </td><td> Y </td><td> N </td><td> N </td></tr>
81 * <tr><td> {@link #enableFIQ} </td><td> Y </td><td> Y </td><td> Y </td><td> N </td><td> N </td></tr>
82 * <tr><td> {@link #enableInterrupt} </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td><td> N </td></tr>
83 * <tr><td> {@link #enableIRQ} </td><td> Y </td><td> Y </td><td> Y </td><td> N </td><td> N </td></tr>
84 * <tr><td> {@link #getHandle} </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td><td> N </td></tr>
85 * <tr><td> {@link #Params_init} </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td></tr>
86 * <tr><td> {@link #restore} </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td></tr>
87 * <tr><td> {@link #restoreFIQ} </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td></tr>
88 * <tr><td> {@link #restoreInterrupt} </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td></tr>
89 * <tr><td> {@link #restoreIRQ} </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td></tr>
90 * <tr><td> {@link #setPriority} </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td><td> N </td></tr>
91 * <tr><td> {@link #construct} </td><td> N </td><td> N </td><td> Y </td><td> Y </td><td> N </td></tr>
92 * <tr><td> {@link #delete} </td><td> N </td><td> N </td><td> Y </td><td> Y </td><td> N </td></tr>
93 * <tr><td> {@link #destruct} </td><td> N </td><td> N </td><td> Y </td><td> Y </td><td> N </td></tr>
94 * <tr><td> {@link #getHookContext} </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td><td> N </td></tr>
95 * <tr><td> {@link #reconfig} </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td><td> N </td></tr>
96 * <tr><td> {@link #setFunc} </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td><td> N </td></tr>
97 * <tr><td> {@link #setHookContext} </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td><td> N </td></tr>
98 * <tr><td colspan="6"> Definitions: <br />
99 * <ul>
100 * <li> <b>Hwi</b>: API is callable from a Hwi thread. </li>
101 * <li> <b>Swi</b>: API is callable from a Swi thread. </li>
102 * <li> <b>Task</b>: API is callable from a Task thread. </li>
103 * <li> <b>Main</b>: API is callable during any of these phases: </li>
104 * <ul>
105 * <li> In your module startup after this module is started (e.g. Hwi_Module_startupDone() returns TRUE). </li>
106 * <li> During xdc.runtime.Startup.lastFxns. </li>
107 * <li> During main().</li>
108 * <li> During BIOS.startupFxns.</li>
109 * </ul>
110 * <li> <b>Startup</b>: API is callable during any of these phases:</li>
111 * <ul>
112 * <li> During xdc.runtime.Startup.firstFxns.</li>
113 * <li> In your module startup before this module is started (e.g. Hwi_Module_startupDone() returns FALSE).</li>
114 * </ul>
115 * </ul>
116 * </td></tr>
117 *
118 *
119 * </table>
120 * @p
121 */
122
123 @Template("./Hwi.xdt")
124 @ModuleStartup
125 @InstanceInitStatic
126
127 module Hwi inherits ti.sysbios.interfaces.IHwi
128 {
129
130
131
132 /*! The DA830 ARM Interrupt Controller has 101 defined interrupts. */
133 const Int NUM_INTERRUPTS = 101;
134
135
136
137 /*! Hwi vector function type definition. */
138 typedef Void (*VectorFuncPtr)(void);
139
140 /*! @_nodoc Hwi plug function type definition. */
141 typedef Void (*PlugFuncPtr)(void);
142
143 /*!
144 * Common Platform Interrupt Controller.
145 */
146 struct CPINTC {
147 UInt32 REV; /*! 0x00 Revision Register */
148 UInt32 CR; /*! 0x04 Control Register */
149 UInt32 RES_08; /*! 0x08 reserved */
150 UInt32 HCR; /*! 0x0C Host Control Register */
151 UInt32 GER; /*! 0x10 Global Enable Register */
152 UInt32 RES_14; /*! 0x14 reserved */
153 UInt32 RES_18; /*! 0x18 reserved */
154 UInt32 GNLR; /*! 0x1C Global Nesting Level Register */
155 UInt32 SISR; /*! 0x20 Status Index Set Register */
156 UInt32 SICR; /*! 0x24 Status Index Clear Register */
157 UInt32 EISR; /*! 0x28 Enable Index Set Register */
158 UInt32 EICR; /*! 0x2C Enable Index Clear Register */
159 UInt32 GWER; /*! 0x30 Global Wakeup Enable Register */
160 UInt32 HIEISR; /*! 0x34 Host Int Enable Index Set Register */
161 UInt32 HIDISR; /*! 0x38 Host Int Disable Index Set Register */
162 UInt32 RES_3C; /*! 0x3C reserved */
163 UInt32 PPR; /*! 0x40 Pacer Prescale Register */
164 UInt32 RES_44; /*! 0x44 reserved */
165 UInt32 RES_48; /*! 0x48 reserved */
166 UInt32 RES_4C; /*! 0x4C reserved */
167 Ptr *VBR; /*! 0x50 Vector Base Register */
168 UInt32 VSR; /*! 0x54 Vector Size Register */
169 Ptr VNR; /*! 0x58 Vector Null Register */
170 UInt32 RES_5C[9]; /*! 0x5C-0x7C reserved */
171 Int32 GPIR; /*! 0x80 Global Prioritized Index Register */
172 Ptr *GPVR; /*! 0x84 Global Prioritized Vector Register */
173 UInt32 RES_88; /*! 0x88 reserved */
174 UInt32 RES_8C; /*! 0x8C reserved */
175 UInt32 GSIER; /*! 0x90 Global Secure Interrupt Enable Register */
176 UInt32 SPIR; /*! 0x94 Secure Prioritized Index Register */
177 UInt32 RES_98[26]; /*! 0x98-0xFC reserved */
178 UInt32 PPMR[64]; /*! 0x100-0x1FC Pacer Parameter/Map Registers */
179 UInt32 SRSR[32]; /*! 0x200-0x27C Status Raw/Set Registers */
180 UInt32 SECR[32]; /*! 0x280-0x2FC Status Enabled/Clear Registers */
181 UInt32 ESR[32]; /*! 0x300-0x37C Enable Set Registers */
182 UInt32 ECR[32]; /*! 0x380-0x3FC Enable Clear Registers */
183 UInt8 CMR[1024]; /*! 0x400-0x7FC Channel Map Registers */
184 UInt8 HIMR[256]; /*! 0x800-0x8FC Host Interrupt Map Registers */
185 UInt32 HIPIR[256]; /*! 0x900-0xCFC Host Interrupt Pri Index Registers */
186 UInt32 PR[32]; /*! 0xD00-0xD7C Polarity Registers */
187 UInt32 TR[32]; /*! 0xD80-0xDFC Type Registers */
188 UInt32 WER[64]; /*! 0xE00-0xEFC Wakeup Enable Registers */
189 UInt32 DSR[64]; /*! 0xF00-0xFFC Debug Select Registers */
190 UInt32 SER[32]; /*! 0x1000-0x107C Secure Enable Registers */
191 UInt32 SDR[32]; /*! 0x1080-0x10FC Secure Disable Registers */
192 UInt32 HINLR[256]; /*! 0x1100-0x14FC Host Interrupt Nesting Level Registers */
193 UInt32 HIER[8]; /*! 0x1500-0x151F Host Interrupt Enable Registers */
194 UInt32 RES_1520[56];/*! 0x1520-0x15fC Reserved */
195 Ptr *HIPVR[256]; /*! 0x1600-0x19fC Host Interrupt Prioritized Vector */
196 };
197
198 /*!
199 * Physical Common Platform Interrupt Controller Device.
200 * Short name is "Hwi_cpIntc"
201 * Long name is "ti_sysbios_family_arm_da830_Hwi_cpIntc"
202 */
203 extern volatile CPINTC cpIntc;
204
205 /*!
206 * ======== BasicView ========
207 * @_nodoc
208 */
209 metaonly struct BasicView {
210 Ptr halHwiHandle;
211 String label;
212 Int intNum;
213 Int priority;
214 String fxn;
215 UArg arg;
216 Ptr irp;
217 String status;
218 };
219
220 /*!
221 * ======== ModuleView ========
222 * @_nodoc
223 */
224 metaonly struct ModuleView {
225 String options[4];
226 String hwiStackPeak;
227 SizeT hwiStackSize;
228 Ptr hwiStackBase;
229 UInt priorities[256];
230 };
231
232 /*!
233 * ======== rovViewInfo ========
234 * @_nodoc
235 */
236 @Facet
237 metaonly config ViewInfo.Instance rovViewInfo =
238 ViewInfo.create({
239 viewMap: [
240 ['Basic', {type: ViewInfo.INSTANCE, viewInitFxn: 'viewInitBasic', structName: 'BasicView'}],
241 ['Module', {type: ViewInfo.MODULE, viewInitFxn: 'viewInitModule', structName: 'ModuleView'}]
242 ]
243 });
244
245
246
247 /*! Assert when bad maskSetting parameter provided */
248 config Assert.Id A_unsupportedMaskingOption = {
249 msg: "A_unsupportedMaskingOption: unsupported maskSetting."
250 };
251
252 /*! Reset Handler. Default is c_int00 */
253 metaonly config VectorFuncPtr resetFunc;
254
255 /*! Undefined instruction exception handler. Default is self loop */
256 metaonly config VectorFuncPtr undefinedInstFunc;
257
258 /*! SWI Handler. Default is internal SWI handler */
259 metaonly config VectorFuncPtr swiFunc;
260
261 /*! Prefetch abort exception handler. Default is self loop */
262 metaonly config VectorFuncPtr prefetchAbortFunc;
263
264 /*! Data abort exception handler. Default is self loop */
265 metaonly config VectorFuncPtr dataAbortFunc;
266
267 /*! Reserved exception handler. Default is self loop */
268 metaonly config VectorFuncPtr reservedFunc;
269
270 /*! IRQ interrupt handler. Default is internal IRQ dispatcher */
271 metaonly config VectorFuncPtr irqFunc;
272
273 /*! FIQ interrupt handler. Default is internal FIQ dispatcher */
274 metaonly config VectorFuncPtr fiqFunc;
275
276 /*!
277 * non-dispatched interrupt object.
278 * provided so that XGCONF users can easily plug non-dispatched interrupts
279 */
280 metaonly struct NonDispatchedInterrupt {
281 Int intNum;
282 PlugFuncPtr fxn; /*! "Hwi_plug'd" ISR function. */
283 UInt priority;
284 Bool enableInt;
285 };
286
287 /*!
288 * non-dispatched interrupt array.
289 * provided so that XGCONF users can easily plug non-dispatched interrupts
290 */
291 metaonly config NonDispatchedInterrupt nonDispatchedInterrupts[string];
292
293 /*!
294 * FIQ stack pointer. Default = null.
295 * (Indicates that stack is to be created using
296 * staticPlace()
297 */
298 config Ptr fiqStack = null;
299
300 /*!
301 * FIQ stack size in bytes.
302 * Default is 1024 bytes.
303 */
304 metaonly config SizeT fiqStackSize = 1024;
305
306 /*!
307 * Memory section used for FIQ stack
308 * Default is null.
309 */
310 metaonly config String fiqStackSection = null;
311
312 /*!
313 * IRQ stack pointer. Default = null.
314 * (Indicates that stack is to be created using
315 * staticPlace()
316 */
317 config Ptr irqStack = null;
318
319 /*!
320 * IRQ stack size in bytes.
321 * Default is 256 bytes.
322 * This is enough room for 32 nested IRQ interrupts.
323 *
324 * An IRQ interrupt pushes 2 32bit words onto the IRQ stack.
325 */
326 metaonly config SizeT irqStackSize = 256;
327
328 /*!
329 * Memory section used for IRQ stack
330 * Default is null.
331 */
332 metaonly config String irqStackSection = null;
333
334 /*!
335 * Location of the Interrupt Vector Table
336 *
337 * The default placement of the Interrupt Vector Table
338 * is immediately after the ARM exception table located
339 * at 0xffff0000.
340 *
341 * The vector table is internally assigned to the ".vectorTable"
342 * memory section.
343 */
344 metaonly config Ptr vectorTableAddress = 0xffff0040;
345
346 /*!
347 * Error raised when Hwi is already defined
348 */
349 config Error.Id E_alreadyDefined = {
350 msg: "E_alreadyDefined: Hwi already defined: intr# %d"
351 };
352
353 /*!
354 * Issued just prior to Hwi function invocation (with interrupts disabled)
355 */
356 config Log.Event LM_begin = {
357 mask: Diags.USER1 | Diags.USER2,
358 msg: "LM_begin: hwi: 0x%x, func: 0x%x, preThread: %d, intNum: %d, irp: 0x%x"
359 };
360
361 /*!
362 * Issued just after return from Hwi function (with interrupts disabled)
363 */
364 config Log.Event LD_end = {
365 mask: Diags.USER2,
366 msg: "LD_end: hwi: 0x%x"
367 };
368
369
370
371
372 /*!
373 * ======== disable ========
374 */
375 @Macro
376 override UInt disable();
377
378 /*!
379 * ======== enable ========
380 */
381 @Macro
382 override UInt enable();
383
384 /*!
385 * ======== restore ========
386 */
387 @Macro
388 override Void restore(UInt key);
389
390 /*!
391 * ======== inUseMeta ========
392 * @_nodoc
393 * Check for Hwi already in use.
394 * For internal SYS/BIOS use only.
395 * Should be called prior to any internal Hwi.create().
396 *
397 * @param(intNum) interrupt number
398 */
399 metaonly Bool inUseMeta(UInt intNum);
400
401 /*!
402 * @_nodoc
403 * ======== plug ========
404 * Plug an interrupt vector with an ISR address.
405 *
406 * Hwi_plug writes an Interrupt Service Fetch Packet (ISFP) into the
407 * Interrupt Service Table (IST), at the address corresponding to intNum
408 * The op-codes written in the ISFP create a branch to the function
409 * entry point specified by fxn:
410 *
411 * @p(code)
412 * stw b0, *SP--[1]
413 * mvk fxn, b0
414 * mvkh fxn, b0
415 * b b0
416 * ldw *++SP[1],b0
417 * nop 4
418 * @p
419 *
420 * Hwi_plug hooks up the specified function as the branch target of a
421 * hardware interrupt (fielded by the CPU) at the vector address
422 * specified in intNum. Hwi_plug does not enable the interrupt.
423 * Use Hwi_enableIER to enable specific interrupts.
424 *
425 * For internal SYS/BIOS use only.
426 *
427 * Constraints and Calling Context
428 * o vecid must be a valid interrupt ID in the range of 0-15.
429 *
430 * @param(intNum) interrupt number
431 * @param(fxn) pointer to ISR function
432 */
433 Void plug(UInt intNum, PlugFuncPtr fxn);
434
435 /*!
436 * ======== plugMeta ========
437 * Statically plug an interrupt vector with an ISR address.
438 *
439 * @param(intNum) interrupt number
440 * @param(fxn) pointer to ISR function
441 */
442 metaonly Void plugMeta(UInt intNum, PlugFuncPtr fxn);
443
444 /*!
445 * ======== getHandle ========
446 * Returns Hwi_handle associated with intNum
447 *
448 * @param(intNum) interrupt number
449 */
450 Handle getHandle(UInt intNum);
451
452 /*!
453 * ======== enableFIQ ========
454 * Enable FIQ interrupts.
455 *
456 * @b(returns) previous FIQ interrupt enable/disable state
457 */
458 UInt enableFIQ();
459
460 /*!
461 * ======== disableFIQ ========
462 * Disable FIQ interrupts.
463 *
464 * @b(returns) previous FIQ interrupt enable/disable state
465 */
466 UInt disableFIQ();
467
468 /*!
469 * ======== restoreFIQ ========
470 * Restore FIQ interrupts.
471 *
472 * @param(key) enable/disable state to restore
473 */
474 Void restoreFIQ(UInt key);
475
476 /*!
477 * ======== enableIRQ ========
478 * Enable IRQ interrupts.
479 *
480 * @param(key) enable/disable state to restore
481 */
482 UInt enableIRQ();
483
484 /*!
485 * ======== disableIRQ ========
486 * Disable IRQ interrupts.
487 *
488 * @b(returns) previous IRQ interrupt enable/disable state
489 */
490 UInt disableIRQ();
491
492 /*!
493 * ======== restoreIRQ ========
494 * Restore IRQ interrupts.
495 *
496 * @param(key) enable/disable state to restore
497 */
498 Void restoreIRQ(UInt key);
499
500 /*!
501 * ======== beginIRQ ========
502 * Function to be invoked at the beginning of a
503 * non-dispatched IRQ handler. Services cpIntc.
504 */
505 Void beginIRQ();
506
507 /*!
508 * ======== endIRQ ========
509 * Function to be invoked at the end of a
510 * non-dispatched IRQ handler. Services cpIntc.
511 */
512 Void endIRQ();
513
514 /*!
515 * ======== beginFIQ ========
516 * Function to be invoked at the beginning of a
517 * non-dispatched FIQ handler. Services cpIntc.
518 */
519 Void beginFIQ();
520
521 /*!
522 * ======== endFIQ ========
523 * Function to be invoked at the end of a
524 * non-dispatched FIQ handler. Services cpIntc.
525 */
526 Void endFIQ();
527
528 /*!
529 * ======== setPriority ========
530 * Set an interrupt's relative priority.
531 *
532 * Valid priorities are 0 - 31. 0 is highest priority.
533 * Priorities 0 - 1 are routed to the ARM's FIQ interrupt.
534 * Priorities 2 - 31 are routed to the ARM's IRQ interrupt.
535 *
536 * @param(intNum) ID of interrupt
537 * @param(priority) priority
538 */
539 Void setPriority(UInt intNum, UInt priority);
540
541 instance:
542
543 /*!
544 * Interrupt priority.
545 * Valid priorities are 0 - 31. 0 is highest priority.
546 * Priorities 0 - 1 are routed to the ARM's FIQ interrupt.
547 * Priorities 2 - 31 are routed to the ARM's IRQ interrupt.
548 * The default is 31 which is the lowest priority IRQ interrupt.
549 */
550 override config Int priority = 31;
551
552 /*!
553 * ======== reconfig ========
554 * Reconfigure a dispatched interrupt.
555 */
556 Void reconfig(FuncPtr fxn, const Params *params);
557
558 internal:
559
560 /*! Hwi vector function type definition. */
561 typedef Void (*HandlerFuncPtr)(Handle, UInt);
562
563 564 565 566 567 568
569 config UInt (*swiDisable)();
570 config Void (*swiRestoreHwi)(UInt);
571 config UInt (*taskDisable)();
572 config Void (*taskRestoreHwi)(UInt);
573
574 575 576 577
578 Int postInit(Object *hwi, Error.Block *eb);
579
580 581 582
583 Void initIntController();
584
585
586 Void init();
587
588
589 Void dispatchIRQ();
590
591
592 Void dispatchIRQC();
593
594
595 Void dispatchFIQC();
596
597
598 Void spuriousInt();
599
600 Void handlerNONE(Handle hwi, UInt intNum);
601
602 Void handlerALL(Handle hwi, UInt intNum);
603
604 Void handlerLOWER(Handle hwi, UInt intNum);
605
606 Void handlerSELF(Handle hwi, UInt intNum);
607
608 /*!
609 * const array to hold all HookSet objects.
610 */
611 config HookSet hooks[length] = [];
612
613 /*! Meta World Only Hwi Configuration Object. */
614 metaonly struct InterruptObj {
615 String name;
616 Bool used;
617 Bool useDispatcher;
618 UInt priority;
619 FuncPtr fxn;
620 PlugFuncPtr pfxn;
621 };
622
623 /*!
624 * Meta-only array of interrupt objects.
625 * This meta-only array of Hwi config objects is initialized
626 * in Hwi.xs:module$meta$init().
627 */
628 metaonly config InterruptObj interrupt[NUM_INTERRUPTS];
629
630 struct Instance_State {
631 UArg arg;
632 FuncPtr fxn;
633 Int intNum;
634 HandlerFuncPtr handler;
635 Irp irp;
636 Ptr hookEnv[];
637 };
638
639 struct Module_State {
640 Bits32 er[4];
641 UInt irp;
642 UInt8 priorities[NUM_INTERRUPTS];
643
644 Char *taskSP;
645
646
647 Ptr vectorTableBase;
648 Char *isrStack;
649 Ptr isrStackBase;
650 Ptr isrStackSize;
651 Char fiqStack[];
652 SizeT fiqStackSize;
653
654 Handle dispatchTable[NUM_INTERRUPTS];
655
656 };
657 }
658