/******************************************************************************** * context handle *******************************************************************************/ int32_t cmdq_sec_setup_context_session(cmdqSecContextHandle handle) { int32_t status = 0; const struct mc_uuid_t uuid = CMDQ_TL_UUID; /* init iwc parameter */ if (IWC_INIT == handle->state) { handle->uuid = uuid; } /* init secure session */ status = cmdq_sec_init_session_unlocked(&(handle->uuid), (uint8_t **) (&(handle->iwcMessage)), sizeof(iwcCmdqMessage_t), &(handle->sessionHandle), &(handle->state), &(handle->openMobicoreByOther)); CMDQ_MSG("SEC_SETUP: status[%d], tgid[%d], mobicoreOpenByOther[%d]\n", status, handle->tgid, handle->openMobicoreByOther); return status; }
int32_t cmdqRecFlushAsync(cmdqRecHandle handle) { int32_t status = 0; cmdqCommandStruct desc = { 0 }; TaskStruct *pTask = NULL; status = cmdq_rec_finalize_command(handle, false); if (status < 0) { return status; } desc.scenario = handle->scenario; desc.priority = handle->priority; desc.engineFlag = handle->engineFlag; desc.pVABase = handle->pBuffer; desc.blockSize = handle->blockSize; desc.regRequest.count = 0; desc.regRequest.regAddresses = NULL; desc.regValue.count = 0; desc.regValue.regValues = NULL; status = cmdqCoreSubmitTaskAsync(&desc, NULL, 0, &pTask); CMDQ_MSG ("[Auto Release] Submit ASYNC task scenario: %d, priority: %d, engine: 0x%llx, buffer: 0x%p, size: %d\n", handle->scenario, handle->priority, handle->engineFlag, handle->pBuffer, handle->blockSize); if (pTask) { pTask->flushCallback = NULL; pTask->flushData = 0; } /* insert the task into auto-release queue */ if (pTask) { status = cmdqCoreAutoReleaseTask(pTask); } else { status = -ENOMEM; } return status; }
int32_t cmdq_subsys_from_phys_addr(uint32_t physAddr) { #define DISP_PWM_BASE 0x1100F000 const int32_t msb = (physAddr & 0x0FFFF0000) >> 16; #undef DECLARE_CMDQ_SUBSYS #define DECLARE_CMDQ_SUBSYS(addr, id, grp, base) case addr: return id; switch (msb) { #include "cmdq_subsys.h" } /* Extra handle for HW registers which not in GCE subsys table, should check and add by case */ if (DISP_PWM_BASE == (physAddr & 0xFFFFF000)){ CMDQ_MSG("Special handle subsys (PWM), physAddr:0x%08x\n", physAddr); return CMDQ_SPECIAL_SUBSYS_ADDR; } CMDQ_ERR("unrecognized subsys, msb=0x%04x, physAddr:0x%08x\n", msb, physAddr); return -1; #undef DECLARE_CMDQ_SUBSYS }
int32_t cmdq_sec_teardown_context_session(cmdqSecContextHandle handle) { int32_t status = 0; if (handle) { CMDQ_MSG("[SEC]SEC_TEARDOWN: state: %d, iwcMessage:0x%p\n", handle->state, handle->iwcMessage); cmdq_sec_deinit_session_unlocked( (uint8_t **) (&(handle->iwcMessage)), &(handle->sessionHandle), handle->state, handle->openMobicoreByOther); /* clrean up handle's attritubes */ handle->state = IWC_INIT; } else { CMDQ_ERR("[SEC]SEC_TEARDOWN: null secCtxHandle\n"); status = -1; } return status; }
int32_t cmdqRecFlush(cmdqRecHandle handle) { int32_t status; cmdqCommandStruct desc = { 0 }; status = cmdq_rec_finalize_command(handle, false); if (status < 0) { return status; } CMDQ_MSG("Submit task scenario: %d, priority: %d, engine: 0x%llx, buffer: 0x%p, size: %d\n", handle->scenario, handle->priority, handle->engineFlag, handle->pBuffer, handle->blockSize); desc.scenario = handle->scenario; desc.priority = handle->priority; desc.engineFlag = handle->engineFlag; desc.pVABase = handle->pBuffer; desc.blockSize = handle->blockSize; return cmdqCoreSubmitTask(&desc); }
static int cmdq_probe(struct platform_device *pDevice) { int status; struct device *object; CMDQ_MSG("CMDQ driver probe begin\n"); /* Function link */ cmdq_virtual_function_setting(); /* init cmdq device related data */ cmdq_dev_init(pDevice); /* init cmdq context */ cmdqCoreInitialize(); status = alloc_chrdev_region(&gCmdqDevNo, 0, 1, CMDQ_DRIVER_DEVICE_NAME); if (status != 0) { /* Cannot get CMDQ device major number */ CMDQ_ERR("Get CMDQ device major number(%d) failed(%d)\n", gCmdqDevNo, status); } else { /* Get CMDQ device major number successfully */ CMDQ_MSG("Get CMDQ device major number(%d) success(%d)\n", gCmdqDevNo, status); } /* ioctl access point (/dev/mtk_cmdq) */ gCmdqCDev = cdev_alloc(); gCmdqCDev->owner = THIS_MODULE; gCmdqCDev->ops = &cmdqOP; status = cdev_add(gCmdqCDev, gCmdqDevNo, 1); gCMDQClass = class_create(THIS_MODULE, CMDQ_DRIVER_DEVICE_NAME); object = device_create(gCMDQClass, NULL, gCmdqDevNo, NULL, CMDQ_DRIVER_DEVICE_NAME); status = request_irq(cmdq_dev_get_irq_id(), cmdq_irq_handler, IRQF_TRIGGER_LOW | IRQF_SHARED, CMDQ_DRIVER_DEVICE_NAME, gCmdqCDev); if (status != 0) { CMDQ_ERR("Register cmdq driver irq handler(%d) failed(%d)\n", gCmdqDevNo, status); return -EFAULT; } /* although secusre CMDQ driver is responsible for handle secure IRQ, */ /* MUST registet secure IRQ to GIC in normal world to ensure it will be initialize correctly */ /* (that's because t-base does not support GIC init IRQ in secure world...) */ #ifdef CMDQ_SECURE_PATH_SUPPORT status = request_irq(cmdq_dev_get_irq_secure_id(), cmdq_irq_handler, IRQF_TRIGGER_LOW, CMDQ_DRIVER_DEVICE_NAME, gCmdqCDev); CMDQ_MSG("register sec IRQ:%d\n", cmdq_dev_get_irq_secure_id()); if (status != 0) { CMDQ_ERR("Register cmdq driver secure irq handler(%d) failed(%d)\n", gCmdqDevNo, status); return -EFAULT; } #endif /* global ioctl access point (/proc/mtk_cmdq) */ if (NULL == proc_create(CMDQ_DRIVER_DEVICE_NAME, 0644, NULL, &cmdqOP)) { CMDQ_ERR("CMDQ procfs node create failed\n"); return -EFAULT; } /* proc debug access point */ cmdq_create_debug_entries(); /* device attributes for debugging */ device_create_file(&pDevice->dev, &dev_attr_status); device_create_file(&pDevice->dev, &dev_attr_error); device_create_file(&pDevice->dev, &dev_attr_record); device_create_file(&pDevice->dev, &dev_attr_log_level); device_create_file(&pDevice->dev, &dev_attr_profile_enable); #ifdef CMDQ_INSTRUCTION_COUNT device_create_file(&pDevice->dev, &dev_attr_instruction_count_level); #endif CMDQ_MSG("CMDQ driver probe end\n"); return 0; }
/** * centralize the write/polling/read command for APB and GPR handle * this function must be called inside cmdq_append_command * because we ignore buffer and pre-fetch check here. * Parameter: * same as cmdq_append_command * Return: * same as cmdq_append_command */ static int32_t cmdq_append_wpr_command(cmdqRecHandle handle, CMDQ_CODE_ENUM code, uint32_t argA, uint32_t argB, uint32_t argAType, uint32_t argBType) { int32_t subsys; uint32_t *pCommand; bool bUseGPR = false; /* use new argA to present final inserted argA*/ uint32_t newArgA; uint32_t newArgAType = argAType; uint32_t argType = 0; /* be careful that subsys encoding position is different among platforms */ const uint32_t subsysBit = cmdq_core_get_subsys_LSB_in_argA(); pCommand = (uint32_t *) ((uint8_t *) handle->pBuffer + handle->blockSize); if (CMDQ_CODE_READ != code && CMDQ_CODE_WRITE != code && CMDQ_CODE_POLL != code){ CMDQ_ERR("Record 0x%p, flow error, should not append comment in wpr API", handle); return -EFAULT; } /* we must re-calculate current PC at first. */ pCommand = (uint32_t *) ((uint8_t *) handle->pBuffer + handle->blockSize); CMDQ_VERBOSE("REC: 0x%p CMD: 0x%p, op: 0x%02x\n", handle, pCommand, code); CMDQ_VERBOSE("REC: 0x%p CMD: argA: 0x%08x, argB: 0x%08x, argAType: %d, argBType: %d\n", handle, argA, argB, argAType, argBType); if (0 == argAType){ /* argA is the HW register address to read from */ subsys = cmdq_subsys_from_phys_addr(argA); if (CMDQ_SPECIAL_SUBSYS_ADDR == subsys){ #ifdef CMDQ_GPR_SUPPORT bUseGPR = true; CMDQ_MSG("REC: Special handle memory base address 0x%08x\n", argA); /* Wait and clear for GPR mutex token to enter mutex*/ *pCommand++ = ((1 << 31) | (1 << 15) | 1); *pCommand++ = (CMDQ_CODE_WFE << 24) | CMDQ_SYNC_TOKEN_GPR_SET_4; handle->blockSize += CMDQ_INST_SIZE; /* Move extra handle APB address to GPR*/ *pCommand++ = argA; *pCommand++ = (CMDQ_CODE_MOVE << 24) | ((CMDQ_DATA_REG_DEBUG & 0x1f) << 16) | (4 << 21); handle->blockSize += CMDQ_INST_SIZE; /* change final argA to GPR */ newArgA = ((CMDQ_DATA_REG_DEBUG & 0x1f) << 16); if (argA & 0x1){ /* MASK case, set final bit to 1*/ newArgA = newArgA | 0x1; } /* change argA type to 1*/ newArgAType = 1; #else CMDQ_ERR("func:%s failed since CMDQ dosen't support GPR\n", __func__); return -EFAULT; #endif }else if (0 == argAType && 0 > subsys){ CMDQ_ERR("REC: Unsupported memory base address 0x%08x\n", argA); return -EFAULT; }else{ /* compose final argA according to subsys table */ newArgA = (argA & 0xffff) | ((subsys & 0x1f) << subsysBit); } }else{ /* compose final argA according GPR value */ newArgA = ((argA & 0x1f) << 16); } argType = (newArgAType << 2) | (argBType << 1); /* newArgA is the HW register address to access from or GPR value store the HW register address */ /* argB is the value or register id */ /* bit 55: argA type, 1 for GPR */ /* bit 54: argB type, 1 for GPR */ /* argType: ('newArgAType', 'argBType', '0') */ *pCommand++ = argB; *pCommand++ = (code << 24) | newArgA | (argType << 21); handle->blockSize += CMDQ_INST_SIZE; if (bUseGPR) { /* Set for GPR mutex token to leave mutex*/ *pCommand++ = ((1 << 31) | (1 << 16)); *pCommand++ = (CMDQ_CODE_WFE << 24) | CMDQ_SYNC_TOKEN_GPR_SET_4; handle->blockSize += CMDQ_INST_SIZE; } return 0; }
static long cmdq_driver_process_command_request(struct cmdqCommandStruct *pCommand) { int32_t status = 0; uint32_t *userRegValue = NULL; uint32_t userRegCount = 0; if (pCommand->regRequest.count != pCommand->regValue.count) { CMDQ_ERR("mismatch regRequest and regValue\n"); return -EFAULT; } /* allocate secure medatata */ status = cmdq_driver_create_secure_medadata(pCommand); if (0 != status) return status; /* backup since we are going to replace these */ userRegValue = CMDQ_U32_PTR(pCommand->regValue.regValues); userRegCount = pCommand->regValue.count; /* create kernel-space address buffer */ status = cmdq_driver_create_reg_address_buffer(pCommand); if (0 != status) { /* free secure path metadata */ cmdq_driver_destroy_secure_medadata(pCommand); return status; } /* create kernel-space value buffer */ pCommand->regValue.regValues = (cmdqU32Ptr_t) (unsigned long) kzalloc(pCommand->regRequest.count * sizeof(uint32_t), GFP_KERNEL); pCommand->regValue.count = pCommand->regRequest.count; if (NULL == CMDQ_U32_PTR(pCommand->regValue.regValues)) { kfree(CMDQ_U32_PTR(pCommand->regRequest.regAddresses)); return -ENOMEM; } /* scenario id fixup */ if ((CMDQ_SCENARIO_USER_DISP_COLOR == pCommand->scenario) || (CMDQ_SCENARIO_USER_MDP == pCommand->scenario)) { CMDQ_VERBOSE("user space request, scenario:%d\n", pCommand->scenario); } else { CMDQ_LOG("[WARNING]fix user space request to CMDQ_SCENARIO_USER_SPACE\n"); pCommand->scenario = CMDQ_SCENARIO_USER_SPACE; } if (CMDQ_SCENARIO_USER_MDP == pCommand->scenario) CMDQ_MSG("srcHandle=0x%08x, dstHandle=0x%08x\n", pCommand->secData.srcHandle, pCommand->secData.dstHandle); status = cmdqCoreSubmitTask(pCommand); if (0 > status) { CMDQ_ERR("Submit user commands for execution failed = %d\n", status); cmdq_driver_destroy_secure_medadata(pCommand); kfree(CMDQ_U32_PTR(pCommand->regRequest.regAddresses)); kfree(CMDQ_U32_PTR(pCommand->regValue.regValues)); return -EFAULT; } /* notify kernel space dump callback */ if (0 != pCommand->debugRegDump) { status = cmdqCoreDebugRegDumpEnd(pCommand->debugRegDump, pCommand->regRequest.count - userRegCount, CMDQ_U32_PTR(pCommand->regValue.regValues) + userRegCount); if (0 != status) CMDQ_ERR("cmdqCoreDebugRegDumpEnd returns %d\n", status); } /* copy back to user space buffer */ if (userRegValue && userRegCount) { /* copy results back to user space */ CMDQ_VERBOSE("regValue[0] is %d\n", CMDQ_U32_PTR(pCommand->regValue.regValues)[0]); if (copy_to_user (userRegValue, CMDQ_U32_PTR(pCommand->regValue.regValues), userRegCount * sizeof(uint32_t))) { CMDQ_ERR("Copy REGVALUE to user space failed\n"); } } /* free allocated kernel buffers */ kfree(CMDQ_U32_PTR(pCommand->regRequest.regAddresses)); kfree(CMDQ_U32_PTR(pCommand->regValue.regValues)); if (pCommand->readAddress.count > 0) cmdq_driver_process_read_address_request(&pCommand->readAddress); /* free allocated secure metadata */ cmdq_driver_destroy_secure_medadata(pCommand); return 0; }
static int cmdq_probe(struct platform_device *pDevice) { int status; struct device *object; CMDQ_MSG("CMDQ driver probe begin\n"); /* init cmdq device related data */ cmdq_dev_init(pDevice); /* init cmdq context */ cmdqCoreInitialize(); status = alloc_chrdev_region(&gCmdqDevNo, 0, 1, CMDQ_DRIVER_DEVICE_NAME); if (status != 0) CMDQ_ERR("Get CMDQ device major number(%d) failed(%d)\n", gCmdqDevNo, status); else CMDQ_MSG("Get CMDQ device major number(%d) success(%d)\n", gCmdqDevNo, status); /* ioctl access point (/dev/mtk_cmdq) */ gCmdqCDev = cdev_alloc(); gCmdqCDev->owner = THIS_MODULE; gCmdqCDev->ops = &cmdqOP; status = cdev_add(gCmdqCDev, gCmdqDevNo, 1); gCMDQClass = class_create(THIS_MODULE, CMDQ_DRIVER_DEVICE_NAME); object = device_create(gCMDQClass, NULL, gCmdqDevNo, NULL, CMDQ_DRIVER_DEVICE_NAME); CMDQ_LOG("register IRQ:%d\n", cmdq_dev_get_irq_id()); status = request_irq(cmdq_dev_get_irq_id(), cmdq_irq_handler, IRQF_TRIGGER_LOW, CMDQ_DRIVER_DEVICE_NAME, gCmdqCDev); if (status != 0) { CMDQ_ERR("Register cmdq driver irq handler(%d) failed(%d)\n", gCmdqDevNo, status); return -EFAULT; } #if 0 /* remove register secure IRQ in Normal world . TZ register instead */ /* although secusre CMDQ driver is responsible for handle secure IRQ, */ /* MUST registet secure IRQ to GIC in normal world to ensure it will be initialize correctly */ /* (that's because t-base does not support GIC init IRQ in secure world...) */ CMDQ_LOG("register sec IRQ:%d\n", cmdq_dev_get_irq_secure_id()); status = request_irq(cmdq_dev_get_irq_secure_id(), cmdq_sec_irq_handler, IRQF_TRIGGER_LOW, "TEE IRQ", gCmdqCDev); if (status != 0) { CMDQ_ERR("Register cmdq driver secure irq handler(%d) failed(%d)\n", gCmdqDevNo, status); return -EFAULT; } #endif /* CMDQ_ERR("prepare to create device mtk_cmdq\n"); */ /* global ioctl access point (/proc/mtk_cmdq) */ if (NULL == proc_create(CMDQ_DRIVER_DEVICE_NAME, 0644, NULL, &cmdqOP)) { CMDQ_ERR("CMDQ procfs node create failed\n"); return -EFAULT; } #ifdef CMDQ_OF_SUPPORT /* CCF - Common Clock Framework */ cmdq_core_get_clk_map(pDevice); #endif /* proc debug access point */ cmdq_create_debug_entries(); /* device attributes for debugging */ device_create_file(&pDevice->dev, &dev_attr_status); device_create_file(&pDevice->dev, &dev_attr_error); device_create_file(&pDevice->dev, &dev_attr_record); device_create_file(&pDevice->dev, &dev_attr_log_level); device_create_file(&pDevice->dev, &dev_attr_profile_enable); CMDQ_MSG("CMDQ driver probe end\n"); return 0; }
int32_t cmdq_sec_submit_to_secure_world_async_unlocked(uint32_t iwcCommand, TaskStruct *pTask, int32_t thread, CmdqSecFillIwcCB iwcFillCB, void *data) { const int32_t tgid = current->tgid; const int32_t pid = current->pid; cmdqSecContextHandle handle = NULL; int32_t status = 0; int32_t duration = 0; CMDQ_TIME tEntrySec; CMDQ_TIME tExitSec; CMDQ_MSG("[SEC]-->SEC_SUBMIT: tgid[%d:%d]\n", tgid, pid); do { /* find handle first */ /* Unlike tBase user space API, * tBase kernel API maintains a GLOBAL table to control mobicore device reference count. * For kernel spece user, mc_open_device and session_handle don't depend on the process context. * Therefore we use global secssion handle to inter-world commumication. */ if(NULL == gCmdqSecContextHandle) { gCmdqSecContextHandle = cmdq_sec_context_handle_create(current->tgid); } handle = gCmdqSecContextHandle; if (NULL == handle) { CMDQ_ERR("SEC_SUBMIT: tgid %d err[NULL secCtxHandle]\n", tgid); status = -(CMDQ_ERR_NULL_SEC_CTX_HANDLE); break; } if (0 > cmdq_sec_setup_context_session(handle)) { status = -(CMDQ_ERR_SEC_CTX_SETUP); break; } tEntrySec = sched_clock(); status = cmdq_sec_send_context_session_message( handle, iwcCommand, pTask, thread, iwcFillCB, data); tExitSec = sched_clock(); CMDQ_GET_TIME_IN_US_PART(tEntrySec, tExitSec, duration); cmdq_sec_track_task_record(iwcCommand, pTask, &tEntrySec, &tExitSec); /* release resource */ #if !(CMDQ_OPEN_SESSION_ONCE) cmdq_sec_teardown_context_session(handle) #endif /* Note we entry secure for config only and wait result in normal world. */ /* No need reset module HW for config failed case*/ } while (0); if (-ETIMEDOUT == status) { /* t-base strange issue, mc_wait_notification false timeout when secure world has done */ /* becuase retry may failed, give up retry method */ CMDQ_AEE("CMDQ", "[SEC]<--SEC_SUBMIT: err[%d][mc_wait_notification timeout], pTask[0x%p], THR[%d], tgid[%d:%d], config_duration_ms[%d], cmdId[%d]\n", status, pTask, thread, tgid, pid, duration, iwcCommand); } else if (0 > status) { /* dump metadata first */ if (pTask) { cmdq_core_dump_secure_metadata(&(pTask->secData)); } /* throw AEE */ CMDQ_AEE("CMDQ", "[SEC]<--SEC_SUBMIT: err[%d], pTask[0x%p], THR[%d], tgid[%d:%d], config_duration_ms[%d], cmdId[%d]\n", status, pTask, thread, tgid, pid, duration, iwcCommand); } else { CMDQ_LOG ("[SEC]<--SEC_SUBMIT: err[%d], pTask[0x%p], THR[%d], tgid[%d:%d], config_duration_ms[%d], cmdId[%d]\n", status, pTask, thread, tgid, pid, duration, iwcCommand); } return status; }
int32_t cmdq_sec_fill_iwc_command_msg_unlocked(int32_t iwcCommand, void *_pTask, int32_t thread, void *_pIwc) { int32_t status; const TaskStruct *pTask = (TaskStruct *)_pTask; iwcCmdqMessage_t *pIwc; /* cmdqSecDr will insert some instr*/ const uint32_t reservedCommandSize = 4 * CMDQ_INST_SIZE; status = 0; pIwc = (iwcCmdqMessage_t *)_pIwc; /* check command size first */ if (pTask && (CMDQ_TZ_CMD_BLOCK_SIZE < (pTask->commandSize + reservedCommandSize))) { CMDQ_ERR("[SEC]SESSION_MSG: pTask %p commandSize %d > %d\n", pTask, pTask->commandSize, CMDQ_TZ_CMD_BLOCK_SIZE); return -EFAULT; } CMDQ_MSG("[SEC]-->SESSION_MSG: cmdId[%d]\n", iwcCommand); /* fill message buffer for inter world communication */ memset(pIwc, 0x0, sizeof(iwcCmdqMessage_t)); pIwc->cmd = iwcCommand; /* metadata */ pIwc->command.metadata.enginesNeedDAPC = pTask->secData.enginesNeedDAPC; pIwc->command.metadata.enginesNeedPortSecurity = pTask->secData.enginesNeedPortSecurity; if (NULL != pTask && CMDQ_INVALID_THREAD != thread) { /* basic data */ pIwc->command.scenario = pTask->scenario; pIwc->command.thread = thread; pIwc->command.priority = pTask->priority; pIwc->command.engineFlag = pTask->engineFlag; pIwc->command.commandSize = pTask->commandSize; pIwc->command.hNormalTask = 0LL | ((unsigned long) pTask); memcpy((pIwc->command.pVABase), (pTask->pVABase), (pTask->commandSize)); /* cookie */ pIwc->command.waitCookie = pTask->secData.waitCookie; pIwc->command.resetExecCnt = pTask->secData.resetExecCnt; CMDQ_MSG("[SEC]SESSION_MSG: task 0x%p, thread: %d, size: %d, bufferSize: %d, scenario:%d, flag:0x%08llx ,hNormalTask:0x%llx\n", pTask, thread, pTask->commandSize, pTask->bufferSize, pTask->scenario, pTask->engineFlag, pIwc->command.hNormalTask); CMDQ_VERBOSE("[SEC]SESSION_MSG: addrList[%d][0x%p]\n", pTask->secData.addrMetadataCount,CMDQ_U32_PTR(pTask->secData.addrMetadatas)); if (0 < pTask->secData.addrMetadataCount) { pIwc->command.metadata.addrListLength = pTask->secData.addrMetadataCount; memcpy((pIwc->command.metadata.addrList), (pTask->secData.addrMetadatas), (pTask->secData.addrMetadataCount) * sizeof(iwcCmdqAddrMetadata_t)); } /* medatada: debug config */ pIwc->debug.logLevel = (cmdq_core_should_print_msg()) ? (1) : (0); pIwc->debug.enableProfile = cmdq_core_profile_enabled(); } else { /* relase resource, or debug function will go here */ CMDQ_VERBOSE("[SEC]-->SESSION_MSG: no task, cmdId[%d]\n", iwcCommand); pIwc->command.commandSize = 0; pIwc->command.metadata.addrListLength = 0; } CMDQ_MSG("[SEC]<--SESSION_MSG[%d]\n", status); return status; }
int32_t cmdq_sec_init_session_unlocked(const struct mc_uuid_t *uuid, uint8_t **ppWsm, uint32_t wsmSize, struct mc_session_handle *pSessionHandle, CMDQ_IWC_STATE_ENUM *pIwcState, uint32_t *openMobicoreByOther) { int32_t openRet = 0; int32_t status = 0; uint32_t deviceId = MC_DEVICE_ID_DEFAULT; CMDQ_MSG("[SEC]-->SESSION_INIT: iwcState[%d]\n", (*pIwcState)); do { #if CMDQ_OPEN_SESSION_ONCE if (IWC_SES_OPENED <= (*pIwcState)) { CMDQ_MSG("SESSION_INIT: already opened\n"); break; } else { CMDQ_MSG("[SEC]SESSION_INIT: open new session[%d]\n", (*pIwcState)); } #endif CMDQ_VERBOSE ("[SEC]SESSION_INIT: wsmSize[%d], pSessionHandle: 0x%p\n", wsmSize, pSessionHandle); CMDQ_PROF_START("CMDQ_SEC_INIT"); /* open mobicore device */ openRet = cmdq_sec_open_mobicore_impl(deviceId); if (-EEXIST == openRet) { /* mobicore has been opened in this process context */ /* it is a ok case, so continue to execute */ status = 0; (*openMobicoreByOther) = 1; } else if (0 > openRet) { status = -1; break; } (*pIwcState) = IWC_MOBICORE_OPENED; /* allocate world shared memory */ if (0 > cmdq_sec_allocate_wsm_impl(deviceId, ppWsm, wsmSize)) { status = -1; break; } (*pIwcState) = IWC_WSM_ALLOCATED; /* open a secure session */ if (0 > cmdq_sec_open_session_impl(deviceId, uuid, (*ppWsm), wsmSize, pSessionHandle)) { status = -1; break; } (*pIwcState) = IWC_SES_OPENED; CMDQ_PROF_END("CMDQ_SEC_INIT"); } while (0); CMDQ_MSG("[SEC]<--SESSION_INIT[%d]\n", status); return status; }