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
37 package ti.sysbios.family.arm.m3;
38
39 import xdc.rov.ViewInfo;
40 import xdc.runtime.Diags;
41 import xdc.runtime.Log;
42 import xdc.runtime.Assert;
43 import xdc.runtime.Error;
44
45 import ti.sysbios.BIOS;
46 import ti.sysbios.interfaces.IHwi;
47
48 /*!
49 * ======== Hwi ========
50 * Cortex M3 Hardware Interrupt Manager
51 *
52 * The Cortex M3's Nested Vectored Interrupt Controller (NVIC)
53 * supports up to 256 interrupts/exceptions. In practice, most
54 * devices support much fewer (ie the Stellaris family of devices
55 * have only 80 total interrupts defined).
56 *
57 * SYS/BIOS Interrupt IDs or interrupt numbers correspond
58 * to an interrupt's position in the interrupt vector table.
59 *
60 * ID 0 corresponds to vector 0 which is used by the NVIC
61 * to hold the initial (reset) stack pointer value.
62 *
63 * ID 1 corresponds to vector 1 which is the reset vector (ie _c_int00)
64 *
65 * IDs 2-14 are hardwired to exceptions.
66 *
67 * ID 15 is the SysTick timer interrupt.
68 *
69 * ID's 16-255 are mapped to the NVIC's user interrupts 0-239
70 * which are tied to platform specific interrupt sources.
71 *
72 * The M3 Hwi module supports "zero latency" interrupts.
73 * Interrupts configured with priority greater (in priority,
74 * lower in number) than {@link #disablePriority}
75 * are NOT disabled by {@link #disable}.
76 *
77 * Zero latency interrupts are not handled by the SYS/BIOS interrupt
78 * dispatcher. Instead, they are vectored to directly.
79 * As such, and because they are not masked by {@link #disable},
80 * these interrupt handlers are severely restricted in terms of the
81 * SYS/BIOS APIs they can invoke and THREAD SAFETY MUST BE CAREFULLY
82 * CONSIDERED!
83 *
84 * Due to the M3's native automatic stacking of saved-by-caller C
85 * context on the way to an ISR, zero latency interrupt handlers
86 * are implemented using regular C functions (ie no 'interrupt'
87 * keyword is required).
88 *
89 * Zero latency interrupts are distinguished from regular dispatched
90 * interrupts at create time by their priority being greater than
91 * {@link #disablePriority}.
92 *
93 * Note that since zero latency interrupts don't use the dispatcher,
94 * the {@link ti.sysbios.interfaces.IHwi#arg arg} parameter is not
95 * functional.
96 *
97 * @a(Interrupt Masking Options)
98 *
99 * The NVIC interrupt controller is designed for priority based
100 * interrupts.
101 *
102 * No support is provided for anything but {@link #MaskingOption_LOWER}.
103 *
104 * @a(Interrupt Priorities)
105 *
106 * In general, the NVIC supports priority values of 0 thru 255.
107 *
108 * In practice valid priorities values are device dependent and their
109 * nesting behaviors depend on the {@link #priGroup} setting.
110 *
111 * Priority 0 is the highest priority and by default is
112 * reserved for zero latency interrupts
113 * (see {@link #disablePriority}).
114 *
115 * See the Cortex M3 architecture reference manual for details
116 * on the behavior of interrupt priorities and their relationship
117 * to the {@link #priGroup} setting.
118 *
119 * @a(Interrupt Vector Tables)
120 * Tiva devices:
121 *
122 * By default, two vector tables are created for Tiva devices:
123 *
124 * A 16 entry boot vector table is placed at address 0x00000000 in
125 * FLASH.
126 *
127 * An 80 entry vector table is placed at address 0x20000000 in RAM.
128 *
129 * The FLASH boot vector table contains the reset vector and exception
130 * handler vectors used until the RAM based vector table is initialized.
131 *
132 * The RAM vector table contains the 16 exception vectors as well as all
133 * the 64 user interrupt vectors.
134 *
135 * During system startup, the NVIC Vector Table Offset Registor is
136 * intialized to point to this vector table after the table has been
137 * initialized.
138 *
139 * @a( )
140 * Dual M3 Core ('Ducati') devices:
141 *
142 * By default, Ducati core 0 places its runtime vector table at address
143 * 0x00000400 and core 1 places its runtime vector table at address
144 * 0x00000800.
145 *
146 * Additionally, a boot vector table is placed at address
147 * 0x00000000 which is shared by both cores.
148 *
149 * The boot reset vector function determines which core it is being
150 * executed on and jumps to the reset vector contained in its corresponding
151 * runtime vector table.
152 *
153 * The generation and placement of these vector tables is made
154 * automatically when the
155 * {@link ti.sysbios.family.arm.ducati.Core} module is used.
156 *
157 * Although STRONGLY discouraged, this default behavior can be overridden
158 * by explicitly setting the
159 * {@link #resetVectorAddress Hwi.resetVectorAddress} and
160 * {@link #vectorTableAddress Hwi.vectorTableAddress} config parameters.
161 *
162 * @a(Restrictions)
163 * When used within a dual M3 core (Ducati) arrangement, care must be
164 * taken when initializing this shared resource.
165 * The "Shared Resources" note provided
166 * in the {@link ti.sysbios.family.arm.ducati ducati} package discusses
167 * the management of the various hardware and software resources
168 * shared by the two M3 cores.
169 * @a
170 *
171 * @p(html)
172 * <h3> Calling Context </h3>
173 * <table border="1" cellpadding="3">
174 * <colgroup span="1"></colgroup> <colgroup span="5" align="center"></colgroup>
175 *
176 * <tr><th> Function </th><th> Hwi </th><th> Swi </th><th> Task </th><th> Main </th><th> Startup </th></tr>
177 * <!-- -->
178 * <tr><td> {@link #clearInterrupt} </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td></tr>
179 * <tr><td> {@link #create} </td><td> N </td><td> N </td><td> Y </td><td> Y </td><td> N </td></tr>
180 * <tr><td> {@link #disable} </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td></tr>
181 * <tr><td> {@link #disableInterrupt} </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td><td> N </td></tr>
182 * <tr><td> {@link #enable} </td><td> Y </td><td> Y </td><td> Y </td><td> N </td><td> N </td></tr>
183 * <tr><td> {@link #enableInterrupt} </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td><td> N </td></tr>
184 * <tr><td> {@link #Params_init} </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td></tr>
185 * <tr><td> {@link #restore} </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td></tr>
186 * <tr><td> {@link #restoreInterrupt} </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td></tr>
187 * <tr><td> {@link #construct} </td><td> N </td><td> N </td><td> Y </td><td> Y </td><td> N </td></tr>
188 * <tr><td> {@link #delete} </td><td> N </td><td> N </td><td> Y </td><td> Y </td><td> N </td></tr>
189 * <tr><td> {@link #destruct} </td><td> N </td><td> N </td><td> Y </td><td> Y </td><td> N </td></tr>
190 * <tr><td> {@link #getHookContext} </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td><td> N </td></tr>
191 * <tr><td> {@link #setFunc} </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td><td> N </td></tr>
192 * <tr><td> {@link #setHookContext} </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td><td> N </td></tr>
193 * <tr><td colspan="6"> Definitions: <br />
194 * <ul>
195 * <li> <b>Hwi</b>: API is callable from a Hwi thread. </li>
196 * <li> <b>Swi</b>: API is callable from a Swi thread. </li>
197 * <li> <b>Task</b>: API is callable from a Task thread. </li>
198 * <li> <b>Main</b>: API is callable during any of these phases: </li>
199 * <ul>
200 * <li> In your module startup after this module is started (e.g. Hwi_Module_startupDone() returns TRUE). </li>
201 * <li> During xdc.runtime.Startup.lastFxns. </li>
202 * <li> During main().</li>
203 * <li> During BIOS.startupFxns.</li>
204 * </ul>
205 * <li> <b>Startup</b>: API is callable during any of these phases:</li>
206 * <ul>
207 * <li> During xdc.runtime.Startup.firstFxns.</li>
208 * <li> In your module startup before this module is started (e.g. Hwi_Module_startupDone() returns FALSE).</li>
209 * </ul>
210 * </ul>
211 * </td></tr>
212 *
213 * </table>
214 * @p
215 */
216
217
218 @Template("./Hwi.xdt")
219 @ModuleStartup
220 @InstanceInitStatic
221
222 module Hwi inherits ti.sysbios.interfaces.IHwi
223 {
224
225
226 /*!
227 * The Cortex M3 NVIC supports up to 256 interrupts/exceptions.
228 *
229 * The actual number supported is device specific and provided by
230 * the catalog device specification.
231 */
232 config Int NUM_INTERRUPTS;
233
234 /*!
235 * The Cortex M3 NVIC supports up to 256 interrupt priorities.
236 *
237 * The actual number supported is device specific and provided by
238 * the catalog device specification.
239 */
240 config Int NUM_PRIORITIES;
241
242
243
244 /*! Hwi vector function type definition. */
245 typedef Void (*VectorFuncPtr)(void);
246
247 /*! Exception hook function type definition. */
248 typedef Void (*ExceptionHookFuncPtr)(ExcContext *);
249
250 /*! NVIC Configuration Control Register (CCR). */
251 struct CCR {
252 Bits8 STKALIGN; /*! Auto stack alignment in exception */
253 Bits8 BFHFNMIGN; /*! All faults ignore BUS Faults */
254 Bits8 DIV_0_TRP; /*! Trap on divide by zero */
255 Bits8 UNALIGN_TRP; /*! Trap on all unaligned accesses */
256 Bits8 USERSETMPEND; /*! Allow user to trigger interrupts */
257 Bits8 NONEBASETHRDENA; /*! Allow entering thread mode anytime */
258 };
259
260 /*! @_nodoc
261 * Nested Vectored Interrupt Controller.
262 */
263 struct NVIC {
264 UInt32 RES_00; /*! 0xE000E000 reserved */
265 UInt32 ICTR; /*! 0xE000E004 Interrupt Control Type */
266 UInt32 RES_08; /*! 0xE000E008 reserved */
267 UInt32 RES_0C; /*! 0xE000E00C reserved */
268 UInt32 STCSR; /*! 0xE000E010 SysTick Control & Status Register */
269 UInt32 STRVR; /*! 0xE000E014 SysTick Reload Value Register */
270 UInt32 STCVR; /*! 0xE000E018 SysTick Current Value Register */
271 UInt32 STCALIB; /*! 0xE000E01C SysTick Calibration Value Register */
272 UInt32 RES_20 [56]; /*! 0xE000E020-0xE000E0FC reserved */
273 UInt32 ISER [8]; /*! 0xE000E100-0xE000E11C Interrupt Set Enable Registers */
274 UInt32 RES_120 [24]; /*! 0xE000E120-0xE000E17C reserved */
275 UInt32 ICER [8]; /*! 0xE000E180-0xE000E19C Interrupt Clear Enable Registers */
276 UInt32 RES_1A0 [24]; /*! 0xE000E1A0-0xE000E1FC reserved */
277 UInt32 ISPR [8]; /*! 0xE000E200-0xE000E21C Interrupt Set Pending Registers */
278 UInt32 RES_220 [24]; /*! 0xE000E220-0xE000E7C reserved */
279 UInt32 ICPR [8]; /*! 0xE000E280-0xE000E29C Interrupt Clear Pending Registers */
280 UInt32 RES_2A0 [24]; /*! 0xE000E2A0-0xE000E2FC reserved */
281 UInt32 IABR [8]; /*! 0xE000E300-0xE000E31C Interrupt Active Bit Registers */
282 UInt32 RES_320 [56]; /*! 0xE000E320-0xE000E3FC reserved */
283 UInt8 IPR [240]; /*! 0xE000E400-0xE000E4EF Interrupt Priority Registers */
284 UInt32 RES_4F0 [516];/*! 0xE000E4F0-0xE000ECFC reserved */
285 UInt32 CPUIDBR; /*! 0xE000ED00 CPUID Base Register */
286 UInt32 ICSR; /*! 0xE000ED04 Interrupt Control State Register */
287 UInt32 VTOR; /*! 0xE000ED08 Vector Table Offset Register */
288 UInt32 AIRCR; /*! 0xE000ED0C Application Interrupt/Reset Control Register */
289 UInt32 SCR; /*! 0xE000ED10 System Control Register */
290 UInt32 CCR; /*! 0xE000ED14 Configuration Control Register */
291 UInt8 SHPR[12]; /*! 0xE000ED18 System Handlers 4-15 Priority Registers */
292 UInt32 SHCSR; /*! 0xE000ED24 System Handler Control & State Register */
293 UInt8 MMFSR; /*! 0xE000ED28 Memory Manage Fault Status Register */
294 UInt8 BFSR; /*! 0xE000ED29 Bus Fault Status Register */
295 UInt16 UFSR; /*! 0xE000ED2A Usage Fault Status Register */
296 UInt32 HFSR; /*! 0xE000ED2C Hard Fault Status Register */
297 UInt32 DFSR; /*! 0xE000ED30 Debug Fault Status Register */
298 UInt32 MMAR; /*! 0xE000ED34 Memory Manager Address Register */
299 UInt32 BFAR; /*! 0xE000ED38 Bus Fault Address Register */
300 UInt32 AFSR; /*! 0xE000ED3C Auxiliary Fault Status Register */
301 UInt32 PFR0; /*! 0xE000ED40 Processor Feature Register */
302 UInt32 PFR1; /*! 0xE000ED44 Processor Feature Register */
303 UInt32 DFR0; /*! 0xE000ED48 Debug Feature Register */
304 UInt32 AFR0; /*! 0xE000ED4C Auxiliary Feature Register */
305 UInt32 MMFR0; /*! 0xE000ED50 Memory Model Fault Register0 */
306 UInt32 MMFR1; /*! 0xE000ED54 Memory Model Fault Register1 */
307 UInt32 MMFR2; /*! 0xE000ED58 Memory Model Fault Register2 */
308 UInt32 MMFR3; /*! 0xE000ED5C Memory Model Fault Register3 */
309 UInt32 ISAR0; /*! 0xE000ED60 ISA Feature Register0 */
310 UInt32 ISAR1; /*! 0xE000ED64 ISA Feature Register1 */
311 UInt32 ISAR2; /*! 0xE000ED68 ISA Feature Register2 */
312 UInt32 ISAR3; /*! 0xE000ED6C ISA Feature Register3 */
313 UInt32 ISAR4; /*! 0xE000ED70 ISA Feature Register4 */
314 UInt32 RES_D74[5]; /*! 0xE000ED74-0xE000ED84 reserved */
315 UInt32 CPACR; /*! 0xE000ED88 Coprocessor Access Control Register */
316 UInt32 RES_D8C[93]; /*! 0xE000ED8C-0xE000EEFC reserved */
317 UInt32 STI; /*! 0xE000EF00 Software Trigger Interrupt Register */
318 UInt32 RES_F04[12]; /*! 0xE000EF04-0xE000EF30 reserved */
319 UInt32 FPCCR; /*! 0xE000EF34 FP Context Control Register */
320 UInt32 FPCAR; /*! 0xE000EF38 FP Context Address Register */
321 UInt32 FPDSCR; /*! 0xE000EF3C FP Default Status Control Register */
322 UInt32 MVFR0; /*! 0xE000EF40 Media & FP Feature Register0 */
323 UInt32 MVFR1; /*! 0xE000EF44 Media & FP Feature Register1 */
324 UInt32 RES_F48[34]; /*! 0xE000EF48-0xE000EFCC reserved */
325 UInt32 PID4; /*! 0xE000EFD0 Peripheral ID Register4 */
326 UInt32 PID5; /*! 0xE000EFD4 Peripheral ID Register5 */
327 UInt32 PID6; /*! 0xE000EFD8 Peripheral ID Register6 */
328 UInt32 PID7; /*! 0xE000EFDC Peripheral ID Register7 */
329 UInt32 PID0; /*! 0xE000EFE0 Peripheral ID Register0 */
330 UInt32 PID1; /*! 0xE000EFE4 Peripheral ID Register1 */
331 UInt32 PID2; /*! 0xE000EFE8 Peripheral ID Register2 */
332 UInt32 PID3; /*! 0xE000EFEC Peripheral ID Register3 */
333 UInt32 CID0; /*! 0xE000EFF0 Component ID Register0 */
334 UInt32 CID1; /*! 0xE000EFF4 Component ID Register1 */
335 UInt32 CID2; /*! 0xE000EFF8 Component ID Register2 */
336 UInt32 CID3; /*! 0xE000EFFC Component ID Register3 */
337 }
338
339 /*!
340 * Physical Nested Vectored Interrupt Controller Device.
341 * Short name is "Hwi_nvic"
342 * Long name is "ti_sysbios_family_arm_m3_Hwi_nvic"
343 */
344 extern volatile NVIC nvic;
345
346 /*!
347 * Virtual Nested Vectored Interrupt Controller structure
348 * written to by both cores for SMP.
349 * Short name is "Hwi_vnvic"
350 * Long name is "ti_sysbios_family_arm_m3_Hwi_vnvic"
351 */
352 extern volatile NVIC vnvic;
353
354 /*!
355 * Exception Context - Register contents at the time of an exception.
356 */
357 struct ExcContext {
358
359 BIOS.ThreadType threadType;
360
361 Ptr threadHandle;
362
363 Ptr threadStack;
364
365
366 SizeT threadStackSize;
367
368
369 Ptr r0;
370 Ptr r1;
371 Ptr r2;
372 Ptr r3;
373 Ptr r4;
374 Ptr r5;
375 Ptr r6;
376 Ptr r7;
377 Ptr r8;
378 Ptr r9;
379 Ptr r10;
380 Ptr r11;
381 Ptr r12;
382 Ptr sp;
383 Ptr lr;
384 Ptr pc;
385 Ptr psr;
386
387
388 Ptr ICSR;
389 Ptr MMFSR;
390 Ptr BFSR;
391 Ptr UFSR;
392 Ptr HFSR;
393 Ptr DFSR;
394 Ptr MMAR;
395 Ptr BFAR;
396 Ptr AFSR;
397 }
398
399 /*! @_nodoc */
400 metaonly struct BasicView {
401 Ptr halHwiHandle;
402 String label;
403 String type;
404 Int intNum;
405 Int priority;
406 Int group;
407 Int subPriority;
408 String fxn;
409 UArg arg;
410 };
411
412 /*! @_nodoc */
413 metaonly struct DetailedView {
414 Ptr halHwiHandle;
415 String label;
416 String type;
417 Int intNum;
418 Int priority;
419 Int group;
420 Int subPriority;
421 String fxn;
422 UArg arg;
423 Ptr irp;
424 String status;
425 Int coreId;
426 };
427
428 /*! @_nodoc */
429 metaonly struct ModuleView {
430 String options[4];
431 String activeInterrupt;
432 String pendingInterrupt;
433 String exception;
434 String hwiStackPeak;
435 SizeT hwiStackSize;
436 Ptr hwiStackBase;
437 };
438
439 /*! @_nodoc */
440 @Facet
441 metaonly config ViewInfo.Instance rovViewInfo =
442 ViewInfo.create({
443 viewMap: [
444 ['Basic',
445 {
446 type: ViewInfo.INSTANCE,
447 viewInitFxn: 'viewInitBasic',
448 structName: 'BasicView'
449 }
450 ],
451 ['Detailed',
452 {
453 type: ViewInfo.INSTANCE,
454 viewInitFxn: 'viewInitDetailed',
455 structName: 'DetailedView'
456 }
457 ],
458 ['Module',
459 {
460 type: ViewInfo.MODULE,
461 viewInitFxn: 'viewInitModule',
462 structName: 'ModuleView'
463 }
464 ],
465 ['Exception',
466 {
467 type: ViewInfo.TREE,
468 viewInitFxn: 'viewInitException',
469 structName: 'ExcContext'
470 }
471 ]
472 ]
473 });
474
475
476
477
478
479 /*!
480 * Issued just prior to Hwi function invocation (with interrupts disabled)
481 */
482 config Log.Event LM_begin = {
483 mask: Diags.USER1 | Diags.USER2,
484 msg: "LM_begin: hwi: 0x%x, func: 0x%x, preThread: %d, intNum: %d, irp: 0x%x"
485 };
486
487 /*!
488 * Issued just after return from Hwi function (with interrupts disabled)
489 */
490 config Log.Event LD_end = {
491 mask: Diags.USER2,
492 msg: "LD_end: hwi: 0x%x"
493 };
494
495
496
497 /*! Assert when bad maskSetting parameter provided */
498 config Assert.Id A_unsupportedMaskingOption = {
499 msg: "A_unsupportedMaskingOption: unsupported maskSetting."
500 };
501
502
503
504 /*!
505 * Error raised when Hwi is already defined
506 */
507 config Error.Id E_alreadyDefined = {
508 msg: "E_alreadyDefined: Hwi already defined: intr# %d"
509 };
510
511 /*!
512 * Error raised when the number of interrupts being created
513 * exceeds the number supported.
514 */
515 config Error.Id E_hwiLimitExceeded = {
516 msg: "E_hwiLimitExceeded: Too many interrupts defined"
517 };
518
519 /*!
520 * Error raised when an exception occurs
521 */
522 config Error.Id E_exception = {
523 msg: "E_exception: id = %d, pc = %08x.\nTo see more exception detail, set ti.sysbios.family.arm.m3.Hwi.enableException = true or,\nexamine the Exception view for the ti.sysbios.family.arm.m3.Hwi module using ROV."
524 };
525
526 /*!
527 * Error raised when an uninitialized interrupt occurs
528 */
529 config Error.Id E_noIsr = {
530 msg: "E_noIsr: id = %d, pc = %08x"
531 };
532
533 /*!
534 * Error raised when NMI exception occurs
535 */
536 config Error.Id E_NMI = {
537 msg: "E_NMI: %s"
538 };
539
540 /*!
541 * Error raised when hard fault exception occurs
542 */
543 config Error.Id E_hardFault = {
544 msg: "E_hardFault: %s"
545 };
546
547 /*!
548 * Error raised when memory fault exception occurs
549 */
550 config Error.Id E_memFault = {
551 msg: "E_memFault: %s, address: %08x"
552 };
553
554 /*!
555 * Error raised when bus fault exception occurs
556 */
557 config Error.Id E_busFault = {
558 msg: "E_busFault: %s, address: %08x"
559 };
560
561 /*!
562 * Error raised when usage fault exception occurs
563 */
564 config Error.Id E_usageFault = {
565 msg: "E_usageFault: %s"
566 };
567
568 /*!
569 * Error raised when svCall exception occurs
570 */
571 config Error.Id E_svCall = {
572 msg: "E_svCall: svNum = %d"
573 };
574
575 /*!
576 * Error raised when debugMon exception occurs
577 */
578 config Error.Id E_debugMon = {
579 msg: "E_debugMon: %s"
580 };
581
582 /*!
583 * Error raised when reserved exception occurs
584 */
585 config Error.Id E_reserved = {
586 msg: "E_reserved: %s %d"
587 };
588
589
590
591 /*!
592 * Size (in number of interrupts) of the table used by the interrupt
593 * dispatcher to locate the corresponding Hwi object. By default,
594 * Hwi.dispatchTableSize will be internally set
595 * to the number of interrupts supported by the device.
596 *
597 * When the Hwi dispatch table size is equal to the number of interrupts
598 * supported {@link #NUM_INTERRUPTS} by the device, a linear-indexed
599 * dispatch table mechanism is used that will consume 4 bytes of RAM
600 * for each interrupt supported.
601 *
602 * If the dispatch table size is set to a number less than the number
603 * of interrupts supported by the device, then a non linear-indexed
604 * dispatch table mechanism is employed that uses 12 bytes of RAM for
605 * each interrupt supported.
606 *
607 * Consequently, for applications that use less than 1/3 of the total
608 * number of interrupts supported by the device, setting this parameter
609 * to the number of interrupts ACTUALLY USED will result in less RAM
610 * memory being used than otherwise.
611 *
612 * For applications that use very few interrupts, this can be a significant RAM memory savings.</p>
613 */
614 metaonly config UInt dispatchTableSize;
615
616 /*!
617 * Location of the Runtime Interrupt Vector Table.
618 * Default is device dependent.
619 *
620 * This parameter allows the user to override the default placement
621 * of the runtime interrupt vector table.
622 * The NVIC's Vector Table Offset
623 * Register (VTOR) is also programmed to this value.
624 *
625 * Some systems require the runtime vector table to be placed at
626 * an address
627 * other than 0 but still need a copy of the two M3 boot vectors
628 * (SP and reset PC), located there. To achieve this, a separate
629 * parameter {@link #resetVectorAdress} is provided. If the
630 * resetVectorAddress has a different value then the vectorTableAddress
631 * then a separate vector table is generated and placed at that
632 * address.
633 *
634 * The vector table must be placed at an address at or lower than
635 * 0x3FFFFC00 and must be aligned on an even 64 word boundary.
636 */
637 metaonly config Ptr vectorTableAddress = 0x00000000;
638
639 /*!
640 * Reset vector table address. Default is 0x00000000.
641 *
642 * This parameter is the address of the vector table used
643 * at system reset time. Typically this is placed at 0x00000000.
644 *
645 * If the Hwi.resetVectorAddress has a different value than
646 * the {@link #vectorTableAddress Hwi.vectorTableAddress}
647 * then two vector tables are generated, one at the Hwi.resetVectorAddress
648 * and another at the {@link #vectorTableAddress Hwi.vectorTableAddress}.
649 *
650 * After the initial boot code has been executed at startup, the NVIC's
651 * Vector Table Offset Register will be programmed to point to the
652 * vector table at the {@link #vectorTableAddress Hwi.vectorTableAddress}.
653 *
654 * is created and placed in the ".resetVecs" section.
655 */
656 metaonly config Ptr resetVectorAddress = 0x00000000;
657
658 /*! Reset Handler. Default is c_int00 */
659 metaonly config VectorFuncPtr resetFunc;
660
661 /*! NMI Handler. Default is set to an internal exception handler */
662 metaonly config VectorFuncPtr nmiFunc;
663
664 /*! Hard Fault Handler. Default is set to an internal exception handler */
665 metaonly config VectorFuncPtr hardFaultFunc;
666
667 /*! Hard Mem Handler. Default is set to an internal exception handler */
668 metaonly config VectorFuncPtr memFaultFunc;
669
670 /*! Bus Fault Handler. Default is set to an internal exception handler */
671 metaonly config VectorFuncPtr busFaultFunc;
672
673 /*! Usage Fault Handler. Default is set to an internal exception handler */
674 metaonly config VectorFuncPtr usageFaultFunc;
675
676 /*! SVCall Handler. Default is set to an internal exception handler */
677 metaonly config VectorFuncPtr svCallFunc;
678
679 /*! Debug Mon Handler. Default is set to an internal exception handler */
680 metaonly config VectorFuncPtr debugMonFunc;
681
682 /*! Reserved Exception Handler. Default is set to an internal exception handler */
683 metaonly config VectorFuncPtr reservedFunc;
684
685 /*! Uninitialized ISR Handler. Default is set to an internal exception handler */
686 config VectorFuncPtr nullIsrFunc;
687
688 /*! Hwi exception handler function type definition. */
689 typedef Void (*ExcHandlerFuncPtr)(UInt *, UInt);
690
691 /*!
692 * Exception handler function pointer.
693 *
694 * The default is determined by the value of Hwi.enableException.
695 *
696 * If the user does NOT set this parameter, then the following default
697 * behavior is followed:
698 *
699 * If Hwi.enableException is true, then the internal 'Hwi_excHandlerMax'
700 * function is used. This exception handler saves the exception context
701 * then does a complete exception decode and dump to the console, then
702 * raises an Error. The exception context can be viewed within CCS
703 * in the ROV Hwi module's Exception view.
704 *
705 * If Hwi.enableException is false, then the internal 'Hwi_excHandlerMin'
706 * function is used. This exception handler saves the exception context
707 * then raises an Error. The exception context can be viewed within CCS
708 * in the ROV Hwi module's Exception view.
709 *
710 * If the user sets this parameter to their own function, then the user's
711 * function will be invoked with the following arguments:
712 *
713 * Void myExceptionHandler(UInt *excStack, UInt lr);
714 *
715 * Where 'excStack' is the address of the stack containing the
716 * register context at the time of the exception, and 'lr' is the
717 * link register value when the low-level-assembly-coded exception
718 * handler was vectored to.
719 *
720 * If this parameter is set to 'null', then an infinite while loop is
721 * entered when an exception occurs. This setting minimizes code and
722 * data footprint but provides no automatic exception decoding.
723 */
724 config ExcHandlerFuncPtr excHandlerFunc = excHandlerMax;
725
726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752
753 metaonly config UInt8 intAffinity[];
754
755 /*!
756 * Enable full exception decoding
757 *
758 * When this is enabled, the exception handler will fully
759 * decode an exception and dump the registers to the
760 * system console.
761 */
762 metaonly config Bool enableException = true;
763
764 /*!
765 * User Exception Context Buffer Address
766 *
767 * By default, when an exception occurs, an {@link #ExcContext}
768 * structure is allocated on the ISR stack and filled in within the
769 * exception handler.
770 *
771 * If {@link #excContextBuffer} is initialized by the user, the
772 * {@link #ExcContext} structure will be placed at that address instead.
773 *
774 * The buffer must be large enough to contain an {@link #ExcContext}
775 * structure.
776 */
777 metaonly config Ptr excContextBuffer;
778 metaonly config Ptr excContextBuffers[];
779
780 /*!
781 * User Exception Stack Buffer Address
782 *
783 * By default, when an exception occurs, a pointer to the base address
784 * of the stack being used by the thread causing the exception is placed
785 *
786 * If {@link #excStackBuffer} is initialized by the user, the
787 * stack contents of the thread causing the exception will be
788 * copied to that address instead.
789 *
790 * The buffer must be large enough to contain the largest task stack
791 * or ISR stack defined in the application.
792 */
793 metaonly config Ptr excStackBuffer;
794 metaonly config Ptr excStackBuffers[];
795
796
797 /*!
798 * User Exception hook function.
799 *
800 * Called just after the exception context has been initialized.
801 *
802 * This function will be run on the ISR stack.
803 *
804 * This function must run to completion.
805 *
806 * It is called without any Task or Swi scheduling protection
807 * and therefore can not call any functions that may cause a Swi or Task
808 * scheduling operation (Swi_post(), Semaphore_post(), Event_post(), etc).
809 */
810 config ExceptionHookFuncPtr excHookFunc = null;
811 config ExceptionHookFuncPtr excHookFuncs[];
812
813 /*!
814 * NVIC CCR register settings
815 *
816 * These setting are written to Hwi_nvic.CCR at startup time.
817 *
818 * See the Cortex M3 architecture reference manual for details
819 * on the meanings of these parameters.
820 */
821 metaonly config CCR nvicCCR = {
822 STKALIGN: 1,
823 BFHFNMIGN: 0,
824 DIV_0_TRP: 0,
825 UNALIGN_TRP: 0,
826 USERSETMPEND: 0,
827 NONEBASETHRDENA: 0
828 };
829
830 /*!
831 * The priority that BASEPRI is set to by Hwi_disable().
832 *
833 * All interrupts configured with equal or less priority (equal or
834 * higher number) than disablePriority are disabled by Hwi_disable.
835 * Interrupts configured with higher priority (smaller number) than
836 * disablePriority are non-maskable (ie zero-latency).
837 *
838 * The default setting is the second highest interrupt priority
839 * defined for the device. This results in priority 0 (and all
840 * other values in the same priority group) being
841 * the non-maskable interrupt priority. All other priorities
842 * are disabled with Hwi_disable().
843 */
844 config UInt disablePriority;
845
846 /*!
847 * The PRIGROUP setting. Default is 0.
848 *
849 * This value will be written to the PRIGROUP field
850 * within the NVIC's Application Interrupt and Reset Control
851 * Register (Hwi_nvic.AIRCR). It defines how the 8 bit priority
852 * values are interpreted by the hardware.
853 *
854 * Valid settings are 0-7.
855 *
856 * The default setting of 0 causes bits 7-1 of an interrupt's
857 * priority value to be used to as a pre-emption priority, and bit 0
858 * is used to determine which of two simultaneous interrupts with
859 * the same pre-emption priority will be serviced first.
860 */
861 config UInt priGroup = 0;
862
863
864
865 /*!
866 * ======== disable ========
867 */
868 @Macro
869 override UInt disable();
870
871 /*!
872 * ======== enable ========
873 */
874 @Macro
875 override UInt enable();
876
877 /*!
878 * ======== restore ========
879 */
880 @Macro
881 override Void restore(UInt key);
882
883 /*!
884 * @_nodoc
885 * ======== disableFxn ========
886 * function call implementation
887 */
888 UInt disableFxn();
889
890 /*!
891 * @_nodoc
892 * ======== enableFxn ========
893 * function call implementation
894 */
895 UInt enableFxn();
896
897 /*!
898 * @_nodoc
899 * ======== restoreFxn ========
900 * function call implementation
901 */
902 Void restoreFxn(UInt key);
903
904 /*!
905 * ======== inUseMeta ========
906 * @_nodoc
907 * Check for Hwi already in use.
908 * For internal SYS/BIOS use only.
909 * Should be called prior to any internal Hwi.create().
910 *
911 * @param(intNum) interrupt number
912 */
913 metaonly Bool inUseMeta(UInt intNum);
914
915 /*!
916 * @_nodoc
917 * ======== plug ========
918 * Plug a non dispatched interrupt vector with an ISR address.
919 *
920 * @param(intNum) interrupt number
921 * @param(fxn) pointer to ISR function
922 */
923 Void plug(UInt intNum, Void *fxn);
924
925 /*!
926 * ======== getHandle ========
927 * Returns Hwi_handle associated with intNum
928 *
929 * @param(intNum) interrupt number
930 */
931 Handle getHandle(UInt intNum);
932
933 /*!
934 * ======== setPriority ========
935 * Set an interrupt's relative priority.
936 *
937 * Valid priorities are 0 - 255. 0 is highest priority.
938 *
939 * @param(intNum) ID of interrupt
940 * @param(priority) priority
941 */
942 Void setPriority(UInt intNum, UInt priority);
943
944 /*!
945 * ======== excSetBuffers ========
946 * Set the exception context and stack buffer pointers
947 *
948 * @param(excContextBuffer) Address to place ExcContext
949 * @param(excStackBuffer) Address to place ExcStack
950 */
951 Void excSetBuffers(Ptr excContextBuffer, Ptr excStackBuffer);
952
953 /*!
954 * @_nodoc
955 * ======== initNVIC ========
956 * initialize everything but leave ints disabled
957 */
958 Void initNVIC();
959
960 /*!
961 * @_nodoc
962 * ======== initStacks ========
963 * set up M3 split stacks
964 */
965 Void initStacks(Ptr hwiStack);
966
967 /*!
968 * @_nodoc
969 * ======== flushVnvic ========
970 * Reconfigure a dispatched interrupt.
971 *
972 * Called by the internal function "Hwi_updateNvic()".
973 *
974 * This is a public API because it is also called by "Core_hwiFunc()".
975 */
976 Void flushVnvic();
977
978 instance:
979
980 /*!
981 * Interrupt priority.
982 * The default is 255 which is the lowest priority.
983 *
984 * Priority 0 is the highest priority and by default is
985 * reserved for zero latency interrupts
986 * (see {@link #disablePriority}).
987 *
988 * Valid priorities values are device dependent and their
989 * nesting behaviors depend on the {@link #priGroup} setting.
990 *
991 * See the Cortex M3 architecture reference manual for details
992 * on the meanings of these parameters.
993 */
994 override config Int priority = 255;
995
996 /*!
997 * Interrupt Masking Option. Only MaskingOption_LOWER is supported.
998 *
999 * The NVIC interrupt controller is designed for priority based
1000 * interrupts. No support is provided for anything but
1001 * Hwi.MaskingOption_LOWER.
1002 */
1003 override config IHwi.MaskingOption maskSetting = IHwi.MaskingOption_LOWER;
1004
1005 /*!
1006 * Use the interrupt dispatcher with this interrupt. Default is true.
1007 *
1008 * If set to false, the interrupt dispatcher is NOT used. Instead,
1009 * the configured Hwi function address is placed directly in the
1010 * vector table, which results in the dispatcher being bypassed.
1011 *
1012 * @a(Warning)
1013 * Interrupts configured to bupass the dispatcher are not allowed
1014 * to call ANY SYS/BIOS APIs that effect thread scheduling. Examples
1015 * of API that should no be invoked are:
1016 *
1017 * @p(dlist)
1018 * - Swi_post(),
1019 * - Semaphore_post(),
1020 * - Event_post(),
1021 * - Task_yield()
1022 * @p
1023 *
1024 * Additionally, although the signature for a non-dispatched interrupt
1025 * function is the same as that for a dispatched interrupt
1026 * (see {@link #FuncPtr}), no argument is actually passed
1027 * to the non-dispatched ISR handler.
1028 */
1029 config Bool useDispatcher = true;
1030
1031 /*!
1032 * ======== reconfig ========
1033 * Reconfigure a dispatched interrupt.
1034 */
1035 Void reconfig(FuncPtr fxn, const Params *params);
1036
1037 internal:
1038
1039 /*!
1040 * If Hwi.dispatchTableSize is initialized by the user then
1041 * Hwi.numSparseInterrupts is set to the value of Hwi.dispatchTableSize
1042 *
1043 * If Hwi.dispatchTableSize is NOT set by the user, the normal
1044 * intNum-indexed Hwi dispatchTable mechanism is used by
1045 * the dispatcher to find the corresponding Hwi object.
1046 *
1047 * If Hwi.dispatchTableSize is set by the user, then a
1048 * RAM-based fixed sized interrupt jump table is generated
1049 * that contains a repeating pattern of the following 3 word
1050 * assembly code snippets:
1051 *
1052 * hwiX: ldr r3, hwiObjectX
1053 * ldr pc, ti_sysbios_family_arm_m3_Hwi_dispatch__I
1054 * hwiObjectX: .word 0
1055 * hwiY: ldr r3, hwiObjectY
1056 * ldr pc, ti_sysbios_family_arm_m3_Hwi_dispatch__I
1057 * hwiObjectY: .word 0
1058 * ...
1059 *
1060 * Each dispatched interrupt vector is then initialized to point
1061 * to one of these tuples, and the address of the corresponding Hwi
1062 * object is written into the hwiObjectX field.
1063 *
1064 * The low level assembly code in Hwi_dispatch__I preserves the
1065 * value of r3 when it calls Hwi_dispatchC(), which results in
1066 * the Hwi object being passed as the arg3.
1067 *
1068 * Depending on the boolean value of Hwi_numSparseInterrupts, the
1069 * dispatcher either uses the value passed in arg3 as the
1070 * Hwi object, or uses intNum to index into the standard
1071 * dispatchTable to fetch the Hwi object.
1072 */
1073 config UInt numSparseInterrupts = 0;
1074
1075 1076 1077 1078
1079 metaonly config Bool isTiva = false;
1080
1081 1082 1083 1084 1085 1086 1087 1088 1089
1090 metaonly config Bool enableWA1_1 = false;
1091
1092 1093 1094 1095 1096 1097
1098 config UInt (*swiDisable)();
1099 config Void (*swiRestoreHwi)(UInt);
1100 config UInt (*taskDisable)();
1101 config Void (*taskRestoreHwi)(UInt);
1102
1103
1104 config UInt32 ccr;
1105
1106 /*!
1107 * const array to hold all HookSet objects.
1108 */
1109 config HookSet hooks[length] = [];
1110
1111 1112 1113 1114
1115 Int postInit(Object *hwi, Error.Block *eb);
1116
1117 /*!
1118 * ======== updateNvic ========
1119 * Internal SMP function to cause the virtual NVIC to be flushed to the
1120 * actual NVIC.
1121 *
1122 * This function is called by the various user APIs that manipulate
1123 * individual NVIC register bits
1124 * (ie Hwi_enable/disable/restore/clearInterrupt())
1125 *
1126 * If the current core is the owner of "intNum", flushVnvic() is called
1127 * immediately.
1128 *
1129 * Otherwise an intercore interrupt is generated to force the other core
1130 * to perform the flushVnvic().
1131 *
1132 */
1133 Void updateNvic(UInt intNum);
1134
1135 /*!
1136 * ======== excHandlerAsm ========
1137 * asm code exception handler
1138 */
1139 Void excHandlerAsm();
1140
1141 /*!
1142 * ======== excHandler ========
1143 * exception Handler routes to
1144 * either min, max, or spin exception handler
1145 */
1146 Void excHandler(UInt *excStack, UInt lr);
1147
1148 /*!
1149 * ======== excHandlerMin ========
1150 * Minimal Exception Handler
1151 */
1152 Void excHandlerMin(UInt *excStack, UInt lr);
1153
1154 /*!
1155 * ======== excHandlerMax ========
1156 * Full Featured Exception Handler
1157 */
1158 Void excHandlerMax(UInt *excStack, UInt lr);
1159
1160 /*!
1161 * ======== excFillContext ========
1162 */
1163 Void excFillContext(UInt *excStack);
1164
1165 /*!
1166 * ======== excNmi ========
1167 */
1168 Void excNmi(UInt *excStack);
1169
1170 /*!
1171 * ======== excHardFault ========
1172 */
1173 Void excHardFault(UInt *excStack);
1174
1175 /*!
1176 * ======== excMemFault ========
1177 */
1178 Void excMemFault(UInt *excStack);
1179
1180 /*!
1181 * ======== excBusFault ========
1182 */
1183 Void excBusFault(UInt *excStack);
1184
1185 /*!
1186 * ======== excUsageFault ========
1187 */
1188 Void excUsageFault(UInt *excStack);
1189
1190 /*!
1191 * ======== excSvCall ========
1192 */
1193 Void excSvCall(UInt *excStack);
1194
1195 /*!
1196 * ======== excDebugMon ========
1197 */
1198 Void excDebugMon(UInt *excStack);
1199
1200 /*!
1201 * ======== excReserved ========
1202 */
1203 Void excReserved(UInt *excStack, UInt excNum);
1204
1205 /*!
1206 * ======== excNoIsr ========
1207 */
1208 Void excNoIsr(UInt *excStack, UInt excNum);
1209
1210 /*!
1211 * ======== excDumpRegs ========
1212 */
1213 Void excDumpRegs(UInt lr);
1214
1215 /*!
1216 * ======== pendSV ========
1217 * Used by dispatcher
1218 */
1219 Void pendSV();
1220
1221 /*! Hwi vector function type definition. */
1222 typedef Void (*HandlerFuncPtr)(Handle, UInt);
1223
1224
1225 Void dispatch();
1226
1227 1228 1229 1230
1231 UInt dispatchC(Irp irp, UInt32 dummy1, UInt32 dummy2, Object *hwi);
1232
1233
1234 Void doSwiRestore(UInt tskKey);
1235
1236
1237 Void doTaskRestore(UInt tskKey);
1238
1239 /*! Meta World Only Hwi Configuration Object. */
1240 metaonly struct InterruptObj {
1241 String name;
1242 Bool used;
1243 Bool useDispatcher;
1244 UInt priority;
1245 FuncPtr fxn;
1246 Handle hwi;
1247 };
1248
1249 /*!
1250 * Meta-only array of interrupt objects.
1251 * This meta-only array of Hwi config objects is initialized
1252 * in Hwi.xs:module$meta$init().
1253 */
1254 metaonly config InterruptObj interrupt[];
1255
1256 struct Instance_State {
1257 UArg arg;
1258 FuncPtr fxn;
1259 Irp irp;
1260
1261 UInt8 priority;
1262 Int16 intNum;
1263
1264
1265 Ptr hookEnv[];
1266 };
1267
1268 struct Module_State {
1269 Char *taskSP;
1270
1271 Bool excActive[];
1272 ExcContext *excContext[];
1273 Ptr excStack[];
1274 Ptr isrStack;
1275 Ptr isrStackBase;
1276 SizeT isrStackSize;
1277 Ptr vectorTableBase;
1278 UInt swiTaskKeys;
1279 Ptr dispatchTable;
1280 volatile Bool vnvicFlushRequired;
1281
1282 UInt8 intAffinity[];
1283 UInt32 intAffinityMasks[][];
1284 };
1285 }