Beispiel #1
0
/** This is the function to write data to PCAP interface
 *
 * @param	WrSize: Number of 32bit words that the DMA should write to
 *          the PCAP interface
 * @param   WrAddr: Linear memory space from where CSUDMA will read
 *	        the data to be written to PCAP interface
 *
 * @return	None
 *
 *****************************************************************************/
u32 XFsbl_WriteToPcap(u32 WrSize, u8 *WrAddr) {
	u32 RegVal;
	u32 Status = XFSBL_SUCCESS;

	/*
	 * Setup the  SSS, setup the PCAP to receive from DMA source
	 */
	RegVal = XFsbl_In32(CSU_CSU_SSS_CFG) & CSU_CSU_SSS_CFG_PCAP_SSS_MASK;
	RegVal = RegVal
			| (XFSBL_CSU_SSS_SRC_SRC_DMA << CSU_CSU_SSS_CFG_PCAP_SSS_SHIFT);
	XFsbl_Out32(CSU_CSU_SSS_CFG, RegVal);

	/* Setup the source DMA channel */
	XCsuDma_Transfer(&CsuDma, XCSUDMA_SRC_CHANNEL, (PTRSIZE) WrAddr, WrSize, 0);

	/* wait for the SRC_DMA to complete and the pcap to be IDLE */
	XCsuDma_WaitForDone(&CsuDma, XCSUDMA_SRC_CHANNEL);

	/* Acknowledge the transfer has completed */
	XCsuDma_IntrClear(&CsuDma, XCSUDMA_SRC_CHANNEL, XCSUDMA_IXR_DONE_MASK);

	XFsbl_Printf(DEBUG_GENERAL, "DMA transfer done \r\n");
	Status = XFsbl_PcapWaitForDone();
	if (Status != XFSBL_SUCCESS) {
		goto END;
	}

	END: return Status;
}
/**
 *
 * Sending the last data and padding when blocksize is not multiple of 104
 * bytes
 *
 * @param	InstancePtr is a pointer to the XSecure_Sha3 instance.
 * @param	Hash is the pointer to location where resulting hash will be
 *			written
 *
 * @return	None
 *
 * @note	None
 *
 *****************************************************************************/
void XSecure_Sha3Finish(XSecure_Sha3 *InstancePtr, u8 *Hash)
{
	/* Asserts validate the input arguments */
	Xil_AssertVoid(InstancePtr != NULL);
	Xil_AssertVoid(Hash != NULL);

	u32 *HashPtr = (u32 *)Hash;
	u32 PartialLen = InstancePtr->Sha3Len % XSECURE_SHA3_BLOCK_LEN;
	u8 XSecure_RsaSha3Array[512] = {0U};

	PartialLen = (PartialLen == 0U)?(XSECURE_SHA3_BLOCK_LEN) :
		(XSECURE_SHA3_BLOCK_LEN - PartialLen);

	XSecure_Sha3Padd(InstancePtr, XSecure_RsaSha3Array, PartialLen);

	XCsuDma_Transfer(InstancePtr->CsuDmaPtr, XCSUDMA_SRC_CHANNEL,
				(UINTPTR)XSecure_RsaSha3Array, PartialLen/4, 1);

	/* Check the SHA3 DONE bit. */
	XSecure_Sha3WaitForDone(InstancePtr);

	/* If requested, read out the Hash in reverse order.  */
	if (Hash)
	{
		u32 Index = 0U;
		u32 Val = 0U;
		for (Index=0U; Index < 12U; Index++)
		{
			Val = XSecure_ReadReg(InstancePtr->BaseAddress,
				XSECURE_CSU_SHA3_DIGEST_0_OFFSET + (Index * 4));
			HashPtr[11U - Index] = Val;
		}
	}

}
/******************************************************************************
*
* This function is used to copy data to AES/PL.
*
* @param	InstancePtr is an instance of CSUDMA
* @param	Src holds the source Address
* @param	Size of the data
* @param	EnLast - 0 or 1
*
* @return	None
*
* @note		None
*
******************************************************************************/
static void XFsbl_DmaPlCopy(XCsuDma *InstancePtr, UINTPTR Src, u32 Size,
			u8 EnLast)
{

	/* Data transfer */
	XCsuDma_Transfer(InstancePtr, XCSUDMA_SRC_CHANNEL, (UINTPTR)Src,
							Size, EnLast);
	/* Polling for transfer to be done */
	XCsuDma_WaitForDone(InstancePtr, XCSUDMA_SRC_CHANNEL);
	/* To acknowledge the transfer has completed */
	XCsuDma_IntrClear(InstancePtr, XCSUDMA_SRC_CHANNEL,
					XCSUDMA_IXR_DONE_MASK);

}
/**
 *
 * Update hash for new input data block
 *
 * @param	InstancePtr is a pointer to the XSecure_Sha3 instance.
 * @param	Data is the pointer to the input data for hashing
 * @param	Size of the input data in bytes
 *
 * @return	None
 *
 * @note	None
 *
 ******************************************************************************/
void XSecure_Sha3Update(XSecure_Sha3 *InstancePtr, const u8 *Data,
						const u32 Size)
{
	/* Asserts validate the input arguments */
	Xil_AssertVoid(InstancePtr != NULL);
	Xil_AssertVoid(Size != (u32)0x00U);

	InstancePtr->Sha3Len += Size;

	XCsuDma_Transfer(InstancePtr->CsuDmaPtr, XCSUDMA_SRC_CHANNEL,
					(UINTPTR)Data, (u32)Size/4, 0);

	/* Checking the CSU DMA done bit should be enough. */
	XCsuDma_WaitForDone(InstancePtr->CsuDmaPtr, XCSUDMA_SRC_CHANNEL);

	/* Acknowledge the transfer has completed */
	XCsuDma_IntrClear(InstancePtr->CsuDmaPtr, XCSUDMA_SRC_CHANNEL,
						XCSUDMA_IXR_DONE_MASK);
}
/**
*
* This function performs data transfer in loop back mode in polled mode
* and verify the data.
*
* @param	DeviceId is the XPAR_<CSUDMA Instance>_DEVICE_ID value from
*		xparameters.h.
*
* @return
*		- XST_SUCCESS if successful.
*		- XST_FAILURE if failed.
*
* @note		None.
*
******************************************************************************/
int XCsuDma_PolledExample(u16 DeviceId)
{
	int Status;
	XCsuDma_Config *Config;
	u32 Index = 0;
	u32 *SrcPtr = (u32 *)SRC_ADDR;
	u32 *DstPtr = (u32 *)DST_ADDR;
	u32 Test_Data = 0xABCD1234;
	u32 *Ptr = (u32 *)SRC_ADDR;
	u32 EnLast = 0;
	/*
	 * Initialize the CsuDma driver so that it's ready to use
	 * look up the configuration in the config table,
	 * then initialize it.
	 */
	Config = XCsuDma_LookupConfig(DeviceId);
	if (NULL == Config) {
		return XST_FAILURE;
	}

	Status = XCsuDma_CfgInitialize(&CsuDma, Config, Config->BaseAddress);
	if (Status != XST_SUCCESS) {
		return XST_FAILURE;
	}

	/*
	 * Performs the self-test to check hardware build.
	 */
	Status = XCsuDma_SelfTest(&CsuDma);
	if (Status != XST_SUCCESS) {
		return XST_FAILURE;
	}

	/*
	 * Setting CSU_DMA in loop back mode.
	 */

	Xil_Out32(XCSU_BASEADDRESS + CSU_SSS_CONFIG_OFFSET,
		((Xil_In32(XCSU_BASEADDRESS + CSU_SSS_CONFIG_OFFSET) & 0xF0000) |
					CSUDMA_LOOPBACK_CFG));

	/* Data writing at source address location */

	for(Index = 0; Index < SIZE; Index++)
	{
		*Ptr = Test_Data;
		Test_Data += 0x1;
		Ptr++;
	}


	/* Data transfer in loop back mode */
	XCsuDma_Transfer(&CsuDma, XCSUDMA_DST_CHANNEL, DST_ADDR, SIZE, EnLast);
	XCsuDma_Transfer(&CsuDma, XCSUDMA_SRC_CHANNEL, SRC_ADDR, SIZE, EnLast);


	/* Polling for transfer to be done */
	XCsuDma_WaitForDone(&CsuDma, XCSUDMA_DST_CHANNEL);

	/* To acknowledge the transfer has completed */
	XCsuDma_IntrClear(&CsuDma, XCSUDMA_SRC_CHANNEL, XCSUDMA_IXR_DONE_MASK);
	XCsuDma_IntrClear(&CsuDma, XCSUDMA_DST_CHANNEL, XCSUDMA_IXR_DONE_MASK);

	/*
	 * Verifying data of transfered by comparing data at source
	 * and address locations.
	 */

	for (Index = 0; Index < SIZE; Index++) {
		if (*SrcPtr != *DstPtr) {
			return XST_FAILURE;
		}
		else {
			SrcPtr++;
			DstPtr++;
		}
	}

	return XST_SUCCESS;
}
/**
*
* This function performs data transfer in loop back mode in interrupt mode
* and verify the data.
*
* @param	DeviceId is the XPAR_<CSUDMA Instance>_DEVICE_ID value from
*		xparameters.h.
*
* @return
*		- XST_SUCCESS if successful.
*		- XST_FAILURE if failed.
*
* @note		None.
*
******************************************************************************/
int XCsuDma_IntrExample(u16 DeviceId)
{
	int Status;
	XCsuDma_Config *Config;
	u32 Index = 0;
	u32 *SrcPtr = (u32 *)SRC_ADDR;
	u32 *DstPtr = (u32 *)DST_ADDR;
	u32 Test_Data = 0xABCD1234;
	u32 *Ptr = (u32 *)SRC_ADDR;
	u32 EnLast = 0;
	/*
	 * Initialize the CsuDma driver so that it's ready to use
	 * look up the configuration in the config table,
	 * then initialize it.
	 */
	Config = XCsuDma_LookupConfig(DeviceId);
	if (NULL == Config) {
		return XST_FAILURE;
	}

	Status = XCsuDma_CfgInitialize(&CsuDma, Config, Config->BaseAddress);
	if (Status != XST_SUCCESS) {
		return XST_FAILURE;
	}

	/*
	 * Performs the self-test to check hardware build.
	 */
	Status = XCsuDma_SelfTest(&CsuDma);
	if (Status != XST_SUCCESS) {
		return XST_FAILURE;
	}

	/*
	 * Connect to the interrupt controller.
	 */
	Status = SetupInterruptSystem(&Intc, &CsuDma,
				INTG_CSUDMA_INTR_DEVICE_ID);
	if (Status != XST_SUCCESS) {
		return XST_FAILURE;
	}
	/* Enable interrupts */
	XCsuDma_EnableIntr(&CsuDma, XCSUDMA_DST_CHANNEL,
				XCSUDMA_IXR_DONE_MASK);
	/*
	 * Setting CSU_DMA in loop back mode.
	 */

	Xil_Out32(XCSU_BASEADDRESS + CSU_SSS_CONFIG_OFFSET,
		(Xil_In32(XCSU_BASEADDRESS + CSU_SSS_CONFIG_OFFSET) |
						CSUDMA_LOOPBACK_CFG));

	/* Data writing at source address location */

	for(Index = 0; Index < SIZE; Index++)
	{
		*Ptr = Test_Data;
		Test_Data += 0x1;
		Ptr++;
	}

	/* Data transfer in loop back mode */
	XCsuDma_Transfer(&CsuDma, XCSUDMA_DST_CHANNEL, DST_ADDR, SIZE, EnLast);
	XCsuDma_Transfer(&CsuDma, XCSUDMA_SRC_CHANNEL, SRC_ADDR, SIZE, EnLast);

	/* Wait for generation of destination work is done */
	while(DstDone == 0);
	/* Disable interrupts */
	XCsuDma_DisableIntr(&CsuDma, XCSUDMA_DST_CHANNEL,
				XCSUDMA_IXR_DONE_MASK);
	/* To acknowledge the transfer has completed */
	XCsuDma_IntrClear(&CsuDma, XCSUDMA_SRC_CHANNEL, XCSUDMA_IXR_DONE_MASK);
	XCsuDma_IntrClear(&CsuDma, XCSUDMA_DST_CHANNEL, XCSUDMA_IXR_DONE_MASK);

	/*
	 * Verifying data of transfered by comparing data at
	 * source and address locations.
	 */

	for (Index = 0; Index < SIZE; Index++) {
		if (*SrcPtr != *DstPtr) {
			return XST_FAILURE;
		}
		else {
			SrcPtr++;
			DstPtr++;
		}
	}

	return XST_SUCCESS;
}