Пример #1
0
/**
*
* Run a self-test on the Device Configuration Interface. This test does a
* control register write and reads back the same value.
*
* @param	InstancePtr is a pointer to the XDcfg instance.
*
* @return
*		- XST_SUCCESS if self-test was successful.
*		- XST_FAILURE if fails.
*
* @note		None.
*
******************************************************************************/
int XDcfg_SelfTest(XDcfg *InstancePtr)
{
	u32 OldCfgReg;
	u32 CfgReg;
	int Status = XST_SUCCESS;

	/*
	 * Assert to ensure the inputs are valid and the instance has been
	 * initialized.
	 */
	Xil_AssertNonvoid(InstancePtr != NULL);
	Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);

	OldCfgReg = XDcfg_GetControlRegister(InstancePtr);

	XDcfg_SetControlRegister(InstancePtr, XDCFG_CTRL_NIDEN_MASK);

	CfgReg = XDcfg_GetControlRegister(InstancePtr);

	if ((CfgReg & XDCFG_CTRL_NIDEN_MASK) != XDCFG_CTRL_NIDEN_MASK) {

		Status = XST_FAILURE;
	}

	/*
	 * Restore the original values of the register
	 */
	XDcfg_SetControlRegister(InstancePtr, OldCfgReg);

	return Status;
}
Пример #2
0
/**
*
* This function starts the DMA transfer. This function only starts the
* operation and returns before the operation may be completed.
* If the interrupt is enabled, an interrupt will be generated when the
* operation is completed, otherwise it is necessary to poll the Status register
* to determine when it is completed. It is the responsibility of the caller to
* determine when the operation is completed by handling the generated interrupt
* or polling the Status Register.
*
* @param	InstancePtr is a pointer to the XDcfg instance.
* @param	SourcePtr contains a pointer to the source memory where the data
*		is to be transferred from.
* @param	SrcWordLength is the number of words (32 bit) to be transferred
*		for the source transfer.
* @param	DestPtr contains a pointer to the destination memory
*		where the data is to be transferred to.
* @param	DestWordLength is the number of words (32 bit) to be transferred
*		for the Destination transfer.
* @param	TransferType contains the type of PCAP transfer being requested.
*		The definitions can be found in the xdevcfg.h file.
* @return
*		- XST_SUCCESS.if DMA transfer initiated successfully
*		- XST_DEVICE_BUSY if DMA is busy
*		- XST_INVALID_PARAM if invalid Source / Destination address
*			is sent or an invalid Source / Destination length is
*			sent
*
* @note		It is the responsibility of the caller to ensure that the cache
*		is flushed and invalidated both before the DMA operation is
*		started and after the DMA operation completes if the memory
*		pointed to is  cached. The caller must also ensure that the
*		pointers contain physical address rather than a virtual address
*		if address translation is being used.
*
* 		The 2 LSBs of the SourcePtr (Source)/ DestPtr (Destination)
*		address when equal to 2’b01 indicates the last DMA command of
*		an overall transfer.
*
*****************************************************************************/
u32 XDcfg_Transfer(XDcfg *InstancePtr,
			void *SourcePtr, u32 SrcWordLength,
			void *DestPtr, u32 DestWordLength,
			u32 TransferType)
{

	u32 CtrlReg;

	Xil_AssertNonvoid(InstancePtr != NULL);
	Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);


	if (XDcfg_IsDmaBusy(InstancePtr) == XST_SUCCESS) {
		return XST_DEVICE_BUSY;
	}

	/*
	 * Check whether the fabric is in initialized state
	 */
	if ((XDcfg_ReadReg(InstancePtr->Config.BaseAddr, XDCFG_STATUS_OFFSET)
			& XDCFG_STATUS_PCFG_INIT_MASK) == 0) {
		/*
		 * We don't need to check PCFG_INIT to be high for
		 * non-encrypted loopback transfers.
		 */
		if (TransferType != XDCFG_CONCURRENT_NONSEC_READ_WRITE) {
			return XST_FAILURE;
		}
	}

	if ((TransferType == XDCFG_SECURE_PCAP_WRITE) ||
		(TransferType == XDCFG_NON_SECURE_PCAP_WRITE)) {

		/* Check for valid source pointer and length */
		if ((!SourcePtr) || (SrcWordLength == 0)) {
			return XST_INVALID_PARAM;
		}

		/* Clear internal PCAP loopback */
		CtrlReg = XDcfg_ReadReg(InstancePtr->Config.BaseAddr,
					XDCFG_MCTRL_OFFSET);
		XDcfg_WriteReg(InstancePtr->Config.BaseAddr,
				XDCFG_MCTRL_OFFSET, (CtrlReg &
				~(XDCFG_MCTRL_PCAP_LPBK_MASK)));

		if (TransferType == XDCFG_NON_SECURE_PCAP_WRITE) {
			/*
			 * Clear QUARTER_PCAP_RATE_EN bit
			 * so that the PCAP data is transmitted every clock
			 */
			CtrlReg = XDcfg_ReadReg(InstancePtr->Config.BaseAddr,
						XDCFG_CTRL_OFFSET);

			XDcfg_WriteReg(InstancePtr->Config.BaseAddr,
					XDCFG_CTRL_OFFSET, (CtrlReg &
					  ~XDCFG_CTRL_PCAP_RATE_EN_MASK));

		}
		if (TransferType == XDCFG_SECURE_PCAP_WRITE) {
			/*
			 * AES engine handles only 8 bit data every clock cycle.
			 * Hence, Encrypted PCAP data which is 32 bit data can
			 * only be sent in every 4 clock cycles. Set the control
			 * register QUARTER_PCAP_RATE_EN bit to achieve this
			 * operation.
			 */
			XDcfg_SetControlRegister(InstancePtr,
						XDCFG_CTRL_PCAP_RATE_EN_MASK);
		}

		XDcfg_InitiateDma(InstancePtr, (u32)SourcePtr,
				(u32)DestPtr, SrcWordLength, DestWordLength);

	}

	if (TransferType == XDCFG_PCAP_READBACK) {

		if ((!DestPtr) || (DestWordLength == 0)) {

			return XST_INVALID_PARAM;
		}

		/* Clear internal PCAP loopback */
		CtrlReg = XDcfg_ReadReg(InstancePtr->Config.BaseAddr,
					XDCFG_MCTRL_OFFSET);
		XDcfg_WriteReg(InstancePtr->Config.BaseAddr,
				XDCFG_MCTRL_OFFSET, (CtrlReg &
				~(XDCFG_MCTRL_PCAP_LPBK_MASK)));

		/*
		 * For PCAP readback of FPGA configuration register or memory,
		 * the read command is first sent (written) to the FPGA fabric
		 * which responds by returning the required read data. Read data
		 * from the FPGA is captured if pcap_radata_v is active.A DMA
		 * read transfer is required to obtain the readback command,
		 * which is then sent to the FPGA, followed by a DMA write
		 * transfer to support this mode of operation.
		 */
		return XDcfg_PcapReadback(InstancePtr,
					 (u32)SourcePtr, SrcWordLength,
					 (u32)DestPtr, 	 DestWordLength);
	}


	if ((TransferType == XDCFG_CONCURRENT_SECURE_READ_WRITE) ||
		(TransferType == XDCFG_CONCURRENT_NONSEC_READ_WRITE)) {

		if ((!SourcePtr) || (SrcWordLength == 0) ||
			(!DestPtr) || (DestWordLength == 0)) {
			return XST_INVALID_PARAM;
		}

		if (TransferType == XDCFG_CONCURRENT_NONSEC_READ_WRITE) {
			/* Enable internal PCAP loopback */
			CtrlReg = XDcfg_ReadReg(InstancePtr->Config.BaseAddr,
					XDCFG_MCTRL_OFFSET);
			XDcfg_WriteReg(InstancePtr->Config.BaseAddr,
					XDCFG_MCTRL_OFFSET, (CtrlReg |
					XDCFG_MCTRL_PCAP_LPBK_MASK));

			/*
			 * Clear QUARTER_PCAP_RATE_EN bit
			 * so that the PCAP data is transmitted every clock
			 */
			CtrlReg = XDcfg_ReadReg(InstancePtr->Config.BaseAddr,
						XDCFG_CTRL_OFFSET);

			XDcfg_WriteReg(InstancePtr->Config.BaseAddr,
					XDCFG_CTRL_OFFSET, (CtrlReg &
					  ~XDCFG_CTRL_PCAP_RATE_EN_MASK));

		}
		if (TransferType == XDCFG_CONCURRENT_SECURE_READ_WRITE) {
			/* Clear internal PCAP loopback */
			CtrlReg = XDcfg_ReadReg(InstancePtr->Config.BaseAddr,
						XDCFG_MCTRL_OFFSET);
			XDcfg_WriteReg(InstancePtr->Config.BaseAddr,
					XDCFG_MCTRL_OFFSET, (CtrlReg &
					~(XDCFG_MCTRL_PCAP_LPBK_MASK)));

			/*
			 * Set the QUARTER_PCAP_RATE_EN bit
			 * so that the PCAP data is transmitted every 4 clock
			 * cycles, this is required for encrypted data.
			 */
			XDcfg_SetControlRegister(InstancePtr,
					XDCFG_CTRL_PCAP_RATE_EN_MASK);
		}

		XDcfg_InitiateDma(InstancePtr, (u32)SourcePtr,
				(u32)DestPtr, SrcWordLength, DestWordLength);
	}

	return XST_SUCCESS;
}