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