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 * Stellaris devices:
121 *
122 * By default, two vector tables are created for Stellaris 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
221 module Hwi inherits ti.sysbios.interfaces.IHwi
222 {
223
224
225 /*!
226 * The Cortex M3 NVIC supports up to 256 interrupts/exceptions.
227 *
228 * The actual number supported is device specific and provided by
229 * the catalog device specification.
230 */
231 config Int NUM_INTERRUPTS;
232
233 /*!
234 * The Cortex M3 NVIC supports up to 256 interrupt priorities.
235 *
236 * The actual number supported is device specific and provided by
237 * the catalog device specification.
238 */
239 config Int NUM_PRIORITIES;
240
241
242
243 /*! Hwi vector function type definition. */
244 typedef Void (*VectorFuncPtr)(void);
245
246 /*! Exception hook function type definition. */
247 typedef Void (*ExceptionHookFuncPtr)(ExcContext *);
248
249 /*! NVIC Configuration Control Register (CCR). */
250 struct CCR {
251 Bits8 STKALIGN; /*! Auto stack alignment in exception */
252 Bits8 BFHFNMIGN; /*! All faults ignore BUS Faults */
253 Bits8 DIV_0_TRP; /*! Trap on divide by zero */
254 Bits8 UNALIGN_TRP; /*! Trap on all unaligned accesses */
255 Bits8 USERSETMPEND; /*! Allow user to trigger interrupts */
256 Bits8 NONEBASETHRDENA; /*! Allow entering thread mode anytime */
257 };
258
259 /*! @_nodoc
260 * Nested Vectored Interrupt Controller.
261 */
262 struct NVIC {
263 UInt32 RES_00; /*! 0xE000E000 reserved */
264 UInt32 ICTR; /*! 0xE000E004 Interrupt Control Type */
265 UInt32 RES_08; /*! 0xE000E008 reserved */
266 UInt32 RES_0C; /*! 0xE000E00C reserved */
267 UInt32 STCSR; /*! 0xE000E010 SysTick Control & Status Register */
268 UInt32 STRVR; /*! 0xE000E014 SysTick Reload Value Register */
269 UInt32 STCVR; /*! 0xE000E018 SysTick Current Value Register */
270 UInt32 STCALIB; /*! 0xE000E01C SysTick Calibration Value Register */
271 UInt32 RES_20 [56]; /*! 0xE000E020-0xE000E0FC reserved */
272 UInt32 ISER [8]; /*! 0xE000E100-0xE000E11C Interrupt Set Enable Registers */
273 UInt32 RES_120 [24]; /*! 0xE000E120-0xE000E17C reserved */
274 UInt32 ICER [8]; /*! 0xE000E180-0xE000E19C Interrupt Clear Enable Registers */
275 UInt32 RES_1A0 [24]; /*! 0xE000E1A0-0xE000E1FC reserved */
276 UInt32 ISPR [8]; /*! 0xE000E200-0xE000E21C Interrupt Set Pending Registers */
277 UInt32 RES_220 [24]; /*! 0xE000E220-0xE000E7C reserved */
278 UInt32 ICPR [8]; /*! 0xE000E280-0xE000E29C Interrupt Clear Pending Registers */
279 UInt32 RES_2A0 [24]; /*! 0xE000E2A0-0xE000E2FC reserved */
280 UInt32 IABR [8]; /*! 0xE000E300-0xE000E31C Interrupt Active Bit Registers */
281 UInt32 RES_320 [56]; /*! 0xE000E320-0xE000E3FC reserved */
282 UInt8 IPR [240]; /*! 0xE000E400-0xE000E4EF Interrupt Priority Registers */
283 UInt32 RES_4F0 [516];/*! 0xE000E4F0-0xE000ECFC reserved */
284 UInt32 CPUIDBR; /*! 0xE000ED00 CPUID Base Register */
285 UInt32 ICSR; /*! 0xE000ED04 Interrupt Control State Register */
286 UInt32 VTOR; /*! 0xE000ED08 Vector Table Offset Register */
287 UInt32 AIRCR; /*! 0xE000ED0C Application Interrupt/Reset Control Register */
288 UInt32 SCR; /*! 0xE000ED10 System Control Register */
289 UInt32 CCR; /*! 0xE000ED14 Configuration Control Register */
290 UInt8 SHPR[12]; /*! 0xE000ED18 System Handlers 4-15 Priority Registers */
291 UInt32 SHCSR; /*! 0xE000ED24 System Handler Control & State Register */
292 UInt8 MMFSR; /*! 0xE000ED28 Memory Manage Fault Status Register */
293 UInt8 BFSR; /*! 0xE000ED29 Bus Fault Status Register */
294 UInt16 UFSR; /*! 0xE000ED2A Usage Fault Status Register */
295 UInt32 HFSR; /*! 0xE000ED2C Hard Fault Status Register */
296 UInt32 DFSR; /*! 0xE000ED30 Debug Fault Status Register */
297 UInt32 MMAR; /*! 0xE000ED34 Memory Manager Address Register */
298 UInt32 BFAR; /*! 0xE000ED38 Bus Fault Address Register */
299 UInt32 AFSR; /*! 0xE000ED3C Auxiliary Fault Status Register */
300 UInt32 PFR0; /*! 0xE000ED40 Processor Feature Register */
301 UInt32 PFR1; /*! 0xE000ED44 Processor Feature Register */
302 UInt32 DFR0; /*! 0xE000ED48 Debug Feature Register */
303 UInt32 AFR0; /*! 0xE000ED4C Auxiliary Feature Register */
304 UInt32 MMFR0; /*! 0xE000ED50 Memory Model Fault Register0 */
305 UInt32 MMFR1; /*! 0xE000ED54 Memory Model Fault Register1 */
306 UInt32 MMFR2; /*! 0xE000ED58 Memory Model Fault Register2 */
307 UInt32 MMFR3; /*! 0xE000ED5C Memory Model Fault Register3 */
308 UInt32 ISAR0; /*! 0xE000ED60 ISA Feature Register0 */
309 UInt32 ISAR1; /*! 0xE000ED64 ISA Feature Register1 */
310 UInt32 ISAR2; /*! 0xE000ED68 ISA Feature Register2 */
311 UInt32 ISAR3; /*! 0xE000ED6C ISA Feature Register3 */
312 UInt32 ISAR4; /*! 0xE000ED70 ISA Feature Register4 */
313 UInt32 RES_D74[5]; /*! 0xE000ED74-0xE000ED84 reserved */
314 UInt32 CPACR; /*! 0xE000ED88 Coprocessor Access Control Register */
315 UInt32 RES_D8C[93]; /*! 0xE000ED8C-0xE000EEFC reserved */
316 UInt32 STI; /*! 0xE000EF00 Software Trigger Interrupt Register */
317 UInt32 RES_F04[12]; /*! 0xE000EF04-0xE000EF30 reserved */
318 UInt32 FPCCR; /*! 0xE000EF34 FP Context Control Register */
319 UInt32 FPCAR; /*! 0xE000EF38 FP Context Address Register */
320 UInt32 FPDSCR; /*! 0xE000EF3C FP Default Status Control Register */
321 UInt32 MVFR0; /*! 0xE000EF40 Media & FP Feature Register0 */
322 UInt32 MVFR1; /*! 0xE000EF44 Media & FP Feature Register1 */
323 UInt32 RES_F48[34]; /*! 0xE000EF48-0xE000EFCC reserved */
324 UInt32 PID4; /*! 0xE000EFD0 Peripheral ID Register4 */
325 UInt32 PID5; /*! 0xE000EFD4 Peripheral ID Register5 */
326 UInt32 PID6; /*! 0xE000EFD8 Peripheral ID Register6 */
327 UInt32 PID7; /*! 0xE000EFDC Peripheral ID Register7 */
328 UInt32 PID0; /*! 0xE000EFE0 Peripheral ID Register0 */
329 UInt32 PID1; /*! 0xE000EFE4 Peripheral ID Register1 */
330 UInt32 PID2; /*! 0xE000EFE8 Peripheral ID Register2 */
331 UInt32 PID3; /*! 0xE000EFEC Peripheral ID Register3 */
332 UInt32 CID0; /*! 0xE000EFF0 Component ID Register0 */
333 UInt32 CID1; /*! 0xE000EFF4 Component ID Register1 */
334 UInt32 CID2; /*! 0xE000EFF8 Component ID Register2 */
335 UInt32 CID3; /*! 0xE000EFFC Component ID Register3 */
336 }
337
338 /*!
339 * Physical Nested Vectored Interrupt Controller Device.
340 * Short name is "Hwi_nvic"
341 * Long name is "ti_sysbios_family_arm_m3_Hwi_nvic"
342 */
343 extern volatile NVIC nvic;
344
345 /*!
346 * Exception Context - Register contents at the time of an exception.
347 */
348 struct ExcContext {
349
350 BIOS.ThreadType threadType;
351
352 Ptr threadHandle;
353
354 Ptr threadStack;
355
356
357 SizeT threadStackSize;
358
359
360 Ptr r0;
361 Ptr r1;
362 Ptr r2;
363 Ptr r3;
364 Ptr r4;
365 Ptr r5;
366 Ptr r6;
367 Ptr r7;
368 Ptr r8;
369 Ptr r9;
370 Ptr r10;
371 Ptr r11;
372 Ptr r12;
373 Ptr sp;
374 Ptr lr;
375 Ptr pc;
376 Ptr psr;
377
378
379 Ptr ICSR;
380 Ptr MMFSR;
381 Ptr BFSR;
382 Ptr UFSR;
383 Ptr HFSR;
384 Ptr DFSR;
385 Ptr MMAR;
386 Ptr BFAR;
387 Ptr AFSR;
388 }
389
390 /*! @_nodoc */
391 metaonly struct BasicView {
392 Ptr halHwiHandle;
393 String label;
394 Int intNum;
395 Int priority;
396 Int group;
397 Int subPriority;
398 String fxn;
399 UArg arg;
400 };
401
402 /*! @_nodoc */
403 metaonly struct DetailedView {
404 Ptr halHwiHandle;
405 String label;
406 Int intNum;
407 Int priority;
408 Int group;
409 Int subPriority;
410 String fxn;
411 UArg arg;
412 Ptr irp;
413 String status;
414 };
415
416 /*! @_nodoc */
417 metaonly struct ModuleView {
418 String options[4];
419 String activeInterrupt;
420 String pendingInterrupt;
421 String exception;
422 SizeT hwiStackPeak;
423 SizeT hwiStackSize;
424 Ptr hwiStackBase;
425 };
426
427 /*! @_nodoc */
428 @Facet
429 metaonly config ViewInfo.Instance rovViewInfo =
430 ViewInfo.create({
431 viewMap: [
432 ['Basic',
433 {
434 type: ViewInfo.INSTANCE,
435 viewInitFxn: 'viewInitBasic',
436 structName: 'BasicView'
437 }
438 ],
439 ['Detailed',
440 {
441 type: ViewInfo.INSTANCE,
442 viewInitFxn: 'viewInitDetailed',
443 structName: 'DetailedView'
444 }
445 ],
446 ['Module',
447 {
448 type: ViewInfo.MODULE,
449 viewInitFxn: 'viewInitModule',
450 structName: 'ModuleView'
451 }
452 ],
453 ['Exception',
454 {
455 type: ViewInfo.TREE,
456 viewInitFxn: 'viewInitException',
457 structName: 'ExcContext'
458 }
459 ]
460 ]
461 });
462
463
464
465
466
467 /*!
468 * Issued just prior to Hwi function invocation (with interrupts disabled)
469 */
470 config Log.Event LM_begin = {
471 mask: Diags.USER1 | Diags.USER2,
472 msg: "LM_begin: hwi: 0x%x, func: 0x%x, preThread: %d, intNum: %d, irp: 0x%x"
473 };
474
475 /*!
476 * Issued just after return from Hwi function (with interrupts disabled)
477 */
478 config Log.Event LD_end = {
479 mask: Diags.USER2,
480 msg: "LD_end: hwi: 0x%x"
481 };
482
483
484
485 /*! Assert when bad maskSetting parameter provided */
486 config Assert.Id A_unsupportedMaskingOption = {
487 msg: "A_unsupportedMaskingOption: unsupported maskSetting."
488 };
489
490
491
492 /*!
493 * Error raised when Hwi is already defined
494 */
495 config Error.Id E_alreadyDefined = {
496 msg: "E_alreadyDefined: Hwi already defined: intr# %d"
497 };
498
499 /*!
500 * Error raised when an exception occurs
501 */
502 config Error.Id E_exception = {
503 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."
504 };
505
506 /*!
507 * Error raised when an uninitialized interrupt occurs
508 */
509 config Error.Id E_noIsr = {
510 msg: "E_noIsr: id = %d, pc = %08x"
511 };
512
513 /*!
514 * Error raised when NMI exception occurs
515 */
516 config Error.Id E_NMI = {
517 msg: "E_NMI: %s"
518 };
519
520 /*!
521 * Error raised when hard fault exception occurs
522 */
523 config Error.Id E_hardFault = {
524 msg: "E_hardFault: %s"
525 };
526
527 /*!
528 * Error raised when memory fault exception occurs
529 */
530 config Error.Id E_memFault = {
531 msg: "E_memFault: %s"
532 };
533
534 /*!
535 * Error raised when bus fault exception occurs
536 */
537 config Error.Id E_busFault = {
538 msg: "E_busFault: %s"
539 };
540
541 /*!
542 * Error raised when usage fault exception occurs
543 */
544 config Error.Id E_usageFault = {
545 msg: "E_usageFault: %s"
546 };
547
548 /*!
549 * Error raised when svCall exception occurs
550 */
551 config Error.Id E_svCall = {
552 msg: "E_svCall: svNum = %d"
553 };
554
555 /*!
556 * Error raised when debugMon exception occurs
557 */
558 config Error.Id E_debugMon = {
559 msg: "E_debugMon: %s"
560 };
561
562 /*!
563 * Error raised when reserved exception occurs
564 */
565 config Error.Id E_reserved = {
566 msg: "E_reserved: %s %d"
567 };
568
569
570
571 /*!
572 * Location of the Interrupt Vector Table
573 *
574 * This parameter allows the user to override the default placement
575 * of the interrupt vector table. The NVIC's Vector Table Offset
576 * Register (VTOR) is also programmed to this value.
577 *
578 * By default, the interrupt vector table will be placed at
579 * address 0x00000000.
580 *
581 * Some systems require the vector table to be placed at an address
582 * other than 0 but still need a copy of the two M3 boot vectors
583 * (SP and reset PC), located there. To achieve this, a separate
584 * parameter {@link #resetVectorAdress} is provided. If the
585 * resetVectorAddress has a different value then the vectorTableAddress
586 * then a separate 2 vector table is generated and placed at that
587 * address.
588 *
589 * The vector table must be placed at an address at or lower than
590 * 0x3FFFFC00 and must be aligned on an even 64 word boundary.
591 */
592 metaonly config Ptr vectorTableAddress = 0x00000000;
593
594 /*!
595 * Alternate reset vector address. Default is 0x00000000
596 *
597 * if initialized by the user then an additional reset vector
598 * is created and placed in the ".resetVecs" section.
599 * To place the .resetVecs section into a specific memory section,
600 * add the following command to your config script:
601 * @p(code)
602 * Program.sectMap[".resetVecs"] = YourMemorySection;
603 * @p
604 */
605 metaonly config Ptr resetVectorAddress = 0x00000000;
606
607 /*! Reset Handler. Default is c_int00 */
608 metaonly config VectorFuncPtr resetFunc;
609
610 /*! NMI Handler. Default is set to an internal exception handler */
611 metaonly config VectorFuncPtr nmiFunc;
612
613 /*! Hard Fault Handler. Default is set to an internal exception handler */
614 metaonly config VectorFuncPtr hardFaultFunc;
615
616 /*! Hard Mem Handler. Default is set to an internal exception handler */
617 metaonly config VectorFuncPtr memFaultFunc;
618
619 /*! Bus Fault Handler. Default is set to an internal exception handler */
620 metaonly config VectorFuncPtr busFaultFunc;
621
622 /*! Usage Fault Handler. Default is set to an internal exception handler */
623 metaonly config VectorFuncPtr usageFaultFunc;
624
625 /*! SVCall Handler. Default is set to an internal exception handler */
626 metaonly config VectorFuncPtr svCallFunc;
627
628 /*! Debug Mon Handler. Default is set to an internal exception handler */
629 metaonly config VectorFuncPtr debugMonFunc;
630
631 /*! Reserved Exception Handler. Default is set to an internal exception handler */
632 metaonly config VectorFuncPtr reservedFunc;
633
634 /*! Uninitialized ISR Handler. Default is set to an internal exception handler */
635 metaonly config VectorFuncPtr nullIsrFunc;
636
637 /*!
638 * Enable full exception decoding
639 *
640 * When this is enabled, the exception handler will fully
641 * decode an exception and dump the registers to the
642 * system console.
643 */
644 metaonly config Bool enableException = true;
645
646 /*!
647 * User Exception Context Buffer Address
648 *
649 * By default, when an exception occurs, an {@link #ExcContext}
650 * structure is allocated on the ISR stack and filled in within the
651 * exception handler.
652 *
653 * If {@link #excContextBuffer} is initialized by the user, the
654 * {@link #ExcContext} structure will be placed at that address instead.
655 *
656 * The buffer must be large enough to contain an {@link #ExcContext}
657 * structure.
658 */
659 metaonly config Ptr excContextBuffer;
660
661 /*!
662 * User Exception Stack Buffer Address
663 *
664 * By default, when an exception occurs, a pointer to the base address
665 * of the stack being used by the thread causing the exception is placed
666 *
667 * If {@link #excStackBuffer} is initialized by the user, the
668 * stack contents of the thread causing the exception will be
669 * copied to that address instead.
670 *
671 * The buffer must be large enough to contain the largest task stack
672 * or ISR stack defined in the application.
673 */
674 metaonly config Ptr excStackBuffer;
675
676
677 /*!
678 * User Exception hook function.
679 *
680 * Called just after the exception context has been initialized.
681 *
682 * This function will be run on the ISR stack.
683 *
684 * This function must run to completion.
685 *
686 * It is called without any Task or Swi scheduling protection
687 * and therefore can not call any functions that may cause a Swi or Task
688 * scheduling operation (Swi_post(), Semaphore_post(), Event_post(), etc).
689 */
690 config ExceptionHookFuncPtr excHookFunc = null;
691
692 /*!
693 * NVIC CCR register settings
694 *
695 * These setting are written to Hwi_nvic.CCR at startup time.
696 *
697 * See the Cortex M3 architecture reference manual for details
698 * on the meanings of these parameters.
699 */
700 metaonly config CCR nvicCCR = {
701 STKALIGN: 1,
702 BFHFNMIGN: 0,
703 DIV_0_TRP: 0,
704 UNALIGN_TRP: 0,
705 USERSETMPEND: 0,
706 NONEBASETHRDENA: 0
707 };
708
709 /*!
710 * The priority that BASEPRI is set to by Hwi_disable().
711 *
712 * All interrupts configured with equal or less priority (equal or
713 * higher number) than disablePriority are disabled by Hwi_disable.
714 * Interrupts configured with higher priority (smaller number) than
715 * disablePriority are non-maskable (ie zero-latency).
716 *
717 * The default setting is the second highest interrupt priority
718 * defined for the device. This results in priority 0 (and all
719 * other values in the same priority group) being
720 * the non-maskable interrupt priority. All other priorities
721 * are disabled with Hwi_disable().
722 */
723 config UInt disablePriority;
724
725 /*!
726 * The PRIGROUP setting. Default is 0.
727 *
728 * This value will be written to the PRIGROUP field
729 * within the NVIC's Application Interrupt and Reset Control
730 * Register (Hwi_nvic.AIRCR). It defines how the 8 bit priority
731 * values are interpreted by the hardware.
732 *
733 * Valid settings are 0-7.
734 *
735 * The default setting of 0 causes bits 7-1 of an interrupt's
736 * priority value to be used to as a pre-emption priority, and bit 0
737 * is used to determine which of two simultaneous interrupts with
738 * the same pre-emption priority will be serviced first.
739 */
740 config UInt priGroup = 0;
741
742 /*!
743 * non-dispatched interrupt object.
744 * provided so that XGCONF users can easily plug non-dispatched interrupts
745 */
746 metaonly struct NonDispatchedInterrupt {
747 Int intNum;
748 VectorFuncPtr vfxn;
749 UInt priority;
750 Bool enableInt;
751 };
752
753 /*!
754 * non-dispatched interrupt array.
755 * provided so that XGCONF users can easily plug non-dispatched interrupts
756 */
757 metaonly config NonDispatchedInterrupt nonDispatchedInterrupts[string];
758
759
760
761 /*!
762 * ======== disable ========
763 */
764 @Macro
765 override UInt disable();
766
767 /*!
768 * ======== enable ========
769 */
770 @Macro
771 override UInt enable();
772
773 /*!
774 * ======== restore ========
775 */
776 @Macro
777 override Void restore(UInt key);
778
779 /*!
780 * ======== disableInterrupt ========
781 */
782 @DirectCall
783 override UInt disableInterrupt(UInt intNum);
784
785 /*!
786 * ======== enableInterrupt ========
787 */
788 @DirectCall
789 override UInt enableInterrupt(UInt intNum);
790
791 /*!
792 * ======== restore ========
793 */
794 @DirectCall
795 override Void restoreInterrupt(UInt intNum, UInt key);
796
797 /*!
798 * ======== inUseMeta ========
799 * @_nodoc
800 * Check for Hwi already in use.
801 * For internal SYS/BIOS use only.
802 * Should be called prior to any internal Hwi.create().
803 *
804 * @param(intNum) interrupt number
805 */
806 metaonly Bool inUseMeta(UInt intNum);
807
808 /*!
809 * @_nodoc
810 * ======== plug ========
811 * Plug a non dispatched interrupt vector with an ISR address.
812 *
813 * @param(intNum) interrupt number
814 * @param(fxn) pointer to ISR function
815 */
816 @DirectCall
817 Void plug(UInt intNum, VectorFuncPtr fxn);
818
819 /*!
820 * ======== getHandle ========
821 * Returns Hwi_handle associated with intNum
822 *
823 * @param(intNum) interrupt number
824 */
825 @DirectCall
826 Handle getHandle(UInt intNum);
827
828 /*!
829 * ======== setPriority ========
830 * Set an interrupt's relative priority.
831 *
832 * Valid priorities are 0 - 255. 0 is highest priority.
833 *
834 * @param(intNum) ID of interrupt
835 * @param(priority) priority
836 */
837 @DirectCall
838 Void setPriority(UInt intNum, UInt priority);
839
840 /*!
841 * ======== excSetBuffers ========
842 * Set the exception context and stack buffer pointers
843 *
844 * @param(excContextBuffer) Address to place ExcContext
845 * @param(excStackBuffer) Address to place ExcStack
846 */
847 @DirectCall
848 Void excSetBuffers(Ptr excContextBuffer, Ptr excStackBuffer);
849
850 /*! @_nodoc
851 * ======== allowInterrupts ========
852 * WA 1.1 function to briefly enable interrupts
853 */
854 @DirectCall
855 Void allowInterrupts_wa1_1();
856
857 instance:
858
859 /*!
860 * Interrupt priority.
861 * The default is 255 which is the lowest priority.
862 *
863 * Priority 0 is the highest priority and by default is
864 * reserved for zero latency interrupts
865 * (see {@link #disablePriority}).
866 *
867 * Valid priorities values are device dependent and their
868 * nesting behaviors depend on the {@link #priGroup} setting.
869 *
870 * See the Cortex M3 architecture reference manual for details
871 * on the meanings of these parameters.
872 */
873 override config Int priority = 255;
874
875 /*!
876 * Interrupt Masking Option. Only MaskingOption_LOWER is supported.
877 *
878 * The NVIC interrupt controller is designed for priority based
879 * interrupts. No support is provided for anything but
880 * Hwi.MaskingOption_LOWER.
881 */
882 override config IHwi.MaskingOption maskSetting = IHwi.MaskingOption_LOWER;
883
884 /*!
885 * ======== reconfig ========
886 * Reconfigure a dispatched interrupt.
887 */
888 @DirectCall
889 Void reconfig(FuncPtr fxn, const Params *params);
890
891 internal:
892
893 894 895 896 897 898 899 900 901
902 metaonly config Bool enableWA1_1 = false;
903
904 905 906 907 908 909
910 config UInt (*swiDisable)();
911 config Void (*swiRestoreHwi)(UInt);
912 config UInt (*taskDisable)();
913 config Void (*taskRestoreHwi)(UInt);
914
915
916 config UInt32 ccr;
917
918 /*!
919 * const array to hold all HookSet objects.
920 */
921 config HookSet hooks[length] = [];
922
923
924
925 Void beginHook_wa1_1(IHwi.Handle hwi);
926
927 /*!
928 * ======== initVTOR ========
929 * Initialize the Vector Table Offset Register
930 * This function is plugged as a Startup.firstFxn
931 * to set up vector table as early as possible
932 */
933 Void initVTOR();
934
935 /*!
936 * ======== excHandlerAsm ========
937 * asm code exception handler
938 */
939 Void excHandlerAsm();
940
941 /*!
942 * ======== excHandler ========
943 * exception Handler routes to
944 * either min or max exception handler
945 */
946 Void excHandler(UInt *excStack, UInt lr);
947
948 /*!
949 * ======== excHandlerMin ========
950 * Minimal Exception Handler
951 */
952 Void excHandlerMin(UInt *excStack, UInt lr);
953
954 /*!
955 * ======== excHandlerMax ========
956 * Full Featured Exception Handler
957 */
958 Void excHandlerMax(UInt *excStack, UInt lr);
959
960 /*! Hwi exception handler function type definition. */
961 typedef Void (*ExcHandlerFuncPtr)(UInt *, UInt);
962
963 config ExcHandlerFuncPtr excHandlerFunc = excHandlerMin;
964
965 /*!
966 * ======== excFillContext ========
967 */
968 Void excFillContext();
969
970 /*!
971 * ======== excNmi ========
972 */
973 Void excNmi(UInt *excStack);
974
975 /*!
976 * ======== excHardFault ========
977 */
978 Void excHardFault(UInt *excStack);
979
980 /*!
981 * ======== excMemFault ========
982 */
983 Void excMemFault(UInt *excStack);
984
985 /*!
986 * ======== excBusFault ========
987 */
988 Void excBusFault(UInt *excStack);
989
990 /*!
991 * ======== excUsageFault ========
992 */
993 Void excUsageFault(UInt *excStack);
994
995 /*!
996 * ======== excSvCall ========
997 */
998 Void excSvCall(UInt *excStack);
999
1000 /*!
1001 * ======== excDebugMon ========
1002 */
1003 Void excDebugMon(UInt *excStack);
1004
1005 /*!
1006 * ======== excReserved ========
1007 */
1008 Void excReserved(UInt *excStack, UInt excNum);
1009
1010 /*!
1011 * ======== excNoIsr ========
1012 */
1013 Void excNoIsr(UInt *excStack, UInt excNum);
1014
1015 /*!
1016 * ======== excDumpRegs ========
1017 */
1018 Void excDumpRegs(UInt lr);
1019
1020 /*!
1021 * ======== pendSV ========
1022 * Used by dispatcher
1023 */
1024 Void pendSV();
1025
1026 /*!
1027 * ======== init ========
1028 * set up Hwi stack
1029 */
1030 Void init();
1031
1032 /*! Hwi vector function type definition. */
1033 typedef Void (*HandlerFuncPtr)(Handle, UInt);
1034
1035
1036 Void dispatch();
1037
1038 1039 1040 1041
1042 UInt dispatchC(Irp irp);
1043
1044
1045 Void doSwiRestore(UInt tskKey);
1046
1047
1048 Void doTaskRestore(UInt tskKey);
1049
1050 /*! Meta World Only Hwi Configuration Object. */
1051 metaonly struct InterruptObj {
1052 String name;
1053 Bool used;
1054 Bool useDispatcher;
1055 UInt priority;
1056 FuncPtr fxn;
1057 VectorFuncPtr vfxn;
1058 };
1059
1060 /*!
1061 * Meta-only array of interrupt objects.
1062 * This meta-only array of Hwi config objects is initialized
1063 * in Hwi.xs:module$meta$init().
1064 */
1065 metaonly config InterruptObj interrupt[];
1066
1067 struct Instance_State {
1068 UArg arg;
1069 FuncPtr fxn;
1070 Int intNum;
1071 Irp irp;
1072 Ptr hookEnv[];
1073 };
1074
1075 struct Module_State {
1076 Bits16 enables;
1077
1078 Bits32 iser[8];
1079 UInt8 priorities[];
1080 Char *taskSP;
1081
1082 Bool excActive;
1083 ExcContext *excContext;
1084 Ptr excStack;
1085
1086
1087 Ptr isrStack;
1088 Ptr isrStackBase;
1089 SizeT isrStackSize;
1090 Ptr vectorTableBase;
1091 UInt swiTaskKeys;
1092 Handle dispatchTable[];
1093 };
1094 }
1095 1096 1097 1098
1099