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.v6m;
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 UInt32 IPR [60]; /*! 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 UInt32 SHPR[3]; /*! 0xE000ED18 System Handlers 4-15 Priority Registers */
292 UInt32 SHCSR; /*! 0xE000ED24 System Handler Control & State Register */
293 UInt32 CFSR; /*! 0xE000ED28 Combined Fault Status Register
294 // UInt8 MMFSR; /*! 0xE000ED28 Memory Manage Fault Status Register */
295
296
297 UInt32 HFSR; /*! 0xE000ED2C Hard Fault Status Register */
298 UInt32 DFSR; /*! 0xE000ED30 Debug Fault Status Register */
299 UInt32 MMAR; /*! 0xE000ED34 Memory Manager Address Register */
300 UInt32 BFAR; /*! 0xE000ED38 Bus Fault Address Register */
301 UInt32 AFSR; /*! 0xE000ED3C Auxiliary Fault Status Register */
302 UInt32 PFR0; /*! 0xE000ED40 Processor Feature Register */
303 UInt32 PFR1; /*! 0xE000ED44 Processor Feature Register */
304 UInt32 DFR0; /*! 0xE000ED48 Debug Feature Register */
305 UInt32 AFR0; /*! 0xE000ED4C Auxiliary Feature Register */
306 UInt32 MMFR0; /*! 0xE000ED50 Memory Model Fault Register0 */
307 UInt32 MMFR1; /*! 0xE000ED54 Memory Model Fault Register1 */
308 UInt32 MMFR2; /*! 0xE000ED58 Memory Model Fault Register2 */
309 UInt32 MMFR3; /*! 0xE000ED5C Memory Model Fault Register3 */
310 UInt32 ISAR0; /*! 0xE000ED60 ISA Feature Register0 */
311 UInt32 ISAR1; /*! 0xE000ED64 ISA Feature Register1 */
312 UInt32 ISAR2; /*! 0xE000ED68 ISA Feature Register2 */
313 UInt32 ISAR3; /*! 0xE000ED6C ISA Feature Register3 */
314 UInt32 ISAR4; /*! 0xE000ED70 ISA Feature Register4 */
315 UInt32 RES_D74[5]; /*! 0xE000ED74-0xE000ED84 reserved */
316 UInt32 CPACR; /*! 0xE000ED88 Coprocessor Access Control Register */
317 UInt32 RES_D8C[93]; /*! 0xE000ED8C-0xE000EEFC reserved */
318 UInt32 STI; /*! 0xE000EF00 Software Trigger Interrupt Register */
319 UInt32 RES_F04[12]; /*! 0xE000EF04-0xE000EF30 reserved */
320 UInt32 FPCCR; /*! 0xE000EF34 FP Context Control Register */
321 UInt32 FPCAR; /*! 0xE000EF38 FP Context Address Register */
322 UInt32 FPDSCR; /*! 0xE000EF3C FP Default Status Control Register */
323 UInt32 MVFR0; /*! 0xE000EF40 Media & FP Feature Register0 */
324 UInt32 MVFR1; /*! 0xE000EF44 Media & FP Feature Register1 */
325 UInt32 RES_F48[34]; /*! 0xE000EF48-0xE000EFCC reserved */
326 UInt32 PID4; /*! 0xE000EFD0 Peripheral ID Register4 */
327 UInt32 PID5; /*! 0xE000EFD4 Peripheral ID Register5 */
328 UInt32 PID6; /*! 0xE000EFD8 Peripheral ID Register6 */
329 UInt32 PID7; /*! 0xE000EFDC Peripheral ID Register7 */
330 UInt32 PID0; /*! 0xE000EFE0 Peripheral ID Register0 */
331 UInt32 PID1; /*! 0xE000EFE4 Peripheral ID Register1 */
332 UInt32 PID2; /*! 0xE000EFE8 Peripheral ID Register2 */
333 UInt32 PID3; /*! 0xE000EFEC Peripheral ID Register3 */
334 UInt32 CID0; /*! 0xE000EFF0 Component ID Register0 */
335 UInt32 CID1; /*! 0xE000EFF4 Component ID Register1 */
336 UInt32 CID2; /*! 0xE000EFF8 Component ID Register2 */
337 UInt32 CID3; /*! 0xE000EFFC Component ID Register3 */
338 }
339
340 /*!
341 * Physical Nested Vectored Interrupt Controller Device.
342 * Short name is "Hwi_nvic"
343 * Long name is "ti_sysbios_family_arm_v6m_Hwi_nvic"
344 */
345 extern volatile NVIC nvic;
346
347 /*!
348 * Exception Context - Register contents at the time of an exception.
349 */
350 struct ExcContext {
351
352 BIOS.ThreadType threadType;
353
354 Ptr threadHandle;
355
356 Ptr threadStack;
357
358
359 SizeT threadStackSize;
360
361
362 Ptr r0;
363 Ptr r1;
364 Ptr r2;
365 Ptr r3;
366 Ptr r4;
367 Ptr r5;
368 Ptr r6;
369 Ptr r7;
370 Ptr r8;
371 Ptr r9;
372 Ptr r10;
373 Ptr r11;
374 Ptr r12;
375 Ptr sp;
376 Ptr lr;
377 Ptr pc;
378 Ptr psr;
379
380
381 Ptr ICSR;
382 Ptr DFSR;
383 }
384
385 /*! @_nodoc */
386 metaonly struct BasicView {
387 Ptr halHwiHandle;
388 String label;
389 String type;
390 Int intNum;
391 Int priority;
392 String fxn;
393 UArg arg;
394 };
395
396 /*! @_nodoc */
397 metaonly struct DetailedView {
398 Ptr halHwiHandle;
399 String label;
400 String type;
401 Int intNum;
402 Int priority;
403 String fxn;
404 UArg arg;
405 Ptr irp;
406 String status;
407 };
408
409 /*! @_nodoc */
410 metaonly struct ModuleView {
411 String options[4];
412 String activeInterrupt;
413 String pendingInterrupt;
414 String exception;
415 String hwiStackPeak;
416 SizeT hwiStackSize;
417 Ptr hwiStackBase;
418 };
419
420 /*! @_nodoc */
421 @Facet
422 metaonly config ViewInfo.Instance rovViewInfo =
423 ViewInfo.create({
424 viewMap: [
425 ['Basic',
426 {
427 type: ViewInfo.INSTANCE,
428 viewInitFxn: 'viewInitBasic',
429 structName: 'BasicView'
430 }
431 ],
432 ['Detailed',
433 {
434 type: ViewInfo.INSTANCE,
435 viewInitFxn: 'viewInitDetailed',
436 structName: 'DetailedView'
437 }
438 ],
439 ['Module',
440 {
441 type: ViewInfo.MODULE,
442 viewInitFxn: 'viewInitModule',
443 structName: 'ModuleView'
444 }
445 ],
446 ['Exception',
447 {
448 type: ViewInfo.TREE,
449 viewInitFxn: 'viewInitException',
450 structName: 'ExcContext'
451 }
452 ]
453 ]
454 });
455
456
457
458
459
460 /*!
461 * Issued just prior to Hwi function invocation (with interrupts disabled)
462 */
463 config Log.Event LM_begin = {
464 mask: Diags.USER1 | Diags.USER2,
465 msg: "LM_begin: hwi: 0x%x, func: 0x%x, preThread: %d, intNum: %d, irp: 0x%x"
466 };
467
468 /*!
469 * Issued just after return from Hwi function (with interrupts disabled)
470 */
471 config Log.Event LD_end = {
472 mask: Diags.USER2,
473 msg: "LD_end: hwi: 0x%x"
474 };
475
476
477
478 /*! Assert when bad maskSetting parameter provided */
479 config Assert.Id A_unsupportedMaskingOption = {
480 msg: "A_unsupportedMaskingOption: unsupported maskSetting."
481 };
482
483
484
485 /*!
486 * Error raised when Hwi is already defined
487 */
488 config Error.Id E_alreadyDefined = {
489 msg: "E_alreadyDefined: Hwi already defined: intr# %d"
490 };
491
492 /*!
493 * Error raised when the number of interrupts being created
494 * exceeds the number supported.
495 */
496 config Error.Id E_hwiLimitExceeded = {
497 msg: "E_hwiLimitExceeded: Too many interrupts defined"
498 };
499
500 /*!
501 * Error raised when an exception occurs
502 */
503 config Error.Id E_exception = {
504 msg: "E_exception: id = %d, pc = %08x.\nTo see more exception detail, set ti.sysbios.family.arm.v6m.Hwi.enableException = true or,\nexamine the Exception view for the ti.sysbios.family.arm.v6m.Hwi module using ROV."
505 };
506
507 /*!
508 * Error raised when an uninitialized interrupt occurs
509 */
510 config Error.Id E_noIsr = {
511 msg: "E_noIsr: id = %d, pc = %08x"
512 };
513
514 /*!
515 * Error raised when NMI exception occurs
516 */
517 config Error.Id E_NMI = {
518 msg: "E_NMI: %s"
519 };
520
521 /*!
522 * Error raised when hard fault exception occurs
523 */
524 config Error.Id E_hardFault = {
525 msg: "E_hardFault: %s"
526 };
527
528 /*!
529 * Error raised when memory fault exception occurs
530 */
531 config Error.Id E_memFault = {
532 msg: "E_memFault: %s, address: %08x"
533 };
534
535 /*!
536 * Error raised when bus fault exception occurs
537 */
538 config Error.Id E_busFault = {
539 msg: "E_busFault: %s, address: %08x"
540 };
541
542 /*!
543 * Error raised when usage fault exception occurs
544 */
545 config Error.Id E_usageFault = {
546 msg: "E_usageFault: %s"
547 };
548
549 /*!
550 * Error raised when svCall exception occurs
551 */
552 config Error.Id E_svCall = {
553 msg: "E_svCall: svNum = %d"
554 };
555
556 /*!
557 * Error raised when debugMon exception occurs
558 */
559 config Error.Id E_debugMon = {
560 msg: "E_debugMon: %s"
561 };
562
563 /*!
564 * Error raised when reserved exception occurs
565 */
566 config Error.Id E_reserved = {
567 msg: "E_reserved: %s %d"
568 };
569
570
571
572 /*!
573 * Size (in number of interrupts) of the table used by the interrupt
574 * dispatcher to locate the corresponding Hwi object. By default,
575 * Hwi.dispatchTableSize will be internally set
576 * to the number of interrupts supported by the device.
577 *
578 * When the Hwi dispatch table size is equal to the number of interrupts
579 * supported {@link #NUM_INTERRUPTS} by the device, a linear-indexed
580 * dispatch table mechanism is used that will consume 4 bytes of RAM
581 * for each interrupt supported.
582 *
583 * If the dispatch table size is set to a number less than the number
584 * of interrupts supported by the device, then a non linear-indexed
585 * dispatch table mechanism is employed that uses 12 bytes of RAM for
586 * each interrupt supported.
587 *
588 * Consequently, for applications that use less than 1/3 of the total
589 * number of interrupts supported by the device, setting this parameter
590 * to the number of interrupts ACTUALLY USED will result in less RAM
591 * memory being used than otherwise.
592 *
593 * For applications that use very few interrupts, this can be a significant RAM memory savings.</p>
594 */
595 metaonly config UInt dispatchTableSize;
596
597 /*!
598 * Location of the Runtime Interrupt Vector Table.
599 * Default is device dependent.
600 *
601 * This parameter allows the user to override the default placement
602 * of the runtime interrupt vector table.
603 * The NVIC's Vector Table Offset
604 * Register (VTOR) is also programmed to this value.
605 *
606 * Some systems require the runtime vector table to be placed at
607 * an address
608 * other than 0 but still need a copy of the two M3 boot vectors
609 * (SP and reset PC), located there. To achieve this, a separate
610 * parameter {@link #resetVectorAdress} is provided. If the
611 * resetVectorAddress has a different value then the vectorTableAddress
612 * then a separate vector table is generated and placed at that
613 * address.
614 *
615 * The vector table must be placed at an address at or lower than
616 * 0x3FFFFC00 and must be aligned on an even 64 word boundary.
617 */
618 metaonly config Ptr vectorTableAddress = 0x00000000;
619
620 /*!
621 * Reset vector table address. Default is 0x00000000.
622 *
623 * This parameter is the address of the vector table used
624 * at system reset time. Typically this is placed at 0x00000000.
625 *
626 * If the Hwi.resetVectorAddress has a different value than
627 * the {@link #vectorTableAddress Hwi.vectorTableAddress}
628 * then two vector tables are generated, one at the Hwi.resetVectorAddress
629 * and another at the {@link #vectorTableAddress Hwi.vectorTableAddress}.
630 *
631 * After the initial boot code has been executed at startup, the NVIC's
632 * Vector Table Offset Register will be programmed to point to the
633 * vector table at the {@link #vectorTableAddress Hwi.vectorTableAddress}.
634 *
635 * is created and placed in the ".resetVecs" section.
636 */
637 metaonly config Ptr resetVectorAddress = 0x00000000;
638
639 /*! Reset Handler. Default is c_int00 */
640 metaonly config VectorFuncPtr resetFunc;
641
642 /*! NMI Handler. Default is set to an internal exception handler */
643 metaonly config VectorFuncPtr nmiFunc;
644
645 /*! Hard Fault Handler. Default is set to an internal exception handler */
646 metaonly config VectorFuncPtr hardFaultFunc;
647
648 /*! SVCall Handler. Default is set to an internal exception handler */
649 metaonly config VectorFuncPtr svCallFunc;
650
651 /*! Debug Mon Handler. Default is set to an internal exception handler */
652 metaonly config VectorFuncPtr debugMonFunc;
653
654 /*! Reserved Exception Handler. Default is set to an internal exception handler */
655 metaonly config VectorFuncPtr reservedFunc;
656
657 /*! Uninitialized ISR Handler. Default is set to an internal exception handler */
658 config VectorFuncPtr nullIsrFunc;
659
660 /*! Hwi exception handler function type definition. */
661 typedef Void (*ExcHandlerFuncPtr)(UInt *, UInt);
662
663 /*!
664 * Exception handler function pointer.
665 *
666 * The default is determined by the value of Hwi.enableException.
667 *
668 * If the user does NOT set this parameter, then the following default
669 * behavior is followed:
670 *
671 * If Hwi.enableException is true, then the internal 'Hwi_excHandlerMax'
672 * function is used. This exception handler saves the exception context
673 * then does a complete exception decode and dump to the console, then
674 * raises an Error. The exception context can be viewed within CCS
675 * in the ROV Hwi module's Exception view.
676 *
677 * If Hwi.enableException is false, then the internal 'Hwi_excHandlerMin'
678 * function is used. This exception handler saves the exception context
679 * then raises an Error. The exception context can be viewed within CCS
680 * in the ROV Hwi module's Exception view.
681 *
682 * If the user sets this parameter to their own function, then the user's
683 * function will be invoked with the following arguments:
684 *
685 * Void myExceptionHandler(UInt *excStack, UInt lr);
686 *
687 * Where 'excStack' is the address of the stack containing the
688 * register context at the time of the exception, and 'lr' is the
689 * link register value when the low-level-assembly-coded exception
690 * handler was vectored to.
691 *
692 * If this parameter is set to 'null', then an infinite while loop is
693 * entered when an exception occurs. This setting minimizes code and
694 * data footprint but provides no automatic exception decoding.
695 */
696 config ExcHandlerFuncPtr excHandlerFunc = excHandlerMax;
697
698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724
725 metaonly config UInt8 intAffinity[];
726
727 /*!
728 * Enable full exception decoding
729 *
730 * When this is enabled, the exception handler will fully
731 * decode an exception and dump the registers to the
732 * system console.
733 */
734 metaonly config Bool enableException = true;
735
736 /*!
737 * User Exception Context Buffer Address
738 *
739 * By default, when an exception occurs, an {@link #ExcContext}
740 * structure is allocated on the ISR stack and filled in within the
741 * exception handler.
742 *
743 * If {@link #excContextBuffer} is initialized by the user, the
744 * {@link #ExcContext} structure will be placed at that address instead.
745 *
746 * The buffer must be large enough to contain an {@link #ExcContext}
747 * structure.
748 */
749 metaonly config Ptr excContextBuffer;
750 metaonly config Ptr excContextBuffers[];
751
752 /*!
753 * User Exception Stack Buffer Address
754 *
755 * By default, when an exception occurs, a pointer to the base address
756 * of the stack being used by the thread causing the exception is placed
757 *
758 * If {@link #excStackBuffer} is initialized by the user, the
759 * stack contents of the thread causing the exception will be
760 * copied to that address instead.
761 *
762 * The buffer must be large enough to contain the largest task stack
763 * or ISR stack defined in the application.
764 */
765 metaonly config Ptr excStackBuffer;
766 metaonly config Ptr excStackBuffers[];
767
768
769 /*!
770 * User Exception hook function.
771 *
772 * Called just after the exception context has been initialized.
773 *
774 * This function will be run on the ISR stack.
775 *
776 * This function must run to completion.
777 *
778 * It is called without any Task or Swi scheduling protection
779 * and therefore can not call any functions that may cause a Swi or Task
780 * scheduling operation (Swi_post(), Semaphore_post(), Event_post(), etc).
781 */
782 config ExceptionHookFuncPtr excHookFunc = null;
783 config ExceptionHookFuncPtr excHookFuncs[];
784
785 /*!
786 * NVIC CCR register settings
787 *
788 * These setting are written to Hwi_nvic.CCR at startup time.
789 *
790 * See the Cortex M3 architecture reference manual for details
791 * on the meanings of these parameters.
792 */
793 metaonly config CCR nvicCCR = {
794 STKALIGN: 1,
795 BFHFNMIGN: 0,
796 DIV_0_TRP: 0,
797 UNALIGN_TRP: 0,
798 USERSETMPEND: 0,
799 NONEBASETHRDENA: 0
800 };
801
802
803
804 /*!
805 * ======== disable ========
806 * Globally disable interrupts.
807 *
808 * Hwi_disable globally disables hardware interrupts and returns an
809 * opaque key indicating whether interrupts were globally enabled or
810 * disabled on entry to Hwi_disable().
811 * The actual value of the key is target/device specific and is meant
812 * to be passed to Hwi_restore().
813 *
814 * Call Hwi_disable before a portion of a function that needs
815 * to run without interruption. When critical processing is complete, call
816 * Hwi_restore or Hwi_enable to reenable hardware interrupts.
817 *
818 * Servicing of interrupts that occur while interrupts are disabled is
819 * postponed until interrupts are reenabled. However, if the same type
820 * of interrupt occurs several times while interrupts are disabled,
821 * the interrupt's function is executed only once when interrupts are
822 * reenabled.
823 *
824 * A context switch can occur when calling Hwi_enable or Hwi_restore if
825 * an enabled interrupt occurred while interrupts are disabled.
826 *
827 * Hwi_disable may be called from main(). However, since Hwi interrupts
828 * are already disabled in main(), such a call has no effect.
829 *
830 * @a(constraints)
831 * If a Task switching API such as
832 * {@link ti.sysbios.knl.Semaphore#pend Semaphore_pend()},
833 * {@link ti.sysbios.knl.Semaphore#post Semaphore_post()},
834 * {@link ti.sysbios.knl.Task#sleep Task_sleep()}, or
835 * {@link ti.sysbios.knl.Task#yield Task_yield()}
836 * is invoked which results in a context switch while
837 * interrupts are disabled, an embedded call to
838 * {@link #enable Hwi_enable} occurs
839 * on the way to the new thread context which unconditionally re-enables
840 * interrupts. Interrupts will remain enabled until a subsequent
841 * {@link #disable Hwi_disable}
842 * invocation.
843 *
844 * Swis always run with interrupts enabled.
845 * See {@link ti.sysbios.knl.Swi#post Swi_post()} for a discussion Swis and
846 * interrupts.
847 *
848 * @b(returns) opaque key for use by Hwi_restore()
849 */
850 @Macro
851 override UInt disable();
852
853 /*!
854 * ======== enable ========
855 */
856 @Macro
857 override UInt enable();
858
859 /*!
860 * ======== restore ========
861 */
862 @Macro
863 override Void restore(UInt key);
864
865 /*!
866 * @_nodoc
867 * ======== disableFxn ========
868 * function call implementation
869 */
870 UInt disableFxn();
871
872 /*!
873 * @_nodoc
874 * ======== enableFxn ========
875 * function call implementation
876 */
877 UInt enableFxn();
878
879 /*!
880 * @_nodoc
881 * ======== restoreFxn ========
882 * function call implementation
883 */
884 Void restoreFxn(UInt key);
885
886 /*!
887 * ======== inUseMeta ========
888 * @_nodoc
889 * Check for Hwi already in use.
890 * For internal SYS/BIOS use only.
891 * Should be called prior to any internal Hwi.create().
892 *
893 * @param(intNum) interrupt number
894 */
895 metaonly Bool inUseMeta(UInt intNum);
896
897 /*!
898 * @_nodoc
899 * ======== plug ========
900 * Plug a non dispatched interrupt vector with an ISR address.
901 *
902 * @param(intNum) interrupt number
903 * @param(fxn) pointer to ISR function
904 */
905 Void plug(UInt intNum, Void *fxn);
906
907 /*!
908 * ======== getHandle ========
909 * Returns Hwi_handle associated with intNum
910 *
911 * @param(intNum) interrupt number
912 */
913 Handle getHandle(UInt intNum);
914
915 /*!
916 * ======== setPriority ========
917 * Set an interrupt's relative priority.
918 *
919 * Valid priorities are 0 - 255. 0 is highest priority.
920 *
921 * @param(intNum) ID of interrupt
922 * @param(priority) priority
923 */
924 Void setPriority(UInt intNum, UInt priority);
925
926 /*!
927 * ======== excSetBuffers ========
928 * Set the exception context and stack buffer pointers
929 *
930 * @param(excContextBuffer) Address to place ExcContext
931 * @param(excStackBuffer) Address to place ExcStack
932 */
933 Void excSetBuffers(Ptr excContextBuffer, Ptr excStackBuffer);
934
935 /*!
936 * @_nodoc
937 * ======== initNVIC ========
938 * initialize everything but leave ints disabled
939 */
940 Void initNVIC();
941
942 /*!
943 * @_nodoc
944 * ======== initStacks ========
945 * set up M3 split stacks
946 */
947 Void initStacks(Ptr hwiStack);
948
949 /*!
950 * @_nodoc
951 * ======== flushVnvic ========
952 * Reconfigure a dispatched interrupt.
953 *
954 * Called by the internal function "Hwi_updateNvic()".
955 *
956 * This is a public API because it is also called by "Core_hwiFunc()".
957 */
958 Void flushVnvic();
959
960 instance:
961
962 /*!
963 * Interrupt priority.
964 * The default is 255 which is the lowest priority.
965 *
966 * Priority 0 is the highest priority and by default is
967 * reserved for zero latency interrupts
968 * (see {@link #disablePriority}).
969 *
970 * Valid priorities values are device dependent and their
971 * nesting behaviors depend on the {@link #priGroup} setting.
972 *
973 * See the Cortex M3 architecture reference manual for details
974 * on the meanings of these parameters.
975 */
976 override config Int priority = 255;
977
978 /*!
979 * Interrupt Masking Option. Only MaskingOption_LOWER is supported.
980 *
981 * The NVIC interrupt controller is designed for priority based
982 * interrupts. No support is provided for anything but
983 * Hwi.MaskingOption_LOWER.
984 */
985 override config IHwi.MaskingOption maskSetting = IHwi.MaskingOption_LOWER;
986
987 /*!
988 * Use the interrupt dispatcher with this interrupt. Default is true.
989 *
990 * If set to false, the interrupt dispatcher is NOT used. Instead,
991 * the configured Hwi function address is placed directly in the
992 * vector table, which results in the dispatcher being bypassed.
993 *
994 * @a(Warning)
995 * Interrupts configured to bupass the dispatcher are not allowed
996 * to call ANY SYS/BIOS APIs that effect thread scheduling. Examples
997 * of API that should no be invoked are:
998 *
999 * @p(dlist)
1000 * - Swi_post(),
1001 * - Semaphore_post(),
1002 * - Event_post(),
1003 * - Task_yield()
1004 * @p
1005 *
1006 * Additionally, although the signature for a non-dispatched interrupt
1007 * function is the same as that for a dispatched interrupt
1008 * (see {@link #FuncPtr}), no argument is actually passed
1009 * to the non-dispatched ISR handler.
1010 */
1011 config Bool useDispatcher = true;
1012
1013 /*!
1014 * ======== reconfig ========
1015 * Reconfigure a dispatched interrupt.
1016 */
1017 Void reconfig(FuncPtr fxn, const Params *params);
1018
1019 internal:
1020
1021 /*!
1022 * If Hwi.dispatchTableSize is initialized by the user then
1023 * Hwi.numSparseInterrupts is set to the value of Hwi.dispatchTableSize
1024 *
1025 * If Hwi.dispatchTableSize is NOT set by the user, the normal
1026 * intNum-indexed Hwi dispatchTable mechanism is used by
1027 * the dispatcher to find the corresponding Hwi object.
1028 *
1029 * If Hwi.dispatchTableSize is set by the user, then a
1030 * RAM-based fixed sized interrupt jump table is generated
1031 * that contains a repeating pattern of the following 3 word
1032 * assembly code snippets:
1033 *
1034 * hwiX: ldr r3, hwiObjectX
1035 * ldr pc, ti_sysbios_family_arm_v6m_Hwi_dispatch__I
1036 * hwiObjectX: .word 0
1037 * hwiY: ldr r3, hwiObjectY
1038 * ldr pc, ti_sysbios_family_arm_v6m_Hwi_dispatch__I
1039 * hwiObjectY: .word 0
1040 * ...
1041 *
1042 * Each dispatched interrupt vector is then initialized to point
1043 * to one of these tuples, and the address of the corresponding Hwi
1044 * object is written into the hwiObjectX field.
1045 *
1046 * The low level assembly code in Hwi_dispatch__I preserves the
1047 * value of r3 when it calls Hwi_dispatchC(), which results in
1048 * the Hwi object being passed as the arg3.
1049 *
1050 * Depending on the boolean value of Hwi_numSparseInterrupts, the
1051 * dispatcher either uses the value passed in arg3 as the
1052 * Hwi object, or uses intNum to index into the standard
1053 * dispatchTable to fetch the Hwi object.
1054 */
1055 config UInt numSparseInterrupts = 0;
1056
1057 1058 1059 1060
1061 metaonly config Bool isTiva = false;
1062
1063 1064 1065 1066 1067 1068 1069 1070 1071
1072 metaonly config Bool enableWA1_1 = false;
1073
1074 1075 1076 1077 1078 1079
1080 config UInt (*swiDisable)();
1081 config Void (*swiRestoreHwi)(UInt);
1082 config UInt (*taskDisable)();
1083 config Void (*taskRestoreHwi)(UInt);
1084
1085
1086 config UInt32 ccr;
1087
1088 /*!
1089 * const array to hold all HookSet objects.
1090 */
1091 config HookSet hooks[length] = [];
1092
1093 1094 1095 1096
1097 Int postInit(Object *hwi, Error.Block *eb);
1098
1099 /*!
1100 * ======== updateNvic ========
1101 * Internal SMP function to cause the virtual NVIC to be flushed to the
1102 * actual NVIC.
1103 *
1104 * This function is called by the various user APIs that manipulate
1105 * individual NVIC register bits
1106 * (ie Hwi_enable/disable/restore/clearInterrupt())
1107 *
1108 * If the current core is the owner of "intNum", flushVnvic() is called
1109 * immediately.
1110 *
1111 * Otherwise an intercore interrupt is generated to force the other core
1112 * to perform the flushVnvic().
1113 *
1114 */
1115 Void updateNvic(UInt intNum);
1116
1117 /*!
1118 * ======== excHandlerAsm ========
1119 * asm code exception handler
1120 */
1121 Void excHandlerAsm();
1122
1123 /*!
1124 * ======== excHandler ========
1125 * exception Handler routes to
1126 * either min, max, or spin exception handler
1127 */
1128 Void excHandler(UInt *excStack, UInt lr);
1129
1130 /*!
1131 * ======== excHandlerMin ========
1132 * Minimal Exception Handler
1133 */
1134 Void excHandlerMin(UInt *excStack, UInt lr);
1135
1136 /*!
1137 * ======== excHandlerMax ========
1138 * Full Featured Exception Handler
1139 */
1140 Void excHandlerMax(UInt *excStack, UInt lr);
1141
1142 /*!
1143 * ======== excFillContext ========
1144 */
1145 Void excFillContext(UInt *excStack);
1146
1147 /*!
1148 * ======== excNmi ========
1149 */
1150 Void excNmi(UInt *excStack);
1151
1152 /*!
1153 * ======== excHardFault ========
1154 */
1155 Void excHardFault(UInt *excStack);
1156
1157 /*!
1158 * ======== excMemFault ========
1159 */
1160 Void excMemFault(UInt *excStack);
1161
1162 /*!
1163 * ======== excBusFault ========
1164 */
1165 Void excBusFault(UInt *excStack);
1166
1167 /*!
1168 * ======== excUsageFault ========
1169 */
1170 Void excUsageFault(UInt *excStack);
1171
1172 /*!
1173 * ======== excSvCall ========
1174 */
1175 Void excSvCall(UInt *excStack);
1176
1177 /*!
1178 * ======== excDebugMon ========
1179 */
1180 Void excDebugMon(UInt *excStack);
1181
1182 /*!
1183 * ======== excReserved ========
1184 */
1185 Void excReserved(UInt *excStack, UInt excNum);
1186
1187 /*!
1188 * ======== excNoIsr ========
1189 */
1190 Void excNoIsr(UInt *excStack, UInt excNum);
1191
1192 /*!
1193 * ======== excDumpRegs ========
1194 */
1195 Void excDumpRegs(UInt lr);
1196
1197 /*!
1198 * ======== pendSV ========
1199 * Used by dispatcher
1200 */
1201 Void pendSV();
1202
1203 /*! Hwi vector function type definition. */
1204 typedef Void (*HandlerFuncPtr)(Handle, UInt);
1205
1206
1207 Void dispatch();
1208
1209 1210 1211 1212
1213 UInt dispatchC(Irp irp, UInt32 dummy1, UInt32 dummy2, Object *hwi);
1214
1215
1216 Void doSwiRestore(UInt tskKey);
1217
1218
1219 Void doTaskRestore(UInt tskKey);
1220
1221 /*! Meta World Only Hwi Configuration Object. */
1222 metaonly struct InterruptObj {
1223 String name;
1224 Bool used;
1225 Bool useDispatcher;
1226 UInt priority;
1227 FuncPtr fxn;
1228 Handle hwi;
1229 };
1230
1231 /*!
1232 * Meta-only array of interrupt objects.
1233 * This meta-only array of Hwi config objects is initialized
1234 * in Hwi.xs:module$meta$init().
1235 */
1236 metaonly config InterruptObj interrupt[];
1237
1238 struct Instance_State {
1239 UArg arg;
1240 FuncPtr fxn;
1241 Irp irp;
1242
1243 UInt8 priority;
1244 Int16 intNum;
1245
1246
1247 Ptr hookEnv[];
1248 };
1249
1250 struct Module_State {
1251 Char *taskSP;
1252
1253 Bool excActive[];
1254 ExcContext *excContext[];
1255 Ptr excStack[];
1256 Ptr isrStack;
1257 Ptr isrStackBase;
1258 SizeT isrStackSize;
1259 Ptr vectorTableBase;
1260 UInt swiTaskKeys;
1261 Ptr dispatchTable;
1262 volatile Bool vnvicFlushRequired;
1263
1264 UInt8 intAffinity[];
1265 UInt32 intAffinityMasks[][];
1266 };
1267 }