void secwidevinemdw_listenDci(void) { enum mc_result mc_ret = MC_DRV_OK; u32 cmdId; MSG(INFO, "%s: DCI listener.\n", __func__); for (;;) { MSG(INFO, "%s: Waiting for notification\n", __func__); /* Wait for notification from SWd */ mc_ret = mc_wait_notification(&secwidevinemdwdr_session, MC_INFINITE_TIMEOUT); if (mc_ret != MC_DRV_OK) { MSG(ERR, "%s: mcWaitNotification failed, mc_ret=%d\n", __func__, mc_ret); break; } cmdId = secwidevinemdw_dci->command; u32 currentversion = secwidevinemdw_dci->request.currenthdcpversion; u32 requiredversion = secwidevinemdw_dci->request.requiredhdcpversion; MSG(INFO, "%s: wait notification done!! cmdId = 0x%x, current = 0x%x, required = 0x%x\n", __func__, cmdId, currentversion, requiredversion); /* Received exception. */ mc_ret = secwidevinemdw_execute(cmdId); /* Notify the STH*/ mc_ret = mc_notify(&secwidevinemdwdr_session); if (mc_ret != MC_DRV_OK) { MSG(ERR, "%s: mcNotify returned: %d\n", __func__, mc_ret); break; } } }
/* ------------------------------------------------------------- */ static void tlcWaitCmdFromDriver(void) { uint32_t ret = TUI_DCI_ERR_INTERNAL_ERROR; /* Wait for a command from secure driver */ ret = mc_wait_notification(&drSessionHandle, -1); if (MC_DRV_OK == ret) pr_debug("tlcWaitCmdFromDriver: Got a command\n"); else pr_debug("ERROR tlcWaitCmdFromDriver: mc_wait_notification() failed: %d\n", ret); }
/* ------------------------------------------------------------- */ static void tlc_wait_cmd_from_driver(void) { uint32_t ret = TUI_DCI_ERR_INTERNAL_ERROR; /* Wait for a command from secure driver */ ret = mc_wait_notification(&dr_session_handle, -1); if (MC_DRV_OK == ret) pr_debug("tlc_wait_cmd_from_driver: Got a command\n"); else pr_debug("ERROR %s: mc_wait_notification() failed: %d\n", __func__, ret); }
// return 0 for success and -1 for error static int set_tplay_handle_addr_request(void) { int ret = 0; enum mc_result mcRet = MC_DRV_OK; DDPDBG("[SVP] set_tplay_handle_addr_request \n"); open_tplay_driver_connection(); if (tplaySessionHandle.session_id == 0) { DDPERR("[SVP] invalid tplay session \n"); return -1; } DDPDBG("[SVP] handle_pa=0x%pa \n", &handle_pa); /* set other TCI parameter */ pTplayTci->tplay_handle_low_addr = (uint32_t)handle_pa; pTplayTci->tplay_handle_high_addr = (uint32_t)(handle_pa >> 32); /* set TCI command */ pTplayTci->cmd.header.commandId = CMD_TPLAY_REQUEST; /* notify the trustlet */ DDPDBG("[SVP] notify Tlsec trustlet CMD_TPLAY_REQUEST \n"); mcRet = mc_notify(&tplaySessionHandle); if (MC_DRV_OK != mcRet) { DDPERR("[SVP] mc_notify failed: %d @%s line %d\n", mcRet, __func__, __LINE__); ret = -1; goto _notify_to_trustlet_fail; } /* wait for response from the trustlet */ mcRet = mc_wait_notification(&tplaySessionHandle, MC_INFINITE_TIMEOUT); if (MC_DRV_OK != mcRet) { DDPERR("[SVP] mc_wait_notification failed: %d @%s line %d\n", mcRet, __func__, __LINE__); ret = -1; goto _notify_from_trustlet_fail; } DDPDBG("[SVP] CMD_TPLAY_REQUEST result=%d, return code=%d\n", pTplayTci->result, pTplayTci->rsp.header.returnCode); _notify_from_trustlet_fail: _notify_to_trustlet_fail: close_tplay_driver_connection(); return ret; }
int32_t cmdq_sec_execute_session_unlocked(struct mc_session_handle *pSessionHandle, CMDQ_IWC_STATE_ENUM *pIwcState, int32_t timeout_ms) { enum mc_result mcRet; int32_t status = 0; const int32_t secureWoldTimeout_ms = (0 < timeout_ms) ? (timeout_ms) : (MC_INFINITE_TIMEOUT); CMDQ_PROF_START("CMDQ_SEC_EXE"); do { /* notify to secure world */ mcRet = mc_notify(pSessionHandle); if (MC_DRV_OK != mcRet) { CMDQ_ERR("[SEC]EXEC: mc_notify err[0x%x]\n", mcRet); status = -1; break; } else { CMDQ_MSG("[SEC]EXEC: mc_notify ret[0x%x]\n", mcRet); } (*pIwcState) = IWC_SES_TRANSACTED; /* wait respond */ mcRet = mc_wait_notification(pSessionHandle, secureWoldTimeout_ms); if (MC_DRV_ERR_TIMEOUT == mcRet) { CMDQ_ERR ("[SEC]EXEC: mc_wait_notification timeout, err[0x%x], secureWoldTimeout_ms[%d]\n", mcRet, secureWoldTimeout_ms); status = -ETIMEDOUT; break; } if (MC_DRV_OK != mcRet) { CMDQ_ERR("[SEC]EXEC: mc_wait_notification err[0x%x]\n", mcRet); status = -1; break; } else { CMDQ_MSG("[SEC]EXEC: mc_wait_notification err[%d]\n", mcRet); } (*pIwcState) = IWC_SES_ON_TRANSACTED; } while (0); CMDQ_PROF_END("CMDQ_SEC_EXE"); return status; }
static int dump_tplay_physcial_addr(void) { DDPDBG("[SVP] dump_tplay_physcial_addr \n"); int ret = 0; enum mc_result mcRet = MC_DRV_OK; open_tplay_driver_connection(); if (tplaySessionHandle.session_id == 0) { DDPERR("[SVP] invalid tplay session \n"); return -1; } /* set TCI command */ pTplayTci->cmd.header.commandId = CMD_TPLAY_DUMP_PHY; /* notify the trustlet */ DDPMSG("[SVP] notify Tlsec trustlet CMD_TPLAY_DUMP_PHY \n"); mcRet = mc_notify(&tplaySessionHandle); if (MC_DRV_OK != mcRet) { DDPERR("[SVP] mc_notify failed: %d @%s line %d\n", mcRet, __func__, __LINE__); ret = -1; goto _notify_to_trustlet_fail; } /* wait for response from the trustlet */ mcRet = mc_wait_notification(&tplaySessionHandle, MC_INFINITE_TIMEOUT); if (MC_DRV_OK != mcRet) { DDPERR("[SVP] mc_wait_notification failed: %d @%s line %d\n", mcRet, __func__, __LINE__); ret = -1; goto _notify_from_trustlet_fail; } DDPDBG("[SVP] CMD_TPLAY_DUMP_PHY result=%d, return code=%d\n", pTplayTci->result, pTplayTci->rsp.header.returnCode); _notify_from_trustlet_fail: _notify_to_trustlet_fail: close_tplay_driver_connection(); return ret; }
/* DO NOT invoke this function unless you get HACC lock */ int tee_secure_request(unsigned int user, unsigned char *data, unsigned int data_size, unsigned int direction, unsigned char *seed, unsigned int seed_size) { int ret = SEC_OK; struct mc_bulk_map dataMapInfo; struct mc_bulk_map seedMapInfo; char *databuf = NULL; char *seedbuf = NULL; enum mc_result mcRet = 0; /* allocate data buffer to be sent to TEE */ databuf = vmalloc(data_size); if (databuf == NULL) { pr_debug("NWD HACC: vmalloc fail for data buffer"); ret = ERR_HACC_ALLOCATE_BUFFER_FAIL; goto _allocate_data_buf_err; } memcpy(databuf, data, data_size); if (seed_size != 0) { /* allocate seed buffer to be sent to TEE */ seedbuf = vmalloc(seed_size); if (seedbuf == NULL) { pr_debug("NWD HACC: vmalloc fail for seed buffer"); ret = ERR_HACC_ALLOCATE_BUFFER_FAIL; goto _allocate_seed_buf_err; } memcpy(seedbuf, seed, seed_size); } /* map TCI virtual address for data buffer */ ret = mc_map(&drSessionHandle, databuf, data_size, &dataMapInfo); if (MC_DRV_OK != ret) { pr_debug("NWD HACC: mcMap failed of data buffer: %d", ret); ret = ERR_HACC_MCMAP_BUFFER_FAIL; goto _mcmap_data_fail; } pTci->data_addr = (uint32_t) dataMapInfo.secure_virt_addr; pTci->data_len = data_size; if (seed_size != 0) { /* map TCI virtual address for seed buffer */ ret = mc_map(&drSessionHandle, seedbuf, seed_size, &seedMapInfo); if (MC_DRV_OK != ret) { pr_debug("NWD HACC: mcMap failed of seed buffer: %d", ret); ret = ERR_HACC_MCMAP_BUFFER_FAIL; goto _mcmap_seed_fail; } pTci->seed_addr = (uint32_t) seedMapInfo.secure_virt_addr; pTci->seed_len = seed_size; } else { pTci->seed_addr = 0; pTci->seed_len = 0; } /* set other TCI parameter */ pTci->hacc_user = user; pTci->direction = direction; /* set TCI command */ pTci->cmd.header.commandId = CMD_HACC_REQUEST; /* notify the trustlet */ pr_debug("NWD HACC: prepare notify\n"); mcRet = mc_notify(&drSessionHandle); if (MC_DRV_OK != mcRet) { pr_debug("NWD HACC IRQ fail: mc_notify returned: %d\n", mcRet); ret = ERR_HACC_NOTIFY_TO_TRUSTLET_FAIL; goto _notify_to_trustlet_fail; } /* wait for response from the trustlet */ mcRet = mc_wait_notification(&drSessionHandle, /*MC_INFINITE_TIMEOUT */ 20000); if (MC_DRV_OK != mcRet) { pr_debug("NWD HACC IRQ fail: mc_wait_notification 20s timeout: %d\n", mcRet); ret = ERR_HACC_NOTIFY_FROM_TRUSTLET_FAIL; goto _notify_from_trustlet_fail; } if (pTci->result != 0) { pr_debug("NWD HACC Request Fail!!!!!!!!(ret:%d, err:%d)\n", pTci->result, pTci->rsp.header.returnCode); } else { pr_debug("NWD HACC Request Success!!!!!!!!\n"); /* update result from secure buffer */ memcpy(data, databuf, data_size); } _notify_from_trustlet_fail: _notify_to_trustlet_fail: if (seed_size != 0) mc_unmap(&drSessionHandle, seedbuf, &seedMapInfo); _mcmap_seed_fail: mc_unmap(&drSessionHandle, databuf, &dataMapInfo); _mcmap_data_fail: if (seed_size != 0) vfree(seedbuf); _allocate_seed_buf_err: vfree(databuf); _allocate_data_buf_err: return ret; }