/** * * 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; }
/** * * 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; }