예제 #1
0
PUBLIC t_cm_error cm_SRV_allocateTraceBufferMemory(t_nmf_core_id coreId, t_cm_domain_id domainId)
{
    t_ee_state *state = cm_EEM_getExecutiveEngine(coreId);

    state->traceDataHandle = cm_DM_Alloc(domainId, SDRAM_EXT16,
                                         TRACE_BUFFER_SIZE * sizeof(struct t_nmf_trace) / 2, CM_MM_ALIGN_WORD, TRUE);
    if (state->traceDataHandle == INVALID_MEMORY_HANDLE)
        return CM_NO_MORE_MEMORY;
    else
    {
        t_uint32 mmdspAddr;
        int i;

        state->traceDataAddr = (struct t_nmf_trace*)cm_DSP_GetHostLogicalAddress(state->traceDataHandle);
        cm_DSP_GetDspAddress(state->traceDataHandle, &mmdspAddr);
        cm_writeAttribute(state->instance, "rtos/commonpart/traceDataAddr", mmdspAddr);

        eeState[coreId].readTracePointer = 0;
        eeState[coreId].lastReadedTraceRevision = 0;

        for(i = 0; i < TRACE_BUFFER_SIZE; i++)
            state->traceDataAddr[i].revision = 0;

        return CM_OK;
    }
}
예제 #2
0
/*
 * Bind component
 */
static void cm_bindLowLevelInterface(
        const t_interface_require_description *itfRequire,
        const t_interface_provide_description *itfLocalBC,	         /* On the same DSP */
        t_bf_info_ID bfInfoID, void* bfInfo)
{
    const t_component_instance* client = itfRequire->client;
    t_component_instance* server = (t_component_instance*)itfLocalBC->server;
    t_interface_require *require = &client->Template->requires[itfRequire->requireIndex];
    t_interface_provide* provide = &server->Template->provides[itfLocalBC->provideIndex];
    t_interface_provide_loaded* provideLoaded = &server->Template->providesLoaded[itfLocalBC->provideIndex];
    int k, j;

    if(require->indexes != NULL)
    {
        t_interface_require_index *requireindex = &require->indexes[itfRequire->collectionIndex];

        for(k = 0; k < requireindex->numberOfClient; k++) {
            t_uint32 *hostAddr;

            hostAddr = (t_uint32*)(
                    cm_DSP_GetHostLogicalAddress(client->memories[requireindex->memories[k].memory->id]) +
                    requireindex->memories[k].offset * requireindex->memories[k].memory->memEntSize);

            LOG_INTERNAL(2, "Fill ItfRef %s.%s mem=%s Off=%x @=%x\n",
                    client->pathname, require->name,
                    requireindex->memories[k].memory->memoryName,
                    requireindex->memories[k].offset,
                    hostAddr, 0);

            /*
             * Fill the interface references. We start by This then methods in order to keep
             * Unbinded panic as long as possible and not used method with wrong This. This is
             * relevent only for optional since we must go in stop state before rebinding other
             * required interface.
             *
             * Direct write to DSP memory without go through DSP abstraction since we know we are in 24bits
             */
            // Write THIS reference into the Data field of the interface reference
            // Write the interface methods reference

            if(((t_uint32)hostAddr & 0x7) == 0 && require->interface->methodNumber > 0)
            {
                // We are 64word byte aligned, combine this write with first method
                *(volatile t_uint64*)hostAddr =
                        ((t_uint64)server->thisAddress << 0) |
                        ((t_uint64)provideLoaded->indexesLoaded[itfLocalBC->collectionIndex][0].methodAddresses << 32);
                hostAddr += 2;
                j = 1;
            }
            else
            {
                // We are not, write this which will align us
                *hostAddr++ = (t_uint32)server->thisAddress;
                j = 0;
            }

            // Word align copy
            for(; j < require->interface->methodNumber - 1; j+=2) {
                *(volatile t_uint64*)hostAddr =
                        ((t_uint64)provideLoaded->indexesLoaded[itfLocalBC->collectionIndex][j].methodAddresses << 0) |
                        ((t_uint64)provideLoaded->indexesLoaded[itfLocalBC->collectionIndex][j+1].methodAddresses << 32);
                hostAddr += 2;
            }

            // Last word align if required
            if(j < require->interface->methodNumber)
                *hostAddr = provideLoaded->indexesLoaded[itfLocalBC->collectionIndex][j].methodAddresses;
        }
    }
    else
    {
        t_function_relocation *reloc = client->Template->delayedRelocation;
        while(reloc != NULL) {
            for(j = 0; j < provide->interface->methodNumber; j++)
            {
                if(provide->interface->methodNames[j] == reloc->symbol_name) {
                    cm_ELF_performRelocation(
                                        reloc->type,
                                        reloc->symbol_name,
                                        provideLoaded->indexesLoaded[itfLocalBC->collectionIndex][j].methodAddresses,
                                        reloc->reloc_addr);
                    break;
                }
            }

            reloc = reloc -> next;
        }
    }

    /*
     * Memorise this reference
     */
    {
        t_interface_reference* itfRef = &client->interfaceReferences[itfRequire->requireIndex][itfRequire->collectionIndex];

        itfRef->provideIndex = itfLocalBC->provideIndex;
        itfRef->collectionIndex = itfLocalBC->collectionIndex;
        itfRef->instance = itfLocalBC->server;
        itfRef->bfInfoID = bfInfoID;
        itfRef->bfInfo = bfInfo;

        /*
         * Do not count binding from EE (ie interrupt line), as this will prevent
         * cm_destroyInstance() of server to succeed (interrupt line bindings are
         * destroyed after the check in cm_destroyInstance()
         */
        if (client->Template->classe != FIRMWARE)
            server->providedItfUsedCount++;
    }
}
예제 #3
0
static void cm_bindLowLevelInterfaceToConst(
        const t_interface_require_description *itfRequire,
        const t_dsp_address functionAddress,
        const t_component_instance* targetInstance) {
    const t_component_instance* client = itfRequire->client;
    t_interface_require *require = &client->Template->requires[itfRequire->requireIndex];
    int j, k;


    // If DSP is off/panic/... -> write nothing
    if(
            require->indexes != NULL
            && cm_DSP_GetState(client->Template->dspId)->state == MPC_STATE_BOOTED)
    {
        t_interface_require_index *requireindex = &require->indexes[itfRequire->collectionIndex];

        for(k = 0; k < requireindex->numberOfClient; k++) {
            t_uint32 *hostAddr;

            hostAddr = (t_uint32*)(
                    cm_DSP_GetHostLogicalAddress(client->memories[requireindex->memories[k].memory->id]) +
                    requireindex->memories[k].offset * requireindex->memories[k].memory->memEntSize);

            /*
             * Fill the interface references. We start by Methods then This in order to swith to
             * Unbinded panic as fast as possible and not used method with wrong This. This is
             * relevent only for optional since we must go in stop state before rebinding other
             * required interface.
             *
             * Direct write to DSP memory without go through DSP abstraction since we know we are in 24bits
             */
            /*
             * Write THIS reference into the Data field of the interface reference
             * Hack for simplifying debug just to keep THIS reference with caller one
             * (could be removed if __return_address MMDSP intrinsec provided by compiler).
             */
            // Write the interface methods reference

            if(((t_uint32)hostAddr & 0x7) == 0 && require->interface->methodNumber > 0)
            {
                // We are 64word byte aligned, combine this write with first method
                *(volatile t_uint64*)hostAddr =
                        ((t_uint64)client->thisAddress << 0) |
                        ((t_uint64)functionAddress << 32);
                hostAddr += 2;
                j = 1;
            }
            else
            {
                // We are not, write this which will align us
                *hostAddr++ = (t_uint32)client->thisAddress;
                j = 0;
            }

            // Word align copy
            for(; j < require->interface->methodNumber - 1; j+=2) {
                *(volatile t_uint64*)hostAddr =
                        ((t_uint64)functionAddress << 0) |
                        ((t_uint64)functionAddress << 32);
                hostAddr += 2;
            }

            // Last word align if required
            if(j < require->interface->methodNumber)
                *hostAddr = functionAddress;
        }
    }

    cm_registerLowLevelInterfaceToConst(itfRequire, targetInstance);
}