/*!
 * 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;
}
Esempio n. 6
0
/*!
 * 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;
}
Esempio n. 7
0
/*!
 * 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;
}
Esempio n. 9
0
/*! 
 * 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;
}