From f696e052ae92a8a0c15d80c9ddf2eba79af38117 Mon Sep 17 00:00:00 2001 From: Ramsey Harris Date: Mon, 17 Feb 2014 14:14:54 -0800 Subject: [PATCH] SDOCM00106428 Notify mailbox driver support on DRA7xx (DSP, EVE) New NotifyDriverMbx module; initial implementation of notify mailbox driver on dsp and eve only. Added support for multiple notify driver configs in NotifySetup; requires new dispatch isr for notify events. The isr will dispatch to the appropriate driver (shm or mbx). Improved the NotifyDriverShm performance because it checks only the mailboxes which might have raised the given event instead of always checking all mailboxes. Added ROV view of NotifyDriverMbx. Added a mailbox tab which shows inbound and outbound mailbox status. Better ISA handling in source code and script code. Updated Build module with NotifyDriverMbx.c to include new driver in IPC product libraries for C66 and ARP32. --- packages/ti/sdo/ipc/Build.xs | 4 +- .../ti/sdo/ipc/family/vayu/InterruptArp32.c | 98 +-- .../ti/sdo/ipc/family/vayu/InterruptArp32.xdc | 20 +- .../ti/sdo/ipc/family/vayu/InterruptArp32.xs | 42 +- .../ti/sdo/ipc/family/vayu/InterruptDsp.c | 99 +-- .../ti/sdo/ipc/family/vayu/InterruptDsp.xdc | 42 +- .../ti/sdo/ipc/family/vayu/InterruptDsp.xs | 28 +- .../ti/sdo/ipc/family/vayu/NotifyDriverMbx.c | 643 ++++++++++++++++++ .../sdo/ipc/family/vayu/NotifyDriverMbx.xdc | 220 ++++++ .../ti/sdo/ipc/family/vayu/NotifyDriverMbx.xs | 309 +++++++++ packages/ti/sdo/ipc/family/vayu/NotifySetup.c | 497 +++++++++++++- .../ti/sdo/ipc/family/vayu/NotifySetup.xdc | 166 ++++- .../ti/sdo/ipc/family/vayu/NotifySetup.xdt | 97 +++ .../ti/sdo/ipc/family/vayu/NotifySetup.xs | 230 ++++++- packages/ti/sdo/ipc/family/vayu/TableInit.xs | 105 +-- packages/ti/sdo/ipc/family/vayu/package.bld | 5 +- packages/ti/sdo/ipc/family/vayu/package.xdc | 5 +- 17 files changed, 2270 insertions(+), 340 deletions(-) create mode 100644 packages/ti/sdo/ipc/family/vayu/NotifyDriverMbx.c create mode 100644 packages/ti/sdo/ipc/family/vayu/NotifyDriverMbx.xdc create mode 100644 packages/ti/sdo/ipc/family/vayu/NotifyDriverMbx.xs create mode 100644 packages/ti/sdo/ipc/family/vayu/NotifySetup.xdt diff --git a/packages/ti/sdo/ipc/Build.xs b/packages/ti/sdo/ipc/Build.xs index dd013b7..3287489 100644 --- a/packages/ti/sdo/ipc/Build.xs +++ b/packages/ti/sdo/ipc/Build.xs @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2014, Texas Instruments Incorporated + * Copyright (c) 2013-2014 Texas Instruments Incorporated - http://www.ti.com * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -397,6 +397,7 @@ var C66Sources = "ipc/gates/GateHWSem.c " + "ipc/family/tci663x/NotifyCircSetup.c " + "ipc/family/tci663x/NotifySetup.c " + "ipc/family/vayu/InterruptDsp.c " + + "ipc/family/vayu/NotifyDriverMbx.c " + "ipc/family/vayu/NotifySetup.c "; var C674Sources = @@ -515,6 +516,7 @@ var ARP32Sources = "ipc/family/c6a8149/NotifyCircSetup.c " + "ipc/family/c6a8149/InterruptEve.c " + "ipc/family/vayu/InterruptArp32.c " + + "ipc/family/vayu/NotifyDriverMbx.c " + "ipc/family/vayu/NotifySetup.c "; var cList = { diff --git a/packages/ti/sdo/ipc/family/vayu/InterruptArp32.c b/packages/ti/sdo/ipc/family/vayu/InterruptArp32.c index 6d706d1..8b0fdbe 100644 --- a/packages/ti/sdo/ipc/family/vayu/InterruptArp32.c +++ b/packages/ti/sdo/ipc/family/vayu/InterruptArp32.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2013, Texas Instruments Incorporated + * Copyright (c) 2012-2014 Texas Instruments Incorporated - http://www.ti.com * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -29,20 +29,21 @@ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ + /* * ======== InterruptArp32.c ======== * ARP32 mailbox based interrupt manager */ - #include #include #include #include -#include #include +#include #include +#include #include "package/internal/InterruptArp32.xdc.h" @@ -113,8 +114,7 @@ Void InterruptArp32_intEnable(UInt16 remoteProcId, IInterrupt_IntInfo *intInfo) * ======== InterruptArp32_intDisable ======== * Disables remote processor interrupt */ -Void InterruptArp32_intDisable(UInt16 remoteProcId, - IInterrupt_IntInfo *intInfo) +Void InterruptArp32_intDisable(UInt16 remoteProcId, IInterrupt_IntInfo *intInfo) { UInt16 index; @@ -127,13 +127,10 @@ Void InterruptArp32_intDisable(UInt16 remoteProcId, * ======== InterruptArp32_intRegister ======== */ Void InterruptArp32_intRegister(UInt16 remoteProcId, - IInterrupt_IntInfo *intInfo, - Fxn func, UArg arg) + IInterrupt_IntInfo *intInfo, Fxn func, UArg arg) { UInt key; UInt16 index; - UInt mbxIdx; - Hwi_Params hwiAttrs; Error_Block eb; InterruptArp32_FxnTable *table; @@ -161,31 +158,9 @@ Void InterruptArp32_intRegister(UInt16 remoteProcId, InterruptArp32_intClear(remoteProcId, intInfo); - if ((index == DSP1_ID) || (index == IPU1_ID) || (index == HOST_ID)) { - mbxIdx = 0; - } - else if ((index == DSP2_ID) || (index == IPU2_ID) || - (index == IPU1_1_ID) || (index == IPU2_1_ID)) { - mbxIdx = 1; - } - else if (index < InterruptArp32_NUM_EVES) { - mbxIdx = 2; - } - - /* Make sure the interrupt only gets plugged once */ - InterruptArp32_module->numPlugged[mbxIdx]++; - if (InterruptArp32_module->numPlugged[mbxIdx] == 1) { - /* Register interrupt to remote processor */ - Hwi_Params_init(&hwiAttrs); - hwiAttrs.arg = arg; - hwiAttrs.vectorNum = intInfo->intVectorId; - - Hwi_create(InterruptArp32_eveInterruptTable[index], - (Hwi_FuncPtr)InterruptArp32_intShmStub, - &hwiAttrs, - &eb); - Hwi_enableInterrupt(InterruptArp32_eveInterruptTable[index]); - } + /* plug the cpu interrupt */ + NotifySetup_plugHwi(remoteProcId, intInfo->intVectorId, + InterruptArp32_intShmStub); /* enable the mailbox and Hwi */ InterruptArp32_intEnable(remoteProcId, intInfo); @@ -201,41 +176,22 @@ Void InterruptArp32_intUnregister(UInt16 remoteProcId, IInterrupt_IntInfo *intInfo) { UInt16 index; - UInt mbxIdx; - Hwi_Handle hwiHandle; InterruptArp32_FxnTable *table; index = PROCID(remoteProcId); - if ((remoteProcId == DSP1_ID) || (remoteProcId == IPU1_ID) || - (remoteProcId == HOST_ID)) { - mbxIdx = 0; - } - else if ((remoteProcId == DSP2_ID) || (remoteProcId == IPU2_ID) || - (remoteProcId == IPU1_1_ID) || (remoteProcId == IPU2_1_ID)) { - mbxIdx = 1; - } - else if (remoteProcId < InterruptArp32_NUM_EVES) { - mbxIdx = 2; - } - - /* Disable the mailbox interrupt source */ + /* disable the mailbox interrupt source */ InterruptArp32_intDisable(remoteProcId, intInfo); - InterruptArp32_module->numPlugged[mbxIdx]--; - if (InterruptArp32_module->numPlugged[mbxIdx] == 0) { - /* Delete the Hwi */ - hwiHandle = Hwi_getHandle(InterruptArp32_eveInterruptTable[index]); - Hwi_delete(&hwiHandle); - } + /* unplug isr */ + NotifySetup_unplugHwi(remoteProcId, intInfo->intVectorId); /* Clear the FxnTable entry for the remote processor */ table = &(InterruptArp32_module->fxnTable[index]); table->func = NULL; - table->arg = 0; + table->arg = 0; } - /* * ======== InterruptArp32_intSend ======== * Send interrupt to the remote processor @@ -260,7 +216,6 @@ Void InterruptArp32_intSend(UInt16 remoteProcId, IInterrupt_IntInfo *intInfo, Hwi_restore(key); } - /* * ======== InterruptArp32_intPost ======== * Simulate an interrupt from a remote processor @@ -316,29 +271,12 @@ UInt InterruptArp32_intClear(UInt16 remoteProcId, IInterrupt_IntInfo *intInfo) /* * ======== InterruptArp32_intShmStub ======== */ -Void InterruptArp32_intShmStub(UArg arg) +Void InterruptArp32_intShmStub(UInt16 idx) { - UInt16 index; - UInt16 selfIdx; - UInt16 loopIdx; + UInt16 srcVirtId; InterruptArp32_FxnTable *table; - selfIdx = MultiProc_self(); - - for (loopIdx = 0; loopIdx < MultiProc_getNumProcsInCluster(); loopIdx++) { - - if (loopIdx == selfIdx) { - continue; - } - - index = MBX_TABLE_IDX(loopIdx, selfIdx); - - if ((REG32(MAILBOX_STATUS(index)) != 0) && - (REG32(MAILBOX_IRQENABLE_SET(index)) & - MAILBOX_REG_VAL(SUBMBX_IDX(index)))) { - /* call function with arg */ - table = &(InterruptArp32_module->fxnTable[PROCID(loopIdx)]); - (table->func)(table->arg); - } - } + srcVirtId = idx / InterruptArp32_NUM_CORES; + table = &(InterruptArp32_module->fxnTable[srcVirtId]); + (table->func)(table->arg); } diff --git a/packages/ti/sdo/ipc/family/vayu/InterruptArp32.xdc b/packages/ti/sdo/ipc/family/vayu/InterruptArp32.xdc index ed7246d..40d5c9a 100644 --- a/packages/ti/sdo/ipc/family/vayu/InterruptArp32.xdc +++ b/packages/ti/sdo/ipc/family/vayu/InterruptArp32.xdc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2013, Texas Instruments Incorporated + * Copyright (c) 2012-2014 Texas Instruments Incorporated - http://www.ti.com * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -29,10 +29,11 @@ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ + /* * ======== InterruptArp32.xdc ======== - * */ +package ti.sdo.ipc.family.vayu; import ti.sdo.utils.MultiProc; @@ -40,7 +41,6 @@ import ti.sdo.utils.MultiProc; * ======== InterruptArp32 ======== * ARP32 based interrupt manager */ - module InterruptArp32 inherits ti.sdo.ipc.notifyDrivers.IInterrupt { /* Total number of cores on Vayu SoC */ @@ -58,6 +58,8 @@ module InterruptArp32 inherits ti.sdo.ipc.notifyDrivers.IInterrupt /* Base address for the Mailbox subsystem */ config UInt32 mailboxBaseAddr[NUM_EVE_MBX + NUM_SYS_MBX]; +internal: + /* * Mailbox table for storing encoded Base Address, mailbox user Id, * and sub-mailbox index. @@ -68,8 +70,6 @@ module InterruptArp32 inherits ti.sdo.ipc.notifyDrivers.IInterrupt config UInt32 procIdTable[NUM_CORES]; -internal: - /*! Statically retrieve procIds to avoid doing this at runtime */ config UInt eve1ProcId = MultiProc.INVALIDID; config UInt eve2ProcId = MultiProc.INVALIDID; @@ -90,14 +90,14 @@ internal: } /*! Stub to be plugged for dsp-arp32 interrupts */ - Void intShmStub(UArg arg); + Void intShmStub(UInt16 idx); struct Module_State { - /* - * Create a function table of length 8 (Total number of cores in the - * System) for each EVE core. + + /* Interrupt isr dispatch table. This table is indexed + * by virtual processor ID. */ - FxnTable fxnTable[NUM_CORES]; + FxnTable fxnTable[NUM_CORES]; /* * numPlugged is used to track number of times the interrupt was diff --git a/packages/ti/sdo/ipc/family/vayu/InterruptArp32.xs b/packages/ti/sdo/ipc/family/vayu/InterruptArp32.xs index 8716ecb..66e250f 100644 --- a/packages/ti/sdo/ipc/family/vayu/InterruptArp32.xs +++ b/packages/ti/sdo/ipc/family/vayu/InterruptArp32.xs @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2013, Texas Instruments Incorporated + * Copyright (c) 2012-2014 Texas Instruments Incorporated - http://www.ti.com * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -29,26 +29,27 @@ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ + /* * ======== InterruptArp32.xs ======== - * */ - -var Hwi = null; -var Core = null; -var MultiProc = null; -var InterruptArp32 = null; +var InterruptArp32 = null; /* * ======== module$use ======== */ function module$use() { - Hwi = xdc.useModule("ti.sysbios.family.arp32.Hwi"); - MultiProc = xdc.useModule("ti.sdo.utils.MultiProc"); - Ipc = xdc.useModule("ti.sdo.ipc.Ipc"); - InterruptArp32 = xdc.useModule("ti.sdo.ipc.family.vayu.InterruptArp32"); - TableInit = xdc.useModule("ti.sdo.ipc.family.vayu.TableInit"); + var TableInit = xdc.useModule("ti.sdo.ipc.family.vayu.TableInit"); + var MultiProc = xdc.useModule("ti.sdo.utils.MultiProc"); + InterruptArp32 = this; + + xdc.useModule('xdc.runtime.Assert'); + xdc.useModule('xdc.runtime.Error'); + xdc.useModule("ti.sysbios.family.arp32.Hwi"); + xdc.useModule("ti.sdo.ipc.Ipc"); + xdc.useModule('ti.sdo.ipc.family.vayu.NotifySetup'); + xdc.useModule('ti.sdo.ipc.notifyDrivers.IInterrupt'); /* Initialize procIdTable */ TableInit.initProcId(InterruptArp32); @@ -104,7 +105,7 @@ function module$use() /* * In case of a spec change, follow the process shown below: * 1. Update the mailboxBaseAddr Table. - * 2. Update the dspInterruptTable. + * 2. Update the eveInterruptTable. * 3. Update Virtual Index assignment. * 4. Update NUMCORES, NUMEVES and EVEMBX2BASEIDX variables * in order to correctly intialize the mailboxTable. @@ -115,17 +116,16 @@ function module$use() * ======== module$static$init ======== * Initialize module values. */ -function module$static$init(mod, params) +function module$static$init(state, mod) { - var idx; - var remoteProcId; + var i; - for (remoteProcId=0; remoteProcId < InterruptArp32.procIdTable.length; remoteProcId++) { - mod.fxnTable[remoteProcId].func = null; - mod.fxnTable[remoteProcId].arg = 0; + for (i = 0; i < mod.procIdTable.length; i++) { + state.fxnTable[i].func = null; + state.fxnTable[i].arg = 0; } - for (idx = 0; idx < (InterruptArp32.NUM_EVE_MBX/InterruptArp32.NUM_EVES); idx++) { - mod.numPlugged[idx] = 0; + for (i = 0; i < (mod.NUM_EVE_MBX/mod.NUM_EVES); i++) { + state.numPlugged[i] = 0; } } diff --git a/packages/ti/sdo/ipc/family/vayu/InterruptDsp.c b/packages/ti/sdo/ipc/family/vayu/InterruptDsp.c index 406558e..907f85c 100644 --- a/packages/ti/sdo/ipc/family/vayu/InterruptDsp.c +++ b/packages/ti/sdo/ipc/family/vayu/InterruptDsp.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2014, Texas Instruments Incorporated + * Copyright (c) 2012-2014 Texas Instruments Incorporated - http://www.ti.com * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -29,24 +29,23 @@ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ + /* * ======== InterruptDsp.c ======== * Mailbox based interrupt manager */ #include -#include -#include #include +#include -#include - -#include #include +#include +#include -#include #include - +#include #include +#include #include "package/internal/InterruptDsp.xdc.h" @@ -198,17 +197,14 @@ Void InterruptDsp_intDisable(UInt16 remoteProcId, IInterrupt_IntInfo *intInfo) * ======== InterruptDsp_intRegister ======== */ Void InterruptDsp_intRegister(UInt16 remoteProcId, IInterrupt_IntInfo *intInfo, - Fxn func, UArg arg) + Fxn func, UArg arg) { UInt key; - UInt eventId; - UInt combinedEventId; Int index; - Hwi_Params params; InterruptDsp_FxnTable *table; Assert_isTrue(((remoteProcId < MultiProc_getNumProcsInCluster()) && - (remoteProcId != MultiProc_self())), ti_sdo_ipc_Ipc_A_internal); + (remoteProcId != MultiProc_self())), ti_sdo_ipc_Ipc_A_internal); index = PROCID(remoteProcId); @@ -221,28 +217,9 @@ Void InterruptDsp_intRegister(UInt16 remoteProcId, IInterrupt_IntInfo *intInfo, InterruptDsp_intClear(remoteProcId, intInfo); - /* Make sure the interrupt only gets plugged once */ - eventId = InterruptDsp_module->interruptTable[index]; - - InterruptDsp_module->numPlugged++; - - if (InterruptDsp_module->numPlugged == 1) { - EventCombiner_dispatchPlug(eventId, - (Hwi_FuncPtr)InterruptDsp_intShmStub, eventId, TRUE); - - Hwi_Params_init(¶ms); - combinedEventId = eventId / EVENT_GROUP_SIZE; - params.eventId = combinedEventId; - params.arg = combinedEventId; - params.enableInt = TRUE; - Hwi_create(intInfo->intVectorId, &ti_sysbios_family_c64p_EventCombiner_dispatch, - ¶ms, NULL); - Hwi_enableInterrupt(intInfo->intVectorId); - } - else { - EventCombiner_dispatchPlug(eventId, - (Hwi_FuncPtr)InterruptDsp_intShmStub, eventId, TRUE); - } + /* plug the cpu interrupt */ + NotifySetup_plugHwi(remoteProcId, intInfo->intVectorId, + InterruptDsp_intShmStub); /* Enable the mailbox interrupt to the DSP */ InterruptDsp_intEnable(remoteProcId, intInfo); @@ -257,31 +234,19 @@ Void InterruptDsp_intRegister(UInt16 remoteProcId, IInterrupt_IntInfo *intInfo, Void InterruptDsp_intUnregister(UInt16 remoteProcId, IInterrupt_IntInfo *intInfo) { - Hwi_Handle hwiHandle; - Int index; - UInt eventId; + Int index; InterruptDsp_FxnTable *table; Assert_isTrue(((remoteProcId < MultiProc_getNumProcsInCluster()) && - (remoteProcId != MultiProc_self())), ti_sdo_ipc_Ipc_A_internal); + (remoteProcId != MultiProc_self())), ti_sdo_ipc_Ipc_A_internal); index = PROCID(remoteProcId); - /* Disable the mailbox interrupt source */ + /* disable the mailbox interrupt source */ InterruptDsp_intDisable(remoteProcId, intInfo); - /* Make sure the interrupt only gets plugged once */ - eventId = InterruptDsp_module->interruptTable[index]; - - InterruptDsp_module->numPlugged--; - - EventCombiner_disableEvent(eventId); - - if (InterruptDsp_module->numPlugged == 0) { - /* Delete the Hwi */ - hwiHandle = Hwi_getHandle(intInfo->intVectorId); - Hwi_delete(&hwiHandle); - } + /* unplug isr and unprogram the event dispatcher */ + NotifySetup_unplugHwi(remoteProcId, intInfo->intVectorId); table = &(InterruptDsp_module->fxnTable[index]); table->func = NULL; @@ -363,32 +328,12 @@ UInt InterruptDsp_intClear(UInt16 remoteProcId, IInterrupt_IntInfo *intInfo) /* * ======== InterruptDsp_intShmStub ======== */ -Void InterruptDsp_intShmStub(UArg arg) +Void InterruptDsp_intShmStub(UInt16 idx) { - UInt16 index; - UInt16 selfIdx; - UInt16 loopIdx; + UInt16 srcVirtId; InterruptDsp_FxnTable *table; - selfIdx = MultiProc_self(); - - /* - * Loop through each Sub-mailbox to determine which one generated - * interrupt. - */ - for (loopIdx = 0; loopIdx < MultiProc_getNumProcsInCluster(); loopIdx++) { - - if (loopIdx == selfIdx) { - continue; - } - - index = MBX_TABLE_IDX(loopIdx, selfIdx); - - if ((REG32(MAILBOX_STATUS(index)) != 0) && - (REG32(MAILBOX_IRQENABLE_SET_DSP(index)) & - MAILBOX_REG_VAL(SUBMBX_IDX(index)))) { - table = &(InterruptDsp_module->fxnTable[PROCID(loopIdx)]); - (table->func)(table->arg); - } - } + srcVirtId = idx / InterruptDsp_NUM_CORES; + table = &(InterruptDsp_module->fxnTable[srcVirtId]); + (table->func)(table->arg); } diff --git a/packages/ti/sdo/ipc/family/vayu/InterruptDsp.xdc b/packages/ti/sdo/ipc/family/vayu/InterruptDsp.xdc index a52b4f5..69a2479 100644 --- a/packages/ti/sdo/ipc/family/vayu/InterruptDsp.xdc +++ b/packages/ti/sdo/ipc/family/vayu/InterruptDsp.xdc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2013, Texas Instruments Incorporated + * Copyright (c) 2012-2014 Texas Instruments Incorporated - http://www.ti.com * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -29,17 +29,19 @@ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ + /* * ======== InterruptDsp.xdc ======== */ +package ti.sdo.ipc.family.vayu; import ti.sdo.utils.MultiProc; +import xdc.rov.ViewInfo; /*! * ======== InterruptDsp ======== * Vayu/DSP interrupt manager */ - @ModuleStartup module InterruptDsp inherits ti.sdo.ipc.notifyDrivers.IInterrupt @@ -54,19 +56,19 @@ module InterruptDsp inherits ti.sdo.ipc.notifyDrivers.IInterrupt }; /*! @_nodoc */ - @Facet - metaonly config xdc.rov.ViewInfo.Instance rovViewInfo = - xdc.rov.ViewInfo.create({ - viewMap: [ - ['IncomingInterrupts', - { - type: xdc.rov.ViewInfo.MODULE_DATA, - viewInitFxn: 'viewInitInterrupt', - structName: 'InterruptDataView' - } - ], - ] - }); +// @Facet +// metaonly config xdc.rov.ViewInfo.Instance rovViewInfo = +// xdc.rov.ViewInfo.create({ +// viewMap: [ +// ['IncomingInterrupts', +// { +// type: xdc.rov.ViewInfo.MODULE_DATA, +// viewInitFxn: 'viewInitInterrupt', +// structName: 'InterruptDataView' +// } +// ], +// ] +// }); /* Total number of cores on Vayu SoC */ const UInt8 NUM_CORES = 11; @@ -119,7 +121,7 @@ internal: * ======== intShmStub ======== * Stub to be plugged */ - Void intShmStub(UArg arg); + Void intShmStub(UInt16 idx); struct Module_State { /* @@ -129,12 +131,8 @@ internal: FxnTable fxnTable[NUM_CORES]; /* - * Number of numPlugged counters is equal to the number of combined - * events used by the mailbox interrupts. - */ - UInt16 numPlugged; /* # of times the interrupt was registered */ - - /* table of interrupt event ids use to communicate with this proc */ + * Interrupt event IDs used to communicate with this processor. + * Table is indexed by virtual processor ID. */ UInt16 interruptTable[NUM_CORES]; }; } diff --git a/packages/ti/sdo/ipc/family/vayu/InterruptDsp.xs b/packages/ti/sdo/ipc/family/vayu/InterruptDsp.xs index 75897ed..787964c 100644 --- a/packages/ti/sdo/ipc/family/vayu/InterruptDsp.xs +++ b/packages/ti/sdo/ipc/family/vayu/InterruptDsp.xs @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2013, Texas Instruments Incorporated + * Copyright (c) 2012-2014 Texas Instruments Incorporated - http://www.ti.com * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -29,24 +29,29 @@ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ + /* * ======== InterruptDsp.xs ======== */ - -var Hwi = null; -var InterruptDsp = null; +var InterruptDsp = null; /* * ======== module$use ======== */ function module$use() { - Hwi = xdc.useModule("ti.sysbios.family.c64p.Hwi"); - EventCombiner = xdc.useModule("ti.sysbios.family.c64p.EventCombiner"); - Ipc = xdc.useModule("ti.sdo.ipc.Ipc"); - InterruptDsp = xdc.useModule("ti.sdo.ipc.family.vayu.InterruptDsp"); - Xbar = xdc.useModule("ti.sysbios.family.shared.vayu.IntXbar"); - TableInit = xdc.useModule("ti.sdo.ipc.family.vayu.TableInit"); + /* load modules needed in meta domain and in target domain */ + var TableInit = xdc.useModule("ti.sdo.ipc.family.vayu.TableInit"); + InterruptDsp = this; + xdc.useModule('xdc.runtime.Assert'); + xdc.useModule('xdc.runtime.Startup'); + xdc.useModule('ti.sysbios.family.c64p.EventCombiner'); + xdc.useModule('ti.sysbios.family.c64p.Hwi'); + xdc.useModule('ti.sysbios.family.shared.vayu.IntXbar'); + xdc.useModule('ti.sdo.ipc.Ipc'); + xdc.useModule('ti.sdo.ipc.family.vayu.NotifySetup'); + xdc.useModule('ti.sdo.ipc.notifyDrivers.IInterrupt'); + xdc.useModule('ti.sdo.utils.MultiProc'); /* Initialize procIdTable */ TableInit.initProcId(InterruptDsp); @@ -107,7 +112,4 @@ function module$static$init(mod, params) mod.interruptTable[7] = 0; /* IPU2 -> DSP1 or DSP2 */ mod.interruptTable[9] = 0; /* IPU1-1 -> DSP1 or DSP2 */ mod.interruptTable[10] = 0; /* IPU2-1 -> DSP1 or DSP2 */ - - /* Intialize numPlugged */ - mod.numPlugged = 0; } diff --git a/packages/ti/sdo/ipc/family/vayu/NotifyDriverMbx.c b/packages/ti/sdo/ipc/family/vayu/NotifyDriverMbx.c new file mode 100644 index 0000000..aa63a36 --- /dev/null +++ b/packages/ti/sdo/ipc/family/vayu/NotifyDriverMbx.c @@ -0,0 +1,643 @@ +/* + * Copyright (c) 2014 Texas Instruments Incorporated - http://www.ti.com + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of Texas Instruments Incorporated nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * ======== NotifyDriverMbx.c ======== + */ +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "package/internal/NotifyDriverMbx.xdc.h" + +/* Bit mask operations */ +#define SET_BIT(num,pos) ((num) |= (1u << (pos))) +#define CLEAR_BIT(num,pos) ((num) &= ~(1u << (pos))) +#define TEST_BIT(num,pos) ((num) & (1u << (pos))) + +/* register access methods */ +#define REG16(A) (*(volatile UInt16 *)(A)) +#define REG32(A) (*(volatile UInt32 *)(A)) + +#define MAILBOX_FIFOLENGTH 4 +#define PROCID(idx) (NotifyDriverMbx_procIdTable[idx]) + +#define MBX_BASEADDR_IDX(idx) \ + ((NotifyDriverMbx_mailboxTable[idx] >> 16) & 0xFFFF) + +#define MAILBOX_ADDR(idx) \ + (NotifyDriverMbx_mailboxBaseAddr[MBX_BASEADDR_IDX(idx)]) + +#define MBX_TABLE_IDX(src, dst) \ + ((PROCID(src) * NotifyDriverMbx_NUM_CORES) + PROCID(dst)) + +#define SUBMBX_IDX(idx) (NotifyDriverMbx_mailboxTable[idx] & 0xFF) + +#define MBX_USER_IDX(idx) ((NotifyDriverMbx_mailboxTable[idx] >> 8) & 0xFF) + +#define MAILBOX_REG_VAL(m) (0x1 << (2 * m)) + +#define MAILBOX_MESSAGE(idx) \ + (MAILBOX_ADDR(idx) + 0x40 + (0x4 * SUBMBX_IDX(idx))) + +#define MAILBOX_STATUS(idx) \ + (MAILBOX_ADDR(idx) + 0xC0 + (0x4 * SUBMBX_IDX(idx))) + +#define MAILBOX_IRQSTATUS_CLR(idx) \ + (MAILBOX_ADDR(idx) + 0x104 + (0x10 * MBX_USER_IDX(idx))) + +#define MAILBOX_IRQENABLE_SET(idx) \ + (MAILBOX_ADDR(idx) + 0x108 + (0x10 * MBX_USER_IDX(idx))) + +#define MAILBOX_IRQENABLE_CLR(idx) \ + (MAILBOX_ADDR(idx) + 0x10C + (0x10 * MBX_USER_IDX(idx))) + +#define MAILBOX_EOI_REG(idx) (MAILBOX_ADDR(idx) + 0x140) + +#define EVENT_GROUP_SIZE 32 + +/* empty the mailbox for the given index, clear its interrupt */ +#define MAILBOX_INIT(idx) \ + while (REG32(MAILBOX_STATUS(idx)) != 0) { \ + REG32(MAILBOX_MESSAGE(idx)); \ + } \ + REG32(MAILBOX_IRQSTATUS_CLR(idx)) = MAILBOX_REG_VAL(SUBMBX_IDX(idx)); + +/* + ************************************************************************* + * Module functions + ************************************************************************* + */ + +/* + * ======== NotifyDriverMbx_Module_startup ======== + */ +Int NotifyDriverMbx_Module_startup(Int phase) +{ +#if defined(xdc_target__isaCompatible_64P) + + extern cregister volatile UInt DNUM; + + if (IntXbar_Module_startupDone()) { + /* connect mailbox interrupts at startup */ + if (DNUM == 0) { /* DSP1 */ + IntXbar_connect(24, 284); // eve1 mailbox 0 user 1 + IntXbar_connect(25, 293); // eve2 mailbox 0 user 1 + IntXbar_connect(26, 249); // system mailbox 5 user 0 + + NotifyDriverMbx_module->interruptTable[6] = 57; // IPU1-0 + NotifyDriverMbx_module->interruptTable[9] = 57; // IPU1-1 + + /* plug eve3 and eve4 mbxs only if eve3 and eve4 exists */ + if ((MultiProc_getId("EVE3") != MultiProc_INVALIDID) || + (MultiProc_getId("EVE4") != MultiProc_INVALIDID)) { + IntXbar_connect(27, 302); // eve3 mailbox 0 user 1 + IntXbar_connect(28, 311); // eve4 mailbox 0 user 1 + } + + /* plug mbx7 only if DSP2 or IPU2 exists */ + if ((MultiProc_getId("DSP2") != MultiProc_INVALIDID) || + (MultiProc_getId("IPU2") != MultiProc_INVALIDID) || + (MultiProc_getId("IPU2-0") != MultiProc_INVALIDID)) { + IntXbar_connect(29, 257); // system mailbox 7 user 0 + NotifyDriverMbx_module->interruptTable[7] = 60; // IPU2-0 + } + + /* plug mbx8 only if IPU2-1 exists */ + if (MultiProc_getId("IPU2-1") != MultiProc_INVALIDID) { + IntXbar_connect(30, 261); // system mailbox 8 user 0 + NotifyDriverMbx_module->interruptTable[10] = 61; // IPU2-1 + } + } + else if (DNUM == 1) { /* DSP2 */ + IntXbar_connect(24, 287); // eve1 mailbox 1 user 1 + IntXbar_connect(25, 296); // eve2 mailbox 1 user 1 + IntXbar_connect(26, 253); // system mailbox 6 user 0 + + NotifyDriverMbx_module->interruptTable[7] = 57; // IPU2-0 + NotifyDriverMbx_module->interruptTable[10] = 57; // IPU2-1 + + /* plug eve3 and eve4 mbxs only if eve3 and eve4 exists */ + if ((MultiProc_getId("EVE3") != MultiProc_INVALIDID) || + (MultiProc_getId("EVE4") != MultiProc_INVALIDID)) { + IntXbar_connect(27, 305); // eve3 mailbox 1 user 1 + IntXbar_connect(28, 314); // eve4 mailbox 1 user 1 + } + + /* plug mbx7 only if DSP1 or IPU1 exists */ + if ((MultiProc_getId("DSP1") != MultiProc_INVALIDID) || + (MultiProc_getId("IPU1") != MultiProc_INVALIDID) || + (MultiProc_getId("IPU1-0") != MultiProc_INVALIDID)) { + IntXbar_connect(29, 258); // system mailbox 7 user 1 + NotifyDriverMbx_module->interruptTable[6] = 60; // IPU1-0 + } + + /* plug mbx8 only if IPU1-1 exists */ + if (MultiProc_getId("IPU1-1") != MultiProc_INVALIDID) { + IntXbar_connect(30, 262); // system mailbox 8 user 1 + NotifyDriverMbx_module->interruptTable[9] = 61; // IPU1-1 + } + } + return (Startup_DONE); + } + + return (Startup_NOTDONE); + +#elif defined(xdc_target__isaCompatible_arp32) + + /* nothing to do on this processor */ + return (Startup_DONE); + +#elif defined(xdc_target__isaCompatible_v7M) + + /* TODO */ + return (Startup_DONE); + +#elif defined(xdc_target__isaCompatible_v7A) + + /* TODO */ + return (Startup_DONE); + +#else +#error Invalid target +#endif +} + +/* + ************************************************************** + * Instance functions + ************************************************************** + */ + +/* + * ======== NotifyDriverMbx_Instance_init ======== + */ +Void NotifyDriverMbx_Instance_init(NotifyDriverMbx_Object *obj, + const NotifyDriverMbx_Params *params) +{ + UInt key; + UInt16 selfVirtId; + UInt16 index; + + Assert_isTrue((params->remoteProcId != MultiProc_INVALIDID) && + (params->remoteProcId != MultiProc_self()), + ti_sdo_ipc_Ipc_A_invParam); + + /* TODO: this check is weak */ + if (params->remoteProcId >= MultiProc_getNumProcessors() || + params->remoteProcId == MultiProc_INVALIDID) { + return; /* keep Coverity happy */ + } + + obj->evtRegMask = 0; + obj->notifyHandle = NULL; + obj->remoteProcId = params->remoteProcId; + obj->remoteVirtId = PROCID(params->remoteProcId); + obj->cpuIntrNum = params->intVectorId; + + /* disable global interrupts */ + key = Hwi_disable(); + + /* clear mailbox of any old messages */ + selfVirtId = PROCID(MultiProc_self()); + index = (selfVirtId * NotifyDriverMbx_NUM_CORES) + obj->remoteVirtId; + MAILBOX_INIT(index); + + /* must use processor virtual ID to store driver handle in table */ + NotifyDriverMbx_module->drvHandles[obj->remoteVirtId] = obj; + + /* plug the cpu interrupt */ + NotifySetup_plugHwi(params->remoteProcId, params->intVectorId, + NotifyDriverMbx_isr); + + /* enable the mailbox interrupt from the remote core */ + NotifyDriverMbx_enable(obj); + + /* restore global interrupts */ + Hwi_restore(key); +} + +/* + * ======== NotifyDriverMbx_Instance_finalize ======== + */ +Void NotifyDriverMbx_Instance_finalize(NotifyDriverMbx_Object *obj) +{ + + /* disable the mailbox interrupt source */ + NotifyDriverMbx_disable(obj); + + /* unplug isr and unprogram the event dispatcher */ + NotifySetup_unplugHwi(obj->remoteProcId, obj->cpuIntrNum); + + /* must use processor virtual ID to remove driver handle from table */ + NotifyDriverMbx_module->drvHandles[obj->remoteVirtId] = NULL; +} + +/* + * ======== NotifyDriverMbx_registerEvent ======== + */ +Void NotifyDriverMbx_registerEvent(NotifyDriverMbx_Object *obj, + UInt32 eventId) +{ + UInt hwiKey; + + /* + * Disable interrupt line to ensure that isr doesn't + * preempt registerEvent and encounter corrupt state + */ + hwiKey = Hwi_disable(); + + /* Set the 'registered' bit */ + SET_BIT(obj->evtRegMask, eventId); + + /* Restore the interrupt line */ + Hwi_restore(hwiKey); +} + +/* + * ======== NotifyDriverMbx_unregisterEvent ======== + */ +Void NotifyDriverMbx_unregisterEvent(NotifyDriverMbx_Object *obj, + UInt32 eventId) +{ + UInt hwiKey; + + /* + * Disable interrupt line to ensure that isr doesn't + * preempt registerEvent and encounter corrupt state + */ + hwiKey = Hwi_disable(); + + /* Clear the registered bit */ + CLEAR_BIT(obj->evtRegMask, eventId); + + /* Restore the interrupt line */ + Hwi_restore(hwiKey); +} + +/* + * ======== NotifyDriverMbx_sendEvent ======== + */ +/* + * PUT_NOTIFICATION will spin waiting for enough room in the mailbox FIFO + * to store the number of messages needed for the notification ('numMsgs'). + * If spinning is necesssary (i.e. if waitClear is TRUE and there isn't enough + * room in the FIFO) then PUT_NOTIFICATION will allow pre-emption while + * spinning. + * + * PUT_NOTIFICATION needs to prevent another local thread from writing to the + * same mailbox after the current thread has + * 1) determined that there is enough room to write the notification and + * 2) written the first of two messages to the mailbox. + * This is needed to respectively prevent + * 1) both threads from incorrectly assuming there is enough space in the FIFO + * for their own notifications + * 2) the interrupting thread from writing a notification between two + * two messages that need to be successivly written by the preempted thread. + * Therefore, the check for enough FIFO room and one/both mailbox write(s) + * should all occur atomically (i.e. with interrupts disabled) + */ +#define PUT_NOTIFICATION(idx) \ + key = Hwi_disable(); \ + while(MAILBOX_FIFOLENGTH - REG32(MAILBOX_STATUS(idx)) < numMsgs) { \ + Hwi_restore(key); \ + if (!waitClear) { \ + return (Notify_E_FAIL); \ + } \ + key = Hwi_disable(); \ + }; \ + REG32(MAILBOX_MESSAGE(idx)) = eventId + smallPayload; \ + if (smallPayload == 0xFFFFFFE0) { \ + REG32(MAILBOX_MESSAGE(idx)) = payload; \ + } \ + Hwi_restore(key); + +Int NotifyDriverMbx_sendEvent(NotifyDriverMbx_Object *obj, UInt32 eventId, + UInt32 payload, Bool waitClear) +{ + UInt16 selfVirtId = PROCID(MultiProc_self()); + UInt key, numMsgs; + UInt32 smallPayload; + UInt16 index; + + /* Decide if the payload is small enough to fit in the first mbx msg */ + if (payload < 0x7FFFFFF) { + smallPayload = (payload << 5); + numMsgs = 1; + } + else { + smallPayload = 0xFFFFFFE0; + numMsgs = 2; + } + +#if defined(xdc_target__isaCompatible_64P) || \ + defined(xdc_target__isaCompatible_arp32) + + index = (selfVirtId * NotifyDriverMbx_NUM_CORES) + obj->remoteVirtId; + PUT_NOTIFICATION(index); + +#elif defined(xdc_target__isaCompatible_v7M) + +// if (!(BIOS_smpEnabled) && (Core_getId())) { +// if (remoteProcId == NotifyDriverMbx_dspProcId) { +// PUT_NOTIFICATION(VPSS_TO_DSP) +// } +// else if (remoteProcId == NotifyDriverMbx_hostProcId) { +// PUT_NOTIFICATION(VPSS_TO_HOST) +// } +// else { +// PUT_NOTIFICATION(VPSS_TO_VIDEO) +// } +// } +// else { +// if (remoteProcId == NotifyDriverMbx_dspProcId) { +// PUT_NOTIFICATION(VIDEO_TO_DSP) +// } +// else if (remoteProcId == NotifyDriverMbx_hostProcId) { +// PUT_NOTIFICATION(VIDEO_TO_HOST) +// } +// else { +// PUT_NOTIFICATION(VIDEO_TO_VPSS) +// } +// } + +#elif defined(xdc_target__isaCompatible_v7A) + +// if (remoteProcId == NotifyDriverMbx_dspProcId) { +// PUT_NOTIFICATION(HOST_TO_DSP) +// } +// else if (remoteProcId == NotifyDriverMbx_videoProcId) { +// PUT_NOTIFICATION(HOST_TO_VIDEO) +// } +// else { +// PUT_NOTIFICATION(HOST_TO_VPSS) +// } + +#else +#error Invalid target +#endif + + return (Notify_S_SUCCESS); +} + +/* + * ======== NotifyDriverMbx_disable ======== + */ +Void NotifyDriverMbx_disable(NotifyDriverMbx_Object *obj) +{ + UInt16 selfVirtId = PROCID(MultiProc_self()); + UInt16 index; + +#if defined(xdc_target__isaCompatible_64P) || \ + defined(xdc_target__isaCompatible_arp32) + + index = (obj->remoteVirtId * NotifyDriverMbx_NUM_CORES) + selfVirtId; + REG32(MAILBOX_IRQENABLE_CLR(index)) = MAILBOX_REG_VAL(SUBMBX_IDX(index)); + +#elif defined(xdc_target__isaCompatible_v7M) + +// if (!(BIOS_smpEnabled) && (Core_getId())) { +// if (remoteProcId == NotifyDriverMbx_hostProcId) { +// REG32(MAILBOX_IRQENABLE_CLR_VPSS) = MAILBOX_REG_VAL(HOST_TO_VPSS); +// } +// else if (remoteProcId == NotifyDriverMbx_dspProcId) { +// REG32(MAILBOX_IRQENABLE_CLR_VPSS) = MAILBOX_REG_VAL(DSP_TO_VPSS); +// } +// else { +// REG32(MAILBOX_IRQENABLE_CLR_VPSS) = MAILBOX_REG_VAL(VIDEO_TO_VPSS); +// } +// } +// else { +// if (remoteProcId == NotifyDriverMbx_hostProcId) { +// REG32(MAILBOX_IRQENABLE_CLR_VIDEO) = MAILBOX_REG_VAL(HOST_TO_VIDEO); +// } +// else if (remoteProcId == NotifyDriverMbx_dspProcId) { +// REG32(MAILBOX_IRQENABLE_CLR_VIDEO) = MAILBOX_REG_VAL(DSP_TO_VIDEO); +// } +// else { +// REG32(MAILBOX_IRQENABLE_CLR_VIDEO) = MAILBOX_REG_VAL(VPSS_TO_VIDEO); +// } +// } + +#elif defined(xdc_target__isaCompatible_v7A) + +// if (remoteProcId == NotifyDriverMbx_dspProcId) { +// REG32(MAILBOX_IRQENABLE_CLR_HOST) = MAILBOX_REG_VAL(DSP_TO_HOST); +// } +// else if (remoteProcId == NotifyDriverMbx_videoProcId) { +// REG32(MAILBOX_IRQENABLE_CLR_HOST) = MAILBOX_REG_VAL(VIDEO_TO_HOST); +// } +// else { +// REG32(MAILBOX_IRQENABLE_CLR_HOST) = MAILBOX_REG_VAL(VPSS_TO_HOST); +// } + +#else +#error Invalid target +#endif +} + +/* + * ======== NotifyDriverMbx_enable ======== + */ +Void NotifyDriverMbx_enable(NotifyDriverMbx_Object *obj) +{ + UInt16 selfVirtId = PROCID(MultiProc_self()); + UInt16 index; + +#if defined(xdc_target__isaCompatible_64P) || \ + defined(xdc_target__isaCompatible_arp32) + + index = (obj->remoteVirtId * NotifyDriverMbx_NUM_CORES) + selfVirtId; + REG32(MAILBOX_IRQENABLE_SET(index)) = MAILBOX_REG_VAL(SUBMBX_IDX(index)); + +#elif defined(xdc_target__isaCompatible_v7M) + +// if (!(BIOS_smpEnabled) && (Core_getId())) { +// if (remoteProcId == NotifyDriverMbx_hostProcId) { +// REG32(MAILBOX_IRQENABLE_SET_VPSS) = MAILBOX_REG_VAL(HOST_TO_VPSS); +// } +// else if (remoteProcId == NotifyDriverMbx_dspProcId) { +// REG32(MAILBOX_IRQENABLE_SET_VPSS) = MAILBOX_REG_VAL(DSP_TO_VPSS); +// } +// else { +// REG32(MAILBOX_IRQENABLE_SET_VPSS) = MAILBOX_REG_VAL(VIDEO_TO_VPSS); +// } +// } +// else { +// if (remoteProcId == NotifyDriverMbx_hostProcId) { +// REG32(MAILBOX_IRQENABLE_SET_VIDEO) = MAILBOX_REG_VAL(HOST_TO_VIDEO); +// } +// else if (remoteProcId == NotifyDriverMbx_dspProcId) { +// REG32(MAILBOX_IRQENABLE_SET_VIDEO) = MAILBOX_REG_VAL(DSP_TO_VIDEO); +// } +// else { +// REG32(MAILBOX_IRQENABLE_SET_VIDEO) = MAILBOX_REG_VAL(VPSS_TO_VIDEO); +// } +// } + +#elif defined(xdc_target__isaCompatible_v7A) + +// if (remoteProcId == NotifyDriverMbx_dspProcId) { +// REG32(MAILBOX_IRQENABLE_SET_HOST) = MAILBOX_REG_VAL(DSP_TO_HOST); +// } +// else if (remoteProcId == NotifyDriverMbx_videoProcId) { +// REG32(MAILBOX_IRQENABLE_SET_HOST) = MAILBOX_REG_VAL(VIDEO_TO_HOST); +// } +// else { +// REG32(MAILBOX_IRQENABLE_SET_HOST) = MAILBOX_REG_VAL(VPSS_TO_HOST); +// } + +#else +#error Invalid target +#endif +} + +/* + * ======== NotifyDriverMbx_disableEvent ======== + */ +Void NotifyDriverMbx_disableEvent(NotifyDriverMbx_Object *obj, UInt32 eventId) +{ + /* NotifyDriverMbx_disableEvent not supported by this driver */ + Assert_isTrue(FALSE, NotifyDriverMbx_A_notSupported); +} + +/* + * ======== NotifyDriverMbx_enableEvent ======== + */ +Void NotifyDriverMbx_enableEvent(NotifyDriverMbx_Object *obj, UInt32 eventId) +{ + /* NotifyDriverMbx_enableEvent not supported by this driver */ + Assert_isTrue(FALSE, NotifyDriverMbx_A_notSupported); +} + +/* + ************************************************************************* + * Internal functions + ************************************************************************* + */ + +/* + * ======== NotifyDriverMbx_isr ======== + */ + +/* Read a message from the mailbox. The low 5 bits of the message + * contains the eventId. The high 27 bits of the message contains + * either: + * 1) The payload if the payload is less than 0x7FFFFFF + * 2) 0x7FFFFFF otherwise + * If the high 27 bits of the first message is 0x7FFFFFF, then the + * payload is in the next mailbox message. + * + * idx = mailbox table index + */ +#define MESSAGE_DELIVERY(idx) \ + msg = REG32(MAILBOX_MESSAGE(idx)); \ + eventId = (UInt16)(msg & 0x1F); \ + payload = msg >> 5; \ + if (payload == 0x7FFFFFF) { \ + while(REG32(MAILBOX_STATUS(idx)) == 0); \ + payload = REG32(MAILBOX_MESSAGE(idx)); \ + } \ + REG32(MAILBOX_IRQSTATUS_CLR(idx)) = MAILBOX_REG_VAL(SUBMBX_IDX(idx)); \ + obj = NotifyDriverMbx_module->drvHandles[srcVirtId]; \ + Assert_isTrue(obj != NULL, ti_sdo_ipc_Notify_A_internal); \ + if (TEST_BIT(obj->evtRegMask, eventId)) { \ + ti_sdo_ipc_Notify_exec(obj->notifyHandle, eventId, payload); \ + } \ + REG32(MAILBOX_EOI_REG(idx)) = 0x1; + +Void NotifyDriverMbx_isr(UInt16 idx) +{ + NotifyDriverMbx_Object *obj; + UInt32 msg, payload; + UInt16 eventId; + +#if defined(xdc_target__isaCompatible_64P) || \ + defined(xdc_target__isaCompatible_arp32) + + UInt16 srcVirtId; + + srcVirtId = idx / NotifyDriverMbx_NUM_CORES; + MESSAGE_DELIVERY(idx) + +#elif defined(xdc_target__isaCompatible_v7M) + +// do { +// numProcessed = 0; +// if (!(BIOS_smpEnabled) && (Core_getId())) { +// GET_NOTIFICATION(VPSS, HOST) +// GET_NOTIFICATION(VPSS, DSP) +// GET_NOTIFICATION(VPSS, VIDEO) +// } +// else { +// GET_NOTIFICATION(VIDEO, HOST) +// GET_NOTIFICATION(VIDEO, DSP) +// GET_NOTIFICATION(VIDEO, VPSS) +// } +// } +// while (numProcessed != 0); + +#elif defined(xdc_target__isaCompatible_v7A) + +// do { +// numProcessed = 0; +// GET_NOTIFICATION(HOST, DSP) +// GET_NOTIFICATION(HOST, VPSS) +// GET_NOTIFICATION(HOST, VIDEO) +// } +// while (numProcessed != 0); + +#else +#error Invalid target +#endif +} + +/* + * ======== NotifyDriverMbx_setNotifyHandle ======== + */ +Void NotifyDriverMbx_setNotifyHandle(NotifyDriverMbx_Object *obj, + Ptr notifyHandle) +{ + /* internally used, so no assert needed */ + obj->notifyHandle = (ti_sdo_ipc_Notify_Handle)notifyHandle; +} diff --git a/packages/ti/sdo/ipc/family/vayu/NotifyDriverMbx.xdc b/packages/ti/sdo/ipc/family/vayu/NotifyDriverMbx.xdc new file mode 100644 index 0000000..3fe0be7 --- /dev/null +++ b/packages/ti/sdo/ipc/family/vayu/NotifyDriverMbx.xdc @@ -0,0 +1,220 @@ +/* + * Copyright (c) 2014 Texas Instruments Incorporated - http://www.ti.com + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of Texas Instruments Incorporated nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * ======== NotifyDriverMbx.xdc ================ + */ +package ti.sdo.ipc.family.vayu; + +import ti.sdo.utils.MultiProc; +import ti.sdo.ipc.interfaces.INotifyDriver; +import ti.sdo.ipc.Notify; + +import ti.sysbios.hal.Hwi; + +import xdc.runtime.Assert; +import xdc.rov.ViewInfo; + +/*! + * ======== NotifyDriverMbx ======== + * A notify driver based on hardware mailbox. + * + * This notify driver uses hardware mailboxes to transmit notifications + * to remote processors. This driver implements the + * {@link ti.sdo.ipc.interfaces.INotifyDriver} interface. + * + * Unlike the Notify drivers available in the {@link ti.sdo.ipc.notifyDrivers} + * package, this driver is not generic and will only work with the Vayu + * family of devices. + * + * The driver does not use shared memory. The event IDs and payloads are + * transmitted via the hardware mailbox FIFO. The FIFO can hold up to 4 + * mailbox messages. The number of notification that can be stored in the + * FIFO depends on the size of the payloads being sent via Notify_sendEvent. + * If the payload is less than 0x7FFFFFF, then a single message will be + * sent per notification. Otherwise, two mailbox messages are needed to + * send the notification. + * + * The behavior of Notify_sendEvent when the FIFO is full depends on the + * value of the 'waitClear' argument to the function. If 'waitClear' is + * TRUE, then Notify_sendEvent will spin waiting for enough room in the + * FIFO. If 'waitClear' is FALSE, then Notify_sendEvent will return + * Notify_E_FAIL. + * + * The Notify_enableEvent and Notify_disableEvent APIs are not supported + * by this driver. + */ +@InstanceFinalize +@ModuleStartup + +module NotifyDriverMbx inherits ti.sdo.ipc.interfaces.INotifyDriver +{ + /*! @_nodoc */ + metaonly struct BasicView { + String remoteProc; + } + + /*! @_nodoc */ + metaonly struct MailboxView { + String direction; + String mailboxAddr; + Int subMbxId; + Int msgCount; + Int mbxInterrupt; + } + + /*! @_nodoc */ + metaonly struct ModuleView { + UInt16 interruptTable[NUM_CORES]; + NotifyDriverMbx.Handle drvHandles[NUM_CORES]; + } + + /*! + * ======== rovViewInfo ======== + */ + @Facet + metaonly config ViewInfo.Instance rovViewInfo = + ViewInfo.create({ + viewMap: [ + ['Basic', + { + type: ViewInfo.INSTANCE, + viewInitFxn: 'viewInitBasic', + structName: 'BasicView' + } + ], + ['Mailbox', + { + type: ViewInfo.INSTANCE_DATA, + viewInitFxn: 'viewInitMailbox', + structName: 'MailboxView' + } + ] +// ['Module', +// { +// type: ViewInfo.MODULE, +// viewInitFxn: 'viewInitModule', +// structName: 'ModuleView' +// } +// ] + ] + }); + + /*! + * Assert raised when trying to use Notify_[enable/disable]Event with + * NotifyDriverMbx + */ + config Assert.Id A_notSupported = { + msg: "A_notSupported: [enable/disable]Event not supported" + }; + +instance: + + /*! + * ======== remoteProcId ======== + * The MultiProc ID corresponding to the remote processor + * + * This is a required parameter, it is not optional. + */ + config UInt16 remoteProcId = MultiProc.INVALIDID; + + /*! + * ======== intVectorId ======== + * Interrupt vector ID to be used by the driver. + * + * This parameter is only used by C66 targets. + * This is a required parameter, it is not optional. + */ + config UInt intVectorId = ~1u; + +internal: + /* total number of cores on Vayu SoC */ + const UInt8 NUM_CORES = 11; + + /* number of cores in eve subsystem */ + const UInt8 NUM_EVES = 4; + + /* number of internal eve mailboxes */ + const UInt8 NUM_EVE_MBX = 12; + + /* number of system mailboxes (used by IPC) */ + const UInt8 NUM_SYS_MBX = 4; + + /* Mailbox table for storing encoded base address, mailbox user ID, + * and sub-mailbox index. + */ + config UInt32 mailboxTable[NUM_CORES * NUM_CORES]; + + /* base address table for the mailbox subsystem */ + config UInt32 mailboxBaseAddr[NUM_EVE_MBX + NUM_SYS_MBX]; + + /* map MultiProc ID to virtual ID, virtId = procIdTable[procId] */ + config UInt32 procIdTable[NUM_CORES]; + + /*! define MultiProcID for each core to avoid doing this at runtime */ + config UInt eve1ProcId = MultiProc.INVALIDID; + config UInt eve2ProcId = MultiProc.INVALIDID; + config UInt eve3ProcId = MultiProc.INVALIDID; + config UInt eve4ProcId = MultiProc.INVALIDID; + config UInt dsp1ProcId = MultiProc.INVALIDID; + config UInt dsp2ProcId = MultiProc.INVALIDID; + config UInt ipu1_0ProcId = MultiProc.INVALIDID; + config UInt ipu2_0ProcId = MultiProc.INVALIDID; + config UInt hostProcId = MultiProc.INVALIDID; + config UInt ipu1_1ProcId = MultiProc.INVALIDID; + config UInt ipu2_1ProcId = MultiProc.INVALIDID; + + /* plugs the interrupt and executes the callback functions */ + Void isr(UInt16 idx); + + /*! instance state structure */ + struct Instance_State { + Bits32 evtRegMask; /* local event register mask */ + Notify.Handle notifyHandle; /* handle to front-end object */ + UInt16 remoteProcId; /* remote processor ID */ + UInt16 remoteVirtId; /* remote processor virtual ID */ + Int cpuIntrNum; /* cpu interrupt number */ + } + + struct Module_State { + /* Interrupt event IDs used to communicate with this processor. + * This table is indexed by virtual processor ID. + * TODO: move this table to NotifySetup module + */ + UInt16 interruptTable[NUM_CORES]; + + /* Used by the isr to retrieve the driver handle. This table is + * indexed by virtual processorID. + */ + NotifyDriverMbx.Handle drvHandles[NUM_CORES]; + }; +} diff --git a/packages/ti/sdo/ipc/family/vayu/NotifyDriverMbx.xs b/packages/ti/sdo/ipc/family/vayu/NotifyDriverMbx.xs new file mode 100644 index 0000000..510ef86 --- /dev/null +++ b/packages/ti/sdo/ipc/family/vayu/NotifyDriverMbx.xs @@ -0,0 +1,309 @@ +/* + * Copyright (c) 2012-2014 Texas Instruments Incorporated - http://www.ti.com + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of Texas Instruments Incorporated nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * ======== NotifyDriverMbx.xs ================ + */ +var NotifyDriverMbx = null; +var Core = null; +var isaChain = ""; + +/* + * ======== module$use ======== + */ +function module$use() +{ + /* load modules needed in meta domain and in target domain */ + var TableInit = xdc.useModule("ti.sdo.ipc.family.vayu.TableInit"); + var MultiProc = xdc.useModule("ti.sdo.utils.MultiProc"); + NotifyDriverMbx = this; + xdc.useModule('xdc.runtime.Assert'); + xdc.useModule('xdc.runtime.Error'); + xdc.useModule('xdc.runtime.Startup'); + xdc.useModule("ti.sysbios.BIOS"); + + /* concatinate isa chain into single string for easier matching */ + isaChain = "#" + Program.build.target.getISAChain().join("#") + "#"; + + if (isaChain.match(/#64P#/)) { + xdc.useModule("ti.sysbios.family.c64p.EventCombiner"); + xdc.useModule("ti.sysbios.family.c64p.Hwi"); + xdc.useModule("ti.sysbios.family.shared.vayu.IntXbar"); + } + else if (isaChain.match(/#arp32#/)) { + xdc.useModule('ti.sysbios.family.arp32.Hwi'); + } + else if (isaChain.match(/#v7M#/)) { + Core = xdc.useModule("ti.sysbios.family.arm.ducati.Core"); + } + + xdc.useModule('ti.sdo.ipc.Ipc'); + xdc.useModule("ti.sdo.ipc.Notify"); + xdc.useModule('ti.sdo.ipc.family.vayu.NotifySetup'); + xdc.useModule('ti.sdo.ipc.interfaces.INotifyDriver'); + + /* initialize procIdTable */ + TableInit.initProcId(this); + + /* Initialize mailboxTable */ + TableInit.generateTable(this); + + if (isaChain.match(/#64P#|#v7M#|#v7A#/)) { + /* initialize mailbox base address table */ + this.mailboxBaseAddr[0] = 0x4208B000; /* EVE1 Internal Mailbox 0 */ + this.mailboxBaseAddr[1] = 0x4208C000; /* EVE1 Internal Mailbox 1 */ + this.mailboxBaseAddr[2] = 0x4208D000; /* EVE1 Internal Mailbox 2 */ + this.mailboxBaseAddr[3] = 0x4218B000; /* EVE2 Internal Mailbox 0 */ + this.mailboxBaseAddr[4] = 0x4218C000; /* EVE2 Internal Mailbox 1 */ + this.mailboxBaseAddr[5] = 0x4218D000; /* EVE2 Internal Mailbox 2 */ + this.mailboxBaseAddr[6] = 0x4228B000; /* EVE3 Internal Mailbox 0 */ + this.mailboxBaseAddr[7] = 0x4228C000; /* EVE3 Internal Mailbox 1 */ + this.mailboxBaseAddr[8] = 0x4228D000; /* EVE3 Internal Mailbox 2 */ + this.mailboxBaseAddr[9] = 0x4238B000; /* EVE4 Internal Mailbox 0 */ + this.mailboxBaseAddr[10] = 0x4238C000; /* EVE4 Internal Mailbox 1 */ + this.mailboxBaseAddr[11] = 0x4238D000; /* EVE4 Internal Mailbox 2 */ + this.mailboxBaseAddr[12] = 0x48840000; /* System Mailbox 5 */ + this.mailboxBaseAddr[13] = 0x48842000; /* System Mailbox 6 */ + this.mailboxBaseAddr[14] = 0x48844000; /* System Mailbox 7 */ + this.mailboxBaseAddr[15] = 0x48846000; /* System Mailbox 8 */ + } + else if (isaChain.match(/#arp32#/)) { + this.mailboxBaseAddr[0] = 0x4008B000; /* EVE1 Internal Mailbox 0 */ + this.mailboxBaseAddr[1] = 0x4008C000; /* EVE1 Internal Mailbox 1 */ + this.mailboxBaseAddr[2] = 0x4208D000; /* EVE1 Internal Mailbox 2 */ + this.mailboxBaseAddr[3] = 0x4008B000; /* EVE2 Internal Mailbox 0 */ + this.mailboxBaseAddr[4] = 0x4008C000; /* EVE2 Internal Mailbox 1 */ + this.mailboxBaseAddr[5] = 0x4218D000; /* EVE2 Internal Mailbox 2 */ + this.mailboxBaseAddr[6] = 0x4008B000; /* EVE3 Internal Mailbox 0 */ + this.mailboxBaseAddr[7] = 0x4008C000; /* EVE3 Internal Mailbox 1 */ + this.mailboxBaseAddr[8] = 0x4228D000; /* EVE3 Internal Mailbox 2 */ + this.mailboxBaseAddr[9] = 0x4008B000; /* EVE4 Internal Mailbox 0 */ + this.mailboxBaseAddr[10] = 0x4008C000; /* EVE4 Internal Mailbox 1 */ + this.mailboxBaseAddr[11] = 0x4238D000; /* EVE4 Internal Mailbox 2 */ + this.mailboxBaseAddr[12] = 0x48840000; /* System Mailbox 5 */ + this.mailboxBaseAddr[13] = 0x48842000; /* System Mailbox 6 */ + this.mailboxBaseAddr[14] = 0x48844000; /* System Mailbox 7 */ + this.mailboxBaseAddr[15] = 0x48846000; /* System Mailbox 8 */ + + /* each EVE receives its message using the local mailbox address */ + if (MultiProc.id == this.eve1ProcId) { + this.mailboxBaseAddr[2] = 0x4008D000; + } + else if (MultiProc.id == this.eve2ProcId) { + this.mailboxBaseAddr[5] = 0x4008D000; + } + else if (MultiProc.id == this.eve3ProcId) { + this.mailboxBaseAddr[8] = 0x4008D000; + } + else if (MultiProc.id == this.eve4ProcId) { + this.mailboxBaseAddr[11] = 0x4008D000; + } + } + else { + throw("Invalid target: " + Program.build.target.$name); + } +} + + +/* + * ======== module$static$init ======== + * Initialize the target state object. + */ +function module$static$init(state, mod) +{ + + for (var i = 0; i < state.drvHandles.length; i++) { + state.drvHandles[i] = null; + } + + if (isaChain.match(/#64P#/)) { + /* interrupt event IDs used by this processor */ + state.interruptTable[0] = 55; /* EVE1 -> DSP1 or DSP2 */ + state.interruptTable[1] = 56; /* EVE2 -> DSP1 or DSP2 */ + state.interruptTable[2] = 58; /* EVE3 -> DSP1 or DSP2 */ + state.interruptTable[3] = 59; /* EVE4 -> DSP1 or DSP2 */ + state.interruptTable[4] = 60; /* DSP1 -> DSP2 */ + state.interruptTable[5] = 60; /* DSP2 -> DSP1 */ + state.interruptTable[8] = 57; /* HOST -> DSP1 or DSP2 */ + + /* these are not known at config time, set at runtime */ + state.interruptTable[6] = 0; /* IPU1 -> DSP1 or DSP2 */ + state.interruptTable[7] = 0; /* IPU2 -> DSP1 or DSP2 */ + state.interruptTable[9] = 0; /* IPU1-1 -> DSP1 or DSP2 */ + state.interruptTable[10] = 0; /* IPU2-1 -> DSP1 or DSP2 */ + } + else if (isaChain.match(/#arp32#/)) { + /* interrupt event IDs used by this processor */ + state.interruptTable[0] = 60; /* EVE1 - Group1/INTC1 */ + state.interruptTable[1] = 60; /* EVE2 - Group1/INTC1 */ + state.interruptTable[2] = 60; /* EVE3 - Group1/INTC1 */ + state.interruptTable[3] = 60; /* EVE4 - Group1/INTC1 */ + state.interruptTable[4] = 29; /* DSP1 - Group0/INTC0 */ + state.interruptTable[5] = 30; /* DSP2 - Group0/INTC0 */ + state.interruptTable[6] = 29; /* IPU1-0 */ + state.interruptTable[7] = 30; /* IPU2-0 */ + state.interruptTable[8] = 29; /* HOST */ + state.interruptTable[9] = 30; /* IPU1-1 */ + state.interruptTable[10] = 30; /* IPU2-1 */ + } + else if (isaChain.match(/#v7M#/)) { + /* TODO */ +// if (Core.id == 0) { +// Hwi.construct(state.hwi, 53, NotifyDriverMbx.isr); +// } +// else { +// Hwi.construct(state.hwi, 54, NotifyDriverMbx.isr); +// } + } + else if (isaChain.match(/#v7A#/)) { + /* TODO */ +// Hwi.construct(state.hwi, 77, NotifyDriverMbx.isr); + } + else { + throw("Invalid target: " + Program.build.target.$name); + } +} + +/* + ************************************************************************* + * ROV View functions + ************************************************************************* + */ + +/* + * ======== viewInitBasic ======== + * Initizalize the 'Basic' ROV view. Called once per instance. + * + * view = instance of 'struct NotifyDriverMbx.BasicView' + */ +function viewInitBasic(view, obj) +{ + var Program = xdc.useModule('xdc.rov.Program'); + var MultiProc = xdc.useModule('ti.sdo.utils.MultiProc'); + + /* view.remoteProc */ + try { + view.remoteProc = MultiProc.getName$view(obj.remoteProcId); + } + catch (e) { + Program.displayError(view, 'remoteProc', + "Problem retrieving proc name: " + e); + } +} + +/* + * ======== viewInitMailbox ======== + * Initizalize the 'Mailbox' ROV view. Called once per instance. + * + * view = instance of 'struct xdc.rov.Program.InstDataView' + */ +function viewInitMailbox(view, obj) +{ + var Program = xdc.useModule('xdc.rov.Program'); + var ScalarStructs = xdc.useModule('xdc.rov.support.ScalarStructs'); + var MultiProc = xdc.useModule('ti.sdo.utils.MultiProc'); + var modCfg = Program.getModuleConfig( + 'ti.sdo.ipc.family.vayu.NotifyDriverMbx'); + + /* view.label (use remote processor name) */ + try { + view.label = MultiProc.getName$view(obj.remoteProcId); + } + catch (e) { + Program.displayError(view, 'remoteProcId', + "Problem retrieving proc name: " + e); + } + + /* create an array to hold the instance data table */ + var dataTable = new Array(); + var mailbox = ["Inbound", "Outbound"]; + + for (var i = 0; i < mailbox.length; i++) { + + /* create the view element */ + var elem = Program.newViewStruct( + 'ti.sdo.ipc.family.vayu.NotifyDriverMbx', 'Mailbox'); + + /* elem.direction (make a descriptive label) */ + if (mailbox[i] == "Inbound") { + elem.direction = mailbox[i] + " (from " + view.label + ")"; + } + else if (mailbox[i] == "Outbound") { + elem.direction = mailbox[i] + " (to " + view.label + ")"; + } + else { + throw new Error("invalid mailbox type"); + } + + /* elem.mailboxAddr */ + var selfVirtId = modCfg.procIdTable[MultiProc.self$view()]; + var idx; + + if (mailbox[i] == "Inbound") { + idx = (obj.remoteVirtId * modCfg.NUM_CORES) + selfVirtId; + } + else if (mailbox[i] == "Outbound") { + idx = (selfVirtId * modCfg.NUM_CORES) + obj.remoteVirtId; + } + else { + throw new Error("invalid mailbox type"); + } + + var baseAddrIdx = (modCfg.mailboxTable[idx] >> 16) & 0xFFFF; + var mailboxAddr = modCfg.mailboxBaseAddr[baseAddrIdx]; + elem.mailboxAddr = "0x" + Number(mailboxAddr).toString(16); + + /* elem.subMbxId */ + elem.subMbxId = modCfg.mailboxTable[idx] & 0xFF; + + /* elem.msgCount */ + try { + var MAILBOX_STATUS_IN = Program.fetchStruct( + ScalarStructs.S_Bits32$fetchDesc, + mailboxAddr + 0xC0 + (0x4 * elem.subMbxId), false); + elem.msgCount = MAILBOX_STATUS_IN.elem; + } + catch (e) { + Program.displayError(view, 'msgCount', + "Problem retrieving messsage count: " + e); + } + + /* elem.mbxInterrupt */ + elem.mbxInterrupt = (modCfg.mailboxTable[idx] >> 8) & 0xFF; + + /* add the element to the instance data table */ + dataTable.push(elem); + } + + /* view.elements */ + view.elements = dataTable; +} diff --git a/packages/ti/sdo/ipc/family/vayu/NotifySetup.c b/packages/ti/sdo/ipc/family/vayu/NotifySetup.c index 023a1c2..80a4bf8 100644 --- a/packages/ti/sdo/ipc/family/vayu/NotifySetup.c +++ b/packages/ti/sdo/ipc/family/vayu/NotifySetup.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2013, Texas Instruments Incorporated + * Copyright (c) 2012-2014 Texas Instruments Incorporated - http://www.ti.com * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -29,21 +29,78 @@ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ + /* * ======== NotifySetup.c ======== */ #include +#include #include +#include -#include -#include #include - +#include +#include +#include #include +#if defined(xdc_target__isaCompatible_64P) + +#include +#include +#include + +#elif defined(xdc_target__isaCompatible_arp32) + +#include + +#elif defined(xdc_target__isaCompatible_v7M) + +#include + +#elif defined(xdc_target__isaCompatible_v7A) + +#include + +#else +#error Invalid target +#endif + #include "package/internal/NotifySetup.xdc.h" -#define PROCID(IDX) (NotifySetup_procIdTable[(IDX)]) + +#define EVENT_GROUP_SIZE 32 + +/* register access methods */ +#define REG16(A) (*(volatile UInt16 *)(A)) +#define REG32(A) (*(volatile UInt32 *)(A)) + +/* ipc helper macros */ +#define MAILBOX_REG_VAL(m) (0x1 << (2 * (m))) + +#define VIRTID(procId) (NotifySetup_procIdTable[(procId)]) + +#define MBX_BASEADDR_IDX(idx) ((NotifySetup_mailboxTable[(idx)] >> 16) & 0xFFFF) + +#define MBX_USER_IDX(idx) ((NotifySetup_mailboxTable[(idx)] >> 8) & 0xFF) + +#define SUBMBX_IDX(idx) (NotifySetup_mailboxTable[(idx)] & 0xFF) + +#define MAILBOX_ADDR(idx) \ + (NotifySetup_mailboxBaseAddr[MBX_BASEADDR_IDX(idx)]) + +#define MAILBOX_STATUS(idx) \ + (MAILBOX_ADDR((idx)) + 0xC0 + (0x4 * SUBMBX_IDX((idx)))) + +#define MAILBOX_IRQENABLE_SET(idx) \ + (MAILBOX_ADDR((idx)) + 0x108 + (0x10 * MBX_USER_IDX((idx)))) + +#define MBOX_IRQ_ENABLE(idx) \ + ((REG32(MAILBOX_IRQENABLE_SET((idx))) & \ + MAILBOX_REG_VAL(SUBMBX_IDX((idx)))) != 0) + +#define MBOX_MSG_COUNT(idx) (REG32(MAILBOX_STATUS((idx)))) + /* ************************************************************************* @@ -51,11 +108,312 @@ ************************************************************************* */ +/* + * ======== NotifySetup_Module_startup ======== + */ +Int NotifySetup_Module_startup(Int phase) +{ +#if defined(xdc_target__isaCompatible_64P) + + extern cregister volatile UInt DNUM; + + if (IntXbar_Module_startupDone()) { + if (DNUM == 0) { /* DSP1 */ + NotifySetup_module->interruptTable[6] = 57; // IPU1-0 + NotifySetup_module->interruptTable[9] = 57; // IPU1-1 + + /* plug eve3 and eve4 mbxs only if eve3 and eve4 exists */ + if ((MultiProc_getId("EVE3") != MultiProc_INVALIDID) || + (MultiProc_getId("EVE4") != MultiProc_INVALIDID)) { + } + + /* plug mbx7 only if DSP2 or IPU2 exists */ + if ((MultiProc_getId("DSP2") != MultiProc_INVALIDID) || + (MultiProc_getId("IPU2") != MultiProc_INVALIDID) || + (MultiProc_getId("IPU2-0") != MultiProc_INVALIDID)) { + NotifySetup_module->interruptTable[7] = 60; // IPU2-0 + } + + /* plug mbx8 only if IPU2-1 exists */ + if (MultiProc_getId("IPU2-1") != MultiProc_INVALIDID) { + NotifySetup_module->interruptTable[10] = 61; // IPU2-1 + } + } + else if (DNUM == 1) { /* DSP2 */ + NotifySetup_module->interruptTable[7] = 57; // IPU2-0 + NotifySetup_module->interruptTable[10] = 57; // IPU2-1 + + /* plug eve3 and eve4 mbxs only if eve3 and eve4 exists */ + if ((MultiProc_getId("EVE3") != MultiProc_INVALIDID) || + (MultiProc_getId("EVE4") != MultiProc_INVALIDID)) { + } + + /* plug mbx7 only if DSP1 or IPU1 exists */ + if ((MultiProc_getId("DSP1") != MultiProc_INVALIDID) || + (MultiProc_getId("IPU1") != MultiProc_INVALIDID) || + (MultiProc_getId("IPU1-0") != MultiProc_INVALIDID)) { + NotifySetup_module->interruptTable[6] = 60; // IPU1-0 + } + + /* plug mbx8 only if IPU1-1 exists */ + if (MultiProc_getId("IPU1-1") != MultiProc_INVALIDID) { + NotifySetup_module->interruptTable[9] = 61; // IPU1-1 + } + } + return (Startup_DONE); + } + + return (Startup_NOTDONE); + +#elif defined(xdc_target__isaCompatible_arp32) + + /* nothing to do on this processor */ + return (Startup_DONE); + +#elif defined(xdc_target__isaCompatible_v7M) + + /* TODO */ + return (Startup_DONE); + +#elif defined(xdc_target__isaCompatible_v7A) + + /* TODO */ + return (Startup_DONE); + +#else +#error Invalid target +#endif +} + /*! * ======== NotifySetup_attach ======== - * Initialize interrupt + * Create driver instance specified at config time. + * + * This functions is generated by the NotifySetup.xdt template. + */ + +/*! + * ======== NotifySetup_sharedMemReq ======== + * Compute how much shared memory is required by the driver. + * + * This functions is generated by the NotifySetup.xdt template. + */ + +/*! + * ======== NotifySetup_numIntLines ======== + * Return number of available interrupt lines to the current processor. + */ +UInt16 NotifySetup_numIntLines(UInt16 remoteProcId) +{ + return (1); +} + +/* + * ======== NotifySetup_driverType ======== + * Find driver type for given connection. + * + * Search the connection array for the given remote processor. If + * found, return the requested notify driver type. + */ +NotifySetup_Driver NotifySetup_driverType(UInt16 remoteProcId) +{ + Int i; + NotifySetup_Driver driver = NotifySetup_Driver_SHAREDMEMORY; + + /* look for remote processor in connection array */ + for (i = 0; i < NotifySetup_module->connAry.length; i++) { + if (remoteProcId == NotifySetup_module->connAry.elem[i].procId) { + driver = NotifySetup_module->connAry.elem[i].driver; + break; + } + } + + return(driver); +} + +/* + * ======== NotifySetup_plugHwi ======== + */ +Void NotifySetup_plugHwi(UInt16 remoteProcId, Int cpuIntrNum, + NotifySetup_DriverIsr isr) +{ + Error_Block eb; + UInt key; + Hwi_Params hwiParams; + UInt16 virtId; + Int eventId; +#if defined(xdc_target__isaCompatible_64P) + UInt combinedEventId; +#elif defined(xdc_target__isaCompatible_arp32) + UInt mbxIdx; +#endif + + Error_init(&eb); + + /* disable global interrupts (TODO: should be a gated module) */ + key = Hwi_disable(); + + /* map processor id to virtual id */ + virtId = VIRTID(remoteProcId); + + /* save driver isr in dispatch table */ + NotifySetup_module->isrDispatchTable[virtId] = isr; + +#if defined(xdc_target__isaCompatible_64P) + + /* program the event dispatcher */ + eventId = NotifySetup_module->interruptTable[virtId]; + EventCombiner_dispatchPlug(eventId, NotifySetup_dispatchIsr, eventId, TRUE); + + /* make sure the interrupt is plugged only once */ + NotifySetup_module->numPlugged[0]++; + + if (NotifySetup_module->numPlugged[0] == 1) { + combinedEventId = eventId / EVENT_GROUP_SIZE; + + Hwi_Params_init(&hwiParams); + hwiParams.eventId = combinedEventId; + hwiParams.arg = combinedEventId; + hwiParams.enableInt = TRUE; + + Hwi_create(cpuIntrNum, + &ti_sysbios_family_c64p_EventCombiner_dispatch, + &hwiParams, &eb); + /* TODO: add error handling */ + + Hwi_enableInterrupt(cpuIntrNum); + } + +#elif defined(xdc_target__isaCompatible_arp32) + + if ((remoteProcId == NotifySetup_dsp1ProcId) || + (remoteProcId == NotifySetup_ipu1_0ProcId) || + (remoteProcId == NotifySetup_hostProcId)) { + + mbxIdx = 0; + } + else if ((remoteProcId == NotifySetup_dsp2ProcId) || + (remoteProcId == NotifySetup_ipu2_0ProcId) || + (remoteProcId == NotifySetup_ipu1_1ProcId) || + (remoteProcId == NotifySetup_ipu2_1ProcId)) { + + mbxIdx = 1; + } + else { + mbxIdx = 2; /* remote processor must be EVEx */ + } + + /* make sure the interrupt is plugged only once */ + NotifySetup_module->numPlugged[mbxIdx]++; + + if (NotifySetup_module->numPlugged[mbxIdx] == 1) { + eventId = NotifySetup_module->interruptTable[virtId]; + + Hwi_Params_init(&hwiParams); + hwiParams.arg = eventId; + hwiParams.vectorNum = cpuIntrNum; + + Hwi_create(eventId, NotifySetup_dispatchIsr, &hwiParams, &eb); + /* TODO: add error handling */ + + Hwi_enableInterrupt(NotifySetup_module->interruptTable[virtId]); + } + +#elif defined(xdc_target__isaCompatible_v7M) + + /* TODO */ + +#elif defined(xdc_target__isaCompatible_v7A) + + /* TODO */ + +#else +#error Invalid target +#endif + + /* restore global interrupts */ + Hwi_restore(key); +} + +/* + * ======== NotifySetup_unplugHwi ======== */ -Int NotifySetup_attach(UInt16 remoteProcId, Ptr sharedAddr) +Void NotifySetup_unplugHwi(UInt16 remoteProcId, Int cpuIntrNum) +{ + UInt key; + Hwi_Handle hwi; +#if defined(xdc_target__isaCompatible_64P) + UInt16 virtId; + Int eventId; +#elif defined(xdc_target__isaCompatible_arp32) + UInt mbxIdx; +#endif + + /* disable global interrupts (TODO: should be a gated module) */ + key = Hwi_disable(); + +#if defined(xdc_target__isaCompatible_64P) + + /* unplug interrupt if last user */ + NotifySetup_module->numPlugged[0]--; + + if (NotifySetup_module->numPlugged[0] == 0) { + hwi = Hwi_getHandle(cpuIntrNum); + Hwi_delete(&hwi); + } + + /* unprogram the event dispatcher */ + virtId = VIRTID(remoteProcId); + eventId = NotifySetup_module->interruptTable[virtId]; + EventCombiner_disableEvent(eventId); + +#elif defined(xdc_target__isaCompatible_arp32) + + if ((remoteProcId == NotifySetup_dsp1ProcId) || + (remoteProcId == NotifySetup_ipu1_0ProcId) || + (remoteProcId == NotifySetup_hostProcId)) { + + mbxIdx = 0; + } + else if ((remoteProcId == NotifySetup_dsp2ProcId) || + (remoteProcId == NotifySetup_ipu2_0ProcId) || + (remoteProcId == NotifySetup_ipu1_1ProcId) || + (remoteProcId == NotifySetup_ipu2_1ProcId)) { + + mbxIdx = 1; + } + else { + mbxIdx = 2; /* remote processor must be EVEx */ + } + + /* unplug interrupt if last user */ + NotifySetup_module->numPlugged[mbxIdx]--; + + if (NotifySetup_module->numPlugged[0] == 0) { + hwi = Hwi_getHandle(cpuIntrNum); + Hwi_delete(&hwi); + } + +#elif defined(xdc_target__isaCompatible_v7M) + + /* TODO */ + +#elif defined(xdc_target__isaCompatible_v7A) + + /* TODO */ + +#else +#error Invalid target +#endif + + /* restore global interrupts */ + Hwi_restore(key); +} + +/* + * ======== NotifySetup_Shm_attach ======== + */ +Int NotifySetup_Shm_attach(UInt16 remoteProcId, Ptr sharedAddr) { NotifyDriverShm_Params notifyShmParams; NotifyDriverShm_Handle shmDrvHandle; @@ -80,7 +438,8 @@ Int NotifySetup_attach(UInt16 remoteProcId, Ptr sharedAddr) (MultiProc_self() == NotifySetup_eve2ProcId) || (MultiProc_self() == NotifySetup_eve3ProcId) || (MultiProc_self() == NotifySetup_eve4ProcId)) { - if (PROCID(remoteProcId) < 4) { + + if (VIRTID(remoteProcId) < 4) { notifyShmParams.intVectorId = NotifySetup_eveIntVectId_INTC1; } else { @@ -88,14 +447,18 @@ Int NotifySetup_attach(UInt16 remoteProcId, Ptr sharedAddr) } } + /* create the notify driver instance */ shmDrvHandle = NotifyDriverShm_create(¬ifyShmParams, &eb); + if (shmDrvHandle == NULL) { return (Notify_E_FAIL); } + /* create the front-end notify instance */ notifyHandle = ti_sdo_ipc_Notify_create( NotifyDriverShm_Handle_upCast(shmDrvHandle), remoteProcId, 0, NULL, &eb); + if (notifyHandle == NULL) { NotifyDriverShm_delete(&shmDrvHandle); status = Notify_E_FAIL; @@ -104,11 +467,10 @@ Int NotifySetup_attach(UInt16 remoteProcId, Ptr sharedAddr) return (status); } - /*! - * ======== NotifySetup_sharedMemReq ======== + * ======== NotifySetup_Shm_sharedMemReq ======== */ -SizeT NotifySetup_sharedMemReq(UInt16 remoteProcId, Ptr sharedAddr) +SizeT NotifySetup_Shm_sharedMemReq(UInt16 remoteProcId, Ptr sharedAddr) { SizeT memReq; NotifyDriverShm_Params notifyShmParams; @@ -121,10 +483,117 @@ SizeT NotifySetup_sharedMemReq(UInt16 remoteProcId, Ptr sharedAddr) return (memReq); } +/* + * ======== NotifySetup_Mbx_attach ======== + */ +Int NotifySetup_Mbx_attach(UInt16 remoteProcId, Ptr sharedAddr) +{ + Int status = Notify_S_SUCCESS; + NotifyDriverMbx_Params params; + NotifyDriverMbx_Handle driver; + ti_sdo_ipc_Notify_Handle notify; + Error_Block eb; + + Error_init(&eb); + + NotifyDriverMbx_Params_init(¶ms); + params.remoteProcId = remoteProcId; + + /* set the intVectorId if on the DSP */ + if ((MultiProc_self() == NotifySetup_dsp1ProcId) || + (MultiProc_self() == NotifySetup_dsp2ProcId)) { + params.intVectorId = NotifySetup_dspIntVectId; + } + + /* set the intVectorId if on the EVE */ + if ((MultiProc_self() == NotifySetup_eve1ProcId) || + (MultiProc_self() == NotifySetup_eve2ProcId) || + (MultiProc_self() == NotifySetup_eve3ProcId) || + (MultiProc_self() == NotifySetup_eve4ProcId)) { + + if (VIRTID(remoteProcId) < 4) { + params.intVectorId = NotifySetup_eveIntVectId_INTC1; + } + else { + params.intVectorId = NotifySetup_eveIntVectId_INTC0; + } + } + + /* create the notify driver instance */ + driver = NotifyDriverMbx_create(¶ms, &eb); + + if (driver == NULL) { + return(Notify_E_FAIL); + } + + /* create the front-end notify instance */ + notify = ti_sdo_ipc_Notify_create(NotifyDriverMbx_Handle_upCast(driver), + remoteProcId, 0, NULL, &eb); + + if (notify == NULL) { + NotifyDriverMbx_delete(&driver); + status = Notify_E_FAIL; + } + + return(status); +} + /*! - * ======== NotifySetup_numIntLines ======== + * ======== NotifySetup_Mbx_sharedMemReq ======== */ -UInt16 NotifySetup_numIntLines(UInt16 remoteProcId) +SizeT NotifySetup_Mbx_sharedMemReq(UInt16 remoteProcId, Ptr sharedAddr) { - return 1; + SizeT memReq = 0; + + return (memReq); +} + +/* + ************************************************************************* + * Internal functions + ************************************************************************* + */ + +/* + * ======== NotifySetup_dispatchIsr ======== + * arg = eventId + */ +Void NotifySetup_dispatchIsr(UArg arg) +{ + Int numProcessed; + UInt16 idx; + UInt16 srcVirtId; + UInt16 dstVirtId = VIRTID(MultiProc_self()); + NotifySetup_DriverIsr driver; + + do { + numProcessed = 0; + + for (srcVirtId = 0; srcVirtId < NotifySetup_NUM_CORES; srcVirtId++) { + + /* skip null drivers, processor not in system or self */ + driver = NotifySetup_module->isrDispatchTable[srcVirtId]; + + if (driver == NULL) { + continue; + } + + /* check if processor would raise the given hardware eventId */ + if (arg == NotifySetup_module->interruptTable[srcVirtId]) { + + /* compute table index for given source and destination */ + idx = (srcVirtId * NotifySetup_NUM_CORES) + dstVirtId; + + /* check if submailbox has a message and irq is enabled */ + if ((MBOX_MSG_COUNT(idx) != 0) && MBOX_IRQ_ENABLE(idx)) { + + /* invoke driver isr to deliver the event */ + (*driver)(idx); + + /* event has been delivered */ + numProcessed++; + } + } + } + } while (numProcessed != 0); } diff --git a/packages/ti/sdo/ipc/family/vayu/NotifySetup.xdc b/packages/ti/sdo/ipc/family/vayu/NotifySetup.xdc index f63369d..44d3ff2 100644 --- a/packages/ti/sdo/ipc/family/vayu/NotifySetup.xdc +++ b/packages/ti/sdo/ipc/family/vayu/NotifySetup.xdc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2013, Texas Instruments Incorporated + * Copyright (c) 2012-2014 Texas Instruments Incorporated - http://www.ti.com * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -29,25 +29,41 @@ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ + /* * ======== NotifySetup.xdc ======== - * */ +package ti.sdo.ipc.family.vayu; +import xdc.runtime.Assert; import ti.sdo.utils.MultiProc; /*! * ======== NotifySetup ======== * Notify setup proxy for Vayu * - * This module creates and registers all drivers necessary for inter-processor - * notification on Vayu. + * This module creates and registers all drivers necessary for + * inter-processor notification on Vayu. */ +@ModuleStartup +@Template("./NotifySetup.xdt") module NotifySetup inherits ti.sdo.ipc.interfaces.INotifySetup { - /* Total number of cores on Vayu SoC */ - const UInt8 NUM_CORES = 11; + /* + * ======== DriverIsr ======== + * Notify driver isr function type definition + * param1 = mailbox table index + */ + typedef Void (*DriverIsr)(UInt16); + + /*! + * ======== A_internal ======== + * Internal implementation error. + */ + config Assert.Id A_internal = { + msg: "A_internal: internal implementation error" + }; /*! * Interrupt vector id for Vayu/DSP. @@ -60,16 +76,136 @@ module NotifySetup inherits ti.sdo.ipc.interfaces.INotifySetup config UInt eveIntVectId_INTC0 = -1; config UInt eveIntVectId_INTC1 = -1; - config UInt32 procIdTable[NUM_CORES]; + /*! + * Available notify drivers. + */ + enum Driver { + Driver_SHAREDMEMORY = 0x01, /*! shared memory */ + Driver_MAILBOX = 0x02 /*! hardware mailbox */ + }; + + /*! + * Notify driver connection specification. + */ + struct Connection { + Driver driver; /*! notify driver */ + String procName; /*! remote processor name */ + }; + + /*! + * Specify notify driver for given processor connections. + */ + metaonly config Connection connections[length]; + + /*! + * ======== plugHwi ======== + * Register an isr for the given interrupt and event. + * + * The given interrupt number must be the same for all calls + * because all IPC events should be taken by the same interrupt. + */ + Void plugHwi(UInt16 remoteProcId, Int cpuIntrNum, DriverIsr isr); + + /*! + * ======== unplugHwi ======== + * Unregister the isr for the given interrupt. + */ + Void unplugHwi(UInt16 remoteProcId, Int cpuIntrNum); internal: + /* total number of cores on Vayu SoC */ + const UInt8 NUM_CORES = 11; + + /* number of cores in eve subsystem */ + const UInt8 NUM_EVES = 4; + + /* number of internal eve mailboxes */ + const UInt8 NUM_EVE_MBX = 12; + + /* number of system mailboxes (used by IPC) */ + const UInt8 NUM_SYS_MBX = 4; + + /* Mailbox table for storing encoded base address, mailbox user ID, + * and sub-mailbox index. + */ + config UInt32 mailboxTable[NUM_CORES * NUM_CORES]; + + /* base address table for the mailbox subsystem */ + config UInt32 mailboxBaseAddr[NUM_EVE_MBX + NUM_SYS_MBX]; + + /* map procId to discrete processor/core */ + config UInt eve1ProcId = MultiProc.INVALIDID; + config UInt eve2ProcId = MultiProc.INVALIDID; + config UInt eve3ProcId = MultiProc.INVALIDID; + config UInt eve4ProcId = MultiProc.INVALIDID; + config UInt dsp1ProcId = MultiProc.INVALIDID; + config UInt dsp2ProcId = MultiProc.INVALIDID; + config UInt ipu1_0ProcId = MultiProc.INVALIDID; + config UInt ipu1_1ProcId = MultiProc.INVALIDID; + config UInt ipu2_0ProcId = MultiProc.INVALIDID; + config UInt ipu2_1ProcId = MultiProc.INVALIDID; + config UInt hostProcId = MultiProc.INVALIDID; + + /* map MultiProc ID to virtual ID, virtId = procIdTable[procId] */ + config UInt32 procIdTable[NUM_CORES]; + + /* + * ======== driverType ======== + */ + Driver driverType(UInt16 remoteProcId); + + /* + * ======== Shm_attach ======== + */ + Int Shm_attach(UInt16 remoteProcId, Ptr sharedAddr); + + /* + * ======== Shm_sharedMemReq ======== + */ + SizeT Shm_sharedMemReq(UInt16 remoteProcId, Ptr sharedAddr); + + /* + * ======== Mbx_attach ======== + */ + Int Mbx_attach(UInt16 remoteProcId, Ptr sharedAddr); + + /* + * ======== Mbx_sharedMemReq ======== + */ + SizeT Mbx_sharedMemReq(UInt16 remoteProcId, Ptr sharedAddr); + + /* + * ======== dispatchIsr ======== + * Dispatch interrupt to notify driver instance. + */ + Void dispatchIsr(UArg arg); + + /* + * ======== DrvBind ======== + */ + struct DrvBind { + Driver driver; /*! notify driver */ + UInt16 procId; /*! remote processor ID */ + }; + + /* + * ======== Module_State ======== + */ + struct Module_State { + /* interrupt plug counter */ + UInt16 numPlugged[]; + + /* connection array */ + DrvBind connAry[length]; + + /* Interrupt event IDs used to communicate with this processor. + * This table is indexed by virtual processor ID. + */ + UInt16 interruptTable[NUM_CORES]; - /* note: IPU intentionally omitted, nothing to setup */ - config UInt eve1ProcId = MultiProc.INVALIDID; - config UInt eve2ProcId = MultiProc.INVALIDID; - config UInt eve3ProcId = MultiProc.INVALIDID; - config UInt eve4ProcId = MultiProc.INVALIDID; - config UInt dsp1ProcId = MultiProc.INVALIDID; - config UInt dsp2ProcId = MultiProc.INVALIDID; - config UInt hostProcId = MultiProc.INVALIDID; + /* Notify driver isr dispatch table. This table is indexed + * by virtual processor ID. + */ + DriverIsr isrDispatchTable[NUM_CORES]; + }; } diff --git a/packages/ti/sdo/ipc/family/vayu/NotifySetup.xdt b/packages/ti/sdo/ipc/family/vayu/NotifySetup.xdt new file mode 100644 index 0000000..880d213 --- /dev/null +++ b/packages/ti/sdo/ipc/family/vayu/NotifySetup.xdt @@ -0,0 +1,97 @@ +%%{ +/* + * Copyright (c) 2014 Texas Instruments Incorporated - http://www.ti.com + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of Texas Instruments Incorporated nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +var pkg = this.$package.$name.replace(/\./g, "_"); + +%%} +#include + +/* + * ======== `pkg`_NotifySetup_attach ======== + */ +Int `pkg`_NotifySetup_attach(UInt16 remoteProcId, Ptr sharedAddr) +{ + Int status = Notify_E_FAIL; + `pkg`_NotifySetup_Driver driver; + + driver = `pkg`_NotifySetup_driverType(remoteProcId); + + switch (driver) { +% if (this.$private.driverMask & this.Driver_SHAREDMEMORY) { + case `pkg`_NotifySetup_Driver_SHAREDMEMORY: + status = `pkg`_NotifySetup_Shm_attach(remoteProcId, sharedAddr); + break; +% } +% if (this.$private.driverMask & this.Driver_MAILBOX) { + case `pkg`_NotifySetup_Driver_MAILBOX: + status = `pkg`_NotifySetup_Mbx_attach(remoteProcId, sharedAddr); + break; +% } + default: + xdc_runtime_Assert_isTrue(FALSE, `pkg`_NotifySetup_A_internal); + break; + } + + return (status); +} + +/*! + * ======== `pkg`_NotifySetup_sharedMemReq ======== + */ +SizeT `pkg`_NotifySetup_sharedMemReq(UInt16 remoteProcId, Ptr sharedAddr) +{ + `pkg`_NotifySetup_Driver driver; + SizeT memReq; + + driver = `pkg`_NotifySetup_driverType(remoteProcId); + + switch (driver) { +% if (this.$private.driverMask & this.Driver_SHAREDMEMORY) { + case `pkg`_NotifySetup_Driver_SHAREDMEMORY: + memReq = `pkg`_NotifySetup_Shm_sharedMemReq(remoteProcId, + sharedAddr); + break; +% } +% if (this.$private.driverMask & this.Driver_MAILBOX) { + case `pkg`_NotifySetup_Driver_MAILBOX: + memReq = `pkg`_NotifySetup_Mbx_sharedMemReq(remoteProcId, + sharedAddr); + break; +% } + default: + xdc_runtime_Assert_isTrue(FALSE, `pkg`_NotifySetup_A_internal); + break; + } + + return (memReq); +} diff --git a/packages/ti/sdo/ipc/family/vayu/NotifySetup.xs b/packages/ti/sdo/ipc/family/vayu/NotifySetup.xs index 3a2d36d..5119952 100644 --- a/packages/ti/sdo/ipc/family/vayu/NotifySetup.xs +++ b/packages/ti/sdo/ipc/family/vayu/NotifySetup.xs @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2013, Texas Instruments Incorporated + * Copyright (c) 2012-2014 Texas Instruments Incorporated - http://www.ti.com * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -29,60 +29,218 @@ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ + /* * ======== NotifySetup.xs ======== - * */ - -var NotifyDriverShm = null; -var Notify = null; -var MultiProc = null; -var NotifySetup = null; +var MultiProc = null; +var Core = null; +var isaChain = ""; /* * ======== module$use ======== */ function module$use() { - NotifyDriverShm = xdc.useModule('ti.sdo.ipc.notifyDrivers.NotifyDriverShm'); - Notify = xdc.useModule('ti.sdo.ipc.Notify'); - MultiProc = xdc.useModule('ti.sdo.utils.MultiProc'); - NotifySetup = this; + /* load modules needed in meta domain and in target domain */ + var TableInit = xdc.useModule("ti.sdo.ipc.family.vayu.TableInit"); + MultiProc = xdc.useModule('ti.sdo.utils.MultiProc'); + xdc.useModule('xdc.runtime.Assert'); + xdc.useModule('xdc.runtime.Error'); + xdc.useModule('xdc.runtime.Startup'); - var loopIdx; + /* concatinate isa chain into single string for easier matching */ + isaChain = "#" + Program.build.target.getISAChain().join("#") + "#"; - for (loopIdx = 0; loopIdx < this.NUM_CORES; loopIdx++) { - this.procIdTable[loopIdx] = -1; + if (isaChain.match(/#64P#/)) { + xdc.useModule('ti.sysbios.family.c64p.EventCombiner'); + xdc.useModule('ti.sysbios.family.c64p.Hwi'); + xdc.useModule('ti.sysbios.family.shared.vayu.IntXbar'); + } + else if (isaChain.match(/#arp32#/)) { + xdc.useModule('ti.sysbios.family.arp32.Hwi'); + } + else if (isaChain.match(/#v7M#/)) { + Core = xdc.useModule("ti.sysbios.family.arm.ducati.Core"); } - /* note: IPU intentionally omitted, nothing to setup */ - this.eve1ProcId = MultiProc.getIdMeta("EVE1"); - this.eve2ProcId = MultiProc.getIdMeta("EVE2"); - this.eve3ProcId = MultiProc.getIdMeta("EVE3"); - this.eve4ProcId = MultiProc.getIdMeta("EVE4"); - this.dsp1ProcId = MultiProc.getIdMeta("DSP1"); - this.dsp2ProcId = MultiProc.getIdMeta("DSP2"); - this.hostProcId = MultiProc.getIdMeta("HOST"); + xdc.useModule('ti.sdo.ipc.Ipc'); + xdc.useModule('ti.sdo.ipc.Notify'); + + /* initialize procIdTable */ + TableInit.initProcId(this); + + /* initialize mailboxTable */ + TableInit.generateTable(this); + + if (isaChain.match(/#64P#|#v7M#|#v7A#/)) { + /* initialize mailbox base address table */ + this.mailboxBaseAddr[0] = 0x4208B000; /* EVE1 Internal Mailbox 0 */ + this.mailboxBaseAddr[1] = 0x4208C000; /* EVE1 Internal Mailbox 1 */ + this.mailboxBaseAddr[2] = 0x4208D000; /* EVE1 Internal Mailbox 2 */ + this.mailboxBaseAddr[3] = 0x4218B000; /* EVE2 Internal Mailbox 0 */ + this.mailboxBaseAddr[4] = 0x4218C000; /* EVE2 Internal Mailbox 1 */ + this.mailboxBaseAddr[5] = 0x4218D000; /* EVE2 Internal Mailbox 2 */ + this.mailboxBaseAddr[6] = 0x4228B000; /* EVE3 Internal Mailbox 0 */ + this.mailboxBaseAddr[7] = 0x4228C000; /* EVE3 Internal Mailbox 1 */ + this.mailboxBaseAddr[8] = 0x4228D000; /* EVE3 Internal Mailbox 2 */ + this.mailboxBaseAddr[9] = 0x4238B000; /* EVE4 Internal Mailbox 0 */ + this.mailboxBaseAddr[10] = 0x4238C000; /* EVE4 Internal Mailbox 1 */ + this.mailboxBaseAddr[11] = 0x4238D000; /* EVE4 Internal Mailbox 2 */ + this.mailboxBaseAddr[12] = 0x48840000; /* System Mailbox 5 */ + this.mailboxBaseAddr[13] = 0x48842000; /* System Mailbox 6 */ + this.mailboxBaseAddr[14] = 0x48844000; /* System Mailbox 7 */ + this.mailboxBaseAddr[15] = 0x48846000; /* System Mailbox 8 */ + } + else if (isaChain.match(/#arp32#/)) { + this.mailboxBaseAddr[0] = 0x4008B000; /* EVE1 Internal Mailbox 0 */ + this.mailboxBaseAddr[1] = 0x4008C000; /* EVE1 Internal Mailbox 1 */ + this.mailboxBaseAddr[2] = 0x4208D000; /* EVE1 Internal Mailbox 2 */ + this.mailboxBaseAddr[3] = 0x4008B000; /* EVE2 Internal Mailbox 0 */ + this.mailboxBaseAddr[4] = 0x4008C000; /* EVE2 Internal Mailbox 1 */ + this.mailboxBaseAddr[5] = 0x4218D000; /* EVE2 Internal Mailbox 2 */ + this.mailboxBaseAddr[6] = 0x4008B000; /* EVE3 Internal Mailbox 0 */ + this.mailboxBaseAddr[7] = 0x4008C000; /* EVE3 Internal Mailbox 1 */ + this.mailboxBaseAddr[8] = 0x4228D000; /* EVE3 Internal Mailbox 2 */ + this.mailboxBaseAddr[9] = 0x4008B000; /* EVE4 Internal Mailbox 0 */ + this.mailboxBaseAddr[10] = 0x4008C000; /* EVE4 Internal Mailbox 1 */ + this.mailboxBaseAddr[11] = 0x4238D000; /* EVE4 Internal Mailbox 2 */ + this.mailboxBaseAddr[12] = 0x48840000; /* System Mailbox 5 */ + this.mailboxBaseAddr[13] = 0x48842000; /* System Mailbox 6 */ + this.mailboxBaseAddr[14] = 0x48844000; /* System Mailbox 7 */ + this.mailboxBaseAddr[15] = 0x48846000; /* System Mailbox 8 */ - if (this.eve1ProcId != MultiProc.INVALIDID) { - this.procIdTable[this.eve1ProcId] = 0; + /* each EVE receives its message using the local mailbox address */ + if (MultiProc.id == this.eve1ProcId) { + this.mailboxBaseAddr[2] = 0x4008D000; + } + else if (MultiProc.id == this.eve2ProcId) { + this.mailboxBaseAddr[5] = 0x4008D000; + } + else if (MultiProc.id == this.eve3ProcId) { + this.mailboxBaseAddr[8] = 0x4008D000; + } + else if (MultiProc.id == this.eve4ProcId) { + this.mailboxBaseAddr[11] = 0x4008D000; + } } - if (this.eve2ProcId != MultiProc.INVALIDID) { - this.procIdTable[this.eve2ProcId] = 1; + else { + throw("Invalid target: " + Program.build.target.$name); } - if (this.eve3ProcId != MultiProc.INVALIDID) { - this.procIdTable[this.eve3ProcId] = 2; + + /* determine which notify drivers to include */ + this.$private.driverMask = 0; + + /* for unspecfied connections, the default is shared memory */ + if (this.connections.length < (MultiProc.numProcessors - 1)) { + this.$private.driverMask |= this.Driver_SHAREDMEMORY; } - if (this.eve4ProcId != MultiProc.INVALIDID) { - this.procIdTable[this.eve4ProcId] = 3; + + /* remember which notify drivers have been specified */ + for (var i = 0; i < this.connections.length; i++) { + if (this.connections[i].driver == this.Driver_SHAREDMEMORY) { + this.$private.driverMask |= this.Driver_SHAREDMEMORY; + } + if (this.connections[i].driver == this.Driver_MAILBOX) { + this.$private.driverMask |= this.Driver_MAILBOX; + } } - if (this.dsp1ProcId != MultiProc.INVALIDID) { - this.procIdTable[this.dsp1ProcId] = 4; + + /* load notify drivers into configuration model */ + if (this.$private.driverMask & this.Driver_SHAREDMEMORY) { + xdc.useModule('ti.sdo.ipc.notifyDrivers.NotifyDriverShm'); } - if (this.dsp2ProcId != MultiProc.INVALIDID) { - this.procIdTable[this.dsp2ProcId] = 5; + if (this.$private.driverMask & this.Driver_MAILBOX) { + xdc.useModule('ti.sdo.ipc.family.vayu.NotifyDriverMbx'); } - if (this.hostProcId != MultiProc.INVALIDID) { - this.procIdTable[this.hostProcId] = 8; +} + +/* + * ======== module$static$init ======== + * Initialize the target state object. + */ +function module$static$init(state, mod) +{ + var procId; + + /* Initialize the state connAry from the config params. Translate + * processor names into IDs for better runtime performance. + */ + state.connAry.length = mod.connections.length; + + for (var i = 0; i < mod.connections.length; i++) { + procId = MultiProc.getIdMeta(mod.connections[i].procName); + state.connAry[i].procId = procId; + state.connAry[i].driver = mod.connections[i].driver; + } + + if (isaChain.match(/#64P#/)) { + state.numPlugged.length = 1; + + /* interrupt event IDs used by this processor */ + state.interruptTable[0] = 55; /* EVE1 -> DSP1 or DSP2 */ + state.interruptTable[1] = 56; /* EVE2 -> DSP1 or DSP2 */ + state.interruptTable[2] = 58; /* EVE3 -> DSP1 or DSP2 */ + state.interruptTable[3] = 59; /* EVE4 -> DSP1 or DSP2 */ + state.interruptTable[4] = 60; /* DSP1 -> DSP2 */ + state.interruptTable[5] = 60; /* DSP2 -> DSP1 */ + state.interruptTable[8] = 57; /* HOST -> DSP1 or DSP2 */ + + /* these are not known at config time, set at runtime */ + state.interruptTable[6] = 0; /* IPU1 -> DSP1 or DSP2 */ + state.interruptTable[7] = 0; /* IPU2 -> DSP1 or DSP2 */ + state.interruptTable[9] = 0; /* IPU1-1 -> DSP1 or DSP2 */ + state.interruptTable[10] = 0; /* IPU2-1 -> DSP1 or DSP2 */ + } + else if (isaChain.match(/#arp32#/)) { + state.numPlugged.length = this.NUM_EVE_MBX / this.NUM_EVES; + + /* interrupt event IDs used by this processor */ + state.interruptTable[0] = 60; /* EVE1 - Group1/INTC1 */ + state.interruptTable[1] = 60; /* EVE2 - Group1/INTC1 */ + state.interruptTable[2] = 60; /* EVE3 - Group1/INTC1 */ + state.interruptTable[3] = 60; /* EVE4 - Group1/INTC1 */ + state.interruptTable[4] = 29; /* DSP1 - Group0/INTC0 */ + state.interruptTable[5] = 30; /* DSP2 - Group0/INTC0 */ + state.interruptTable[6] = 29; /* IPU1-0 */ + state.interruptTable[7] = 30; /* IPU2-0 */ + state.interruptTable[8] = 29; /* HOST */ + state.interruptTable[9] = 30; /* IPU1-1 */ + state.interruptTable[10] = 30; /* IPU2-1 */ + } + else if (isaChain.match(/#v7M#/)) { + state.numPlugged.length = 1; + + /* TODO */ +// if (Core.id == 0) { +// Hwi.construct(state.hwi, 53, NotifyDriverMbx.isr); +// } +// else { +// Hwi.construct(state.hwi, 54, NotifyDriverMbx.isr); +// } + + /* interrupt event IDs used by this processor */ + for (var i = 0; i < state.interruptTable.length; i++) { + state.interruptTable[i] = 0xFFFF; /* TODO */ + } + } + else if (isaChain.match(/#v7A#/)) { + state.numPlugged.length = 1; + + /* interrupt event IDs used by this processor */ + for (var i = 0; i < state.interruptTable.length; i++) { + state.interruptTable[i] = 0xFFFF; /* TODO */ + } + + /* TODO */ + // Hwi.construct(state.hwi, 77, NotifyDriverMbx.isr); + } + else { + throw("Invalid target: " + Program.build.target.$name); + } + + /* initialize the driver table */ + for (var i = 0; i < state.isrDispatchTable.length; i++) { + state.isrDispatchTable[i] = null; } } diff --git a/packages/ti/sdo/ipc/family/vayu/TableInit.xs b/packages/ti/sdo/ipc/family/vayu/TableInit.xs index 17f8b74..2021fcf 100644 --- a/packages/ti/sdo/ipc/family/vayu/TableInit.xs +++ b/packages/ti/sdo/ipc/family/vayu/TableInit.xs @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2013, Texas Instruments Incorporated + * Copyright (c) 2012-2014 Texas Instruments Incorporated - http://www.ti.com * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -63,73 +63,84 @@ var hostVirtId = 8; var ipu1_1VirtId = 9; var ipu2_1VirtId = 10; + /* - * Function to initialize coreIds. + * ======== initProcId ======== + * Assign MultiProc ids and virtual processor ids. */ -function initProcId(InterruptCore) +function initProcId(mod) { - var MultiProc = xdc.useModule("ti.sdo.utils.MultiProc"); + var MultiProc = xdc.useModule("ti.sdo.utils.MultiProc"); - for (var loopIdx=0; loopIdx