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 * Virtual Nested Vectored Interrupt Controller structure
347 * written to by both cores for SMP.
348 * Short name is "Hwi_vnvic"
349 * Long name is "ti_sysbios_family_arm_m3_Hwi_vnvic"
350 */
351 extern volatile NVIC vnvic;
352
353 /*!
354 * Exception Context - Register contents at the time of an exception.
355 */
356 struct ExcContext {
357
358 BIOS.ThreadType threadType;
359
360 Ptr threadHandle;
361
362 Ptr threadStack;
363
364
365 SizeT threadStackSize;
366
367
368 Ptr r0;
369 Ptr r1;
370 Ptr r2;
371 Ptr r3;
372 Ptr r4;
373 Ptr r5;
374 Ptr r6;
375 Ptr r7;
376 Ptr r8;
377 Ptr r9;
378 Ptr r10;
379 Ptr r11;
380 Ptr r12;
381 Ptr sp;
382 Ptr lr;
383 Ptr pc;
384 Ptr psr;
385
386
387 Ptr ICSR;
388 Ptr MMFSR;
389 Ptr BFSR;
390 Ptr UFSR;
391 Ptr HFSR;
392 Ptr DFSR;
393 Ptr MMAR;
394 Ptr BFAR;
395 Ptr AFSR;
396 }
397
398 /*! @_nodoc */
399 metaonly struct BasicView {
400 Ptr halHwiHandle;
401 String label;
402 String type;
403 Int intNum;
404 Int priority;
405 Int group;
406 Int subPriority;
407 String fxn;
408 UArg arg;
409 };
410
411 /*! @_nodoc */
412 metaonly struct DetailedView {
413 Ptr halHwiHandle;
414 String label;
415 String type;
416 Int intNum;
417 Int priority;
418 Int group;
419 Int subPriority;
420 String fxn;
421 UArg arg;
422 Ptr irp;
423 String status;
424 Int coreId;
425 };
426
427 /*! @_nodoc */
428 metaonly struct ModuleView {
429 String options[4];
430 String activeInterrupt;
431 String pendingInterrupt;
432 String exception;
433 SizeT hwiStackPeak;
434 SizeT hwiStackSize;
435 Ptr hwiStackBase;
436 };
437
438 /*! @_nodoc */
439 @Facet
440 metaonly config ViewInfo.Instance rovViewInfo =
441 ViewInfo.create({
442 viewMap: [
443 ['Basic',
444 {
445 type: ViewInfo.INSTANCE,
446 viewInitFxn: 'viewInitBasic',
447 structName: 'BasicView'
448 }
449 ],
450 ['Detailed',
451 {
452 type: ViewInfo.INSTANCE,
453 viewInitFxn: 'viewInitDetailed',
454 structName: 'DetailedView'
455 }
456 ],
457 ['Module',
458 {
459 type: ViewInfo.MODULE,
460 viewInitFxn: 'viewInitModule',
461 structName: 'ModuleView'
462 }
463 ],
464 ['Exception',
465 {
466 type: ViewInfo.TREE,
467 viewInitFxn: 'viewInitException',
468 structName: 'ExcContext'
469 }
470 ]
471 ]
472 });
473
474
475
476
477
478 /*!
479 * Issued just prior to Hwi function invocation (with interrupts disabled)
480 */
481 config Log.Event LM_begin = {
482 mask: Diags.USER1 | Diags.USER2,
483 msg: "LM_begin: hwi: 0x%x, func: 0x%x, preThread: %d, intNum: %d, irp: 0x%x"
484 };
485
486 /*!
487 * Issued just after return from Hwi function (with interrupts disabled)
488 */
489 config Log.Event LD_end = {
490 mask: Diags.USER2,
491 msg: "LD_end: hwi: 0x%x"
492 };
493
494
495
496 /*! Assert when bad maskSetting parameter provided */
497 config Assert.Id A_unsupportedMaskingOption = {
498 msg: "A_unsupportedMaskingOption: unsupported maskSetting."
499 };
500
501
502
503 /*!
504 * Error raised when Hwi is already defined
505 */
506 config Error.Id E_alreadyDefined = {
507 msg: "E_alreadyDefined: Hwi already defined: intr# %d"
508 };
509
510 /*!
511 * Error raised when an exception occurs
512 */
513 config Error.Id E_exception = {
514 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."
515 };
516
517 /*!
518 * Error raised when an uninitialized interrupt occurs
519 */
520 config Error.Id E_noIsr = {
521 msg: "E_noIsr: id = %d, pc = %08x"
522 };
523
524 /*!
525 * Error raised when NMI exception occurs
526 */
527 config Error.Id E_NMI = {
528 msg: "E_NMI: %s"
529 };
530
531 /*!
532 * Error raised when hard fault exception occurs
533 */
534 config Error.Id E_hardFault = {
535 msg: "E_hardFault: %s"
536 };
537
538 /*!
539 * Error raised when memory fault exception occurs
540 */
541 config Error.Id E_memFault = {
542 msg: "E_memFault: %s, address: %08x"
543 };
544
545 /*!
546 * Error raised when bus fault exception occurs
547 */
548 config Error.Id E_busFault = {
549 msg: "E_busFault: %s, address: %08x"
550 };
551
552 /*!
553 * Error raised when usage fault exception occurs
554 */
555 config Error.Id E_usageFault = {
556 msg: "E_usageFault: %s"
557 };
558
559 /*!
560 * Error raised when svCall exception occurs
561 */
562 config Error.Id E_svCall = {
563 msg: "E_svCall: svNum = %d"
564 };
565
566 /*!
567 * Error raised when debugMon exception occurs
568 */
569 config Error.Id E_debugMon = {
570 msg: "E_debugMon: %s"
571 };
572
573 /*!
574 * Error raised when reserved exception occurs
575 */
576 config Error.Id E_reserved = {
577 msg: "E_reserved: %s %d"
578 };
579
580
581
582 /*!
583 * Location of the Interrupt Vector Table
584 *
585 * This parameter allows the user to override the default placement
586 * of the interrupt vector table. The NVIC's Vector Table Offset
587 * Register (VTOR) is also programmed to this value.
588 *
589 * By default, the interrupt vector table will be placed at
590 * address 0x00000000.
591 *
592 * Some systems require the vector table to be placed at an address
593 * other than 0 but still need a copy of the two M3 boot vectors
594 * (SP and reset PC), located there. To achieve this, a separate
595 * parameter {@link #resetVectorAdress} is provided. If the
596 * resetVectorAddress has a different value then the vectorTableAddress
597 * then a separate 2 vector table is generated and placed at that
598 * address.
599 *
600 * The vector table must be placed at an address at or lower than
601 * 0x3FFFFC00 and must be aligned on an even 64 word boundary.
602 */
603 metaonly config Ptr vectorTableAddress = 0x00000000;
604
605 /*!
606 * Alternate reset vector address. Default is 0x00000000
607 *
608 * if initialized by the user then an additional reset vector
609 * is created and placed in the ".resetVecs" section.
610 * To place the .resetVecs section into a specific memory section,
611 * add the following command to your config script:
612 * @p(code)
613 * Program.sectMap[".resetVecs"] = YourMemorySection;
614 * @p
615 */
616 metaonly config Ptr resetVectorAddress = 0x00000000;
617
618 /*! Reset Handler. Default is c_int00 */
619 metaonly config VectorFuncPtr resetFunc;
620
621 /*! NMI Handler. Default is set to an internal exception handler */
622 metaonly config VectorFuncPtr nmiFunc;
623
624 /*! Hard Fault Handler. Default is set to an internal exception handler */
625 metaonly config VectorFuncPtr hardFaultFunc;
626
627 /*! Hard Mem Handler. Default is set to an internal exception handler */
628 metaonly config VectorFuncPtr memFaultFunc;
629
630 /*! Bus Fault Handler. Default is set to an internal exception handler */
631 metaonly config VectorFuncPtr busFaultFunc;
632
633 /*! Usage Fault Handler. Default is set to an internal exception handler */
634 metaonly config VectorFuncPtr usageFaultFunc;
635
636 /*! SVCall Handler. Default is set to an internal exception handler */
637 metaonly config VectorFuncPtr svCallFunc;
638
639 /*! Debug Mon Handler. Default is set to an internal exception handler */
640 metaonly config VectorFuncPtr debugMonFunc;
641
642 /*! Reserved Exception Handler. Default is set to an internal exception handler */
643 metaonly config VectorFuncPtr reservedFunc;
644
645 /*! Uninitialized ISR Handler. Default is set to an internal exception handler */
646 metaonly config VectorFuncPtr nullIsrFunc;
647
648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674
675 metaonly config UInt8 intAffinity[];
676
677 /*!
678 * Enable full exception decoding
679 *
680 * When this is enabled, the exception handler will fully
681 * decode an exception and dump the registers to the
682 * system console.
683 */
684 metaonly config Bool enableException = true;
685
686 /*!
687 * User Exception Context Buffer Address
688 *
689 * By default, when an exception occurs, an {@link #ExcContext}
690 * structure is allocated on the ISR stack and filled in within the
691 * exception handler.
692 *
693 * If {@link #excContextBuffer} is initialized by the user, the
694 * {@link #ExcContext} structure will be placed at that address instead.
695 *
696 * The buffer must be large enough to contain an {@link #ExcContext}
697 * structure.
698 */
699 metaonly config Ptr excContextBuffer;
700 metaonly config Ptr excContextBuffers[];
701
702 /*!
703 * User Exception Stack Buffer Address
704 *
705 * By default, when an exception occurs, a pointer to the base address
706 * of the stack being used by the thread causing the exception is placed
707 *
708 * If {@link #excStackBuffer} is initialized by the user, the
709 * stack contents of the thread causing the exception will be
710 * copied to that address instead.
711 *
712 * The buffer must be large enough to contain the largest task stack
713 * or ISR stack defined in the application.
714 */
715 metaonly config Ptr excStackBuffer;
716 metaonly config Ptr excStackBuffers[];
717
718
719 /*!
720 * User Exception hook function.
721 *
722 * Called just after the exception context has been initialized.
723 *
724 * This function will be run on the ISR stack.
725 *
726 * This function must run to completion.
727 *
728 * It is called without any Task or Swi scheduling protection
729 * and therefore can not call any functions that may cause a Swi or Task
730 * scheduling operation (Swi_post(), Semaphore_post(), Event_post(), etc).
731 */
732 config ExceptionHookFuncPtr excHookFunc = null;
733 config ExceptionHookFuncPtr excHookFuncs[];
734
735 /*!
736 * NVIC CCR register settings
737 *
738 * These setting are written to Hwi_nvic.CCR at startup time.
739 *
740 * See the Cortex M3 architecture reference manual for details
741 * on the meanings of these parameters.
742 */
743 metaonly config CCR nvicCCR = {
744 STKALIGN: 1,
745 BFHFNMIGN: 0,
746 DIV_0_TRP: 0,
747 UNALIGN_TRP: 0,
748 USERSETMPEND: 0,
749 NONEBASETHRDENA: 0
750 };
751
752 /*!
753 * The priority that BASEPRI is set to by Hwi_disable().
754 *
755 * All interrupts configured with equal or less priority (equal or
756 * higher number) than disablePriority are disabled by Hwi_disable.
757 * Interrupts configured with higher priority (smaller number) than
758 * disablePriority are non-maskable (ie zero-latency).
759 *
760 * The default setting is the second highest interrupt priority
761 * defined for the device. This results in priority 0 (and all
762 * other values in the same priority group) being
763 * the non-maskable interrupt priority. All other priorities
764 * are disabled with Hwi_disable().
765 */
766 config UInt disablePriority;
767
768 /*!
769 * The PRIGROUP setting. Default is 0.
770 *
771 * This value will be written to the PRIGROUP field
772 * within the NVIC's Application Interrupt and Reset Control
773 * Register (Hwi_nvic.AIRCR). It defines how the 8 bit priority
774 * values are interpreted by the hardware.
775 *
776 * Valid settings are 0-7.
777 *
778 * The default setting of 0 causes bits 7-1 of an interrupt's
779 * priority value to be used to as a pre-emption priority, and bit 0
780 * is used to determine which of two simultaneous interrupts with
781 * the same pre-emption priority will be serviced first.
782 */
783 config UInt priGroup = 0;
784
785
786
787 /*!
788 * ======== disable ========
789 */
790 @Macro
791 override UInt disable();
792
793 /*!
794 * ======== enable ========
795 */
796 @Macro
797 override UInt enable();
798
799 /*!
800 * ======== restore ========
801 */
802 @Macro
803 override Void restore(UInt key);
804
805 /*!
806 * @_nodoc
807 * ======== disableFxn ========
808 * function call implementation
809 */
810 @DirectCall
811 UInt disableFxn();
812
813 /*!
814 * @_nodoc
815 * ======== enableFxn ========
816 * function call implementation
817 */
818 @DirectCall
819 UInt enableFxn();
820
821 /*!
822 * @_nodoc
823 * ======== restoreFxn ========
824 * function call implementation
825 */
826 @DirectCall
827 Void restoreFxn(UInt key);
828
829 /*!
830 * ======== inUseMeta ========
831 * @_nodoc
832 * Check for Hwi already in use.
833 * For internal SYS/BIOS use only.
834 * Should be called prior to any internal Hwi.create().
835 *
836 * @param(intNum) interrupt number
837 */
838 metaonly Bool inUseMeta(UInt intNum);
839
840 /*!
841 * @_nodoc
842 * ======== plug ========
843 * Plug a non dispatched interrupt vector with an ISR address.
844 *
845 * @param(intNum) interrupt number
846 * @param(fxn) pointer to ISR function
847 */
848 @DirectCall
849 Void plug(UInt intNum, VectorFuncPtr fxn);
850
851 /*!
852 * ======== getHandle ========
853 * Returns Hwi_handle associated with intNum
854 *
855 * @param(intNum) interrupt number
856 */
857 @DirectCall
858 Handle getHandle(UInt intNum);
859
860 /*!
861 * ======== setPriority ========
862 * Set an interrupt's relative priority.
863 *
864 * Valid priorities are 0 - 255. 0 is highest priority.
865 *
866 * @param(intNum) ID of interrupt
867 * @param(priority) priority
868 */
869 @DirectCall
870 Void setPriority(UInt intNum, UInt priority);
871
872 /*!
873 * ======== excSetBuffers ========
874 * Set the exception context and stack buffer pointers
875 *
876 * @param(excContextBuffer) Address to place ExcContext
877 * @param(excStackBuffer) Address to place ExcStack
878 */
879 @DirectCall
880 Void excSetBuffers(Ptr excContextBuffer, Ptr excStackBuffer);
881
882 /*!
883 * @_nodoc
884 * ======== initNVIC ========
885 * initialize everything but leave ints disabled
886 */
887 @DirectCall
888 Void initNVIC();
889
890 /*!
891 * @_nodoc
892 * ======== initStacks ========
893 * set up M3 split stacks
894 */
895 @DirectCall
896 Void initStacks(Ptr hwiStack);
897
898 /*!
899 * @_nodoc
900 * ======== flushVnvic ========
901 * Reconfigure a dispatched interrupt.
902 *
903 * Called by the internal function "Hwi_updateNvic()".
904 *
905 * This is a public API because it is also called by "Core_hwiFunc()".
906 */
907 @DirectCall
908 Void flushVnvic();
909
910 instance:
911
912 /*!
913 * Interrupt priority.
914 * The default is 255 which is the lowest priority.
915 *
916 * Priority 0 is the highest priority and by default is
917 * reserved for zero latency interrupts
918 * (see {@link #disablePriority}).
919 *
920 * Valid priorities values are device dependent and their
921 * nesting behaviors depend on the {@link #priGroup} setting.
922 *
923 * See the Cortex M3 architecture reference manual for details
924 * on the meanings of these parameters.
925 */
926 override config Int priority = 255;
927
928 /*!
929 * Interrupt Masking Option. Only MaskingOption_LOWER is supported.
930 *
931 * The NVIC interrupt controller is designed for priority based
932 * interrupts. No support is provided for anything but
933 * Hwi.MaskingOption_LOWER.
934 */
935 override config IHwi.MaskingOption maskSetting = IHwi.MaskingOption_LOWER;
936
937 /*!
938 * Use the interrupt dispatcher with this interrupt. Default is true.
939 *
940 * If set to false, the interrupt dispatcher is NOT used. Instead,
941 * the configured Hwi function address is placed directly in the
942 * vector table, which results in the dispatcher being bypassed.
943 *
944 * @a(Warning)
945 * Interrupts configured to bupass the dispatcher are not allowed
946 * to call ANY SYS/BIOS APIs that effect thread scheduling. Examples
947 * of API that should no be invoked are:
948 *
949 * @p(dlist)
950 * - Swi_post(),
951 * - Semaphore_post(),
952 * - Event_post(),
953 * - Task_yield()
954 * @p
955 *
956 * Additionally, although the signature for a non-dispatched interrupt
957 * function is the same as that for a dispatched interrupt
958 * (see {@link #FuncPtr}), no argument is actually passed
959 * to the non-dispatched ISR handler.
960 */
961 config Bool useDispatcher = true;
962
963 /*!
964 * ======== reconfig ========
965 * Reconfigure a dispatched interrupt.
966 */
967 @DirectCall
968 Void reconfig(FuncPtr fxn, const Params *params);
969
970 internal:
971
972
973 config Handle dispatchTable[];
974
975
976 config UInt8 priorities[];
977
978 979 980 981 982 983 984 985 986
987 metaonly config Bool enableWA1_1 = false;
988
989 990 991 992 993 994
995 config UInt (*swiDisable)();
996 config Void (*swiRestoreHwi)(UInt);
997 config UInt (*taskDisable)();
998 config Void (*taskRestoreHwi)(UInt);
999
1000
1001 config UInt32 ccr;
1002
1003 /*!
1004 * const array to hold all HookSet objects.
1005 */
1006 config HookSet hooks[length] = [];
1007
1008 1009 1010 1011
1012 Int postInit(Object *hwi, Error.Block *eb);
1013
1014 /*!
1015 * ======== updateNvic ========
1016 * Internal SMP function to cause the virtual NVIC to be flushed to the
1017 * actual NVIC.
1018 *
1019 * This function is called by the various user APIs that manipulate
1020 * individual NVIC register bits
1021 * (ie Hwi_enable/disable/restore/clearInterrupt())
1022 *
1023 * If the current core is the owner of "intNum", flushVnvic() is called
1024 * immediately.
1025 *
1026 * Otherwise an intercore interrupt is generated to force the other core
1027 * to perform the flushVnvic().
1028 *
1029 */
1030 Void updateNvic(UInt intNum);
1031
1032 /*!
1033 * ======== initEnables ========
1034 * initialize the enables
1035 */
1036 Void initEnables();
1037
1038 /*!
1039 * ======== excHandlerAsm ========
1040 * asm code exception handler
1041 */
1042 Void excHandlerAsm();
1043
1044 /*!
1045 * ======== excHandler ========
1046 * exception Handler routes to
1047 * either min or max exception handler
1048 */
1049 Void excHandler(UInt *excStack, UInt lr);
1050
1051 /*!
1052 * ======== excHandlerMin ========
1053 * Minimal Exception Handler
1054 */
1055 Void excHandlerMin(UInt *excStack, UInt lr);
1056
1057 /*!
1058 * ======== excHandlerMax ========
1059 * Full Featured Exception Handler
1060 */
1061 Void excHandlerMax(UInt *excStack, UInt lr);
1062
1063 /*! Hwi exception handler function type definition. */
1064 typedef Void (*ExcHandlerFuncPtr)(UInt *, UInt);
1065
1066 config ExcHandlerFuncPtr excHandlerFunc = excHandlerMin;
1067
1068 /*!
1069 * ======== excFillContext ========
1070 */
1071 Void excFillContext();
1072
1073 /*!
1074 * ======== excNmi ========
1075 */
1076 Void excNmi(UInt *excStack);
1077
1078 /*!
1079 * ======== excHardFault ========
1080 */
1081 Void excHardFault(UInt *excStack);
1082
1083 /*!
1084 * ======== excMemFault ========
1085 */
1086 Void excMemFault(UInt *excStack);
1087
1088 /*!
1089 * ======== excBusFault ========
1090 */
1091 Void excBusFault(UInt *excStack);
1092
1093 /*!
1094 * ======== excUsageFault ========
1095 */
1096 Void excUsageFault(UInt *excStack);
1097
1098 /*!
1099 * ======== excSvCall ========
1100 */
1101 Void excSvCall(UInt *excStack);
1102
1103 /*!
1104 * ======== excDebugMon ========
1105 */
1106 Void excDebugMon(UInt *excStack);
1107
1108 /*!
1109 * ======== excReserved ========
1110 */
1111 Void excReserved(UInt *excStack, UInt excNum);
1112
1113 /*!
1114 * ======== excNoIsr ========
1115 */
1116 Void excNoIsr(UInt *excStack, UInt excNum);
1117
1118 /*!
1119 * ======== excDumpRegs ========
1120 */
1121 Void excDumpRegs(UInt lr);
1122
1123 /*!
1124 * ======== pendSV ========
1125 * Used by dispatcher
1126 */
1127 Void pendSV();
1128
1129 /*! Hwi vector function type definition. */
1130 typedef Void (*HandlerFuncPtr)(Handle, UInt);
1131
1132
1133 Void dispatch();
1134
1135 1136 1137 1138
1139 UInt dispatchC(Irp irp);
1140
1141
1142 Void doSwiRestore(UInt tskKey);
1143
1144
1145 Void doTaskRestore(UInt tskKey);
1146
1147 /*! Meta World Only Hwi Configuration Object. */
1148 metaonly struct InterruptObj {
1149 String name;
1150 Bool used;
1151 Bool useDispatcher;
1152 UInt priority;
1153 FuncPtr fxn;
1154 };
1155
1156 /*!
1157 * Meta-only array of interrupt objects.
1158 * This meta-only array of Hwi config objects is initialized
1159 * in Hwi.xs:module$meta$init().
1160 */
1161 metaonly config InterruptObj interrupt[];
1162
1163 struct Instance_State {
1164 UArg arg;
1165 FuncPtr fxn;
1166 Int intNum;
1167 Irp irp;
1168 Ptr hookEnv[];
1169 };
1170
1171 struct Module_State {
1172 Bits16 enables;
1173
1174 Bits32 iser[8];
1175 UInt8 priorities[];
1176 Char *taskSP;
1177
1178 Bool excActive[];
1179 ExcContext *excContext[];
1180 Ptr excStack[];
1181 Ptr isrStack;
1182 Ptr isrStackBase;
1183 SizeT isrStackSize;
1184 Ptr vectorTableBase;
1185 UInt swiTaskKeys;
1186 volatile Bool vnvicFlushRequired;
1187
1188 Handle dispatchTable[];
1189 UInt8 intAffinity[];
1190 UInt32 intAffinityMasks[][];
1191 };
1192 }