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