]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - ipc/ipcdev.git/blob - packages/ti/sdo/ipc/family/vayu/NotifySetup.c
2f7710af638c7d005166f7f504a2398c346b9d4e
[ipc/ipcdev.git] / packages / ti / sdo / ipc / family / vayu / NotifySetup.c
1 /*
2  * Copyright (c) 2012-2014 Texas Instruments Incorporated - http://www.ti.com
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  */
33 /*
34  *  ======== NotifySetup.c ========
35  */
36 #include <xdc/std.h>
37 #include <xdc/runtime/Assert.h>
38 #include <xdc/runtime/Error.h>
39 #include <xdc/runtime/Startup.h>
41 #include <ti/sdo/ipc/_Notify.h>
42 #include <ti/sdo/ipc/Ipc.h>
43 #include <ti/sdo/ipc/family/vayu/NotifyDriverMbx.h>
44 #include <ti/sdo/ipc/notifyDrivers/NotifyDriverShm.h>
45 #include <ti/sdo/utils/_MultiProc.h>
47 #include <ti/sysbios/family/c64p/EventCombiner.h>
48 #include <ti/sysbios/family/c64p/Hwi.h>
49 #include <ti/sysbios/family/shared/vayu/IntXbar.h>
51 #include "package/internal/NotifySetup.xdc.h"
54 #define EVENT_GROUP_SIZE 32
56 /* register access methods */
57 #define REG16(A)        (*(volatile UInt16 *)(A))
58 #define REG32(A)        (*(volatile UInt32 *)(A))
60 /* ipc helper macros */
61 #define MAILBOX_REG_VAL(m) (0x1 << (2 * (m)))
63 #define VIRTID(procId) (NotifySetup_procIdTable[(procId)])
65 #define MBX_BASEADDR_IDX(idx) ((NotifySetup_mailboxTable[(idx)] >> 16) & 0xFFFF)
67 #define MBX_USER_IDX(idx) ((NotifySetup_mailboxTable[(idx)] >> 8) & 0xFF)
69 #define SUBMBX_IDX(idx) (NotifySetup_mailboxTable[(idx)] & 0xFF)
71 #define MAILBOX_ADDR(idx) \
72         (NotifySetup_mailboxBaseAddr[MBX_BASEADDR_IDX(idx)])
74 #define MAILBOX_STATUS(idx) \
75         (MAILBOX_ADDR((idx)) + 0xC0 + (0x4 * SUBMBX_IDX((idx))))
77 #define MAILBOX_IRQENABLE_SET(idx) \
78         (MAILBOX_ADDR((idx)) + 0x108 + (0x10 * MBX_USER_IDX((idx))))
80 #define MBOX_IRQ_ENABLE(idx) \
81     ((REG32(MAILBOX_IRQENABLE_SET((idx))) & \
82     MAILBOX_REG_VAL(SUBMBX_IDX((idx)))) != 0)
84 #define MBOX_MSG_COUNT(idx) (REG32(MAILBOX_STATUS((idx))))
87 /*
88  *************************************************************************
89  *                      Module functions
90  *************************************************************************
91  */
93 /*
94  *  ======== NotifySetup_Module_startup ========
95  */
96 Int NotifySetup_Module_startup(Int phase)
97 {
98 #if defined(xdc_target__isa_66)
100     extern cregister volatile UInt DNUM;
102     if (IntXbar_Module_startupDone()) {
103         if (DNUM == 0) {               /* DSP1 */
104             NotifySetup_module->interruptTable[6] = 57; // IPU1-0
105             NotifySetup_module->interruptTable[9] = 57; // IPU1-1
107             /* plug eve3 and eve4 mbxs only if eve3 and eve4 exists */
108             if ((MultiProc_getId("EVE3") != MultiProc_INVALIDID) ||
109                 (MultiProc_getId("EVE4") != MultiProc_INVALIDID)) {
110             }
112             /* plug mbx7 only if DSP2 or IPU2 exists */
113             if ((MultiProc_getId("DSP2") != MultiProc_INVALIDID) ||
114                 (MultiProc_getId("IPU2") != MultiProc_INVALIDID) ||
115                 (MultiProc_getId("IPU2-0") != MultiProc_INVALIDID)) {
116                 NotifySetup_module->interruptTable[7] = 60; // IPU2-0
117             }
119             /* plug mbx8 only if IPU2-1 exists */
120             if (MultiProc_getId("IPU2-1") != MultiProc_INVALIDID) {
121                 NotifySetup_module->interruptTable[10] = 61; // IPU2-1
122             }
123         }
124         else if (DNUM == 1) {          /* DSP2 */
125             NotifySetup_module->interruptTable[7] = 57; // IPU2-0
126             NotifySetup_module->interruptTable[10] = 57; // IPU2-1
128             /* plug eve3 and eve4 mbxs only if eve3 and eve4 exists */
129             if ((MultiProc_getId("EVE3") != MultiProc_INVALIDID) ||
130                 (MultiProc_getId("EVE4") != MultiProc_INVALIDID)) {
131             }
133             /* plug mbx7 only if DSP1 or IPU1 exists */
134             if ((MultiProc_getId("DSP1") != MultiProc_INVALIDID) ||
135                 (MultiProc_getId("IPU1") != MultiProc_INVALIDID) ||
136                 (MultiProc_getId("IPU1-0") != MultiProc_INVALIDID)) {
137                 NotifySetup_module->interruptTable[6] = 60; // IPU1-0
138             }
140             /* plug mbx8 only if IPU1-1 exists */
141             if (MultiProc_getId("IPU1-1") != MultiProc_INVALIDID) {
142                 NotifySetup_module->interruptTable[9] = 61; // IPU1-1
143             }
144         }
145         return (Startup_DONE);
146     }
148     return (Startup_NOTDONE);
150 #elif defined(xdc_target__isa_arp32)
152     /* TODO */
153     return (Startup_DONE);
155 #elif defined(xdc_target__isa_v7M4)
157     /* TODO */
158     return (Startup_DONE);
160 #elif defined(xdc_target__isa_v7A15)
162     /* TODO */
163     return (Startup_DONE);
165 #else
166 #error Invalid target
167 #endif
170 /*!
171  *  ======== NotifySetup_attach ========
172  *  Create driver instance specified at config time.
173  *
174  *  This functions is generated by the NotifySetup.xdt template.
175  */
177 /*!
178  *  ======== NotifySetup_sharedMemReq ========
179  *  Compute how much shared memory is required by the driver.
180  *
181  *  This functions is generated by the NotifySetup.xdt template.
182  */
184 /*!
185  * ======== NotifySetup_numIntLines ========
186  * Return number of available interrupt lines to the current processor.
187  */
188 UInt16 NotifySetup_numIntLines(UInt16 remoteProcId)
190     return (1);
193 /*
194  *  ======== NotifySetup_driverType ========
195  *  Find driver type for given connection.
196  *
197  *  Search the connection array for the given remote processor. If
198  *  found, return the requested notify driver type.
199  */
200 NotifySetup_Driver NotifySetup_driverType(UInt16 remoteProcId)
202     Int i;
203     NotifySetup_Driver driver = NotifySetup_Driver_SHAREDMEMORY;
205     /* look for remote processor in connection array */
206     for (i = 0; i < NotifySetup_module->connAry.length; i++) {
207         if (remoteProcId == NotifySetup_module->connAry.elem[i].procId) {
208             driver = NotifySetup_module->connAry.elem[i].driver;
209             break;
210         }
211     }
213     return(driver);
216 /*
217  *  ======== NotifySetup_plugHwi ========
218  */
219 Void NotifySetup_plugHwi(UInt16 remoteProcId, Int cpuIntrNum,
220         NotifySetup_DriverIsr isr)
222     UInt        key;
223     Hwi_Params  hwiParams;
224     UInt16      virtId;
225     Int         eventId;
226     UInt        combinedEventId;
228     /* disable global interrupts (TODO: should be a gated module) */
229     key = Hwi_disable();
231     /* map processor id to virtual id */
232     virtId = VIRTID(remoteProcId);
234     /* save driver isr in dispatch table */
235     NotifySetup_module->isrDispatchTable[virtId] = isr;
237     /* program the event dispatcher */
238     eventId = NotifySetup_module->interruptTable[virtId];
239     EventCombiner_dispatchPlug(eventId, NotifySetup_dispatchIsr, eventId, TRUE);
241     /* make sure the interrupt is plugged only once */
242     NotifySetup_module->numPlugged++;
244     if (NotifySetup_module->numPlugged == 1) {
245         combinedEventId = eventId / EVENT_GROUP_SIZE;
247         Hwi_Params_init(&hwiParams);
248         hwiParams.eventId = combinedEventId;
249         hwiParams.arg = combinedEventId;
250         hwiParams.enableInt = TRUE;
252         Hwi_create(cpuIntrNum,
253                 &ti_sysbios_family_c64p_EventCombiner_dispatch,
254                 &hwiParams, NULL);
256         Hwi_enableInterrupt(cpuIntrNum);
257     }
259     /* restore global interrupts */
260     Hwi_restore(key);
263 /*
264  *  ======== NotifySetup_unplugHwi ========
265  */
266 Void NotifySetup_unplugHwi(UInt16 remoteProcId, Int cpuIntrNum)
268     UInt        key;
269     Hwi_Handle  hwi;
270     UInt16      virtId;
271     Int         eventId;
273     /* disable global interrupts (TODO: should be a gated module) */
274     key = Hwi_disable();
276     /* unplug interrupt if last user */
277     NotifySetup_module->numPlugged--;
279     if (NotifySetup_module->numPlugged == 0) {
280         hwi= Hwi_getHandle(cpuIntrNum);
281         Hwi_delete(&hwi);
282     }
284     /* unprogram the event dispatcher */
285     virtId = VIRTID(remoteProcId);
286     eventId = NotifySetup_module->interruptTable[virtId];
287     EventCombiner_disableEvent(eventId);
289     /* restore global interrupts */
290     Hwi_restore(key);
293 /*
294  *  ======== NotifySetup_Shm_attach ========
295  */
296 Int NotifySetup_Shm_attach(UInt16 remoteProcId, Ptr sharedAddr)
298     NotifyDriverShm_Params notifyShmParams;
299     NotifyDriverShm_Handle shmDrvHandle;
300     ti_sdo_ipc_Notify_Handle notifyHandle;
301     Int status = Notify_S_SUCCESS;
302     Error_Block eb;
304     Error_init(&eb);
306     NotifyDriverShm_Params_init(&notifyShmParams);
307     notifyShmParams.sharedAddr = sharedAddr;
308     notifyShmParams.remoteProcId  = remoteProcId;
310     /* Set the intVectorId if on the DSP */
311     if ((MultiProc_self() == NotifySetup_dsp1ProcId) ||
312         (MultiProc_self() == NotifySetup_dsp2ProcId)) {
313             notifyShmParams.intVectorId = NotifySetup_dspIntVectId;
314     }
316     /* Set the intVectorId if on the EVE */
317     if ((MultiProc_self() == NotifySetup_eve1ProcId) ||
318         (MultiProc_self() == NotifySetup_eve2ProcId) ||
319         (MultiProc_self() == NotifySetup_eve3ProcId) ||
320         (MultiProc_self() == NotifySetup_eve4ProcId)) {
322         if (VIRTID(remoteProcId) < 4) {
323             notifyShmParams.intVectorId = NotifySetup_eveIntVectId_INTC1;
324         }
325         else {
326             notifyShmParams.intVectorId = NotifySetup_eveIntVectId_INTC0;
327         }
328     }
330     /* create the notify driver instance */
331     shmDrvHandle = NotifyDriverShm_create(&notifyShmParams, &eb);
333     if (shmDrvHandle == NULL) {
334         return (Notify_E_FAIL);
335     }
337     /* create the front-end notify instance */
338     notifyHandle = ti_sdo_ipc_Notify_create(
339             NotifyDriverShm_Handle_upCast(shmDrvHandle), remoteProcId, 0,
340             NULL, &eb);
342     if (notifyHandle == NULL) {
343         NotifyDriverShm_delete(&shmDrvHandle);
344         status = Notify_E_FAIL;
345     }
347     return (status);
350 /*!
351  *  ======== NotifySetup_Shm_sharedMemReq ========
352  */
353 SizeT NotifySetup_Shm_sharedMemReq(UInt16 remoteProcId, Ptr sharedAddr)
355     SizeT memReq;
356     NotifyDriverShm_Params notifyShmParams;
358     NotifyDriverShm_Params_init(&notifyShmParams);
359     notifyShmParams.sharedAddr = sharedAddr;
361     memReq = NotifyDriverShm_sharedMemReq(&notifyShmParams);
363     return (memReq);
366 /*
367  *  ======== NotifySetup_Mbx_attach ========
368  */
369 Int NotifySetup_Mbx_attach(UInt16 remoteProcId, Ptr sharedAddr)
371     Int status = Notify_S_SUCCESS;
372     NotifyDriverMbx_Params params;
373     NotifyDriverMbx_Handle driver;
374     ti_sdo_ipc_Notify_Handle notify;
375     Error_Block eb;
377     Error_init(&eb);
379     NotifyDriverMbx_Params_init(&params);
380     params.remoteProcId = remoteProcId;
382     /* set the intVectorId if on the DSP */
383     if ((MultiProc_self() == NotifySetup_dsp1ProcId) ||
384         (MultiProc_self() == NotifySetup_dsp2ProcId)) {
385         params.intVectorId = NotifySetup_dspIntVectId;
386     }
388     /* set the intVectorId if on the EVE */
389     if ((MultiProc_self() == NotifySetup_eve1ProcId) ||
390         (MultiProc_self() == NotifySetup_eve2ProcId) ||
391         (MultiProc_self() == NotifySetup_eve3ProcId) ||
392         (MultiProc_self() == NotifySetup_eve4ProcId)) {
394         if (VIRTID(remoteProcId) < 4) {
395             params.intVectorId = NotifySetup_eveIntVectId_INTC1;
396         }
397         else {
398             params.intVectorId = NotifySetup_eveIntVectId_INTC0;
399         }
400     }
402     /* create the notify driver instance */
403     driver = NotifyDriverMbx_create(&params, &eb);
405     if (driver == NULL) {
406         return(Notify_E_FAIL);
407     }
409     /* create the front-end notify instance */
410     notify = ti_sdo_ipc_Notify_create(NotifyDriverMbx_Handle_upCast(driver),
411             remoteProcId, 0, NULL, &eb);
413     if (notify == NULL) {
414         NotifyDriverMbx_delete(&driver);
415         status = Notify_E_FAIL;
416     }
418     return(status);
421 /*!
422  *  ======== NotifySetup_Mbx_sharedMemReq ========
423  */
424 SizeT NotifySetup_Mbx_sharedMemReq(UInt16 remoteProcId, Ptr sharedAddr)
426     SizeT memReq = 0;
428     return (memReq);
431 /*
432  *************************************************************************
433  *                       Internal functions
434  *************************************************************************
435  */
437 /*
438  *  ======== NotifySetup_dispatchIsr ========
439  *  arg = eventId
440  */
441 Void NotifySetup_dispatchIsr(UArg arg)
443     Int numProcessed;
444     UInt16 idx;
445     UInt16 srcVirtId;
446     UInt16 dstVirtId = VIRTID(MultiProc_self());
447     NotifySetup_DriverIsr driver;
449     do {
450         numProcessed = 0;
452         for (srcVirtId = 0; srcVirtId < NotifySetup_NUM_CORES; srcVirtId++) {
454             /* should not receive interrupts from myself */
455             if (srcVirtId == dstVirtId) {
456                 continue;
457             }
459             /* check if processor would raise the given hardware eventId */
460             if (arg == NotifySetup_module->interruptTable[srcVirtId]) {
462                 /* compute table index for given source and destination */
463                 idx = (srcVirtId * NotifySetup_NUM_CORES) + dstVirtId;
465                 /* check if submailbox has a message and irq is enabled */
466                 if ((MBOX_MSG_COUNT(idx) != 0) && MBOX_IRQ_ENABLE(idx)) {
468                     /* invoke driver isr to deliver the event */
469                     driver = NotifySetup_module->isrDispatchTable[srcVirtId];
470                     (*driver)(idx);
472                     /* event has been delivered */
473                     numProcessed++;
474                 }
475             }
476         }
477     } while (numProcessed != 0);