lib/sw_apps/zynqmp_fsbl/src/xfsbl_image_header.c
u32 XFsbl_ReadImageHeader(XFsblPs_ImageHeader * ImageHeader,
				const XFsblPs_DeviceOps * DeviceOps,
				u32 FlashImageOffsetAddress,
				u32 RunningCpu, u32 ImageHeaderTableAddressOffset)
{
	u32 Status;
	u32 PartitionHeaderAddress;
	u32 PartitionIndex;
	const XFsblPs_PartitionHeader *CurrPartitionHdr;
	u32 EntryCount = 0;
	u32 DestnCPU;
	u32 GetDstnCpu;

	/**
	 * Read the Image header table of 64 bytes
	 * and update the image header table structure
	 */
	if (DeviceOps != NULL) {
		Status = DeviceOps->DeviceCopy(FlashImageOffsetAddress +
			ImageHeaderTableAddressOffset,
			(PTRSIZE ) &(ImageHeader->ImageHeaderTable),
			XIH_IHT_LEN);
		if (XFSBL_SUCCESS != Status)
		{
			XFsbl_Printf(DEBUG_GENERAL,"Device Copy Failed \n\r");
			goto END;
		}
	}
	else {
#ifdef XFSBL_SECURE
		XFsbl_MemCpy((u8 *)&(ImageHeader->ImageHeaderTable),
				ImageHdr,   XIH_IHT_LEN);
#endif
	}

	/**
	 * Check the validity of Image Header Table
	 */
	Status = XFsbl_ValidateImageHeaderTable(
	          &(ImageHeader->ImageHeaderTable));
	if (Status == XFSBL_STATUS_SECONDARY_BOOT_MODE) {
		Status = XFSBL_SUCCESS;
		goto END;
	}
	if (XFSBL_SUCCESS != Status)
	{
		XFsbl_Printf(DEBUG_GENERAL,"Image Header Table "
				"Validation failed \n\r");
		goto END;
	}

	/**
	 * Update the first partition address
	 */
	PartitionHeaderAddress =
		(ImageHeader->ImageHeaderTable.PartitionHeaderAddress)
			* XIH_PARTITION_WORD_LENGTH;


	/**
	 * Read the partitions based on the partition offset
	 * and update the partition header structure
	 */
	for (PartitionIndex=0U;
		PartitionIndex<ImageHeader->ImageHeaderTable.NoOfPartitions;
		PartitionIndex++)
	{

		/**
		 * Read the Image header table of 64 bytes
		 * and update the image header table structure
		 */
		if (DeviceOps != NULL) {
			Status = DeviceOps->DeviceCopy(
				FlashImageOffsetAddress +
				PartitionHeaderAddress,
			(PTRSIZE)&(ImageHeader->PartitionHeader[PartitionIndex]),
					XIH_PH_LEN);
			if (XFSBL_SUCCESS != Status)
			{
				XFsbl_Printf(DEBUG_GENERAL,
				"Device Copy Failed \n\r");
				goto END;
			}
		}
		else {
			PartitionHeaderAddress =
			PartitionHeaderAddress - ImageHeaderTableAddressOffset;
#ifdef XFSBL_SECURE
			XFsbl_MemCpy(
			&(ImageHeader->PartitionHeader[PartitionIndex]),
			(u8 *)(UINTPTR)(ImageHdr + PartitionHeaderAddress),
						XIH_PH_LEN);
#endif
		}
		/**
		 * Assumption: Next partition corresponds to ATF
		 * The first partition of an application will have a non zero
		 * execution address. All the remaining partitions of that
		 * application will have 0 as execution address. Hence look for
		 * the non zero execution address for partition which is not
		 * the first one and ensure the CPU is A53
		 */

		CurrPartitionHdr = &ImageHeader->PartitionHeader[PartitionIndex];

		GetDstnCpu = XFsbl_GetDestinationCpu(CurrPartitionHdr);

		/* if destination cpu is not present, it means it is for same cpu */
		if (GetDstnCpu == XIH_PH_ATTRB_DEST_CPU_NONE)
		{
			DestnCPU = RunningCpu;
		}
		else
		{
			DestnCPU = GetDstnCpu;
		}

		if ((PartitionIndex > 1U) && (EntryCount < XFSBL_MAX_ENTRIES_FOR_ATF) &&
				(CurrPartitionHdr->DestinationExecutionAddress != 0U) &&
				(((DestnCPU >= XIH_PH_ATTRB_DEST_CPU_A53_0) &&
						(DestnCPU <= XIH_PH_ATTRB_DEST_CPU_A53_3))))
		{
			/**
			 *  Populate handoff parameters to ATF
			 *  These correspond to the partition of application
			 *  which ATF will be loading
			 */
			XFsbl_SetATFHandoffParameters(CurrPartitionHdr, EntryCount);
			EntryCount++;
		}

		/**
		 * Update the next partition present address
		 */
		PartitionHeaderAddress =
		 (ImageHeader->PartitionHeader[PartitionIndex].NextPartitionOffset)
			  * XIH_PARTITION_WORD_LENGTH;
	}

	/**
	 * After setting handoff parameters of all partitions to ATF,
	 * store address of the structure in PMU_GLOBAL.GLOBAL_GEN_STORAGE6.
	 */
	XFsbl_Out32(PMU_GLOBAL_GLOB_GEN_STORAGE6, (u32)((PTRSIZE) &ATFHandoffParams));

END:
	return Status;
}
/****************************************************************************/
/**
 * This function reads the image header from flash device. Image header
 * reads the image header table and partition headers
 *
 * @param ImageHeader pointer to the image header at which image header to
 * be stored
 *
 * @param DeviceOps pointer deviceops structure which contains the
 * function pointer to flash read function
 * 		 If it is NULL then image header will be copied from OCM buffer,
 * 		 which has image header copied from flash device.
 *
 * @param FlashImageOffsetAddress base offset to the image in the flash
 *
 * @return
 * 	- XFSBL_SUCCESS on successful reading image header
 * 	- errors as mentioned in xfsbl_error.h
 *
 * @note
 *****************************************************************************/
This function reads the image header from flash device. Image header
reads the image header table and partition headers

@param ImageHeader pointer to the image header at which image header to
be stored

@param DeviceOps pointer deviceops structure which contains the
function pointer to flash read function
If it is NULL then image header will be copied from OCM buffer,
which has image header copied from flash device.

@param FlashImageOffsetAddress base offset to the image in the flash

@return
- XFSBL_SUCCESS on successful reading image header
- errors as mentioned in xfsbl_error.h

@note
This function reads the image header from flash device . Image header reads the image header table and partition headers @param ImageHeader pointer to the image header at which image header to be stored @param DeviceOps pointer deviceops structure which contains the function pointer to flash read function If it is NULL then image header will be copied from OCM buffer which has image header copied from flash device . @param FlashImageOffsetAddress base offset to the image in the flash @return - XFSBL_SUCCESS on successful reading image header - errors as mentioned in xfsbl_error . h @note
u32 XFsbl_ReadImageHeader(XFsblPs_ImageHeader * ImageHeader,
				const XFsblPs_DeviceOps * DeviceOps,
				u32 FlashImageOffsetAddress,
				u32 RunningCpu, u32 ImageHeaderTableAddressOffset)
{
	u32 Status;
	u32 PartitionHeaderAddress;
	u32 PartitionIndex;
	const XFsblPs_PartitionHeader *CurrPartitionHdr;
	u32 EntryCount = 0;
	u32 DestnCPU;
	u32 GetDstnCpu;
	if (DeviceOps != NULL) {
		Status = DeviceOps->DeviceCopy(FlashImageOffsetAddress +
			ImageHeaderTableAddressOffset,
			(PTRSIZE ) &(ImageHeader->ImageHeaderTable),
			XIH_IHT_LEN);
		if (XFSBL_SUCCESS != Status)
		{
			XFsbl_Printf(DEBUG_GENERAL,"Device Copy Failed \n\r");
			goto END;
		}
	}
	else {
#ifdef XFSBL_SECURE
		XFsbl_MemCpy((u8 *)&(ImageHeader->ImageHeaderTable),
				ImageHdr,   XIH_IHT_LEN);
#endif
	}
	Status = XFsbl_ValidateImageHeaderTable(
	          &(ImageHeader->ImageHeaderTable));
	if (Status == XFSBL_STATUS_SECONDARY_BOOT_MODE) {
		Status = XFSBL_SUCCESS;
		goto END;
	}
	if (XFSBL_SUCCESS != Status)
	{
		XFsbl_Printf(DEBUG_GENERAL,"Image Header Table "
				"Validation failed \n\r");
		goto END;
	}
	PartitionHeaderAddress =
		(ImageHeader->ImageHeaderTable.PartitionHeaderAddress)
			* XIH_PARTITION_WORD_LENGTH;
	for (PartitionIndex=0U;
		PartitionIndex<ImageHeader->ImageHeaderTable.NoOfPartitions;
		PartitionIndex++)
	{
		if (DeviceOps != NULL) {
			Status = DeviceOps->DeviceCopy(
				FlashImageOffsetAddress +
				PartitionHeaderAddress,
			(PTRSIZE)&(ImageHeader->PartitionHeader[PartitionIndex]),
					XIH_PH_LEN);
			if (XFSBL_SUCCESS != Status)
			{
				XFsbl_Printf(DEBUG_GENERAL,
				"Device Copy Failed \n\r");
				goto END;
			}
		}
		else {
			PartitionHeaderAddress =
			PartitionHeaderAddress - ImageHeaderTableAddressOffset;
#ifdef XFSBL_SECURE
			XFsbl_MemCpy(
			&(ImageHeader->PartitionHeader[PartitionIndex]),
			(u8 *)(UINTPTR)(ImageHdr + PartitionHeaderAddress),
						XIH_PH_LEN);
#endif
		}
		CurrPartitionHdr = &ImageHeader->PartitionHeader[PartitionIndex];
		GetDstnCpu = XFsbl_GetDestinationCpu(CurrPartitionHdr);
		if (GetDstnCpu == XIH_PH_ATTRB_DEST_CPU_NONE)
		{
			DestnCPU = RunningCpu;
		}
		else
		{
			DestnCPU = GetDstnCpu;
		}
		if ((PartitionIndex > 1U) && (EntryCount < XFSBL_MAX_ENTRIES_FOR_ATF) &&
				(CurrPartitionHdr->DestinationExecutionAddress != 0U) &&
				(((DestnCPU >= XIH_PH_ATTRB_DEST_CPU_A53_0) &&
						(DestnCPU <= XIH_PH_ATTRB_DEST_CPU_A53_3))))
		{
			XFsbl_SetATFHandoffParameters(CurrPartitionHdr, EntryCount);
			EntryCount++;
		}
		PartitionHeaderAddress =
		 (ImageHeader->PartitionHeader[PartitionIndex].NextPartitionOffset)
			  * XIH_PARTITION_WORD_LENGTH;
	}
	XFsbl_Out32(PMU_GLOBAL_GLOB_GEN_STORAGE6, (u32)((PTRSIZE) &ATFHandoffParams));
END:
	return Status;
}
u32 XFsbl_ReadImageHeader ( XFsblPs_ImageHeader * ImageHeader , const XFsblPs_DeviceOps * DeviceOps , u32 FlashImageOffsetAddress , u32 RunningCpu , u32 ImageHeaderTableAddressOffset ) { u32 Status ; u32 PartitionHeaderAddress ; u32 PartitionIndex ; const XFsblPs_PartitionHeader * CurrPartitionHdr ; u32 EntryCount = 0 ; u32 DestnCPU ; u32 GetDstnCpu ; if ( DeviceOps != NULL ) { Status = DeviceOps -> DeviceCopy ( FlashImageOffsetAddress + ImageHeaderTableAddressOffset , ( PTRSIZE ) & ( ImageHeader -> ImageHeaderTable ) , XIH_IHT_LEN ) ; if ( XFSBL_SUCCESS != Status ) { XFsbl_Printf ( DEBUG_GENERAL , " \n \r " ) ; goto END ; } } else { #ifdef XFSBL_SECURE XFsbl_MemCpy ( ( u8 * ) & ( ImageHeader -> ImageHeaderTable ) , ImageHdr , XIH_IHT_LEN ) ; #endif } Status = XFsbl_ValidateImageHeaderTable ( & ( ImageHeader -> ImageHeaderTable ) ) ; if ( Status == XFSBL_STATUS_SECONDARY_BOOT_MODE ) { Status = XFSBL_SUCCESS ; goto END ; } if ( XFSBL_SUCCESS != Status ) { XFsbl_Printf ( DEBUG_GENERAL , " " " \n \r " ) ; goto END ; } PartitionHeaderAddress = ( ImageHeader -> ImageHeaderTable . PartitionHeaderAddress ) * XIH_PARTITION_WORD_LENGTH ; for ( PartitionIndex = 0U ; PartitionIndex < ImageHeader -> ImageHeaderTable . NoOfPartitions ; PartitionIndex ++ ) { if ( DeviceOps != NULL ) { Status = DeviceOps -> DeviceCopy ( FlashImageOffsetAddress + PartitionHeaderAddress , ( PTRSIZE ) & ( ImageHeader -> PartitionHeader [ PartitionIndex ] ) , XIH_PH_LEN ) ; if ( XFSBL_SUCCESS != Status ) { XFsbl_Printf ( DEBUG_GENERAL , " \n \r " ) ; goto END ; } } else { PartitionHeaderAddress = PartitionHeaderAddress - ImageHeaderTableAddressOffset ; #ifdef XFSBL_SECURE XFsbl_MemCpy ( & ( ImageHeader -> PartitionHeader [ PartitionIndex ] ) , ( u8 * ) ( UINTPTR ) ( ImageHdr + PartitionHeaderAddress ) , XIH_PH_LEN ) ; #endif } CurrPartitionHdr = & ImageHeader -> PartitionHeader [ PartitionIndex ] ; GetDstnCpu = XFsbl_GetDestinationCpu ( CurrPartitionHdr ) ; if ( GetDstnCpu == XIH_PH_ATTRB_DEST_CPU_NONE ) { DestnCPU = RunningCpu ; } else { DestnCPU = GetDstnCpu ; } if ( ( PartitionIndex > 1U ) && ( EntryCount < XFSBL_MAX_ENTRIES_FOR_ATF ) && ( CurrPartitionHdr -> DestinationExecutionAddress != 0U ) && ( ( ( DestnCPU >= XIH_PH_ATTRB_DEST_CPU_A53_0 ) && ( DestnCPU <= XIH_PH_ATTRB_DEST_CPU_A53_3 ) ) ) ) { XFsbl_SetATFHandoffParameters ( CurrPartitionHdr , EntryCount ) ; EntryCount ++ ; } PartitionHeaderAddress = ( ImageHeader -> PartitionHeader [ PartitionIndex ] . NextPartitionOffset ) * XIH_PARTITION_WORD_LENGTH ; } XFsbl_Out32 ( PMU_GLOBAL_GLOB_GEN_STORAGE6 , ( u32 ) ( ( PTRSIZE ) & ATFHandoffParams ) ) ; END : return Status ; }
This function reads the image header from flash device.
This function reads the image header from flash device .
/**
	 * Read the Image header table of 64 bytes
	 * and update the image header table structure
	 */ /**
	 * Check the validity of Image Header Table
	 */ /**
	 * Update the first partition address
	 */ /**
	 * Read the partitions based on the partition offset
	 * and update the partition header structure
	 */ /**
		 * Read the Image header table of 64 bytes
		 * and update the image header table structure
		 */ /**
		 * Assumption: Next partition corresponds to ATF
		 * The first partition of an application will have a non zero
		 * execution address. All the remaining partitions of that
		 * application will have 0 as execution address. Hence look for
		 * the non zero execution address for partition which is not
		 * the first one and ensure the CPU is A53
		 */ /* if destination cpu is not present, it means it is for same cpu */ /**
			 *  Populate handoff parameters to ATF
			 *  These correspond to the partition of application
			 *  which ATF will be loading
			 */ /**
		 * Update the next partition present address
		 */ /**
	 * After setting handoff parameters of all partitions to ATF,
	 * store address of the structure in PMU_GLOBAL.GLOBAL_GEN_STORAGE6.
	 */