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
38 package ti.sysbios.family.c64p;
39
40 import xdc.runtime.Assert;
41 import xdc.runtime.Error;
42
43 /*!
44 * ======== EventCombiner ========
45 * Event Combiner Manager module
46 *
47 * The event combiner allows the user to combine up to 32 system events
48 * into a single combined event. The events 0, 1, 2, and 3 are the events
49 * associated with the event combiner. Using the EventCombiner module
50 * along with the Hwi module, allows the user to route a combined event
51 * to any of the 12 maskable CPU interrupts available on GEM. The
52 * EventCombiner supports up to 128 system events. Users can specify
53 * a function and an argument for each system event and can choose to
54 * enable whichever system events they want.
55 *
56 * An example of using the EventCombiner during runtime to plug the ISR
57 * handlers for events 65 and 66 on the same Hwi:
58 *
59 * @p(code)
60 *
61 * Hwi_Params params;
62 * Error_Block eb;
63 *
64 * // Initialize the error block
65 * Error_init(&eb);
66 *
67 * // Plug the function and argument for event 65 then enable it
68 * EventCombiner_dispatchPlug(65, &myEvent65Fxn, 0, TRUE);
69 *
70 * // Plug the function and argument for event 66 then enable it
71 * EventCombiner_dispatchPlug(66, &myEvent66Fxn, 1, TRUE);
72 *
73 * // Initialize the Hwi parameters
74 * Hwi_Params_init(¶ms);
75 *
76 * // The eventId must be set to the combined event for event 65 or 66.
77 * // The combined event is event 2 for both. If the combined events are
78 * // different, then another Hwi must be used for the other combined event
79 * params.eventId = 65 / 32;
80 *
81 * // The arg must be set to params.eventId.
82 * params.arg = params.eventId;
83 *
84 * // Enable the interrupt.
85 * params.enableInt = TRUE;
86 *
87 * // Events 65 and 66 are on the same combined event so create a single Hwi.
88 * // Create the Hwi on interrupt 7 then specify 'EventCombiner_dispatch'
89 * // as the function.
90 * Hwi_create(7, &EventCombiner_dispatch, ¶ms, &eb);
91 *
92 * @p
93 *
94 * An example of using the EventCombiner during static creation to plug the
95 * ISR handlers for events 31 and 63 on different Hwis:
96 *
97 * @p(code)
98 *
99 * // Use EventCombiner module
100 * var EventCombiner = xdc.useModule('ti.sysbios.family.c64p.EventCombiner');
101 *
102 * // Plug function and argument for event 31 then enable it.
103 * EventCombiner.events[31].fxn = '&myEvent31Fxn';
104 * EventCombiner.events[31].arg = 31;
105 * EventCombiner.events[31].unmask = true;
106 *
107 * // Plug function and argument for event 63 then enable it.
108 * EventCombiner.events[63].fxn = '&myEvent63Fxn';
109 * EventCombiner.events[63].arg = 63;
110 * EventCombiner.events[63].unmask = true;
111 *
112 * // Map event 0 (combine events 0-31) to vector 8
113 * EventCombiner.eventGroupHwiNum[0] = 8;
114 *
115 * // Map event 1 (combine events 32-63) to vector 9
116 * EventCombiner.eventGroupHwiNum[1] = 9;
117 *
118 * @p
119 *
120 * @p(html)
121 * <h3> Calling Context </h3>
122 * <table border="1" cellpadding="3">
123 * <colgroup span="1"></colgroup> <colgroup span="5" align="center"></colgroup>
124 *
125 * <tr><th> Function </th><th> Hwi </th><th> Swi </th><th> Task </th><th> Main </th><th> Startup </th></tr>
126 * <!-- -->
127 * <tr><td> {@link #disableEvent} </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td></tr>
128 * <tr><td> {@link #dispatch} </td><td> Y </td><td> N </td><td> N </td><td> N </td><td> N </td></tr>
129 * <tr><td> {@link #dispatchPlug} </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td></tr>
130 * <tr><td> {@link #enableEvent} </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td></tr>
131 * <tr><td colspan="6"> Definitions: <br />
132 * <ul>
133 * <li> <b>Hwi</b>: API is callable from a Hwi thread. </li>
134 * <li> <b>Swi</b>: API is callable from a Swi thread. </li>
135 * <li> <b>Task</b>: API is callable from a Task thread. </li>
136 * <li> <b>Main</b>: API is callable during any of these phases: </li>
137 * <ul>
138 * <li> In your module startup after this module is started (e.g. EventCombiner_Module_startupDone() returns TRUE). </li>
139 * <li> During xdc.runtime.Startup.lastFxns. </li>
140 * <li> During main().</li>
141 * <li> During BIOS.startupFxns.</li>
142 * </ul>
143 * <li> <b>Startup</b>: API is callable during any of these phases:</li>
144 * <ul>
145 * <li> During xdc.runtime.Startup.firstFxns.</li>
146 * <li> In your module startup before this module is started (e.g. EventCombiner_Module_startupDone() returns FALSE).</li>
147 * </ul>
148 * </ul>
149 * </td></tr>
150 *
151 * </table>
152 * @p
153 */
154
155 @ModuleStartup
156 @DirectCall
157 module EventCombiner
158 {
159 /*!
160 * ======== EventView ========
161 * @_nodoc
162 */
163 metaonly struct EventView {
164 UInt eventId;
165 String fxn;
166 String arg;
167 };
168
169 /*!
170 * ======== rovViewInfo ========
171 * @_nodoc
172 */
173 @Facet
174 metaonly config xdc.rov.ViewInfo.Instance rovViewInfo =
175 xdc.rov.ViewInfo.create({
176 viewMap: [
177 ['Events',
178 {
179 type: xdc.rov.ViewInfo.MODULE_DATA,
180 viewInitFxn: 'viewInitEvents',
181 structName: 'EventView'
182 }
183 ]
184 ]
185 });
186
187
188
189 /*! C64+ supports 128 events. */
190 const Int NUM_EVENTS = 128;
191
192
193
194 /*! Event Combiner dispatcher function type definition. */
195 typedef Void (*FuncPtr)(UArg);
196
197 /*!
198 * Event Configuration Object.
199 *
200 * unmask - Boolean value that specifies if an event should be
201 * unmasked in the C64+ EVTMASK registers.
202 * fxn - function to call when this event occurs.
203 * arg - arg to fxn.
204 */
205 metaonly struct EventObj {
206 Bool unmask;
207 FuncPtr fxn;
208 UArg arg;
209 };
210
211 /*!
212 * Event Combiner registers template
213 */
214 struct Registers {
215 UInt EVTFLAG[4];
216 UInt hole1[4];
217 UInt EVTSET[4];
218 UInt hole2[4];
219 UInt EVTCLR[4];
220 UInt hole3[12];
221 UInt EVTMASK[4];
222 UInt hole4[4];
223 UInt MEVTFLAG[4];
224 UInt hole5[4];
225 UInt EXPMASK[4];
226 UInt hole6[4];
227 UInt MEXPMASK[4];
228 };
229
230 /*!
231 * Event Combiner registers base address
232 */
233 config Registers *EVTRegs;
234
235 /*!
236 * Assert raised when an invalid event id number is specified
237 */
238 config Assert.Id A_invalidEventId = {
239 msg: "A_invalidEventId: Invalid event Id specified"
240 };
241
242 /*!
243 * Error raised when an unplug Event is executed.
244 */
245 config Error.Id E_unpluggedEvent = {
246 msg: "E_unpluggedEvent: Event# %d is unplugged"
247 };
248
249
250
251 /*!
252 * ======== EVTMASK ========
253 * Holds the initialization values for the C64+ EVTMASK registers (0-3).
254 *
255 * It is assigned values based on the 'unmask' member of the 'events'
256 * configuration array. It can also be assigned manually in the program
257 * configuration script.
258 */
259 config Bits32 EVTMASK[4];
260
261 /*!
262 * ======== events ========
263 * For holding configuration values for all C64+ events.
264 *
265 * Array elements can be configured in the program
266 * configuration script.
267 */
268 metaonly config EventObj events[NUM_EVENTS];
269
270 /*!
271 * ======== eventGroupHwiNum ========
272 * Configures the mapping of a C64+ combined event group to an interrupt.
273 *
274 * There is one element per combined event group (0-3).
275 */
276 metaonly config Int eventGroupHwiNum[4];
277
278 /*!
279 * ======== dispatchEventGroup ========
280 * Configuration method for assigning the eventGroupHwiNum array.
281 *
282 * It accomplishes the same thing as directly setting
283 * eventGroupHwiNum[0-3].
284 *
285 * @param(evt) event id
286 * @param(hwiVec) the Hwi vector to use
287 */
288 metaonly Void dispatchEventGroup(UInt evt, UInt hwiVec);
289
290 /*!
291 * ======== disableEvent ========
292 * Disables 'evt' from contributing to its combined event group.
293 *
294 * It accomplishes this by setting the corresponding
295 * bit in the C64+ EVTMASK array to 1 (to mask it).
296 *
297 * @param(evt) event id
298 */
299 Void disableEvent(UInt evt);
300
301 /*!
302 * ======== enableEvent ========
303 * Enables 'evt' to contribute to its combined event group.
304 *
305 * It accomplishes this by setting the corresponding
306 * bit in the C64+ EVTMASK array to 0 (to unmask it).
307 *
308 * @param(evt) event id
309 */
310 Void enableEvent(UInt evt);
311
312 /*!
313 * ======== dispatch ========
314 * The Event Combiner dispatcher.
315 *
316 * It is mostly used internally, but can be used directly by the user.
317 *
318 * @param(evt) event id
319 */
320 Void dispatch(UInt evt);
321
322 /*!
323 * ======== dispatchPlug ========
324 * Used to configure a dispatcher entry for 'evt'.
325 *
326 * This function plugs the dispatch table with the specified fxn and attrs.
327 * It does not map the corresponding combined event group to a Hwi
328 * interrupt - such an action needs to be performed either using the
329 * event combiner configuration or using the Hwi module.
330 *
331 * @param(evt) event id
332 * @param(fxn) function to call
333 * @param(arg) argument to the function
334 * @param(unmask) whether to enable the event or not
335 */
336 Void dispatchPlug(UInt evt, FuncPtr fxn, UArg arg, Bool unmask);
337
338 /*!
339 * @_nodoc
340 * ======== unused ========
341 * unused exists simply to map a call in the Ecm dispatcher calling
342 * context to the System_exit calling context (casts UArg to Int).
343 *
344 * @param(arg) argument to function
345 */
346 Void unused(UArg arg);
347
348 internal:
349
350 struct DispatchTabElem {
351 FuncPtr fxn;
352 UArg arg;
353 };
354
355 struct Module_State {
356 DispatchTabElem dispatchTab[NUM_EVENTS];
357 };
358
359 }
360