
Added new lines in example prints. Modified CRC calculation API name and provided backward compatability. Signed-off-by: VNSL Durga <vnsldurg@xilinx.com> Reviewed-by: Harini Katakam <harinik@xilinx.com>
922 lines
31 KiB
C
922 lines
31 KiB
C
/******************************************************************************
|
||
*
|
||
* Copyright (C) 2013 - 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
|
||
* xilskey_efuse_example.c
|
||
* @note
|
||
*
|
||
* Contains the api functions for the PS & PL eFUSE functionality.
|
||
* eFUSE Application project is capable of programming the PS and PL eFUSE
|
||
* bits given by the user. PS eFUSE holds the RSA primary key hash bits and
|
||
* user feature bits, which will enable/disable some features in ZYNQ.
|
||
* In Zynq PL eFUSE holds the AES key, user key and some feature bits and
|
||
* and in Ultrascale eFUSE holds AES key, User key, RSA key Hash and
|
||
* some feature bits.
|
||
* User has the provision to write PS eFUSE & PL eFUSE independently or
|
||
* can combine together. This can be selected by using the compilation
|
||
* switch provided in xilskey_input.h. XSK_EFUSEPS_DRIVER should be
|
||
* defined to enable PS functionality & XSK_EFUSEPL_DRIVER for PL
|
||
* functionality.
|
||
* However for programming eFuse Ultrascale only XSK_EFUSEPL_DRIVER should be
|
||
* enabled.
|
||
*
|
||
* eFUSE bits are one-time programmable. Once they are burnt, they
|
||
* cannot be changed. Make sure you enter the correct information before
|
||
* you program eFUSE bits.
|
||
*
|
||
* POR reset is required for the eFUSE values to become into effect.
|
||
* Please do a POR reset after eFUSE writing.
|
||
*
|
||
* All the user configurable parameters for PS & PL eFUSE writing should be
|
||
* defined in xilskey_input.h. By default, all the macros will be defined
|
||
* with FALSE values.
|
||
*
|
||
* For Zynq
|
||
* -----------------------------------------------------------------------
|
||
* For PL eFUSE writing enabling the caches are necessary if the image is
|
||
* executing from DDR. This will be done in BSP by default. User has to
|
||
* take care not to disable caches.
|
||
*
|
||
* eFUSE writing procedure running out of DDR as an application:
|
||
* (This sequence is same as the existing flow described below)
|
||
*
|
||
* 1) After providing the required inputs in xilskey_input.h, compile the
|
||
* project.
|
||
* 2) Take the latest FSBL (.elf) and stitch the <output>.elf generated
|
||
* to it using the bootgen utility and generate a bootable image.
|
||
* 3) Write the generated binary image into the flash device.
|
||
* (Ex: QSPI,NAND etc)
|
||
* 4) Execute image from flash which will write the mentioned eFUSE key
|
||
* bits.
|
||
*
|
||
* eFUSE driver compilation procedure for OCM:
|
||
*
|
||
* 1) Open the linker script (lscript.ld) in the SDK project.
|
||
* 2) Now map all the sections points to <20>ps7_ram_0_S_AXI_BASEADDR<44>
|
||
* instead of <20>ps7_ddr_0_S_AXI_BASEADDR<44>.
|
||
*
|
||
* Example: Click on the <20>Memory Region<6F> tab for .text section & select
|
||
* <09>ps7_ram_0_S_AXI_BASEADDR<44> from the drop down list.
|
||
*
|
||
* 3) Copy the ps7_init.c & ps7_init.h files from the hw_platform folder
|
||
* into the example folder.
|
||
* 4) Uncomment calling of <20>ps7_init()<29> routine in
|
||
* <09>xilskey_efuse_example.c<>
|
||
* 5) Compile the project.
|
||
* 6) <project name>.elf will be generated. This will be executed
|
||
* out of OCM.
|
||
*
|
||
* SVF File Generation using <output>.elf :
|
||
*
|
||
* 1) Use the below xmd to create the svf file from the above generated
|
||
* elf file. Please note that path to the elf file should be given in opt file.
|
||
*
|
||
* <09>xmd <20>tcl efuse.tcl <20>opt efuse.opt<70>
|
||
*
|
||
* 2) Output of the above command will be <O/p file name>.svf.
|
||
*
|
||
* For Ultrascale
|
||
* -----------------------------------------------------------------------
|
||
* Accessing Ultrascale microblaze 's eFuse is done by using block RAM
|
||
* initialization.
|
||
* Master Jtag primitive has to added to design i.e MASTER_JTAG_inst
|
||
* instantiation have to performed and AXI GPIO pins has to be connected
|
||
* to TDO, TDI, TMS and TCK signals of MASTER_JTAG primitive.
|
||
* All Inputs(TDO) and All Outputs(TDI, TMS, TCK) of MASTER_JTAG can be
|
||
* connected as
|
||
* 1) All Inputs to one channel
|
||
* All Outputs to other channel
|
||
* Valid example: All Outputs connected to Channel 1
|
||
* Input signal TDO also connected to channel 2
|
||
* 2) All Inputs and All Outputs to same channel.
|
||
* Valid example: All Outputs connected to Channel 1
|
||
* Input signal TDO also connected to channel 1
|
||
* 3) But some of the Outputs in one channel and some of them in different
|
||
* channel is not accepted.
|
||
* Invalid example: All Outputs connected to Channel 1
|
||
* Input signals (TDI, TMS) connected to Channel 1
|
||
* Input signal TCK also connected to channel 2
|
||
* The design should only contain AXI bram Ctrl memory mapped(1MB).
|
||
* System management wizard should be operated in DRP interface.
|
||
* Note: MASTER_JTAG will disable all other JTAGs
|
||
*
|
||
* Procedure to access efuse of Ultrascale:
|
||
* 1) After providing the required inputs in xilskey_input.h, compile the
|
||
* project.
|
||
* 2) Generate a memory mapped interface file using TCL command
|
||
* write_mem_info $Outfilename
|
||
* 3) Update memory has to be done using the tcl command updatemem.
|
||
* updatemem -meminfo $file.mmi -data $Outfilename.elf -bit $design.bit
|
||
* -proc design_1_i/microblaze_0 -out $Final.bit
|
||
* 4) Program the board using $Final.bit bitstream
|
||
* 5) Output can be seen in UART terminal.
|
||
* 6) For calculating CRC of AES key reverse polynomial is 0x82F63B78 or
|
||
* one can use the API u32 XilSKey_CrcCalculation(u8 *Key)
|
||
*
|
||
* MODIFICATION HISTORY:
|
||
*
|
||
* Ver Who Date Changes
|
||
* ----- ---- -------- --------------------------------------------------------
|
||
* 1.00a rpoolla 04/26/13 First release
|
||
* 1.02a hk 10/28/13 Added use of API's read status and key. PR# 735957.
|
||
* 3.00 vns 31/07/15 Modified XSK_EFUSEPL_RSA_KEY_HASH_STRING_SIZE macro
|
||
* name to XSK_EFUSEPS_RSA_KEY_HASH_STRING_SIZE.
|
||
* Added missing goto statement.
|
||
* Modified init function, intialisation of instance is
|
||
* done based on the platform and Modified example
|
||
* to support both Zynq PL's eFuse and also Ultrascale's
|
||
* eFuse.
|
||
* 4.00 vns 09/10/15 Added DFT JTAG disable and DFT MODE disable
|
||
* programming and reading options for Zynq eFuse PS.
|
||
*
|
||
****************************************************************************/
|
||
/***************************** Include Files *********************************/
|
||
#include "stdio.h"
|
||
#include "xil_io.h"
|
||
#include "xstatus.h"
|
||
#include "xilskey_utils.h"
|
||
#include "xilskey_eps.h"
|
||
#include "xilskey_epl.h"
|
||
#include "xilskey_input.h"
|
||
/************************** Constant Definitions *****************************/
|
||
/**************************** Type Definitions ******************************/
|
||
/***************** Macros (Inline Functions) Definitions ********************/
|
||
/**
|
||
* Address for the Reboot Status Register
|
||
*/
|
||
#define REBOOT_STATUS_REG_ADDR (0xF8000258)
|
||
/**
|
||
* PL eFUSE aes key size in characters
|
||
*/
|
||
#define XSK_EFUSEPL_AES_KEY_STRING_SIZE (64)
|
||
/**
|
||
* PL eFUSE user low key size in characters
|
||
*/
|
||
#define XSK_EFUSEPL_USER_LOW_KEY_STRING_SIZE (2)
|
||
/**
|
||
* PL eFUSE user high key size in characters
|
||
*/
|
||
#define XSK_EFUSEPL_USER_HIGH_KEY_STRING_SIZE (6)
|
||
/**
|
||
* User AES Key size in Bytes
|
||
*/
|
||
#define XSK_EFUSEPL_AES_KEY_SIZE_IN_BITS (256)
|
||
/**
|
||
* User Low Key size in Bytes
|
||
*/
|
||
#define XSK_EFUSEPL_USER_LOW_KEY_SIZE_IN_BITS (8)
|
||
/**
|
||
* User High Key size in Bytes
|
||
*/
|
||
#define XSK_EFUSEPL_USER_HIGH_KEY_SIZE_IN_BITS (24)
|
||
/**
|
||
* user key size in bits
|
||
*/
|
||
#define XSK_EFUSEPL_USER_KEY_SIZE_IN_BITS (32)
|
||
/**
|
||
* PL eFUSE RSA key size in characters
|
||
*/
|
||
#define XSK_EFUSEPL_RSA_KEY_HASH_STRING_SIZE (96)
|
||
/**
|
||
* RSA Key size in Bytes
|
||
*/
|
||
#define XSK_EFUSEPL_RSA_KEY_SIZE_IN_BITS (384)
|
||
/**
|
||
* PL eFuse user key size in characters
|
||
*/
|
||
#define XSK_EFUSEPL_USER_KEY_STRING_SIZE (8)
|
||
/**
|
||
* Key length definition for RSA KEY Hash
|
||
*/
|
||
/**
|
||
* PS eFUSE RSA key Hash size in characters
|
||
*/
|
||
#define XSK_EFUSEPS_RSA_KEY_HASH_STRING_SIZE (64)
|
||
|
||
/*
|
||
* PS efuse status bit definitions
|
||
*/
|
||
#define XSK_EFUSEPS_STATUS_WP_BIT_LOW 0x1000
|
||
#define XSK_EFUSEPS_STATUS_WP_BIT_HIGH 0x2000
|
||
#define XSK_EFUSEPS_STATUS_RSA_EN 0x400
|
||
#define XSK_EFUSEPS_STATUS_ROM_128_CRC 0x800
|
||
#define XSK_EFUSEPS_STATUS_DFT_JTAG_DISABLE 0x200
|
||
#define XSK_EFUSEPS_STATUS_DFT_MODE_DISABLE 0x100
|
||
|
||
/*
|
||
* PL efuse status bit definitions of Zynq
|
||
*/
|
||
#define XSK_EFUSEPL_STATUS_FORCE_PCYCLE_RECONFIG 0x002
|
||
#define XSK_EFUSEPL_STATUS_DISABLE_KEY_WRITE 0x004
|
||
#define XSK_EFUSEPL_STATUS_DISABLE_AES_KEY_READ 0x008
|
||
#define XSK_EFUSEPL_STATUS_DISABLE_USER_KEY_READ 0x010
|
||
#define XSK_EFUSEPL_STATUS_DISABLE_FUSE_CNTRL_WRITE 0x020
|
||
#define XSK_EFUSEPL_STATUS_EFUSE_SEC_ENABLE 0x100
|
||
#define XSK_EFUSEPL_STATUS_JTAG_DISABLE 0x200
|
||
#define XSK_EFUSEPL_STATUS_BBRAM_KEY_DISABLE 0x400
|
||
|
||
/************************** Variable Definitions ****************************/
|
||
/************************** Function Prototypes *****************************/
|
||
/**
|
||
* Function used to convert the string to Hex in Little Endian format
|
||
*/
|
||
u32 XilSKey_Efuse_ConvertStringToHexLE(const char * Str, u8 * Buf, u32 Len);
|
||
/**
|
||
* Function used to convert the string to Hex in Little Endian format
|
||
*/
|
||
u32 XilSKey_Efuse_ConvertStringToHexBE(const char * Str, u8 * Buf, u32 Len);
|
||
/**
|
||
* Function used to validate the AES & RSA key provided as input
|
||
*/
|
||
u32 XilSKey_Efuse_ValidateKey(const char *Key, u32 Len);
|
||
u32 XilSKey_EfusePs_InitData(XilSKey_EPs *PsInstancePtr);
|
||
u32 XilSKey_EfusePl_InitData(XilSKey_EPl *PlInstancePtr);
|
||
/*extern void ps7_init();*/
|
||
/***************************************************************************/
|
||
int main()
|
||
{
|
||
u32 PlStatus = 0xFFFF;
|
||
u32 PsStatus = 0xFFFF;
|
||
u32 Status = 0;
|
||
|
||
/*ps7_init();*/
|
||
#ifdef XSK_EFUSEPS_DRIVER
|
||
XilSKey_EPs PsInstancePtr;
|
||
u32 PsStatusBits = 0;
|
||
#ifdef XSK_MICROBLAZE_PLATFORM
|
||
xil_printf("Kintex ultrascale will not have PS please disable"
|
||
"XSK_EFUSEPS_DRIVER\n\r");
|
||
goto EFUSE_ERROR;
|
||
#endif
|
||
/**
|
||
* Initialize the PS instance pointer with the data
|
||
* populated in xilskey_input.h
|
||
*/
|
||
PsStatus = XilSKey_EfusePs_InitData(&PsInstancePtr);
|
||
if(PsStatus != XST_SUCCESS) {
|
||
printf("PS Data Initialization failed\r\n");
|
||
goto EFUSE_ERROR;
|
||
}
|
||
|
||
/*
|
||
* Read the PS efuse status
|
||
* Change in these status bits will only be reflected after POR
|
||
*/
|
||
PsStatus = XilSKey_EfusePs_ReadStatus(&PsInstancePtr, &PsStatusBits);
|
||
if(PsStatus != XST_SUCCESS) {
|
||
printf("PS status read failed\r\n");
|
||
goto EFUSE_ERROR;
|
||
}
|
||
|
||
/*
|
||
* Print Efuse PS status bits
|
||
*/
|
||
xil_printf("EfusePS status bits : 0x%x \n\r", PsStatusBits);
|
||
|
||
if((PsStatusBits & XSK_EFUSEPS_STATUS_WP_BIT_LOW) ||
|
||
(PsStatusBits & XSK_EFUSEPS_STATUS_WP_BIT_HIGH)) {
|
||
xil_printf("EfusePS status bits : Write protect enabled\n\r");
|
||
}else {
|
||
xil_printf("EfusePS status bits : Write protect disabled\n\r");
|
||
}
|
||
|
||
if(PsStatusBits & XSK_EFUSEPS_STATUS_RSA_EN) {
|
||
xil_printf("EfusePS status bits : RSA authentication of "
|
||
"fsbl enabled\n\r");
|
||
}else {
|
||
xil_printf("EfusePS status bits : RSA authentication of "
|
||
"fsbl disabled\n\r");
|
||
}
|
||
|
||
if(PsStatusBits & XSK_EFUSEPS_STATUS_ROM_128_CRC) {
|
||
xil_printf("EfusePS status bits : 128k CRC check on ROM enabled\n\r");
|
||
}else {
|
||
xil_printf("EfusePS status bits : 128k CRC check on ROM disabled\n\r");
|
||
}
|
||
|
||
if (PsStatusBits & XSK_EFUSEPS_STATUS_DFT_JTAG_DISABLE) {
|
||
xil_printf("EfusePS status bits : DFT JTAG is disabled\n\r");
|
||
}
|
||
else {
|
||
xil_printf("EfusePS status bits : DFT JTAG is enabled\n\r");
|
||
}
|
||
|
||
if (PsStatusBits & XSK_EFUSEPS_STATUS_DFT_MODE_DISABLE) {
|
||
xil_printf("EfusePS status bits : DFT mode is disabled\n\r");
|
||
}
|
||
else {
|
||
xil_printf("EfusePS status bits : DFT mode is enabled\n\r");
|
||
}
|
||
|
||
|
||
/**
|
||
* Write the PS eFUSE as defined in xilskeyinput.h
|
||
*/
|
||
PsStatus = XilSKey_EfusePs_Write(&PsInstancePtr);
|
||
if (PsStatus != XST_SUCCESS) {
|
||
printf("PS EFUSE writing failed\n");
|
||
goto EFUSE_ERROR;
|
||
}
|
||
|
||
u32 Index;
|
||
/**
|
||
* Clear the structure element of Rsa Key Hash for reading
|
||
*/
|
||
for(Index=0;Index<32;Index++){
|
||
PsInstancePtr.RsaKeyHashValue[Index]=0;
|
||
}
|
||
/**
|
||
* Read the PS eFUSE RSA Key Hash
|
||
*/
|
||
PsStatus = XilSKey_EfusePs_Read(&PsInstancePtr);
|
||
if (PsStatus != XST_SUCCESS){
|
||
printf("PS EFUSE reading failed\n");
|
||
goto EFUSE_ERROR;
|
||
}
|
||
|
||
/**
|
||
* Print the read PS eFUSE RSA Key Hash
|
||
*/
|
||
printf("Read RSA Key Hash: \n");
|
||
|
||
for(Index=0;Index<32;Index++){
|
||
printf("%02x",PsInstancePtr.RsaKeyReadback[Index]);
|
||
}
|
||
printf("\n");
|
||
|
||
#endif /* XSK_EFUSEPS_DRIVER*/
|
||
|
||
#ifdef XSK_EFUSEPL_DRIVER
|
||
|
||
XilSKey_EPl PlInstancePtr;
|
||
u32 PlStatusBits = 0;
|
||
int KeyCnt;
|
||
|
||
/**
|
||
* Initialize the PL data structure based on the xilskey_input.h values
|
||
*/
|
||
PlStatus = XilSKey_EfusePl_InitData(&PlInstancePtr);
|
||
if( PlStatus != XST_SUCCESS) {
|
||
printf("PL Data Initialization Failed\r\n");
|
||
goto EFUSE_ERROR;
|
||
}
|
||
|
||
/**
|
||
* Call the PL eFUSE programming function to program the eFUSE
|
||
* based on the user input
|
||
*/
|
||
PlStatus = XilSKey_EfusePl_Program(&PlInstancePtr);
|
||
if(PlStatus != XST_SUCCESS) {
|
||
printf("PL eFUSE programming failed\r\n");
|
||
goto EFUSE_ERROR;
|
||
}
|
||
|
||
/*
|
||
* Read Efuse PL status bits
|
||
*/
|
||
PlStatus = XilSKey_EfusePl_ReadStatus(&PlInstancePtr, &PlStatusBits);
|
||
if( PlStatus != XST_SUCCESS) {
|
||
printf("PL efuse status read failed\r\n");
|
||
goto EFUSE_ERROR;
|
||
}
|
||
|
||
/*
|
||
* Print Efuse PL status bits
|
||
*/
|
||
xil_printf("EfusePL status bits : 0x%x \n\r", PlStatusBits);
|
||
/* Status bits for Zynq */
|
||
if (PlInstancePtr.FpgaFlag == XSK_FPGA_SERIES_ZYNQ) {
|
||
if(PlStatusBits & XSK_EFUSEPL_STATUS_FORCE_PCYCLE_RECONFIG) {
|
||
xil_printf("EfusePL status bits : Force power cycle for "
|
||
"reconfiguration enabled\n\r");
|
||
}else {
|
||
xil_printf("EfusePL status bits : Force power cycle for "
|
||
"reconfiguration disabled\n\r");
|
||
}
|
||
|
||
if(PlStatusBits & XSK_EFUSEPL_STATUS_DISABLE_KEY_WRITE) {
|
||
xil_printf("EfusePL status bits : Key write disabled \n\r");
|
||
}else {
|
||
xil_printf("EfusePL status bits : Key write enabled \n\r");
|
||
}
|
||
|
||
if(PlStatusBits & XSK_EFUSEPL_STATUS_DISABLE_AES_KEY_READ) {
|
||
xil_printf("EfusePL status bits : AES Key read disabled \n\r");
|
||
}else {
|
||
xil_printf("EfusePL status bits : AES Key read enabled \n\r");
|
||
}
|
||
|
||
if(PlStatusBits & XSK_EFUSEPL_STATUS_DISABLE_USER_KEY_READ) {
|
||
xil_printf("EfusePL status bits : User Key read disabled \n\r");
|
||
}else {
|
||
xil_printf("EfusePL status bits : User Key read enabled \n\r");
|
||
}
|
||
|
||
if(PlStatusBits & XSK_EFUSEPL_STATUS_DISABLE_FUSE_CNTRL_WRITE) {
|
||
xil_printf("EfusePL status bits : Fuse Control write disabled \n\r");
|
||
}else {
|
||
xil_printf("EfusePL status bits : Fuse Control write enabled \n\r");
|
||
}
|
||
|
||
if(PlStatusBits & XSK_EFUSEPL_STATUS_EFUSE_SEC_ENABLE) {
|
||
xil_printf("EfusePL status bits : Efuse secure boot enabled \n\r");
|
||
}else {
|
||
xil_printf("EfusePL status bits : Efuse secure boot disabled \n\r");
|
||
}
|
||
|
||
if(PlStatusBits & XSK_EFUSEPL_STATUS_JTAG_DISABLE) {
|
||
xil_printf("EfusePL status bits : Jtag disabled \n\r");
|
||
}else {
|
||
xil_printf("EfusePL status bits : Jtag enabled \n\r");
|
||
}
|
||
|
||
if(PlStatusBits & XSK_EFUSEPL_STATUS_BBRAM_KEY_DISABLE) {
|
||
xil_printf("EfusePL status bits : BBRAM key disabled \n\r");
|
||
}else {
|
||
xil_printf("EfusePL status bits : BBRAM key enabled \n\r");
|
||
}
|
||
}
|
||
else { /* for Ultrascale */
|
||
if(PlStatusBits & (1 << XSK_EFUSEPL_STATUS_DISABLE_KEY_READ_ULTRA)) {
|
||
xil_printf("EfusePL status bits : AES key read and programming disabled \n\r");
|
||
}else {
|
||
xil_printf("EfusePL status bits : AES key read enabled\n\r");
|
||
}
|
||
if(PlStatusBits & (1 << XSK_EFUSEPL_STATUS_DISABLE_USER_KEY_READ_ULTRA)) {
|
||
xil_printf("EfusePL status bits : User key read and programming disabled \n\r");
|
||
}else {
|
||
xil_printf("EfusePL status bits : User key read enabled\n\r");
|
||
}
|
||
if(PlStatusBits & (1 << XSK_EFUSEPL_STATUS_DISABLE_SECURE_READ_ULTRA)) {
|
||
xil_printf("EfusePL status bits : Secure bits read and programming disabled \n\r");
|
||
}else {
|
||
xil_printf("EfusePL status bits : Secure bits read enabled\n\r");
|
||
}
|
||
if(PlStatusBits & (1<< XSK_EFUSEPL_STATUS_DISABLE_CNTRL_WRITE_ULTRA)) {
|
||
xil_printf("EfusePL status bits : Cntrol bits write disabled \n\r");
|
||
}else {
|
||
xil_printf("EfusePL status bits : Control bits write enabled\n\r");
|
||
}
|
||
if(PlStatusBits & (1 << XSK_EFUSEPL_STATUS_DISABLE_RSA_KEY_READ_ULTRA)) {
|
||
xil_printf("EfusePL status bits : RSA key read and programming disabled \n\r");
|
||
}else {
|
||
xil_printf("EfusePL status bits : RSA key read enabled\n\r");
|
||
}
|
||
if(PlStatusBits & (1 << XSK_EFUSEPL_STATUS_DISABLE_KEY_WRITE_ULTRA)) {
|
||
xil_printf("EfusePL status bits : AES key programming disabled \n\r");
|
||
}else {
|
||
xil_printf("EfusePL status bits : AES key programming enabled\n\r");
|
||
}
|
||
if(PlStatusBits & (1 << XSK_EFUSEPL_STATUS_DISABLE_USER_KEY_WRITE_ULTRA)) {
|
||
xil_printf("EfusePL status bits : User key programming disabled \n\r");
|
||
}else {
|
||
xil_printf("EfusePL status bits : User key programming enabled\n\r");
|
||
}
|
||
if(PlStatusBits & (1 << XSK_EFUSEPL_STATUS_DISABLE_SECURE_WRITE_ULTRA)) {
|
||
xil_printf("EfusePL status bits : Secure bits programming disabled \n\r");
|
||
}else {
|
||
xil_printf("EfusePL status bits : Secure bits programming enabled\n\r");
|
||
}
|
||
if(PlStatusBits & (1 << XSK_EFUSEPL_STATUS_DISABLE_RSA_KEY_WRITE_ULTRA)) {
|
||
xil_printf("EfusePL status bits : RSA key programming disabled \n\r");
|
||
}else {
|
||
xil_printf("EfusePL status bits : RSA key programming enabled\n\r");
|
||
}
|
||
if(PlStatusBits & (1 << XSK_EFUSEPL_STATUS_FUSE_LOGIC_IS_BUSY_ULTRA)) {
|
||
xil_printf("EfusePL status bits : FUSE logic is busy \n\r");
|
||
}else {
|
||
xil_printf("EfusePL status bits : FUSE logic is free \n\r");
|
||
}
|
||
if(PlStatusBits & (1 << XSK_EFUSEPL_STATUS_ALLOW_ENCRYPTED_ONLY_ULTRA)) {
|
||
xil_printf("EfusePL status bits : Only allows encrypted bitstreams\n\r");
|
||
}else {
|
||
xil_printf("EfusePL status bits : Non encrypted bitstream allowed\n\r");
|
||
}
|
||
if(PlStatusBits & (1 << XSK_EFUSEPL_STATUS_AES_ONLY_ENABLED_ULTRA)) {
|
||
xil_printf("EfusePL status bits : Decryption only by AES of FUSE \n\r");
|
||
}else {
|
||
xil_printf("EfusePL status bits : Decryption can be AES of FUSE or BBRAM \n\r");
|
||
}
|
||
if(PlStatusBits & (1 << XSK_EFUSEPL_STATUS_RSA_AUTH_ENABLED_ULTRA)) {
|
||
xil_printf("EfusePL status bits : RSA authentication is enabled \n\r");
|
||
}else {
|
||
xil_printf("EfusePL status bits : RSA authentication is disabled \n\r");
|
||
}
|
||
if(PlStatusBits & (1 << XSK_EFUSEPL_STATUS_DISABLE_JTAG_ULTRA)) {
|
||
xil_printf("EfusePL status bits : External Jtag pins are disabled\n\r");
|
||
}else {
|
||
xil_printf("EfusePL status bits : Jtag is not disabled\n\r");
|
||
}
|
||
if(PlStatusBits & (1 << XSK_EFUSEPL_STATUS_DISABLE_TEST_ACCESS_ULTRA)) {
|
||
xil_printf("EfusePL status bits : Disables test access\n\r");
|
||
}else {
|
||
xil_printf("EfusePL status bits : Xilinx test access is enabled\n\r");
|
||
}
|
||
if(PlStatusBits & (1 << XSK_EFUSEPL_STATUS_DISABLE_DCRPTR_ULTRA)) {
|
||
xil_printf("EfusePL status bits : Decryptor disabled \n\r");
|
||
}else {
|
||
xil_printf("EfusePL status bits : Decryptor enabled\n\r");
|
||
}
|
||
|
||
}
|
||
|
||
/*
|
||
* Read Efuse PL key
|
||
*/
|
||
PlStatus = XilSKey_EfusePl_ReadKey(&PlInstancePtr);
|
||
if( PlStatus != XST_SUCCESS) {
|
||
xil_printf("PL efuse key read failed\r\n");
|
||
goto EFUSE_ERROR;
|
||
}
|
||
#ifdef XSK_ARM_PLATFORM
|
||
/*
|
||
* Print Efuse PL key
|
||
*/
|
||
xil_printf("EfusePL User key : 0x");
|
||
for(KeyCnt = 3; KeyCnt >= 0; KeyCnt--)
|
||
{
|
||
xil_printf("%02x", PlInstancePtr.UserKeyReadback[KeyCnt]);
|
||
}
|
||
xil_printf("\n\r");
|
||
|
||
xil_printf("EfusePL AES key : 0x");
|
||
for(KeyCnt = 31; KeyCnt >= 0; KeyCnt--)
|
||
{
|
||
xil_printf("%02x", PlInstancePtr.AESKeyReadback[KeyCnt]);
|
||
}
|
||
xil_printf("\n\r");
|
||
#else
|
||
|
||
if (XSK_EFUSEPL_CHECK_AES_KEY_CRC == TRUE){
|
||
if (PlInstancePtr.AESKeyMatched == TRUE) {
|
||
xil_printf("AES key matched with expected AES Key's CRC\n\r");
|
||
}
|
||
else {
|
||
xil_printf("AES key not matched with expected AES's CRC "
|
||
"Please provide key's valid CRC \n\r");
|
||
}
|
||
}
|
||
if (XSK_EFUSEPL_READ_USER_KEY == TRUE) {
|
||
xil_printf("\r\nEfusePL User key : 0x");
|
||
for(KeyCnt = (XSK_EFUSEPL_USER_KEY_SIZE_IN_BYTES - 1); KeyCnt >= 0; KeyCnt--) {
|
||
xil_printf("%02x", PlInstancePtr.UserKeyReadback[KeyCnt]);
|
||
}
|
||
}
|
||
xil_printf("\r\n");
|
||
if (XSK_EFUSEPL_READ_RSA_KEY_HASH == TRUE) {
|
||
xil_printf("\r\nEfusePL RSA hash value : 0x");
|
||
for(KeyCnt = (XSK_EFUSEPL_RSA_KEY_HASH_SIZE_IN_BYTES - 1); KeyCnt >= 0; KeyCnt--) {
|
||
xil_printf("%02x", PlInstancePtr.RSAHashReadback[KeyCnt]);
|
||
}
|
||
}
|
||
xil_printf("\r\n");
|
||
#endif
|
||
|
||
|
||
#endif /*XSK_EFUSEPL_DRIVER*/
|
||
|
||
EFUSE_ERROR:
|
||
/**
|
||
* Write the error returned in the Reboot Status Register
|
||
* Eg: If the reboot status register value is 0xYYYYZZZZ
|
||
* then
|
||
* - YYYY Represents the PS eFUSE Status.
|
||
* - ZZZZ Represents the PL eFUSE Status.
|
||
*
|
||
* - Value 0x0000ZZZZ
|
||
* represents PS eFUSE is successful & PL eFUSE process
|
||
* returned with error.
|
||
* - Value 0xYYYY0000
|
||
* represents PL eFUSE is successful & PS eFUSE process
|
||
* returned with error.
|
||
* - Value 0xFFFF0000
|
||
* represents PS eFUSE is not initiated & PL eFUSE is successful.
|
||
* - Value 0x0000FFFF
|
||
* represents PL eFUSE is not initiated & PS eFUSE is successful.
|
||
* - Value 0xFFFFZZZZ
|
||
* represents PS eFUSE is not initiated & PL eFUSE is process
|
||
* returned with error.
|
||
* - Value 0xYYYYFFFF
|
||
* represents PL eFUSE is not initiated & PS eFUSE is process
|
||
* returned with error.
|
||
*/
|
||
Status = ((PsStatus << 16) + PlStatus);
|
||
|
||
xil_printf("\r\neFUSE operations exit status: %08X\r\n", Status);
|
||
#ifdef XSK_ARM_PLATFORM
|
||
/**
|
||
* Writing the Exit Status to Reboot Status Register
|
||
*/
|
||
Xil_Out32(REBOOT_STATUS_REG_ADDR,Status);
|
||
#endif
|
||
while(1);
|
||
return 0;
|
||
}
|
||
|
||
|
||
#ifdef XSK_EFUSEPS_DRIVER
|
||
/****************************************************************************/
|
||
/**
|
||
*
|
||
*
|
||
* Helper functions to properly initialize the PS eFUSE structure instance
|
||
*
|
||
*
|
||
* @param PsInstancePtr - Structure Address to update the structure elements
|
||
*
|
||
* @return
|
||
*
|
||
* - XST_SUCCESS - In case of Success
|
||
* - XST_FAILURE - If initialization fails
|
||
*
|
||
* @note
|
||
*
|
||
*****************************************************************************/
|
||
|
||
u32 XilSKey_EfusePs_InitData(XilSKey_EPs *PsInstancePtr)
|
||
{
|
||
u32 PsStatus;
|
||
|
||
PsStatus = XST_SUCCESS;
|
||
|
||
/**
|
||
* Copy the xilskeyinput.h values into PS structure elements
|
||
*/
|
||
PsInstancePtr->EnableWriteProtect = XSK_EFUSEPS_ENABLE_WRITE_PROTECT;
|
||
PsInstancePtr->EnableRsaAuth = XSK_EFUSEPS_ENABLE_RSA_AUTH;
|
||
PsInstancePtr->EnableRom128Crc = XSK_EFUSEPS_ENABLE_ROM_128K_CRC;
|
||
PsInstancePtr->EnableRsaKeyHash = XSK_EFUSEPS_ENABLE_RSA_KEY_HASH;
|
||
PsInstancePtr->DisableDftJtag = XSK_EFUSEPS_DISABLE_DFT_JTAG;
|
||
PsInstancePtr->DisableDftMode = XSK_EFUSEPS_DISABLE_DFT_MODE;
|
||
|
||
if (PsInstancePtr->EnableRsaKeyHash == TRUE) {
|
||
/**
|
||
* Validation of RSA Hash
|
||
*/
|
||
PsStatus = XilSKey_Efuse_ValidateKey(
|
||
(char *)XSK_EFUSEPS_RSA_KEY_HASH_VALUE,
|
||
XSK_EFUSEPS_RSA_KEY_HASH_STRING_SIZE);
|
||
if(PsStatus != XST_SUCCESS) {
|
||
return PsStatus;
|
||
}
|
||
|
||
/**
|
||
* Convert the input RSA Key Hash string into Hex buffer
|
||
*/
|
||
PsStatus = XilSKey_Efuse_ConvertStringToHexBE(
|
||
XSK_EFUSEPS_RSA_KEY_HASH_VALUE,
|
||
&(PsInstancePtr->RsaKeyHashValue[0]), 64);
|
||
if(PsStatus != XST_SUCCESS) {
|
||
return PsStatus;
|
||
}
|
||
}
|
||
return PsStatus;
|
||
}
|
||
#endif /* XSK_EFUSEPS_DRIVER*/
|
||
|
||
|
||
#ifdef XSK_EFUSEPL_DRIVER
|
||
/****************************************************************************/
|
||
/**
|
||
*
|
||
*
|
||
* Helper functions to properly initialize the PL eFUSE structure instance
|
||
*
|
||
*
|
||
* @param PlInstancePtr - Structure Address to update the structure elements
|
||
*
|
||
* @return
|
||
*
|
||
* - XST_SUCCESS - In case of Success
|
||
* - XST_FAILURE - If initialization fails
|
||
*
|
||
* @note
|
||
*
|
||
*****************************************************************************/
|
||
|
||
u32 XilSKey_EfusePl_InitData(XilSKey_EPl *PlInstancePtr)
|
||
{
|
||
|
||
u32 PlStatus;
|
||
|
||
PlStatus = XST_SUCCESS;
|
||
|
||
|
||
/**
|
||
* Copy the xilskeyinput.h values into PL eFUSE structure elements
|
||
*/
|
||
/* For Zynq PL efuse */
|
||
/**
|
||
* Assign FUSE CNTRL bits[1:5] to the PL eFUSE structure elements.
|
||
*/
|
||
#ifdef XSK_ARM_PLATFORM
|
||
/* Assign FUSE CNTRL bits[1:5] to the PL eFUSE structure elements.*/
|
||
|
||
PlInstancePtr->ForcePowerCycle = XSK_EFUSEPL_FORCE_PCYCLE_RECONFIG;
|
||
PlInstancePtr->KeyWrite = XSK_EFUSEPL_DISABLE_KEY_WRITE;
|
||
PlInstancePtr->AESKeyRead = XSK_EFUSEPL_DISABLE_AES_KEY_READ;
|
||
PlInstancePtr->UserKeyRead = XSK_EFUSEPL_DISABLE_USER_KEY_READ;
|
||
PlInstancePtr->CtrlWrite = XSK_EFUSEPL_DISABLE_FUSE_CNTRL_WRITE;
|
||
/**
|
||
* Assign the FUSE CNTRL bits[8:10] into the PL eFUSE structure elements
|
||
*/
|
||
PlInstancePtr->UseAESOnly = XSK_EFUSEPL_FORCE_USE_AES_ONLY;
|
||
PlInstancePtr->JtagDisable = XSK_EFUSEPL_DISABLE_JTAG_CHAIN;
|
||
PlInstancePtr->AESKeyExclusive = XSK_EFUSEPL_BBRAM_KEY_DISABLE;
|
||
|
||
PlInstancePtr->JtagMioTDI = XSK_EFUSEPL_MIO_JTAG_TDI;
|
||
PlInstancePtr->JtagMioTDO = XSK_EFUSEPL_MIO_JTAG_TDO;
|
||
PlInstancePtr->JtagMioTCK = XSK_EFUSEPL_MIO_JTAG_TCK;
|
||
PlInstancePtr->JtagMioTMS = XSK_EFUSEPL_MIO_JTAG_TMS;
|
||
PlInstancePtr->JtagMioMuxSel = XSK_EFUSEPL_MIO_JTAG_MUX_SELECT;
|
||
PlInstancePtr->JtagMuxSelLineDefVal = XSK_EFUSEPL_MIO_MUX_SEL_DEFAULT_VAL;
|
||
|
||
/*
|
||
* Variable to check whether internal system initialization is done.
|
||
*/
|
||
PlInstancePtr->SystemInitDone = 0;
|
||
|
||
/**
|
||
* Assign the user selection for AES & USER Low Key (or)
|
||
* User High Key (or) both
|
||
*/
|
||
PlInstancePtr->ProgAESandUserLowKey =
|
||
XSK_EFUSEPL_PROGRAM_AES_AND_USER_LOW_KEY;
|
||
PlInstancePtr->ProgUserHighKey = XSK_EFUSEPL_PROGRAM_USER_HIGH_KEY;
|
||
|
||
if (PlInstancePtr->ProgAESandUserLowKey == TRUE) {
|
||
/**
|
||
* Validation of AES Key
|
||
*/
|
||
PlStatus = XilSKey_Efuse_ValidateKey((char *)XSK_EFUSEPL_AES_KEY,
|
||
XSK_EFUSEPL_AES_KEY_STRING_SIZE);
|
||
if(PlStatus != XST_SUCCESS) {
|
||
goto PL_INIT_ERROR;
|
||
}
|
||
/**
|
||
* Validation of User Low Key
|
||
*/
|
||
PlStatus = XilSKey_Efuse_ValidateKey((char *)XSK_EFUSEPL_USER_LOW_KEY,
|
||
XSK_EFUSEPL_USER_LOW_KEY_STRING_SIZE);
|
||
if(PlStatus != XST_SUCCESS) {
|
||
goto PL_INIT_ERROR;
|
||
}
|
||
|
||
/**
|
||
* Assign the AES Key Value
|
||
*/
|
||
XilSKey_Efuse_ConvertStringToHexLE((char *)XSK_EFUSEPL_AES_KEY ,
|
||
&PlInstancePtr->AESKey[0],
|
||
XSK_EFUSEPL_AES_KEY_SIZE_IN_BITS);
|
||
|
||
/**
|
||
* Assign the User Low key [7:0] bits
|
||
*/
|
||
XilSKey_Efuse_ConvertStringToHexLE((char *)XSK_EFUSEPL_USER_LOW_KEY ,
|
||
&PlInstancePtr->UserKey[0],
|
||
XSK_EFUSEPL_USER_LOW_KEY_SIZE_IN_BITS);
|
||
}
|
||
|
||
if (PlInstancePtr->ProgUserHighKey == TRUE) {
|
||
/**
|
||
* Validation of User High Key
|
||
*/
|
||
PlStatus = XilSKey_Efuse_ValidateKey(
|
||
(char *)XSK_EFUSEPL_USER_HIGH_KEY,
|
||
XSK_EFUSEPL_USER_HIGH_KEY_STRING_SIZE);
|
||
if(PlStatus != XST_SUCCESS) {
|
||
goto PL_INIT_ERROR;
|
||
}
|
||
/**
|
||
* Assign the User High key [31:8] bits
|
||
*/
|
||
XilSKey_Efuse_ConvertStringToHexLE((char *)XSK_EFUSEPL_USER_HIGH_KEY ,
|
||
&PlInstancePtr->UserKey[1],
|
||
XSK_EFUSEPL_USER_HIGH_KEY_SIZE_IN_BITS);
|
||
}
|
||
|
||
#else
|
||
/* For Ultrascle efuse */
|
||
/* eFuse control bits [2:0] */
|
||
PlInstancePtr->AESKeyRead= XSK_EFUSEPL_DISABLE_AES_KEY_READ;
|
||
PlInstancePtr->UserKeyRead = XSK_EFUSEPL_DISABLE_USER_KEY_READ;
|
||
PlInstancePtr->SecureRead = XSK_EFUSEPL_DISABLE_SECURE_READ;
|
||
/* eFuse Control bits [9:5] */
|
||
PlInstancePtr->CtrlWrite = XSK_EFUSEPL_DISABLE_FUSE_CNTRL_WRITE;
|
||
PlInstancePtr->RSARead = XSK_EFUSEPL_DISABLE_RSA_KEY_READ;
|
||
PlInstancePtr->KeyWrite = XSK_EFUSEPL_DISABLE_KEY_WRITE;
|
||
PlInstancePtr->UserKeyWrite = XSK_EFUSEPL_DISABLE_USER_KEY_WRITE;
|
||
PlInstancePtr->SecureWrite = XSK_EFUSEPL_DISABLE_SECURE_WRITE;
|
||
/* eFuse control bit 15 */
|
||
PlInstancePtr->RSAWrite = XSK_EFUSEPL_DISABLE_RSA_HASH_WRITE;
|
||
|
||
/* eFuse secure bits [5:0] */
|
||
PlInstancePtr->EncryptOnly = XSK_EFUSEPL_ALLOW_ENCRYPTED_ONLY;
|
||
PlInstancePtr->UseAESOnly = XSK_EFUSEPL_FORCE_USE_FUSE_AES_ONLY;
|
||
PlInstancePtr->RSAEnable = XSK_EFUSEPL_ENABLE_RSA_AUTH;
|
||
PlInstancePtr->JtagDisable = XSK_EFUSEPL_DISABLE_JTAG_CHAIN;
|
||
PlInstancePtr->IntTestAccessDisable = XSK_EFUSEPL_DISABLE_TEST_ACCESS;
|
||
PlInstancePtr->DecoderDisable = XSK_EFUSEPL_DISABLE_DECODER;
|
||
|
||
|
||
PlInstancePtr->ProgAESKeyUltra = XSK_EFUSEPL_PROGRAM_AES_KEY;
|
||
PlInstancePtr->ProgUserKeyUltra = XSK_EFUSEPL_PROGRAM_USER_KEY;
|
||
PlInstancePtr->ProgRSAKeyUltra = XSK_EFUSEPL_PROGRAM_RSA_KEY_HASH;
|
||
|
||
PlInstancePtr->ReadUserKeyUltra = XSK_EFUSEPL_READ_USER_KEY;
|
||
PlInstancePtr->ReadRSAKeyUltra = XSK_EFUSEPL_READ_RSA_KEY_HASH;
|
||
PlInstancePtr->CheckAESKeyUltra = XSK_EFUSEPL_CHECK_AES_KEY_CRC;
|
||
|
||
PlInstancePtr->CrcOfAESKey = XSK_EFUSEPL_CRC_OF_EXPECTED_AES_KEY;
|
||
|
||
PlInstancePtr->JtagGpioTDI = XSK_EFUSEPL_AXI_GPIO_JTAG_TDI;
|
||
PlInstancePtr->JtagGpioTMS = XSK_EFUSEPL_AXI_GPIO_JTAG_TMS;
|
||
PlInstancePtr->JtagGpioTCK = XSK_EFUSEPL_AXI_GPIO_JTAG_TCK;
|
||
PlInstancePtr->JtagGpioTDO = XSK_EFUSEPL_AXI_GPIO_JTAG_TDO;
|
||
PlInstancePtr->GpioInputCh = XSK_EFUSEPL_GPIO_INPUT_CH;
|
||
PlInstancePtr->GpioOutPutCh = XSK_EFUSEPL_GPIO_OUTPUT_CH;
|
||
|
||
if (PlInstancePtr->ProgUserKeyUltra == TRUE) {
|
||
/* Validation of User High Key */
|
||
PlStatus = XilSKey_Efuse_ValidateKey(
|
||
(char *)XSK_EFUSEPL_USER_KEY,
|
||
XSK_EFUSEPL_USER_KEY_STRING_SIZE);
|
||
if(PlStatus != XST_SUCCESS) {
|
||
goto PL_INIT_ERROR;
|
||
}
|
||
/* Assign the User key [31:0]bits */
|
||
XilSKey_Efuse_ConvertStringToHexLE(
|
||
(char *)XSK_EFUSEPL_USER_KEY ,
|
||
&PlInstancePtr->UserKey[0],
|
||
XSK_EFUSEPL_USER_KEY_SIZE_IN_BITS);
|
||
}
|
||
if (PlInstancePtr->ProgAESKeyUltra == TRUE) {
|
||
/* Validation of AES Key */
|
||
PlStatus = XilSKey_Efuse_ValidateKey(
|
||
(char *)XSK_EFUSEPL_AES_KEY,
|
||
XSK_EFUSEPL_AES_KEY_STRING_SIZE);
|
||
if(PlStatus != XST_SUCCESS) {
|
||
goto PL_INIT_ERROR;
|
||
}
|
||
/* Assign the AES Key Value */
|
||
XilSKey_Efuse_ConvertStringToHexLE(
|
||
(char *)XSK_EFUSEPL_AES_KEY,
|
||
&PlInstancePtr->AESKey[0],
|
||
XSK_EFUSEPL_AES_KEY_SIZE_IN_BITS);
|
||
}
|
||
|
||
if (PlInstancePtr->ProgRSAKeyUltra == TRUE) {
|
||
/* Validation of RSA hash */
|
||
PlStatus = XilSKey_Efuse_ValidateKey(
|
||
(char *)XSK_EFUSEPL_RSA_KEY_HASH_VALUE,
|
||
XSK_EFUSEPL_RSA_KEY_HASH_STRING_SIZE);
|
||
if(PlStatus != XST_SUCCESS) {
|
||
goto PL_INIT_ERROR;
|
||
}
|
||
/* Assign the RSA hash */
|
||
XilSKey_Efuse_ConvertStringToHexLE(
|
||
(char *)XSK_EFUSEPL_RSA_KEY_HASH_VALUE,
|
||
&PlInstancePtr->RSAKeyHash[0],
|
||
XSK_EFUSEPL_RSA_KEY_SIZE_IN_BITS);
|
||
}
|
||
/* Variable to check whether internal system initialization is done.*/
|
||
PlInstancePtr->SystemInitDone = 0;
|
||
|
||
#endif
|
||
|
||
PL_INIT_ERROR:
|
||
return PlStatus;
|
||
}
|
||
|
||
#endif /*XSK_EFUSEPL_DRIVER*/
|