//------------------------------------------------------------------------------ void MobiCoreDevice::donateRam(const uint32_t donationSize) { // Donate additional RAM to the MobiCore CWsm_ptr ram = allocateContiguousPersistentWsm(donationSize); if (NULL == ram) { LOG_E("Allocation of additional RAM failed"); return; } ramType_t ramType = RAM_GENERIC; addr_t adrBuffer = ram->physAddr; const uint32_t numPages = donationSize / (4 * 1024); LOG_I("donateRam(): adrBuffer=%p, numPages=%d, ramType=%d", adrBuffer, numPages, ramType); do { // Write MCP open message to buffer mcpMessage->cmdDonateRam.cmdHeader.cmdId = MC_MCP_CMD_DONATE_RAM; mcpMessage->cmdDonateRam.adrBuffer = (uint32_t) adrBuffer; mcpMessage->cmdDonateRam.numPages = numPages; mcpMessage->cmdDonateRam.ramType = ramType; // Notify MC about a new command inside the MCP buffer notify(SID_MCP); // Wait till response from MC is available if (!waitMcpNotification()) { break; } // Check if the command response ID is correct if ((MC_MCP_CMD_DONATE_RAM | FLAG_RESPONSE) != mcpMessage->rspHeader.rspId) { LOG_E("donateRam(): CMD_DONATE_RAM got invalid MCP response - rspId is: %d", mcpMessage->rspHeader.rspId); break; } uint32_t mcRet = mcpMessage->rspDonateRam.rspHeader.result; if (MC_MCP_RET_OK != mcRet) { LOG_E("donateRam(): CMD_DONATE_RAM error %d", mcRet); break; } LOG_I("donateRam() succeeded."); } while (0); }
/** * Set up MCI and wait till MC is initialized * @return true if mobicore is already initialized */ bool TrustZoneDevice::initDevice( const char *devFile, bool loadMobiCore, const char *mobicoreImage, bool enableScheduler ) throw (ExcDevice) { notificationQueue_t* nqStartOut; notificationQueue_t* nqStartIn; addr_t mciBuffer; pMcKMod = new CMcKMod(); if (!pMcKMod->open(devFile)) { LOG_E("open() kernel module device failed"); return false; } if (!pMcKMod->checkKmodVersionOk()) { LOG_E("kernel module version mismatch"); return false; } // Start MobiCore from DDRAM if (loadMobiCore) { // 1. Allocate DDRAM as pseudo IRAM mobicoreInDDR = allocateContiguousPersistentWsm(SIZE_DDRAM); if (NULL == mobicoreInDDR) { LOG_E("Allocation of additional RAM failed"); return false; } memset(mobicoreInDDR->virtAddr,0xCC,SIZE_DDRAM); int ret = loadMobiCoreImage(mobicoreInDDR->virtAddr, SIZE_DDRAM, mobicoreImage); if (0 != ret) { LOG_E("loading Mobicore file failed: %d", ret); return false; } ret = pMcKMod->fcExecute( mobicoreInDDR->physAddr, MCP_BUFFER_SIZE); if (0 != ret) { LOG_E("pMcKMod->fcExecute() failed : %d", ret); return false; } } this->schedulerEnabled = enableScheduler; // Init MC with NQ and MCP buffer addresses // Set up MCI buffer if(!getMciInstance(MCI_BUFFER_SIZE, &pWsmMcp, &mciReused)) { return false; } mciBuffer = pWsmMcp->virtAddr; if(!checkMciVersion()) { return false; } // Only do a fastcall if MCI has not been reused (MC already initialized) if (!mciReused) { // Wipe memory before first usage bzero(mciBuffer, MCI_BUFFER_SIZE); // Init MC with NQ and MCP buffer addresses int ret = pMcKMod->fcInit( pWsmMcp->physAddr, 0, NQ_BUFFER_SIZE, NQ_BUFFER_SIZE, MCP_BUFFER_SIZE); if (0 != ret) { LOG_E("pMcKMod->fcInit() failed"); return false; } // First empty N-SIQ which results in set up of the MCI structure if(!nsiq()) { return false; } // Wait until MobiCore state switches to MC_STATUS_INITIALIZED // It is assumed that MobiCore always switches state at a certain point in time. while(1) { uint32_t status = getMobicoreStatus(); if (MC_STATUS_INITIALIZED == status) { break; } else if (MC_STATUS_NOT_INITIALIZED == status) { // Switch to MobiCore to give it more CPU time. if(!yield()) { return false; } } else if (MC_STATUS_HALT == status) { dumpMobicoreStatus(); LOG_E("MobiCore halted during init !!!, state is 0x%x", status); return false; } else // MC_STATUS_BAD_INIT or anything else { LOG_E("MCI buffer init failed, state is 0x%x", status); return false; } } } nqStartOut = (notificationQueue_t *) mciBuffer; nqStartIn = (notificationQueue_t *) ((uint8_t *) nqStartOut + sizeof(notificationQueueHeader_t) + NQ_NUM_ELEMS * sizeof(notification_t)); // Set up the NWd NQ nq = new NotificationQueue(nqStartIn, nqStartOut, NQ_NUM_ELEMS); mcpBuffer_t *mcpBuf = (mcpBuffer_t*) ((uint8_t *) mciBuffer + NQ_BUFFER_SIZE); // Set up the MC flags mcFlags = &(mcpBuf->mcFlags); // Set up the MCP message mcpMessage = &(mcpBuf->mcpMessage); // convert virtual address of mapping to physical address for the init. LOG_I("MCP: virt=%p, phys=%p, reused=%s", pWsmMcp->virtAddr, pWsmMcp->physAddr, mciReused ? "true" : "false"); return true; }