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.c64p;
38
39 import xdc.rov.ViewInfo;
40
41 import xdc.runtime.Diags;
42 import xdc.runtime.Error;
43 import xdc.runtime.Log;
44
45 /*!
46 * ======== Hwi ========
47 * C64+ Hardware Interrupt Support Module.
48 *
49 * This Hwi module provides C64+ family-specific implementations of the
50 * APIs defined in {@link ti.sysbios.interfaces.IHwi IHwi}.
51 *
52 * Additional C64+ device-specific APIs are also provided.
53 *
54 * An example of creating a Hwi instance:
55 *
56 * @p(code)
57 *
58 * Int intNum;
59 * Hwi_Params params;
60 * Error_Block eb;
61 *
62 * // Initialize the error block
63 * Error_init(&eb);
64 *
65 * // Initialize the Hwi parameters
66 * Hwi_Params_init(¶ms);
67 *
68 * // Set the GEM event id in the params
69 * params.eventId = 78
70 *
71 * // Specify the interrupt vector number
72 * intNum = 8;
73 *
74 * // create the Hwi for the specified interrupt number and params
75 * Hwi_create(intNum, myIsr, ¶ms, &eb);
76 *
77 * @p
78 *
79 * @a(NOTE)
80 * In this Hwi module implementation, the instance config parameter value
81 * {@link #MaskingOption_LOWER} is equivalent to {@link #MaskingOption_SELF}.
82 * Statically configuring a Hwi object's {@link #Params.maskSetting} to
83 * {@link #MaskingOption_LOWER} will result in the generation of a benign
84 * build warning. Dynamic usages of {@link #MaskingOption_LOWER} will be
85 * silently converted to {@link #MaskingOption_SELF}.
86 *
87 * @p(html)
88 * <h3> Calling Context </h3>
89 * <table border="1" cellpadding="3">
90 * <colgroup span="1"></colgroup> <colgroup span="5" align="center"></colgroup>
91 *
92 * <tr><th> Function </th><th> Hwi </th><th> Swi </th><th> Task </th><th> Main </th><th> Startup </th></tr>
93 * <!-- -->
94 * <tr><td> {@link #clearInterrupt} </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td></tr>
95 * <tr><td> {@link #create} </td><td> N </td><td> N </td><td> Y </td><td> Y </td><td> N </td></tr>
96 * <tr><td> {@link #disable} </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td></tr>
97 * <tr><td> {@link #disableIER} </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td><td> N </td></tr>
98 * <tr><td> {@link #disableInterrupt} </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td><td> N </td></tr>
99 * <tr><td> {@link #enable} </td><td> Y </td><td> Y </td><td> Y </td><td> N </td><td> N </td></tr>
100 * <tr><td> {@link #enableIER} </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td><td> N </td></tr>
101 * <tr><td> {@link #enableInterrupt} </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td><td> N </td></tr>
102 * <tr><td> {@link #eventMap} </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td><td> N </td></tr>
103 * <tr><td> {@link #getHandle} </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td><td> N </td></tr>
104 * <tr><td> {@link #Params_init} </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td></tr>
105 * <tr><td> {@link #restore} </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td></tr>
106 * <tr><td> {@link #restoreIER} </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td><td> N </td></tr>
107 * <tr><td> {@link #restoreInterrupt} </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td></tr>
108 * <tr><td> {@link #construct} </td><td> N </td><td> N </td><td> Y </td><td> Y </td><td> N </td></tr>
109 * <tr><td> {@link #delete} </td><td> N </td><td> N </td><td> Y </td><td> Y </td><td> N </td></tr>
110 * <tr><td> {@link #destruct} </td><td> N </td><td> N </td><td> Y </td><td> Y </td><td> N </td></tr>
111 * <tr><td> {@link #getHookContext} </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td><td> N </td></tr>
112 * <tr><td> {@link #reconfig} </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td><td> N </td></tr>
113 * <tr><td> {@link #setFunc} </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td><td> N </td></tr>
114 * <tr><td> {@link #setHookContext} </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td><td> N </td></tr>
115 * <tr><td colspan="6"> Definitions: <br />
116 * <ul>
117 * <li> <b>Hwi</b>: API is callable from a Hwi thread. </li>
118 * <li> <b>Swi</b>: API is callable from a Swi thread. </li>
119 * <li> <b>Task</b>: API is callable from a Task thread. </li>
120 * <li> <b>Main</b>: API is callable during any of these phases: </li>
121 * <ul>
122 * <li> In your module startup after this module is started (e.g. Hwi_Module_startupDone() returns TRUE). </li>
123 * <li> During xdc.runtime.Startup.lastFxns. </li>
124 * <li> During main().</li>
125 * <li> During BIOS.startupFxns.</li>
126 * </ul>
127 * <li> <b>Startup</b>: API is callable during any of these phases:</li>
128 * <ul>
129 * <li> During xdc.runtime.Startup.firstFxns.</li>
130 * <li> In your module startup before this module is started (e.g. Hwi_Module_startupDone() returns FALSE).</li>
131 * </ul>
132 * </ul>
133 * </td></tr>
134 *
135 * </table>
136 * @p
137 */
138
139 @Template("./Hwi.xdt")
140 @ModuleStartup
141
142 module Hwi inherits ti.sysbios.interfaces.IHwi
143 {
144
145
146 /*! C64+ supports 16 interrupts. */
147 const Int NUM_INTERRUPTS = 16;
148
149
150
151 /*! @_nodoc Hwi plug function type definition. */
152 typedef Void (*PlugFuncPtr)(void);
153
154 /*!
155 * ======== BasicView ========
156 * @_nodoc
157 */
158 metaonly struct BasicView {
159 Ptr halHwiHandle;
160 String label;
161 UInt intNum;
162 String fxn;
163 UArg arg;
164 Ptr irp;
165 UInt eventId;
166 String disableMask;
167 String restoreMask;
168 };
169
170 /*!
171 * ======== ModuleView ========
172 * @_nodoc
173 */
174 metaonly struct ModuleView {
175 String options[4];
176 SizeT hwiStackPeak;
177 SizeT hwiStackSize;
178 Ptr hwiStackBase;
179 };
180
181 /*!
182 * ======== rovViewInfo ========
183 * @_nodoc
184 */
185 @Facet
186 metaonly config ViewInfo.Instance rovViewInfo =
187 ViewInfo.create({
188 viewMap: [
189 ['Basic', {type: ViewInfo.INSTANCE, viewInitFxn: 'viewInitBasic', structName: 'BasicView'}],
190 ['Module', {type: ViewInfo.MODULE, viewInitFxn: 'viewInitModule', structName: 'ModuleView'}]
191 ]
192 });
193
194
195
196 /*!
197 * non-dispatched interrupt object.
198 * provided so that XGCONF users can easily plug non-dispatched interrupts
199 */
200 metaonly struct NonDispatchedInterrupt {
201 Int intNum;
202 PlugFuncPtr fxn; /*! "Hwi_plug'd" ISR function. */
203 Bool enableInt;
204 Int eventId;
205 };
206
207 /*!
208 * non-dispatched interrupt array.
209 * provided so that XGCONF users can easily plug non-dispatched interrupts
210 */
211 metaonly config NonDispatchedInterrupt nonDispatchedInterrupts[string];
212
213 /*!
214 * Alternate reset vector address. Default is undefined.
215 *
216 * if initialized by the user then an additional reset vector
217 * is created and placed in the ".resetVector" section.
218 * To place the .resetVector section into a specific memory section,
219 * add the following command to your config script:
220 * @p(code)
221 * Program.sectMap[".resetVector"] = YourMemorySection;
222 * @p
223 */
224 metaonly config Ptr resetVectorAddress;
225
226 /*!
227 * Error raised when Hwi is already defined
228 */
229 config Error.Id E_alreadyDefined = {
230 msg: "E_alreadyDefined: Hwi already defined: intr# %d"
231 };
232
233 /*!
234 * Issued just prior to Hwi function invocation (with interrupts disabled)
235 */
236 config Log.Event LM_begin = {
237 mask: Diags.USER1 | Diags.USER2,
238 msg: "LM_begin: hwi: 0x%x, func: 0x%x, preThread: %d, intNum: %d, irp: 0x%x"
239 };
240
241 /*!
242 * Issued just after return from Hwi function (with interrupts disabled)
243 */
244 config Log.Event LD_end = {
245 mask: Diags.USER2,
246 msg: "LD_end: hwi: 0x%x"
247 };
248
249 /*!
250 * enable Exception module for exception processing.
251 */
252 config Bool enableException = true;
253
254
255
256 /*!
257 * ======== disable ========
258 */
259 @Macro
260 override UInt disable();
261
262 /*!
263 * ======== enable ========
264 */
265 @Macro
266 override UInt enable();
267
268 /*!
269 * ======== restore ========
270 */
271 @Macro
272 override Void restore(UInt key);
273
274 /*!
275 * ======== inUseMeta ========
276 * @_nodoc
277 * Check for Hwi already in use.
278 * For internal SYS/BIOS use only.
279 * Should be called prior to any internal Hwi.create().
280 *
281 * @param(intNum) interrupt number
282 */
283 metaonly Bool inUseMeta(UInt intNum);
284
285 /*!
286 * ======== eventMap ========
287 * Maps a GEM event to interrupt number
288 *
289 * Function maps a GEM event to an interrupt number so that the
290 * event is the interrupt source of the vector.
291 *
292 * @p(code)
293 * // Maps GEM event #65 as the interrupt source of int vector #7
294 * Hwi_eventMap(7, 65);
295 * @p
296 *
297 * @param(intNum) interrupt number
298 * @param(eventId) event ID
299 */
300 @DirectCall
301 Void eventMap(Int intNum, Int eventId);
302
303 /*!
304 * ======== eventMapMeta ========
305 * Maps GEM Event to interrupt number statically
306 *
307 * Function maps a GEM event to an interrupt number so that the
308 * event is the interrupt source of the vector.
309 *
310 * @p(code)
311 * // Maps GEM event #65 as the interrupt source of int vector #7
312 * Hwi.eventMapMeta(7, 65);
313 * @p
314 *
315 * @param(intNum) interrupt number
316 * @param(eventId) event Id
317 */
318 metaonly Void eventMapMeta(Int intNum, Int eventId);
319
320 /*!
321 * @_nodoc
322 * ======== plug ========
323 * Plug an interrupt vector with an ISR address.
324 *
325 * Hwi_plug writes an Interrupt Service Fetch Packet (ISFP) into the
326 * Interrupt Service Table (IST), at the address corresponding to intNum
327 * The op-codes written in the ISFP create a branch to the function
328 * entry point specified by fxn:
329 *
330 * @p(code)
331 * stw b0, *SP--[1]
332 * mvk fxn, b0
333 * mvkh fxn, b0
334 * b b0
335 * ldw *++SP[1],b0
336 * nop 4
337 * @p
338 *
339 * Hwi_plug hooks up the specified function as the branch target of a
340 * hardware interrupt (fielded by the CPU) at the vector address
341 * specified in intNum. Hwi_plug does not enable the interrupt.
342 * Use Hwi_enableIER to enable specific interrupts.
343 *
344 * For internal SYS/BIOS use only.
345 *
346 * Constraints and Calling Context
347 * o vecid must be a valid interrupt ID in the range of 0-15.
348 *
349 * @param(intNum) interrupt number
350 * @param(fxn) pointer to ISR function
351 */
352 @DirectCall
353 Void plug(UInt intNum, PlugFuncPtr fxn);
354
355 /*!
356 * ======== plugMeta ========
357 * Statically plug an interrupt vector with an ISR address.
358 *
359 * @param(intNum) interrupt number
360 * @param(fxn) pointer to ISR function
361 */
362 metaonly Void plugMeta(UInt intNum, PlugFuncPtr fxn);
363
364 /*!
365 * ======== getHandle ========
366 * Returns Hwi_handle associated with interrupt number
367 *
368 * @param(intNum) interrupt number
369 * @b(returns) handle associated with intNum
370 */
371 @DirectCall
372 Handle getHandle(UInt intNum);
373
374 /*!
375 * ======== disableIER ========
376 * Disable certain maskable interrupts.
377 *
378 * Atomically disables specific interrupts by clearing the bits
379 * specified by mask in the Interrupt Enable Register (IER).
380 *
381 * The IER bits to be cleared should be set to 1 in the mask.
382 *
383 * @param(mask) bitmask of interrupts to disable
384 * @b(returns) previous IER settings bitmask
385 */
386 @DirectCall
387 Bits16 disableIER(Bits16 mask);
388
389 /*!
390 * ======== enableIER ========
391 * Enable certain maskable interrupts.
392 *
393 * Atomically enables specific interrupts by setting the bits
394 * specified by mask in the Interrupt Enable Register (IER).
395 *
396 * The IER bits to be set should be set to 1 in the mask.
397 *
398 * @param(mask) bitmask of interrupts to enable
399 * @b(returns) previous IER settings bitmask
400 */
401 @DirectCall
402 Bits16 enableIER(Bits16 mask);
403
404 /*!
405 * ======== restoreIER ========
406 * Restore maskable interrupts to the state they were in
407 * when either disableIER() or enableIER() was called.
408 *
409 * Atomically writes the given mask to the IER register. Typically used
410 * to restore the IER register to the state returned from a call to
411 * either {@link #disableIER()} or {@link #enableIER()}.
412 *
413 * @param(mask) bitmask of interrupts to restore
414 * @b(returns) previous IER settings bitmask
415 */
416 @DirectCall
417 Bits16 restoreIER(Bits16 mask);
418
419 instance:
420
421 /*!
422 * Dispatcher auto-nesting interrupt disable mask.
423 *
424 * When the dispatcher's auto interrupt nesting support feature
425 * is enabled (see {@link #dispatcherAutoNestingSupport}),
426 * this mask defines which IER bits are disabled prior to invoking
427 * the user's ISR function with GIE = 1.
428 *
429 * disableMask bits set to 1 correspond to IER bits that will be cleared
430 * prior to invoking the ISR.
431 *
432 * The value of this mask is normally auto-calculated based on the
433 * value of the maskSetting. However, manual setting of this
434 * mask is enabled by setting the maskSetting to
435 * {@link #MaskingOption MaskingOption_BITMASK}.
436 *
437 * The default value is derived from the
438 * {@link #MaskingOption MaskingOption_SELF}
439 * maskSetting.
440 */
441 config Bits16 disableMask = 0;
442
443 /*!
444 * Dispatcher auto-nesting interrupt restore mask.
445 *
446 * When the dispatcher's auto interrupt nesting support feature
447 * is enabled (see {@link #dispatcherAutoNestingSupport}),
448 * this mask defines which IER bits are restored to their previous
449 * setting upon return from the user's ISR function.
450 *
451 * restoreMask bits set to 1 correspond to IER bits that will be restored.
452 *
453 * The value of this mask is normally auto-calculated based on the
454 * value of the maskSetting. However, manual setting of this
455 * mask is enabled by setting the maskSetting to
456 * {@link #MaskingOption MaskingOption_BITMASK}.
457 *
458 * The default value is derived from the
459 * {@link #MaskingOption MaskingOption_SELF}
460 * maskSetting.
461 */
462 config Bits16 restoreMask = 0;
463
464 /*!
465 * Interrupt priority. Not supported on this target.
466 */
467 override config Int priority = 0;
468
469 /*!
470 * ======== reconfig ========
471 * Reconfigures a dispatched interrupt.
472 *
473 * This function reconfigures the dispatched interrupt so the
474 * specified function is called with the specified parameters.
475 *
476 * @param(fxn) pointer to ISR function
477 * @param(params) pointer to Hwi parameter structure
478 */
479 @DirectCall
480 Void reconfig(FuncPtr fxn, const Params *params);
481
482 internal:
483
484 485 486 487 488 489
490 config UInt (*swiDisable)();
491 config Void (*swiRestoreHwi)(UInt);
492 config UInt (*taskDisable)();
493 config Void (*taskRestoreHwi)(UInt);
494
495 496 497 498 499 500 501 502
503 Char *getIsrStackAddress();
504
505 506 507 508
509 UInt getEvent(UInt intNum);
510
511
512 Void dispatchC(Int intNum);
513
514
515 Void unPluggedInterrupt();
516
517 /*!
518 * const array to hold all HookSet objects.
519 */
520 config HookSet hooks[length] = [];
521
522 /*! Meta World Only Hwi Configuration Object. */
523 metaonly struct InterruptObj {
524 String name;
525 Bool used;
526 Bool useDispatcher;
527 FuncPtr fxn;
528 PlugFuncPtr pfxn;
529 };
530
531 /*!
532 * Meta-only array of interrupt objects.
533 * This meta-only array of Hwi config objects is initialized
534 * in Hwi.xs:module$meta$init().
535 */
536 metaonly config InterruptObj interrupt[NUM_INTERRUPTS];
537
538 struct Instance_State {
539 Bits16 disableMask;
540 Bits16 restoreMask;
541 UArg arg;
542 FuncPtr fxn;
543 Irp irp;
544 Ptr hookEnv[];
545 };
546
547 struct Module_State {
548 Char intEvents[12];
549 Bits16 ierMask;
550 volatile Int intNum;
551 Char *taskSP;
552
553
554 Char *isrStack;
555 Ptr vectorTableBase;
556 Ptr bss;
557
558 Handle dispatchTable[NUM_INTERRUPTS];
559 };
560 }
561 562 563 564
565