1 /*
2 * Copyright (c) 2013, Texas Instruments Incorporated
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * * Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 *
12 * * Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * * Neither the name of Texas Instruments Incorporated nor the names of
17 * its contributors may be used to endorse or promote products derived
18 * from this software without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
22 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
24 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
27 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
28 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
29 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
30 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 */
32
33 /*
34 * ======== Hwi.xdc ========
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") /* generates the vector table and the dispatcher */
219 @ModuleStartup /* generate a call to startup function */
220
221 module Hwi inherits ti.sysbios.interfaces.IHwi
222 {
223 // -------- Module Constants --------
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 // -------- Module Types --------
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 /* Thread Context */
358 BIOS.ThreadType threadType; /* Type of thread executing at */
359 /* the time the exception occurred */
360 Ptr threadHandle; /* Handle to thread executing at */
361 /* the time the exception occurred */
362 Ptr threadStack; /* Address of stack contents of thread */
363 /* executing at the time the exception */
364 /* occurred */
365 SizeT threadStackSize; /* size of thread stack */
366
367 /* Internal Registers */
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 /* NVIC registers */
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 metaonlystruct 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 metaonlystruct 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 metaonlystruct ModuleView {
429 String options[4];
430 String activeInterrupt;
431 String pendingInterrupt;
432 String exception;
433 String hwiStackPeak;
434 SizeT hwiStackSize;
435 Ptr hwiStackBase;
436 };
437
438 /*! @_nodoc */
439 @Facet
440 metaonlyconfig 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 // -------- Module Parameters --------
475
476 // Logs
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 // Asserts
495
496 /*! Assert when bad maskSetting parameter provided */
497 config Assert.Id A_unsupportedMaskingOption = {
498 msg: "A_unsupportedMaskingOption: unsupported maskSetting."
499 };
500
501 // Errors
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 // configs
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 metaonlyconfig 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 metaonlyconfig Ptr resetVectorAddress = 0x00000000;
617
618 /*! Reset Handler. Default is c_int00 */
619 metaonlyconfig VectorFuncPtr resetFunc;
620
621 /*! NMI Handler. Default is set to an internal exception handler */
622 metaonlyconfig VectorFuncPtr nmiFunc;
623
624 /*! Hard Fault Handler. Default is set to an internal exception handler */
625 metaonlyconfig VectorFuncPtr hardFaultFunc;
626
627 /*! Hard Mem Handler. Default is set to an internal exception handler */
628 metaonlyconfig VectorFuncPtr memFaultFunc;
629
630 /*! Bus Fault Handler. Default is set to an internal exception handler */
631 metaonlyconfig VectorFuncPtr busFaultFunc;
632
633 /*! Usage Fault Handler. Default is set to an internal exception handler */
634 metaonlyconfig VectorFuncPtr usageFaultFunc;
635
636 /*! SVCall Handler. Default is set to an internal exception handler */
637 metaonlyconfig VectorFuncPtr svCallFunc;
638
639 /*! Debug Mon Handler. Default is set to an internal exception handler */
640 metaonlyconfig VectorFuncPtr debugMonFunc;
641
642 /*! Reserved Exception Handler. Default is set to an internal exception handler */
643 metaonlyconfig VectorFuncPtr reservedFunc;
644
645 /*! Uninitialized ISR Handler. Default is set to an internal exception handler */
646 metaonlyconfig VectorFuncPtr nullIsrFunc;
647
648 /*
649 * SMP Interrupt affinity mappings
650 *
651 * In SMP mode, this array maps an interrupt number to the
652 * coreId it is to be tied to. By default, all ints are mapped to
653 * core 0.
654 *
655 * For example, to make Timer 1 from the
656 * ti.sysbios.family.arm.ducati.Timer
657 * module interrupt on core 1 rather than core 0, add the following to
658 * your config file:
659 *
660 * @p(code)
661 * var m3Hwi = xdc.useModule('ti.sysbios.family.arm.m3.Hwi');
662 * m3Hwi.intAffinity[22] = 1;
663 * @p
664 *
665 * @a(constraints)
666 * Valid core Ids are 0 and 1 for Ducati/Benelli SMP applications.
667 *
668 * Interrupt numbers below 16 are ignored.
669 * Only interrupt numbers greater than or equal to #16 can be routed to
670 * either Ducati/Benelli core.
671 *
672 * Interrupt #19, the Ducati inter-core interrupt, is reserved for
673 * exclusive use within the SMP kernel.
674 */
675 metaonlyconfig 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 metaonlyconfig 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 metaonlyconfig Ptr excContextBuffer;
700 metaonlyconfig 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 metaonlyconfig Ptr excStackBuffer;
716 metaonlyconfig 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 metaonlyconfig 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 // -------- Module Functions --------
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 overrideconfig 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 overrideconfig 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: /* not for client use */
971
972 /* const dispatchTable */
973 config Handle dispatchTable[];
974
975 /* const array of statically created Hwi priorities */
976 config UInt8 priorities[];
977
978 /*
979 * Boolean to indicate whether the current target is being
980 * built using tiva platform.
981 */
982 metaonlyconfig Bool isTiva = false;
983
984 /*
985 * The omap4430 ES1 devices have a nasty bug in the unicache
986 * that locks the bus up when an interrupt occurs at a specific
987 * time during an internal cache operation.
988 * The flag below, when set to true, activates special
989 * code in the Hwi module to work around this bug.
990 * "WA1_1" comes from "WorkAround 1.1" from a list of potential
991 * solutions to the problem developed by the design team.
992 */
993 metaonlyconfig Bool enableWA1_1 = false;
994
995 /*
996 * Swi and Task module function pointers.
997 * Used to decouple Hwi from Swi and Task when
998 * dispatcherSwiSupport or
999 * dispatcherTaskSupport is false.
1000 */
1001 config UInt (*swiDisable)();
1002 config Void (*swiRestoreHwi)(UInt);
1003 config UInt (*taskDisable)();
1004 config Void (*taskRestoreHwi)(UInt);
1005
1006 /* initial Hwi_nvic.CCR value */
1007 config UInt32 ccr;
1008
1009 /*!
1010 * const array to hold all HookSet objects.
1011 */
1012 config HookSet hooks[length] = [];
1013
1014 /*
1015 * ======== postInit ========
1016 * finish initializing static and dynamic Hwis
1017 */
1018 Int postInit(Object *hwi, Error.Block *eb);
1019
1020 /*!
1021 * ======== updateNvic ========
1022 * Internal SMP function to cause the virtual NVIC to be flushed to the
1023 * actual NVIC.
1024 *
1025 * This function is called by the various user APIs that manipulate
1026 * individual NVIC register bits
1027 * (ie Hwi_enable/disable/restore/clearInterrupt())
1028 *
1029 * If the current core is the owner of "intNum", flushVnvic() is called
1030 * immediately.
1031 *
1032 * Otherwise an intercore interrupt is generated to force the other core
1033 * to perform the flushVnvic().
1034 *
1035 */
1036 Void updateNvic(UInt intNum);
1037
1038 /*!
1039 * ======== initEnables ========
1040 * initialize the enables
1041 */
1042 Void initEnables();
1043
1044 /*!
1045 * ======== excHandlerAsm ========
1046 * asm code exception handler
1047 */
1048 Void excHandlerAsm();
1049
1050 /*!
1051 * ======== excHandler ========
1052 * exception Handler routes to
1053 * either min or max exception handler
1054 */
1055 Void excHandler(UInt *excStack, UInt lr);
1056
1057 /*!
1058 * ======== excHandlerMin ========
1059 * Minimal Exception Handler
1060 */
1061 Void excHandlerMin(UInt *excStack, UInt lr);
1062
1063 /*!
1064 * ======== excHandlerMax ========
1065 * Full Featured Exception Handler
1066 */
1067 Void excHandlerMax(UInt *excStack, UInt lr);
1068
1069 /*! Hwi exception handler function type definition. */
1070 typedef Void (*ExcHandlerFuncPtr)(UInt *, UInt);
1071
1072 config ExcHandlerFuncPtr excHandlerFunc = excHandlerMin;
1073
1074 /*!
1075 * ======== excFillContext ========
1076 */
1077 Void excFillContext();
1078
1079 /*!
1080 * ======== excNmi ========
1081 */
1082 Void excNmi(UInt *excStack);
1083
1084 /*!
1085 * ======== excHardFault ========
1086 */
1087 Void excHardFault(UInt *excStack);
1088
1089 /*!
1090 * ======== excMemFault ========
1091 */
1092 Void excMemFault(UInt *excStack);
1093
1094 /*!
1095 * ======== excBusFault ========
1096 */
1097 Void excBusFault(UInt *excStack);
1098
1099 /*!
1100 * ======== excUsageFault ========
1101 */
1102 Void excUsageFault(UInt *excStack);
1103
1104 /*!
1105 * ======== excSvCall ========
1106 */
1107 Void excSvCall(UInt *excStack);
1108
1109 /*!
1110 * ======== excDebugMon ========
1111 */
1112 Void excDebugMon(UInt *excStack);
1113
1114 /*!
1115 * ======== excReserved ========
1116 */
1117 Void excReserved(UInt *excStack, UInt excNum);
1118
1119 /*!
1120 * ======== excNoIsr ========
1121 */
1122 Void excNoIsr(UInt *excStack, UInt excNum);
1123
1124 /*!
1125 * ======== excDumpRegs ========
1126 */
1127 Void excDumpRegs(UInt lr);
1128
1129 /*!
1130 * ======== pendSV ========
1131 * Used by dispatcher
1132 */
1133 Void pendSV();
1134
1135 /*! Hwi vector function type definition. */
1136 typedef Void (*HandlerFuncPtr)(Handle, UInt);
1137
1138 /* Low Level Interrupt Dispatcher Wrapper */
1139 Void dispatch();
1140
1141 /*
1142 * "Top Half" of Interrupt Dispatcher
1143 * Does not include Swi_restore() and Task_restore()
1144 */
1145 UInt dispatchC(Irp irp);
1146
1147 /* "Bottom half", run swi scheduler */
1148 Void doSwiRestore(UInt tskKey);
1149
1150 /* "Bottom half", run task scheduler */
1151 Void doTaskRestore(UInt tskKey);
1152
1153 /*! Meta World Only Hwi Configuration Object. */
1154 metaonlystruct InterruptObj {
1155 String name; /* symbol used for vector table entry */
1156 Bool used; /* Interrupt already defined? */
1157 Bool useDispatcher; /* Should dispatcher handle this Int? */
1158 UInt priority; /* priority */
1159 FuncPtr fxn; /* Dispatched ISR function */
1160 };
1161
1162 /*!
1163 * Meta-only array of interrupt objects.
1164 * This meta-only array of Hwi config objects is initialized
1165 * in Hwi.xs:module$meta$init().
1166 */
1167 metaonlyconfig InterruptObj interrupt[];
1168
1169 struct Instance_State {
1170 UArg arg; // Argument to Hwi function.
1171 FuncPtr fxn; // Hwi function.
1172 Int intNum; // Interrupt number
1173 Irp irp; // current IRP
1174 Ptr hookEnv[];
1175 };
1176
1177 struct Module_State {
1178 Bits16 enables; // Bit 15 = SysTick IE,
1179 // Bit 0 = WA1.1
1180 Bits32 iser[8]; // Initial Interrupt Set Enable Reg values
1181 UInt8 priorities[]; // table of interrupt priorities
1182 Char *taskSP; // Temporary storage of interrupted
1183 // Task's SP during ISR execution
1184 Bool excActive[]; // TRUE if an exception has occurred
1185 ExcContext *excContext[]; // Exception context
1186 Ptr excStack[]; // Exception thread stack
1187 Ptr isrStack; // Points to isrStack address
1188 Ptr isrStackBase; // = __TI_STACK_BASE
1189 SizeT isrStackSize; // = Program.stack
1190 Ptr vectorTableBase; // Points to base of vector table
1191 UInt swiTaskKeys; // dispatcher Swi and Task key storage
1192 volatile Bool vnvicFlushRequired; // if TRUE, Hwi_vnvicFlush will copy
1193 // changed vnvic regs to nvic
1194 Handle dispatchTable[]; // dispatch table
1195 UInt8 intAffinity[]; // smp int-to-coreId mappings
1196 UInt32 intAffinityMasks[][]; // smp per-core NVIC register masks
1197 };
1198 }