/*! * This function waits for current descriptor sequence completion. */ void WaitForSequenceCompletionPlat(void) { int qid = CURR_QUEUE_ID(); uint32_t taskId = CURR_TASK_ID(); uint32_t lazyWait = 0; uint32_t irr = 0; uint32_t data = 0; /* Acknowledge completion to host */ AddCompletionDesc(qid, taskId, (void *)COMPLETION_EXTERNAL); /* wait for descriptor completion signal */ irr = DX_HAL_WaitInterrupt(data); /* clear interrupt */ DX_HAL_WriteCcRegister(DX_CC_REG_OFFSET(HOST_RGF, HOST_RGF_ICR), irr); /* check for compeltion */ while (!HW_QUEUE_NO_OS_IS_DESC_COMPLETED(irr)) { /* completion may be on its way... */ if (lazyWait++ > 100) { DX_PAL_Abort("Completion failed to arrive for too long"); } irr = DX_HAL_WaitInterrupt(data); /* clear interrupt */ DX_HAL_WriteCcRegister(DX_CC_REG_OFFSET(HOST_RGF, HOST_RGF_ICR), irr); } CompletionDescHandler(); //DX_PAL_LOG_INFO("Sequence completed\n"); //PRINT_INFO("Sequence completed\n"); }
/** * dx_sep_req_enable() - Enable the sep request interrupt handling * @drvdata: Driver private data */ void dx_sep_req_enable(struct sep_drvdata *drvdata) { /* clear pending interrupts in GPRs of SEP request * (leftovers from init writes to GPRs..) */ WRITE_REGISTER(drvdata->cc_base + DX_CC_REG_OFFSET(HOST, ICR), SEP_HOST_GPR_IRQ_MASK(DX_SEP_REQUEST_GPR_IDX)); /* set IMR register */ drvdata->irq_mask |= SEP_HOST_GPR_IRQ_MASK(DX_SEP_REQUEST_GPR_IDX); WRITE_REGISTER(drvdata->cc_base + DX_CC_REG_OFFSET(HOST, IMR), ~drvdata->irq_mask); }
static void CompletionDescHandler() { int qid; uint32_t status; status = 0; /* Init to lowest prioirty */ qid = 0; //PRINT_INFO("--->now into CompletionDescHandler()\n"); /* Mask only one counter per queue */ while ( (status |= ( DX_HAL_ReadCcRegister(DX_CC_REG_OFFSET(CRY_KERNEL,DSCRPTR_COMPLETION_STATUS)) & BITMASK(MAX_COMPLETION_COUNTERS))) ) { /* Loop will start at highest prioirty */ qid = (qid + 1 ) & (MAX_COMPLETION_COUNTERS-1); if (status & BITMASK_AT(1, qid)) { /* Read completion counter register. Counter is cleared once we read it ! */ gCompletionCount[qid] += DX_HAL_ReadCcRegister(DX_CC_REG_OFFSET(CRY_KERNEL, DSCRPTR_COMPLETION_COUNTER0) + qid*sizeof(uint32_t)); /* status still set, but engine completion counter was already handled */ if ( gCompletionCount[qid] == 0 ) { status = status & ~(BITMASK_AT(1, qid)); continue; } /* Get completion info from fifo, if not already done so */ if ( gCompletionCtx[qid] == COMPLETION_INVALID ) { CompletionFifoRemove(qid, &gTaskId[qid], &gCompletionCtx[qid], &gExpectedAxiWrites[qid]); } /* Actual bus values of AXI IDs for queues (0-3) DMA are 8, 9, A, B */ gAxiWriteCompleted[qid] += DX_CC_REG_FLD_GET(CRY_KERNEL, AXIM_MON_COMP8, VALUE, DX_HAL_ReadCcRegister(DX_CC_REG_OFFSET(CRY_KERNEL, AXIM_MON_COMP8) + QID_TO_AXI_ID(qid)*sizeof(uint32_t))); if ( gAxiWriteCompleted[qid] >= gExpectedAxiWrites[qid] ) { gAxiWriteCompleted[qid] -= gExpectedAxiWrites[qid]; gCompletionCtx[qid] = COMPLETION_INVALID; gCompletionCount[qid]--; } } /* if (status & BITMASK_AT(1, qid)) */ } /* while ( (status = ( READ_REGISTER... */ }
/*! * This function initializes the completion counter event, clears the * state structure and sets completion counter "0" as the first available * counter to be used when calling "AllocCounter". * * \return int one of the error codes defined in err.h */ int InitCompletionPlat(void) { uint8_t dummy; int qid; /* Clear completion fifo */ for ( qid=0; qid < MAX_NUM_HW_QUEUES; qid++ ) { /* Clear FIFO head/tail */ gCompletionFifoHead[qid] = 0; gCompletionFifoTail[qid] = 0; /* The global AXI write counter is reset only once */ gAxiWriteCompleted[qid] = 0; gCompletionCount[qid] = 0; gExpectedAxiWrites[qid] = 0; gCompletionCtx[qid] = COMPLETION_INVALID; DX_PAL_MemSetZero( gCompletionFifo, MAX_NUM_HW_QUEUES*COMPLETION_FIFO_LEN ); /* Clear all past AXI completion counters */ /* Actual bus values of AXI IDs for queues (0-3) DMA are 8, 9, A, B */ dummy = DX_HAL_ReadCcRegister(DX_CC_REG_OFFSET(CRY_KERNEL, AXIM_MON_COMP8) + QID_TO_AXI_ID(qid)*sizeof(uint32_t)); DX_PAL_LOG_DEBUG("Initial AXI_MON_COMP%d value=0x%08X\n", (int)qid, (unsigned int)dummy); dummy = dummy; /*avoid compiler warning*/ } return DX_RET_OK; }
static int process_hibernation_req(void) { enum dx_sep_state sep_state; int rc; sep_state = GET_SEP_STATE(power_control.drvdata); /* Already off, no need to send the sleep descriptor */ if (sep_state == DX_SEP_STATE_OFF || sep_state == DX_SEP_STATE_DONE_SLEEP_MODE) return 0; if (sep_state != DX_SEP_STATE_DONE_FW_INIT || !(is_desc_qs_active())) { pr_err("Requested hibernation while SeP state=0x%08X\n", sep_state); return -EINVAL; } rc = set_desc_qs_state(DESC_Q_ASLEEP); if (unlikely(rc != 0)) { pr_err("Failed moving queues to SLEEP state (%d)\n", rc); return rc; } /* Write value SEP_SLEEP_ENABLE command to GPR7 to initialize sleep sequence */ WRITE_REGISTER(power_control.drvdata->cc_base + DX_CC_REG_OFFSET(HOST, HOST_SEP_GPR7), SEP_SLEEP_ENABLE); /* Process state change */ sep_state = dx_sep_wait_for_state(DX_SEP_STATE_DONE_SLEEP_MODE, SEP_STATE_CHANGE_TIMEOUT_MSEC); switch (sep_state) { case DX_SEP_STATE_DONE_SLEEP_MODE: break; case DX_SEP_STATE_DONE_FW_INIT: pr_err("Transition to SLEEP mode aborted.\n"); rc = -EBUSY; break; case DX_SEP_STATE_PROC_SLEEP_MODE: pr_err("Stuck in processing of SLEEP req.\n"); rc = -ETIME; break; default: pr_err( "Unexpected SeP state after SLEEP request: 0x%08X\n", sep_state); rc = -EINVAL; } if (unlikely(rc != 0)) { sep_state = GET_SEP_STATE(power_control.drvdata); if (sep_state == DX_SEP_STATE_DONE_FW_INIT) /* Revert queues state on failure */ /* (if remained on active state) */ set_desc_qs_state(DESC_Q_ACTIVE); } else { reset_desc_qs(); } return rc; }
/*! * Busy wait upon Interrupt Request Register (IRR) signals. * This function notifys for any CC interrupt, it is the caller responsiblity * to verify and prompt the expected case interupt source. * * @param[in] data - input data for future use * \return uint32_t The IRR value. */ uint32_t DX_HAL_WaitInterrupt(uint32_t data) { uint32_t irr = 0; /* busy wait upon IRR signal */ while ( !(irr = DX_HAL_ReadCcRegister(DX_CC_REG_OFFSET(HOST_RGF, HOST_RGF_IRR))) ); return irr; }
/*! * Waits until the HW queue Water Mark is signaled. */ void WaitForHwQueueWaterMark(void) { uint32_t lazyWait = 0; uint32_t irr; uint32_t data = 0; /* wait for watermark signal */ irr = DX_HAL_WaitInterrupt(data); /* clear interrupt */ DX_HAL_WriteCcRegister(DX_CC_REG_OFFSET(HOST_RGF, HOST_RGF_ICR), irr); /* check if this is watermark signal */ while (!HW_QUEUE_NO_OS_IS_QUEUE_WATERMARK(irr)) { /* completion may be on its way... */ if (lazyWait++ > 100) { DX_PAL_Abort("WaterMark failed to arrive for too long"); } irr = DX_HAL_WaitInterrupt(data); /* clear interrupt */ DX_HAL_WriteCcRegister(DX_CC_REG_OFFSET(HOST_RGF, HOST_RGF_ICR), irr); } }
static int process_activate_req(void) { enum dx_sep_state sep_state; int rc; int count = 0; sep_state = GET_SEP_STATE(power_control.drvdata); if ((sep_state == DX_SEP_STATE_DONE_FW_INIT) && is_desc_qs_active()) { pr_info("Requested activation when in active state\n"); return 0; /* Already in this state */ } /* make sure Sep is not off before restore IMR */ if (sep_state == DX_SEP_STATE_OFF) { while (count < SEP_POWERON_TIMEOUT) { sep_state = GET_SEP_STATE(power_control.drvdata); if (sep_state != DX_SEP_STATE_OFF) break; usleep_range(50, 150); count++; } if (count >= SEP_TIMEOUT) { pr_info("Timeout while waiting SEP poweron\n"); return -ETIME; } } /* SeP may have been reset - restore IMR if SeP is not off */ /* This must be done before dx_sep_wait_for_state() */ WRITE_REGISTER(power_control.drvdata->cc_base + DX_CC_REG_OFFSET(HOST, IMR), ~power_control.drvdata->irq_mask); /* Nothing to initiate - just wait for FW_INIT_DONE */ sep_state = dx_sep_wait_for_state(DX_SEP_STATE_DONE_FW_INIT, SEP_STATE_CHANGE_TIMEOUT_MSEC); if (sep_state == DX_SEP_STATE_DONE_FW_INIT) rc = set_desc_qs_state(DESC_Q_ACTIVE); else { pr_info("Timeout while waiting SEP wakeup\n"); rc = -ETIME; /* Timed out waiting */ } return rc; }
/*! * TEE (Trusted Execution Environment) entry point. * Init CryptoCell for TEE. * * \return DX_CclibRetCode_t one of the error codes defined in dx_cclib.h */ DX_CclibRetCode_t DX_CclibInit(void) { int rc = DX_CCLIB_RET_OK; int virtMemBaseAddr = 0; PRINT_INFO("->now entrt into DX_CclibInit \n"); if(dx_cclib_init_state) { PRINT_INFO("->in DX_CclibInit :dx_cclib_init_state's value: 0x%x\n",dx_cclib_init_state); return DX_CCLIB_RET_OK; } PRINT_INFO("->in DX_CclibInit :before DX_PAL_Init \n"); virtMemBaseAddr = DX_PAL_Init(); PRINT_INFO("->in DX_CclibInit :DX_PAL_Init virtMemBaseAddr = %d\n",virtMemBaseAddr); if (NULL == (uint32_t *)virtMemBaseAddr) { PRINT_INFO("->in DX_CclibInit :DX_PAL_Init error,NULL == virtMemBaseAddr\n"); rc = DX_CCLIB_RET_EINVAL; goto InitErr; } rc = DX_HAL_Init(); PRINT_INFO("->in DX_CclibInit :DX_HAL_Init return:%d\n",rc); if (rc != DX_CCLIB_RET_OK) { PRINT_INFO("->in DX_CclibInit :DX_HAL_Init error,rc != DX_CCLIB_RET_OK\n"); rc = DX_CCLIB_RET_HAL; goto InitErr1; } /* Call sw reset to reset the CC before starting to work with it */ // DX_HAL_WriteCcRegister(DX_CC_REG_OFFSET(HOST_RGF, HOST_RGF_CC_SW_RST) , 0x1UL); /* wait for reset to be completed */ //for (i=0; i<20; i++); #ifdef BIG__ENDIAN /*initiate the Endian to BIG */ PRINT_INFO("->into BIG__ENDIAN\n"); DX_HAL_WriteCcRegister(DX_CC_REG_OFFSET(HOST_RGF, HOST_RGF_ENDIAN) , 0xCCUL); //DX_HAL_WriteCcRegister(DX_CC_REG_OFFSET(HOST_RGF, HOST_RGF_ENDIAN) , 0x00UL); #endif PRINT_INFO("->before InitHWQueue\n"); rc = InitHWQueue(NO_OS_QUEUE_ID); PRINT_INFO("->after InitHWQueue,InitHWQueue return value %d\n",rc); if (rc != DX_CCLIB_RET_OK) { PRINT_INFO("->n DX_CclibInit :InitHWQueue error,rc != DX_CCLIB_RET_OK\n"); rc = DX_CCLIB_RET_HW_Q_INIT; goto InitErr2; } PRINT_INFO("->before InitCompletion\n"); rc = InitCompletion(); PRINT_INFO("->after InitCompletion,InitCompletion return value %d\n",rc); if (rc != DX_CCLIB_RET_OK) { PRINT_INFO("->in DX_CclibInit :InitCompletion error,rc != DX_CCLIB_RET_OK\n"); rc = DX_CCLIB_RET_COMPLETION; goto InitErr2; } rc = SymDriverAdaptorModuleInit(); if (rc != DX_CCLIB_RET_OK) { rc = DX_CCLIB_RET_COMPLETION; // check goto InitErr; } #if ENABLE_RSA_DRIVER /* Initialize PKA's semaphore */ PRINT_INFO("->into ENABLE_RSA_DRIVER\n"); rc = DX_ASYM_Init(); #endif #ifndef CRYS_NO_RND_SUPPORT /* Initialize RND module */ rc = CRYS_RND_Instantiation(&workBuff_ptr); if (rc != CRYS_OK) { goto InitErr2; } #endif dx_cclib_init_state = DX_CCLIB_RET_OK; return 0; InitErr2: DX_HAL_Terminate(); InitErr1: DX_PAL_Terminate(); InitErr: PRINT_INFO("->in DX_CclibInit :at end,the rc value is:%d\n",rc); return rc; }