/**
 * This function initializes the primary boot device
 *
 * @param	FsblInstancePtr is pointer to the XFsbl Instance
 *
 * @return	returns the error codes described in xfsbl_error.h on any error
 * 			returns XFSBL_SUCCESS on success
 *
 ******************************************************************************/
static u32 XFsbl_PrimaryBootDeviceInit(XFsblPs * FsblInstancePtr)
{
	u32 Status =  XFSBL_SUCCESS;
	u32 BootMode=0U;

	/**
	 * Read Boot Mode register and update the value
	 */
	BootMode = XFsbl_In32(CRL_APB_BOOT_MODE_USER) &
			CRL_APB_BOOT_MODE_USER_BOOT_MODE_MASK;

	FsblInstancePtr->PrimaryBootDevice = BootMode;

	/**
	 * Enable drivers only if they are device boot modes
	 * Not required for JTAG modes
	 */
	if ( (BootMode == XFSBL_QSPI24_BOOT_MODE) ||
			(BootMode == XFSBL_QSPI32_BOOT_MODE) ||
			(BootMode == XFSBL_NAND_BOOT_MODE) ||
			(BootMode == XFSBL_SD0_BOOT_MODE) ||
			(BootMode == XFSBL_EMMC_BOOT_MODE) ||
			(BootMode == XFSBL_SD1_BOOT_MODE) ||
			(BootMode == XFSBL_SD1_LS_BOOT_MODE)) {
		/**
		 * Initialize the WDT and CSU drivers
		 */
#ifdef XFSBL_WDT_PRESENT
		Status = XFsbl_InitWdt();
		if (XFSBL_SUCCESS != Status) {
			XFsbl_Printf(DEBUG_GENERAL,"WDT initialization failed \n\r");
			goto END;
		}
#endif

		/* Initialize CSUDMA driver */
		Status = XFsbl_CsuDmaInit();
		if (XFSBL_SUCCESS != Status) {
			goto END;
		}
	}

	switch(BootMode)
	{
		/**
		 * For JTAG boot mode, it will be in while loop
		 */
		case XFSBL_JTAG_BOOT_MODE:
		{
			XFsbl_Printf(DEBUG_GENERAL,"In JTAG Boot Mode \n\r");
			Status = XFSBL_STATUS_JTAG;
		}
		break;

		case XFSBL_QSPI24_BOOT_MODE:
		{
			XFsbl_Printf(DEBUG_GENERAL,"QSPI 24bit Boot Mode \n\r");
#ifdef XFSBL_QSPI
			/**
			 * Update the deviceops structure with necessary values
			 */
			FsblInstancePtr->DeviceOps.DeviceInit = XFsbl_Qspi24Init;
			FsblInstancePtr->DeviceOps.DeviceCopy = XFsbl_Qspi24Copy;
			FsblInstancePtr->DeviceOps.DeviceRelease = XFsbl_Qspi24Release;
#else
			/**
			 * This bootmode is not supported in this release
			 */
			XFsbl_Printf(DEBUG_GENERAL,
				"XFSBL_ERROR_UNSUPPORTED_BOOT_MODE\n\r");
			Status = XFSBL_ERROR_UNSUPPORTED_BOOT_MODE;
#endif
		}
		break;

		case XFSBL_QSPI32_BOOT_MODE:
		{
			XFsbl_Printf(DEBUG_GENERAL,"QSPI 32 bit Boot Mode \n\r");
#ifdef XFSBL_QSPI
			/**
			 * Update the deviceops structure with necessary values
			 *
			 */
            FsblInstancePtr->DeviceOps.DeviceInit = XFsbl_Qspi32Init;
			FsblInstancePtr->DeviceOps.DeviceCopy = XFsbl_Qspi32Copy;
			FsblInstancePtr->DeviceOps.DeviceRelease = XFsbl_Qspi32Release;
#else
			/**
			 * This bootmode is not supported in this release
			 */
			XFsbl_Printf(DEBUG_GENERAL,
					"XFSBL_ERROR_UNSUPPORTED_BOOT_MODE\n\r");
			Status = XFSBL_ERROR_UNSUPPORTED_BOOT_MODE;
#endif
        }
        break;

		case XFSBL_NAND_BOOT_MODE:
		{
			XFsbl_Printf(DEBUG_GENERAL,"NAND Boot Mode \n\r");
#ifdef XFSBL_NAND
			/**
			 * Update the deviceops structure with necessary values
			 *
			 */
			FsblInstancePtr->DeviceOps.DeviceInit = XFsbl_NandInit;
			FsblInstancePtr->DeviceOps.DeviceCopy = XFsbl_NandCopy;
			FsblInstancePtr->DeviceOps.DeviceRelease =
							XFsbl_NandRelease;
#else
			/**
			 * This bootmode is not supported in this release
			 */
			XFsbl_Printf(DEBUG_GENERAL,
				"XFSBL_ERROR_UNSUPPORTED_BOOT_MODE\n\r");
			Status = XFSBL_ERROR_UNSUPPORTED_BOOT_MODE;
#endif
		} break;

		case XFSBL_SD0_BOOT_MODE:
		case XFSBL_EMMC_BOOT_MODE:
		{
			if (BootMode == XFSBL_SD0_BOOT_MODE) {
				XFsbl_Printf(DEBUG_GENERAL,"SD0 Boot Mode \n\r");
			}
			else {
				XFsbl_Printf(DEBUG_GENERAL,"eMMC Boot Mode \n\r");
			}
#ifdef XFSBL_SD_0
			/**
			 * Update the deviceops structure with necessary values
			 */
			FsblInstancePtr->DeviceOps.DeviceInit = XFsbl_SdInit;
			FsblInstancePtr->DeviceOps.DeviceCopy = XFsbl_SdCopy;
			FsblInstancePtr->DeviceOps.DeviceRelease = XFsbl_SdRelease;
#else
			/**
			 * This bootmode is not supported in this release
			 */
			XFsbl_Printf(DEBUG_GENERAL,
				"XFSBL_ERROR_UNSUPPORTED_BOOT_MODE\n\r");
			Status = XFSBL_ERROR_UNSUPPORTED_BOOT_MODE;
#endif
		} break;

		case XFSBL_SD1_BOOT_MODE:
		case XFSBL_SD1_LS_BOOT_MODE:
		{
			if (BootMode == XFSBL_SD1_BOOT_MODE) {
				XFsbl_Printf(DEBUG_GENERAL, "SD1 Boot Mode \n\r");
			}
			else {
				XFsbl_Printf(DEBUG_GENERAL,
						"SD1 with level shifter Boot Mode \n\r");
			}
#ifdef XFSBL_SD_1
			/**
			 * Update the deviceops structure with necessary values
			 */
			FsblInstancePtr->DeviceOps.DeviceInit = XFsbl_SdInit;
			FsblInstancePtr->DeviceOps.DeviceCopy = XFsbl_SdCopy;
			FsblInstancePtr->DeviceOps.DeviceRelease = XFsbl_SdRelease;
#else
			/**
			 * This bootmode is not supported in this release
			 */
			XFsbl_Printf(DEBUG_GENERAL,
				"XFSBL_ERROR_UNSUPPORTED_BOOT_MODE\n\r");
			Status = XFSBL_ERROR_UNSUPPORTED_BOOT_MODE;
#endif
		} break;

		default:
		{
			XFsbl_Printf(DEBUG_GENERAL,
					"XFSBL_ERROR_UNSUPPORTED_BOOT_MODE\n\r");
			Status = XFSBL_ERROR_UNSUPPORTED_BOOT_MODE;
		} break;

	}

	/**
	 * In case of error or Jtag boot, goto end
	 */
	if (XFSBL_SUCCESS != Status) {
		goto END;
	}

	/**
	 * Initialize the Device Driver
	 */
	Status = FsblInstancePtr->DeviceOps.DeviceInit(BootMode);
	if (XFSBL_SUCCESS != Status) {
		goto END;
	}

END:
	return Status;
}
Exemplo n.º 2
0
/**
 * Configure the RSA and SHA for the SPK
 * Signature verification.
 * If SPK Signature verification fails
 * then return unique error code saying
 * XFSBL_STAGE3_SPK_SIGN_VERIF_ERROR.
 *
 * @param
 *
 * @return
 *
 ******************************************************************************/
u32 XFsbl_SpkVer(XFsblPs *FsblInstancePtr , u64 AcOffset, u32 HashLen,
			u32 PartitionNum)
{
	u8 SpkHash[XFSBL_HASH_TYPE_SHA3] __attribute__ ((aligned (4)));
	u8 * PpkModular = (u8 *)NULL;
	u8 * PpkModularEx = (u8 *)NULL;
	u32 PpkExp = 0;
	u8 * AcPtr = (u8*) (PTRSIZE) AcOffset;
	u32 Status = XFSBL_SUCCESS;
	void * ShaCtx = (void * )NULL;
	u8 XFsbl_RsaSha3Array[512];

#ifdef XFSBL_SHA2
	sha2_context ShaCtxObj;
	ShaCtx = &ShaCtxObj;
#endif

#ifndef XFSBL_PS_DDR
	XFsblPs_PartitionHeader * PartitionHeader;
	u32 DestinationDevice = 0U;
	PartitionHeader =
		&FsblInstancePtr->ImageHeader.PartitionHeader[PartitionNum];
	DestinationDevice = XFsbl_GetDestinationDevice(PartitionHeader);

	if (DestinationDevice == XIH_PH_ATTRB_DEST_DEVICE_PL)
	{
		/*
		 * If it is DDR less system, bitstream chunk containing
		 * Authentication Certificate has to be read from boot device
		 */
		if(XFSBL_SUCCESS != FsblInstancePtr->DeviceOps.DeviceCopy(
					(INTPTR)AcPtr, (PTRSIZE)ReadBuffer,
					XFSBL_AUTH_CERT_MIN_SIZE)) {
			XFsbl_Printf(DEBUG_GENERAL,
			"XFsbl_SpkVer: Device to OCM copy of certificate failed \r\n");
			Status = XFSBL_ERROR_SPK_RSA_DECRYPT;
			goto END;
		}

		/* Repoint Auth. cert. pointer to OCM buffer beginning*/
		AcPtr = ReadBuffer;
	}
#endif

	/* Re-initialize CSU DMA. This is a workaround and need to be removed */
	Status = XFsbl_CsuDmaInit();
	if (XST_SUCCESS != Status) {
		goto END;
	}

	(void)XFsbl_ShaStart(ShaCtx, HashLen);

	/* Hash the PPK + SPK choice */
	XFsbl_ShaUpdate(ShaCtx, AcPtr, 8, HashLen);

	/* Set PPK pointer */
	AcPtr += XFSBL_RSA_AC_ALIGN;
	PpkModular = (u8 *)AcPtr;
	AcPtr += XFSBL_PPK_MOD_SIZE;
	PpkModularEx = (u8 *)AcPtr;
	AcPtr += XFSBL_PPK_MOD_EXT_SIZE;
	PpkExp = *((u32 *)AcPtr);
	AcPtr += XFSBL_RSA_AC_ALIGN;

	XFsbl_Printf(DEBUG_DETAILED,
		"XFsbl_SpkVer: Ppk Mod %0x, Ppk Mod Ex %0x, Ppk Exp %0x\r\n",
		PpkModular, PpkModularEx, PpkExp);

	/* Calculate SPK + Auth header Hash */
	XFsbl_ShaUpdate(ShaCtx, (u8 *)AcPtr, XFSBL_SPK_SIZE, HashLen);

	XFsbl_ShaFinish(ShaCtx, (u8 *)SpkHash, HashLen);

	/* Set SPK Signature pointer */
	AcPtr += XFSBL_SPK_SIZE;

	XSecure_RsaInitialize(&SecureRsa, PpkModular,
				PpkModularEx, (u8 *)&PpkExp);

	/* Decrypt SPK Signature */
	if(XFSBL_SUCCESS !=
		XSecure_RsaDecrypt(&SecureRsa, AcPtr, XFsbl_RsaSha3Array))
	{
		XFsbl_Printf(DEBUG_GENERAL,
			"XFsbl_SpkVer: XFSBL_ERROR_SPK_RSA_DECRYPT\r\n");
		Status = XFSBL_ERROR_SPK_RSA_DECRYPT;
		goto END;
	}

	/* Authenticate SPK Signature */
	if(XFSBL_SUCCESS != XSecure_RsaSignVerification(XFsbl_RsaSha3Array,
							SpkHash, HashLen))
	{
		XFsbl_PrintArray(DEBUG_INFO, SpkHash,
				HashLen, "Calculated SPK Hash");
		XFsbl_PrintArray(DEBUG_INFO, XFsbl_RsaSha3Array,
				512, "RSA decrypted Hash");
		XFsbl_Printf(DEBUG_GENERAL,
			"XFsbl_SpkVer: XFSBL_ERROR_SPK_SIGNATURE\r\n");
		Status = XFSBL_ERROR_SPK_SIGNATURE;
	}

END:
	return Status;
}