Ejemplo n.º 1
0
/*
 *  ======== Notify_eventAvailable ========
 */
Bool Notify_eventAvailable(UInt16 procId, UInt16 lineId, UInt32 eventId)
{
    UInt32 strippedEventId = (eventId & 0xFFFF);
    UInt16 clusterId = ti_sdo_utils_MultiProc_getClusterId(procId);
    Bool available;
    ti_sdo_ipc_Notify_Object *obj;

    Assert_isTrue(procId < ti_sdo_utils_MultiProc_numProcessors && lineId <
                  ti_sdo_ipc_Notify_numLines, ti_sdo_ipc_Notify_A_invArgument);
    Assert_isTrue(strippedEventId < ti_sdo_ipc_Notify_numEvents,
                  ti_sdo_ipc_Notify_A_invArgument);

    obj = (ti_sdo_ipc_Notify_Object *)
          Notify_module->notifyHandles[clusterId][lineId];
    if (obj == NULL) {
        /* Driver not registered */
        return (FALSE);
    }

    if (!ISRESERVED(eventId)) {
        /* Event is reserved and the caller isn't using Notify_SYSTEMKEY */
        return (FALSE);
    }

    available = (obj->callbacks[strippedEventId].fnNotifyCbck == NULL);

    return (available);
}
Ejemplo n.º 2
0
/*
 *  ======== ti_sdo_ipc_Notify_Instance_finalize ========
 */
Void ti_sdo_ipc_Notify_Instance_finalize(ti_sdo_ipc_Notify_Object *obj,
        Int status)
{
    UInt    i;
    UInt16  clusterId = ti_sdo_utils_MultiProc_getClusterId(obj->remoteProcId);

    switch (status) {
    case 0:
        /* Unregister the notify instance from the Notify module */
        Notify_module->notifyHandles[clusterId][obj->lineId] = NULL;

        /* Destruct the event lists */
        for (i = 0; i < ti_sdo_ipc_Notify_numEvents; i++) {
            List_destruct(List_struct(List_Object_get(obj->eventList, i)));
        }

        /* Free memory used for the List.Objects */
        Memory_free(ti_sdo_ipc_Notify_Object_heap(), obj->eventList,
                    sizeof(List_Struct) * ti_sdo_ipc_Notify_numEvents);

    /* OK to fall through */

    case 1:
        /* Free memory used for callbacks array */
        Memory_free(ti_sdo_ipc_Notify_Object_heap(), obj->callbacks,
                    sizeof(ti_sdo_ipc_Notify_EventCallback) *
                    ti_sdo_ipc_Notify_numEvents);
    }
}
Ejemplo n.º 3
0
/*
 *  ======== Notify_disable ========
 */
UInt Notify_disable(UInt16 procId, UInt16 lineId)
{
    UInt key;
    UInt modKey;
    UInt16 clusterId = ti_sdo_utils_MultiProc_getClusterId(procId);
    ti_sdo_ipc_Notify_Object *obj;

    Assert_isTrue(procId < ti_sdo_utils_MultiProc_numProcessors &&
                  lineId < ti_sdo_ipc_Notify_numLines,
                  ti_sdo_ipc_Notify_A_invArgument);

    obj = (ti_sdo_ipc_Notify_Object *)
          Notify_module->notifyHandles[clusterId][lineId];

    Assert_isTrue(obj != NULL, ti_sdo_ipc_Notify_A_notRegistered);

    /* Nesting value and enable state have to be in sync */
    modKey = Gate_enterModule();

    obj->nesting++;
    if (obj->nesting == 1) {
        /* Disable receiving all events */
        if (procId != MultiProc_self()) {
            INotifyDriver_disable(obj->driverHandle);
        }
    }

    key = obj->nesting;

    Gate_leaveModule(modKey);

    return (key);
}
Ejemplo n.º 4
0
/*
 *  ======== Notify_restore ========
 */
Void Notify_restore(UInt16 procId, UInt16 lineId, UInt key)
{
    UInt modKey;
    UInt16 clusterId = ti_sdo_utils_MultiProc_getClusterId(procId);
    ti_sdo_ipc_Notify_Object *obj;

    Assert_isTrue(procId < ti_sdo_utils_MultiProc_numProcessors &&
                  lineId < ti_sdo_ipc_Notify_numLines, ti_sdo_ipc_Notify_A_invArgument);

    obj = (ti_sdo_ipc_Notify_Object *)
          Notify_module->notifyHandles[clusterId][lineId];

    Assert_isTrue(obj != NULL, ti_sdo_ipc_Notify_A_notRegistered);
    Assert_isTrue(key == obj->nesting, ti_sdo_ipc_Notify_A_outOfOrderNesting);

    /* Nesting value and enable state have to be in sync */
    modKey = Gate_enterModule();

    obj->nesting--;
    if (obj->nesting == 0) {
        /* Enable receiving events */
        if (procId != MultiProc_self()) {
            INotifyDriver_enable(obj->driverHandle);
        }
    }

    Gate_leaveModule(modKey);
}
Ejemplo n.º 5
0
/*
 *  ======== Notify_enableEvent ========
 */
Void Notify_enableEvent(UInt16 procId, UInt16 lineId, UInt32 eventId)
{
    UInt32 strippedEventId = (eventId & 0xFFFF);
    UInt16 clusterId = ti_sdo_utils_MultiProc_getClusterId(procId);
    ti_sdo_ipc_Notify_Object *obj;
    UInt sysKey;

    Assert_isTrue(procId < ti_sdo_utils_MultiProc_numProcessors && lineId <
                  ti_sdo_ipc_Notify_numLines, ti_sdo_ipc_Notify_A_invArgument);
    Assert_isTrue(strippedEventId < ti_sdo_ipc_Notify_numEvents,
                  ti_sdo_ipc_Notify_A_invArgument);
    Assert_isTrue(ISRESERVED(eventId), ti_sdo_ipc_Notify_A_reservedEvent);

    obj = (ti_sdo_ipc_Notify_Object *)
          Notify_module->notifyHandles[clusterId][lineId];

    Assert_isTrue(obj != NULL, ti_sdo_ipc_Notify_A_notRegistered);

    if (procId != MultiProc_self()) {
        /* enable the remote event */
        INotifyDriver_enableEvent(obj->driverHandle, strippedEventId);
    }
    else {
        /* enable the local event */
        sysKey = Hwi_disable();
        SET_BIT(Notify_module->localEnableMask, strippedEventId);
        Hwi_restore(sysKey);
    }
}
Ejemplo n.º 6
0
/*
 *  ======== ti_sdo_ipc_Notify_detach ========
 *  Called within Ipc module
 */
Int ti_sdo_ipc_Notify_detach(UInt16 remoteProcId)
{
    ti_sdo_ipc_Notify_Object *obj;
    UInt16 clusterId = ti_sdo_utils_MultiProc_getClusterId(remoteProcId);
    INotifyDriver_Handle driverHandle;
    UInt i;

    for (i = 0; i < ti_sdo_ipc_Notify_numLines; i++) {
        obj = (ti_sdo_ipc_Notify_Object *)
              Notify_module->notifyHandles[clusterId][i];

        /* Ensure that notify is actually registered for the procId + lineId */
        if (obj != NULL) {
            driverHandle = obj->driverHandle;

            /* First, unregister the driver since it was registered last */
            ti_sdo_ipc_Notify_delete(&obj);

            /* Second, delete the driver itself */
            INotifyDriver_delete(&driverHandle);
        }

    }

    /* Notify_detech never fails on RTOS */
    return (Notify_S_SUCCESS);
}
Ejemplo n.º 7
0
/*
 *  ======== ti_sdo_ipc_Notify_Instance_init ========
 */
Int ti_sdo_ipc_Notify_Instance_init(
    ti_sdo_ipc_Notify_Object *obj,
    INotifyDriver_Handle driverHandle,
    UInt16 remoteProcId, UInt16 lineId,
    const ti_sdo_ipc_Notify_Params *params,
    Error_Block *eb)
{
    UInt        i;
    UInt16      clusterId = ti_sdo_utils_MultiProc_getClusterId(remoteProcId);
    List_Handle eventList;

    Assert_isTrue(remoteProcId < ti_sdo_utils_MultiProc_numProcessors &&
                  lineId < ti_sdo_ipc_Notify_numLines, ti_sdo_ipc_Notify_A_invArgument);
    Assert_isTrue(Notify_module->notifyHandles[clusterId][lineId] == NULL,
                  ti_sdo_ipc_Notify_A_alreadyRegistered);

    obj->remoteProcId = remoteProcId;
    obj->lineId = lineId;
    obj->nesting = 0;

    /* Allocate and initialize (to 0 with calloc()) the callbacks array. */
    obj->callbacks = Memory_calloc(ti_sdo_ipc_Notify_Object_heap(),
                                   (sizeof(ti_sdo_ipc_Notify_EventCallback) *
                                    ti_sdo_ipc_Notify_numEvents), 0, eb);
    if (obj->callbacks == NULL) {
        return (2);
    }

    obj->eventList = Memory_alloc(ti_sdo_ipc_Notify_Object_heap(),
                                  sizeof(List_Struct) * ti_sdo_ipc_Notify_numEvents, 0, eb);
    if (obj->eventList == NULL) {
        return (1);
    }

    for (i = 0; i < ti_sdo_ipc_Notify_numEvents; i++) {
        eventList = List_Object_get(obj->eventList, i);

        /* Pass in NULL for eb since construct should never fail */
        List_construct(List_struct(eventList), NULL);
    }

    /* Used solely for remote driver (NULL if remoteProcId == self) */
    obj->driverHandle = driverHandle;

    if (driverHandle != NULL) {
        /* Send this handle to the INotifyDriver */
        INotifyDriver_setNotifyHandle(driverHandle, obj);
    }

    Notify_module->notifyHandles[clusterId][lineId] = obj;

    return (0);
}
Ejemplo n.º 8
0
/*
 *  ======== ti_sdo_ipc_Ipc_setEntry ========
 */
Void ti_sdo_ipc_Ipc_setEntry(ti_sdo_ipc_Ipc_Entry *entry)
{
    UInt16 clusterId = ti_sdo_utils_MultiProc_getClusterId(entry->remoteProcId);

    /* Set the setupNotify flag */
    Ipc_module->procEntry[clusterId].entry.setupNotify =
        entry->setupNotify;

    /* Set the setupMessageQ flag */
    Ipc_module->procEntry[clusterId].entry.setupMessageQ =
        entry->setupMessageQ;
}
Ejemplo n.º 9
0
/*
 *  ======== Notify_intLineRegistered ========
 */
Bool Notify_intLineRegistered(UInt16 procId, UInt16 lineId)
{
    Bool registered;
    UInt16 clusterId = ti_sdo_utils_MultiProc_getClusterId(procId);

    Assert_isTrue(procId < ti_sdo_utils_MultiProc_numProcessors && lineId <
                  ti_sdo_ipc_Notify_numLines, ti_sdo_ipc_Notify_A_invArgument);

    registered = (Notify_module->notifyHandles[clusterId][lineId] != NULL);

    return (registered);
}
Ejemplo n.º 10
0
/*
 *  ======== Ipc_readConfig ========
 */
Int Ipc_readConfig(UInt16 remoteProcId, UInt32 tag, Ptr cfg, SizeT size)
{
    Int status = Ipc_E_FAIL;
    UInt16 clusterId = ti_sdo_utils_MultiProc_getClusterId(remoteProcId);
    volatile ti_sdo_ipc_Ipc_ConfigEntry *entry;
    Bool cacheEnabled = SharedRegion_isCacheEnabled(0);

    /* Assert that the remoteProc in our cluster and isn't our own */
    Assert_isTrue(clusterId < ti_sdo_utils_MultiProc_numProcsInCluster,
                  ti_sdo_utils_MultiProc_A_invalidMultiProcId);

    if (cacheEnabled) {
        Cache_inv(Ipc_module->procEntry[clusterId].remoteConfigList,
                  SharedRegion_getCacheLineSize(0),
                  Cache_Type_ALL,
                  TRUE);
    }

    entry = (ti_sdo_ipc_Ipc_ConfigEntry *)
            *Ipc_module->procEntry[clusterId].remoteConfigList;

    while ((SharedRegion_SRPtr)entry != ti_sdo_ipc_SharedRegion_INVALIDSRPTR) {
        entry = (ti_sdo_ipc_Ipc_ConfigEntry *)
                SharedRegion_getPtr((SharedRegion_SRPtr)entry);

        /* Traverse the list to find the tag */
        if (cacheEnabled) {
            Cache_inv((Ptr)entry,
                      size + sizeof(ti_sdo_ipc_Ipc_ConfigEntry),
                      Cache_Type_ALL,
                      TRUE);
        }

        if ((entry->remoteProcId == MultiProc_self()) &&
            (entry->localProcId == remoteProcId) &&
            (entry->tag == tag)) {

            if (size == entry->size) {
                memcpy(cfg, (Ptr)((UInt32)entry + sizeof(ti_sdo_ipc_Ipc_ConfigEntry)),
                        entry->size);
                return (Ipc_S_SUCCESS);
            }
            else {
                return (Ipc_E_FAIL);
            }
        }

        entry = (ti_sdo_ipc_Ipc_ConfigEntry *)entry->next;
    }

    return (status);
}
Ejemplo n.º 11
0
/*
 *  ======== Notify_unregisterEventSingle ========
 */
Int Notify_unregisterEventSingle(UInt16 procId, UInt16 lineId, UInt32 eventId)
{
    UInt32  strippedEventId = (eventId & 0xFFFF);
    UInt16  clusterId = ti_sdo_utils_MultiProc_getClusterId(procId);
    Int     status;
    ti_sdo_ipc_Notify_Object *obj;
    UInt    modKey;

    Assert_isTrue(procId < ti_sdo_utils_MultiProc_numProcessors &&
                  lineId < ti_sdo_ipc_Notify_numLines, ti_sdo_ipc_Notify_A_invArgument);
    Assert_isTrue(strippedEventId < ti_sdo_ipc_Notify_numEvents,
                  ti_sdo_ipc_Notify_A_invArgument);
    Assert_isTrue(ISRESERVED(eventId), ti_sdo_ipc_Notify_A_reservedEvent);

    modKey = Gate_enterModule();

    obj = (ti_sdo_ipc_Notify_Object *)
          Notify_module->notifyHandles[clusterId][lineId];

    Assert_isTrue(obj != NULL, ti_sdo_ipc_Notify_A_notRegistered);

    if (obj->callbacks[strippedEventId].fnNotifyCbck) {
        if (procId != MultiProc_self()) {
            /*
             *  First, Tell the remote notify driver that the event is now
             *  unregistered
             */
            INotifyDriver_unregisterEvent(obj->driverHandle,
                                          strippedEventId);
        }

        /*
         *  No need to protect these modifications with the system gate because
         *  we shouldn't get preempted by Notify_exec after INotifyDriver_
         *  unregisterEvent.
         */
        obj->callbacks[strippedEventId].fnNotifyCbck = NULL;
        obj->callbacks[strippedEventId].cbckArg = NULL;

        status = Notify_S_SUCCESS;
    }
    else {
        /* No callback is registered. Fail. */
        status = Notify_E_FAIL;
    }

    Gate_leaveModule(modKey);

    return (status);
}
Ejemplo n.º 12
0
/*
 *  ======== Notify_registerEventSingle ========
 */
Int Notify_registerEventSingle(UInt16                 procId,
                               UInt16                 lineId,
                               UInt32                 eventId,
                               Notify_FnNotifyCbck    fnNotifyCbck,
                               UArg                   cbckArg)
{
    UInt32        strippedEventId = (eventId & 0xFFFF);
    UInt16 clusterId = ti_sdo_utils_MultiProc_getClusterId(procId);
    UInt          modKey;
    Int           status;
    ti_sdo_ipc_Notify_Object *obj;

    Assert_isTrue(procId < ti_sdo_utils_MultiProc_numProcessors &&
                  lineId < ti_sdo_ipc_Notify_numLines, ti_sdo_ipc_Notify_A_invArgument);
    Assert_isTrue(strippedEventId < ti_sdo_ipc_Notify_numEvents,
                  ti_sdo_ipc_Notify_A_invArgument);
    Assert_isTrue(ISRESERVED(eventId), ti_sdo_ipc_Notify_A_reservedEvent);

    modKey = Gate_enterModule();

    obj = (ti_sdo_ipc_Notify_Object *)
          Notify_module->notifyHandles[clusterId][lineId];

    Assert_isTrue(obj != NULL, ti_sdo_ipc_Notify_A_notRegistered);

    if (obj->callbacks[strippedEventId].fnNotifyCbck) {
        /* A callback is already registered. Fail. */
        status = Notify_E_ALREADYEXISTS;
    }
    else {
        /*
         *  No callback is registered. Register it. There is no need to protect
         *  these modifications because the event isn't registered yet.
         */
        obj->callbacks[strippedEventId].fnNotifyCbck = (Fxn)fnNotifyCbck;
        obj->callbacks[strippedEventId].cbckArg = cbckArg;

        if (procId != MultiProc_self()) {
            /* Tell the remote notify driver that the event is now registered */
            INotifyDriver_registerEvent(obj->driverHandle, strippedEventId);
        }

        status = Notify_S_SUCCESS;
    }

    Gate_leaveModule(modKey);

    return (status);
}
Ejemplo n.º 13
0
/*
 *  ======== ti_sdo_ipc_Ipc_getMasterAddr ========
 */
Ptr ti_sdo_ipc_Ipc_getMasterAddr(UInt16 remoteProcId, Ptr sharedAddr)
{
    Int slot;
    UInt16 masterId;
    volatile ti_sdo_ipc_Ipc_Reserved *master;
    SizeT reservedSize = ti_sdo_ipc_Ipc_reservedSizePerProc();

    /* determine the master's procId and slot */
    if (MultiProc_self() < remoteProcId) {
        masterId = ti_sdo_utils_MultiProc_getClusterId(remoteProcId);
        slot = ti_sdo_utils_MultiProc_getClusterId(MultiProc_self());
    }
    else {
        masterId = ti_sdo_utils_MultiProc_getClusterId(MultiProc_self());
        slot = ti_sdo_utils_MultiProc_getClusterId(remoteProcId);
    }

    /* determine the reserve address for master between self and remote */
    master = (ti_sdo_ipc_Ipc_Reserved *)((UInt32)sharedAddr +
             ((masterId * reservedSize) +
             (slot * sizeof(ti_sdo_ipc_Ipc_Reserved))));

    return ((Ptr)master);
}
Ejemplo n.º 14
0
/*
 *  ======== ti_sdo_ipc_Ipc_getSlaveAddr ========
 */
Ptr ti_sdo_ipc_Ipc_getSlaveAddr(UInt16 remoteProcId, Ptr sharedAddr)
{
    Int slot;
    UInt16 slaveId;
    volatile ti_sdo_ipc_Ipc_Reserved *slave;
    SizeT reservedSize = ti_sdo_ipc_Ipc_reservedSizePerProc();

    /* determine the slave's procId and slot */
    if (MultiProc_self() < remoteProcId) {
        slaveId = ti_sdo_utils_MultiProc_getClusterId(MultiProc_self());
        slot = ti_sdo_utils_MultiProc_getClusterId(remoteProcId) - 1;
    }
    else {
        slaveId = ti_sdo_utils_MultiProc_getClusterId(remoteProcId);
        slot = ti_sdo_utils_MultiProc_getClusterId(MultiProc_self()) - 1;
    }

    /* determine the reserve address for slave between self and remote */
    slave = (ti_sdo_ipc_Ipc_Reserved *)((UInt32)sharedAddr +
            ((slaveId * reservedSize) +
            (slot * sizeof(ti_sdo_ipc_Ipc_Reserved))));

    return ((Ptr)slave);
}
Ejemplo n.º 15
0
/*
 *  ======== Ipc_isAttached ========
 */
Bool Ipc_isAttached(UInt16 remoteProcId)
{
    UInt16 clusterId = ti_sdo_utils_MultiProc_getClusterId(remoteProcId);

    /* Assert remoteProcId is in our cluster */
    Assert_isTrue(clusterId < ti_sdo_utils_MultiProc_numProcsInCluster,
                  ti_sdo_utils_MultiProc_A_invalidMultiProcId);

    if (remoteProcId == MultiProc_self()) {
        return (FALSE);
    }
    else {
        return (Ipc_module->procEntry[clusterId].attached);
    }
}
Ejemplo n.º 16
0
/*
 *  ======== ti_sdo_ipc_Ipc_getEntry ========
 */
Void ti_sdo_ipc_Ipc_getEntry(ti_sdo_ipc_Ipc_Entry *entry)
{
    UInt16 clusterId = ti_sdo_utils_MultiProc_getClusterId(entry->remoteProcId);

    /* Assert remoteProcId is in our cluster */
    Assert_isTrue(clusterId < ti_sdo_utils_MultiProc_numProcsInCluster,
                  ti_sdo_utils_MultiProc_A_invalidMultiProcId);

    /* Get the setupNotify flag */
    entry->setupNotify =
        Ipc_module->procEntry[clusterId].entry.setupNotify;

    /* Get the setupMessageQ flag */
    entry->setupMessageQ =
        Ipc_module->procEntry[clusterId].entry.setupMessageQ;
}
Ejemplo n.º 17
0
/*
 *  ======== Notify_sendEvent ========
 */
Int Notify_sendEvent(UInt16   procId,
                     UInt16   lineId,
                     UInt32   eventId,
                     UInt32   payload,
                     Bool     waitClear)
{
    UInt32        strippedEventId = (eventId & 0xFFFF);
    UInt16        clusterId = ti_sdo_utils_MultiProc_getClusterId(procId);
    Int           status;
    ti_sdo_ipc_Notify_Object *obj;
    UInt          sysKey;

    Assert_isTrue(procId < ti_sdo_utils_MultiProc_numProcessors &&
                  lineId < ti_sdo_ipc_Notify_numLines, ti_sdo_ipc_Notify_A_invArgument);
    Assert_isTrue(strippedEventId < ti_sdo_ipc_Notify_numEvents,
                  ti_sdo_ipc_Notify_A_invArgument);
    Assert_isTrue(ISRESERVED(eventId), ti_sdo_ipc_Notify_A_reservedEvent);

    obj = (ti_sdo_ipc_Notify_Object *)
          Notify_module->notifyHandles[clusterId][lineId];

    Assert_isTrue(obj != NULL, ti_sdo_ipc_Notify_A_notRegistered);

    if (procId != MultiProc_self()) {
        /* Send a remote event */
        status = INotifyDriver_sendEvent(obj->driverHandle,
                                         strippedEventId,
                                         payload, waitClear);
    }
    else {
        /*
         *  The check agaist non-NULL fnNotifyCbCk must be atomic with
         *  Notify_exec so Notify_exec doesn't encounter a null callback.
         */
        sysKey = Hwi_disable();

        /*
         *  If nesting == 0 (the driver is enabled) and the event is enabled,
         *  send the event
         */
        if (obj->callbacks[strippedEventId].fnNotifyCbck == NULL) {
            /* No callbacks are registered locally for the event. */
            status = Notify_E_EVTNOTREGISTERED;
        }
        else if (obj->nesting != 0) {
            /* Driver is disabled */
            status = Notify_E_FAIL;
        }
        else if (!TEST_BIT (Notify_module->localEnableMask, strippedEventId)) {
            /* Event is disabled */
            status = Notify_E_EVTDISABLED;
        }
        else {
            /* Execute the callback function registered to the event */
            ti_sdo_ipc_Notify_exec(obj, strippedEventId, payload);

            status = Notify_S_SUCCESS;
        }

        Hwi_restore(sysKey);
    }

    return (status);
}
Ejemplo n.º 18
0
/*
 *  ======== Ipc_attach ========
 */
Int Ipc_attach(UInt16 remoteProcId)
{
    Int i;
    Ptr sharedAddr;
    SizeT memReq;
    volatile ti_sdo_ipc_Ipc_Reserved *slave;
    ti_sdo_ipc_Ipc_ProcEntry *ipc;
    Error_Block eb;
    SharedRegion_Entry entry;
    SizeT reservedSize = ti_sdo_ipc_Ipc_reservedSizePerProc();
    Bool cacheEnabled = SharedRegion_isCacheEnabled(0);
    UInt16 clusterId = ti_sdo_utils_MultiProc_getClusterId(remoteProcId);
    Int status;
    UInt hwiKey;

    /* Assert remoteProcId is in our cluster and isn't our own */
    Assert_isTrue(clusterId < ti_sdo_utils_MultiProc_numProcsInCluster,
                  ti_sdo_utils_MultiProc_A_invalidMultiProcId);
    Assert_isTrue(remoteProcId != MultiProc_self(),
                  ti_sdo_ipc_Ipc_A_invArgument);

    /* Check whether Ipc_start has been called.  If not, fail. */
    if (Ipc_module->ipcSharedAddr == NULL) {
        return (Ipc_E_FAIL);
    }

    /* for checking and incrementing attached below */
    hwiKey = Hwi_disable();

    /* Make sure its not already attached */
    if (Ipc_module->procEntry[clusterId].attached) {
        Ipc_module->procEntry[clusterId].attached++;
        /* restore interrupts and return */
        Hwi_restore(hwiKey);
        return (Ipc_S_ALREADYSETUP);
    }

    /* restore interrupts */
    Hwi_restore(hwiKey);

    /* get region 0 information */
    SharedRegion_getEntry(0, &entry);

    /* Make sure we've attached to owner of SR0 if we're not owner */
    if ((MultiProc_self() != entry.ownerProcId) &&
        (remoteProcId != entry.ownerProcId) &&
        !(Ipc_module->procEntry[ti_sdo_utils_MultiProc_getClusterId(
            entry.ownerProcId)].attached)) {
        return (Ipc_E_FAIL);
    }

    /* Init error block */
    Error_init(&eb);

    /* determine the slave's slot */
    slave = Ipc_getSlaveAddr(remoteProcId, Ipc_module->ipcSharedAddr);

    if (cacheEnabled) {
        Cache_inv((Ptr)slave, reservedSize, Cache_Type_ALL, TRUE);
    }

    /* Synchronize the processors. */
    status = Ipc_procSyncStart(remoteProcId, Ipc_module->ipcSharedAddr);
    if (status < 0) {
        return (status);
    }

    /* must be called before SharedRegion_attach */
    status = ti_sdo_ipc_GateMP_attach(remoteProcId,
            Ipc_module->gateMPSharedAddr);
    if (status < 0) {
        return (status);
    }

    /* retrieves the SharedRegion Heap handles */
    status = ti_sdo_ipc_SharedRegion_attach(remoteProcId);
    if (status < 0) {
        return (status);
    }

    /* get the attach parameters associated with remoteProcId */
    ipc = &(Ipc_module->procEntry[clusterId]);

    /* attach Notify if not yet attached and specified to set internal setup */
    if (!(Notify_intLineRegistered(remoteProcId, 0)) &&
        (ipc->entry.setupNotify)) {
        /* call Notify_attach */
        memReq = Notify_sharedMemReq(remoteProcId, Ipc_module->ipcSharedAddr);
        if (memReq != 0) {
            if (MultiProc_self() < remoteProcId) {
                /*
                 *  calloc required here due to race condition.  Its possible
                 *  that the slave, who creates the instance, tries a sendEvent
                 *  before the master has created its instance because the
                 *  state of memory was enabled from a previous run.
                 */
                sharedAddr = Memory_calloc(SharedRegion_getHeap(0),
                                       memReq,
                                       SharedRegion_getCacheLineSize(0),
                                       &eb);

                /* make sure alloc did not fail */
                if (sharedAddr == NULL) {
                    return (Ipc_E_MEMORY);
                }

                /* if cache enabled, wbInv the calloc above */
                if (cacheEnabled) {
                    Cache_wbInv(sharedAddr, memReq, Cache_Type_ALL, TRUE);
                }

                /* set the notify SRPtr */
                slave->notifySRPtr = SharedRegion_getSRPtr(sharedAddr, 0);
            }
            else {
                /* get the notify SRPtr */
                sharedAddr = SharedRegion_getPtr(slave->notifySRPtr);
            }
        }
        else {
            sharedAddr = NULL;
            slave->notifySRPtr = 0;
        }

        /* call attach to remote processor */
        status = Notify_attach(remoteProcId, sharedAddr);

        if (status < 0) {
            if (MultiProc_self() < remoteProcId && sharedAddr != NULL) {
                /* free the memory back to SharedRegion 0 heap */
                Memory_free(SharedRegion_getHeap(0), sharedAddr, memReq);
            }

            return (Ipc_E_FAIL);
        }
    }

    /* Must come after GateMP_start because depends on default GateMP */
    if (!(ti_sdo_utils_NameServer_isRegistered(remoteProcId)) &&
        (ipc->entry.setupNotify)) {
        memReq = ti_sdo_utils_NameServer_SetupProxy_sharedMemReq(
            Ipc_module->ipcSharedAddr);
        if (memReq != 0) {
            if (MultiProc_self() < remoteProcId) {
                sharedAddr = Memory_alloc(SharedRegion_getHeap(0),
                                     memReq,
                                     SharedRegion_getCacheLineSize(0),
                                     &eb);

                /* make sure alloc did not fail */
                if (sharedAddr == NULL) {
                    return (Ipc_E_MEMORY);
                }

                /* set the NSRN SRPtr */
                slave->nsrnSRPtr = SharedRegion_getSRPtr(sharedAddr, 0);
            }
            else {
                /* get the NSRN SRPtr */
                sharedAddr = SharedRegion_getPtr(slave->nsrnSRPtr);
            }
        }
        else {
            sharedAddr = NULL;
            slave->nsrnSRPtr = 0;
        }

        /* call attach to remote processor */
        status = ti_sdo_utils_NameServer_SetupProxy_attach(remoteProcId,
                                                           sharedAddr);

        if (status < 0) {
            if (MultiProc_self() < remoteProcId && sharedAddr != NULL) {
                /* free the memory back to SharedRegion 0 heap */
                Memory_free(SharedRegion_getHeap(0), sharedAddr, memReq);
            }

            return (Ipc_E_FAIL);
        }
    }

    /* Must come after GateMP_start because depends on default GateMP */
    if (!(ti_sdo_ipc_MessageQ_SetupTransportProxy_isRegistered(remoteProcId)) &&
        (ipc->entry.setupMessageQ)) {
        memReq = ti_sdo_ipc_MessageQ_SetupTransportProxy_sharedMemReq(
            Ipc_module->ipcSharedAddr);

        if (memReq != 0) {
            if (MultiProc_self() < remoteProcId) {
                sharedAddr = Memory_alloc(SharedRegion_getHeap(0),
                    memReq, SharedRegion_getCacheLineSize(0), &eb);

                /* make sure alloc did not fail */
                if (sharedAddr == NULL) {
                    return (Ipc_E_MEMORY);
                }

                /* set the transport SRPtr */
                slave->transportSRPtr = SharedRegion_getSRPtr(sharedAddr, 0);
            }
            else {
                /* get the transport SRPtr */
                sharedAddr = SharedRegion_getPtr(slave->transportSRPtr);
            }
        }
        else {
            sharedAddr = NULL;
            slave->transportSRPtr = 0;
        }

        /* call attach to remote processor */
        status = ti_sdo_ipc_MessageQ_SetupTransportProxy_attach(remoteProcId,
            sharedAddr);

        if (status < 0) {
            if (MultiProc_self() < remoteProcId && sharedAddr != NULL) {
                /* free the memory back to SharedRegion 0 heap */
                Memory_free(SharedRegion_getHeap(0), sharedAddr, memReq);
            }

            return (Ipc_E_FAIL);
        }
    }

    /* writeback invalidate slave's shared memory if cache enabled */
    if (cacheEnabled) {
        if (MultiProc_self() < remoteProcId) {
            Cache_wbInv((Ptr)slave, reservedSize, Cache_Type_ALL, TRUE);
        }
    }

    /* Call user attach fxns */
    for (i = 0; i < ti_sdo_ipc_Ipc_numUserFxns; i++) {
        if (ti_sdo_ipc_Ipc_userFxns[i].userFxn.attach) {
            status = ti_sdo_ipc_Ipc_userFxns[i].userFxn.attach(
                ti_sdo_ipc_Ipc_userFxns[i].arg, remoteProcId);

            if (status < 0) {
                return (status);
            }
        }
    }

    /* Finish the processor synchronization */
    status = ti_sdo_ipc_Ipc_procSyncFinish(remoteProcId,
        Ipc_module->ipcSharedAddr);

    if (status < 0) {
        return (status);
    }

    /* for atomically incrementing attached */
    hwiKey = Hwi_disable();

    /* now attached to remote processor */
    Ipc_module->procEntry[clusterId].attached++;

    /* restore interrupts */
    Hwi_restore(hwiKey);

    return (status);
}
Ejemplo n.º 19
0
/*
 *  ======== Ipc_writeConfig ========
 */
Int Ipc_writeConfig(UInt16 remoteProcId, UInt32 tag, Ptr cfg, SizeT size)
{
    Int status = Ipc_S_SUCCESS;
    UInt16 clusterId = ti_sdo_utils_MultiProc_getClusterId(remoteProcId);
    SharedRegion_SRPtr curSRPtr, *prevSRPtr;
    ti_sdo_ipc_Ipc_ConfigEntry *entry;
    Error_Block eb;
    Bool cacheEnabled = SharedRegion_isCacheEnabled(0);

    /* Assert that the remoteProc in our cluster */
    Assert_isTrue(clusterId < ti_sdo_utils_MultiProc_numProcsInCluster,
                  ti_sdo_utils_MultiProc_A_invalidMultiProcId);

    Error_init(&eb);

    if (cfg == NULL) {
        status = Ipc_E_FAIL;

        /* get head of local config list and set prevSRPtr to it */
        prevSRPtr = (Ipc_module->procEntry[clusterId].localConfigList);

        /* 
         *  When cfg is NULL, the last memory allocated from a previous
         *  Ipc_writeConfig call with the same remoteProcId, tag, and size
         *  is freed.
         */
        curSRPtr = *prevSRPtr;

        /* loop through list of config entries until matching entry is found */
        while (curSRPtr != ti_sdo_ipc_SharedRegion_INVALIDSRPTR) {
            /* convert Ptr associated with curSRPtr */
            entry = (ti_sdo_ipc_Ipc_ConfigEntry *)
                    (SharedRegion_getPtr(curSRPtr));

            /* make sure entry matches remoteProcId, tag, and size */
            if ((entry->remoteProcId == remoteProcId) &&
                (entry->tag == tag) &&
                (entry->size == size)) {
                /* Update the 'prev' next ptr */
                *prevSRPtr = (SharedRegion_SRPtr)entry->next;

                /* writeback the 'prev' ptr */
                if (cacheEnabled) {
                    Cache_wb(prevSRPtr,
                        sizeof(ti_sdo_ipc_Ipc_ConfigEntry),
                        Cache_Type_ALL,
                        FALSE);
                }

                /* free entry's memory back to shared heap */
                Memory_free(SharedRegion_getHeap(0),
                    entry,
                    size + sizeof(ti_sdo_ipc_Ipc_ConfigEntry));

                /* set the status to success */
                status = Ipc_S_SUCCESS;
                break;
            }

            /* set the 'prev' to the 'cur' SRPtr */
            prevSRPtr = (SharedRegion_SRPtr *)(&entry->next);

            /* point to next config entry */
            curSRPtr = (SharedRegion_SRPtr)entry->next;
        }

        /* return that status */
        return (status);
    }

    /* Allocate memory from the shared heap (System Heap) */
    entry = Memory_alloc(SharedRegion_getHeap(0),
                         size + sizeof(ti_sdo_ipc_Ipc_ConfigEntry),
                         SharedRegion_getCacheLineSize(0),
                         &eb);

    if (entry == NULL) {
        return (Ipc_E_FAIL);
    }

    /* set the entry */
    entry->remoteProcId = remoteProcId;
    entry->localProcId = MultiProc_self();
    entry->tag = tag;
    entry->size = size;
    memcpy((Ptr)((UInt32)entry + sizeof(ti_sdo_ipc_Ipc_ConfigEntry)), cfg,
                  size);
        
    /* point the entry's next to the first entry in the list */
    entry->next = *Ipc_module->procEntry[clusterId].localConfigList;

    /* first write-back the entry if cache is enabled */
    if (cacheEnabled) {
        Cache_wb(entry, size + sizeof(ti_sdo_ipc_Ipc_ConfigEntry),
                 Cache_Type_ALL,
                 FALSE);
    }

    /* set the entry as the new first in the list */
    *Ipc_module->procEntry[clusterId].localConfigList =
        SharedRegion_getSRPtr(entry, 0);

    /* write-back the config list */
    if (cacheEnabled) {
        Cache_wb(Ipc_module->procEntry[clusterId].localConfigList, 
                 SharedRegion_getCacheLineSize(0), 
                 Cache_Type_ALL, 
                 FALSE);
    }

    return (status);
}
Ejemplo n.º 20
0
/*
 *  ======== Notify_unregisterEvent ========
 */
Int Notify_unregisterEvent(UInt16                 procId,
                           UInt16                 lineId,
                           UInt32                 eventId,
                           Notify_FnNotifyCbck    fnNotifyCbck,
                           UArg                   cbckArg)
{
    UInt32  strippedEventId = (eventId & 0xFFFF);
    UInt16  clusterId = ti_sdo_utils_MultiProc_getClusterId(procId);
    Int     status;
    UInt    sysKey, modKey;
    ti_sdo_ipc_Notify_Object *obj;
    List_Handle eventList;
    ti_sdo_ipc_Notify_EventListener *listener;
    UInt    count = 0;

    Assert_isTrue(procId < ti_sdo_utils_MultiProc_numProcessors && lineId <
                  ti_sdo_ipc_Notify_numLines, ti_sdo_ipc_Notify_A_invArgument);
    Assert_isTrue(strippedEventId < ti_sdo_ipc_Notify_numEvents,
                  ti_sdo_ipc_Notify_A_invArgument);
    Assert_isTrue(ISRESERVED(eventId), ti_sdo_ipc_Notify_A_reservedEvent);

    modKey = Gate_enterModule();

    obj = (ti_sdo_ipc_Notify_Object *)
          Notify_module->notifyHandles[clusterId][lineId];

    Assert_isTrue(obj != NULL, ti_sdo_ipc_Notify_A_notRegistered);

    eventList = List_Object_get(obj->eventList, strippedEventId);

    if (List_empty(eventList)) {
        return (Notify_E_NOTFOUND);
    }

    /* Get the first listener on the list */
    listener = (ti_sdo_ipc_Notify_EventListener *)List_next(eventList, NULL);

    while (listener != NULL) {
        count++;
        if (listener->callback.fnNotifyCbck == (Fxn)fnNotifyCbck &&
                listener->callback.cbckArg == cbckArg ) {
            break;      /* found a match! */
        }
        listener = (ti_sdo_ipc_Notify_EventListener *)
                   List_next(eventList, (List_Elem *)listener);
    }

    if (listener == NULL) {
        /* Event listener not found */
        status = Notify_E_NOTFOUND;
    }
    else {
        if (count == 1 && List_next(eventList, (List_Elem *)listener) == NULL) {
            /*
             *  If only one element counted so far and the List_next returns
             *  NULL, the list will be empty after unregistering.  Therefore,
             *  unregister the callback function.
             */
            status = Notify_unregisterEventSingle(procId, lineId, eventId);
            /* unregisterEvent should always suceed */
            Assert_isTrue(status == Notify_S_SUCCESS,
                          ti_sdo_ipc_Notify_A_internal);

            /*  No need to protect the list removal: the event's unregistered */
            List_remove(eventList, (List_Elem *)listener);
        }
        else {
            /*
             *  Need to atomically remove from the list using the system gate
             *  because Notify_exec might preempt List_remove (the event is
             *  still registered)
             */
            sysKey = Hwi_disable();
            List_remove(eventList, (List_Elem *)listener);
            Hwi_restore(sysKey);
        }

        /* Free the memory alloc'ed for the event listener */
        Memory_free(ti_sdo_ipc_Notify_Object_heap(), listener,
                    sizeof(ti_sdo_ipc_Notify_EventListener));

        status = Notify_S_SUCCESS;
    }

    Gate_leaveModule(modKey);

    return (status);
}
Ejemplo n.º 21
0
/*
 *  ======== Ipc_detach ========
 */
Int Ipc_detach(UInt16 remoteProcId)
{
    Int i;
    UInt16 baseId = MultiProc_getBaseIdOfCluster();
    UInt16 clusterId = ti_sdo_utils_MultiProc_getClusterId(remoteProcId);
    Ptr notifySharedAddr;
    Ptr nsrnSharedAddr;
    Ptr msgqSharedAddr;
    volatile ti_sdo_ipc_Ipc_Reserved *slave, *master;
    SharedRegion_Entry entry;
    ti_sdo_ipc_Ipc_ProcEntry *ipc;
    SizeT reservedSize = ti_sdo_ipc_Ipc_reservedSizePerProc();
    Bool cacheEnabled = SharedRegion_isCacheEnabled(0);
    Int status = Ipc_S_SUCCESS;
    UInt hwiKey;

    /* Assert remoteProcId is in our cluster and isn't our own */
    Assert_isTrue(clusterId < ti_sdo_utils_MultiProc_numProcsInCluster,
                  ti_sdo_utils_MultiProc_A_invalidMultiProcId);
    Assert_isTrue(remoteProcId != MultiProc_self(),
                  ti_sdo_ipc_Ipc_A_invArgument);

    /* for checking and incrementing attached below */
    hwiKey = Hwi_disable();

    if (Ipc_module->procEntry[clusterId].attached > 1) {
        /* only detach if attach count reaches 1 */
        Ipc_module->procEntry[clusterId].attached--;
        Hwi_restore(hwiKey);
        return (Ipc_S_BUSY);
    }
    else if (Ipc_module->procEntry[clusterId].attached == 0) {
        /* already detached, restore interrupts and return success */
        Hwi_restore(hwiKey);
        return (Ipc_S_SUCCESS);
    }

    /* restore interrupts */
    Hwi_restore(hwiKey);

    /* get region 0 information */
    SharedRegion_getEntry(0, &entry);

    /*
     *  Make sure we detach from all other procs in cluster before
     *  detaching from owner of SR 0.
     */
    if (remoteProcId == entry.ownerProcId) {
        for (i = 0; i < ti_sdo_utils_MultiProc_numProcsInCluster; i++, baseId++) {
            if ((baseId != MultiProc_self()) && (baseId != entry.ownerProcId) &&
                (Ipc_module->procEntry[i].attached)) {
                return (Ipc_E_FAIL);
            }
        }
    }

    /* get the paramters associated with remoteProcId */
    ipc = &(Ipc_module->procEntry[clusterId]);

    /* determine the slave's slot */
    slave = Ipc_getSlaveAddr(remoteProcId, Ipc_module->ipcSharedAddr);

    /* determine the master's slot */
    master = ti_sdo_ipc_Ipc_getMasterAddr(remoteProcId,
        Ipc_module->ipcSharedAddr);

    if (cacheEnabled) {
        Cache_inv((Ptr)slave, reservedSize, Cache_Type_ALL, TRUE);
        Cache_inv((Ptr)master, reservedSize, Cache_Type_ALL, TRUE);
    }

    if (MultiProc_self() < remoteProcId) {
        /* check to make sure master is not trying to attach */
        if (master->startedKey == ti_sdo_ipc_Ipc_PROCSYNCSTART) {
            return (Ipc_E_NOTREADY);
        }
    }
    else {
        /* check to make sure slave is not trying to attach */
        if (slave->startedKey == ti_sdo_ipc_Ipc_PROCSYNCSTART) {
            return (Ipc_E_NOTREADY);
        }
    }

    /* The slave processor waits for master to finish its detach sequence */
    if (MultiProc_self() < remoteProcId) {
        if (master->startedKey != ti_sdo_ipc_Ipc_PROCSYNCDETACH) {
            return (Ipc_E_NOTREADY);
        }
    }

    /* Call user detach fxns */
    for (i = 0; i < ti_sdo_ipc_Ipc_numUserFxns; i++) {
        if (ti_sdo_ipc_Ipc_userFxns[i].userFxn.detach) {
            status = ti_sdo_ipc_Ipc_userFxns[i].userFxn.detach(
                ti_sdo_ipc_Ipc_userFxns[i].arg, remoteProcId);

            if (status < 0) {
                return (status);
            }
        }
    }

    if ((ipc->entry.setupMessageQ) &&
       (ti_sdo_ipc_MessageQ_SetupTransportProxy_isRegistered(remoteProcId))) {
        /* call MessageQ_detach for remote processor */
        status = ti_sdo_ipc_MessageQ_SetupTransportProxy_detach(remoteProcId);
        if (status < 0) {
            return (Ipc_E_FAIL);
        }

        if (slave->transportSRPtr) {
            /* free the memory if slave processor */
            if (MultiProc_self() < remoteProcId) {
                /* get the pointer to MessageQ transport instance */
                msgqSharedAddr = SharedRegion_getPtr(slave->transportSRPtr);

                /* free the memory back to SharedRegion 0 heap */
                Memory_free(SharedRegion_getHeap(0),
                    msgqSharedAddr,
                    ti_sdo_ipc_MessageQ_SetupTransportProxy_sharedMemReq(
                        msgqSharedAddr));

                /* set pointer for MessageQ transport instance back to NULL */
                slave->transportSRPtr = NULL;
            }
        }
    }

    if ((ipc->entry.setupNotify) &&
        (ti_sdo_utils_NameServer_isRegistered(remoteProcId))) {
        /* call NameServer_SetupProxy_detach for remote processor */
        status = ti_sdo_utils_NameServer_SetupProxy_detach(remoteProcId);
        if (status < 0) {
            return (Ipc_E_FAIL);
        }

        if (slave->nsrnSRPtr) {
            /* free the memory if slave processor */
            if (MultiProc_self() < remoteProcId) {
                /* get the pointer to NSRN instance */
                nsrnSharedAddr = SharedRegion_getPtr(slave->nsrnSRPtr);

                /* free the memory back to SharedRegion 0 heap */
                Memory_free(SharedRegion_getHeap(0),
                            nsrnSharedAddr,
                            ti_sdo_utils_NameServer_SetupProxy_sharedMemReq(
                                nsrnSharedAddr));

                /* set pointer for NSRN instance back to NULL */
                slave->nsrnSRPtr = NULL;
            }
        }
    }

    if ((ipc->entry.setupNotify) &&
        (Notify_intLineRegistered(remoteProcId, 0))) {
        /* call Notify_detach for remote processor */
        status = ti_sdo_ipc_Notify_detach(remoteProcId);
        if (status < 0) {
            return (Ipc_E_FAIL);
        }

        if (slave->notifySRPtr) {
            /* free the memory if slave processor */
            if (MultiProc_self() < remoteProcId) {
                /* get the pointer to Notify instance */
                notifySharedAddr = SharedRegion_getPtr(slave->notifySRPtr);

                /* free the memory back to SharedRegion 0 heap */
                Memory_free(SharedRegion_getHeap(0),
                            notifySharedAddr,
                            Notify_sharedMemReq(remoteProcId, notifySharedAddr));

                /* set pointer for Notify instance back to NULL */
                slave->notifySRPtr = NULL;
            }
        }
    }

    /* close any HeapMemMP which may have been opened */
    status = ti_sdo_ipc_SharedRegion_detach(remoteProcId);
    if (status < 0) {
        return (status);
    }
    
    /* close any GateMP which may have been opened */
    status = ti_sdo_ipc_GateMP_detach(remoteProcId);
    if (status < 0) {
        return (status);
    }

    if (MultiProc_self() < remoteProcId) {
        slave->configListHead = ti_sdo_ipc_SharedRegion_INVALIDSRPTR;
        slave->startedKey = ti_sdo_ipc_Ipc_PROCSYNCDETACH;
        if (cacheEnabled) {
            Cache_wbInv((Ptr)slave, reservedSize, Cache_Type_ALL, TRUE);
        }
    }
    else {
        master->configListHead = ti_sdo_ipc_SharedRegion_INVALIDSRPTR;
        master->startedKey = ti_sdo_ipc_Ipc_PROCSYNCDETACH;
        if (cacheEnabled) {
            Cache_wbInv((Ptr)master, reservedSize, Cache_Type_ALL, TRUE);
        }
    }

    /* attached must be decremented atomically */
    hwiKey = Hwi_disable();

    /* now detached from remote processor */
    Ipc_module->procEntry[clusterId].attached--;

    /* restore interrupts */
    Hwi_restore(hwiKey);

    return (status);
}
Ejemplo n.º 22
0
/*
 *  ======== ti_sdo_ipc_Ipc_procSyncStart ========
 *  The owner of SharedRegion 0 writes to its reserve memory address
 *  in region 0 to let the other processors know it has started.
 *  It then spins until the other processors start.
 *  The other processors write their reserve memory address in
 *  region 0 to let the owner processor know they've started.
 *  The other processors then spin until the owner processor writes
 *  to let them know that its finished the process of synchronization
 *  before continuing.
 */
Int ti_sdo_ipc_Ipc_procSyncStart(UInt16 remoteProcId, Ptr sharedAddr)
{
    volatile ti_sdo_ipc_Ipc_Reserved *self, *remote;
    ti_sdo_ipc_Ipc_ProcEntry *ipc;
    UInt16 clusterId = ti_sdo_utils_MultiProc_getClusterId(remoteProcId);
    SizeT reservedSize = ti_sdo_ipc_Ipc_reservedSizePerProc();
    Bool cacheEnabled = SharedRegion_isCacheEnabled(0);

    /* don't do any synchronization if procSync is NONE */
    if (ti_sdo_ipc_Ipc_procSync == ti_sdo_ipc_Ipc_ProcSync_NONE) {
        return (Ipc_S_SUCCESS);
    }

    /* determine self and remote pointers */
    if (MultiProc_self() < remoteProcId) {
        self = Ipc_getSlaveAddr(remoteProcId, sharedAddr);
        remote = ti_sdo_ipc_Ipc_getMasterAddr(remoteProcId, sharedAddr);
    }
    else {
        self = ti_sdo_ipc_Ipc_getMasterAddr(remoteProcId, sharedAddr);
        remote = Ipc_getSlaveAddr(remoteProcId, sharedAddr);
    }

    /* construct the config list */
    ipc = &(Ipc_module->procEntry[clusterId]);

    ipc->localConfigList = (Ptr)&self->configListHead;
    ipc->remoteConfigList = (Ptr)&remote->configListHead;

    *ipc->localConfigList = ti_sdo_ipc_SharedRegion_INVALIDSRPTR;

    if (cacheEnabled) {
        Cache_wbInv(ipc->localConfigList, reservedSize, Cache_Type_ALL, TRUE);
    }

    if (MultiProc_self() < remoteProcId) {
        /* set my processor's reserved key to start */
        self->startedKey = ti_sdo_ipc_Ipc_PROCSYNCSTART;

        /* write back my processor's reserve key */
        if (cacheEnabled) {
            Cache_wbInv((Ptr)self, reservedSize, Cache_Type_ALL, TRUE);
        }

        /* wait for remote processor to start */
        if (cacheEnabled) {
            Cache_inv((Ptr)remote, reservedSize, Cache_Type_ALL, TRUE);
        }

        if (remote->startedKey != ti_sdo_ipc_Ipc_PROCSYNCSTART) {
            return (Ipc_E_NOTREADY);
        }
    }
    else {
        /*  wait for remote processor to start */
        if (cacheEnabled) {
            Cache_inv((Ptr)remote, reservedSize, Cache_Type_ALL, TRUE);
        }

        if ((self->startedKey != ti_sdo_ipc_Ipc_PROCSYNCSTART) &&
            (remote->startedKey != ti_sdo_ipc_Ipc_PROCSYNCSTART)) {
            return (Ipc_E_NOTREADY);
        }

        /* set my processor's reserved key to start */
        self->startedKey = ti_sdo_ipc_Ipc_PROCSYNCSTART;

        /* write my processor's reserve key back */
        if (cacheEnabled) {
            Cache_wbInv((Ptr)self, reservedSize, Cache_Type_ALL, TRUE);

            /* wait for remote processor to finish */
            Cache_inv((Ptr)remote, reservedSize, Cache_Type_ALL, TRUE);
        }

        if (remote->startedKey != ti_sdo_ipc_Ipc_PROCSYNCFINISH) {
            return (Ipc_E_NOTREADY);
        }
    }

    return (Ipc_S_SUCCESS);
}
Ejemplo n.º 23
0
/*
 *  ======== Notify_registerEvent ========
 */
Int Notify_registerEvent(UInt16                 procId,
                         UInt16                 lineId,
                         UInt32                 eventId,
                         Notify_FnNotifyCbck    fnNotifyCbck,
                         UArg                   cbckArg)
{
    UInt32               strippedEventId = (eventId & 0xFFFF);
    UInt16 clusterId =   ti_sdo_utils_MultiProc_getClusterId(procId);
    Int                  status;
    ti_sdo_ipc_Notify_Object        *obj;
    UInt                 modKey;
    List_Handle          eventList;
    ti_sdo_ipc_Notify_EventListener *listener;
    Bool                 listWasEmpty;
    Error_Block          eb;

    Assert_isTrue(procId < ti_sdo_utils_MultiProc_numProcessors &&
                  lineId < ti_sdo_ipc_Notify_numLines, ti_sdo_ipc_Notify_A_invArgument);
    Assert_isTrue(strippedEventId < ti_sdo_ipc_Notify_numEvents,
                  ti_sdo_ipc_Notify_A_invArgument);
    Assert_isTrue(ISRESERVED(eventId), ti_sdo_ipc_Notify_A_reservedEvent);

    Error_init(&eb);

    modKey = Gate_enterModule();

    obj = (ti_sdo_ipc_Notify_Object *)
          Notify_module->notifyHandles[clusterId][lineId];

    Assert_isTrue(obj != NULL, ti_sdo_ipc_Notify_A_notRegistered);

    /* Allocate a new EventListener */
    listener = Memory_alloc(ti_sdo_ipc_Notify_Object_heap(),
                            sizeof(ti_sdo_ipc_Notify_EventListener), 0, &eb);
    if (listener == NULL) {
        /* Listener memory allocation failed.  Leave module gate & return */
        Gate_leaveModule(modKey);

        return (Notify_E_MEMORY);
    }

    listener->callback.fnNotifyCbck = (Fxn)fnNotifyCbck;
    listener->callback.cbckArg = cbckArg;

    eventList = List_Object_get(obj->eventList, strippedEventId);

    /*
     *  Store whether the list was empty so we know whether to register the
     *  callback
     */
    listWasEmpty = List_empty(eventList);

    /*
     *  Need to atomically add to the list using the system gate because
     *  Notify_exec might preempt List_remove.  List_put is atomic.
     */
    List_put(eventList, (List_Elem *)listener);

    if (listWasEmpty) {
        /*
         *  Registering this event for the first time.  Need to register the
         *  callback function.
         */
        status = Notify_registerEventSingle(procId, lineId, eventId,
                                            Notify_execMany, (UArg)obj);

        /* Notify_registerEventSingle should always succeed */
        Assert_isTrue(status == Notify_S_SUCCESS,
                      ti_sdo_ipc_Notify_A_internal);
    }

    status = Notify_S_SUCCESS;

    Gate_leaveModule(modKey);

    return (status);
}