/* ------------------------------------------------------------- */ bool tlcNotifyEvent(uint32_t eventType) { bool ret = false; enum mc_result result; if (NULL == pDci) { pr_debug("ERROR tlcNotifyEvent: DCI has not been set up properly - exiting\n"); return false; } /* Wait for previous notification to be acknowledged */ while (pDci->nwdNotif != NOT_TUI_NONE) { pr_debug("TLC waiting for previous notification ack\n"); usleep_range(10000, 10000); }; /* Prepare notification message in DCI */ pr_debug("tlcNotifyEvent: eventType = %d\n", eventType); pDci->nwdNotif = eventType; /* Signal the Driver */ pr_debug("DCI EVENT NOTIFY CORE\n"); result = mc_notify(&drSessionHandle); if (MC_DRV_OK != result) { pr_debug("ERROR tlcNotifyEvent: mcNotify failed: %d\n", result); ret = false; } else { ret = true; } return ret; }
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; } } }
/* ------------------------------------------------------------- */ bool tlc_notify_event(uint32_t event_type) { bool ret = false; enum mc_result result; if (NULL == dci) { pr_debug("ERROR tlc_notify_event: DCI has not been set up "\ "properly - exiting\n"); return false; } /* Prepare notification message in DCI */ pr_debug("tlc_notify_event: event_type = %d\n", event_type); dci->nwd_notif = event_type; /* Signal the Driver */ pr_debug("DCI EVENT NOTIFY CORE\n"); result = mc_notify(&dr_session_handle); if (MC_DRV_OK != result) { pr_debug("ERROR tlc_notify_event: mc_notify failed: %d\n", result); ret = false; } else { ret = true; } return 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; }
/* ------------------------------------------------------------- */ static void tlcProcessCmd(void) { uint32_t ret = TUI_DCI_ERR_INTERNAL_ERROR; uint32_t commandId = CMD_TUI_SW_NONE; if (NULL == pDci) { pr_debug("ERROR tlcProcessCmd: DCI has not been set up properly - exiting\n"); return; } else { commandId = pDci->cmdNwd.id; } /* Warn if previous response was not acknowledged */ if (CMD_TUI_SW_NONE == commandId) { pr_debug("ERROR tlcProcessCmd: Notified without command\n"); return; } else { if (pDci->nwdRsp.id != CMD_TUI_SW_NONE) pr_debug("tlcProcessCmd: Warning, previous response not ack\n"); } /* Handle command */ switch (commandId) { case CMD_TUI_SW_OPEN_SESSION: pr_debug("tlcProcessCmd: CMD_TUI_SW_OPEN_SESSION.\n"); /* Start android TUI activity */ ret = sendCmdToUser(TLC_TUI_CMD_START_ACTIVITY); if (TUI_DCI_OK == ret) { /* allocate TUI frame buffer */ if (!allocateTuiBuffer(pDci)) ret = TUI_DCI_ERR_INTERNAL_ERROR; } break; case CMD_TUI_SW_STOP_DISPLAY: pr_debug("tlcProcessCmd: CMD_TUI_SW_STOP_DISPLAY.\n"); #ifndef CONFIG_SOC_EXYNOS5420 /* Set linux TUI flag */ trustedui_set_mask(TRUSTEDUI_MODE_TUI_SESSION); #endif trustedui_blank_set_counter(0); #ifdef CONFIG_TRUSTONIC_TRUSTED_UI_FB_BLANK blank_framebuffer(1); disable_irq(gpio_to_irq(190)); #endif trustedui_set_mask(TRUSTEDUI_MODE_VIDEO_SECURED|TRUSTEDUI_MODE_INPUT_SECURED); ret = TUI_DCI_OK; break; case CMD_TUI_SW_CLOSE_SESSION: pr_debug("tlcProcessCmd: CMD_TUI_SW_CLOSE_SESSION.\n"); freeTuiBuffer(); // Protect NWd trustedui_clear_mask(TRUSTEDUI_MODE_VIDEO_SECURED|TRUSTEDUI_MODE_INPUT_SECURED); #ifdef CONFIG_TRUSTONIC_TRUSTED_UI_FB_BLANK pr_info("Unblanking"); enable_irq(gpio_to_irq(190)); unblank_framebuffer(1); #endif /* Clear linux TUI flag */ trustedui_set_mode(TRUSTEDUI_MODE_OFF); #ifdef CONFIG_TRUSTONIC_TRUSTED_UI_FB_BLANK pr_info("Unsetting TUI flag (blank counter=%d)", trustedui_blank_get_counter()); if (0 < trustedui_blank_get_counter()) { blank_framebuffer(0); } #endif /* Stop android TUI activity */ ret = sendCmdToUser(TLC_TUI_CMD_STOP_ACTIVITY); break; default: pr_debug("ERROR tlcProcessCmd: Unknown command %d\n", commandId); break; } /* Fill in response to SWd, fill ID LAST */ pr_debug("tlcProcessCmd: return 0x%08x to cmd 0x%08x\n", ret, commandId); pDci->nwdRsp.returnCode = ret; pDci->nwdRsp.id = RSP_ID(commandId); /* Acknowledge command */ pDci->cmdNwd.id = CMD_TUI_SW_NONE; /* Notify SWd */ pr_debug("DCI RSP NOTIFY CORE\n"); ret = mc_notify(&drSessionHandle); if (MC_DRV_OK != ret) pr_debug("ERROR tlcProcessCmd: Notify failed: %d\n", 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; }
/* ------------------------------------------------------------- */ static void tlc_process_cmd(void) { uint32_t ret = TUI_DCI_ERR_INTERNAL_ERROR; uint32_t command_id = CMD_TUI_SW_NONE; #if defined(CONFIG_SECURE_OS_BOOSTER_API) int ret_val = 0; u8 retry_cnt = 0; #endif if (NULL == dci) { pr_debug("ERROR %s: DCI has not been set up properly - exiting"\ "\n", __func__); return; } else { command_id = dci->cmd_nwd.id; } /* Warn if previous response was not acknowledged */ if (CMD_TUI_SW_NONE == command_id) { pr_debug("ERROR %s: Notified without command\n", __func__); return; } else { if (dci->nwd_rsp.id != CMD_TUI_SW_NONE) pr_debug("%s: Warning, previous response not ack\n", __func__); } /* Handle command */ switch (command_id) { case CMD_TUI_SW_OPEN_SESSION: pr_debug("%s: CMD_TUI_SW_OPEN_SESSION.\n", __func__); #if defined(CONFIG_SECURE_OS_BOOSTER_API) pr_info("%s TUI_CPU_SPEEDUP ON retry: %d\n", __func__, retry_cnt); do { ret_val = secos_booster_start(MAX_PERFORMANCE); retry_cnt++; if (ret_val) { pr_err("%s: booster start failed. (%d) retry: %d\n" , __func__, ret_val, retry_cnt); if (retry_cnt < 7) usleep_range(500, 510); } } while (ret_val && retry_cnt < 7); #endif /* Start android TUI activity */ ret = send_cmd_to_user(TLC_TUI_CMD_START_ACTIVITY); if (TUI_DCI_OK != ret) break; /* allocate TUI frame buffer */ ret = hal_tui_alloc(dci->nwd_rsp.alloc_buffer, dci->cmd_nwd.payload.alloc_data.alloc_size, dci->cmd_nwd.payload.alloc_data.num_of_buff); if (TUI_DCI_OK != ret) { pr_err("%s: hal_tui_alloc error : %d\n", __func__ ,ret); /* no need to call tui_i2c_reset, because there will be no TUI * session */ //tui_i2c_reset(); send_cmd_to_user(TLC_TUI_CMD_STOP_ACTIVITY); break; } /* Deactivate linux UI drivers */ ret = hal_tui_deactivate(); if (TUI_DCI_OK != ret) { pr_err("%s: hal_tui_deactivate error : %d\n", __func__ ,ret); hal_tui_free(); send_cmd_to_user(TLC_TUI_CMD_STOP_ACTIVITY); break; } break; case CMD_TUI_SW_CLOSE_SESSION: pr_debug("%s: CMD_TUI_SW_CLOSE_SESSION.\n", __func__); /* Activate linux UI drivers */ ret = hal_tui_activate(); hal_tui_free(); #if defined(CONFIG_SECURE_OS_BOOSTER_API) ret_val = secos_booster_stop(); if (ret_val) pr_err("%s: booster stop failed. (%d)\n" , __func__, ret_val); #endif /* Stop android TUI activity */ ret = send_cmd_to_user(TLC_TUI_CMD_STOP_ACTIVITY); break; default: pr_debug("ERROR %s: Unknown command %d\n", __func__, command_id); break; } /* Fill in response to SWd, fill ID LAST */ pr_debug("%s: return 0x%08x to cmd 0x%08x\n", __func__, ret, command_id); dci->nwd_rsp.return_code = ret; dci->nwd_rsp.id = RSP_ID(command_id); /* Acknowledge command */ dci->cmd_nwd.id = CMD_TUI_SW_NONE; /* Notify SWd */ pr_debug("DCI RSP NOTIFY CORE\n"); ret = mc_notify(&dr_session_handle); if (MC_DRV_OK != ret) pr_debug("ERROR %s: Notify failed: %d\n", __func__, ret); }
/* ------------------------------------------------------------- */ static void tlcProcessCmd(void) { uint32_t ret = TUI_DCI_ERR_INTERNAL_ERROR; uint32_t commandId = CMD_TUI_SW_NONE; pDci->cmdNwd.payload.allocData.numOfBuff = TUI_BUFFER_NUM; if (NULL == pDci) { pr_debug("ERROR tlcProcessCmd: DCI has not been set up properly - exiting\n"); return; } else { commandId = pDci->cmdNwd.id; } /* Warn if previous response was not acknowledged */ if (CMD_TUI_SW_NONE == commandId) { pr_debug("ERROR tlcProcessCmd: Notified without command\n"); return; } else { if (pDci->nwdRsp.id != CMD_TUI_SW_NONE) pr_debug("tlcProcessCmd: Warning, previous response not ack\n"); } /* Handle command */ switch (commandId) { case CMD_TUI_SW_OPEN_SESSION: printk(KERN_ERR "tlcProcessCmd: CMD_TUI_SW_OPEN_SESSION.\n"); /* Start android TUI activity */ ret = sendCmdToUser(TLC_TUI_CMD_START_ACTIVITY); if (TUI_DCI_OK == ret) { /* allocate TUI frame buffer */ ret = hal_tui_alloc(&pDci->nwdRsp.allocBuffer[MAX_DCI_BUFFER_NUMBER], pDci->cmdNwd.payload.allocData.allocSize, pDci->cmdNwd.payload.allocData.numOfBuff); printk(KERN_ERR "tlcProcessCmd: CMD_TUI_SW_OPEN_SESSION & disable_irq(%d);.\n",tsp_irq_num); disable_irq(tsp_irq_num); msleep(100); // temp code } hal_tui_video_space_alloc(); pDci->nwdRsp.allocBuffer[0].pa = g_sec_tuiMemPool.pa; pDci->nwdRsp.allocBuffer[1].pa = (g_sec_tuiMemPool.pa + g_sec_tuiMemPool.size/2); pDci->cmdNwd.payload.allocData.allocSize = g_sec_tuiMemPool.size; break; case CMD_TUI_SW_STOP_DISPLAY: printk(KERN_ERR "tlcProcessCmd: CMD_TUI_SW_STOP_DISPLAY.\n"); /* Deactivate linux UI drivers */ ret = hal_tui_deactivate(); break; case CMD_TUI_SW_CLOSE_SESSION: printk(KERN_ERR "tlcProcessCmd: CMD_TUI_SW_CLOSE_SESSION & enable_irq(%d).\n", tsp_irq_num); disable_irq(pwr_irq_num); /* Activate linux UI drivers */ ret = hal_tui_activate(); tui_i2c_reset(); enable_irq(tsp_irq_num); hal_tui_free(); enable_irq(pwr_irq_num); /* Stop android TUI activity */ ret = sendCmdToUser(TLC_TUI_CMD_STOP_ACTIVITY); break; default: pr_debug("ERROR tlcProcessCmd: Unknown command %d\n", commandId); break; } /* Fill in response to SWd, fill ID LAST */ pr_debug("tlcProcessCmd: return 0x%08x to cmd 0x%08x\n", ret, commandId); pDci->nwdRsp.returnCode = ret; pDci->nwdRsp.id = RSP_ID(commandId); /* Acknowledge command */ pDci->cmdNwd.id = CMD_TUI_SW_NONE; /* Notify SWd */ pr_debug("DCI RSP NOTIFY CORE\n"); ret = mc_notify(&drSessionHandle); if (MC_DRV_OK != ret) pr_debug("ERROR tlcProcessCmd: Notify failed: %d\n", ret); }