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.dm6446;
37
38 import xdc.rov.ViewInfo;
39
40 import xdc.runtime.Diags;
41 import xdc.runtime.Error;
42 import xdc.runtime.Log;
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 * @a(NOTE)
54 * In this Hwi module implementation, the instance config parameter value
55 * {@link #MaskingOption_LOWER} is equivalent to {@link #MaskingOption_SELF}.
56 * Statically configuring a Hwi object's {@link #Params.maskSetting} to
57 * {@link #MaskingOption_LOWER} will result in the generation of a benign
58 * build warning. Dynamic usages of {@link #MaskingOption_LOWER} will be
59 * silently converted to {@link #MaskingOption_SELF}.
60 *
61 * @p(html)
62 * <h3> Calling Context </h3>
63 * <table border="1" cellpadding="3">
64 * <colgroup span="1"></colgroup> <colgroup span="5" align="center"></colgroup>
65 *
66 * <tr><th> Function </th><th> Hwi </th><th> Swi </th><th> Task </th><th> Main </th><th> Startup </th></tr>
67 * <!-- -->
68 * <tr><td> {@link #clearInterrupt} </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td></tr>
69 * <tr><td> {@link #create} </td><td> N </td><td> N </td><td> Y </td><td> Y </td><td> N </td></tr>
70 * <tr><td> {@link #disable} </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td></tr>
71 * <tr><td> {@link #disableEINT0} </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td><td> N </td></tr>
72 * <tr><td> {@link #disableEINT1} </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td><td> N </td></tr>
73 * <tr><td> {@link #disableFIQ} </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td></tr>
74 * <tr><td> {@link #disableInterrupt} </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td><td> N </td></tr>
75 * <tr><td> {@link #disableIRQ} </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td></tr>
76 * <tr><td> {@link #enable} </td><td> Y </td><td> Y </td><td> Y </td><td> N </td><td> N </td></tr>
77 * <tr><td> {@link #enableEINT0} </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td><td> N </td></tr>
78 * <tr><td> {@link #enableEINT1} </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td><td> N </td></tr>
79 * <tr><td> {@link #enableFIQ} </td><td> Y </td><td> Y </td><td> Y </td><td> N </td><td> N </td></tr>
80 * <tr><td> {@link #enableInterrupt} </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td><td> N </td></tr>
81 * <tr><td> {@link #enableIRQ} </td><td> Y </td><td> Y </td><td> Y </td><td> N </td><td> N </td></tr>
82 * <tr><td> {@link #getHandle} </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td><td> N </td></tr>
83 * <tr><td> {@link #Params_init} </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td></tr>
84 * <tr><td> {@link #restore} </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td></tr>
85 * <tr><td> {@link #restoreEINT0} </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td><td> N </td></tr>
86 * <tr><td> {@link #restoreEINT1} </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td><td> N </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 DM6446 ARM Interrupt Controller supports 64 interrupts. */
133 const Int NUM_INTERRUPTS = 64;
134
135
136
137 /*! Hwi vector function type definition. */
138 typedef Void (*VectorFuncPtr)(void);
139
140 /*!
141 * ARM Interrupt Controller.
142 */
143 struct AINTC {
144 UInt32 FIQ0; /*! 0x00 Interrupt Status of INT [31:0] if mapped to FIQ */
145 UInt32 FIQ1; /*! 0x04 Interrupt Status of INT [63:32] if mapped to FIQ */
146 UInt32 IRQ0; /*! 0x08 Interrupt Status of INT [31:0] if mapped to IRQ */
147 UInt32 IRQ1; /*! 0x0C Interrupt Status of INT [63:32] if mapped to IRQ */
148 UInt32 FIQENTRY;/*! 0x10 Entry Address [28:0] for valid FIQ interrupt */
149 UInt32 IRQENTRY;/*! 0x14 Entry Address [28:0] for valid IRQ interrupt */
150 UInt32 EINT0; /*! 0x18 Interrupt Enable Register 0 */
151 UInt32 EINT1; /*! 0x1C Interrupt Enable Register 1 */
152 UInt32 INTCTL; /*! 0x20 Interrupt Operation Control Register */
153 UInt32 EABASE; /*! 0x24 Interrupt Entry Base Address */
154 UInt32 RES[2]; /*! 0x28 reserved */
155 UInt32 INTPR[8];/*! 0x30 Interrupt 0-7 Priority select */
156
157
158
159
160
161
162
163 };
164
165 /*!
166 * Physical ARM Interrupt Controller Device.
167 * Short name is "Hwi_aIntc"
168 * Long name is "ti_sysbios_family_arm_dm6446_Hwi_aIntc"
169 */
170 extern volatile AINTC aIntc;
171
172 /*!
173 * ======== BasicView ========
174 * @_nodoc
175 */
176 metaonly struct BasicView {
177 Ptr halHwiHandle;
178 String label;
179 Int intNum;
180 Int priority;
181 String fxn;
182 UArg arg;
183 Ptr irp;
184 String status;
185 };
186
187 /*!
188 * ======== ModuleView ========
189 * @_nodoc
190 */
191 metaonly struct ModuleView {
192 String options[4];
193 String hwiStackPeak;
194 SizeT hwiStackSize;
195 Ptr hwiStackBase;
196 };
197
198 /*!
199 * ======== rovViewInfo ========
200 * @_nodoc
201 */
202 @Facet
203 metaonly config ViewInfo.Instance rovViewInfo =
204 ViewInfo.create({
205 viewMap: [
206 ['Basic', {type: ViewInfo.INSTANCE, viewInitFxn: 'viewInitBasic', structName: 'BasicView'}],
207 ['Module', {type: ViewInfo.MODULE, viewInitFxn: 'viewInitModule', structName: 'ModuleView'}]
208 ]
209 });
210
211
212
213 /*! Reset Handler. Default is c_int00 */
214 metaonly config VectorFuncPtr resetFunc;
215
216 /*! Undefined instruction exception handler. Default is self loop */
217 metaonly config VectorFuncPtr undefinedInstFunc;
218
219 /*! SWI Handler. Default is internal SWI handler */
220 metaonly config VectorFuncPtr swiFunc;
221
222 /*! Prefetch abort exception handler. Default is self loop */
223 metaonly config VectorFuncPtr prefetchAbortFunc;
224
225 /*! Data abort exception handler. Default is self loop */
226 metaonly config VectorFuncPtr dataAbortFunc;
227
228 /*! Reserved exception handler. Default is self loop */
229 metaonly config VectorFuncPtr reservedFunc;
230
231 /*! IRQ interrupt handler. Default is internal IRQ dispatcher */
232 metaonly config VectorFuncPtr irqFunc;
233
234 /*! FIQ interrupt handler. Default is internal FIQ dispatcher */
235 metaonly config VectorFuncPtr fiqFunc;
236
237 /*!
238 * FIQ stack pointer. Default = null.
239 * (Indicates that stack is to be created using
240 * staticPlace()
241 */
242 config Ptr fiqStack = null;
243
244 /*!
245 * FIQ stack size in MAUs.
246 * Default is 1024 bytes.
247 */
248 metaonly config SizeT fiqStackSize = 1024;
249
250 /*!
251 * Memory section used for FIQ stack
252 * Default is null.
253 */
254 metaonly config String fiqStackSection = null;
255
256 /*!
257 * EABASE Size Setting. Default is 4 bytes per entry.
258 * Options are 4, 8, 16, 32 bytes per entry.
259 */
260 config Bits32 eabaseSize = 4;
261
262 /*!
263 * Error raised when Hwi is already defined
264 */
265 config Error.Id E_alreadyDefined = {
266 msg: "E_alreadyDefined: Hwi already defined: intr# %d"
267 };
268
269 /*!
270 * Issued just prior to Hwi function invocation (with interrupts disabled)
271 */
272 config Log.Event LM_begin = {
273 mask: Diags.USER1 | Diags.USER2,
274 msg: "LM_begin: hwi: 0x%x, func: 0x%x, preThread: %d, intNum: %d, irp: 0x%x"
275 };
276
277 /*!
278 * Issued just after return from Hwi function (with interrupts disabled)
279 */
280 config Log.Event LD_end = {
281 mask: Diags.USER2,
282 msg: "LD_end: hwi: 0x%x"
283 };
284
285
286
287
288 /*!
289 * ======== disable ========
290 * Globally disable interrupts.
291 *
292 * Hwi_disable globally disables hardware interrupts and returns an
293 * opaque key indicating whether interrupts were globally enabled or
294 * disabled on entry to Hwi_disable().
295 * The actual value of the key is target/device specific and is meant
296 * to be passed to Hwi_restore().
297 *
298 * Call Hwi_disable before a portion of a function that needs
299 * to run without interruption. When critical processing is complete, call
300 * Hwi_restore or Hwi_enable to reenable hardware interrupts.
301 *
302 * Servicing of interrupts that occur while interrupts are disabled is
303 * postponed until interrupts are reenabled. However, if the same type
304 * of interrupt occurs several times while interrupts are disabled,
305 * the interrupt's function is executed only once when interrupts are
306 * reenabled.
307 *
308 * A context switch can occur when calling Hwi_enable or Hwi_restore if
309 * an enabled interrupt occurred while interrupts are disabled.
310 *
311 * Hwi_disable may be called from main(). However, since Hwi interrupts
312 * are already disabled in main(), such a call has no effect.
313 *
314 * @a(constraints)
315 * If a Task switching API such as
316 * {@link ti.sysbios.knl.Semaphore#pend Semaphore_pend()},
317 * {@link ti.sysbios.knl.Semaphore#post Semaphore_post()},
318 * {@link ti.sysbios.knl.Task#sleep Task_sleep()}, or
319 * {@link ti.sysbios.knl.Task#yield Task_yield()}
320 * is invoked which results in a context switch while
321 * interrupts are disabled, an embedded call to
322 * {@link #enable Hwi_enable} occurs
323 * on the way to the new thread context which unconditionally re-enables
324 * interrupts. Interrupts will remain enabled until a subsequent
325 * {@link #disable Hwi_disable}
326 * invocation.
327 *
328 * Swis always run with interrupts enabled.
329 * See {@link ti.sysbios.knl.Swi#post Swi_post()} for a discussion Swis and
330 * interrupts.
331 *
332 * @b(returns) opaque key for use by Hwi_restore()
333 */
334 @Macro
335 override UInt disable();
336
337 /*!
338 * ======== enable ========
339 */
340 @Macro
341 override UInt enable();
342
343 /*!
344 * ======== restore ========
345 */
346 @Macro
347 override Void restore(UInt key);
348
349 /*!
350 * @_nodoc
351 * ======== inUseMeta ========
352 * Check for Hwi already in use.
353 * For internal SYS/BIOS use only.
354 * Should be called prior to any internal Hwi.create().
355 *
356 * @param(intNum) interrupt number
357 */
358 metaonly Bool inUseMeta(UInt intNum);
359
360 /*!
361 * ======== getHandle ========
362 * Returns pointer to Hwi instance object.
363 *
364 * @param(intNum) interrupt number
365 */
366 Object *getHandle(UInt intNum);
367
368 /*!
369 * @_nodoc
370 * ======== getInstance ========
371 * Returns pointer to Hwi instance object.
372 *
373 * @param(intNum) interrupt number
374 */
375 Object *getInstance(UInt intNum);
376
377 /*!
378 * ======== enableFIQ ========
379 * Enable FIQ interrupts.
380 *
381 * @b(returns) previous FIQ interrupt enable/disable state
382 */
383 UInt enableFIQ();
384
385 /*!
386 * ======== disableFIQ ========
387 * Disable FIQ interrupts.
388 *
389 * @b(returns) previous FIQ interrupt enable/disable state
390 */
391 UInt disableFIQ();
392
393 /*!
394 * ======== restoreFIQ ========
395 * Restore FIQ interrupts.
396 *
397 * @param(key) enable/disable state to restore
398 */
399 Void restoreFIQ(UInt key);
400
401 /*!
402 * ======== enableIRQ ========
403 * Enable IRQ interrupts.
404 *
405 * @param(key) enable/disable state to restore
406 */
407 UInt enableIRQ();
408
409 /*!
410 * ======== disableIRQ ========
411 * Disable IRQ interrupts.
412 *
413 * @b(returns) previous IRQ interrupt enable/disable state
414 */
415 UInt disableIRQ();
416
417 /*!
418 * ======== restoreIRQ ========
419 * Restore IRQ interrupts.
420 *
421 * @param(key) enable/disable state to restore
422 */
423 Void restoreIRQ(UInt key);
424
425 /*!
426 * ======== disableEINT0 ========
427 * Disable specific interrupts (0-31).
428 *
429 * Disables specific interrupts by clearing the bits specified by
430 * 'mask' in the EINT0.
431 *
432 * @param(mask) bitmask of interrupts to disable
433 * @b(returns) previous EINT0 settings bitmask
434 */
435 Bits32 disableEINT0(Bits32 mask);
436
437 /*!
438 * ======== disableEINT1 ========
439 * Disable specific interrupts (32-63).
440 *
441 * Disables specific interrupts by clearing the bits specified by
442 * 'mask' in the EINT1.
443 *
444 * @param(mask) bitmask of interrupts to disable
445 * @b(returns) previous EINT1 settings bitmask
446 */
447 Bits32 disableEINT1(Bits32 mask);
448
449 /*!
450 * ======== enableEINT0 ========
451 * Enable specific interrupts (0-31).
452 *
453 * Enables specific interrupts by clearing the bits specified by
454 * 'mask' in the EINT0.
455 *
456 * @param(mask) bitmask of interrupts to disable
457 * @b(returns) previous EINT0 settings bitmask
458 */
459 Bits32 enableEINT0(Bits32 mask);
460
461 /*!
462 * ======== enableEINT1 ========
463 * Enable specific interrupts (32-63).
464 *
465 * Enables specific interrupts by clearing the bits specified by
466 * 'mask' in the EINT0.
467 *
468 * @param(mask) bitmask of interrupts to disable
469 * @b(returns) previous EINT0 settings bitmask
470 */
471 Bits32 enableEINT1(Bits32 mask);
472
473 /*!
474 * ======== restoreEINT0 ========
475 * Restore maskable interrupts to the state they were in
476 * when either disableEINT0() or enableEINT0() was called.
477 *
478 * Simply writes mask to the EINT0 register.
479 *
480 * @param(mask) bitmask of interrupts to restore
481 * @b(returns) previous EINT0 settings bitmask
482 */
483 Bits32 restoreEINT0(Bits32 mask);
484
485 /*!
486 * ======== restoreEINT1 ========
487 * Restore maskable interrupts to the state they were in
488 * when either disableEINT1() or enableEINT1() was called.
489 *
490 * Simply writes mask to the EINT1 register.
491 *
492 * @param(mask) bitmask of interrupts to restore
493 * @b(returns) previous EINT1 settings bitmask
494 */
495 Bits32 restoreEINT1(Bits32 mask);
496
497 /*!
498 * ======== setPriority ========
499 * Set an interrupt's relative priority.
500 *
501 * Priority 0-1 define the interrupt as an FIQ interrupt
502 * Priority 2-7 define the interrupt as an IRQ interrupt
503 *
504 * @param(intNum) ID of interrupt
505 * @param(priority) priority
506 */
507 Void setPriority(UInt intNum, UInt priority);
508
509 instance:
510
511 /*! disableMask0. default is derived from MaskingOption_SELF maskSetting. */
512 config Bits32 disableMask0 = 0;
513
514 /*! disableMask1. default is derived from MaskingOption_SELF maskSetting. */
515 config Bits32 disableMask1 = 0;
516
517 /*! restoreMask0. default is derived from MaskingOption_SELF maskSetting. */
518 config Bits32 restoreMask0 = 0;
519
520 /*! restoreMask1. default is derived from MaskingOption_SELF maskSetting. */
521 config Bits32 restoreMask1 = 0;
522
523 /*!
524 * Interrupt priority (0-7). Default is 7 which is the
525 * lowest priority IRQ interrupt.
526 */
527 override config Int priority = 7;
528
529 /*!
530 * ======== reconfig ========
531 * Reconfigure a dispatched interrupt.
532 */
533 Void reconfig(FuncPtr fxn, const Params *params);
534
535 internal:
536
537 538 539 540 541 542
543 config UInt (*swiDisable)();
544 config Void (*swiRestoreHwi)(UInt);
545 config UInt (*taskDisable)();
546 config Void (*taskRestoreHwi)(UInt);
547
548 549 550 551
552 Int postInit(Object *hwi, Error.Block *eb);
553
554 555 556
557 Void initIntController();
558
559 560 561 562 563
564 UInt interruptType(UInt intNum);
565
566
567 Void init();
568
569
570 Void dispatchIRQ();
571
572
573 Void dispatchIRQC(Irp irp);
574
575
576 Void dispatchFIQC();
577
578 /*!
579 * const array to hold all HookSet objects.
580 */
581 config HookSet hooks[length] = [];
582
583 /*! Meta World Only Hwi Configuration Object. */
584 metaonly struct InterruptObj {
585 Bool used;
586 Bool useDispatcher;
587 FuncPtr fxn;
588 };
589
590 /*!
591 * Meta-only array of interrupt objects.
592 * This meta-only array of Hwi config objects is initialized
593 * in Hwi.xs:module$meta$init().
594 */
595 metaonly config InterruptObj interrupt[NUM_INTERRUPTS];
596
597 metaonly config Bool assignResetVector = true;
598
599 struct Instance_State {
600 UInt priority;
601 Bits32 disableMask0;
602 Bits32 disableMask1;
603 Bits32 restoreMask0;
604 Bits32 restoreMask1;
605 UArg arg;
606 FuncPtr fxn;
607 Int intNum;
608 Irp irp;
609 Ptr hookEnv[];
610 };
611
612 struct Module_State {
613 Bits32 eint0Mask;
614 Bits32 eint1Mask;
615 UInt irp;
616 Char *taskSP;
617
618
619
620 Char *isrStack;
621 Ptr isrStackBase;
622 Ptr isrStackSize;
623 Char fiqStack[];
624 SizeT fiqStackSize;
625
626 Handle dispatchTable[NUM_INTERRUPTS];
627
628 };
629 }
630