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.shared.vayu;
37
38 import xdc.rov.ViewInfo;
39
40 import xdc.runtime.Assert;
41 import xdc.runtime.Error;
42
43 import ti.sysbios.interfaces.IHwi;
44
45 /*!
46 * ======== IntXbar ========
47 * IntXbar module
48 *
49 * This module provides APIs to connect an IRQ source to
50 * an IRQ line on the target cpu's interrupt controller
51 * using the Interrupt Crossbar module in the hardware.
52 *
53 * Below is an example of how to override the default mapping of
54 * interrupt 23 on a M4 so that the interrupt source is I2C module 1
55 * rather than Display Controller interrupt request(mapped by default):
56 *
57 * @p(code)
58 * #include <ti/sysbios/family/arm/m3/Hwi.h>
59 * #include <ti/sysbios/family/shared/vayu/IntXbar.h>
60 *
61 * Void myI2CHandler(UArg arg)
62 * {
63 * // Handler Code
64 * }
65 *
66 * Int main(Int argc, Char* argv[])
67 * {
68 * Hwi_Params params;
69 *
70 * Hwi_Params_init(¶ms);
71 *
72 * // Connect IRQ 23 to Interrupt source index 51 (I2C1_IRQ)
73 * IntXbar_connectIRQ(23, 51);
74 *
75 * // Alternately, IntXbar_connect API can be used. This
76 * // API expects XBAR instance number as an argument.
77 * //
78 * // Connect Xbar Instance 1 (IRQ 23) to Interrupt
79 * // source index 51 (I2C1_IRQ)
80 * //
81 * // IntXbar_connect(1, 51);
82 *
83 * // create a corresponding interrupt handler
84 * params.arg = 23; // pass the Interrupt number to the handler
85 *
86 * Hwi_create(23, myI2CHandler, ¶ms, NULL);
87 *
88 * BIOS_start();
89 *
90 * return (0);
91 * }
92 * @p
93 *
94 * Here is how you would define the same interrupt handler statically
95 * in a configuration script:
96 *
97 * @p(code)
98 * var Hwi = xdc.useModule('ti.sysbios.family.arm.m3.Hwi');
99 * var IntXbar = xdc.useModule('ti.sysbios.family.shared.vayu.IntXbar');
100 *
101 * // Connect IRQ 23 to Interrupt source index 51 (I2C1_IRQ)
102 * IntXbar.connectIRQMeta(23, 51);
103 *
104 * // Alternately, the connectIRQMeta API can be used. This
105 * // API expects XBAR instance number as an argument.
106 * //
107 * // Connect Xbar Instance 1 (IRQ 23) to Interrupt
108 * // source index 51 (I2C1_IRQ)
109 * //
110 * // IntXbar.connectMeta(1, 51);
111 *
112 * var hwiParams = new Hwi.Params();
113 * hwiParams.arg = 23;
114 *
115 * Program.global.staticHwi = Hwi.create(23, '&myTimerHandler', hwiParams);
116 * @p
117 *
118 * @p(html)
119 * <h3> Calling Context </h3>
120 * <table border="1" cellpadding="3">
121 * <colgroup span="1"></colgroup> <colgroup span="5" align="center"></colgroup>
122 *
123 * <tr><th> Function </th><th> Hwi </th><th> Swi </th><th> Task </th><th> Main </th><th> Startup </th></tr>
124 * <!-- -->
125 * <tr><td> {@link #connect} </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td></tr>
126 * <tr><td> {@link #disconnect} </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td></tr>
127 * <tr><td colspan="6"> Definitions: <br />
128 * <ul>
129 * <li> <b>Hwi</b>: API is callable from a Hwi thread. </li>
130 * <li> <b>Swi</b>: API is callable from a Swi thread. </li>
131 * <li> <b>Task</b>: API is callable from a Task thread. </li>
132 * <li> <b>Main</b>: API is callable during any of these phases: </li>
133 * <ul>
134 * <li> In your module startup after this module is started (e.g. Mod_Module_startupDone() returns TRUE). </li>
135 * <li> During xdc.runtime.Startup.lastFxns. </li>
136 * <li> During main().</li>
137 * <li> During BIOS.startupFxns.</li>
138 * </ul>
139 * <li> <b>Startup</b>: API is callable during any of these phases:</li>
140 * <ul>
141 * <li> During xdc.runtime.Startup.firstFxns.</li>
142 * <li> In your module startup before this module is started (e.g. Mod_Module_startupDone() returns FALSE).</li>
143 * </ul>
144 * </ul>
145 * </td></tr>
146 *
147 * </table>
148 * @p
149 */
150
151 @DirectCall
152 module IntXbar
153 {
154 /*!
155 * ======== ModuleDataView ========
156 * @_nodoc
157 */
158 metaonly struct ModuleDataView {
159 Int cpuIRQNumber;
160 Int xbarInstanceNumber;
161 Int interruptSourceIndex;
162 }
163
164 /*!
165 * ======== rovViewInfo ========
166 * @_nodoc
167 */
168 @Facet
169 metaonly config ViewInfo.Instance rovViewInfo =
170 ViewInfo.create({
171 viewMap: [
172 [
173 'XbarList',
174 {
175 type: ViewInfo.MODULE_DATA,
176 viewInitFxn: 'viewInitData',
177 structName: 'ModuleDataView'
178 }
179 ],
180 ]
181 });
182
183 /*!
184 * Assert if EVE XBAR instance number < 1 or > 8
185 */
186 config Assert.Id A_badEveXbarInstanceNum = {
187 msg: "A_badEveXbarInstanceNum: xbarInstance must be >= 1 and <= 8"
188 };
189
190 /*!
191 * Assert if DSP XBAR instance number < 1 or > 64
192 */
193 config Assert.Id A_badDspXbarInstanceNum = {
194 msg: "A_badDspXbarInstanceNum: xbarInstance must be >= 1 and <= 64"
195 };
196
197 /*!
198 * Assert if Benelli XBAR instance number < 1 or > 57
199 */
200 config Assert.Id A_badBenelliXbarInstanceNum = {
201 msg: "A_badBenelliXbarInstanceNum: xbarInstance must be >= 1 and <= 57"
202 };
203
204 /*!
205 * Assert if A15 XBAR instance number < 1 or > 152
206 */
207 config Assert.Id A_badA15XbarInstanceNum = {
208 msg: "A_badA15XbarInstanceNum: xbarInstance must be >= 1 and <= 152"
209 };
210
211 /*!
212 * Assert if EVE IRQ number > 7
213 */
214 config Assert.Id A_badEveIRQNum = {
215 msg: "A_badEveIRQNum: IRQ number must be <= 7"
216 };
217
218 /*!
219 * Assert if DSP IRQ number is < 32 or > 95
220 */
221 config Assert.Id A_badDspIRQNum = {
222 msg: "A_badDspIRQNum: IRQ number must be >= 32 and <= 95"
223 };
224
225 /*!
226 * Assert if Benelli/IPU IRQ number is < 23 or > 79
227 */
228 config Assert.Id A_badBenelliIRQNum = {
229 msg: "A_badBenelliIRQNum: IRQ number must be >= 23 and <= 79"
230 };
231
232 /*!
233 * Assert if A15 IRQ number is < 4 or == 5 or == 6 or == 131 or == 132 or
234 * == 139 or == 140 or > 159
235 */
236 config Assert.Id A_badA15IRQNum = {
237 msg: "A_badA15IRQNum: No XBAR instance corresponding to given IRQ num"
238 };
239
240 /*!
241 * Assert if IRQ crossbar input index is out of range.
242 */
243 config Assert.Id A_badIntSourceIdx = {
244 msg: "A_badIntSourceIdx: IRQ crossbar input index (intSource) out of range."
245 };
246
247 /*!
248 * Assert if EVE CPU Id invalid
249 */
250 config Assert.Id A_badEveCpuId = {
251 msg: "A_badEveCpuId: CPU Id must be 0, 1, 2 or 3"
252 };
253
254 /*!
255 * Assert if DSP CPU Id invalid
256 */
257 config Assert.Id A_badDspCpuId = {
258 msg: "A_badDspCpuId: CPU Id must be 0 or 1"
259 };
260
261 /*!
262 * Assert if Benelli IPU Id invalid
263 */
264 config Assert.Id A_badBenelliIpuId = {
265 msg: "A_badBenelliIpuId: Ipu Id must be 1 or 2"
266 };
267
268 /*!
269 * Base address of interrupt crossbar MMR registers
270 */
271 config UInt32 mmrBaseAddr = 0x4A002000;
272
273 /*!
274 * Number of IRQ XBAR inputs
275 */
276 const UInt16 numIrqXbarInputs = 420;
277
278 /*!
279 * Number of XBAR instances per EVE core
280 */
281 const UInt16 NUM_EVE_XBAR_INST = 8;
282
283 /*!
284 * Number of XBAR instances per DSP core
285 */
286 const UInt16 NUM_DSP_XBAR_INST = 64;
287
288 /*!
289 * Number of XBAR instances per Benelli Core
290 */
291 const UInt16 NUM_BENELLI_XBAR_INST = 57;
292
293 /*!
294 * Number of XBAR instances per A15 Core
295 */
296 const UInt16 NUM_A15_XBAR_INST = 152;
297
298 /*!
299 * Offset of "AVATAR_INTR_DMA_OCPINTF__EVE1_IRQ_0_1" register
300 */
301 const UInt32 MMR_OFFSET_EVE0 = 0x7A0;
302
303 /*!
304 * Offset of "AVATAR_INTR_DMA_OCPINTF__EVE2_IRQ_0_1" register
305 */
306 const UInt32 MMR_OFFSET_EVE1 = 0x7B0;
307
308 /*!
309 * Offset of "AVATAR_INTR_DMA_OCPINTF__EVE3_IRQ_0_1" register
310 */
311 const UInt32 MMR_OFFSET_EVE2 = 0x7C0;
312
313 /*!
314 * Offset of "AVATAR_INTR_DMA_OCPINTF__EVE4_IRQ_0_1" register
315 */
316 const UInt32 MMR_OFFSET_EVE3 = 0x7D0;
317
318 /*!
319 * Offset of "AVATAR_INTR_DMA_OCPINTF__DSP1_IRQ_32_33" register
320 */
321 const UInt32 MMR_OFFSET_DSP0 = 0x948;
322
323 /*!
324 * Offset of "AVATAR_INTR_DMA_OCPINTF__DSP2_IRQ_32_33" register
325 */
326 const UInt32 MMR_OFFSET_DSP1 = 0x9c8;
327
328 /*!
329 * Offset of "AVATAR_INTR_DMA_OCPINTF__IPU1_IRQ_23_24" register
330 */
331 const UInt32 MMR_OFFSET_BENELLI_IPU1 = 0x7E0;
332
333 /*!
334 * Offset of "AVATAR_INTR_DMA_OCPINTF__IPU2_IRQ_23_24" register
335 */
336 const UInt32 MMR_OFFSET_BENELLI_IPU2 = 0x854;
337
338 /*!
339 * Offset of "AVATAR_INTR_DMA_OCPINTF__MPU_IRQ_4_5" register
340 */
341 const UInt32 MMR_OFFSET_A15 = 0xA48;
342
343 /*!
344 * Offset of MMR Lock 2 register
345 *
346 * Register to lock memory region starting at address offset 0x000007A0
347 * and ending at address offset 0x00000D9F
348 */
349 const UInt32 MMR_OFFSET_LOCK2 = 0x544;
350
351 /*!
352 * MMR Lock 2 lock value
353 */
354 const UInt32 MMR_LOCK2_LOCK = 0xFDF45530;
355
356 /*!
357 * MMR Lock 2 unlock value
358 */
359 const UInt32 MMR_LOCK2_UNLOCK = 0xF757FDC0;
360
361 /*!
362 * ======== connectMeta ========
363 * Connect the XBAR instance associated with an interrupt.
364 *
365 * Dynamically connects the XBAR instance associated with
366 * an interrupt on the current core to the selected
367 * interrupt source.
368 *
369 * @param(xbarInstance) XBAR instance number
370 * @p(code)
371 * (1-8) For EVE Cores
372 * (1-64) For DSP Cores
373 * (1-57) For M4 Cores
374 * (1-152) For A15 Cores
375 * @p
376 * @param(intSource) IRQ crossbar input index
377 *
378 */
379 metaonly Void connectMeta(UInt xbarInstance, UInt intSource);
380
381 /*!
382 * ======== connect ========
383 * Connect the XBAR instance associated with an interrupt.
384 *
385 * Dynamically connects the XBAR instance associated with
386 * an interrupt on the current core to the selected
387 * interrupt source.
388 *
389 * @param(xbarInstance) XBAR instance number
390 * @p(code)
391 * (1-8) For EVE Cores
392 * (1-64) For DSP Cores
393 * (1-57) For M4 Cores
394 * (1-152) For A15 Cores
395 * @p
396 * @param(intSource) IRQ crossbar input index
397 */
398 Void connect(UInt xbarInstance, UInt intSource);
399
400 /*!
401 * ======== disconnect ========
402 * Disconnect the XBAR instance associated with an interrupt.
403 *
404 * Dynamically disconnects the XBAR instance associated with
405 * an interrupt on the current core by clearing the
406 * interrupt source index.
407 *
408 * @param(xbarInstance) XBAR instance number
409 * @p(code)
410 * (1-8) For EVE Cores
411 * (1-64) For DSP Cores
412 * (1-57) For M4 Cores
413 * (1-152) For A15 Cores
414 * @p
415 */
416 Void disconnect(UInt xbarInstance);
417
418 /*!
419 * ======== connectIRQMeta ========
420 * Make a XBAR connection for the given IRQ number.
421 *
422 * Dynamically connects the XBAR instance associated with
423 * the given IRQ number on the current core to the selected
424 * interrupt source.
425 *
426 * Please note that IRQ number is same as Event Id on C66 DSP.
427 *
428 * @param(cpuIRQNum) CPU's IRQ number
429 * @param(intSource) IRQ crossbar input index
430 */
431 metaonly Void connectIRQMeta(UInt cpuIRQNum, UInt intSource);
432
433 /*!
434 * ======== connectIRQ ========
435 * Make a XBAR connection for the given IRQ number.
436 *
437 * Dynamically connects the XBAR instance associated with
438 * the given IRQ number on the current core to the selected
439 * interrupt source.
440 *
441 * Please note that IRQ number is same as Event Id on C66 DSP.
442 *
443 * @param(cpuIRQNum) CPU's IRQ number
444 * @param(intSource) IRQ crossbar input index
445 */
446 Void connectIRQ(UInt cpuIRQNum, UInt intSource);
447
448 /*!
449 * ======== disconnectIRQ ========
450 * Disconnect the XBAR connection associated with the given IRQ number.
451 *
452 * Dynamically disconnects the XBAR instance associated with
453 * the given IRQ number on the current core by clearing the
454 * interrupt source index.
455 *
456 * Please note that IRQ number is same as Event Id on C66 DSP.
457 *
458 * @param(cpuIRQNum) CPU's IRQ number
459 */
460 Void disconnectIRQ(UInt cpuIRQNum);
461
462 internal:
463
464 config UInt16 intXbar[];
465
466 467 468
469 Void initXbarRegs(volatile UInt32 **intXbarReg, UInt16 *intXbarLength);
470
471 472 473
474 Void initIntXbar();
475
476 struct Module_State {
477 UInt16 intXbar[];
478 };
479 }