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