Example #1
0
/**
* This function perform the reset sequence to the given devcfg interface by
* configuring the appropriate control bits in the devcfg specifc registers
* the devcfg reset squence involves the following steps
*	Disable all the interuupts
*	Clear the status
*	Update relevant config registers with reset values
*	Disbale the looopback mode and pcap rate enable
*
* @param   BaseAddress of the interface
*
* @return N/A
*
* @note
* This function will not modify the slcr registers that are relavant for
* devcfg controller
******************************************************************************/
void XDcfg_ResetHw(u32 BaseAddr)
{
	u32 Regval = 0;

	/* Mask the interrupts  */
	XDcfg_WriteReg(BaseAddr, XDCFG_INT_MASK_OFFSET,
			XDCFG_IXR_ALL_MASK);
	/* Clear the interuupt status */
	Regval = XDcfg_ReadReg(BaseAddr, XDCFG_INT_STS_OFFSET);
	XDcfg_WriteReg(BaseAddr, XDCFG_INT_STS_OFFSET, Regval);
	/* Clear the source address register */
	XDcfg_WriteReg(BaseAddr, XDCFG_DMA_SRC_ADDR_OFFSET, 0x0);
	/* Clear the destination address register */
	XDcfg_WriteReg(BaseAddr, XDCFG_DMA_DEST_ADDR_OFFSET, 0x0);
	/* Clear the source length register */
	XDcfg_WriteReg(BaseAddr, XDCFG_DMA_SRC_LEN_OFFSET, 0x0);
	/* Clear the destination length register */
	XDcfg_WriteReg(BaseAddr, XDCFG_DMA_DEST_LEN_OFFSET, 0x0);
	/* Clear the loopback enable bit */
	Regval = XDcfg_ReadReg(BaseAddr, XDCFG_MCTRL_OFFSET);
	Regval = Regval & ~XDCFG_MCTRL_PCAP_LPBK_MASK;
	XDcfg_WriteReg(BaseAddr, XDCFG_MCTRL_OFFSET, Regval);
	/*Reset the configuration register to reset value */
	XDcfg_WriteReg(BaseAddr, XDCFG_CFG_OFFSET,
				XDCFG_CONFIG_RESET_VALUE);
	/*Disable the PCAP rate enable bit */
	Regval = XDcfg_ReadReg(BaseAddr, XDCFG_CTRL_OFFSET);
	Regval = Regval & ~XDCFG_CTRL_PCAP_RATE_EN_MASK;
	XDcfg_WriteReg(BaseAddr, XDCFG_CTRL_OFFSET, Regval);

}
Example #2
0
/**
* The interrupt handler for the Device Config Interface.
*
* Events are signaled to upper layer for proper handling.
*
*
* @param	InstancePtr is a pointer to the XDcfg instance.
*
* @return	None.
*
* @note 	None.
*
****************************************************************************/
void XDcfg_InterruptHandler(XDcfg *InstancePtr)
{
	u32 IntrStatusReg;

	/*
	 * Assert validates the input arguments.
	 */
	Xil_AssertVoid(InstancePtr != NULL);
	Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);

	/*
	 * Read the Interrupt status register.
	 */
	IntrStatusReg = XDcfg_ReadReg(InstancePtr->Config.BaseAddr,
					 XDCFG_INT_STS_OFFSET);

	/*
	 * Write the status back to clear the interrupts so that no
	 * subsequent interrupts are missed while processing this interrupt.
	 * This also does the DMA acknowledgment automatically.
	 */
	XDcfg_WriteReg(InstancePtr->Config.BaseAddr,
				XDCFG_INT_STS_OFFSET, IntrStatusReg);

	/*
	 * Signal application that there are events to handle.
	 */
	InstancePtr->StatusHandler(InstancePtr->CallBackRef,
					   IntrStatusReg);

}
Example #3
0
/**
*
* The function reads the contents of the Configuration Register with the
* given value.
*
* @param	InstancePtr is a pointer to the XDcfg instance.
*
* @return	A 32-bit value representing the contents of the Config
*		Register.
*		Use the XDCFG_CFG_*_MASK constants defined in xdevcfg_hw.h to
*		interpret the returned value.
*
* @note		None.
*
*****************************************************************************/
u32 XDcfg_GetConfigRegister(XDcfg *InstancePtr)
{
	/*
	 * Assert the arguments.
	 */
	Xil_AssertNonvoid(InstancePtr != NULL);
	Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);

	return XDcfg_ReadReg(InstancePtr->Config.BaseAddr, XDCFG_CFG_OFFSET);

}
Example #4
0
/**
*
* The function reads the contents of the Miscellaneous Control Register.
*
* @param	InstancePtr is a pointer to the XDcfg instance.
*
* @return	32 Bit boot software ID.
*
* @note		This register is locked for write once the system enters
*		usermode. Hence API to reading the register only is provided.
*
*****************************************************************************/
u32 XDcfg_GetMiscControlRegister(XDcfg *InstancePtr)
{
	/*
	 * Assert the arguments.
	 */
	Xil_AssertNonvoid(InstancePtr != NULL);
	Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);

	/*
	 * Read the Miscellaneous Control Register and return the value.
	 */
	return XDcfg_ReadReg(InstancePtr->Config.BaseAddr, XDCFG_MCTRL_OFFSET);
}
Example #5
0
/**
*
* The function reads the contents of the Software ID Register.
*
* @param	InstancePtr is a pointer to the XDcfg instance.
*
* @return	32 Bit boot software ID.
*
* @note		This register is locked for write once the system enters
*		usermode. Hence API for reading the register only is provided.
*
*****************************************************************************/
u32 XDcfg_GetSoftwareIdRegister(XDcfg *InstancePtr)
{
	/*
	 * Assert the arguments.
	 */
	Xil_AssertNonvoid(InstancePtr != NULL);
	Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);

	/*
	 * Read the Software ID Register and return the value.
	 */
	return XDcfg_ReadReg(InstancePtr->Config.BaseAddr, XDCFG_SW_ID_OFFSET);
}
Example #6
0
/**
*
* This function returns the interrupt status read from Interrupt Status
* Register. Use the XDCFG_INT_* constants defined in xdevcfg_hw.h
* to interpret the returned value.
*
* @param	InstancePtr is a pointer to the XDcfg instance.
*
* @return	A 32-bit value representing the contents of the Interrupt
*		Status register.
*
* @note		None.
*
*****************************************************************************/
u32 XDcfg_IntrGetStatus(XDcfg *InstancePtr)
{
	/*
	 * Assert the arguments.
	 */
	Xil_AssertNonvoid(InstancePtr != NULL);
	Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);

	/*
	 * Return the value read from the Interrupt Status register.
	 */
	return XDcfg_ReadReg(InstancePtr->Config.BaseAddr,
				XDCFG_INT_STS_OFFSET);
}
Example #7
0
/**
*
* The function sets the bit mask for the feature in Miscellaneous Control
* Register.
*
* @param	InstancePtr is a pointer to the XDcfg instance.
* @param	Mask is the bit-mask of the feature to be set.
*
* @return	None.
*
* @note		None
*
*****************************************************************************/
void XDcfg_SetMiscControlRegister(XDcfg *InstancePtr, u32 Mask)
{
	u32 RegData;

	/*
	 * Assert the arguments.
	 */
	Xil_AssertVoid(InstancePtr != NULL);
	Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);


	RegData = XDcfg_ReadReg(InstancePtr->Config.BaseAddr,
					XDCFG_MCTRL_OFFSET);

	XDcfg_WriteReg(InstancePtr->Config.BaseAddr, XDCFG_MCTRL_OFFSET,
				(RegData | Mask));
}
Example #8
0
/**
*
* The functions disables the PCAP interface by clearing the PCAP mode bit in
* the control register.
*
* @param	InstancePtr is a pointer to the XDcfg instance.
*
* @return	None.
*
* @note		None.
*
*****************************************************************************/
void XDcfg_DisablePCAP(XDcfg *InstancePtr)
{
	u32 CtrlReg;
	/*
	 * Assert the arguments.
	 */
	Xil_AssertVoid(InstancePtr != NULL);
	Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);


	CtrlReg = XDcfg_ReadReg(InstancePtr->Config.BaseAddr,
					XDCFG_CTRL_OFFSET);

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

}
Example #9
0
/**
*
* The function Clears the specified bit positions of the Control Register.
*
* @param	InstancePtr is a pointer to the XDcfg instance.
* @param	Mask is the 32 bit value which holds the bit positions to be cleared.
*
* @return	None.
*
* @note		None.
*
*****************************************************************************/
void XDcfg_ClearControlRegister(XDcfg *InstancePtr, u32 Mask)
{
	u32 CtrlReg;
	/*
	 * Assert the arguments.
	 */
	Xil_AssertVoid(InstancePtr != NULL);
	Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);


	CtrlReg = XDcfg_ReadReg(InstancePtr->Config.BaseAddr,
					XDCFG_CTRL_OFFSET);

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

}
Example #10
0
static XDcfg *XDcfg_Initialize(u16 DeviceId)
{
	u32 CtrlReg;
	u32 Status;
	XDcfg *Instance = malloc(sizeof *Instance);
	XDcfg_Config *Config = XDcfg_LookupConfig(DeviceId);
	Status = XDcfg_CfgInitialize(Instance, Config, Config->BaseAddr);
	if(Status != XST_SUCCESS){
		print("Device configuration initialisation failed\n\r");
		exit(0);
	}
	// Disable PCAP interface for partial reconfiguration
	XDcfg_DisablePCAP(Instance);
	CtrlReg = XDcfg_ReadReg(Instance->Config.BaseAddr,XDCFG_CTRL_OFFSET);
	XDcfg_WriteReg(Instance->Config.BaseAddr, XDCFG_CTRL_OFFSET,(CtrlReg & XDCFG_CTRL_ICAP_PR_MASK));
	return Instance;
}
Example #11
0
/**
*
* This function checks if DMA command queue is full.
*
* @param	InstancePtr is a pointer to the XDcfg instance.
*
* @return	XST_SUCCESS is the DMA is busy
*		XST_FAILURE if the DMA is idle
*
* @note		The DMA queue has a depth of two.
*
****************************************************************************/
u32 XDcfg_IsDmaBusy(XDcfg *InstancePtr)
{

	u32 RegData;

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

	/* Read the PCAP status register for DMA status */
	RegData = XDcfg_ReadReg(InstancePtr->Config.BaseAddr,
					XDCFG_STATUS_OFFSET);

	if ((RegData & XDCFG_STATUS_DMA_CMD_Q_F_MASK) ==
				XDCFG_STATUS_DMA_CMD_Q_F_MASK){
		return XST_SUCCESS;
	}

	return XST_FAILURE;
}
Example #12
0
/**
*
* This function enables the specified interrupts in the device.
*
* @param	InstancePtr is a pointer to the XDcfg instance.
* @param	Mask is the bit-mask of the interrupts to be enabled.
*		Bit positions of 1 will be enabled. Bit positions of 0 will
*		keep the previous setting. This mask is formed by OR'ing
*		XDCFG_INT_* bits defined in xdevcfg_hw.h.
*
* @return	None.
*
* @note		None.
*
*****************************************************************************/
void XDcfg_IntrEnable(XDcfg *InstancePtr, u32 Mask)
{
	u32 RegValue;

	/*
	 * Assert the arguments.
	 */
	Xil_AssertVoid(InstancePtr != NULL);
	Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);

	/*
	 * Enable the specified interrupts in the Interrupt Mask Register.
	 */
	RegValue = XDcfg_ReadReg(InstancePtr->Config.BaseAddr,
				    XDCFG_INT_MASK_OFFSET);
	RegValue &= ~(Mask & XDCFG_IXR_ALL_MASK);
	XDcfg_WriteReg(InstancePtr->Config.BaseAddr,
				XDCFG_INT_MASK_OFFSET,
			  	RegValue);
}
Example #13
0
/**
*
* This function Implements the DMA Read Command. This command is used to
* transfer the image data from FPGA to the external memory.
*
* @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.
*
* @return	- XST_INVALID_PARAM if source address/length is invalid.
*		- XST_SUCCESS if DMA transfer initiated properly.
*
* @note		None.
*
****************************************************************************/
static u32 XDcfg_PcapReadback(XDcfg *InstancePtr, u32 SourcePtr,
				u32 SrcWordLength, u32 DestPtr,
				u32 DestWordLength)
{
	u32 IntrReg;

	/*
	 * Send READ Frame command to FPGA
	 */
	XDcfg_InitiateDma(InstancePtr, SourcePtr, XDCFG_DMA_INVALID_ADDRESS,
				SrcWordLength, 0);

	/*
	 * Store the enabled interrupts to enable before the actual read
	 * transfer is initiated and Disable all the interrupts temporarily.
	 */
	IntrReg = XDcfg_IntrGetEnabled(InstancePtr);
	XDcfg_IntrDisable(InstancePtr, XDCFG_IXR_ALL_MASK);

	/*
	 * Wait till you get the DMA done for the read command sent
	 */
	 while ((XDcfg_ReadReg(InstancePtr->Config.BaseAddr,
			XDCFG_INT_STS_OFFSET) &
			XDCFG_IXR_D_P_DONE_MASK) ==
			XDCFG_IXR_D_P_DONE_MASK);
	/*
	 * Enable the previously stored Interrupts .
	 */
	XDcfg_IntrEnable(InstancePtr, IntrReg);

	/*
	 * Initiate the DMA write command.
	 */
	XDcfg_InitiateDma(InstancePtr, XDCFG_DMA_INVALID_ADDRESS, (u32)DestPtr,
				0, DestWordLength);

	return XST_SUCCESS;
}
Example #14
0
/**
*
* This function programs the Fabric for use.
*
* @param	None
*
* @return	None
*		- XST_SUCCESS if the Fabric  initialization is successful
*		- XST_FAILURE if the Fabric  initialization fails
* @note		None
*
****************************************************************************/
void FabricInit(void)
{
	u32 PcapReg; 
	u32 PcapCtrlRegVal;
	u32 StatusReg;

	/*
	 * 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%x \r\n",
				Xil_In32(PS_LVL_SHFTR_EN));

	/*
	 * Get DEVCFG controller settings
	 */
	PcapReg = XDcfg_ReadReg(DcfgInstPtr->Config.BaseAddr,
				XDCFG_CTRL_OFFSET);

	/*
	 * 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
	 */
	while(XDcfg_GetStatusRegister(DcfgInstPtr) &
				XDCFG_STATUS_PCFG_INIT_MASK);

	/*
	 * 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%x \r\n",StatusReg);

	fsbl_printf(DEBUG_INFO,"PCAP:Fabric is Initialized done\r\n");
}
Example #15
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;
}
Example #16
0
/**
*
* This function
*
* @param
*
* @return
*
*
* @note		None
*
****************************************************************************/
u32 LoadBootImage(void)
{
	u32 RebootStatusRegister = 0;
	u32 MultiBootReg = 0;
	u32 ImageStartAddress = 0;
	u32 PartitionNum;
	u32 PartitionDataLength;
	u32 PartitionImageLength;
	u32 PartitionTotalSize;
	u32 PartitionExecAddr;
	u32 PartitionAttr;
	u32 ExecAddress = 0;
	u32 PartitionLoadAddr;
	u32 PartitionStartAddr;
	u32 PartitionChecksumOffset;
	u8 ExecAddrFlag = 0 ;
	u32 Status;
	PartHeader *HeaderPtr;
	u32 EfuseStatusRegValue;
#ifdef RSA_SUPPORT
	u32 HeaderSize;
#endif
	/*
	 * Resetting the Flags
	 */
	BitstreamFlag = 0;
	ApplicationFlag = 0;

	RebootStatusRegister = Xil_In32(REBOOT_STATUS_REG);
	fsbl_printf(DEBUG_INFO,
			"Reboot status register: 0x%08x\r\n",RebootStatusRegister);

	if (Silicon_Version == SILICON_VERSION_1) {
		/*
		 * Clear out fallback mask from previous run
		 * We start from the first partition again
		 */
		if ((RebootStatusRegister & FSBL_FAIL_MASK) ==
				FSBL_FAIL_MASK) {
			fsbl_printf(DEBUG_INFO,
					"Reboot status shows previous run falls back\r\n");
			RebootStatusRegister &= ~(FSBL_FAIL_MASK);
			Xil_Out32(REBOOT_STATUS_REG, RebootStatusRegister);
		}

		/*
		 * Read the image start address
		 */
		ImageStartAddress = *(u32 *)BASEADDR_HOLDER;
	} else {
		/*
		 * read the multiboot register
		 */
		MultiBootReg =  XDcfg_ReadReg(DcfgInstPtr->Config.BaseAddr,
				XDCFG_MULTIBOOT_ADDR_OFFSET);

		fsbl_printf(DEBUG_INFO,"Multiboot Register: 0x%08x\r\n",MultiBootReg);

		/*
		 * Compute the image start address
		 */
		ImageStartAddress = (MultiBootReg & PCAP_MBOOT_REG_REBOOT_OFFSET_MASK)
									* GOLDEN_IMAGE_OFFSET;
	}

	fsbl_printf(DEBUG_INFO,"Image Start Address: 0x%08x\r\n",ImageStartAddress);

	/*
	 * Get partitions header information
	 */
	Status = GetPartitionHeaderInfo(ImageStartAddress);
	if (Status != XST_SUCCESS) {
		fsbl_printf(DEBUG_GENERAL, "Partition Header Load Failed\r\n");
		OutputStatus(GET_HEADER_INFO_FAIL);
		FsblFallback();
	}

	/*
	 * RSA is not implemented in 1.0 and 2.0
	 * silicon
	 */
	if ((Silicon_Version != SILICON_VERSION_1) &&
			(Silicon_Version != SILICON_VERSION_2)) {
		/*
		 * Read Efuse Status Register
		 */
		EfuseStatusRegValue = Xil_In32(EFUSE_STATUS_REG);
		if (EfuseStatusRegValue & EFUSE_STATUS_RSA_ENABLE_MASK) {
			fsbl_printf(DEBUG_GENERAL,"RSA enabled for Chip\r\n");
#ifdef RSA_SUPPORT
			/*
			 * Set the Ppk
			 */
			SetPpk();

			/*
			 * Read partition header with signature
			 */
			Status = GetImageHeaderAndSignature(ImageStartAddress,
					(u32 *)DDR_TEMP_START_ADDR);
			if (Status != XST_SUCCESS) {
				fsbl_printf(DEBUG_GENERAL,
						"Read Partition Header signature Failed\r\n");
				OutputStatus(GET_HEADER_INFO_FAIL);
				FsblFallback();
			}
			HeaderSize=TOTAL_HEADER_SIZE+RSA_SIGNATURE_SIZE;

			Status = AuthenticatePartition((u8 *)DDR_TEMP_START_ADDR, HeaderSize);
			if (Status != XST_SUCCESS) {
				fsbl_printf(DEBUG_GENERAL,
						"Partition Header signature Failed\r\n");
				OutputStatus(GET_HEADER_INFO_FAIL);
				FsblFallback();
			}
#else
			/*
			 * In case user not enabled RSA authentication feature
			 */
			fsbl_printf(DEBUG_GENERAL,"RSA_SUPPORT_NOT_ENABLED_FAIL\r\n");
			OutputStatus(RSA_SUPPORT_NOT_ENABLED_FAIL);
			FsblFallback();
#endif
		}
	}

#ifdef MMC_SUPPORT
	/*
	 * In case of MMC support
	 * boot image preset in MMC will not have FSBL partition
	 */
	PartitionNum = 0;
#else
	/*
	 * First partition header was ignored by FSBL
	 * As it contain FSBL partition information
	 */
	PartitionNum = 1;
#endif

	while (PartitionNum < PartitionCount) {

		fsbl_printf(DEBUG_INFO, "Partition Number: %d\r\n", PartitionNum);

		HeaderPtr = &PartitionHeader[PartitionNum];

		/*
		 * Print partition header information
		 */
		HeaderDump(HeaderPtr);

		/*
		 * Validate partition header
		 */
		Status = ValidateHeader(HeaderPtr);
		if (Status != XST_SUCCESS) {
			fsbl_printf(DEBUG_GENERAL, "INVALID_HEADER_FAIL\r\n");
			OutputStatus(INVALID_HEADER_FAIL);
			FsblFallback();
		}

		/*
		 * Load partition header information in to local variables
		 */
		PartitionDataLength = HeaderPtr->DataWordLen;
		PartitionImageLength = HeaderPtr->ImageWordLen;
		PartitionExecAddr = HeaderPtr->ExecAddr;
		PartitionAttr = HeaderPtr->PartitionAttr;
		PartitionLoadAddr = HeaderPtr->LoadAddr;
		PartitionChecksumOffset = HeaderPtr->CheckSumOffset;
		PartitionStartAddr = HeaderPtr->PartitionStart;
		PartitionTotalSize = HeaderPtr->PartitionWordLen;

		/*
		 * Partition owner should be FSBL to validate the partition
		 */
		if ((PartitionAttr & ATTRIBUTE_PARTITION_OWNER_MASK) !=
				ATTRIBUTE_PARTITION_OWNER_FSBL) {
			/*
			 * if FSBL is not the owner of partition,
			 * skip this partition, continue with next partition
			 */
			 fsbl_printf(DEBUG_INFO, "Skipping partition %0x\r\n", 
			 							PartitionNum);
			/*
			 * Increment partition number
			 */
			PartitionNum++;
			continue;
		}

		if (PartitionAttr & ATTRIBUTE_PL_IMAGE_MASK) {
			fsbl_printf(DEBUG_INFO, "Bitstream\r\n");
			PLPartitionFlag = 1;
			PSPartitionFlag = 0;
			BitstreamFlag = 1;
			if (ApplicationFlag == 1) {
#ifdef STDOUT_BASEADDRESS
				xil_printf("\r\nFSBL Warning !!!"
						"Bitstream not loaded into PL\r\n");
                xil_printf("Partition order invalid\r\n");
#endif
				break;
			}
		}

		if (PartitionAttr & ATTRIBUTE_PS_IMAGE_MASK) {
			fsbl_printf(DEBUG_INFO, "Application\r\n");
			PSPartitionFlag = 1;
			PLPartitionFlag = 0;
			ApplicationFlag = 1;
		}

		/*
		 * Encrypted partition will have different value
		 * for Image length and data length
		 */
		if (PartitionDataLength != PartitionImageLength) {
			fsbl_printf(DEBUG_INFO, "Encrypted\r\n");
			EncryptedPartitionFlag = 1;
		} else {
			EncryptedPartitionFlag = 0;
		}

		/*
		 * Check for partition checksum check
		 */
		if (PartitionAttr & ATTRIBUTE_CHECKSUM_TYPE_MASK) {
			PartitionChecksumFlag = 1;
		} else {
			PartitionChecksumFlag = 0;
		}

		/*
		 * RSA signature check
		 */
		if (PartitionAttr & ATTRIBUTE_RSA_PRESENT_MASK) {
			fsbl_printf(DEBUG_INFO, "RSA Signed\r\n");
			SignedPartitionFlag = 1;
		} else {
			SignedPartitionFlag = 0;
		}

		/*
		 * Load address check
		 * Loop will break when PS load address zero and partition is
		 * un-signed or un-encrypted
		 */
		if ((PSPartitionFlag == 1) && (PartitionLoadAddr < DDR_START_ADDR)) {
			if ((PartitionLoadAddr == 0) &&
					(!((SignedPartitionFlag == 1) ||
							(EncryptedPartitionFlag == 1)))) {
				break;
			} else {
				fsbl_printf(DEBUG_GENERAL,
						"INVALID_LOAD_ADDRESS_FAIL\r\n");
				OutputStatus(INVALID_LOAD_ADDRESS_FAIL);
				FsblFallback();
			}
		}

		if (PSPartitionFlag && (PartitionLoadAddr > DDR_END_ADDR)) {
			fsbl_printf(DEBUG_GENERAL,
					"INVALID_LOAD_ADDRESS_FAIL\r\n");
			OutputStatus(INVALID_LOAD_ADDRESS_FAIL);
			FsblFallback();
		}

        /*
         * Load execution address of first PS partition
         */
        if (PSPartitionFlag && (!ExecAddrFlag)) {
        	ExecAddrFlag++;
        	ExecAddress = PartitionExecAddr;
        }

		/*
		 * FSBL user hook call before bitstream download
		 */
		if (PLPartitionFlag) {
			Status = FsblHookBeforeBitstreamDload();
			if (Status != XST_SUCCESS) {
				fsbl_printf(DEBUG_GENERAL,"FSBL_BEFORE_BSTREAM_HOOK_FAIL\r\n");
				OutputStatus(FSBL_BEFORE_BSTREAM_HOOK_FAIL);
				FsblFallback();
			}
		}

		/*
		 * Move partitions from boot device
		 */
		Status = PartitionMove(ImageStartAddress, HeaderPtr);
		if (Status != XST_SUCCESS) {
			fsbl_printf(DEBUG_GENERAL,"PARTITION_MOVE_FAIL\r\n");
			OutputStatus(PARTITION_MOVE_FAIL);
			FsblFallback();
		}

		if ((SignedPartitionFlag) || (PartitionChecksumFlag)) {
			if(PLPartitionFlag) {
				/*
				 * PL partition loaded in to DDR temporary address
				 * for authentication and checksum verification
				 */
				PartitionStartAddr = DDR_TEMP_START_ADDR;
			} else {
				PartitionStartAddr = PartitionLoadAddr;
			}

			if (PartitionChecksumFlag) {
				/*
				 * Validate the partition data with checksum
				 */
				Status = ValidateParition(PartitionStartAddr,
						(PartitionTotalSize << WORD_LENGTH_SHIFT),
						ImageStartAddress  +
						(PartitionChecksumOffset << WORD_LENGTH_SHIFT));
				if (Status != XST_SUCCESS) {
					fsbl_printf(DEBUG_GENERAL,"PARTITION_CHECKSUM_FAIL\r\n");
					OutputStatus(PARTITION_CHECKSUM_FAIL);
					FsblFallback();
				}

				fsbl_printf(DEBUG_INFO, "Partition Validation Done\r\n");
			}

			/*
			 * Authentication Partition
			 */
			if (SignedPartitionFlag == 1 ) {
#ifdef RSA_SUPPORT
				Xil_DCacheEnable();
				Status = AuthenticatePartition((u8*)PartitionStartAddr,
						(PartitionTotalSize << WORD_LENGTH_SHIFT));
				if (Status != XST_SUCCESS) {
					Xil_DCacheFlush();
		        	Xil_DCacheDisable();
					fsbl_printf(DEBUG_GENERAL,"AUTHENTICATION_FAIL\r\n");
					OutputStatus(AUTHENTICATION_FAIL);
					FsblFallback();
				}
				fsbl_printf(DEBUG_INFO,"Authentication Done\r\n");
				Xil_DCacheFlush();
                Xil_DCacheDisable();
#else
				/*
				 * In case user not enabled RSA authentication feature
				 */
				fsbl_printf(DEBUG_GENERAL,"RSA_SUPPORT_NOT_ENABLED_FAIL\r\n");
				OutputStatus(RSA_SUPPORT_NOT_ENABLED_FAIL);
				FsblFallback();
#endif
			}

			/*
			 * Decrypt PS partition
			 */
			if (EncryptedPartitionFlag && PSPartitionFlag) {
				Status = DecryptPartition(PartitionStartAddr,
						PartitionDataLength,
						PartitionImageLength);
				if (Status != XST_SUCCESS) {
					fsbl_printf(DEBUG_GENERAL,"DECRYPTION_FAIL\r\n");
					OutputStatus(DECRYPTION_FAIL);
					FsblFallback();
				}
			}

			/*
			 * Load Signed PL partition in Fabric
			 */
			if (PLPartitionFlag) {
				Status = PcapLoadPartition((u32*)PartitionStartAddr,
						(u32*)PartitionLoadAddr,
						PartitionImageLength,
						PartitionDataLength,
						EncryptedPartitionFlag);
				if (Status != XST_SUCCESS) {
					fsbl_printf(DEBUG_GENERAL,"BITSTREAM_DOWNLOAD_FAIL\r\n");
					OutputStatus(BITSTREAM_DOWNLOAD_FAIL);
					FsblFallback();
				}
			}
		}


		/*
		 * FSBL user hook call after bitstream download
		 */
		if (PLPartitionFlag) {
			Status = FsblHookAfterBitstreamDload();
			if (Status != XST_SUCCESS) {
				fsbl_printf(DEBUG_GENERAL,"FSBL_AFTER_BSTREAM_HOOK_FAIL\r\n");
				OutputStatus(FSBL_AFTER_BSTREAM_HOOK_FAIL);
				FsblFallback();
			}
		}
		/*
		 * Increment partition number
		 */
		PartitionNum++;
	}

	return ExecAddress;
}