1 /*
2 * Copyright (c) 2012, Texas Instruments Incorporated
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * * Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 *
12 * * Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * * Neither the name of Texas Instruments Incorporated nor the names of
17 * its contributors may be used to endorse or promote products derived
18 * from this software without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
22 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
24 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
27 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
28 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
29 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
30 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 * */
32 /*
33 * ======== Hwi.xdc ========
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 #getEventId} </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td><td> N </td></tr>
104 * <tr><td> {@link #getHandle} </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td><td> N </td></tr>
105 * <tr><td> {@link #Params_init} </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td></tr>
106 * <tr><td> {@link #restore} </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td></tr>
107 * <tr><td> {@link #restoreIER} </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td><td> N </td></tr>
108 * <tr><td> {@link #restoreInterrupt} </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td></tr>
109 * <tr><td> {@link #construct} </td><td> N </td><td> N </td><td> Y </td><td> Y </td><td> N </td></tr>
110 * <tr><td> {@link #delete} </td><td> N </td><td> N </td><td> Y </td><td> Y </td><td> N </td></tr>
111 * <tr><td> {@link #destruct} </td><td> N </td><td> N </td><td> Y </td><td> Y </td><td> N </td></tr>
112 * <tr><td> {@link #getHookContext} </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td><td> N </td></tr>
113 * <tr><td> {@link #reconfig} </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td><td> N </td></tr>
114 * <tr><td> {@link #setFunc} </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td><td> N </td></tr>
115 * <tr><td> {@link #setHookContext} </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td><td> N </td></tr>
116 * <tr><td colspan="6"> Definitions: <br />
117 * <ul>
118 * <li> <b>Hwi</b>: API is callable from a Hwi thread. </li>
119 * <li> <b>Swi</b>: API is callable from a Swi thread. </li>
120 * <li> <b>Task</b>: API is callable from a Task thread. </li>
121 * <li> <b>Main</b>: API is callable during any of these phases: </li>
122 * <ul>
123 * <li> In your module startup after this module is started (e.g. Hwi_Module_startupDone() returns TRUE). </li>
124 * <li> During xdc.runtime.Startup.lastFxns. </li>
125 * <li> During main().</li>
126 * <li> During BIOS.startupFxns.</li>
127 * </ul>
128 * <li> <b>Startup</b>: API is callable during any of these phases:</li>
129 * <ul>
130 * <li> During xdc.runtime.Startup.firstFxns.</li>
131 * <li> In your module startup before this module is started (e.g. Hwi_Module_startupDone() returns FALSE).</li>
132 * </ul>
133 * </ul>
134 * </td></tr>
135 *
136 * </table>
137 * @p 138 */
139
140 @Template("./Hwi.xdt") /* generates the vector table and the dispatcher */
141 @ModuleStartup /* generate a call to Hwi_init at startup */
142
143 module Hwi inherits ti.sysbios.interfaces.IHwi
144 {
145 // -------- Module Constants --------
146
147 /*! C64+ supports 16 interrupts. */
148 const Int NUM_INTERRUPTS = 16;
149
150 // -------- Module Types --------
151
152 /*! @_nodoc Hwi plug function type definition. */
153 typedef Void (*PlugFuncPtr)(void);
154
155 /*!
156 * ======== BasicView ========
157 * @_nodoc 158 */
159 metaonlystruct BasicView {
160 Ptr halHwiHandle;
161 String label;
162 UInt intNum;
163 String fxn;
164 UArg arg; // Argument to Hwi function.
165 Ptr irp;
166 UInt eventId;
167 String disableMask; // Interrupts to mask during ISR.
168 String restoreMask; // Interrupts to restore after ISR.
169 };
170
171 /*!
172 * ======== ModuleView ========
173 * @_nodoc 174 */
175 metaonlystruct ModuleView {
176 String options[4];
177 SizeT hwiStackPeak;
178 SizeT hwiStackSize;
179 Ptr hwiStackBase;
180 };
181
182 /*!
183 * ======== rovViewInfo ========
184 * @_nodoc 185 */
186 @Facet
187 metaonlyconfig ViewInfo.Instance rovViewInfo =
188 ViewInfo.create({
189 viewMap: [
190 ['Basic', {type: ViewInfo.INSTANCE, viewInitFxn: 'viewInitBasic', structName: 'BasicView'}],
191 ['Module', {type: ViewInfo.MODULE, viewInitFxn: 'viewInitModule', structName: 'ModuleView'}]
192 ]
193 });
194
195 // -------- Module Parameters --------
196
197 /*!
198 * non-dispatched interrupt object.
199 * provided so that XGCONF users can easily plug non-dispatched interrupts
200 */
201 metaonlystruct NonDispatchedInterrupt {
202 Int intNum;
203 PlugFuncPtr fxn; /*! "Hwi_plug'd" ISR function. */
204 Bool enableInt;
205 Int eventId;
206 };
207
208 /*!
209 * non-dispatched interrupt array.
210 * provided so that XGCONF users can easily plug non-dispatched interrupts
211 */
212 metaonlyconfig NonDispatchedInterrupt nonDispatchedInterrupts[string];
213
214 /*!
215 * Alternate reset vector address. Default is undefined.
216 *
217 * if initialized by the user then an additional reset vector
218 * is created and placed in the ".resetVector" section.
219 * To place the .resetVector section into a specific memory section,
220 * add the following command to your config script:
221 * @p(code) 222 * Program.sectMap[".resetVector"] = YourMemorySection;
223 * @p 224 */
225 metaonlyconfig Ptr resetVectorAddress;
226
227 /*!
228 * Error raised when Hwi is already defined
229 */
230 config Error.Id E_alreadyDefined = {
231 msg: "E_alreadyDefined: Hwi already defined: intr# %d"
232 };
233
234 /*!
235 * Error raised when Hwi handle referenced in Hwi_delete()
236 * is not found in the Hwi dispatch table
237 */
238 config Error.Id E_handleNotFound = {
239 msg: "E_handleNotFound: Hwi handle not found: 0x%x"
240 };
241
242 /*!
243 * Issued just prior to Hwi function invocation (with interrupts disabled)
244 */
245 config Log.Event LM_begin = {
246 mask: Diags.USER1 | Diags.USER2,
247 msg: "LM_begin: hwi: 0x%x, func: 0x%x, preThread: %d, intNum: %d, irp: 0x%x"
248 };
249
250 /*!
251 * Issued just after return from Hwi function (with interrupts disabled)
252 */
253 config Log.Event LD_end = {
254 mask: Diags.USER2,
255 msg: "LD_end: hwi: 0x%x"
256 };
257
258 /*!
259 * enable Exception module for exception processing.
260 */
261 config Bool enableException = true;
262
263 // -------- Module Functions --------
264
265 /*!
266 * ======== disable ========
267 */
268 @Macro
269 override UInt disable();
270
271 /*!
272 * ======== enable ========
273 */
274 @Macro
275 override UInt enable();
276
277 /*!
278 * ======== restore ========
279 */
280 @Macro
281 override Void restore(UInt key);
282
283 /*!
284 * ======== inUseMeta ========
285 * @_nodoc 286 * Check for Hwi already in use.
287 * For internal SYS/BIOS use only.
288 * Should be called prior to any internal Hwi.create().
289 *
290 * @param(intNum) interrupt number
291 */
292 metaonly Bool inUseMeta(UInt intNum);
293
294 /*!
295 * ======== eventMap ========
296 * Maps a GEM event to interrupt number
297 *
298 * Function maps a GEM event to an interrupt number so that the
299 * event is the interrupt source of the vector.
300 *
301 * @p(code) 302 * // Maps GEM event #65 as the interrupt source of int vector #7
303 * Hwi_eventMap(7, 65);
304 * @p 305 *
306 * @param(intNum) interrupt number
307 * @param(eventId) event ID
308 */
309 @DirectCall
310 Void eventMap(Int intNum, Int eventId);
311
312 /*!
313 * ======== eventMapMeta ========
314 * Maps GEM Event to interrupt number statically
315 *
316 * Function maps a GEM event to an interrupt number so that the
317 * event is the interrupt source of the vector.
318 *
319 * @p(code) 320 * // Maps GEM event #65 as the interrupt source of int vector #7
321 * Hwi.eventMapMeta(7, 65);
322 * @p 323 *
324 * @param(intNum) interrupt number
325 * @param(eventId) event Id
326 */
327 metaonly Void eventMapMeta(Int intNum, Int eventId);
328
329 /*!
330 * ======== plug ========
331 * Plug an interrupt vector with an ISR address.
332 *
333 * Hwi_plug writes an Interrupt Service Fetch Packet (ISFP) into the
334 * Interrupt Service Table (IST), at the address corresponding to intNum
335 * The op-codes written in the ISFP create a branch to the function
336 * entry point specified by fxn:
337 *
338 * @p(code) 339 * stw b0, *SP--[1]
340 * mvk fxn, b0
341 * mvkh fxn, b0
342 * b b0
343 * ldw *++SP[1],b0
344 * nop 4
345 * @p 346 *
347 * Hwi_plug hooks up the specified function as the branch target of a
348 * hardware interrupt (fielded by the CPU) at the vector address
349 * specified in intNum. Hwi_plug does not enable the interrupt.
350 * Use Hwi_enableIER to enable specific interrupts.
351 *
352 * AN ISR PLUGGED WITH THIS API IS NOT SERVICED BY THE INTERRUPT
353 * DISPATCHER. CONSEQUENTLY, IT SHOULD NOT INVOKE ANY SYS/BIOS APIs
354 * (ie Semaphore_post())!!!
355 *
356 * @a(constraints) 357 * o interrupt function MUST NOT INTERACT WITH SYS/BIOS.
358 * (ie do not call Semaphore_post())
359 *
360 * o vecid must be a valid interrupt ID in the range of 0-15.
361 *
362 * @param(intNum) interrupt number
363 * @param(fxn) pointer to ISR function
364 */
365 @DirectCall
366 Void plug(UInt intNum, PlugFuncPtr fxn);
367
368 /*!
369 * ======== plugMeta ========
370 * Statically plug an interrupt vector with an ISR address.
371 *
372 * @param(intNum) interrupt number
373 * @param(fxn) pointer to ISR function
374 */
375 metaonly Void plugMeta(UInt intNum, PlugFuncPtr fxn);
376
377 /*!
378 * ======== getEventId ========
379 * Returns event id associated with interrupt number
380 *
381 * If a bad interrupt number is passed in, it will return -1.
382 *
383 * @param(intNum) interrupt number
384 * @b(returns) event id associated with intNum
385 */
386 @DirectCall
387 Int getEventId(UInt intNum);
388
389 /*!
390 * ======== getHandle ========
391 * Returns Hwi_handle associated with interrupt number
392 *
393 * @param(intNum) interrupt number
394 * @b(returns) handle associated with intNum
395 */
396 @DirectCall
397 Handle getHandle(UInt intNum);
398
399 /*!
400 * ======== disableIER ========
401 * Disable certain maskable interrupts.
402 *
403 * Atomically disables specific interrupts by clearing the bits
404 * specified by mask in the Interrupt Enable Register (IER).
405 *
406 * The IER bits to be cleared should be set to 1 in the mask.
407 *
408 * @param(mask) bitmask of interrupts to disable
409 * @b(returns) previous IER settings bitmask
410 */
411 @DirectCall
412 Bits16 disableIER(Bits16 mask);
413
414 /*!
415 * ======== enableIER ========
416 * Enable certain maskable interrupts.
417 *
418 * Atomically enables specific interrupts by setting the bits
419 * specified by mask in the Interrupt Enable Register (IER).
420 *
421 * The IER bits to be set should be set to 1 in the mask.
422 *
423 * @param(mask) bitmask of interrupts to enable
424 * @b(returns) previous IER settings bitmask
425 */
426 @DirectCall
427 Bits16 enableIER(Bits16 mask);
428
429 /*!
430 * ======== restoreIER ========
431 * Restore maskable interrupts to the state they were in
432 * when either disableIER() or enableIER() was called.
433 *
434 * Atomically writes the given mask to the IER register. Typically used
435 * to restore the IER register to the state returned from a call to
436 * either {@link #disableIER()} or {@link #enableIER()}.
437 *
438 * @param(mask) bitmask of interrupts to restore
439 * @b(returns) previous IER settings bitmask
440 */
441 @DirectCall
442 Bits16 restoreIER(Bits16 mask);
443
444 instance:
445
446 /*!
447 * Dispatcher auto-nesting interrupt disable mask.
448 *
449 * When the dispatcher's auto interrupt nesting support feature
450 * is enabled (see {@link #dispatcherAutoNestingSupport}),
451 * this mask defines which IER bits are disabled prior to invoking
452 * the user's ISR function with GIE = 1.
453 *
454 * disableMask bits set to 1 correspond to IER bits that will be cleared
455 * prior to invoking the ISR.
456 *
457 * The value of this mask is normally auto-calculated based on the
458 * value of the maskSetting. However, manual setting of this
459 * mask is enabled by setting the maskSetting to
460 * {@link #MaskingOption MaskingOption_BITMASK}.
461 *
462 * The default value is derived from the
463 * {@link #MaskingOption MaskingOption_SELF}
464 * maskSetting.
465 */
466 config Bits16 disableMask = 0;
467
468 /*!
469 * Dispatcher auto-nesting interrupt restore mask.
470 *
471 * When the dispatcher's auto interrupt nesting support feature
472 * is enabled (see {@link #dispatcherAutoNestingSupport}),
473 * this mask defines which IER bits are restored to their previous
474 * setting upon return from the user's ISR function.
475 *
476 * restoreMask bits set to 1 correspond to IER bits that will be restored.
477 *
478 * The value of this mask is normally auto-calculated based on the
479 * value of the maskSetting. However, manual setting of this
480 * mask is enabled by setting the maskSetting to
481 * {@link #MaskingOption MaskingOption_BITMASK}.
482 *
483 * The default value is derived from the
484 * {@link #MaskingOption MaskingOption_SELF}
485 * maskSetting.
486 */
487 config Bits16 restoreMask = 0;
488
489 /*!
490 * Interrupt priority. Not supported on this target.
491 */
492 overrideconfig Int priority = 0;
493
494 /*!
495 * ======== reconfig ========
496 * Reconfigures a dispatched interrupt.
497 *
498 * This function reconfigures the dispatched interrupt so the
499 * specified function is called with the specified parameters.
500 *
501 * @param(fxn) pointer to ISR function
502 * @param(params) pointer to Hwi parameter structure
503 */
504 @DirectCall
505 Void reconfig(FuncPtr fxn, const Params *params);
506
507 internal: /* not for client use */
508
509 /*
510 * Swi and Task module function pointers.
511 * Used to decouple Hwi from Swi and Task when
512 * dispatcherSwiSupport or
513 * dispatcherTaskSupport is false.
514 */
515 config UInt (*swiDisable)();
516 config Void (*swiRestoreHwi)(UInt);
517 config UInt (*taskDisable)();
518 config Void (*taskRestoreHwi)(UInt);
519
520 /*
521 * ======== getIsrStackAddress ========
522 * Returns initial isrStack address.
523 * This API was developed solely for the Exception module
524 * to allow removal of the Hwi_link.xdt template definition
525 * of ti_sysbios_family_c64p_Hwi_isrStack which was not
526 * ROM-able
527 */
528 Char *getIsrStackAddress();
529
530 /* Interrupt Dispatcher */
531 Void dispatchC(Int intNum);
532
533 /* unPlugged interrupt handler */
534 Void unPluggedInterrupt();
535
536 /*!
537 * const array to hold all HookSet objects.
538 */
539 config HookSet hooks[length] = [];
540
541 /*! Meta World Only Hwi Configuration Object. */
542 metaonlystruct InterruptObj {
543 String name; /* symbol used for vector table entry */
544 Bool used; /* Interrupt already defined? */
545 Bool useDispatcher; /* Should dispatcher handle this Int? */
546 FuncPtr fxn; /* Dispatched ISR function */
547 PlugFuncPtr pfxn; /* "Hwi_plug'd" ISR function. */
548 };
549
550 /*!
551 * Meta-only array of interrupt objects.
552 * This meta-only array of Hwi config objects is initialized
553 * in Hwi.xs:module$meta$init().
554 */
555 metaonlyconfig InterruptObj interrupt[NUM_INTERRUPTS];
556
557 struct Instance_State {
558 Bits16 disableMask; // Interrupts to mask during ISR.
559 Bits16 restoreMask; // Interrupts to restore after ISR.
560 UArg arg; // Argument to Hwi function.
561 FuncPtr fxn; // Hwi function.
562 Irp irp; // current IRP
563 Ptr hookEnv[];
564 };
565
566 struct Module_State {
567 Char intEvents[16]; // Initial event mapping
568 Bits16 ierMask; // Initial IER mask
569 volatile Int intNum; // Interrupt number
570 Char *taskSP; // temporary storage of interrupted
571 // Task's SP during ISR execution
572 /* ROM */
573 Char *isrStack; // Points to isrStack address
574 Ptr vectorTableBase;// ti_sysbios_family_c64_Hwi0
575 Ptr bss; // bss address
576
577 Handle dispatchTable[NUM_INTERRUPTS]; // dispatch table
578 };
579 }
580 /*
581 * @(#) ti.sysbios.family.c64p; 2, 0, 0, 0,578; 9-20-2012 14:58:47; /db/vtree/library/trees/avala/avala-r17x/src/ xlibrary
582 583 */
584