Beispiel #1
0
/*
 *  ======== GatePetersonN_Instance_init ========
 */
Int GatePetersonN_Instance_init(GatePetersonN_Object *obj,
                               IGateProvider_Handle localGate,
                               const GatePetersonN_Params *params,
                               Error_Block *eb)
{
    SizeT  offset;
    SizeT  minAlign = Memory_getMaxDefaultTypeAlign();
    SizeT  i;

    if (SharedRegion_getCacheLineSize(params->regionId) > minAlign) {
            minAlign = SharedRegion_getCacheLineSize(params->regionId);
    }

    Assert_isTrue(params->sharedAddr != NULL, ti_sdo_ipc_Ipc_A_invParam);
    Assert_isTrue(GatePetersonN_numInstances != 0, ti_sdo_ipc_Ipc_A_invParam);

    obj->localGate      = localGate;
    obj->cacheEnabled   = SharedRegion_isCacheEnabled(params->regionId);
    obj->cacheLineSize  = SharedRegion_getCacheLineSize(params->regionId);
    obj->nested  = 0;

    /* This is not cluster aware:
     * obj->numProcessors  = MultiProc_getNumProcessors();
     * obj->selfId         = MultiProc_self();
     */

    /* Cluster aware initialization */
    obj->numProcessors  = MultiProc_getNumProcsInCluster();

    /* set selfId to 0-based offset within cluster. */
    obj->selfId         = MultiProc_self() - MultiProc_getBaseIdOfCluster();

    /* Assign shared memory addresses for the protocol state variables */

    offset = 0;

    for (i=0; i < obj->numProcessors; i++) {
        obj->enteredStage[i] = (Int32 *)((UArg)(params->sharedAddr) + offset);
        offset += minAlign;
    }

    for (i=0; i < obj->numProcessors - 1; i++) {
	obj->lastProcEnteringStage[i] = (Int32 *)((UArg)(params->sharedAddr)
                                                   + offset);
        offset += minAlign;
    }

    if (!params->openFlag) {
        /* Creating. */
        obj->objType = ti_sdo_ipc_Ipc_ObjType_CREATEDYNAMIC;
        GatePetersonN_postInit(obj);
    }
    else {
        /* Opening. */
        obj->objType = ti_sdo_ipc_Ipc_ObjType_OPENDYNAMIC;
    }

    return (0);
}
Beispiel #2
0
/*
 *  ======== MultiProc_setBaseIdOfCluster ========
 */
Int MultiProc_setBaseIdOfCluster(UInt16 id)
{
    /*
     *  Check the following
     *  1. Make sure the statically configured constant was invalid.
     *     To call setBaseIdOfCluster, the id must have been set to invalid.
     *  2. Make sure the call is made before module startup
     */
    if ((MultiProc_getBaseIdOfCluster() == MultiProc_INVALIDID) &&
        (Startup_rtsDone() == FALSE)) {
        /* It is ok to set the id */
        MultiProc_module->baseIdOfCluster = id;
        return (MultiProc_S_SUCCESS);
    }

    return (MultiProc_E_FAIL);
}
Beispiel #3
0
/*
 *  ======== Ipc_start ========
 */
Int Ipc_start()
{
    Int i;
    UInt16 baseId = MultiProc_getBaseIdOfCluster();
    SharedRegion_Entry entry;
    Ptr ipcSharedAddr;
    Ptr gateMPSharedAddr;
    GateMP_Params gateMPParams;
    Int status;

    /* Check whether Ipc_start has been called.  If so, succeed. */
    if (Ipc_module->ipcSharedAddr != NULL) {
        return (Ipc_S_ALREADYSETUP);
    }

    if (ti_sdo_ipc_Ipc_generateSlaveDataForHost) {
        /* get Ipc_sr0MemorySetup out of the cache */
        Cache_inv(&Ipc_sr0MemorySetup,
              sizeof(Ipc_sr0MemorySetup),
              Cache_Type_ALL,
              TRUE);

        /* check Ipc_sr0MemorySetup variable */
        if (Ipc_sr0MemorySetup == 0x0) {
            return (Ipc_E_NOTREADY);
        }
    }

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

    /* if entry is not valid then return */
    if (entry.isValid == FALSE) {
        return (Ipc_E_NOTREADY);
    }

    /*
     *  Need to reserve memory in region 0 for processor synchronization.
     *  This must done before SharedRegion_start().
     */
    ipcSharedAddr = ti_sdo_ipc_SharedRegion_reserveMemory(
            0, Ipc_getRegion0ReservedSize());

    /* must reserve memory for GateMP before SharedRegion_start() */
    gateMPSharedAddr = ti_sdo_ipc_SharedRegion_reserveMemory(0,
            ti_sdo_ipc_GateMP_getRegion0ReservedSize());

    /* Init params for default gate (must match those in GateMP_start()) */
    GateMP_Params_init(&gateMPParams);
    gateMPParams.localProtect  = GateMP_LocalProtect_TASKLET;

    if (ti_sdo_utils_MultiProc_numProcessors > 1) {
        gateMPParams.remoteProtect = GateMP_RemoteProtect_SYSTEM;
    }
    else {
        gateMPParams.remoteProtect = GateMP_RemoteProtect_NONE;
    }

    /* reserve memory for default gate before SharedRegion_start() */
    ti_sdo_ipc_SharedRegion_reserveMemory(0, GateMP_sharedMemReq(&gateMPParams));

    /* clear the reserved memory */
    ti_sdo_ipc_SharedRegion_clearReservedMemory();

    /* Set shared addresses */
    Ipc_module->ipcSharedAddr = ipcSharedAddr;
    Ipc_module->gateMPSharedAddr = gateMPSharedAddr;

    /* create default GateMP, must be called before SharedRegion start */
    status = ti_sdo_ipc_GateMP_start(Ipc_module->gateMPSharedAddr);
    if (status < 0) {
        return (status);
    }

    /* create HeapMemMP in each SharedRegion */
    status = ti_sdo_ipc_SharedRegion_start();
    if (status < 0) {
        return (status);
    }

    /* Call attach for all procs if procSync is ALL */
    if (ti_sdo_ipc_Ipc_procSync == ti_sdo_ipc_Ipc_ProcSync_ALL) {
        /* Must attach to owner first to get default GateMP and HeapMemMP */
        if (MultiProc_self() != entry.ownerProcId) {
            do {
                status = Ipc_attach(entry.ownerProcId);
            } while (status == Ipc_E_NOTREADY);

            if (status < 0) {
                /* Ipc_attach failed. Get out of Ipc_start */
                return (status);
            }
        }

        /* Loop to attach to all other processors in cluster */
        for (i = 0; i < ti_sdo_utils_MultiProc_numProcsInCluster; i++, baseId++) {
            if ((baseId == MultiProc_self()) || (baseId == entry.ownerProcId)) {
                continue;
            }

            /* Skip the processor if there are no interrupt lines to it */
            if (Notify_numIntLines(baseId) == 0) {
                continue;
            }

            /* call Ipc_attach for every remote processor */
            do {
                status = Ipc_attach(baseId);
            } while (status == Ipc_E_NOTREADY);

            if (status < 0) {
                /* Ipc_attach failed. Get out of Ipc_start */
                return (status);
            }
        }
    }

    return (status);
}
Beispiel #4
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);
}
Beispiel #5
0
int main (int argc, char ** argv)
{
    Int status = 0;
    int opt;
    UInt numLoops = NUM_LOOPS_DFLT;
    UInt16 procId = PROC_ID_DFLT;
    UInt32 faultId = 0;

    while ((opt = getopt(argc, argv, "f:")) != -1) {
        switch (opt) {
          case 'f':
            /*
             * Argument for -f corresponds to remote-side "fault" commands.
             * Negative commands cause remote fault before remote MessageQ_put.
             * Positive commands cause remote fault after remote MessageQ_put.
             */
            faultId = atoi(optarg);
            printf("fault %d will be sent in 1st msg\n", faultId);
            break;

          default:
            fprintf(stderr, "Unknown arg '%s'\n", optarg);
            return 1;
        }
    }

    /* Parse Args: */
    switch (argc - optind + 1) {
        case 1:
           /* use defaults */
           break;
        case 2:
           numLoops   = atoi(argv[optind]);
           break;
        case 3:
           numLoops   = atoi(argv[optind]);
           procId     = atoi(argv[optind + 1]);
           break;
        default:
           printf("Usage: %s [<numLoops>] [<ProcId>]\n", argv[0]);
           printf("\tDefaults: numLoops: %d; ProcId: %d\n",
                   NUM_LOOPS_DFLT, PROC_ID_DFLT);
           exit(0);
    }

    /* configure the transport factory */
    Ipc_transportConfig(&TransportRpmsg_Factory);

    /* IPC initialization */
    status = Ipc_start();

    if (status < 0) {
        printf("Error: Ipc_start failed, error=%d\n", status);
        goto exit;
    }

    if ((procId == 0) || (procId >= (MultiProc_getBaseIdOfCluster() + MultiProc_getNumProcessors()))) {
        printf("ProcId (%d) must be nonzero and less than %d\n",
                procId, MultiProc_getBaseIdOfCluster() + MultiProc_getNumProcessors());
        Ipc_stop();
        exit(0);
    }
    printf("Using numLoops: %d; procId : %d\n", numLoops, procId);

    if (MessageQApp_execute(numLoops, procId, faultId) < 0) {
        int nAttachAttempts = 1;

        printf("MessageQApp_execute failed, attempting detach/attach...\n");
        Ipc_detach(procId);
        while (Ipc_attach(procId) != Ipc_S_SUCCESS) {
            nAttachAttempts++;
            if ((nAttachAttempts % 1000) == 0) {
                printf("Ipc_attach(%d) failed\n", procId);
            }
        }
        printf("Ipc_attach(%d) succeeded (after %d tries)\n", procId, nAttachAttempts);

        /* call without fault this time */
        MessageQApp_execute(numLoops, procId, 0);
    }

    Ipc_stop();

exit:
    return (status);
}