1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
32 33 34 35
36
37 package ti.sysbios.family.c28;
38
39 import xdc.rov.ViewInfo;
40
41 import xdc.runtime.Diags;
42 import xdc.runtime.Log;
43 import xdc.runtime.Assert;
44 import xdc.runtime.Error;
45
46 /*!
47 * ======== Hwi ========
48 * C28x Hardware Interrupt Manager
49 *
50 * This Hwi module provides C28 family-specific implementations of the
51 * APIs defined in {@link ti.sysbios.interfaces.IHwi IHwi}.
52 *
53 * Additional C28 device-specific APIs are also provided.
54 *
55 * ISRs specified with Hwi_plug will not go through the dispatcher; the
56 * ISR function will be directly plugged into the vector table. Hwi_plug can
57 * be used for any ISR which does not call any SYS/BIOS APIs.
58 *
59 * ISRs can be plugged or created statically in the configuration script or
60 * dynamically at runtime.
61 *
62 * @p(html)
63 * <h3> PIE interrupts </h3>
64 * The peripheral interrupt expansion (PIE) block multiplexes 96 interrupts
65 * into 12 CPU interrupts. The PIE vector table includes entries for each of
66 * these 96 interrupts. The relationship between the numbers corresponding
67 * to PIE interrupts and their groups (CPU interrupt) is as follows:
68 * PIEGROUPNUM = [(PIENUM - 32) / 8] + 1
69 *
70 * <h4>PIE MUXed Peripheral Interrupt Vector Table</h4>
71 * The table below shows a mapping between the PIENUM (interrupt id) and the
72 * various PIE groups. INTX.Y represents the interrupt number for the PIE
73 * interrupt belonging to group X and group-specific id Y.
74 * <br><br>
75 * <table border="1" cellpadding="3">
76 * <tr><th> </th><th>INTX.1</th><th>INTX.2</th><th>INTX.3</th><th>INTX.4</th><th>INTX.5</th><th>INTX.6</th><th>INTX.7</th><th>INTX.8</th></tr>
77 * <tr><th>INT1.Y</th><td>32</td><td>33</td><td>34</td><td>35</td><td>36</td><td>37</td><td>38</td><td>39</td></tr>
78 * <tr><th>INT2.Y</th><td>40</td><td>41</td><td>42</td><td>43</td><td>44</td><td>45</td><td>46</td><td>47</td></tr>
79 * <tr><th>INT3.Y</th><td>48</td><td>49</td><td>50</td><td>51</td><td>52</td><td>53</td><td>54</td><td>55</td></tr>
80 * <tr><th>INT4.Y</th><td>56</td><td>57</td><td>58</td><td>59</td><td>60</td><td>61</td><td>62</td><td>63</td></tr>
81 * <tr><th>INT5.Y</th><td>64</td><td>65</td><td>66</td><td>67</td><td>68</td><td>69</td><td>70</td><td>71</td></tr>
82 * <tr><th>INT6.Y</th><td>72</td><td>73</td><td>74</td><td>75</td><td>76</td><td>77</td><td>78</td><td>79</td></tr>
83 * <tr><th>INT7.Y</th><td>80</td><td>81</td><td>82</td><td>83</td><td>84</td><td>85</td><td>86</td><td>87</td></tr>
84 * <tr><th>INT8.Y</th><td>88</td><td>89</td><td>90</td><td>91</td><td>92</td><td>93</td><td>94</td><td>95</td></tr>
85 * <tr><th>INT9.Y</th><td>96</td><td>97</td><td>98</td><td>99</td><td>100</td><td>101</td><td>102</td><td>103</td></tr>
86 * <tr><th>INT10.Y</th><td>104</td><td>105</td><td>106</td><td>107</td><td>108</td><td>109</td><td>110</td><td>111</td></tr>
87 * <tr><th>INT11.Y</th><td>112</td><td>113</td><td>114</td><td>115</td><td>116</td><td>117</td><td>118</td><td>119</td></tr>
88 * <tr><th>INT12.Y</th><td>120</td><td>121</td><td>122</td><td>123</td><td>124</td><td>125</td><td>126</td><td>127</td></tr>
89 * </table>
90 * <br>
91 *
92 * PIE interrupts must clear the CPU acknowledge bit for their respective PIE
93 * block before further interrupts from that block can occur. The SYS/BIOS 6
94 * dispatcher (used by interrupts created using {@link #create}) takes care of
95 * this, however this differs from DSP/BIOS 5, in which the application is
96 * expected to acknowledge the interrupt.
97 *
98 * PIE interrupt ISRs plugged with {@link #plug}(which do not use the
99 * dispatcher), as well as legacy created PIE HWI instances, must
100 * acknowledge the interrupt manually before returning from the ISR.
101 *
102 * The Hwi module supports zero latency operation. CPU interrupts classified
103 * as zero latency are not disabled by the {@link #disable} call and are
104 * generally left enabled except when explicitly disabled using
105 * {@link #disableIER} or {@link #disablePIEIER}. Refer to
106 * {@link #zeroLatencyIERMask} for using information.
107 *
108 * The following configuration code can be used to plug the function
109 * 'myHwi' into the vector table for PIE group 5, interrupt 1. Using the above
110 * table, one can see that this corresponds to interrupt ID 64:
111 *
112 * @p(code)
113 * Program.global.hwi5 = Hwi.create(64, '&myHwi');
114 * @p
115 *
116 * @a(NOTE)
117 * In this Hwi module implementation, the instance config parameter value
118 * {@link #MaskingOption_LOWER} is equivalent to {@link #MaskingOption_SELF}.
119 * Statically configuring a Hwi object's {@link #Params.maskSetting} to
120 * {@link #MaskingOption_LOWER} will result in the generation of a benign
121 * build warning. Dynamic usages of {@link #MaskingOption_LOWER} will be
122 * silently converted to {@link #MaskingOption_SELF}.
123 *
124 * @p(html)
125 * <h3> Calling Context </h3>
126 * <table border="1" cellpadding="3">
127 * <colgroup span="1"></colgroup> <colgroup span="5" align="center"></colgroup>
128 *
129 * <tr><th> Function </th><th> Hwi </th><th> Swi </th><th> Task </th><th> Main </th><th> Startup </th></tr>
130 * <!-- -->
131 * <tr><td> {@link #clearInterrupt} </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td><td> N </td></tr>
132 * <tr><td> {@link #disable} </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td></tr>
133 * <tr><td> {@link #disableIER} </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td></tr>
134 * <tr><td> {@link #disableInterrupt} </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td><td> N </td></tr>
135 * <tr><td> {@link #disablePIEIER} </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td><td> N </td></tr>
136 * <tr><td> {@link #enable} </td><td> Y </td><td> Y </td><td> Y </td><td> N </td><td> N </td></tr>
137 * <tr><td> {@link #enableIER} </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td></tr>
138 * <tr><td> {@link #enableInterrupt} </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td><td> N </td></tr>
139 * <tr><td> {@link #enablePIEIER} </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td><td> N </td></tr>
140 * <tr><td> {@link #getHandle} </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td><td> N </td></tr>
141 * <tr><td> {@link #getIFR} </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td></tr>
142 * <tr><td> {@link #getIntrReturnAddr} </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td></tr>
143 * <tr><td> {@link #Params_init} </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td><td> N </td></tr>
144 * <tr><td> {@link #pieEnabled} </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td></tr>
145 * <tr><td> {@link #plug} </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td></tr>
146 * <tr><td> {@link #restore} </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td></tr>
147 * <tr><td> {@link #restoreIER} </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td></tr>
148 * <tr><td> {@link #restoreInterrupt} </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td></tr>
149 * <tr><td> {@link #ack} </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td></tr>
150 * <tr><td> {@link #create} </td><td> N </td><td> N </td><td> Y </td><td> Y </td><td> N </td></tr>
151 * <tr><td> {@link #construct} </td><td> N </td><td> N </td><td> Y </td><td> Y </td><td> N </td></tr>
152 * <tr><td> {@link #delete} </td><td> N </td><td> N </td><td> Y </td><td> Y </td><td> N </td></tr>
153 * <tr><td> {@link #destruct} </td><td> N </td><td> N </td><td> Y </td><td> Y </td><td> N </td></tr>
154 * <tr><td> {@link #getHookContext} </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td><td> N </td></tr>
155 * <tr><td> {@link #reconfig} </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td><td> N </td></tr>
156 * <tr><td> {@link #setFunc} </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td><td> N </td></tr>
157 * <tr><td> {@link #setHookContext} </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td><td> N </td></tr>
158 * <tr><td colspan="6"> Definitions: <br />
159 * <ul>
160 * <li> <b>Hwi</b>: API is callable from a Hwi thread. </li>
161 * <li> <b>Swi</b>: API is callable from a Swi thread. </li>
162 * <li> <b>Task</b>: API is callable from a Task thread. </li>
163 * <li> <b>Main</b>: API is callable during any of these phases: </li>
164 * <ul>
165 * <li> In your module startup after this module is started (e.g.
166 Hwi_Module_startupDone() returns TRUE). </li>
167 * <li> During xdc.runtime.Startup.lastFxns. </li>
168 * <li> During main().</li>
169 * <li> During BIOS.startupFxns.</li>
170 * </ul>
171 * <li> <b>Startup</b>: API is callable during any of these phases:</li>
172 * <ul>
173 * <li> During xdc.runtime.Startup.firstFxns.</li>
174 * <li> In your module startup before this module is started
175 (e.g. Hwi_Module_startupDone() returns FALSE).</li>
176 * </ul>
177 * </ul>
178 * </td></tr>
179 *
180 *
181 * </table>
182 * @p
183 *
184 */
185
186 @Template("./Hwi.xdt")
187 @ModuleStartup
188
189 module Hwi inherits ti.sysbios.interfaces.IHwi
190 {
191
192
193
194 /*! C28 supports 32 interrupts. */
195 const Int NUM_INTERRUPTS = 32;
196 /*! C28 supports 96 PIE interrupts */
197 const Int NUM_INTERRUPTS_PIE = 96;
198 const Int NUM_INTERRUPTS_ALL = NUM_INTERRUPTS + NUM_INTERRUPTS_PIE;
199
200
201
202 /*! Hwi plug function type definition, which doesn't take an arg. */
203 typedef Void (*PlugFuncPtr)(void);
204
205 /*! @_nodoc */
206 metaonly struct BasicView {
207 Ptr halHwiHandle;
208 String label;
209 Int intNum;
210 String fxn;
211 UArg arg;
212 Ptr irp;
213 String disableMask;
214 String restoreMask;
215 };
216
217 /*! @_nodoc */
218 metaonly struct ModuleView {
219 String options[4];
220 SizeT hwiStackPeak;
221 SizeT hwiStackSize;
222 Ptr hwiStackBase;
223 String globalEnable;
224 String shadowIER;
225 };
226
227 /*! @_nodoc */
228 @Facet
229 metaonly config ViewInfo.Instance rovViewInfo =
230 ViewInfo.create({
231 viewMap: [
232 ['Basic', {type: ViewInfo.INSTANCE, viewInitFxn: 'viewInitBasic', structName: 'BasicView'}],
233 ['Module', {type: ViewInfo.MODULE, viewInitFxn: 'viewInitModule', structName: 'ModuleView'}]
234 ]
235 });
236
237 /*!
238 * Assert raised when an invalid interrupt number is passed to a Hwi call
239 */
240 config Assert.Id A_badIntNum = {
241 msg: "A_badIntNum: Invalid interrupt number"
242 };
243
244 /*!
245 * Assert raised when an invalid argument has been passed to a function
246 */
247 config Assert.Id A_invalidArg = {
248 msg: "A_invalidArg: Invalid argument"
249 };
250
251 /*!
252 * Assert raised when there is a conflict with the zero latency IER mask
253 *
254 * This assert is raised when trying to create a Hwi with an intNum that
255 * conflicts with the supplied zero latency IER mask.
256 */
257 config Assert.Id A_zeroLatencyConflict = {
258 msg: "A_zeroLatencyConflict: Conflict with zero latency IER mask"
259 };
260
261 /*!
262 * Error raised when an unplugged interrupt is flagged
263 */
264 config Error.Id E_unpluggedInterrupt = {
265 msg: "E_unpluggedInterrupt: Unplugged interrupt flagged: intr# %d"
266 };
267
268 /*!
269 * Error raised when Hwi is already defined
270 */
271 config Error.Id E_alreadyDefined = {
272 msg: "E_alreadyDefined: Hwi already defined: intr# %d"
273 };
274
275
276
277
278 /*!
279 * ======== NonDispatchedInterrupt ========
280 * Non-dispatched interrupt object
281 *
282 * Provided so that XGCONF users can easily plug non-dispatched interrupts
283 *
284 * @field(intNum) Interrupt number
285 * @field(fxn) Non-dispatched interrupt service routine (ISR)
286 * @field(enableInt) Enable the interrupt after plugging the vector
287 */
288 metaonly struct NonDispatchedInterrupt {
289 Int intNum;
290 PlugFuncPtr fxn;
291 Bool enableInt;
292 };
293
294 /*!
295 * ======== nonDispatchedInterrupts ========
296 * Non-dispatched interrupt array.
297 *
298 * Provided so that XGCONF users can easily plug non-dispatched interrupts
299 */
300 metaonly config NonDispatchedInterrupt nonDispatchedInterrupts[string];
301
302 /*!
303 * ======== zeroLatencyIERMask ========
304 * Zero Latency IER Mask
305 *
306 * CPU interrupts specified in this mask (which corresponds to the 16-bit
307 * IER register) will never be disabled. This means that the
308 * {@link #disable}, {@link #enable}, and {@link #restore} calls leave the
309 * zero latency CPU interrupts enabled after being called. Zero latency
310 * operation may be used to ensure minimal interrupt-to-ISR time for
311 * non-BIOS interrupt handlers in applications that demand low latency.
312 *
313 * It is important to note that zero latency and non-zero latency PIE
314 * interrupts may not share a common PIE group. The entire PIE group whose
315 * bit is set in the zeroLatencyIERMask will be treated as zero latency.
316 *
317 * Enabling zero latency mode (specifying a non-zero zeroLatencyIERMask)
318 * generates alternate (and slower) code used to disable, enable and
319 * restore interrupts. This alternate code will maintain a shadow copy
320 * of interrupt state (IER register and global interrupt state). {@link
321 * #disableIER}, {@link #enableIER} and {@link #restoreIER} will update
322 * both the IER register and its shadow. The {@link #disable} call
323 * will copy the zero latency IER mask (supplied here) into the IER
324 * register. The {@link #enable} call will copy the contents of the
325 * shadow IER register into the actual register. The {@link #restore}
326 * call may either disable or enable the non-zero-latency interrupts.
327 *
328 * It is important to be aware of the performance penalty associated with
329 * using zero latency interrupts before using this feature.
330 *
331 * Example:
332 *
333 * @p(code)
334 * var Hwi = xdc.useModule('ti.sysbios.family.c28.Hwi');
335 * Hwi.zeroLatencyIERMask = 0x0010;
336 *
337 * // PIE group 5 classified as zero latency
338 * @p
339 *
340 */
341 config Bits16 zeroLatencyIERMask = 0x0;
342
343 /*!
344 * Issued just prior to Hwi function invocation (with interrupts disabled)
345 */
346 config Log.Event LM_begin = {
347 mask: Diags.USER1 | Diags.USER2,
348 msg: "LM_begin: hwi: 0x%x, func: 0x%x, preThread: %d, intNum: %d, irp: 0x%x"
349 };
350
351 /*!
352 * Issued just after return from Hwi function (with interrupts disabled)
353 */
354 config Log.Event LD_end = {
355 mask: Diags.USER2,
356 msg: "LD_end: hwi: 0x%x"
357 };
358
359
360
361 /*!
362 * ======== disable ========
363 */
364 @Macro
365 override UInt disable();
366
367 /*!
368 * ======== enable ========
369 */
370 @Macro
371 override UInt enable();
372
373 /*!
374 * ======== restore ========
375 */
376 @Macro
377 override Void restore(UInt key);
378
379 /*!
380 * ======== inUseMeta ========
381 * @_nodoc
382 * Check for Hwi already in use.
383 * For internal SYS/BIOS use only.
384 * Should be called prior to any internal Hwi.create().
385 *
386 * @param(intNum) interrupt number
387 */
388 metaonly Bool inUseMeta(UInt intNum);
389
390 /*!
391 * ======== plug ========
392 * Plug an interrupt vector with an ISR address.
393 *
394 * plug hooks up the specified function as the branch target for a
395 * hardware interrupt (fielded by the CPU) at the vector address
396 * corresponding to intNum. plug does not enable the interrupt. Use
397 * Hwi_enableIER to enable specific interrupts.
398 *
399 * This API can plug the full set of vectors supported by the PIE (0-127).
400 *
401 * @param(intNum) interrupt number
402 * @param(fxn) pointer to ISR function
403 */
404 @DirectCall
405 Void plug(UInt intNum, PlugFuncPtr fxn);
406
407 /*!
408 * ======== plugMeta ========
409 * Statically plug an interrupt vector with an ISR address.
410 *
411 * @param(intNum) Interrupt number
412 * @param(fxn) Pointer to ISR function
413 */
414 metaonly Void plugMeta(UInt intNum, PlugFuncPtr fxn);
415
416 /*!
417 * ======== getHandle ========
418 * Returns Hwi handle associated with intNum
419 *
420 * @param(intNum) Interrupt number
421 *
422 * @b(returns) Hwi handle associated with intNum
423 */
424 @DirectCall
425 Handle getHandle(UInt intNum);
426
427 /*!
428 * ======== disableInterrupt ========
429 * @Hwi The behavior of Hwi_disableInterrupt depends on whether the intNum
430 * is a PIE interrupt number. If so, the appropriate bit in its group's
431 * PIEIER register is cleared. Note that, unlike
432 * {@link #enableInterrupt}, disableInterrupt does not touch IER bits
433 * when operating upon a PIE interrupt number. If intNum is a non-PIE
434 * interrupt (1 <= intNum <= 14), then the corresponding bit in the IER
435 * register is cleared.
436 *
437 * @Hwi The return value is a key whose value reflects the previous state of
438 * the PIEIER bit.
439 */
440 @DirectCall
441 override UInt disableInterrupt(UInt intNum);
442
443 /*!
444 * ======== enableInterrupt ========
445 * @Hwi The behavior of enableInterrupt depends on whether the intNum
446 * is a PIE interrupt number. If so, two operations are
447 * performed. The IER bit for intNum's PIE group is set and the
448 * appropriate bit in its group's PIEIER register is also set. However,
449 * if intNum is a non-PIE interrupt (1 <= intNum <= 14), then the
450 * corresponding bit in the IER register is set.
451 *
452 * @Hwi The return value is a key whose value reflects the previous state of
453 * the PIEIER bit. Note that the key does not reflect
454 * the IER register's previous state even if its state is modified by this
455 * call.
456 */
457 @DirectCall
458 override UInt enableInterrupt(UInt intNum);
459
460 /*!
461 * ======== restoreInterrupt ========
462 * @Hwi The behavior of restoreInterrupt depends on whether the intNum
463 * is a PIE interrupt number. If so, the supplied key returned by an
464 * earlier call to {@link #disableInterrupt} and {@link #enableInterrupt}
465 * is used to restore the corresponding PIEIER bit to its state before
466 * the earlier call.
467 * However, if intNum is a non-PIE interrupt (1 <= intNum <= 14), then the
468 * corresponding bit in the IER register is restored using the key.
469 */
470 @DirectCall
471 override Void restoreInterrupt(UInt intNum, UInt key);
472
473 /*!
474 * ======== clearInterrupt ========
475 * @Hwi The behavior of clearInterrupt depends on whether the intNum
476 * is a PIE interrupt number. If so, the corresponding PIEIFR bit is
477 * cleared. If not (1 <= intNum <= 14), the corresponding IFR bit is
478 * cleared.
479 */
480 @DirectCall
481 override Void clearInterrupt(UInt intNum);
482
483 /*!
484 * ======== disableIER ========
485 * Disable certain maskable interrupts.
486 *
487 * Atomically disables specific interrupts by clearing the bits
488 * specified by mask in the Interrupt Enable Register (IER).
489 *
490 * The IER bits to be cleared should be set to 1 in the mask.
491 *
492 * @param(mask) bitmask of interrupts to disable
493 *
494 * @b(returns) previous IER settings bitmask
495 */
496 @DirectCall
497 Bits16 disableIER(Bits16 mask);
498
499 /*!
500 * ======== enableIER ========
501 * Enable certain maskable interrupts.
502 *
503 * Atomically enables specific interrupts by setting the bits
504 * specified by mask in the Interrupt Enable Register (IER).
505 *
506 * The IER bits to be set should be set to 1 in the mask.
507 *
508 * @param(mask) Bitmask of interrupts to enable
509 *
510 * @b(returns) Previous IER settings bitmask
511 */
512 @DirectCall
513 Bits16 enableIER(Bits16 mask);
514
515 /*!
516 * ======== restoreIER ========
517 * Restore maskable interrupts
518 *
519 * Restores maskable interrupts to the state they were in
520 * when either disableIER() or enableIER() was called.
521 *
522 * Atomically writes the given mask to the IER register. Typically used
523 * to restore the IER register to the state returned from a call to
524 * either {@link #disableIER()} or {@link #enableIER()}.
525 *
526 * @param(mask) Bitmask of interrupts to restore
527 *
528 * @b(returns) Previous IER settings bitmask
529 */
530 @DirectCall
531 Bits16 restoreIER(Bits16 mask);
532
533 /*!
534 * ======== enablePIEIER ========
535 * Enable interrupts in a PIE group
536 *
537 * Atomically enable PIE interrupts in a single PIE group
538 * according to supplied PIEIER bitmask
539 *
540 * @param(groupNum) PIE group number
541 * @param(pieMask) PIEIER enable mask for group
542 *
543 * @b(returns) Previous PIEIER settings bitmask
544 */
545 @DirectCall
546 Bits16 enablePIEIER(UInt groupNum, Bits16 pieMask);
547
548 /*!
549 * ======== disablePIEIER ========
550 * Disable interrupts in a PIE group
551 *
552 * Atomically disable PIE interrupts in a single PIE group
553 * according to supplied PIEIER bitmask
554 *
555 * @param(groupNum) PIE group number
556 * @param(pieMask) PIEIER disable mask for group
557 *
558 * @b(returns) Previous PIEIER settings bitmask
559 */
560 @DirectCall
561 Bits16 disablePIEIER(UInt groupNum, Bits16 pieMask);
562
563 /*!
564 * ======== restorePIEIER ========
565 * Restores interrupts in a PIE group
566 *
567 * Atomically restore PIE interrupts in a single PIE group
568 * according to supplied PIEIER bitmask
569 *
570 * @param(groupNum) PIE group number
571 * @param(pieMask) PIEIER restore mask for group
572 *
573 * @b(returns) Previous PIEIER settings bitmask
574 */
575 @DirectCall
576 Bits16 restorePIEIER(UInt groupNum, Bits16 pieMask);
577
578 /*!
579 * ======== getInterruptFlag ========
580 * @_nodoc
581 * Returns IFR/PIEIFR flag corresponding to a single interrupt number
582 *
583 * If intNum >= 32, the PIEIFR bit corresponding to intNum is returned.
584 * If 1 <= intNum <= 14, the IFR bit corresponding to intNum is returned.
585 *
586 * @param(intNum) Interrupt number
587 *
588 * @b(returns) Nonzero if interrupt is flagged, zero otherwise
589 */
590 @DirectCall
591 Bits16 getInterruptFlag(UInt intNum);
592
593 /*!
594 * ======== getIERMask ========
595 * @_nodoc
596 * Calculates IER mask based on an array of C28x interrupt vector IDs
597 *
598 * For each vector id the supplied array, a bit in the generated IER mask
599 * is set. If 1 <= intNum <= 14, the corresponding IER bit is set. If
600 * intNum >= 32, the IER mask bit corresponding to the PIE interrupt's
601 * group is set.
602 *
603 * getIERMask may be used to generate a zero latency IER mask given
604 * an array of vector IDs.
605 *
606 * @param(vecIds) Array of vector IDs
607 *
608 * @b(returns) Calculated IER Mask
609 */
610 metaonly UInt getIERMask(UInt vecIds[]);
611
612 instance:
613
614 /*!
615 * Dispatcher auto-nesting interrupt disable mask.
616 *
617 * When the dispatcher's auto interrupt nesting support feature
618 * is enabled (see {@link #dispatcherAutoNestingSupport}),
619 * this mask defines which IER bits are disabled prior to invoking
620 * the user's ISR function with GIE = 1.
621 *
622 * disableMask bits set to 1 correspond to IER bits that will be cleared
623 * prior to invoking the ISR.
624 *
625 * The value of this mask is normally auto-calculated based on the
626 * value of the maskSetting. However, manual setting of this
627 * mask is enabled by setting the maskSetting to
628 * {@link #MaskingOption MaskingOption_BITMASK}.
629 *
630 * The default value is derived from the
631 * {@link #MaskingOption MaskingOption_SELF}
632 * maskSetting.
633 */
634 config Bits16 disableMask = 0;
635
636 /*!
637 * Dispatcher auto-nesting interrupt restore mask.
638 *
639 * When the dispatcher's auto interrupt nesting support feature
640 * is enabled (see {@link #dispatcherAutoNestingSupport}),
641 * this mask defines which IER bits are restored to their previous
642 * setting upon return from the user's ISR function.
643 *
644 * restoreMask bits set to 1 correspond to IER bits that will be restored.
645 *
646 * The value of this mask is normally auto-calculated based on the
647 * value of the maskSetting. However, manual setting of this
648 * mask is enabled by setting the maskSetting to
649 * {@link #MaskingOption MaskingOption_BITMASK}.
650 *
651 * The default value is derived from the
652 * {@link #MaskingOption MaskingOption_SELF}
653 * maskSetting.
654 */
655 config Bits16 restoreMask = 0;
656
657 /*!
658 * Interrupt priority. Not supported on this target.
659 */
660 override config Int priority = 0;
661
662 /*!
663 * ======== reconfig ========
664 * Reconfigure a dispatched interrupt.
665 */
666 @DirectCall
667 Void reconfig(FuncPtr fxn, const Params *params);
668
669 /*!
670 * Enable automatic acknowledgement of PIE interrupts by the Hwi interrupt
671 * dispatcher.
672 */
673 config Bool enableAck = true;
674
675 internal:
676 677 678 679 680 681
682 config UInt (*swiDisable)();
683 config Void (*swiRestoreHwi)(UInt);
684 config UInt (*taskDisable)();
685 config Void (*taskRestoreHwi)(UInt);
686
687 688 689 690
691 Bits16 getIFR();
692
693
694 Void ack(Handle hwi);
695
696
697 Void interruptReturn();
698
699
700 Bits16 getIERBit(UInt intNum);
701
702
703 Void dispatchC(Int intNum);
704
705
706 Void unPluggedInterrupt();
707
708
709 config HookSet hooks[length] = [];
710
711
712 metaonly struct InterruptObj {
713 String name;
714 Bool used;
715 Bool useDispatcher;
716 FuncPtr fxn;
717 PlugFuncPtr pfxn;
718 };
719
720
721 const Ptr PIEIER1_ADDR = 0x000CE2;
722
723
724 metaonly config String zeroLatencyIERMaskStr;
725 metaonly config String nonZeroLatencyIERMaskStr;
726
727 728 729 730 731
732 metaonly config InterruptObj interrupt[NUM_INTERRUPTS_ALL];
733
734 struct Instance_State {
735 UInt intNum;
736 Bool enableInt;
737 Bool enableAck;
738 Bits16 disableMask;
739 Bits16 restoreMask;
740 Bits16 ierBitMask;
741 UArg arg;
742 FuncPtr fxn;
743 Irp irp;
744 Ptr hookEnv[];
745 };
746
747 struct Module_State {
748 Bits16 ierMask;
749 Char *isrStack;
750 Char *taskSP;
751 Handle dispatchTable[];
752 Irp irp;
753 Bool globalEnable;
754 Bits16 shadowIER;
755 };
756 }
757 758 759 760
761