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.sdo.ipc.family.vayu;
38
39 import xdc.runtime.Assert;
40 import ti.sdo.utils.MultiProc;
41
42 /*!
43 * ======== NotifySetup ========
44 * Notify driver setup proxy for Vayu
45 *
46 * This module creates and registers the IPC Notify drivers for the Vayu
47 * device family. There are two types of notify drivers available: 1) shared
48 * memory driver, and 2) mailbox driver. Use the {@link #connections}
49 * configuration parameter to select which driver to use for communicating
50 * with each remote processor.
51 *
52 * The shared memory notify driver is the default driver. It implements the
53 * full Notify API set. This driver uses memory for passing the notify
54 * payload between processors. The memory is allocated from SharedRegion #0.
55 *
56 * The mailbox notify driver uses hardware FIFOs for passing the notify
57 * payload between processors. No shared memory is required. However, this
58 * driver does not implement the full Notify API set. For example, the
59 * `Notify_sendEvent()` API will never return `Notify_E_EVTNOTREGISTERED`
60 * because it does not track this information.
61 *
62 * When configuring the notify driver, you specify which driver to use
63 * for communicating to each remote processor. If not configured, the
64 * shared memory driver will be used by default. Both sides of each connection
65 * must use the same driver. This is an easy mistake to make and there is
66 * no way to check this.
67 *
68 * This module is primarily used by notify driver authors. It is not expected
69 * that any application would ever use this module in its runtime code.
70 * The typical use of this module is simply to configure which notify driver
71 * to use. See the following example for details.
72 *
73 * @a(Configuration Example)
74 *
75 * The following is a three processor example: HOST DSP1 EVE1. In this
76 * example, HOST and DSP1 will communicate using the shared memory driver
77 * and DSP1 and EVE1 will communicate using the mailbox driver. This example
78 * explicitly configures the shared memory driver for HOST and DSP1, but
79 * this is strictly not necessary. If left unconfigured, the shared memory
80 * driver would be used as the default. Also, the connection between HOST
81 * and EVE1 is left undefined as we don't expect to use this connection.
82 *
83 * Notice that each connection configuration specifies the remote processor
84 * name and the driver type. This is how the local processor declares which
85 * driver it will use when communicating to that remote processor. The
86 * corresponding configuration on the remote processor must be complimentary.
87 *
88 * Add the following to your HOST configuration script.
89 *
90 * @p(code)
91 * // configure the notify driver
92 * var NotifySetup = xdc.useModule('ti.sdo.ipc.family.vayu.NotifySetup');
93 *
94 * NotifySetup.connections.$add(
95 * new NotifySetup.Connection({
96 * driver: NotifySetup.Driver_SHAREDMEMORY,
97 * procName: "DSP1"
98 * })
99 * );
100 * @p
101 * Add the following to your DSP1 configuration script.
102 *
103 * @p(code)
104 * // configure the notify driver
105 * var NotifySetup = xdc.useModule('ti.sdo.ipc.family.vayu.NotifySetup');
106 *
107 * NotifySetup.connections.$add(
108 * new NotifySetup.Connection({
109 * driver: NotifySetup.Driver_SHAREDMEMORY,
110 * procName: "HOST"
111 * })
112 * );
113 *
114 * NotifySetup.connections.$add(
115 * new NotifySetup.Connection({
116 * driver: NotifySetup.Driver_MAILBOX,
117 * procName: "EVE1"
118 * })
119 * );
120 * @p
121 * Add the following to your EVE1 configuration script.
122 *
123 * @p(code)
124 * // configure the notify driver
125 * var NotifySetup = xdc.useModule('ti.sdo.ipc.family.vayu.NotifySetup');
126 *
127 * NotifySetup.connections.$add(
128 * new NotifySetup.Connection({
129 * driver: NotifySetup.Driver_MAILBOX,
130 * procName: "DSP1"
131 * })
132 * );
133 * @p
134 */
135
136 @ModuleStartup
137 @Template("./NotifySetup.xdt")
138
139 module NotifySetup inherits ti.sdo.ipc.interfaces.INotifySetup
140 {
141 /*! @_nodoc
142 * ======== DriverIsr ========
143 * Notify driver isr function type definition
144 * param1 = mailbox table index
145 */
146 typedef Void (*DriverIsr)(UInt16);
147
148 /*!
149 * ======== Driver ========
150 * Define the available notify drivers
151 *
152 * For any given connection to a remote processor, one of the
153 * following notify driver types may be used. Each driver has
154 * different characteristics and system requirements.
155 *
156 * @p(html)
157 * <div class="xdocText"><dl>
158 * <dt>Driver_SHAREDMEMORY</dt>
159 * <dd>
160 * This driver uses shared memory for passing the notify payload
161 * between processors. Additional state is also stored in the
162 * shared memory.<br><br>
163 *
164 * There is a separate, cache-aligned block of memory for each
165 * event number. This is necessary to maintain cache coherency.
166 * However, this requires a non-trivial amount of memory.<br><br>
167 * </dd>
168 *
169 * <dt>Driver_MAILBOX</dt>
170 * <dd>
171 * This driver uses a hardware FIFO (provided by the hardware
172 * mailbox) to pass the notify payload between processors. No
173 * shared memory is required by this driver.<br><br>
174 *
175 * This driver does not support the full Notify API set. This
176 * driver has lower delivery latency when compard to the shared
177 * memory driver.<br><br>
178 * </dd>
179 * </dl>
180 * @p
181 */
182 enum Driver {
183 Driver_SHAREDMEMORY = 0x01, /*! shared memory driver */
184 Driver_MAILBOX = 0x02 /*! hardware mailbox driver */
185 };
186
187 /*!
188 * ======== Connection ========
189 * Define a notify driver connection
190 *
191 * Each IPC connection is defined by two end-points: the local
192 * processor and the remote processor. Each connection supports
193 * only one type of notify driver. In other words, both ends of
194 * the connection must configure the same notify driver type.
195 *
196 * However, when a processor has multiple connections (when
197 * communicating with multiple remote processors), each connection
198 * is configured independently. Therefore, different notify drivers
199 * may be used for different connections. Currently, IPC supports
200 * only one connection for each remote processor.
201 *
202 * The configuration for a given connection must be coordinated with
203 * the remote processor. Each processor is only able to configure its
204 * local end-point for the connection. It is important that the remote
205 * processor use the same notify driver for the connection.
206 *
207 * @field(driver)
208 * The driver to be used for this connection. See the {@link #Driver}
209 * enumeration for details.
210 *
211 * @field(procName)
212 * The name of the remote processor for the given connection.
213 * @p
214 */
215 struct Connection {
216 Driver driver; /*! notify driver */
217 String procName; /*! remote processor name */
218 };
219
220 /*!
221 * ======== connections ========
222 * Configure the notify driver for each given connection
223 *
224 * Use this configuration parameter to define which notify driver
225 * is to be used when communicating with remote processors. Create
226 * one entry in this array for each connection. Each entry you create,
227 * defines the local end-point of the connection. The remote processor
228 * must have a complimentary entry in its `connections` array.
229 *
230 * Any connection which is undefined, will use the shared memory
231 * notify driver. It is not necessary to define all connections, just
232 * the ones which will not use the default.
233 *
234 * To define a local end-point connection, establish a reference to
235 * this module and add a new entry to this array.
236 *
237 * The following example show how to setup the mailbox driver for
238 * communicating from DSP1 to EVE1 and EVE2.
239 *
240 * Add the following to your DSP1 configuration script.
241 *
242 * @p(code)
243 * // configure the notify driver
244 * var NotifySetup = xdc.useModule('ti.sdo.ipc.family.vayu.NotifySetup');
245 *
246 * NotifySetup.connections.$add(
247 * new NotifySetup.Connection({
248 * driver: NotifySetup.Driver_MAILBOX,
249 * procName: "EVE1"
250 * })
251 * );
252 *
253 * NotifySetup.connections.$add(
254 * new NotifySetup.Connection({
255 * driver: NotifySetup.Driver_MAILBOX,
256 * procName: "EVE2"
257 * })
258 * );
259 * @p
260 *
261 * Add the following to your EVE1 configuration script.
262 *
263 * @p(code)
264 * // configure the notify driver
265 * var NotifySetup = xdc.useModule('ti.sdo.ipc.family.vayu.NotifySetup');
266 *
267 * NotifySetup.connections.$add(
268 * new NotifySetup.Connection({
269 * driver: NotifySetup.Driver_MAILBOX,
270 * procName: "DSP1"
271 * })
272 * );
273 * @p
274 *
275 * Add the following to your EVE2 configuration script.
276 *
277 * @p(code)
278 * // configure the notify driver
279 * var NotifySetup = xdc.useModule('ti.sdo.ipc.family.vayu.NotifySetup');
280 *
281 * NotifySetup.connections.$add(
282 * new NotifySetup.Connection({
283 * driver: NotifySetup.Driver_MAILBOX,
284 * procName: "DSP1"
285 * })
286 * );
287 * @p
288 */
289 metaonly config Connection connections[length];
290
291 /*! @_nodoc
292 * ======== plugHwi ========
293 * Register an isr for the given interrupt and event.
294 *
295 * @param(remoteProcId) The MutiProc Id of the remote processor
296 * which will raise the given interrupt.
297 *
298 * @param(cpuIntrNum) The interrupt number which will be raised
299 * by the remote processor.
300 *
301 * @param(isr) The ISR which should be invoked to service the
302 * given interrupt.
303 */
304 Void plugHwi(UInt16 remoteProcId, Int cpuIntrNum, DriverIsr isr);
305
306 /*! @_nodoc
307 * ======== unplugHwi ========
308 * Unregister the isr for the given interrupt.
309 */
310 Void unplugHwi(UInt16 remoteProcId, Int cpuIntrNum);
311
312 /*! @_nodoc
313 * ======== interruptTable ========
314 * Accessor method to return interrupt id for given virtual proc id
315 */
316 UInt16 interruptTable(Int srcVirtId);
317
318 internal:
319
320 config UInt dspIntVectId = 4;
321
322
323 config UInt eveIntVectId_INTC0 = 4;
324 config UInt eveIntVectId_INTC1 = 8;
325
326
327 const UInt8 NUM_CORES = 11;
328
329
330 const UInt8 NUM_EVES = 4;
331
332
333 const UInt8 NUM_EVE_MBX = 12;
334
335
336 const UInt8 NUM_SYS_MBX = 4;
337
338 339 340
341 config UInt32 mailboxTable[NUM_CORES * NUM_CORES];
342
343
344 config UInt32 mailboxBaseAddr[NUM_EVE_MBX + NUM_SYS_MBX];
345
346
347 config UInt eve1ProcId = MultiProc.INVALIDID;
348 config UInt eve2ProcId = MultiProc.INVALIDID;
349 config UInt eve3ProcId = MultiProc.INVALIDID;
350 config UInt eve4ProcId = MultiProc.INVALIDID;
351 config UInt dsp1ProcId = MultiProc.INVALIDID;
352 config UInt dsp2ProcId = MultiProc.INVALIDID;
353 config UInt ipu1_0ProcId = MultiProc.INVALIDID;
354 config UInt ipu1_1ProcId = MultiProc.INVALIDID;
355 config UInt ipu2_0ProcId = MultiProc.INVALIDID;
356 config UInt ipu2_1ProcId = MultiProc.INVALIDID;
357 config UInt hostProcId = MultiProc.INVALIDID;
358
359
360 config UInt32 procIdTable[NUM_CORES];
361
362
363 struct DrvBind {
364 Driver driver;
365 UInt16 procId;
366 };
367
368 369 370 371
372 config Assert.Id A_internal = {
373 msg: "A_internal: internal implementation error"
374 };
375
376 377 378
379 Driver driverType(UInt16 remoteProcId);
380
381 382 383
384 Int Shm_attach(UInt16 remoteProcId, Ptr sharedAddr);
385
386 387 388
389 SizeT Shm_sharedMemReq(UInt16 remoteProcId, Ptr sharedAddr);
390
391 392 393
394 Int Mbx_attach(UInt16 remoteProcId, Ptr sharedAddr);
395
396 397 398
399 SizeT Mbx_sharedMemReq(UInt16 remoteProcId, Ptr sharedAddr);
400
401 402 403 404
405 Void dispatchIsr(UArg arg);
406
407 408 409
410 struct Module_State {
411
412 UInt16 numPlugged[];
413
414
415 DrvBind connAry[length];
416
417 418 419
420 UInt16 interruptTable[NUM_CORES];
421
422 423 424
425 DriverIsr isrDispatchTable[NUM_CORES];
426 };
427 }