zynq_lvgl/sw/swss/zynq_fsbl/pcap.c
2024-10-20 23:34:36 +08:00

791 lines
21 KiB
C

/*****************************************************************************
* Copyright (c) 2012 - 2020 Xilinx, Inc. All rights reserved.
* SPDX-License-Identifier: MIT
******************************************************************************/
/*****************************************************************************/
/**
*
* @file pcap.c
*
* Contains code for enabling and accessing the PCAP
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ---- -------- -------------------------------------------------------
* 1.00a ecm 02/10/10 Initial release
* 2.00a jz 05/28/11 Add SD support
* 2.00a mb 25/05/12 using the EDK provided devcfg driver
* Nand/SD encryption and review comments
* 3.00a mb 16/08/12 Added the poll function
* Removed the FPGA_RST_CTRL define
* Added the flag for NON PS instantiated bitstream
* 4.00a sgd 02/28/13 Fix for CR#681014 - ECC init in FSBL should not call
* fabric_init()
* Fix for CR#689026 - FSBL doesn't hold PL resets active
* during bit download
* Fix for CR#699475 - FSBL functionality is broken and
* its not able to boot in QSPI/NAND
* bootmode
* Fix for CR#705664 - FSBL fails to decrypt the
* bitstream when the image is AES
* encrypted using non-zero key value
* 6.00a kc 08/30/13 Fix for CR#722979 - Provide customer-friendly
* changelogs in FSBL
* 7.00a kc 10/25/13 Fix for CR#724620 - How to handle PCAP_MODE after
* bitstream configuration
* Fix for CR#726178 - FabricInit() PROG_B is kept active
* for 5mS.
* Fix for CR#731839 - FSBL has to check the
* HMAC error status after decryption
* 12/04/13 Fix for CR#764382 - How to handle PCAP_MODE after
* bitstream configuration - PCAP_MODE
* and PCAP_PR bits are not modified
* 8.00a kc 2/20/14 Fix for CR#775631 - FSBL: FsblGetGlobalTimer()
* is not proper
* 10.00a kc 07/24/14 Fix for CR#809336 - Minor code cleanup
* 13.00a ssc 04/10/15 Fix for CR#846899 - Corrected logic to clear
* DMA done count
* 15.00a gan 07/21/16 Fix for CR# 953654 -(2016.3)FSBL -
* In pcap.c/pcap.h/main.h,
* Fabric Initialization sequence
* is modified to check the PL power
* before sequence starts and checking
* INIT_B reset status twice in case
* of failure.
* 16.00a gan 08/02/16 Fix for CR# 955897 -(2016.3)FSBL -
* In pcap.c, check pl power
* through MCTRL register for
* 3.0 and later versions of silicon.
* </pre>
*
* @note
*
******************************************************************************/
/***************************** Include Files *********************************/
#include "pcap.h"
#include "nand.h" /* For NAND geometry information */
#include "fsbl.h"
#include "image_mover.h" /* For MoveImage */
#include "xparameters.h"
#include "xil_exception.h"
#include "xdevcfg.h"
#include "sleep.h"
#include "xtime_l.h"
#ifdef XPAR_XWDTPS_0_BASEADDR
#include "xwdtps.h"
#endif
/************************** Constant Definitions *****************************/
/*
* The following constants map to the XPAR parameters created in the
* xparameters.h file. They are only defined here such that a user can easily
* change all the needed parameters in one place.
*/
#define DCFG_DEVICE_ID XPAR_XDCFG_0_DEVICE_ID
/**************************** Type Definitions *******************************/
/***************** Macros (Inline Functions) Definitions *********************/
/************************** Function Prototypes ******************************/
extern int XDcfgPollDone(u32 MaskValue, u32 MaxCount);
/************************** Variable Definitions *****************************/
/* Devcfg driver instance */
static XDcfg DcfgInstance;
XDcfg *DcfgInstPtr;
extern u32 Silicon_Version;
#ifdef XPAR_XWDTPS_0_BASEADDR
extern XWdtPs Watchdog; /* Instance of WatchDog Timer */
#endif
/******************************************************************************/
/**
*
* This function transfer data using PCAP
*
* @param SourceDataPtr is a pointer to where the data is read from
* @param DestinationDataPtr is a pointer to where the data is written to
* @param SourceLength is the length of the data to be moved in words
* @param DestinationLength is the length of the data to be moved in words
* @param SecureTransfer indicated the encryption key location, 0 for
* non-encrypted
*
* @return
* - XST_SUCCESS if the transfer is successful
* - XST_FAILURE if the transfer fails
*
* @note None
*
****************************************************************************/
u32 PcapDataTransfer(u32 *SourceDataPtr, u32 *DestinationDataPtr,
u32 SourceLength, u32 DestinationLength, u32 SecureTransfer)
{
u32 Status;
u32 IntrStsReg;
u32 PcapTransferType = XDCFG_CONCURRENT_NONSEC_READ_WRITE;
/*
* Check for secure transfer
*/
if (SecureTransfer) {
PcapTransferType = XDCFG_CONCURRENT_SECURE_READ_WRITE;
}
#ifdef FSBL_PERF
XTime tXferCur = 0;
FsblGetGlobalTime(&tXferCur);
#endif
/*
* Clear the PCAP status registers
*/
Status = ClearPcapStatus();
if (Status != XST_SUCCESS) {
fsbl_printf(DEBUG_INFO,"PCAP_CLEAR_STATUS_FAIL \r\n");
return XST_FAILURE;
}
#ifdef XPAR_XWDTPS_0_BASEADDR
/*
* Prevent WDT reset
*/
XWdtPs_RestartWdt(&Watchdog);
#endif
/*
* PCAP single DMA transfer setup
*/
SourceDataPtr = (u32*)((u32)SourceDataPtr | PCAP_LAST_TRANSFER);
DestinationDataPtr = (u32*)((u32)DestinationDataPtr | PCAP_LAST_TRANSFER);
/*
* Transfer using Device Configuration
*/
Status = XDcfg_Transfer(DcfgInstPtr, (u8 *)SourceDataPtr,
SourceLength,
(u8 *)DestinationDataPtr,
DestinationLength, PcapTransferType);
if (Status != XST_SUCCESS) {
fsbl_printf(DEBUG_INFO,"Status of XDcfg_Transfer = %lu \r \n",Status);
return XST_FAILURE;
}
/*
* Dump the PCAP registers
*/
PcapDumpRegisters();
/*
* Poll for the DMA done
*/
Status = XDcfgPollDone(XDCFG_IXR_DMA_DONE_MASK, MAX_COUNT);
if (Status != XST_SUCCESS) {
fsbl_printf(DEBUG_INFO,"PCAP_DMA_DONE_FAIL \r\n");
return XST_FAILURE;
}
fsbl_printf(DEBUG_INFO,"DMA Done ! \n\r");
/*
* Check for errors
*/
IntrStsReg = XDcfg_IntrGetStatus(DcfgInstPtr);
if (IntrStsReg & FSBL_XDCFG_IXR_ERROR_FLAGS_MASK) {
fsbl_printf(DEBUG_INFO,"Errors in PCAP \r\n");
return XST_FAILURE;
}
/*
* For Performance measurement
*/
#ifdef FSBL_PERF
XTime tXferEnd = 0;
fsbl_printf(DEBUG_GENERAL,"Time taken is ");
FsblMeasurePerfTime(tXferCur,tXferEnd);
#endif
return XST_SUCCESS;
}
/******************************************************************************/
/**
*
* This function loads PL partition using PCAP
*
* @param SourceDataPtr is a pointer to where the data is read from
* @param DestinationDataPtr is a pointer to where the data is written to
* @param SourceLength is the length of the data to be moved in words
* @param DestinationLength is the length of the data to be moved in words
* @param SecureTransfer indicated the encryption key location, 0 for
* non-encrypted
*
* @return
* - XST_SUCCESS if the transfer is successful
* - XST_FAILURE if the transfer fails
*
* @note None
*
****************************************************************************/
u32 PcapLoadPartition(u32 *SourceDataPtr, u32 *DestinationDataPtr,
u32 SourceLength, u32 DestinationLength, u32 SecureTransfer)
{
u32 Status;
u32 IntrStsReg;
u32 PcapTransferType = XDCFG_NON_SECURE_PCAP_WRITE;
/*
* Check for secure transfer
*/
if (SecureTransfer) {
PcapTransferType = XDCFG_SECURE_PCAP_WRITE;
}
#ifdef FSBL_PERF
XTime tXferCur = 0;
FsblGetGlobalTime(&tXferCur);
#endif
/*
* Clear the PCAP status registers
*/
Status = ClearPcapStatus();
if (Status != XST_SUCCESS) {
fsbl_printf(DEBUG_INFO,"PCAP_CLEAR_STATUS_FAIL \r\n");
return XST_FAILURE;
}
/*
* For Bitstream case destination address will be 0xFFFFFFFF
*/
DestinationDataPtr = (u32*)XDCFG_DMA_INVALID_ADDRESS;
/*
* New Bitstream download initialization sequence
*/
Status = FabricInit();
if (Status != XST_SUCCESS) {
return XST_FAILURE;
}
#ifdef XPAR_XWDTPS_0_BASEADDR
/*
* Prevent WDT reset
*/
XWdtPs_RestartWdt(&Watchdog);
#endif
/*
* PCAP single DMA transfer setup
*/
SourceDataPtr = (u32*)((u32)SourceDataPtr | PCAP_LAST_TRANSFER);
DestinationDataPtr = (u32*)((u32)DestinationDataPtr | PCAP_LAST_TRANSFER);
/*
* Transfer using Device Configuration
*/
Status = XDcfg_Transfer(DcfgInstPtr, (u8 *)SourceDataPtr,
SourceLength,
(u8 *)DestinationDataPtr,
DestinationLength, PcapTransferType);
if (Status != XST_SUCCESS) {
fsbl_printf(DEBUG_INFO,"Status of XDcfg_Transfer = %lu \r \n",Status);
return XST_FAILURE;
}
/*
* Dump the PCAP registers
*/
PcapDumpRegisters();
/*
* Poll for the DMA done
*/
Status = XDcfgPollDone(XDCFG_IXR_DMA_DONE_MASK, MAX_COUNT);
if (Status != XST_SUCCESS) {
fsbl_printf(DEBUG_INFO,"PCAP_DMA_DONE_FAIL \r\n");
return XST_FAILURE;
}
fsbl_printf(DEBUG_INFO,"DMA Done ! \n\r");
/*
* Poll for FPGA Done
*/
Status = XDcfgPollDone(XDCFG_IXR_PCFG_DONE_MASK, MAX_COUNT);
if (Status != XST_SUCCESS) {
fsbl_printf(DEBUG_INFO,"PCAP_FPGA_DONE_FAIL\r\n");
return XST_FAILURE;
}
fsbl_printf(DEBUG_INFO,"FPGA Done ! \n\r");
/*
* Check for errors
*/
IntrStsReg = XDcfg_IntrGetStatus(DcfgInstPtr);
if (IntrStsReg & FSBL_XDCFG_IXR_ERROR_FLAGS_MASK) {
fsbl_printf(DEBUG_INFO,"Errors in PCAP \r\n");
return XST_FAILURE;
}
/*
* For Performance measurement
*/
#ifdef FSBL_PERF
XTime tXferEnd = 0;
fsbl_printf(DEBUG_GENERAL,"Time taken is ");
FsblMeasurePerfTime(tXferCur,tXferEnd);
#endif
return XST_SUCCESS;
}
/******************************************************************************/
/**
*
* This function Initializes the PCAP driver.
*
* @param none
*
* @return
* - XST_SUCCESS if the pcap driver initialization is successful
* - XST_FAILURE if the pcap driver initialization fails
*
* @note none
*
****************************************************************************/
int InitPcap(void)
{
XDcfg_Config *ConfigPtr;
int Status = XST_SUCCESS;
DcfgInstPtr = &DcfgInstance;
/*
* Initialize the Device Configuration Interface driver.
*/
ConfigPtr = XDcfg_LookupConfig(DCFG_DEVICE_ID);
Status = XDcfg_CfgInitialize(DcfgInstPtr, ConfigPtr,
ConfigPtr->BaseAddr);
if (Status != XST_SUCCESS) {
fsbl_printf(DEBUG_INFO, "XDcfg_CfgInitialize failed \n\r");
return XST_FAILURE;
}
return XST_SUCCESS;
}
/******************************************************************************/
/**
*
* This function programs the Fabric for use.
*
* @param None
*
* @return
* - XST_SUCCESS if the Fabric initialization is successful
* - XST_FAILURE if the Fabric initialization fails
* @note None
*
****************************************************************************/
u32 FabricInit(void)
{
u32 PcapReg;
u32 PcapCtrlRegVal;
u32 StatusReg;
u32 MctrlReg;
u32 PcfgInit;
u32 TimerExpired=0;
XTime tCur=0;
XTime tEnd=0;
/*
* Set Level Shifters DT618760 - PS to PL enabling
*/
Xil_Out32(PS_LVL_SHFTR_EN, LVL_PS_PL);
fsbl_printf(DEBUG_INFO,"Level Shifter Value = 0x%lx \r\n",
Xil_In32(PS_LVL_SHFTR_EN));
/*
* Get DEVCFG controller settings
*/
PcapReg = XDcfg_ReadReg(DcfgInstPtr->Config.BaseAddr,
XDCFG_CTRL_OFFSET);
/*
* Check the PL power status
*/
if(Silicon_Version >= SILICON_VERSION_3)
{
MctrlReg = XDcfg_GetMiscControlRegister(DcfgInstPtr);
if((MctrlReg & XDCFG_MCTRL_PCAP_PCFG_POR_B_MASK) !=
XDCFG_MCTRL_PCAP_PCFG_POR_B_MASK)
{
fsbl_printf(DEBUG_INFO,"Fabric not powered up\r\n");
return XST_FAILURE;
}
}
/*
* Setting PCFG_PROG_B signal to high
*/
XDcfg_WriteReg(DcfgInstPtr->Config.BaseAddr, XDCFG_CTRL_OFFSET,
(PcapReg | XDCFG_CTRL_PCFG_PROG_B_MASK));
/*
* Check for AES source key
*/
PcapCtrlRegVal = XDcfg_GetControlRegister(DcfgInstPtr);
if (PcapCtrlRegVal & XDCFG_CTRL_PCFG_AES_FUSE_MASK) {
/*
* 5msec delay
*/
usleep(5000);
}
/*
* Setting PCFG_PROG_B signal to low
*/
XDcfg_WriteReg(DcfgInstPtr->Config.BaseAddr, XDCFG_CTRL_OFFSET,
(PcapReg & ~XDCFG_CTRL_PCFG_PROG_B_MASK));
/*
* Check for AES source key
*/
if (PcapCtrlRegVal & XDCFG_CTRL_PCFG_AES_FUSE_MASK) {
/*
* 5msec delay
*/
usleep(5000);
}
/*
* Polling the PCAP_INIT status for Reset or timeout
*/
XTime_GetTime(&tCur);
do
{
PcfgInit = (XDcfg_GetStatusRegister(DcfgInstPtr) &
XDCFG_STATUS_PCFG_INIT_MASK);
if(PcfgInit == 0)
{
break;
}
XTime_GetTime(&tEnd);
if((u64)((u64)tCur + (COUNTS_PER_MILLI_SECOND*30)) > (u64)tEnd)
{
TimerExpired = 1;
}
} while(!TimerExpired);
if(TimerExpired == 1)
{
TimerExpired = 0;
/*
* Came here due to expiration and PCAP_INIT is set.
* Retry PCFG_PROG_B High -> Low again
*/
/*
* Setting PCFG_PROG_B signal to high
*/
XDcfg_WriteReg(DcfgInstPtr->Config.BaseAddr, XDCFG_CTRL_OFFSET,
(PcapReg | XDCFG_CTRL_PCFG_PROG_B_MASK));
/*
* Check for AES source key
*/
PcapCtrlRegVal = XDcfg_GetControlRegister(DcfgInstPtr);
if (PcapCtrlRegVal & XDCFG_CTRL_PCFG_AES_FUSE_MASK) {
/*
* 5msec delay
*/
usleep(5000);
}
/*
* Setting PCFG_PROG_B signal to low
*/
XDcfg_WriteReg(DcfgInstPtr->Config.BaseAddr, XDCFG_CTRL_OFFSET,
(PcapReg & ~XDCFG_CTRL_PCFG_PROG_B_MASK));
/*
* Check for AES source key
*/
if (PcapCtrlRegVal & XDCFG_CTRL_PCFG_AES_FUSE_MASK) {
/*
* 5msec delay
*/
usleep(5000);
}
/*
* Polling the PCAP_INIT status for Reset or timeout (second iteration)
*/
XTime_GetTime(&tCur);
do
{
PcfgInit = (XDcfg_GetStatusRegister(DcfgInstPtr) &
XDCFG_STATUS_PCFG_INIT_MASK);
if(PcfgInit == 0)
{
break;
}
XTime_GetTime(&tEnd);
if((u64)((u64)tCur + (COUNTS_PER_MILLI_SECOND*30)) > (u64)tEnd)
{
TimerExpired = 1;
}
} while(!TimerExpired);
if(TimerExpired == 1)
{
/*
* Came here due to PCAP_INIT is not getting reset
* for PCFG_PROG_B signal High -> Low
*/
fsbl_printf(DEBUG_INFO,"Fabric Init failed\r\n");
return XST_FAILURE;
}
}
/*
* Setting PCFG_PROG_B signal to high
*/
XDcfg_WriteReg(DcfgInstPtr->Config.BaseAddr, XDCFG_CTRL_OFFSET,
(PcapReg | XDCFG_CTRL_PCFG_PROG_B_MASK));
/*
* Polling the PCAP_INIT status for Set
*/
while(!(XDcfg_GetStatusRegister(DcfgInstPtr) &
XDCFG_STATUS_PCFG_INIT_MASK));
/*
* Get Device configuration status
*/
StatusReg = XDcfg_GetStatusRegister(DcfgInstPtr);
fsbl_printf(DEBUG_INFO,"Devcfg Status register = 0x%lx \r\n",StatusReg);
fsbl_printf(DEBUG_INFO,"PCAP:Fabric is Initialized done\r\n");
return XST_SUCCESS;
}
/******************************************************************************/
/**
*
* This function Clears the PCAP status registers.
*
* @param None
*
* @return
* - XST_SUCCESS if the pcap status registers are cleared
* - XST_FAILURE if errors are there
* - XST_DEVICE_BUSY if Pcap device is busy
* @note None
*
****************************************************************************/
u32 ClearPcapStatus(void)
{
u32 StatusReg;
u32 IntStatusReg;
/*
* Clear it all, so if Boot ROM comes back, it can proceed
*/
XDcfg_IntrClear(DcfgInstPtr, 0xFFFFFFFF);
/*
* Get PCAP Interrupt Status Register
*/
IntStatusReg = XDcfg_IntrGetStatus(DcfgInstPtr);
if (IntStatusReg & FSBL_XDCFG_IXR_ERROR_FLAGS_MASK) {
fsbl_printf(DEBUG_INFO,"FATAL errors in PCAP %lx\r\n",
IntStatusReg);
return XST_FAILURE;
}
/*
* Read the PCAP status register for DMA status
*/
StatusReg = XDcfg_GetStatusRegister(DcfgInstPtr);
fsbl_printf(DEBUG_INFO,"PCAP:StatusReg = 0x%.8lx\r\n", StatusReg);
/*
* If the queue is full, return w/ XST_DEVICE_BUSY
*/
if ((StatusReg & XDCFG_STATUS_DMA_CMD_Q_F_MASK) ==
XDCFG_STATUS_DMA_CMD_Q_F_MASK) {
fsbl_printf(DEBUG_INFO,"PCAP_DEVICE_BUSY\r\n");
return XST_DEVICE_BUSY;
}
fsbl_printf(DEBUG_INFO,"PCAP:device ready\r\n");
/*
* There are unacknowledged DMA commands outstanding
*/
if ((StatusReg & XDCFG_STATUS_DMA_CMD_Q_E_MASK) !=
XDCFG_STATUS_DMA_CMD_Q_E_MASK) {
IntStatusReg = XDcfg_IntrGetStatus(DcfgInstPtr);
if ((IntStatusReg & XDCFG_IXR_DMA_DONE_MASK) !=
XDCFG_IXR_DMA_DONE_MASK){
/*
* Error state, transfer cannot occur
*/
fsbl_printf(DEBUG_INFO,"PCAP:IntStatus indicates error\r\n");
return XST_FAILURE;
}
else {
/*
* clear out the status
*/
XDcfg_IntrClear(DcfgInstPtr, XDCFG_IXR_DMA_DONE_MASK);
}
}
if ((StatusReg & XDCFG_STATUS_DMA_DONE_CNT_MASK) != 0) {
XDcfg_SetStatusRegister(DcfgInstPtr, StatusReg |
XDCFG_STATUS_DMA_DONE_CNT_MASK);
}
fsbl_printf(DEBUG_INFO,"PCAP:Clear done\r\n");
return XST_SUCCESS;
}
/******************************************************************************/
/**
*
* This function prints PCAP register status.
*
* @param none
*
* @return none
*
* @note none
*
****************************************************************************/
void PcapDumpRegisters (void) {
fsbl_printf(DEBUG_INFO,"PCAP register dump:\r\n");
fsbl_printf(DEBUG_INFO,"PCAP CTRL 0x%x: 0x%08lx\r\n",
XPS_DEV_CFG_APB_BASEADDR + XDCFG_CTRL_OFFSET,
Xil_In32(XPS_DEV_CFG_APB_BASEADDR + XDCFG_CTRL_OFFSET));
fsbl_printf(DEBUG_INFO,"PCAP LOCK 0x%x: 0x%08lx\r\n",
XPS_DEV_CFG_APB_BASEADDR + XDCFG_LOCK_OFFSET,
Xil_In32(XPS_DEV_CFG_APB_BASEADDR + XDCFG_LOCK_OFFSET));
fsbl_printf(DEBUG_INFO,"PCAP CONFIG 0x%x: 0x%08lx\r\n",
XPS_DEV_CFG_APB_BASEADDR + XDCFG_CFG_OFFSET,
Xil_In32(XPS_DEV_CFG_APB_BASEADDR + XDCFG_CFG_OFFSET));
fsbl_printf(DEBUG_INFO,"PCAP ISR 0x%x: 0x%08lx\r\n",
XPS_DEV_CFG_APB_BASEADDR + XDCFG_INT_STS_OFFSET,
Xil_In32(XPS_DEV_CFG_APB_BASEADDR + XDCFG_INT_STS_OFFSET));
fsbl_printf(DEBUG_INFO,"PCAP IMR 0x%x: 0x%08lx\r\n",
XPS_DEV_CFG_APB_BASEADDR + XDCFG_INT_MASK_OFFSET,
Xil_In32(XPS_DEV_CFG_APB_BASEADDR + XDCFG_INT_MASK_OFFSET));
fsbl_printf(DEBUG_INFO,"PCAP STATUS 0x%x: 0x%08lx\r\n",
XPS_DEV_CFG_APB_BASEADDR + XDCFG_STATUS_OFFSET,
Xil_In32(XPS_DEV_CFG_APB_BASEADDR + XDCFG_STATUS_OFFSET));
fsbl_printf(DEBUG_INFO,"PCAP DMA SRC ADDR 0x%x: 0x%08lx\r\n",
XPS_DEV_CFG_APB_BASEADDR + XDCFG_DMA_SRC_ADDR_OFFSET,
Xil_In32(XPS_DEV_CFG_APB_BASEADDR + XDCFG_DMA_SRC_ADDR_OFFSET));
fsbl_printf(DEBUG_INFO,"PCAP DMA DEST ADDR 0x%x: 0x%08lx\r\n",
XPS_DEV_CFG_APB_BASEADDR + XDCFG_DMA_DEST_ADDR_OFFSET,
Xil_In32(XPS_DEV_CFG_APB_BASEADDR + XDCFG_DMA_DEST_ADDR_OFFSET));
fsbl_printf(DEBUG_INFO,"PCAP DMA SRC LEN 0x%x: 0x%08lx\r\n",
XPS_DEV_CFG_APB_BASEADDR + XDCFG_DMA_SRC_LEN_OFFSET,
Xil_In32(XPS_DEV_CFG_APB_BASEADDR + XDCFG_DMA_SRC_LEN_OFFSET));
fsbl_printf(DEBUG_INFO,"PCAP DMA DEST LEN 0x%x: 0x%08lx\r\n",
XPS_DEV_CFG_APB_BASEADDR + XDCFG_DMA_DEST_LEN_OFFSET,
Xil_In32(XPS_DEV_CFG_APB_BASEADDR + XDCFG_DMA_DEST_LEN_OFFSET));
fsbl_printf(DEBUG_INFO,"PCAP ROM SHADOW CTRL 0x%x: 0x%08lx\r\n",
XPS_DEV_CFG_APB_BASEADDR + XDCFG_ROM_SHADOW_OFFSET,
Xil_In32(XPS_DEV_CFG_APB_BASEADDR + XDCFG_ROM_SHADOW_OFFSET));
fsbl_printf(DEBUG_INFO,"PCAP MBOOT 0x%x: 0x%08lx\r\n",
XPS_DEV_CFG_APB_BASEADDR + XDCFG_MULTIBOOT_ADDR_OFFSET,
Xil_In32(XPS_DEV_CFG_APB_BASEADDR + XDCFG_MULTIBOOT_ADDR_OFFSET));
fsbl_printf(DEBUG_INFO,"PCAP SW ID 0x%x: 0x%08lx\r\n",
XPS_DEV_CFG_APB_BASEADDR + XDCFG_SW_ID_OFFSET,
Xil_In32(XPS_DEV_CFG_APB_BASEADDR + XDCFG_SW_ID_OFFSET));
fsbl_printf(DEBUG_INFO,"PCAP UNLOCK 0x%x: 0x%08lx\r\n",
XPS_DEV_CFG_APB_BASEADDR + XDCFG_UNLOCK_OFFSET,
Xil_In32(XPS_DEV_CFG_APB_BASEADDR + XDCFG_UNLOCK_OFFSET));
fsbl_printf(DEBUG_INFO,"PCAP MCTRL 0x%x: 0x%08lx\r\n",
XPS_DEV_CFG_APB_BASEADDR + XDCFG_MCTRL_OFFSET,
Xil_In32(XPS_DEV_CFG_APB_BASEADDR + XDCFG_MCTRL_OFFSET));
}
/******************************************************************************/
/**
*
* This function Polls for the DMA done or FPGA done.
*
* @param none
*
* @return
* - XST_SUCCESS if polling for DMA/FPGA done is successful
* - XST_FAILURE if polling for DMA/FPGA done fails
*
* @note none
*
****************************************************************************/
int XDcfgPollDone(u32 MaskValue, u32 MaxCount)
{
int Count = MaxCount;
u32 IntrStsReg = 0;
/*
* poll for the DMA done
*/
IntrStsReg = XDcfg_IntrGetStatus(DcfgInstPtr);
while ((IntrStsReg & MaskValue) !=
MaskValue) {
IntrStsReg = XDcfg_IntrGetStatus(DcfgInstPtr);
Count -=1;
if (IntrStsReg & FSBL_XDCFG_IXR_ERROR_FLAGS_MASK) {
fsbl_printf(DEBUG_INFO,"FATAL errors in PCAP %lx\r\n",
IntrStsReg);
PcapDumpRegisters();
return XST_FAILURE;
}
if(!Count) {
fsbl_printf(DEBUG_GENERAL,"PCAP transfer timed out \r\n");
return XST_FAILURE;
}
if (Count > (MAX_COUNT-100)) {
fsbl_printf(DEBUG_GENERAL,".");
}
}
fsbl_printf(DEBUG_GENERAL,"\n\r");
XDcfg_IntrClear(DcfgInstPtr, IntrStsReg & MaskValue);
return XST_SUCCESS;
}