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 * Assert raised when an invalid event id number is specified
213 */
214 config Assert.Id A_invalidEventId = {
215 msg: "A_invalidEventId: Invalid event Id specified"
216 };
217
218 /*!
219 * Error raised when an unplug Event is executed.
220 */
221 config Error.Id E_unpluggedEvent = {
222 msg: "E_unpluggedEvent: Event# %d is unplugged"
223 };
224
225
226
227 /*!
228 * ======== EVTMASK ========
229 * Holds the initialization values for the C64+ EVTMASK registers (0-3).
230 *
231 * It is assigned values based on the 'unmask' member of the 'events'
232 * configuration array. It can also be assigned manually in the program
233 * configuration script.
234 */
235 config Bits32 EVTMASK[4];
236
237 /*!
238 * ======== events ========
239 * For holding configuration values for all C64+ events.
240 *
241 * Array elements can be configured in the program
242 * configuration script.
243 */
244 metaonly config EventObj events[NUM_EVENTS];
245
246 /*!
247 * ======== eventGroupHwiNum ========
248 * Configures the mapping of a C64+ combined event group to an interrupt.
249 *
250 * There is one element per combined event group (0-3).
251 */
252 metaonly config Int eventGroupHwiNum[4];
253
254 /*!
255 * ======== dispatchEventGroup ========
256 * Configuration method for assigning the eventGroupHwiNum array.
257 *
258 * It accomplishes the same thing as directly setting
259 * eventGroupHwiNum[0-3].
260 *
261 * @param(evt) event id
262 * @param(hwiVec) the Hwi vector to use
263 */
264 metaonly Void dispatchEventGroup(UInt evt, UInt hwiVec);
265
266 /*!
267 * ======== disableEvent ========
268 * Disables 'evt' from contributing to its combined event group.
269 *
270 * It accomplishes this by setting the corresponding
271 * bit in the C64+ EVTMASK array to 1 (to mask it).
272 *
273 * @param(evt) event id
274 */
275 Void disableEvent(UInt evt);
276
277 /*!
278 * ======== enableEvent ========
279 * Enables 'evt' to contribute to its combined event group.
280 *
281 * It accomplishes this by setting the corresponding
282 * bit in the C64+ EVTMASK array to 0 (to unmask it).
283 *
284 * @param(evt) event id
285 */
286 Void enableEvent(UInt evt);
287
288 /*!
289 * ======== dispatch ========
290 * The Event Combiner dispatcher.
291 *
292 * It is mostly used internally, but can be used directly by the user.
293 *
294 * @param(evt) event id
295 */
296 Void dispatch(UInt evt);
297
298 /*!
299 * ======== dispatchPlug ========
300 * Used to configure a dispatcher entry for 'evt'.
301 *
302 * This function plugs the dispatch table with the specified fxn and attrs.
303 * It does not map the corresponding combined event group to a Hwi
304 * interrupt - such an action needs to be performed either using the
305 * event combiner configuration or using the Hwi module.
306 *
307 * @param(evt) event id
308 * @param(fxn) function to call
309 * @param(arg) argument to the function
310 * @param(unmask) whether to enable the event or not
311 */
312 Void dispatchPlug(UInt evt, FuncPtr fxn, UArg arg, Bool unmask);
313
314 /*!
315 * @_nodoc
316 * ======== unused ========
317 * unused exists simply to map a call in the Ecm dispatcher calling
318 * context to the System_exit calling context (casts UArg to Int).
319 *
320 * @param(arg) argument to function
321 */
322 Void unused(UArg arg);
323
324 internal:
325
326 struct DispatchTabElem {
327 FuncPtr fxn;
328 UArg arg;
329 };
330
331 struct Module_State {
332 DispatchTabElem dispatchTab[NUM_EVENTS];
333 };
334
335 }
336