1 /*
2 * Copyright (c) 2015-2019, 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 import xdc.runtime.Types;
45
46 import ti.sysbios.BIOS;
47 import ti.sysbios.interfaces.IHwi;
48
49 /*!
50 * ======== Hwi ========
51 * Cortex M3/M4 Hardware Interrupt Manager
52 *
53 * The Cortex-M devices' Nested Vectored Interrupt Controller (NVIC)
54 * supports up to 256 interrupts/exceptions. In practice, most
55 * devices support much fewer (ie the SimpleLink CC13XX/CC26XX
56 * family of devices have only 50 total interrupts defined).
57 *
58 * SYS/BIOS Interrupt IDs or interrupt numbers correspond
59 * to an interrupt's position in the interrupt vector table.
60 *
61 * ID 0 corresponds to vector 0 which is used by the NVIC
62 * to hold the initial (reset) stack pointer value.
63 *
64 * ID 1 corresponds to vector 1 which is the reset vector which is
65 * usually initialized to point to an application's entry point
66 * (ie for the TI compiler tool chain, the entry point is "_c_int00")
67 *
68 * IDs 2-13 are, by default, hard wired to the internal exception handler
69 * which will save important context information that can be viewed
70 * using the ROV tool within either the Code Composer Studio debugger
71 * or the IAR Workbench debugger.
72 *
73 * ID 14 is the "pendSV" handler which is used exclusively by the shared
74 * interrupt dispatcher to orchestrate the execution of
75 * {@link ti.sysbios.knl.Swi Swis} posted
76 * from within interrupts, as well as to manage asynchronous
77 * task pre-emption upon returning from interrupts which have
78 * readied a task of higher priority than the task that
79 * was interrupted.
80 *
81 * ID 15 is the SysTick timer interrupt.
82 *
83 * ID's 16-255 are mapped to the NVIC's "User" interrupts 0-239
84 * which are tied to platform specific interrupt sources.
85 *
86 * @a(Zero Latency Interrupts) 87 * The M3/M4 Hwi module supports "zero latency" interrupts.
88 * Interrupts configured with priority greater (in actual
89 * hardware priority, but lower in number) than the configured
90 * {@link #disablePriority Hwi.disablePriority} are NOT
91 * disabled by {@link #disable Hwi_disable()}, and they are not managed by
92 * the internal interrupt dispatcher.
93 *
94 * Zero Latency interrupts fall into the commonly used category
95 * of "Unmanaged Interrupts". However they are somewhat distinct from
96 * that definition in that in addition to being unmanaged, they are
97 * also almost never disabled by SYS/BIOS code, thus gaining the
98 * "Zero Latency" title.
99 *
100 * Zero latency interrupts are distinguished from regular dispatched
101 * interrupts at create time solely by their interrupt priority being
102 * set greater than the configured Hwi.disablePriority.
103 *
104 * Note that since zero latency interrupts don't use the dispatcher,
105 * the {@link ti.sysbios.interfaces.IHwi#arg arg} parameter is not
106 * functional. Also note that due to the Cortex-M's native automatic
107 * stacking of saved-by-caller C context on the way to an ISR, zero
108 * latency interrupt handlers are implemented using regular C functions
109 * (ie no 'interrupt' keyword is required).
110 *
111 * @a(WARNING) 112 * Zero latency interrupts are NOT HANDLED by the SYS/BIOS
113 * interrupt dispatcher! Instead, they are vectored to directly.
114 * As such, and because they are NOT DISABLED BY Hwi_disable(),
115 * these interrupt handlers are SEVERELY RESTRICTED in terms of the
116 * SYS/BIOS APIs they can invoke and THREAD SAFETY MUST BE CAREFULLY
117 * CONSIDERED! See the descriptions of {@link #disable Hwi_disable()} and
118 * and {@link #disablePriority Hwi.disablePriority} for more details.
119 *
120 * @a(Interrupt Masking Options) 121 *
122 * The NVIC interrupt controller is designed for priority based
123 * interrupts.
124 *
125 * In this Hwi module, the {@link #maskSetting} instance configuration
126 * parameter is ignored.
127 * Effectively, only the {@link #MaskingOption_LOWER} is supported.
128 *
129 * @a(Interrupt Priorities) 130 *
131 * In general, the NVIC supports priority values of 0 thru 255.
132 *
133 * In practice, the number of priorities and their values are device
134 * dependent, and their nesting behaviors depend on the
135 * {@link #priGroup Hwi.priGroup} setting.
136 *
137 * For most TI MCU devices, 8 priorities are supported. A peculiarity
138 * of ARM's NVIC is that, although the priority field is an 8 bit value,
139 * the range of supported priority values are left-justified within this
140 * 8 bit field. Consequently, the 8 priority values are not 0 thru 7 as
141 * one might expect, but rather:
142 *
143 * @p(code) 144 * 0x00 // highest priority, non dispatched, Zero Latency priority
145 * 0x20 // highest dispatched interrupt priority
146 * 0x40
147 * 0x60
148 * 0x80
149 * 0xa0
150 * 0xc0
151 * 0xe0 // lowest dispatched interrupt priority, (default)
152 * @p 153 *
154 * Priority 0 is the highest priority and by default is
155 * reserved for zero latency interrupts
156 * (see {@link #disablePriority Hwi.disablePriority}).
157 *
158 * See the {@link http://infocenter.arm.com/help/topic/com.arm.doc.dui0553a/CIHIGCIF.html Cortex M4 Devices Generic User Guide}
159 * for details on the behavior of interrupt priorities and their relationship
160 * to the {@link #priGroup Hwi.priGroup} setting.
161 *
162 * @a(Interrupt Vector Tables) 163 * SimpleLink CC13XX/CC26XX devices:
164 *
165 * By default, two vector tables are created for SimpleLink devices:
166 *
167 * A 15 entry boot vector table is placed at address 0x00000000 in
168 * FLASH.
169 *
170 * A 50 entry vector table is placed at address 0x20000000 in RAM.
171 *
172 * The FLASH boot vector table contains the reset vector and exception
173 * handler vectors used until the RAM based vector table is initialized.
174 *
175 * The RAM vector table contains those same first 15 vectors as well as
176 * the SysTick vector and the remainder of the user interrupt vectors.
177 *
178 * During system startup, the NVIC Vector Table Offset Registor is
179 * intialized to point to the RAM vector table after it has been
180 * initialized.
181 *
182 * @a( ) 183 * Dual M3/M4 Core ('Ducati'/'Benelli') devices:
184 *
185 * By default, Ducati/Benelli core 0 places its runtime vector table at
186 * address 0x00000400 and core 1 places its runtime vector table at
187 * address 0x00000800.
188 *
189 * Additionally, a boot vector table is placed at address
190 * 0x00000000 which is shared by both cores.
191 *
192 * The boot reset vector function determines which core it is being
193 * executed on and jumps to the reset vector contained in its corresponding
194 * runtime vector table.
195 *
196 * The generation and placement of these vector tables is made
197 * automatically when the
198 * {@link ti.sysbios.family.arm.ducati.Core} module is used.
199 *
200 * Although STRONGLY discouraged, this default behavior can be overridden
201 * by explicitly setting the
202 * {@link #resetVectorAddress Hwi.resetVectorAddress} and
203 * {@link #vectorTableAddress Hwi.vectorTableAddress} config parameters.
204 *
205 * @a(Restrictions) 206 * When used within a dual M3/M4 core (Ducati/Benelli) arrangement, care
207 * must be taken when initializing this shared resource.
208 * The "Shared Resources" note provided
209 * in the {@link ti.sysbios.family.arm.ducati ducati} package discusses
210 * the management of the various hardware and software resources
211 * shared by the two M3/M4 cores.
212 * @a 213 *
214 * @p(html) 215 * <h3> Calling Context </h3>
216 * <table border="1" cellpadding="3">
217 * <colgroup span="1"></colgroup> <colgroup span="5" align="center"></colgroup>
218 *
219 * <tr><th> Function </th><th> Hwi </th><th> Swi </th><th> Task </th><th> Main </th><th> Startup </th></tr>
220 * <!-- -->
221 * <tr><td> {@link #clearInterrupt} </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td></tr>
222 * <tr><td> {@link #create} </td><td> N </td><td> N </td><td> Y </td><td> Y </td><td> N </td></tr>
223 * <tr><td> {@link #disable} </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td></tr>
224 * <tr><td> {@link #disableInterrupt} </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td><td> N </td></tr>
225 * <tr><td> {@link #enable} </td><td> Y </td><td> Y </td><td> Y </td><td> N </td><td> N </td></tr>
226 * <tr><td> {@link #enableInterrupt} </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td><td> N </td></tr>
227 * <tr><td> {@link #Params_init} </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td></tr>
228 * <tr><td> {@link #restore} </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td></tr>
229 * <tr><td> {@link #restoreInterrupt} </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td></tr>
230 * <tr><td> {@link #construct} </td><td> N </td><td> N </td><td> Y </td><td> Y </td><td> N </td></tr>
231 * <tr><td> {@link #delete} </td><td> N </td><td> N </td><td> Y </td><td> Y </td><td> N </td></tr>
232 * <tr><td> {@link #destruct} </td><td> N </td><td> N </td><td> Y </td><td> Y </td><td> N </td></tr>
233 * <tr><td> {@link #getHookContext} </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td><td> N </td></tr>
234 * <tr><td> {@link #setFunc} </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td><td> N </td></tr>
235 * <tr><td> {@link #setHookContext} </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td><td> N </td></tr>
236 * <tr><td colspan="6"> Definitions: <br />
237 * <ul>
238 * <li> <b>Hwi</b>: API is callable from a Hwi thread. </li>
239 * <li> <b>Swi</b>: API is callable from a Swi thread. </li>
240 * <li> <b>Task</b>: API is callable from a Task thread. </li>
241 * <li> <b>Main</b>: API is callable during any of these phases: </li>
242 * <ul>
243 * <li> In your module startup after this module is started (e.g. Hwi_Module_startupDone() returns TRUE). </li>
244 * <li> During xdc.runtime.Startup.lastFxns. </li>
245 * <li> During main().</li>
246 * <li> During BIOS.startupFxns.</li>
247 * </ul>
248 * <li> <b>Startup</b>: API is callable during any of these phases:</li>
249 * <ul>
250 * <li> During xdc.runtime.Startup.firstFxns.</li>
251 * <li> In your module startup before this module is started (e.g. Hwi_Module_startupDone() returns FALSE).</li>
252 * </ul>
253 * </ul>
254 * </td></tr>
255 *
256 * </table>
257 * @p 258 */
259
260
261 @Template("./Hwi.xdt") /* generates the vector table and the dispatcher */
262 @ModuleStartup /* generate a call to startup function */
263 @InstanceInitStatic /* allow constructs in static only systems */
264
265 module Hwi inherits ti.sysbios.interfaces.IHwi
266 {
267 // -------- Module Constants --------
268
269 /*!
270 * The Cortex M3/M4 NVIC supports up to 256 interrupts/exceptions.
271 *
272 * The actual number supported is device specific and provided by
273 * the catalog device specification.
274 */
275 config Int NUM_INTERRUPTS;
276
277 /*!
278 * The Cortex M3/M4 NVIC supports up to 256 interrupt priorities.
279 *
280 * The actual number supported is device specific and provided by
281 * the catalog device specification. For all TI SimpleLink devices,
282 * 8 priorities are supported.
283 */
284 config Int NUM_PRIORITIES;
285
286 // -------- Module Types --------
287
288 /*! Hwi vector function type definition. */
289 typedef Void (*VectorFuncPtr)(void);
290
291 /*! Exception hook function type definition. */
292 typedef Void (*ExceptionHookFuncPtr)(ExcContext *);
293
294 /*! NVIC Configuration Control Register (CCR). */
295 struct CCR {
296 Bits8 STKALIGN; /*! Auto stack alignment in exception */
297 Bits8 BFHFNMIGN; /*! All faults ignore BUS Faults */
298 Bits8 DIV_0_TRP; /*! Trap on divide by zero */
299 Bits8 UNALIGN_TRP; /*! Trap on all unaligned accesses */
300 Bits8 USERSETMPEND; /*! Allow user to trigger interrupts */
301 Bits8 NONEBASETHRDENA; /*! Allow entering thread mode anytime */
302 };
303
304 /*! @_nodoc 305 * Nested Vectored Interrupt Controller.
306 */
307 struct NVIC {
308 UInt32 RES_00; /*! 0xE000E000 reserved */
309 UInt32 ICTR; /*! 0xE000E004 Interrupt Control Type */
310 UInt32 RES_08; /*! 0xE000E008 reserved */
311 UInt32 RES_0C; /*! 0xE000E00C reserved */
312 UInt32 STCSR; /*! 0xE000E010 SysTick Control & Status Register */
313 UInt32 STRVR; /*! 0xE000E014 SysTick Reload Value Register */
314 UInt32 STCVR; /*! 0xE000E018 SysTick Current Value Register */
315 UInt32 STCALIB; /*! 0xE000E01C SysTick Calibration Value Register */
316 UInt32 RES_20 [56]; /*! 0xE000E020-0xE000E0FC reserved */
317 UInt32 ISER [8]; /*! 0xE000E100-0xE000E11C Interrupt Set Enable Registers */
318 UInt32 RES_120 [24]; /*! 0xE000E120-0xE000E17C reserved */
319 UInt32 ICER [8]; /*! 0xE000E180-0xE000E19C Interrupt Clear Enable Registers */
320 UInt32 RES_1A0 [24]; /*! 0xE000E1A0-0xE000E1FC reserved */
321 UInt32 ISPR [8]; /*! 0xE000E200-0xE000E21C Interrupt Set Pending Registers */
322 UInt32 RES_220 [24]; /*! 0xE000E220-0xE000E7C reserved */
323 UInt32 ICPR [8]; /*! 0xE000E280-0xE000E29C Interrupt Clear Pending Registers */
324 UInt32 RES_2A0 [24]; /*! 0xE000E2A0-0xE000E2FC reserved */
325 UInt32 IABR [8]; /*! 0xE000E300-0xE000E31C Interrupt Active Bit Registers */
326 UInt32 RES_320 [56]; /*! 0xE000E320-0xE000E3FC reserved */
327 UInt8 IPR [240]; /*! 0xE000E400-0xE000E4EF Interrupt Priority Registers */
328 UInt32 RES_4F0 [516];/*! 0xE000E4F0-0xE000ECFC reserved */
329 UInt32 CPUIDBR; /*! 0xE000ED00 CPUID Base Register */
330 UInt32 ICSR; /*! 0xE000ED04 Interrupt Control State Register */
331 UInt32 VTOR; /*! 0xE000ED08 Vector Table Offset Register */
332 UInt32 AIRCR; /*! 0xE000ED0C Application Interrupt/Reset Control Register */
333 UInt32 SCR; /*! 0xE000ED10 System Control Register */
334 UInt32 CCR; /*! 0xE000ED14 Configuration Control Register */
335 UInt8 SHPR[12]; /*! 0xE000ED18 System Handlers 4-15 Priority Registers */
336 UInt32 SHCSR; /*! 0xE000ED24 System Handler Control & State Register */
337 UInt8 MMFSR; /*! 0xE000ED28 Memory Manage Fault Status Register */
338 UInt8 BFSR; /*! 0xE000ED29 Bus Fault Status Register */
339 UInt16 UFSR; /*! 0xE000ED2A Usage Fault Status Register */
340 UInt32 HFSR; /*! 0xE000ED2C Hard Fault Status Register */
341 UInt32 DFSR; /*! 0xE000ED30 Debug Fault Status Register */
342 UInt32 MMAR; /*! 0xE000ED34 Memory Manager Address Register */
343 UInt32 BFAR; /*! 0xE000ED38 Bus Fault Address Register */
344 UInt32 AFSR; /*! 0xE000ED3C Auxiliary Fault Status Register */
345 UInt32 PFR0; /*! 0xE000ED40 Processor Feature Register */
346 UInt32 PFR1; /*! 0xE000ED44 Processor Feature Register */
347 UInt32 DFR0; /*! 0xE000ED48 Debug Feature Register */
348 UInt32 AFR0; /*! 0xE000ED4C Auxiliary Feature Register */
349 UInt32 MMFR0; /*! 0xE000ED50 Memory Model Fault Register0 */
350 UInt32 MMFR1; /*! 0xE000ED54 Memory Model Fault Register1 */
351 UInt32 MMFR2; /*! 0xE000ED58 Memory Model Fault Register2 */
352 UInt32 MMFR3; /*! 0xE000ED5C Memory Model Fault Register3 */
353 UInt32 ISAR0; /*! 0xE000ED60 ISA Feature Register0 */
354 UInt32 ISAR1; /*! 0xE000ED64 ISA Feature Register1 */
355 UInt32 ISAR2; /*! 0xE000ED68 ISA Feature Register2 */
356 UInt32 ISAR3; /*! 0xE000ED6C ISA Feature Register3 */
357 UInt32 ISAR4; /*! 0xE000ED70 ISA Feature Register4 */
358 UInt32 RES_D74[5]; /*! 0xE000ED74-0xE000ED84 reserved */
359 UInt32 CPACR; /*! 0xE000ED88 Coprocessor Access Control Register */
360 UInt32 RES_D8C[93]; /*! 0xE000ED8C-0xE000EEFC reserved */
361 UInt32 STI; /*! 0xE000EF00 Software Trigger Interrupt Register */
362 UInt32 RES_F04[12]; /*! 0xE000EF04-0xE000EF30 reserved */
363 UInt32 FPCCR; /*! 0xE000EF34 FP Context Control Register */
364 UInt32 FPCAR; /*! 0xE000EF38 FP Context Address Register */
365 UInt32 FPDSCR; /*! 0xE000EF3C FP Default Status Control Register */
366 UInt32 MVFR0; /*! 0xE000EF40 Media & FP Feature Register0 */
367 UInt32 MVFR1; /*! 0xE000EF44 Media & FP Feature Register1 */
368 UInt32 RES_F48[34]; /*! 0xE000EF48-0xE000EFCC reserved */
369 UInt32 PID4; /*! 0xE000EFD0 Peripheral ID Register4 */
370 UInt32 PID5; /*! 0xE000EFD4 Peripheral ID Register5 */
371 UInt32 PID6; /*! 0xE000EFD8 Peripheral ID Register6 */
372 UInt32 PID7; /*! 0xE000EFDC Peripheral ID Register7 */
373 UInt32 PID0; /*! 0xE000EFE0 Peripheral ID Register0 */
374 UInt32 PID1; /*! 0xE000EFE4 Peripheral ID Register1 */
375 UInt32 PID2; /*! 0xE000EFE8 Peripheral ID Register2 */
376 UInt32 PID3; /*! 0xE000EFEC Peripheral ID Register3 */
377 UInt32 CID0; /*! 0xE000EFF0 Component ID Register0 */
378 UInt32 CID1; /*! 0xE000EFF4 Component ID Register1 */
379 UInt32 CID2; /*! 0xE000EFF8 Component ID Register2 */
380 UInt32 CID3; /*! 0xE000EFFC Component ID Register3 */
381 }
382
383 /*!
384 * Physical Nested Vectored Interrupt Controller Device.
385 * Short name is "Hwi_nvic"
386 * Long name is "ti_sysbios_family_arm_m3_Hwi_nvic"
387 */
388 extern volatile NVIC nvic;
389
390 /*!
391 * Virtual Nested Vectored Interrupt Controller structure
392 * written to by both cores for SMP.
393 * Short name is "Hwi_vnvic"
394 * Long name is "ti_sysbios_family_arm_m3_Hwi_vnvic"
395 */
396 extern volatile NVIC vnvic;
397
398 /*!
399 * Exception Context - Register contents at the time of an exception.
400 */
401 struct ExcContext {
402 /* Thread Context */
403 BIOS.ThreadType threadType; /* Type of thread executing at */
404 /* the time the exception occurred */
405 Ptr threadHandle; /* Handle to thread executing at */
406 /* the time the exception occurred */
407 Ptr threadStack; /* Address of stack contents of thread */
408 /* executing at the time the exception */
409 /* occurred */
410 SizeT threadStackSize; /* size of thread stack */
411
412 /* Internal Registers */
413 Ptr r0;
414 Ptr r1;
415 Ptr r2;
416 Ptr r3;
417 Ptr r4;
418 Ptr r5;
419 Ptr r6;
420 Ptr r7;
421 Ptr r8;
422 Ptr r9;
423 Ptr r10;
424 Ptr r11;
425 Ptr r12;
426 Ptr sp;
427 Ptr lr;
428 Ptr pc;
429 Ptr psr;
430
431 /* NVIC registers */
432 Ptr ICSR;
433 Ptr MMFSR;
434 Ptr BFSR;
435 Ptr UFSR;
436 Ptr HFSR;
437 Ptr DFSR;
438 Ptr MMAR;
439 Ptr BFAR;
440 Ptr AFSR;
441 }
442
443 struct Struct2__ {
444 Ptr fxns; /* IHwi fxns - not used */
445 UArg arg;
446 FuncPtr fxn;
447 Irp irp;
448 UInt8 priority;
449 Int16 intNum;
450 Ptr hookEnv;
451 Types.CordAddr name;
452 };
453
454 typedef Struct2__ Struct2;
455
456 /*! @_nodoc */
457 metaonlystruct BasicView {
458 Ptr halHwiHandle;
459 String label;
460 String type;
461 Int intNum;
462 Int priority;
463 Int group;
464 Int subPriority;
465 String fxn;
466 UArg arg;
467 };
468
469 /*! @_nodoc */
470 metaonlystruct DetailedView {
471 Ptr halHwiHandle;
472 String label;
473 String type;
474 Int intNum;
475 Int priority;
476 Int group;
477 Int subPriority;
478 String fxn;
479 UArg arg;
480 Ptr irp;
481 String status;
482 Int coreId;
483 };
484
485 /*! @_nodoc */
486 metaonlystruct ModuleView {
487 String options[4];
488 String processorState;
489 String activeInterrupt;
490 String pendingInterrupt;
491 String exception;
492 String hwiStackPeak;
493 SizeT hwiStackSize;
494 Ptr hwiStackBase;
495 };
496
497 /*! @_nodoc */
498 metaonlystruct VectorTableView {
499 UInt vectorNum;
500 Ptr vector;
501 String vectorLabel;
502 String type;
503 String priority;
504 Int preemptPriority;
505 Int subPriority;
506 String status;
507 String hwiHandle;
508 String hwiFxn;
509 UArg hwiArg;
510 Ptr hwiIrp;
511 };
512
513 /*! @_nodoc */
514 @Facet
515 metaonlyconfig ViewInfo.Instance rovViewInfo =
516 ViewInfo.create({
517 viewMap: [
518 ['Basic',
519 {
520 type: ViewInfo.INSTANCE,
521 viewInitFxn: 'viewInitBasic',
522 structName: 'BasicView'
523 }
524 ],
525 ['Detailed',
526 {
527 type: ViewInfo.INSTANCE,
528 viewInitFxn: 'viewInitDetailed',
529 structName: 'DetailedView'
530 }
531 ],
532 ['Module',
533 {
534 type: ViewInfo.MODULE,
535 viewInitFxn: 'viewInitModule',
536 structName: 'ModuleView'
537 }
538 ],
539 ['Exception',
540 {
541 type: ViewInfo.TREE,
542 viewInitFxn: 'viewInitException',
543 structName: 'ExcContext'
544 }
545 ],
546 ['Vector Table',
547 {
548 type: ViewInfo.MODULE_DATA,
549 viewInitFxn: 'viewInitVectorTable',
550 structName: 'VectorTableView'
551 }
552 ]
553 ]
554 });
555
556 // -------- Module Parameters --------
557
558 // Logs
559
560 /*!
561 * Issued just prior to Hwi function invocation (with interrupts disabled)
562 */
563 config Log.Event LM_begin = {
564 mask: Diags.USER1 | Diags.USER2,
565 msg: "LM_begin: hwi: 0x%x, func: 0x%x, preThread: %d, intNum: %d, irp: 0x%x"
566 };
567
568 /*!
569 * Issued just after return from Hwi function (with interrupts disabled)
570 */
571 config Log.Event LD_end = {
572 mask: Diags.USER2,
573 msg: "LD_end: hwi: 0x%x"
574 };
575
576 // Asserts
577
578 /*! Assert when bad maskSetting parameter provided */
579 config Assert.Id A_unsupportedMaskingOption = {
580 msg: "A_unsupportedMaskingOption: unsupported maskSetting."
581 };
582
583 // Errors
584
585 /*!
586 * Error raised if an attempt is made to create a Hwi
587 * with an interrupt number greater than Hwi_NUM_INTERRUPTS - 1.
588 */
589 config Error.Id E_badIntNum = {
590 msg: "E_badIntNum, intnum: %d is out of range"
591 };
592
593 /*!
594 * Error raised when Hwi is already defined
595 */
596 config Error.Id E_alreadyDefined = {
597 msg: "E_alreadyDefined: Hwi already defined: intr# %d"
598 };
599
600 /*!
601 * Error raised when the number of interrupts being created
602 * exceeds the number supported.
603 */
604 config Error.Id E_hwiLimitExceeded = {
605 msg: "E_hwiLimitExceeded: Too many interrupts defined"
606 };
607
608 /*!
609 * Error raised when an exception occurs
610 */
611 config Error.Id E_exception = {
612 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."
613 };
614
615 /*!
616 * Error raised when an uninitialized interrupt occurs
617 */
618 config Error.Id E_noIsr = {
619 msg: "E_noIsr: id = %d, pc = %08x"
620 };
621
622 /*!
623 * Error raised when NMI exception occurs
624 */
625 config Error.Id E_NMI = {
626 msg: "E_NMI: %s"
627 };
628
629 /*!
630 * Error raised when hard fault exception occurs
631 */
632 config Error.Id E_hardFault = {
633 msg: "E_hardFault: %s"
634 };
635
636 /*!
637 * Error raised when memory fault exception occurs
638 */
639 config Error.Id E_memFault = {
640 msg: "E_memFault: %s, address: %08x"
641 };
642
643 /*!
644 * Error raised when bus fault exception occurs
645 */
646 config Error.Id E_busFault = {
647 msg: "E_busFault: %s, address: %08x"
648 };
649
650 /*!
651 * Error raised when usage fault exception occurs
652 */
653 config Error.Id E_usageFault = {
654 msg: "E_usageFault: %s"
655 };
656
657 /*!
658 * Error raised when svCall exception occurs
659 */
660 config Error.Id E_svCall = {
661 msg: "E_svCall: svNum = %d"
662 };
663
664 /*!
665 * Error raised when debugMon exception occurs
666 */
667 config Error.Id E_debugMon = {
668 msg: "E_debugMon: %s"
669 };
670
671 /*!
672 * Error raised when reserved exception occurs
673 */
674 config Error.Id E_reserved = {
675 msg: "E_reserved: %s %d"
676 };
677
678 // configs
679
680 /*!
681 * Size (in number of interrupts) of the table used by the interrupt
682 * dispatcher to locate the corresponding Hwi object. By default,
683 * Hwi.dispatchTableSize will be internally set
684 * to the number of interrupts supported by the device.
685 *
686 * When the Hwi dispatch table size is equal to the number of interrupts
687 * supported {@link #NUM_INTERRUPTS} by the device, a linear-indexed
688 * dispatch table mechanism is used that will consume 4 bytes of RAM
689 * for each interrupt supported.
690 *
691 * If the dispatch table size is set to a number less than the number
692 * of interrupts supported by the device, then a non linear-indexed
693 * dispatch table mechanism is employed that uses 12 bytes of RAM for
694 * each interrupt supported.
695 *
696 * Consequently, for applications that use less than 1/3 of the total
697 * number of interrupts supported by the device, setting this parameter
698 * to the number of interrupts ACTUALLY USED will result in less RAM
699 * memory being used than otherwise.
700 *
701 * For applications that use very few interrupts, this can be a significant RAM memory savings.</p>
702 */
703 metaonlyconfig UInt dispatchTableSize;
704
705 /*!
706 * Location of the Runtime Interrupt Vector Table.
707 * Default is device dependent.
708 *
709 * This parameter allows the user to override the default placement
710 * of the runtime interrupt vector table.
711 * The NVIC's Vector Table Offset
712 * Register (VTOR) is also programmed to this value.
713 *
714 * Some systems require the runtime vector table to be placed at
715 * an address
716 * other than 0 but still need a copy of the two M3/M4 boot vectors
717 * (SP and reset PC), located there. To achieve this, a separate
718 * parameter {@link #resetVectorAdress} is provided. If the
719 * resetVectorAddress has a different value then the vectorTableAddress
720 * then a separate vector table is generated and placed at that
721 * address.
722 *
723 * The vector table must be placed at an address at or lower than
724 * 0x3FFFFC00 and must be aligned on an even 64 word boundary.
725 */
726 metaonlyconfig Ptr vectorTableAddress = 0x00000000;
727
728 /*!
729 * Reset vector table address. Default is 0x00000000.
730 *
731 * This parameter is the address of the vector table used
732 * at system reset time. Typically this is placed at 0x00000000.
733 *
734 * If the Hwi.resetVectorAddress has a different value than
735 * the {@link #vectorTableAddress Hwi.vectorTableAddress}
736 * then two vector tables are generated, one at the Hwi.resetVectorAddress
737 * and another at the {@link #vectorTableAddress Hwi.vectorTableAddress}.
738 *
739 * After the initial boot code has been executed at startup, the NVIC's
740 * Vector Table Offset Register will be programmed to point to the
741 * vector table at the {@link #vectorTableAddress Hwi.vectorTableAddress}.
742 *
743 * is created and placed in the ".resetVecs" section.
744 */
745 metaonlyconfig Ptr resetVectorAddress = 0x00000000;
746
747 /*! Reset Handler (ID/vector #1). Default is c_int00 */
748 metaonlyconfig VectorFuncPtr resetFunc;
749
750 /*! NMI Handler (ID/vector #2). Default is set to an internal exception handler */
751 metaonlyconfig VectorFuncPtr nmiFunc;
752
753 /*! Hard Fault Handler (ID/vector #3). Default is set to an internal exception handler */
754 metaonlyconfig VectorFuncPtr hardFaultFunc;
755
756 /*! Mem Fault Handler (ID/vector #4). Default is set to an internal exception handler */
757 metaonlyconfig VectorFuncPtr memFaultFunc;
758
759 /*! Bus Fault Handler (ID/vector #5). Default is set to an internal exception handler */
760 metaonlyconfig VectorFuncPtr busFaultFunc;
761
762 /*! Usage Fault Handler (ID/vector #6). Default is set to an internal exception handler */
763 metaonlyconfig VectorFuncPtr usageFaultFunc;
764
765 /*! SVCall Handler (ID/vector #11). Default is set to an internal exception handler */
766 metaonlyconfig VectorFuncPtr svCallFunc;
767
768 /*! Debug Mon Handler (ID/vector #12). Default is set to an internal exception handler */
769 metaonlyconfig VectorFuncPtr debugMonFunc;
770
771 /*! Reserved Exception Handler (ID/vector #13). Default is set to an internal exception handler */
772 metaonlyconfig VectorFuncPtr reservedFunc;
773
774 /*! Uninitialized ISR Handler. Default is set to an internal exception handler */
775 config VectorFuncPtr nullIsrFunc;
776
777 /*! Hwi exception handler function type definition. */
778 typedef Void (*ExcHandlerFuncPtr)(UInt *, UInt);
779
780 /*!
781 * Exception handler function pointer.
782 *
783 * The default is determined by the value of Hwi.enableException.
784 *
785 * If the user does NOT set this parameter, then the following default
786 * behavior is followed:
787 *
788 * If Hwi.enableException is true, then the internal 'Hwi_excHandlerMax'
789 * function is used. This exception handler saves the exception context
790 * then does a complete exception decode and dump to the console, then
791 * raises an Error. The exception context can be viewed within CCS
792 * in the ROV Hwi module's Exception view.
793 *
794 * If Hwi.enableException is false, then the internal 'Hwi_excHandlerMin'
795 * function is used. This exception handler saves the exception context
796 * then raises an Error. The exception context can be viewed within CCS
797 * in the ROV Hwi module's Exception view.
798 *
799 * If the user sets this parameter to their own function, then the user's
800 * function will be invoked with the following arguments:
801 *
802 * Void myExceptionHandler(UInt *excStack, UInt lr);
803 *
804 * Where 'excStack' is the address of the stack containing the
805 * register context at the time of the exception, and 'lr' is the
806 * link register value when the low-level-assembly-coded exception
807 * handler was vectored to.
808 *
809 * If this parameter is set to 'null', then an infinite while loop is
810 * entered when an exception occurs. This setting minimizes code and
811 * data footprint but provides no automatic exception decoding.
812 */
813 config ExcHandlerFuncPtr excHandlerFunc = excHandlerMax;
814
815 /*
816 * SMP Interrupt affinity mappings
817 *
818 * In SMP mode, this array maps an interrupt number to the
819 * coreId it is to be tied to. By default, all ints are mapped to
820 * core 0.
821 *
822 * For example, to make Timer 1 from the
823 * ti.sysbios.family.arm.ducati.Timer
824 * module interrupt on core 1 rather than core 0, add the following to
825 * your config file:
826 *
827 * @p(code)
828 * var m3Hwi = xdc.useModule('ti.sysbios.family.arm.m3.Hwi');
829 * m3Hwi.intAffinity[22] = 1;
830 * @p
831 *
832 * @a(constraints)
833 * Valid core Ids are 0 and 1 for Ducati/Benelli SMP applications.
834 *
835 * Interrupt numbers below 16 are ignored.
836 * Only interrupt numbers greater than or equal to #16 can be routed to
837 * either Ducati/Benelli core.
838 *
839 * Interrupt #19, the Ducati inter-core interrupt, is reserved for
840 * exclusive use within the SMP kernel.
841 */
842 metaonlyconfig UInt8 intAffinity[];
843
844 /*!
845 * Enable full exception decoding
846 *
847 * When this is enabled, the exception handler will fully
848 * decode an exception and dump the registers to the
849 * system console.
850 */
851 metaonlyconfig Bool enableException = true;
852
853 /*!
854 * User Exception Context Buffer Address
855 *
856 * By default, when an exception occurs, an {@link #ExcContext}
857 * structure is allocated on the ISR stack and filled in within the
858 * exception handler.
859 *
860 * If {@link #excContextBuffer} is initialized by the user, the
861 * {@link #ExcContext} structure will be placed at that address instead.
862 *
863 * The buffer must be large enough to contain an {@link #ExcContext}
864 * structure.
865 */
866 metaonlyconfig Ptr excContextBuffer;
867 metaonlyconfig Ptr excContextBuffers[];
868
869 /*!
870 * User Exception Stack Buffer Address
871 *
872 * By default, when an exception occurs, a pointer to the base address
873 * of the stack being used by the thread causing the exception is placed
874 *
875 * If {@link #excStackBuffer} is initialized by the user, the
876 * stack contents of the thread causing the exception will be
877 * copied to that address instead.
878 *
879 * The buffer must be large enough to contain the largest task stack
880 * or ISR stack defined in the application.
881 */
882 metaonlyconfig Ptr excStackBuffer;
883 metaonlyconfig Ptr excStackBuffers[];
884
885
886 /*!
887 * User Exception hook function.
888 *
889 * Called just after the exception context has been initialized.
890 *
891 * This function will be run on the ISR stack.
892 *
893 * This function must run to completion.
894 *
895 * It is called without any Task or Swi scheduling protection
896 * and therefore can not call any functions that may cause a Swi or Task
897 * scheduling operation (Swi_post(), Semaphore_post(), Event_post(), etc).
898 */
899 config ExceptionHookFuncPtr excHookFunc = null;
900 config ExceptionHookFuncPtr excHookFuncs[];
901
902 /*!
903 * NVIC CCR register settings
904 *
905 * These setting are written to Hwi_nvic.CCR at startup time.
906 *
907 * See the {@link http://infocenter.arm.com/help/topic/com.arm.doc.dui0553a/Bhcjabhi.html Configuration and Control Register}
908 * description provided by ARM for more details
909 * on the meanings of these parameters.
910 */
911 metaonlyconfig CCR nvicCCR = {
912 STKALIGN: 1,
913 BFHFNMIGN: 0,
914 DIV_0_TRP: 0,
915 UNALIGN_TRP: 0,
916 USERSETMPEND: 0,
917 NONEBASETHRDENA: 0
918 };
919
920 /*!
921 * The priority that BASEPRI is set to by Hwi_disable().
922 *
923 * All interrupts configured with equal or less priority (equal or
924 * higher number) than disablePriority are disabled by
925 * {@link #disable Hwi_disable}.
926 * Interrupts configured with higher priority (smaller number) than
927 * Hwi.disablePriority are non-maskable (ie zero-latency).
928 *
929 * The default setting is the second highest interrupt priority
930 * defined for the device (typically '0x20' for devices
931 * which support 8 priority values).
932 * This results in priority 0 (and all
933 * other values in the same priority group, ie 0x00 thru 0x1f)
934 * being the zero-latency, non-maskable interrupt priority.
935 * All other priorities are disabled with Hwi_disable().
936 */
937 config UInt disablePriority;
938
939 /*!
940 * The PRIGROUP setting. Default is 0.
941 *
942 * This value will be written to the PRIGROUP field
943 * within the NVIC's Application Interrupt and Reset Control
944 * Register (Hwi_nvic.AIRCR). It defines how the 8 bit priority
945 * values are interpreted by the hardware.
946 *
947 * Valid settings are 0-7.
948 *
949 * The default setting of 0 causes bits 7-1 of an interrupt's
950 * priority value to be used as pre-emption priority, while bit 0
951 * is used to determine which of two simultaneous interrupts with
952 * the same pre-emption priority will be serviced first.
953 *
954 * For most TI MCU devices, this means that each of the 8 supported
955 * priority values are unique pre-emption priorities and are not
956 * subdivided into priority groups.
957 *
958 * For more details regarding priority groups see the
959 * {@link http://infocenter.arm.com/help/topic/com.arm.doc.dui0553a/Cihehdge.html AIRCR}
960 * register description provided by ARM.
961 */
962 config UInt priGroup = 0;
963
964 // -------- Module Functions --------
965
966 /*!
967 * ======== construct2 ========
968 * Construct a Hwi object
969 *
970 * Hwi_construct2 constructs a Hwi object. This function is identical
971 * to Hwi_construct(), but does not take an Error_Block parameter, and
972 * returns a Hwi_Handle.
973 *
974 * The following C code sets Hwi parameters and
975 * constructs a Hwi object:
976 *
977 * @p(code) 978 *
979 * Hwi_Struct2 hwiStruct2;
980 * Hwi_Handle hwi;
981 *
982 * Void main()
983 * {
984 * Hwi_Params hwiParams;
985 *
986 * Hwi_Params_init(&hwiParams);
987 * hwiParams.arg = (UArg)arg;
988 * hwiParams.priority = intPriority;
989 *
990 * hwi = Hwi_construct2(&hwiStruct2, intNum, hwiFxn, &hwiParams);
991 * if (hwi == NULL) {
992 * // Failure
993 * }
994 *
995 * BIOS_start();
996 * }
997 * @p 998 *
999 * @param(hwi) Pointer to Hwi_Struct2 object.
1000 * @param(intNum) Interrupt priority
1001 * @param(hwiFxn) Hwi Function
1002 * @param(prms) Pointer to Hwi_Params structure
1003 *
1004 * @b(returns) A Hwi handle
1005 */
1006 Handle construct2(Struct2 *hwi, Int intNum, FuncPtr hwiFxn,
1007 const Params *prms);
1008
1009 /*!
1010 * ======== disable ========
1011 * Disable all non zero-latency interrupts
1012 *
1013 * Hwi_disable disables all non zero-latency hardware interrupts and
1014 * returns an
1015 * opaque key indicating whether interrupts were globally enabled or
1016 * disabled on entry to Hwi_disable().
1017 * The actual value of the key is target/device specific and is meant
1018 * to be passed to Hwi_restore().
1019 *
1020 * Call Hwi_disable before a portion of a function that needs
1021 * to run without interruption. When critical processing is complete, call
1022 * Hwi_restore or Hwi_enable to reenable hardware interrupts.
1023 *
1024 * Servicing of interrupts that occur while interrupts are disabled is
1025 * postponed until interrupts are reenabled. However, if the same type
1026 * of interrupt occurs several times while interrupts are disabled,
1027 * the interrupt's function is executed only once when interrupts are
1028 * reenabled.
1029 *
1030 * A context switch can occur when calling Hwi_enable or Hwi_restore if
1031 * an enabled interrupt occurred while interrupts are disabled.
1032 *
1033 * Hwi_disable may be called from main(). However, since Hwi interrupts
1034 * are already disabled in main(), such a call has no effect.
1035 *
1036 * @a(Implementation Note) 1037 * In order to support zero latency interrupts, rather
1038 * than setting PRIMASK (which would globally disable all NVIC
1039 * interrupts), Hwi_disable() instead writes the value of
1040 * {@link #disablePriority Hwi.disablePriority}
1041 * to the BASEPRI register. In doing so, all interrupts of equal or
1042 * lower priority than Hwi.disablePriority are disabled.
1043 *
1044 * @a(constraints) 1045 * If a Task switching API such as
1046 * {@link ti.sysbios.knl.Semaphore#pend Semaphore_pend()},
1047 * {@link ti.sysbios.knl.Semaphore#post Semaphore_post()},
1048 * {@link ti.sysbios.knl.Task#sleep Task_sleep()}, or
1049 * {@link ti.sysbios.knl.Task#yield Task_yield()}
1050 * is invoked which results in a context switch while
1051 * interrupts are disabled, an embedded call to
1052 * {@link #enable Hwi_enable} occurs
1053 * on the way to the new thread context which unconditionally re-enables
1054 * interrupts. Interrupts will remain enabled until a subsequent
1055 * {@link #disable Hwi_disable}
1056 * invocation.
1057 *
1058 * Swis always run with interrupts enabled.
1059 * See {@link ti.sysbios.knl.Swi#post Swi_post()} for a discussion Swis and
1060 * interrupts.
1061 *
1062 * @b(returns) opaque key for use by Hwi_restore()
1063 */
1064 @Macro
1065 override UInt disable();
1066
1067 /*!
1068 * ======== enable ========
1069 */
1070 @Macro
1071 override UInt enable();
1072
1073 /*!
1074 * ======== restore ========
1075 */
1076 @Macro
1077 override Void restore(UInt key);
1078
1079 /*!
1080 * @_nodoc 1081 * ======== disableFxn ========
1082 * function call implementation
1083 */
1084 UInt disableFxn();
1085
1086 /*!
1087 * @_nodoc 1088 * ======== enableFxn ========
1089 * function call implementation
1090 */
1091 UInt enableFxn();
1092
1093 /*!
1094 * @_nodoc 1095 * ======== restoreFxn ========
1096 * function call implementation
1097 */
1098 Void restoreFxn(UInt key);
1099
1100 /*!
1101 * ======== inUseMeta ========
1102 * @_nodoc 1103 * Check for Hwi already in use.
1104 * For internal SYS/BIOS use only.
1105 * Should be called prior to any internal Hwi.create().
1106 *
1107 * @param(intNum) interrupt number
1108 */
1109 metaonly Bool inUseMeta(UInt intNum);
1110
1111 /*!
1112 * ======== plug ========
1113 * Plug a non dispatched interrupt vector with an ISR address.
1114 *
1115 * Used internally by Hwi_create() and Hwi_construct().
1116 *
1117 * This API is provided for external use primarily to allow users
1118 * to plug the NMI vector (interrupt #2) at runtime.
1119 *
1120 * @a(Note) 1121 * Interrupt vectors plugged using Hwi_plug() are NOT managed by
1122 * the Hwi interrupt dispatcher. Consequently, it is not safe to
1123 * call SYS/BIOS APIs from within these ISRs.
1124 *
1125 * @param(intNum) interrupt number
1126 * @param(fxn) pointer to ISR function
1127 */
1128 Void plug(UInt intNum, Void *fxn);
1129
1130 /*!
1131 * ======== getHandle ========
1132 * Returns Hwi_handle associated with intNum
1133 *
1134 * @param(intNum) interrupt number
1135 */
1136 Handle getHandle(UInt intNum);
1137
1138 /*!
1139 * ======== setPriority ========
1140 * Set an interrupt's relative priority.
1141 *
1142 * Valid priorities are 0 - 255. 0 is highest priority.
1143 *
1144 * @a(WARNING) 1145 * Setting the priority of a dispatched Hwi to a value higher
1146 * than {@link #disablePriority Hwi.disablePriority} will make
1147 * it become non-maskable by {@link #disable Hwi_disable()}.
1148 * The behavior of your application after that will be
1149 * unpredictable and will likely yield catastrophic results!
1150 *
1151 * @param(intNum) ID of interrupt
1152 * @param(priority) priority
1153 */
1154 Void setPriority(UInt intNum, UInt priority);
1155
1156 /*!
1157 * ======== excSetBuffers ========
1158 * Set the exception context and stack buffer pointers
1159 *
1160 * @param(excContextBuffer) Address to place ExcContext
1161 * @param(excStackBuffer) Address to place ExcStack
1162 */
1163 Void excSetBuffers(Ptr excContextBuffer, Ptr excStackBuffer);
1164
1165 /*!
1166 * @_nodoc 1167 * ======== initNVIC ========
1168 * initialize everything but leave ints disabled
1169 */
1170 Void initNVIC();
1171
1172 /*!
1173 * @_nodoc 1174 * ======== initStacks ========
1175 * set up M3 split stacks
1176 */
1177 Void initStacks(Ptr hwiStack);
1178
1179 /*!
1180 * @_nodoc 1181 * ======== flushVnvic ========
1182 * Reconfigure a dispatched interrupt.
1183 *
1184 * Called by the internal function "Hwi_updateNvic()".
1185 *
1186 * This is a public API because it is also called by "Core_hwiFunc()".
1187 */
1188 Void flushVnvic();
1189
1190 /*!
1191 * @_nodoc 1192 * ======== testStaticInlines ========
1193 * test function that calls static inline function for code coverage
1194 */
1195 Void testStaticInlines();
1196
1197 instance:
1198
1199 /*!
1200 * Interrupt priority.
1201 * The default is 255 which is the lowest priority.
1202 *
1203 * Priority 0 is the highest priority and by default is
1204 * reserved for zero latency interrupts
1205 * (see {@link #disablePriority}).
1206 *
1207 * Valid priorities values are device dependent and their
1208 * nesting behaviors depend on the {@link #priGroup} setting.
1209 *
1210 * See the Cortex M3 architecture reference manual for details
1211 * on the meanings of these parameters.
1212 */
1213 overrideconfig Int priority = 255;
1214
1215 /*!
1216 * Interrupt Masking Option. Only MaskingOption_LOWER is supported.
1217 *
1218 * The NVIC interrupt controller is designed for priority based
1219 * interrupts. No support is provided for anything but
1220 * Hwi.MaskingOption_LOWER.
1221 */
1222 overrideconfig IHwi.MaskingOption maskSetting = IHwi.MaskingOption_LOWER;
1223
1224 /*!
1225 * Use the interrupt dispatcher with this interrupt. Default is true.
1226 *
1227 * If set to false, the interrupt dispatcher is NOT used. Instead,
1228 * the configured Hwi function address is placed directly in the
1229 * vector table, which results in the dispatcher being bypassed.
1230 *
1231 * @a(Warning) 1232 * Interrupts configured to bupass the dispatcher are not allowed
1233 * to call ANY SYS/BIOS APIs that effect thread scheduling. Examples
1234 * of API that should no be invoked are:
1235 *
1236 * @p(dlist) 1237 * - Swi_post(),
1238 * - Semaphore_post(),
1239 * - Event_post(),
1240 * - Task_yield()
1241 * @p 1242 *
1243 * Additionally, although the signature for a non-dispatched interrupt
1244 * function is the same as that for a dispatched interrupt
1245 * (see {@link #FuncPtr}), no argument is actually passed
1246 * to the non-dispatched ISR handler.
1247 */
1248 config Bool useDispatcher = true;
1249
1250 /*!
1251 * ======== reconfig ========
1252 * Reconfigure a dispatched interrupt.
1253 */
1254 Void reconfig(FuncPtr fxn, const Params *params);
1255
1256 internal: /* not for client use */
1257
1258 /*!
1259 * If Hwi.dispatchTableSize is initialized by the user then
1260 * Hwi.numSparseInterrupts is set to the value of Hwi.dispatchTableSize
1261 *
1262 * If Hwi.dispatchTableSize is NOT set by the user, the normal
1263 * intNum-indexed Hwi dispatchTable mechanism is used by
1264 * the dispatcher to find the corresponding Hwi object.
1265 *
1266 * If Hwi.dispatchTableSize is set by the user, then a
1267 * RAM-based fixed sized interrupt jump table is generated
1268 * that contains a repeating pattern of the following 3 word
1269 * assembly code snippets:
1270 *
1271 * hwiX: ldr r3, hwiObjectX
1272 * ldr pc, ti_sysbios_family_arm_m3_Hwi_dispatch__I
1273 * hwiObjectX: .word 0
1274 * hwiY: ldr r3, hwiObjectY
1275 * ldr pc, ti_sysbios_family_arm_m3_Hwi_dispatch__I
1276 * hwiObjectY: .word 0
1277 * ...
1278 *
1279 * Each dispatched interrupt vector is then initialized to point
1280 * to one of these tuples, and the address of the corresponding Hwi
1281 * object is written into the hwiObjectX field.
1282 *
1283 * The low level assembly code in Hwi_dispatch__I preserves the
1284 * value of r3 when it calls Hwi_dispatchC(), which results in
1285 * the Hwi object being passed as the arg3.
1286 *
1287 * Depending on the boolean value of Hwi_numSparseInterrupts, the
1288 * dispatcher either uses the value passed in arg3 as the
1289 * Hwi object, or uses intNum to index into the standard
1290 * dispatchTable to fetch the Hwi object.
1291 */
1292 config UInt numSparseInterrupts = 0;
1293
1294 /*
1295 * Boolean to indicate whether the current target is being
1296 * built using tiva platform.
1297 */
1298 metaonlyconfig Bool isTiva = false;
1299
1300 /*
1301 * The omap4430 ES1 devices have a nasty bug in the unicache
1302 * that locks the bus up when an interrupt occurs at a specific
1303 * time during an internal cache operation.
1304 * The flag below, when set to true, activates special
1305 * code in the Hwi module to work around this bug.
1306 * "WA1_1" comes from "WorkAround 1.1" from a list of potential
1307 * solutions to the problem developed by the design team.
1308 */
1309 metaonlyconfig Bool enableWA1_1 = false;
1310
1311 /*
1312 * Swi and Task module function pointers.
1313 * Used to decouple Hwi from Swi and Task when
1314 * dispatcherSwiSupport or
1315 * dispatcherTaskSupport is false.
1316 */
1317 config UInt (*swiDisable)();
1318 config Void (*swiRestore)(UInt);
1319 config Void (*swiRestoreHwi)(UInt);
1320 config UInt (*taskDisable)();
1321 config Void (*taskRestoreHwi)(UInt);
1322
1323 /* initial Hwi_nvic.CCR value */
1324 config UInt32 ccr;
1325
1326 /*!
1327 * const array to hold all HookSet objects.
1328 */
1329 config HookSet hooks[length] = [];
1330
1331 /*
1332 * ======== postInit ========
1333 * finish initializing static and dynamic Hwis
1334 */
1335 Int postInit(Object *hwi, Error.Block *eb);
1336
1337 /*!
1338 * ======== updateNvic ========
1339 * Internal SMP function to cause the virtual NVIC to be flushed to the
1340 * actual NVIC.
1341 *
1342 * This function is called by the various user APIs that manipulate
1343 * individual NVIC register bits
1344 * (ie Hwi_enable/disable/restore/clearInterrupt())
1345 *
1346 * If the current core is the owner of "intNum", flushVnvic() is called
1347 * immediately.
1348 *
1349 * Otherwise an intercore interrupt is generated to force the other core
1350 * to perform the flushVnvic().
1351 *
1352 */
1353 Void updateNvic(UInt intNum);
1354
1355 /*!
1356 * ======== excHandlerAsm ========
1357 * asm code exception handler
1358 */
1359 Void excHandlerAsm();
1360
1361 /*!
1362 * ======== excHandler ========
1363 * exception Handler routes to
1364 * either min, max, or spin exception handler
1365 */
1366 Void excHandler(UInt *excStack, UInt lr);
1367
1368 /*!
1369 * ======== excHandlerMin ========
1370 * Minimal Exception Handler
1371 */
1372 Void excHandlerMin(UInt *excStack, UInt lr);
1373
1374 /*!
1375 * ======== excHandlerMax ========
1376 * Full Featured Exception Handler
1377 */
1378 Void excHandlerMax(UInt *excStack, UInt lr);
1379
1380 /*!
1381 * ======== excFillContext ========
1382 */
1383 Void excFillContext(UInt *excStack);
1384
1385 /*!
1386 * ======== excNmi ========
1387 */
1388 Void excNmi(UInt *excStack);
1389
1390 /*!
1391 * ======== excHardFault ========
1392 */
1393 Void excHardFault(UInt *excStack);
1394
1395 /*!
1396 * ======== excMemFault ========
1397 */
1398 Void excMemFault(UInt *excStack);
1399
1400 /*!
1401 * ======== excBusFault ========
1402 */
1403 Void excBusFault(UInt *excStack);
1404
1405 /*!
1406 * ======== excUsageFault ========
1407 */
1408 Void excUsageFault(UInt *excStack);
1409
1410 /*!
1411 * ======== excSvCall ========
1412 */
1413 Void excSvCall(UInt *excStack);
1414
1415 /*!
1416 * ======== excDebugMon ========
1417 */
1418 Void excDebugMon(UInt *excStack);
1419
1420 /*!
1421 * ======== excReserved ========
1422 */
1423 Void excReserved(UInt *excStack, UInt excNum);
1424
1425 /*!
1426 * ======== excNoIsr ========
1427 */
1428 Void excNoIsr(UInt *excStack, UInt excNum);
1429
1430 /*!
1431 * ======== excDumpRegs ========
1432 */
1433 Void excDumpRegs(UInt lr);
1434
1435 /*!
1436 * ======== pendSV ========
1437 * Used by dispatcher
1438 */
1439 Void pendSV();
1440
1441 /*
1442 * ======== setStackLimit ========
1443 */
1444 Void setStackLimit(Ptr stackBase);
1445
1446 /*
1447 * ======== swiDisableNull ========
1448 * Empty Hwi_swiDisable()
1449 */
1450 UInt swiDisableNull();
1451
1452 /*
1453 * ======== swiRestoreNull ========
1454 * Empty Hwi_swiRestore()
1455 */
1456 Void swiRestoreNull(UInt key);
1457
1458 /*! Hwi vector function type definition. */
1459 typedef Void (*HandlerFuncPtr)(Handle, UInt);
1460
1461 /* Low Level Interrupt Dispatcher Wrapper */
1462 Void dispatch();
1463
1464 /*
1465 * ======== romInitNVIC ========
1466 * Fix for SDOCM00114681: broken Hwi_initNVIC() function.
1467 * Installed rather than Hwi.initNVIC for ROM app build
1468 * when Hwi.resetVectorAddress is not 0x00000000.
1469 */
1470 Void romInitNVIC();
1471
1472 /*
1473 * "Top Half" of Interrupt Dispatcher
1474 * Does not include Swi_restore() and Task_restore()
1475 */
1476 UInt dispatchC(Irp irp, UInt32 dummy1, UInt32 dummy2, Object *hwi);
1477
1478 /* "Bottom half", run swi scheduler */
1479 Void doSwiRestore(UInt tskKey);
1480
1481 /* "Bottom half", run task scheduler */
1482 Void doTaskRestore(UInt tskKey);
1483
1484 /*! Meta World Only Hwi Configuration Object. */
1485 metaonlystruct InterruptObj {
1486 String name; /* symbol used for vector table entry */
1487 Bool used; /* Interrupt already defined? */
1488 Bool useDispatcher; /* Should dispatcher handle this Int? */
1489 UInt priority; /* priority */
1490 FuncPtr fxn; /* Dispatched ISR function */
1491 Handle hwi; /* Hwi object address */
1492 };
1493
1494 /*!
1495 * Meta-only array of interrupt objects.
1496 * This meta-only array of Hwi config objects is initialized
1497 * in Hwi.xs:module$meta$init().
1498 */
1499 metaonlyconfig InterruptObj interrupt[];
1500
1501 struct Instance_State {
1502 UArg arg; // Argument to Hwi function.
1503 FuncPtr fxn; // Hwi function.
1504 Irp irp; // current IRP/enabled flag
1505 // for static Hwis
1506 UInt8 priority; // Interrupt priorty
1507 Int16 intNum; // Interrupt number. 16 bits used to
1508 // encode non-dispatched interrupt
1509 // as negative intNum
1510 Ptr hookEnv[];
1511 };
1512
1513 struct Module_State {
1514 Char *taskSP; // Temporary storage of interrupted
1515 // Task's SP during ISR execution
1516 Bool excActive[]; // TRUE if an exception has occurred
1517 ExcContext *excContext[]; // Exception context
1518 Ptr excStack[]; // Exception thread stack
1519 Ptr isrStack; // Points to isrStack address
1520 Ptr isrStackBase; // = __TI_STACK_BASE
1521 Ptr isrStackSize; // = Program.stack
1522 Ptr vectorTableBase; // Points to base of vector table
1523 UInt swiTaskKeys; // dispatcher Swi and Task key storage
1524 Ptr dispatchTable; // Ptr to dispatchTable or sparseInterruptTable
1525 volatile Bool vnvicFlushRequired; // if TRUE, Hwi_vnvicFlush will copy
1526 // changed vnvic regs to nvic
1527 UInt8 intAffinity[]; // smp int-to-coreId mappings
1528 UInt32 intAffinityMasks[][]; // smp per-core NVIC register masks
1529 };
1530 }