diff --git a/lib/sw_apps/zynqmp_fsbl/src/xfsbl_bs.c b/lib/sw_apps/zynqmp_fsbl/src/xfsbl_bs.c new file mode 100755 index 00000000..e171451f --- /dev/null +++ b/lib/sw_apps/zynqmp_fsbl/src/xfsbl_bs.c @@ -0,0 +1,253 @@ +/****************************************************************************** + * + * Copyright (C) 2015 Xilinx, Inc. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * Use of the Software is limited solely to applications: + * (a) running on a Xilinx device, or + * (b) that interact with a Xilinx device through a bus or interconnect. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF + * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * Except as contained in this notice, the name of the Xilinx shall not be used + * in advertising or otherwise to promote the sale, use or other dealings in + * this Software without prior written authorization from Xilinx. + * + * + *******************************************************************************/ +/*****************************************************************************/ +/** + * + * @file xfsbl_bs.c + * + * This file contains the definitions of bitstream loading functions. + * + *
+ * MODIFICATION HISTORY: + * + * Ver Who Date Changes + * ----- ---- -------- ------------------------------------------------------- + * 1.00 ba 11/17/14 Initial release + * + *+ * + * @note + * + ******************************************************************************/ + +/***************************** Include Files *********************************/ +#include "xfsbl_hw.h" +#ifdef XFSBL_BS +#include "xfsbl_bs.h" + +/************************** Constant Definitions *****************************/ + +/**************************** Type Definitions *******************************/ + +/***************** Macros (Inline Functions) Definitions *********************/ + +/************************** Function Prototypes ******************************/ + +/************************** Variable Definitions *****************************/ + +/*****************************************************************************/ +/** This function does the necessary initialization of PCAP interface + * + * @param None + * + * @return error status based on implemented functionality (SUCCESS by default) + * + *****************************************************************************/ +u32 XFsbl_PcapInit(void) { + u32 RegVal; + u32 Status = XFSBL_SUCCESS; + + /* Take PCAP out of Reset */ + RegVal = XFsbl_In32(CSU_PCAP_RESET); + RegVal &= (~CSU_PCAP_RESET_RESET_MASK); + XFsbl_Out32(CSU_PCAP_RESET, RegVal); + + /* Select PCAP mode and change PCAP to write mode */ + RegVal = CSU_PCAP_CTRL_PCAP_PR_MASK; + XFsbl_Out32(CSU_PCAP_CTRL, RegVal); + XFsbl_Out32(CSU_PCAP_RDWR, 0x0); + + /* If PL not powered up yet, do it now */ + RegVal = XFsbl_In32(PMU_GLOBAL_PWR_STATE); + if ((RegVal & PMU_GLOBAL_PWR_STATE_PL_MASK) != + PMU_GLOBAL_PWR_STATE_PL_MASK) { + /* Power up request enable */ + RegVal = XFsbl_In32(PMU_GLOBAL_REQ_PWRUP_INT_EN); + RegVal |= PMU_GLOBAL_REQ_PWRUP_INT_EN_PL_MASK; + XFsbl_Out32(PMU_GLOBAL_REQ_PWRUP_INT_EN, RegVal); + + /* Trigger power up request */ + RegVal = XFsbl_In32(PMU_GLOBAL_REQ_PWRUP_TRIG); + RegVal |= PMU_GLOBAL_REQ_PWRUP_TRIG_PL_MASK; + XFsbl_Out32(PMU_GLOBAL_REQ_PWRUP_TRIG, RegVal); + + /* Poll for Power up complete */ + do { + RegVal = XFsbl_In32(PMU_GLOBAL_REQ_PWRUP_STATUS) & + PMU_GLOBAL_REQ_PWRUP_STATUS_PL_MASK; + } while (RegVal != PMU_GLOBAL_REQ_PWRUP_STATUS_PL_MASK); + + if ((RegVal & PMU_GLOBAL_PWR_STATE_PL_MASK) != + PMU_GLOBAL_PWR_STATE_PL_MASK) { + Status = XFSBL_ERROR_PL_POWER_ISOLATION; + XFsbl_Printf(DEBUG_GENERAL, "XFSBL_ERROR_PL_POWER_ISOLATION\r\n"); + goto END; + } + } + + /* Reset PL */ + XFsbl_Out32(CSU_PCAP_PROG, 0x0U); + + usleep(PL_RESET_PERIOD_IN_US); + + XFsbl_Out32(CSU_PCAP_PROG, CSU_PCAP_PROG_PCFG_PROG_B_MASK); + + /* + * Wait for PL_init completion + * Bypass this check in platforms not supporting PCAP interface + */ + if ((XFSBL_PLATFORM != XFSBL_PLATFORM_REMUS) + && (XFSBL_PLATFORM != XFSBL_PLATFORM_QEMU)) { + RegVal = 0U; + do { + RegVal = XFsbl_In32(CSU_PCAP_STATUS) & + CSU_PCAP_STATUS_PL_INIT_MASK; + } while (RegVal != CSU_PCAP_STATUS_PL_INIT_MASK); + } else { + XFsbl_Printf(DEBUG_GENERAL, + "PCAP interface is not supported in this platform \r\n"); + } +END: + return Status; +} + +/*****************************************************************************/ +/** This function waits for PCAP transfer to complete + * + * @param None + * + * @return error status based on implemented functionality (SUCCESS by default) + * + *****************************************************************************/ +static u32 XFsbl_PcapWaitForDone() { + u32 RegVal; + u32 Status = XFSBL_SUCCESS; + + do { + RegVal = XFsbl_In32(CSU_PCAP_STATUS); + RegVal = RegVal & CSU_PCAP_STATUS_PCAP_WR_IDLE_MASK; + } while (RegVal != CSU_PCAP_STATUS_PCAP_WR_IDLE_MASK); + + return Status; +} + +/*****************************************************************************/ +/** This is the function to write data to PCAP interface + * + * @param WrSize: Number of 32bit words that the DMA should write to + * the PCAP interface + * @param WrAddr: Linear memory space from where CSUDMA will read + * the data to be written to PCAP interface + * + * @return None + * + *****************************************************************************/ +u32 XFsbl_WriteToPcap(u32 WrSize, u8 *WrAddr) { + u32 RegVal; + u32 Status = XFSBL_SUCCESS; + + /* + * Setup the SSS, setup the PCAP to receive from DMA source + */ + RegVal = XFsbl_In32(CSU_CSU_SSS_CFG) & CSU_CSU_SSS_CFG_PCAP_SSS_MASK; + RegVal = RegVal + | (XFSBL_CSU_SSS_SRC_SRC_DMA << CSU_CSU_SSS_CFG_PCAP_SSS_SHIFT); + XFsbl_Out32(CSU_CSU_SSS_CFG, RegVal); + + /* Setup the source DMA channel */ + XCsuDma_Transfer(&CsuDma, XCSUDMA_SRC_CHANNEL, (PTRSIZE) WrAddr, WrSize, 0); + + /* wait for the SRC_DMA to complete and the pcap to be IDLE */ + XCsuDma_WaitForDone(&CsuDma, XCSUDMA_SRC_CHANNEL); + + /* Acknowledge the transfer has completed */ + XCsuDma_IntrClear(&CsuDma, XCSUDMA_SRC_CHANNEL, XCSUDMA_IXR_DONE_MASK); + + XFsbl_Printf(DEBUG_GENERAL, "DMA transfer done \r\n"); + Status = XFsbl_PcapWaitForDone(); + if (Status != XFSBL_SUCCESS) { + goto END; + } + + END: return Status; +} + +/*****************************************************************************/ +/** + * This function waits for PL Done bit to be set or till timeout and resets + * PCAP after this. + * + * @param None + * + * @return error status based on implemented functionality (SUCCESS by default) + * + *****************************************************************************/ +u32 XFsbl_PLWaitForDone(void) { + u32 Status = XFSBL_SUCCESS; + u32 PollCount; + u32 RegVal; + + PollCount = (PL_DONE_POLL_COUNT); + while (PollCount) { + /* Read PCAP Status register and check for PL_DONE bit */ + RegVal = XFsbl_In32(CSU_PCAP_STATUS); + RegVal &= CSU_PCAP_STATUS_PL_DONE_MASK; + if (RegVal == CSU_PCAP_STATUS_PL_DONE_MASK) { + break; + } + PollCount--; + } + + if (RegVal == CSU_PCAP_STATUS_PL_DONE_MASK) { + XFsbl_Printf(DEBUG_GENERAL, "PL Configuration done successfully \r\n"); + } else { + Status = XFSBL_ERROR_BITSTREAM_LOAD_FAIL; + XFsbl_Printf(DEBUG_GENERAL, "XFSBL_ERROR_BITSTREAM_LOAD_FAIL\r\n"); + goto END; + } + + /* Reset PCAP after data transfer */ + RegVal = XFsbl_In32(CSU_PCAP_RESET); + RegVal = RegVal | CSU_PCAP_RESET_RESET_MASK; + XFsbl_Out32(CSU_PCAP_RESET, RegVal); + + do { + RegVal = XFsbl_In32(CSU_PCAP_RESET); + RegVal = RegVal & CSU_PCAP_RESET_RESET_MASK; + } while (RegVal != CSU_PCAP_RESET_RESET_MASK); + + END: + return Status; +} + +#endif diff --git a/lib/sw_apps/zynqmp_fsbl/src/xfsbl_bs.h b/lib/sw_apps/zynqmp_fsbl/src/xfsbl_bs.h new file mode 100755 index 00000000..06d8df66 --- /dev/null +++ b/lib/sw_apps/zynqmp_fsbl/src/xfsbl_bs.h @@ -0,0 +1,94 @@ +/****************************************************************************** +* +* Copyright (C) 2015 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* Use of the Software is limited solely to applications: +* (a) running on a Xilinx device, or +* (b) that interact with a Xilinx device through a bus or interconnect. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +* +*******************************************************************************/ +/*****************************************************************************/ +/** +* +* @file xfsbl_bs.h +* +* This is the header file which contains definitions for the PCAP hardware +* registers and declarations of bitstream download functions +* +*
+* MODIFICATION HISTORY: +* +* Ver Who Date Changes +* ----- ---- -------- ------------------------------------------------------- +* 1.00 ba 11/17/14 Initial release +* +*+* +* @note +* +******************************************************************************/ + +#ifndef XFSBL_BS_H +#define XFSBL_BS_H + +#ifdef __cplusplus +extern "C" { +#endif + +/***************************** Include Files *********************************/ + +#include "xfsbl_main.h" +#include "xfsbl_csu_dma.h" +#include "xfsbl_hw.h" +#include "xcsudma.h" +/************************** Constant Definitions *****************************/ + +#define PL_DONE_POLL_COUNT 10000U +#define PL_RESET_PERIOD_IN_US 1U + +/* Dummy address to indicate that destination is PCAP */ +#define XFSBL_DESTINATION_PCAP_ADDR (0XFFFFFFFFU) + +/**************************** Type Definitions *******************************/ + +/***************** Macros (Inline Functions) Definitions *********************/ + +/************************** Function Prototypes ******************************/ +u32 XFsbl_BitstreamLoad(XFsblPs * FsblInstancePtr, u32 PartitionNum, PTRSIZE LoadAddress); +u32 XFsbl_PcapInit(void); +u32 XFsbl_PLWaitForDone(void); +u32 XFsbl_WriteToPcap(u32 WrSize, u8 *WrAddr); + +/************************** Variable Definitions *****************************/ + +extern XCsuDma CsuDma; /* CSU DMA instance */ + + +#ifdef __cplusplus +} +#endif + +#endif /* XFSBL_BS_H */ diff --git a/lib/sw_apps/zynqmp_fsbl/src/xfsbl_config.h b/lib/sw_apps/zynqmp_fsbl/src/xfsbl_config.h index 3bc106aa..583bda3e 100644 --- a/lib/sw_apps/zynqmp_fsbl/src/xfsbl_config.h +++ b/lib/sw_apps/zynqmp_fsbl/src/xfsbl_config.h @@ -118,6 +118,7 @@ extern "C" { * - FSBL_SD_EXCLUDE SD code will be excluded * - FSBL_RSA_EXCLUDE RSA (authentication) code will be excluded * - FSBL_AES_EXCLUDE AES (decryption) code will be excluded + * - FSBL_BS_EXCLUDE AES (PL bitstream) code will be excluded * - FSBL_SHA2_EXCLUDE SHA2 code will be excluded */ #define FSBL_NAND_EXCLUDE_VAL (0U) @@ -125,6 +126,7 @@ extern "C" { #define FSBL_SD_EXCLUDE_VAL (0U) #define FSBL_RSA_EXCLUDE_VAL (0U) #define FSBL_AES_EXCLUDE_VAL (0U) +#define FSBL_BS_EXCLUDE_VAL (0U) #define FSBL_SHA2_EXCLUDE_VAL (1U) #if FSBL_NAND_EXCLUDE_VAL @@ -147,6 +149,10 @@ extern "C" { #define FSBL_AES_EXCLUDE #endif +#if FSBL_BS_EXCLUDE_VAL +#define FSBL_BS_EXCLUDE +#endif + #if FSBL_SHA2_EXCLUDE_VAL #define FSBL_SHA2_EXCLUDE #endif diff --git a/lib/sw_apps/zynqmp_fsbl/src/xfsbl_csu_dma.h b/lib/sw_apps/zynqmp_fsbl/src/xfsbl_csu_dma.h index a3969869..0fc98215 100644 --- a/lib/sw_apps/zynqmp_fsbl/src/xfsbl_csu_dma.h +++ b/lib/sw_apps/zynqmp_fsbl/src/xfsbl_csu_dma.h @@ -64,6 +64,7 @@ extern "C" { /**************************** Type Definitions *******************************/ /**************************** Macros Definitions *****************************/ +#define XFSBL_CSU_SSS_SRC_SRC_DMA 0x5U /************************** Function Prototypes ******************************/ u32 XFsbl_CsuDmaInit(); diff --git a/lib/sw_apps/zynqmp_fsbl/src/xfsbl_error.h b/lib/sw_apps/zynqmp_fsbl/src/xfsbl_error.h index ffdc6f0d..2d45901d 100644 --- a/lib/sw_apps/zynqmp_fsbl/src/xfsbl_error.h +++ b/lib/sw_apps/zynqmp_fsbl/src/xfsbl_error.h @@ -151,10 +151,11 @@ extern "C" { #define XFSBL_ERROR_BITSTREAM_LOAD_FAIL (0x37U) #define XFSBL_ERROR_BITSTREAM_GCM_TAG_MISMATCH (0x38U) #define XFSBL_ERROR_DECRYPTION_IMAGE_LENGTH_MISMATCH (0x39U) -#define XFSBL_ERROR_BITSTREAM_DECRYPTION_FAIL (0x40U) -#define XFSBL_ERROR_DECRYPTION_FAILED (0x41U) -#define XFSBL_ERROR_RSA_NOT_ENABLED (0x42U) -#define XFSBL_ERROR_AES_NOT_ENABLED (0x43U) +#define XFSBL_ERROR_BITSTREAM_DECRYPTION_FAIL (0x3AU) +#define XFSBL_ERROR_RSA_NOT_ENABLED (0x3BU) +#define XFSBL_ERROR_AES_NOT_ENABLED (0x3CU) +#define XFSBL_ERROR_PL_NOT_ENABLED (0x3DU) +#define XFSBL_ERROR_PL_POWER_ISOLATION (0x3EU) #define XFSBL_FAILURE (0x3FFU) diff --git a/lib/sw_apps/zynqmp_fsbl/src/xfsbl_hooks.c b/lib/sw_apps/zynqmp_fsbl/src/xfsbl_hooks.c index 02c3d427..0ea363f5 100644 --- a/lib/sw_apps/zynqmp_fsbl/src/xfsbl_hooks.c +++ b/lib/sw_apps/zynqmp_fsbl/src/xfsbl_hooks.c @@ -61,7 +61,7 @@ /************************** Function Prototypes ******************************/ /************************** Variable Definitions *****************************/ - +#ifdef XFSBL_BS u32 XFsbl_HookBeforeBSDownload(void ) { u32 Status = XFSBL_SUCCESS; @@ -85,7 +85,7 @@ u32 XFsbl_HookAfterBSDownload(void ) return Status; } - +#endif u32 XFsbl_HookBeforeHandoff(void ) { diff --git a/lib/sw_apps/zynqmp_fsbl/src/xfsbl_hw.h b/lib/sw_apps/zynqmp_fsbl/src/xfsbl_hw.h index 16c1540a..cc25b6ea 100644 --- a/lib/sw_apps/zynqmp_fsbl/src/xfsbl_hw.h +++ b/lib/sw_apps/zynqmp_fsbl/src/xfsbl_hw.h @@ -84,16 +84,27 @@ extern "C" { */ #define CSU_CSU_SSS_CFG ( ( CSU_BASEADDR ) + 0X00000008U ) #define CSU_CSU_SSS_CFG_PCAP_SSS_MASK 0X0000000FU +#define CSU_CSU_SSS_CFG_PCAP_SSS_SHIFT 0U /** * Register: CSU_PCAP_STATUS */ #define CSU_PCAP_STATUS ( ( CSU_BASEADDR ) + 0X00003010U ) +#define CSU_PCAP_STATUS_PL_INIT_SHIFT 2U +#define CSU_PCAP_STATUS_PL_INIT_MASK 0X00000004U +#define CSU_PCAP_STATUS_PCAP_WR_IDLE_MASK 0X00000001U +#define CSU_PCAP_STATUS_PL_DONE_MASK 0X00000008U /** * Register: CSU_PCAP_RDWR */ #define CSU_PCAP_RDWR ( ( CSU_BASEADDR ) + 0X00003004U ) +#define CSU_PCAP_RDWR_PCAP_RDWR_B_SHIFT 0U + +/* Register: CSU_PCAP_PROG */ +#define CSU_PCAP_PROG ( ( CSU_BASEADDR ) + 0X00003000U ) +#define CSU_PCAP_PROG_PCFG_PROG_B_MASK 0X00000001U +#define CSU_PCAP_PROG_PCFG_PROG_B_SHIFT 0U /** * Register: CSU_VERSION @@ -130,6 +141,13 @@ extern "C" { */ #define CSU_SHA_DIGEST_0 ( ( CSU_BASEADDR ) + 0X00002010U ) +/* Register: CSU_PCAP_RESET */ +#define CSU_PCAP_RESET ( ( CSU_BASEADDR ) + 0X0000300CU ) +#define CSU_PCAP_RESET_RESET_MASK 0X00000001U + +/* Register: CSU_PCAP_CTRL */ +#define CSU_PCAP_CTRL ( ( CSU_BASEADDR ) + 0X00003008U ) +#define CSU_PCAP_CTRL_PCAP_PR_MASK 0X00000001U /* efuse */ @@ -213,6 +231,12 @@ extern "C" { #define CRL_APB_RESET_CTRL ( ( CRL_APB_BASEADDR ) + 0X00000218U ) #define CRL_APB_RESET_CTRL_SOFT_RESET_MASK 0X00000010U +/* Register: CRL_APB_PCAP_CTRL */ +#define CRL_APB_PCAP_CTRL ( ( CRL_APB_BASEADDR ) + 0X000000A4U ) +#define CRL_APB_PCAP_CTRL_DIVISOR0_SHIFT 8U +#define CRL_APB_PCAP_CTRL_DIVISOR0_MASK 0X00003F00U +#define CRL_APB_PCAP_CTRL_CLKACT_MASK 0X01000000U + /* apu */ /** @@ -280,6 +304,23 @@ extern "C" { #define PMU_GLOBAL_GLOBAL_CNTRL ( ( PMU_GLOBAL_BASEADDR ) + 0X00000000U ) #define PMU_GLOBAL_GLOBAL_CNTRL_MB_SLEEP_MASK 0X00010000U +/* Register: PMU_GLOBAL_REQ_PWRUP_INT_EN */ +#define PMU_GLOBAL_REQ_PWRUP_INT_EN ( ( PMU_GLOBAL_BASEADDR ) + 0X00000118U ) +#define PMU_GLOBAL_REQ_PWRUP_INT_EN_PL_MASK 0X00800000U + +/* Register: PMU_GLOBAL_REQ_PWRUP_TRIG */ +#define PMU_GLOBAL_REQ_PWRUP_TRIG ( ( PMU_GLOBAL_BASEADDR ) + 0X00000120U ) +#define PMU_GLOBAL_REQ_PWRUP_TRIG_PL_MASK 0X00800000U + +/* Register: PMU_GLOBAL_REQ_PWRUP_STATUS */ +#define PMU_GLOBAL_REQ_PWRUP_STATUS ( ( PMU_GLOBAL_BASEADDR ) + 0X00000110U ) +#define PMU_GLOBAL_REQ_PWRUP_STATUS_PL_SHIFT 23U +#define PMU_GLOBAL_REQ_PWRUP_STATUS_PL_MASK 0X00800000U + +/* Register: PMU_GLOBAL_PWR_STATE */ +#define PMU_GLOBAL_PWR_STATE ( ( PMU_GLOBAL_BASEADDR ) + 0X00000100U ) +#define PMU_GLOBAL_PWR_STATE_PL_MASK 0X00800000U + /* rpu */ /** @@ -481,6 +522,13 @@ extern "C" { #define XFSBL_AES #endif +/** + * Definition for PL bitsream feature to be included + */ +#if !defined(FSBL_BS_EXCLUDE) +#define XFSBL_BS +#endif + /** * Definition for SHA2 to be included */ diff --git a/lib/sw_apps/zynqmp_fsbl/src/xfsbl_partition_load.c b/lib/sw_apps/zynqmp_fsbl/src/xfsbl_partition_load.c index 041ca503..d9fa1f4a 100644 --- a/lib/sw_apps/zynqmp_fsbl/src/xfsbl_partition_load.c +++ b/lib/sw_apps/zynqmp_fsbl/src/xfsbl_partition_load.c @@ -57,6 +57,7 @@ #include "xfsbl_image_header.h" #include "xfsbl_hooks.h" #include "xfsbl_authentication.h" +#include "xfsbl_bs.h" /************************** Constant Definitions *****************************/ /**************************** Type Definitions *******************************/ @@ -746,14 +747,17 @@ static u32 XFsbl_PartitionCopy(XFsblPs * FsblInstancePtr, u32 PartitionNum) if (DestinationDevice == XIH_PH_ATTRB_DEST_DEVICE_PL) { - /** - * - * Need to check when bitstream support is added - */ +#ifdef XFSBL_BS + if (LoadAddress == 0U) { LoadAddress = XFSBL_DDR_TEMP_ADDRESS; } +#else + XFsbl_Printf(DEBUG_GENERAL,"XFSBL_ERROR_PL_NOT_ENABLED \r\n"); + Status = XFSBL_ERROR_PL_NOT_ENABLED; + goto END; +#endif } /** @@ -892,13 +896,18 @@ static u32 XFsbl_PartitionValidation(XFsblPs * FsblInstancePtr, #if defined(XFSBL_AES) u32 ImageOffset = 0U; u32 FsblIv[XIH_BH_IV_LENGTH / 4U]; - u32 UnencryptedLength; + u32 UnencryptedLength = 0; u32 IvLocation; #endif #if defined(XFSBL_RSA) || defined(XFSBL_AES) u32 Length=0U; +#endif +#if defined(XFSBL_RSA) || defined(XFSBL_AES) || defined(XFSBL_BS) u64 LoadAddress=0U; #endif +#if defined(XFSBL_BS) + u32 BitstreamWordSize = 0; +#endif /** * Update the variables @@ -985,6 +994,14 @@ static u32 XFsbl_PartitionValidation(XFsblPs * FsblInstancePtr, } #endif +#ifdef XFSBL_BS + if ((DestinationDevice == XIH_PH_ATTRB_DEST_DEVICE_PL) && + (LoadAddress == 0U)) + { + LoadAddress = XFSBL_DDR_TEMP_ADDRESS; + } +#endif + /** * Authentication Check */ @@ -1029,12 +1046,9 @@ static u32 XFsbl_PartitionValidation(XFsblPs * FsblInstancePtr, } /** - * Decrypt image for PS and PMU through CSU DMA + * Decrypt image through CSU DMA */ - if ( ((DestinationDevice == XIH_PH_ATTRB_DEST_DEVICE_PS) || - (DestinationDevice == XIH_PH_ATTRB_DEST_DEVICE_PMU)) && - (IsEncryptionEnabled == TRUE)) - { + if (IsEncryptionEnabled == TRUE) { XFsbl_Printf(DEBUG_INFO, "Decryption Enabled\r\n"); #ifdef XFSBL_AES @@ -1051,15 +1065,18 @@ static u32 XFsbl_PartitionValidation(XFsblPs * FsblInstancePtr, UnencryptedLength = PartitionHeader->UnEncryptedDataWordLength * 4U; - Status = XSecure_AesDecrypt(&SecureAes, (u8 *) LoadAddress, - (u8 *) LoadAddress, UnencryptedLength); - if (Status != XFSBL_SUCCESS) { - Status = XFSBL_ERROR_DECRYPTION_FAILED; - XFsbl_Printf(DEBUG_GENERAL, "XFSBL_ERROR_DECRYPTION_FAILED\r\n"); - goto END; - } else { - XFsbl_Printf(DEBUG_GENERAL, "Decryption Successful\r\n"); + if (DestinationDevice != XIH_PH_ATTRB_DEST_DEVICE_PL) { + Status = XSecure_AesDecrypt(&SecureAes, (u8 *) LoadAddress, + (u8 *) LoadAddress, UnencryptedLength); + + if (Status != XFSBL_SUCCESS) { + Status = XFSBL_ERROR_DECRYPTION_FAIL; + XFsbl_Printf(DEBUG_GENERAL, "XFSBL_ERROR_DECRYPTION_FAIL\r\n"); + goto END; + } else { + XFsbl_Printf(DEBUG_GENERAL, "Decryption Successful\r\n"); + } } #else XFsbl_Printf(DEBUG_GENERAL,"XFSBL_ERROR_AES_NOT_ENABLED \r\n"); @@ -1068,6 +1085,7 @@ static u32 XFsbl_PartitionValidation(XFsblPs * FsblInstancePtr, #endif } +#ifdef XFSBL_BS /** * for PL image use CSU DMA to route to PL */ @@ -1085,14 +1103,52 @@ static u32 XFsbl_PartitionValidation(XFsblPs * FsblInstancePtr, goto END; } - /** - * Configure SSS - */ + XFsbl_Printf(DEBUG_GENERAL, "Bitstream download to start now\r\n"); - /** - * Use CSU DMA to load Bit stream to PL - * Decrypt the PL if it is encrypted - */ + Status = XFsbl_PcapInit(); + if (Status != XFSBL_SUCCESS) { + goto END; + } + + if (IsEncryptionEnabled == TRUE) { +#ifdef XFSBL_AES + /* + * The secure bitstream would be sent through CSU DMA to AES + * and the decrypted bitstream is sent directly to PCAP + * by configuring SSS appropriately + */ + Status = XSecure_AesDecrypt(&SecureAes, + (u8 *) XFSBL_DESTINATION_PCAP_ADDR, + (u8 *) LoadAddress, UnencryptedLength); + + if (Status != XFSBL_SUCCESS) { + Status = XFSBL_ERROR_BITSTREAM_DECRYPTION_FAIL; + XFsbl_Printf(DEBUG_GENERAL, + "XFSBL_ERROR_BITSTREAM_DECRYPTION_FAIL\r\n"); + /* Reset PL */ + XFsbl_Out32(CSU_PCAP_PROG, 0x0); + goto END; + } else { + XFsbl_Printf(DEBUG_GENERAL, + "Bitstream decryption Successful\r\n"); + } +#endif + } + else { + + /* Use CSU DMA to load Bit stream to PL */ + BitstreamWordSize = PartitionHeader->UnEncryptedDataWordLength; + + Status = XFsbl_WriteToPcap(BitstreamWordSize, (u8 *) LoadAddress); + if (Status != XFSBL_SUCCESS) { + goto END; + } + } + + Status = XFsbl_PLWaitForDone(); + if (Status != XFSBL_SUCCESS) { + goto END; + } /** * Fsbl hook after bit stream download @@ -1106,19 +1162,23 @@ static u32 XFsbl_PartitionValidation(XFsblPs * FsblInstancePtr, goto END; } } +#endif /** * Update the handoff details */ - CpuNo = FsblInstancePtr->HandoffCpuNo; - if (XFsbl_CheckHandoffCpu(FsblInstancePtr, - DestinationCpu) == XFSBL_SUCCESS) + if(DestinationDevice != XIH_PH_ATTRB_DEST_DEVICE_PL) { - FsblInstancePtr->HandoffValues[CpuNo].CpuSettings = - DestinationCpu | ExecState; - FsblInstancePtr->HandoffValues[CpuNo].HandoffAddress = - PartitionHeader->DestinationExecutionAddress; - FsblInstancePtr->HandoffCpuNo += 1U; + CpuNo = FsblInstancePtr->HandoffCpuNo; + if (XFsbl_CheckHandoffCpu(FsblInstancePtr, + DestinationCpu) == XFSBL_SUCCESS) + { + FsblInstancePtr->HandoffValues[CpuNo].CpuSettings = + DestinationCpu | ExecState; + FsblInstancePtr->HandoffValues[CpuNo].HandoffAddress = + PartitionHeader->DestinationExecutionAddress; + FsblInstancePtr->HandoffCpuNo += 1U; + } } END: