xillskey: Added new functions
As GpioPs and Timers are different for Ultrascale all the calls related to Gpio and timers are saperated by ifdefinitions. Added new jtag function to access efuse of Ultrascale. Signed-off-by: VNSL Durga <vnsldurg@xilinx.com> Reviewed-by: Harini Katakam <harinik@xilinx.com>
This commit is contained in:
parent
365de9549f
commit
0b14b181ba
7 changed files with 854 additions and 28 deletions
|
@ -50,13 +50,20 @@
|
|||
* Modified efuse PS macro
|
||||
* XSK_EFUSEPS_RSA_KEY_HASH_STRING_SIZE to
|
||||
* XSK_EFUSEPL_RSA_KEY_HASH_STRING_SIZE
|
||||
* Added efuse functionality for Ultrascale.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef XILSKEY_UTILS_H
|
||||
#define XILSKEY_UTILS_H
|
||||
/***************************** Include Files ********************************/
|
||||
#include "xparameters.h"
|
||||
#ifdef XPAR_XSK_MICROBLAZE_PLATFORM
|
||||
#include "xsysmon.h"
|
||||
#include "xtmrctr.h"
|
||||
#else
|
||||
#include "xadcps.h"
|
||||
#endif
|
||||
/************************** Constant Definitions ****************************/
|
||||
/**************************** Type Definitions ******************************/
|
||||
/***************** Macros (Inline Functions) Definitions ********************/
|
||||
|
@ -70,7 +77,31 @@
|
|||
* xparameters.h file. They are defined here such that a user can easily
|
||||
* change all the needed parameters in one place.
|
||||
*/
|
||||
#ifdef XSK_ARM_PLATFORM
|
||||
#define XADC_DEVICE_ID XPAR_XADCPS_0_DEVICE_ID
|
||||
#else
|
||||
#define XTMRCTR_DEVICE_ID (XPAR_TMRCTR_0_DEVICE_ID)
|
||||
#define XSK_EFUSEPL_CLCK_FREQ_ULTRA (XPAR_AXI_TIMER_0_CLOCK_FREQ_HZ)
|
||||
#define XSK_TMRCTR_NUM (0)
|
||||
#define XSK_GPIO_DEVICE_ID (XPAR_AXI_GPIO_0_DEVICE_ID)
|
||||
#endif
|
||||
|
||||
#define REVERSE_POLYNOMIAL (0x82F63B78)
|
||||
/**< Polynomial for calculating CRC */
|
||||
/** @name CSU_DMA pause types
|
||||
* @{
|
||||
*/
|
||||
typedef enum {
|
||||
XSK_FPGA_SERIES_ULTRA, /**< Ultrascale series */
|
||||
XSK_FPGA_SERIES_ZYNQ /**< Zynq series */
|
||||
}XSKEfusePl_Fpga;
|
||||
/*@}*/
|
||||
|
||||
/**
|
||||
* Row numbers of Sysmon
|
||||
*/
|
||||
#define XSK_SYSMON_TEMP_ROW (0) /**< Row for Temperature */
|
||||
#define XSK_SYSMON_VOL_ROW (2) /**< Row for Voltage */
|
||||
|
||||
/**
|
||||
* Temperature and voltage range for PS eFUSE reading and programming
|
||||
|
@ -82,7 +113,7 @@
|
|||
#define XSK_EFUSEPS_READ_VPAUX_MAX (1.98)
|
||||
#define XSK_EFUSEPS_WRITE_VPAUX_MIN (1.71)
|
||||
#define XSK_EFUSEPS_WRITE_VPAUX_MAX (1.98)
|
||||
|
||||
#ifdef XSK_ARM_PLATFORM
|
||||
/**
|
||||
* Converting the celsius temperature to equivalent Binary data for xAdc
|
||||
*/
|
||||
|
@ -96,7 +127,7 @@
|
|||
#define XSK_EFUSEPS_READ_VPAUX_MAX_RAW (XAdcPs_VoltageToRaw(XSK_EFUSEPS_READ_VPAUX_MAX))
|
||||
#define XSK_EFUSEPS_WRITE_VPAUX_MIN_RAW (XAdcPs_VoltageToRaw(XSK_EFUSEPS_WRITE_VPAUX_MIN))
|
||||
#define XSK_EFUSEPS_WRITE_VPAUX_MAX_RAW (XAdcPs_VoltageToRaw(XSK_EFUSEPS_WRITE_VPAUX_MAX))
|
||||
|
||||
#endif
|
||||
/**
|
||||
* Temperature and voltage range for PL eFUSE reading and programming
|
||||
* Temperature in Celsius('C) and Voltage(V) is in volts
|
||||
|
@ -125,11 +156,16 @@
|
|||
#define XSK_EFUSEPL_READ_VOLTAGE_VCCINT_MIN (.795)
|
||||
#define XSK_EFUSEPL_READ_VOLTAGE_VCCINT_MAX (1.1)
|
||||
|
||||
/* Ultrascale Microblaze Voltage range */
|
||||
#define XSK_EFUSEPL_VOL_VCCAUX_MIN_ULTRA (1.746)
|
||||
#define XSK_EFUSEPL_VOL_VCCAUX_MAX_ULTRA (1.854)
|
||||
#define XSK_EFUSEPL_TEMP_MIN_ULTRA (-40)
|
||||
#define XSK_EFUSEPL_TEMP_MAX_ULTRA (125)
|
||||
|
||||
/**
|
||||
* PL eFUSE write Min and Max Temperature and Voltages
|
||||
*/
|
||||
|
||||
#ifdef XSK_ARM_PLATFORM
|
||||
/**
|
||||
* Converting the celsius temperature to equivalent Binary data for xAdc
|
||||
*/
|
||||
|
@ -171,6 +207,17 @@
|
|||
#define XSK_EFUSEPL_READ_VOLTAGE_VCCINT_MIN_RAW (XAdcPs_VoltageToRaw(XSK_EFUSEPL_READ_VOLTAGE_VCCINT_MIN))
|
||||
#define XSK_EFUSEPL_READ_VOLTAGE_VCCINT_MAX_RAW (XAdcPs_VoltageToRaw(XSK_EFUSEPL_READ_VOLTAGE_VCCINT_MAX))
|
||||
|
||||
#else
|
||||
/**
|
||||
* Converting the voltage to equivalent Binary data for xAdc
|
||||
*/
|
||||
#define XSK_EFUSEPL_VOL_VCCAUX_MIN_RAW_ULTRA (XSysMon_VoltageToRaw(XSK_EFUSEPL_VOL_VCCAUX_MIN_ULTRA))
|
||||
#define XSK_EFUSEPL_VOL_VCCAUX_MAX_RAW_ULTRA (XSysMon_VoltageToRaw(XSK_EFUSEPL_VOL_VCCAUX_MAX_ULTRA))
|
||||
|
||||
#define XSK_EFUSEPL_TEMP_MIN_RAW_ULTRA (XSysMon_TemperatureToRaw(XSK_EFUSEPL_TEMP_MIN_ULTRA))
|
||||
#define XSK_EFUSEPL_TEMP_MAX_RAW_ULTRA (XSysMon_TemperatureToRaw(XSK_EFUSEPL_TEMP_MAX_ULTRA))
|
||||
|
||||
#endif
|
||||
/**
|
||||
* Different voltage types that can be read from xAdc
|
||||
*/
|
||||
|
@ -265,6 +312,11 @@
|
|||
* PS eFUSE RSA key Hash size in characters
|
||||
*/
|
||||
#define XSK_EFUSEPS_RSA_KEY_HASH_STRING_SIZE (64)
|
||||
/**
|
||||
* Ultrascale Efuse PL RSA Key size in Bytes
|
||||
*/
|
||||
#define XSK_EFUSEPL_RSA_KEY_HASH_SIZE_IN_BYTES (48)
|
||||
|
||||
/************************** Variable Definitions ****************************/
|
||||
/**
|
||||
* XADC Structure
|
||||
|
@ -342,7 +394,15 @@ typedef enum {
|
|||
XSK_EFUSEPL_ERROR_ZERO_KEY_LENGTH,
|
||||
XSK_EFUSEPL_ERROR_NOT_VALID_KEY_CHAR,
|
||||
XSK_EFUSEPL_ERROR_NULL_KEY,
|
||||
/**
|
||||
* SECURE KEY error codes
|
||||
*/
|
||||
XSK_EFUSEPL_ERROR_FUSE_SEC_WRITE_DISABLED,
|
||||
XSK_EFUSEPL_ERROR_FUSE_SEC_READ_DISABLED,
|
||||
XSK_EFUSEPL_ERROR_SEC_WRITE_BUFFER_NULL,
|
||||
|
||||
XSK_EFUSEPL_ERROR_READ_PAGE_OUT_OF_RANGE,
|
||||
XSK_EFUSEPL_ERROR_FUSE_ROW_RANGE,
|
||||
/**
|
||||
* XSKEfusepl_Program_Efuse() error codes
|
||||
*/
|
||||
|
@ -360,7 +420,13 @@ typedef enum {
|
|||
XSK_EFUSEPL_ERROR_PROGRAMMING_FUSE_DATA_ROW = 0x1A00,
|
||||
XSK_EFUSEPL_ERROR_PROGRAMMING_FUSE_CNTRL_ROW = 0x1B00,
|
||||
XSK_EFUSEPL_ERROR_XADC = 0x1C00,
|
||||
XSK_EFUSEPL_ERROR_INVALID_REF_CLK= 0x3000
|
||||
XSK_EFUSEPL_ERROR_INVALID_REF_CLK= 0x3000,
|
||||
XSK_EFUSEPL_ERROR_FUSE_SEC_WRITE_NOT_ALLOWED = 0x1D00,
|
||||
XSK_EFUSEPL_ERROR_READING_FUSE_STATUS = 0x1E00,
|
||||
XSK_EFUSEPL_ERROR_FUSE_BUSY = 0x1F00,
|
||||
XSK_EFUSEPL_ERROR_READING_FUSE_RSA_ROW = 0x2000,
|
||||
XSK_EFUSEPL_ERROR_TIMER_INTIALISE_ULTRA = 0x2200,
|
||||
XSK_EFUSEPL_ERROR_READING_FUSE_SEC = 0x2300
|
||||
}XSKEfusePl_ErrorCodes;
|
||||
|
||||
|
||||
|
@ -466,6 +532,9 @@ u32 XilSKey_Efuse_ConvertStringToHexLE(const char * Str, u8 * Buf, u32 Len);
|
|||
u32 XilSKey_Efuse_ConvertStringToHexBE(const char * Str, u8 * Buf, u32 Len);
|
||||
u32 XilSKey_Efuse_ValidateKey(const char *Key, u32 Len);
|
||||
u32 Xilskey_Timer_Intialise();
|
||||
u32 Xilskey_Efuse_ReverseHex(u32 Input);
|
||||
void Xilskey_StrCpyRange(u8 *Src, u8 *Dst, u32 From, u32 To);
|
||||
u32 Xilskey_CrcCalculation(u8 *Key);
|
||||
/***************************************************************************/
|
||||
|
||||
|
||||
|
|
|
@ -47,7 +47,7 @@
|
|||
* 2.00 hk 22/01/14 Corrected PL voltage checks to VCCINT and VCCAUX.
|
||||
* CR#768077
|
||||
* 2.1 kvn 04/01/15 Fixed warnings. CR#716453.
|
||||
*
|
||||
* 3.00 vns 31/07/15 Added efuse functionality for Ultrascale.
|
||||
*
|
||||
****************************************************************************/
|
||||
/***************************** Include Files *********************************/
|
||||
|
@ -138,6 +138,7 @@ typedef enum {
|
|||
u32 ErrorCode; /**< Global variable which holds the error key*/
|
||||
static u8 AesDataInBytes[XSK_EFUSEPL_ARRAY_FUSE_AES_KEY_SIZE];
|
||||
static u8 UserDataInBytes[XSK_EFUSEPL_ARRAY_FUSE_USER_KEY_SIZE];
|
||||
XSKEfusePl_Fpga PlFpgaFlag; /**< For Storing Fpga series */
|
||||
|
||||
/************************** Function Prototypes *****************************/
|
||||
/**
|
||||
|
@ -172,6 +173,11 @@ extern void JtagWrite(unsigned char row, unsigned char bit);
|
|||
* JTAG Server Read routine
|
||||
*/
|
||||
extern void JtagRead(unsigned char row, unsigned int * row_data, unsigned char marginOption);
|
||||
extern void JtagWrite_Ultrascale(u8 Row, u8 Bit, u8 Page, u8 Redundant);
|
||||
extern void JtagRead_Ultrascale(u8 Row, u32 *RowData, u8 MarginOption,
|
||||
u8 Page, u8 Redundant);
|
||||
extern void JtagRead_Status_Ultrascale(u32 *Rowdata);
|
||||
extern u32 JtagAES_Check_Ultrascale(u32 *Crc, u8 MarginOption);
|
||||
/***************************************************************************/
|
||||
/****************************************************************************/
|
||||
/**
|
||||
|
@ -249,7 +255,7 @@ u32 XilSKey_EfusePl_Program(XilSKey_EPl *InstancePtr)
|
|||
}
|
||||
|
||||
InstancePtr->SystemInitDone = 1;
|
||||
|
||||
PlFpgaFlag = InstancePtr->FpgaFlag;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -473,7 +479,7 @@ u8 XilSKey_EfusePl_IsVectorAllZeros(u8 *RowDataPtr)
|
|||
*****************************************************************************/
|
||||
u8 XilSKey_EfusePl_ProgramBit(u8 Row, u8 Bit)
|
||||
{
|
||||
XSKEfusePs_XAdc PL_XAdc;
|
||||
|
||||
/**
|
||||
*Check if the row position is valid.
|
||||
*/
|
||||
|
@ -526,6 +532,9 @@ u8 XilSKey_EfusePl_ProgramBit(u8 Row, u8 Bit)
|
|||
* Monitor the Voltage and temperature using XADC, if out of range return
|
||||
* unique error.
|
||||
*/
|
||||
#ifdef XSK_ARM_PLATFORM
|
||||
XSKEfusePs_XAdc PL_XAdc;
|
||||
|
||||
PL_XAdc.VType = XSK_EFUSEPS_VAUX;
|
||||
XilSKey_EfusePs_XAdcReadTemperatureAndVoltage(&PL_XAdc);
|
||||
if((PL_XAdc.Temp < XSK_EFUSEPL_WRITE_TEMP_MIN_RAW) ||
|
||||
|
@ -547,6 +556,7 @@ u8 XilSKey_EfusePl_ProgramBit(u8 Row, u8 Bit)
|
|||
ErrorCode = XSK_EFUSEPL_ERROR_WRITE_VCCINT_VOLTAGE_OUT_OF_RANGE;
|
||||
return XST_FAILURE;
|
||||
}
|
||||
#endif
|
||||
|
||||
JtagWrite(Row, Bit);
|
||||
return XST_SUCCESS;
|
||||
|
@ -866,6 +876,8 @@ u8 XilSKey_EfusePl_ReadRow(u32 Row, u8 MarginOption, u8 *RowDataBytes)
|
|||
* Monitor the Voltage and temperature using XADC, if out of range return
|
||||
* unique error.
|
||||
*/
|
||||
#ifdef XSK_ARM_PLATFORM
|
||||
XSKEfusePs_XAdc PL_XAdc;
|
||||
PL_XAdc.VType = XSK_EFUSEPS_VAUX;
|
||||
XilSKey_EfusePs_XAdcReadTemperatureAndVoltage(&PL_XAdc);
|
||||
if((PL_XAdc.Temp < XSK_EFUSEPL_READ_TEMP_MIN_RAW) ||
|
||||
|
@ -887,7 +899,7 @@ u8 XilSKey_EfusePl_ReadRow(u32 Row, u8 MarginOption, u8 *RowDataBytes)
|
|||
ErrorCode = XSK_EFUSEPL_ERROR_READ_VCCINT_VOLTAGE_OUT_OF_RANGE;
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
#endif
|
||||
/**
|
||||
* Here we have to use the impact algorithm to read the eFUSE row.
|
||||
* and return the data in row_data.
|
||||
|
@ -1122,9 +1134,10 @@ u32 XilSKey_EfusePl_ReadStatus(XilSKey_EPl *InstancePtr, u32 *StatusBits)
|
|||
}
|
||||
|
||||
InstancePtr->SystemInitDone = 1;
|
||||
|
||||
PlFpgaFlag = InstancePtr->FpgaFlag;
|
||||
}
|
||||
|
||||
#ifdef XSK_ARM_PLATFORM
|
||||
/**
|
||||
* Monitor the Voltage and temperature using XADC, if out of range return
|
||||
* unique error.
|
||||
|
@ -1156,6 +1169,7 @@ u32 XilSKey_EfusePl_ReadStatus(XilSKey_EPl *InstancePtr, u32 *StatusBits)
|
|||
JtagRead(0, &RowData, 0);
|
||||
|
||||
*StatusBits = RowData & 0xFFFFFF;
|
||||
#endif
|
||||
|
||||
return XST_SUCCESS;
|
||||
|
||||
|
@ -1185,7 +1199,6 @@ u32 XilSKey_EfusePl_ReadKey(XilSKey_EPl *InstancePtr)
|
|||
unsigned int RowData;
|
||||
u32 KeyCnt;
|
||||
u32 Status;
|
||||
XSKEfusePs_XAdc PL_XAdc;
|
||||
|
||||
if(NULL == InstancePtr) {
|
||||
return XSK_EFUSEPL_ERROR_PL_STRUCT_NULL;
|
||||
|
@ -1224,9 +1237,12 @@ u32 XilSKey_EfusePl_ReadKey(XilSKey_EPl *InstancePtr)
|
|||
}
|
||||
|
||||
InstancePtr->SystemInitDone = 1;
|
||||
PlFpgaFlag = InstancePtr->FpgaFlag;
|
||||
|
||||
}
|
||||
|
||||
#ifdef XSK_ARM_PLATFORM
|
||||
XSKEfusePs_XAdc PL_XAdc = {0};
|
||||
/**
|
||||
* Monitor the Voltage and temperature using XADC, if out of range return
|
||||
* unique error.
|
||||
|
@ -1252,7 +1268,7 @@ u32 XilSKey_EfusePl_ReadKey(XilSKey_EPl *InstancePtr)
|
|||
ErrorCode = XSK_EFUSEPL_ERROR_READ_VCCINT_VOLTAGE_OUT_OF_RANGE;
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
#endif
|
||||
/*
|
||||
* Read AES key and User Key and
|
||||
* store them in the variables in instance structure
|
||||
|
|
|
@ -510,6 +510,7 @@ XilSKey_EfusePs_WriteWithXadcCheckAndVerify(u32 EfuseAddress, u32 RefClk)
|
|||
/**
|
||||
* Check the temperature and voltage
|
||||
*/
|
||||
#ifdef XSK_ARM_PLATFORM
|
||||
if ((XAdcInstancePtr.Temp < XSK_EFUSEPS_TEMP_MIN_RAW) ||
|
||||
((XAdcInstancePtr.Temp > XSK_EFUSEPS_TEMP_MAX_RAW))) {
|
||||
return XSK_EFUSEPS_ERROR_WRITE_TEMPERATURE_OUT_OF_RANGE;
|
||||
|
@ -519,7 +520,7 @@ XilSKey_EfusePs_WriteWithXadcCheckAndVerify(u32 EfuseAddress, u32 RefClk)
|
|||
((XAdcInstancePtr.V > XSK_EFUSEPS_WRITE_VPAUX_MAX_RAW))) {
|
||||
return XSK_EFUSEPS_ERROR_WRITE_VCCPAUX_VOLTAGE_OUT_OF_RANGE;
|
||||
}
|
||||
|
||||
#endif
|
||||
/**
|
||||
* Write the eFUSE bit
|
||||
*/
|
||||
|
@ -780,6 +781,7 @@ XilSKey_EfusePs_ReadWithXadcCheck(u32 EfuseAddress, u32 RefClk, u8 *Data)
|
|||
/**
|
||||
* Check the temperature and voltage
|
||||
*/
|
||||
#ifdef XSK_ARM_PLATFORM
|
||||
if ((XAdcInstancePtr.Temp < XSK_EFUSEPS_TEMP_MIN_RAW) ||
|
||||
((XAdcInstancePtr.Temp > XSK_EFUSEPS_TEMP_MAX_RAW))) {
|
||||
return XSK_EFUSEPS_ERROR_READ_TMEPERATURE_OUT_OF_RANGE;
|
||||
|
@ -789,7 +791,7 @@ XilSKey_EfusePs_ReadWithXadcCheck(u32 EfuseAddress, u32 RefClk, u8 *Data)
|
|||
((XAdcInstancePtr.V > XSK_EFUSEPS_READ_VPAUX_MAX_RAW))) {
|
||||
return XSK_EFUSEPS_ERROR_READ_VCCPAUX_VOLTAGE_OUT_OF_RANGE;
|
||||
}
|
||||
|
||||
#endif
|
||||
/**
|
||||
* Read the eFUSE bit
|
||||
*/
|
||||
|
@ -833,6 +835,7 @@ static u32 XilSKey_EfusePs_VerifyWithXadcCheck(u32 EfuseAddress, u32 RefClk)
|
|||
/**
|
||||
* Check the temperature and voltage
|
||||
*/
|
||||
#ifdef XSK_ARM_PLATFORM
|
||||
if ((XAdcInstancePtr.Temp < XSK_EFUSEPS_TEMP_MIN_RAW) ||
|
||||
((XAdcInstancePtr.Temp > XSK_EFUSEPS_TEMP_MAX_RAW))) {
|
||||
return XSK_EFUSEPS_ERROR_READ_TMEPERATURE_OUT_OF_RANGE;
|
||||
|
@ -842,7 +845,7 @@ static u32 XilSKey_EfusePs_VerifyWithXadcCheck(u32 EfuseAddress, u32 RefClk)
|
|||
((XAdcInstancePtr.V > XSK_EFUSEPS_READ_VPAUX_MAX_RAW))) {
|
||||
return XSK_EFUSEPS_ERROR_READ_VCCPAUX_VOLTAGE_OUT_OF_RANGE;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Read the eFUSE bit in Margin_1 mode
|
||||
|
|
|
@ -50,6 +50,8 @@
|
|||
* void Bbram_DeInit(void)
|
||||
* 2.1 kvn 04/01/15 Fixed warnings. CR#716453.
|
||||
*
|
||||
* 3.00 vns 31/07/15 Added efuse functionality for Ultrascale.
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
*
|
||||
|
@ -73,7 +75,12 @@ typedef long ssize_t;
|
|||
#include "xilskey_utils.h"
|
||||
#include "xilskey_jslib.h"
|
||||
#include "xilskey_jscmd.h"
|
||||
#ifdef XSK_MICROBLAZE_PLATFORM
|
||||
#include "xgpio.h"
|
||||
#else
|
||||
#include "xgpiops.h"
|
||||
#endif
|
||||
|
||||
#include "xilskey_bbram.h"
|
||||
|
||||
//#define DEBUG_PRINT
|
||||
|
@ -88,6 +95,7 @@ void dummy_printf(const char *ctrl1, ...);
|
|||
#define DEFAULT_FREQUENCY 10000000
|
||||
#define MAX_FREQUENCY 30000000
|
||||
#define ZYNQ_DAP_ID 0x4ba00477
|
||||
#define ULTRA_MB_DAP_ID 0x13822093 /**< Ultrascale microblaze TAP ID */
|
||||
|
||||
#define set_last_error(JS, ...) js_set_last_error(&(JS)->js.base, __VA_ARGS__)
|
||||
|
||||
|
@ -99,6 +107,8 @@ static js_port_t *g_port = NULL;
|
|||
static js_server_t *g_js = NULL;
|
||||
static js_port_descr_t *g_useport = NULL;
|
||||
extern u32 TimerTicksfor100ns;
|
||||
extern u32 TimerTicksfor500ns;
|
||||
u32 GpoOutValue = 0;
|
||||
|
||||
void dummy_printf(const char *ctrl1, ...)
|
||||
{
|
||||
|
@ -153,8 +163,11 @@ struct js_port_impl_struct {
|
|||
};
|
||||
|
||||
|
||||
|
||||
#ifdef XSK_ARM_PLATFORM
|
||||
static XGpioPs structXGpioPs;
|
||||
#else
|
||||
static XGpio structXGpio;
|
||||
#endif
|
||||
|
||||
int setPin (int pin, int value);
|
||||
int readPin (int pin);
|
||||
|
@ -169,6 +182,7 @@ void GpioConfig(unsigned long addr, unsigned long mask, unsigned long val)
|
|||
|
||||
void JtagInitGpio ()
|
||||
{
|
||||
#ifdef XSK_ARM_PLATFORM
|
||||
js_printf("===== Initializing PS GPIO pins...\n\r");
|
||||
XGpioPs_Config *ptrConfigPtrPs = XGpioPs_LookupConfig(0);
|
||||
XGpioPs_CfgInitialize(&structXGpioPs,ptrConfigPtrPs,ptrConfigPtrPs->BaseAddr);
|
||||
|
@ -197,6 +211,41 @@ void JtagInitGpio ()
|
|||
|
||||
XGpioPs_SetDirectionPin(&structXGpioPs,MIO_TDO,0);
|
||||
XGpioPs_SetOutputEnablePin(&structXGpioPs,MIO_TDO,0);
|
||||
#else
|
||||
u32 DataDirection;
|
||||
|
||||
js_printf("===== Initializing PL GPIO pins...\n\r");
|
||||
XGpio_Config *ptrConfigPtr = XGpio_LookupConfig(XSK_GPIO_DEVICE_ID);
|
||||
XGpio_CfgInitialize(&structXGpio, ptrConfigPtr,
|
||||
ptrConfigPtr->BaseAddress);
|
||||
|
||||
/* Setting Data direction for GPIO pins */
|
||||
if (GpioInPutCh == GpioOutPutCh) {
|
||||
DataDirection = XGpio_GetDataDirection(&structXGpio,
|
||||
GpioInPutCh);
|
||||
DataDirection = DataDirection & (~((1 << GPIO_TDI) |
|
||||
(1 << GPIO_TCK) | (GPIO_TMS)));
|
||||
DataDirection = DataDirection | (1 << GPIO_TDO);
|
||||
XGpio_SetDataDirection(&structXGpio, GpioInPutCh,
|
||||
DataDirection);
|
||||
}
|
||||
else {
|
||||
DataDirection = XGpio_GetDataDirection(&structXGpio,
|
||||
GpioOutPutCh);
|
||||
DataDirection = DataDirection & (~((1 << GPIO_TDI) |
|
||||
(1 << GPIO_TCK) | (GPIO_TMS)));
|
||||
XGpio_SetDataDirection(&structXGpio, GpioOutPutCh,
|
||||
DataDirection);
|
||||
|
||||
DataDirection = XGpio_GetDataDirection(&structXGpio,
|
||||
GpioInPutCh);
|
||||
DataDirection = DataDirection | (1 << GPIO_TDO);
|
||||
XGpio_SetDataDirection(&structXGpio, GpioInPutCh,
|
||||
DataDirection);
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
} /* initGpio() */
|
||||
|
||||
int getByteCountFromBitCount (int bitCount)
|
||||
|
@ -544,13 +593,28 @@ void navigateTAP (unsigned char startState, unsigned char endState)
|
|||
int setPin (int pin, int value)
|
||||
{
|
||||
int status = 1;
|
||||
#ifdef XSK_ARM_PLATFORM
|
||||
XGpioPs_WritePin(&structXGpioPs, pin, value);
|
||||
#else
|
||||
u32 Mask = (1 << pin);
|
||||
u32 GpoOut = (value) ? (0xFFFFFFFF) : (0x0);
|
||||
|
||||
GpoOutValue = (GpoOutValue & (~Mask)) | (GpoOut & Mask);
|
||||
XGpio_DiscreteWrite(&structXGpio, GpioOutPutCh, GpoOutValue);
|
||||
#endif
|
||||
|
||||
return (status);
|
||||
}
|
||||
|
||||
int readPin (int pin)
|
||||
{
|
||||
#ifdef XSK_ARM_PLATFORM
|
||||
int retVal = XGpioPs_ReadPin(&structXGpioPs, pin);
|
||||
#else
|
||||
int retVal = XGpio_DiscreteRead(&structXGpio, GpioInPutCh);
|
||||
retVal = retVal ? 1: 0;
|
||||
#endif
|
||||
|
||||
return (retVal);
|
||||
}
|
||||
|
||||
|
@ -1099,6 +1163,7 @@ void JtagRead(unsigned char row, unsigned int * row_data, unsigned char marginOp
|
|||
}
|
||||
int JtagValidateMioPins(void)
|
||||
{
|
||||
#ifdef XSK_ARM_PLATFORM
|
||||
/*
|
||||
* Make sure that each every MIO pin defined is valid
|
||||
*/
|
||||
|
@ -1138,6 +1203,64 @@ int JtagValidateMioPins(void)
|
|||
|
||||
if(g_mio_jtag_tms == g_mio_jtag_mux_sel)
|
||||
return 1;
|
||||
#else
|
||||
/*
|
||||
* Make sure that each every AXI GPIO pin defined is valid
|
||||
*/
|
||||
if (GpioPinMasterJtagTDI > 31) {
|
||||
return 1;
|
||||
}
|
||||
if (GpioPinMasterJtagTDO > 31) {
|
||||
return 1;
|
||||
}
|
||||
if (GpioPinMasterJtagTMS > 31) {
|
||||
return 1;
|
||||
}
|
||||
if (GpioPinMasterJtagTCK > 31) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Make sure that provided channel numbers of GPIO is valid
|
||||
*/
|
||||
if ((GpioInPutCh < XSK_EFUSEPL_GPIO_CH1) ||
|
||||
(GpioInPutCh > XSK_EFUSEPL_GPIO_CH2)) {
|
||||
return 1;
|
||||
}
|
||||
if ((GpioOutPutCh < XSK_EFUSEPL_GPIO_CH1) ||
|
||||
(GpioOutPutCh > XSK_EFUSEPL_GPIO_CH2)) {
|
||||
return 1;
|
||||
}
|
||||
/*
|
||||
* Make sure that GPIO pins defined for JTAG operation are
|
||||
* unique among themselves
|
||||
*/
|
||||
/* If both input and output channels is same */
|
||||
if (GpioInPutCh == GpioOutPutCh) {
|
||||
if((GpioPinMasterJtagTDI == GpioPinMasterJtagTDO)||
|
||||
(GpioPinMasterJtagTDI == GpioPinMasterJtagTMS)||
|
||||
(GpioPinMasterJtagTDI == GpioPinMasterJtagTCK)) {
|
||||
return 1;
|
||||
}
|
||||
if((GpioPinMasterJtagTDO == GpioPinMasterJtagTMS)||
|
||||
(GpioPinMasterJtagTDO == GpioPinMasterJtagTCK)) {
|
||||
return 1;
|
||||
}
|
||||
if((GpioPinMasterJtagTMS == GpioPinMasterJtagTCK)) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if((GpioPinMasterJtagTDI == GpioPinMasterJtagTMS)||
|
||||
(GpioPinMasterJtagTDI == GpioPinMasterJtagTCK)) {
|
||||
return 1;
|
||||
}
|
||||
if((GpioPinMasterJtagTMS == GpioPinMasterJtagTCK)) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -1147,10 +1270,11 @@ int JtagServerInit(XilSKey_EPl *InstancePtr)
|
|||
int retval=0, i=0, num_taps=0, status=0;
|
||||
unsigned long *tap_codes = NULL;
|
||||
|
||||
g_mio_jtag_tdi = InstancePtr->JtagMioTDI;
|
||||
g_mio_jtag_tdo = InstancePtr->JtagMioTDO;
|
||||
g_mio_jtag_tck = InstancePtr->JtagMioTCK;
|
||||
g_mio_jtag_tms = InstancePtr->JtagMioTMS;
|
||||
#ifdef XSK_ARM_PLATFORM
|
||||
g_mio_jtag_tdi = InstancePtr->JtagMioTDI;
|
||||
g_mio_jtag_tdo = InstancePtr->JtagMioTDO;
|
||||
g_mio_jtag_tck = InstancePtr->JtagMioTCK;
|
||||
g_mio_jtag_tms = InstancePtr->JtagMioTMS;
|
||||
g_mio_jtag_mux_sel = InstancePtr->JtagMioMuxSel;
|
||||
g_mux_sel_def_val = InstancePtr->JtagMuxSelLineDefVal;
|
||||
|
||||
|
@ -1164,6 +1288,22 @@ int JtagServerInit(XilSKey_EPl *InstancePtr)
|
|||
{
|
||||
return 1;
|
||||
}
|
||||
#else
|
||||
GpioPinMasterJtagTDI = InstancePtr->JtagGpioTDI;
|
||||
GpioPinMasterJtagTDO = InstancePtr->JtagGpioTDO;
|
||||
GpioPinMasterJtagTMS = InstancePtr->JtagGpioTMS;
|
||||
GpioPinMasterJtagTCK = InstancePtr->JtagGpioTCK;
|
||||
|
||||
GpioInPutCh = InstancePtr->GpioInputCh;
|
||||
GpioOutPutCh = InstancePtr->GpioOutPutCh;
|
||||
|
||||
status = JtagValidateMioPins();
|
||||
if(status != 0)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
#endif
|
||||
JtagInitGpio();
|
||||
|
||||
g_js = js_init_zynq();
|
||||
|
@ -1199,6 +1339,11 @@ int JtagServerInit(XilSKey_EPl *InstancePtr)
|
|||
|
||||
for (i = 0; i < num_taps; i++) {
|
||||
if(tap_codes[i] == ZYNQ_DAP_ID){
|
||||
InstancePtr->FpgaFlag = XSK_FPGA_SERIES_ZYNQ;
|
||||
break;
|
||||
}
|
||||
if (tap_codes[i] == ULTRA_MB_DAP_ID) {
|
||||
InstancePtr->FpgaFlag = XSK_FPGA_SERIES_ULTRA;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -1813,4 +1958,412 @@ void Bbram_DeInit(void)
|
|||
|
||||
js_deinit_server(g_js);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* This function reads temperature and voltage of Ultrascale
|
||||
*
|
||||
* @param Row specifies the row number to read.
|
||||
* @param Row_Data is a pointer to a variable, to store the read value
|
||||
* of given row.
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
*****************************************************************************/
|
||||
void Jtag_Read_Sysmon(u8 Row, u32 *Row_Data)
|
||||
{
|
||||
|
||||
u8 WriteBuf[4];
|
||||
u8 ReadBuf[4];
|
||||
u8 *DataPtr = (u8 *)Row_Data;
|
||||
u32 TckCnt;
|
||||
jtag_navigate (g_port, JS_RESET);
|
||||
WriteBuf[0] = 0x37;
|
||||
|
||||
jtag_shift (g_port, ATOMIC_IR_SCAN, 6, WriteBuf,
|
||||
NULL, JS_IREXIT1);
|
||||
WriteBuf[3] = 0xC4;
|
||||
WriteBuf[2] = Row;
|
||||
WriteBuf[1] = 0x00;
|
||||
WriteBuf[0] = 0x00;
|
||||
|
||||
jtag_shift (g_port, ATOMIC_DR_SCAN, 32, WriteBuf,
|
||||
NULL, JS_IDLE);
|
||||
/*
|
||||
* Wait 12 TCK
|
||||
*/
|
||||
for(TckCnt = 0; TckCnt < 12; TckCnt++){
|
||||
setPin (MIO_TCK, 1);
|
||||
setPin (MIO_TCK, 0);
|
||||
}
|
||||
|
||||
jtag_shift (g_port, ATOMIC_DR_SCAN, 32, NULL,
|
||||
ReadBuf, JS_IDLE);
|
||||
|
||||
DataPtr[0] = ReadBuf[0];
|
||||
DataPtr[1] = ReadBuf[1];
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* This function blows the fuse of Ultrascale with provided parameters.
|
||||
*
|
||||
* @param Row specifies the row number of EFUSE to blow.
|
||||
* @param Bit Specifies the bit location in the given row.
|
||||
* @param Page tell the page of EFUSE in which the given row is located.
|
||||
* @param Redundant is a flag to specify the bit to be programmed is
|
||||
* Normal bit or Redundant bit.
|
||||
* - Redundant - XSK_EFUSEPL_REDUNDANT_ULTRA
|
||||
* - Normal - XSK_EFUSEPL_NORMAL_ULTRA
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
*****************************************************************************/
|
||||
void JtagWrite_Ultrascale(u8 Row, u8 Bit, u8 Page, u8 Redundant)
|
||||
{
|
||||
|
||||
u8 wrBuffer [8];
|
||||
u32 Bits = 0;
|
||||
|
||||
jtag_navigate (g_port, JS_RESET);
|
||||
|
||||
Bits = TAP_IR_LENGTH;
|
||||
wrBuffer [0] = 0x30; /* FUSE_CTS instruction */
|
||||
jtag_shift (g_port, ATOMIC_IR_SCAN, Bits, wrBuffer, NULL, JS_DRSELECT);
|
||||
|
||||
/* Prepare FUSE_CTS data */
|
||||
wrBuffer [0] = (((Bit & 0x1) << 7) | ((Row << 2)| 0x3));
|
||||
wrBuffer [1] = ((Bit >> 1) & 0xF) | ((0x20 << Redundant) | (Page << 4));
|
||||
wrBuffer [2] = 0x00;
|
||||
wrBuffer [3] = 0x00;
|
||||
/* Magic word */
|
||||
wrBuffer [4] = 0xAC;
|
||||
wrBuffer [5] = 0x28;
|
||||
wrBuffer [6] = 0xED;
|
||||
wrBuffer [7] = 0xFE;
|
||||
|
||||
Bits = 64; /* fuse_cts data length */
|
||||
|
||||
jtag_shift (g_port, ATOMIC_DR_SCAN, Bits, wrBuffer, NULL, JS_DRSELECT);
|
||||
|
||||
jtag_navigate (g_port, JS_DRCAPTURE);
|
||||
jtag_navigate (g_port, JS_DREXIT1);
|
||||
jtag_navigate (g_port, JS_DRUPDATE);
|
||||
|
||||
XilSKey_Efuse_StartTimer();
|
||||
jtag_navigate (g_port, JS_IDLE);
|
||||
|
||||
/* Here we will be providing 5micro seconds delay */
|
||||
if (XilSKey_Efuse_GetTime() < TimerTicksfor500ns) {
|
||||
while(1) {
|
||||
if(XilSKey_Efuse_IsTimerExpired(TimerTicksfor500ns) == 1) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
jtag_navigate (g_port, JS_DRSELECT);
|
||||
jtag_navigate (g_port, JS_IRSELECT);
|
||||
jtag_navigate (g_port, JS_RESET);
|
||||
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* This function reads entire row of Ultrascale's EFUSE.
|
||||
*
|
||||
* @param Row specifies the row number of EFUSE.
|
||||
* @param Bit Specifies the bit location in the given row.
|
||||
* @param MarginOption is a variable which tells the margin option in
|
||||
* which read operation to be performed.
|
||||
* @param Page tell the page of EFUSE in which the given row is located.
|
||||
* @param Redundant is a flag to specify the bit to be programmed is
|
||||
* Normal bit or Redundant bit.
|
||||
* - Redundant - XSK_EFUSEPL_REDUNDANT_ULTRA
|
||||
* - Normal - XSK_EFUSEPL_NORMAL_ULTRA
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note Method to read FUSE register in Direct Macro Access way.
|
||||
* Go to TLR to clear FUSE_CTS
|
||||
* Load FUSE_CTS instruction on IR
|
||||
* Step to CDR/SDR to shift in 32-bits FUSE_CTS command word
|
||||
* Shift in MAGIC_CTS_WRITE "FEED28AC" for ultrascale
|
||||
* Read 64 bit data in IR read state.
|
||||
*
|
||||
*****************************************************************************/
|
||||
void JtagRead_Ultrascale(u8 Row, u32 *RowData, u8 MarginOption,
|
||||
u8 Page, u8 Redundant)
|
||||
{
|
||||
|
||||
u8 WrBuffer [8];
|
||||
u8 RdBuffer [8];
|
||||
u32 Bits = 8;
|
||||
u8 *RowDataPtr = (u8 *)RowData;
|
||||
|
||||
jtag_navigate (g_port, JS_RESET);
|
||||
|
||||
/* Load FUSE_CTS instruction on IR */
|
||||
Bits = TAP_IR_LENGTH; /* IR length */
|
||||
WrBuffer [0] = 0x30; /* FUSE_CTS instruction */
|
||||
jtag_shift (g_port, ATOMIC_IR_SCAN, Bits, WrBuffer, NULL, JS_DRSELECT);
|
||||
|
||||
/*prepare FUSE_CTS data. */
|
||||
WrBuffer [0] = ((Row << 2)| 0x1); /* Select the row number */
|
||||
WrBuffer [1] = (0x20 << Redundant) | (Page << 4);
|
||||
/* Page and Redundant/normal bit selection */
|
||||
WrBuffer [2] = MarginOption;
|
||||
WrBuffer [3] = 0x00;
|
||||
/* Magic word. */
|
||||
WrBuffer [4] = 0xAC;
|
||||
WrBuffer [5] = 0x28;
|
||||
WrBuffer [6] = 0xED;
|
||||
WrBuffer [7] = 0xFE;
|
||||
|
||||
Bits = 64; /* Fuse_cts data length */
|
||||
jtag_shift (g_port, ATOMIC_DR_SCAN, Bits, WrBuffer, NULL, JS_IDLE);
|
||||
|
||||
jtag_shift (g_port, ATOMIC_DR_SCAN, Bits, NULL, RdBuffer, JS_IDLE);
|
||||
|
||||
/*
|
||||
* Captured macro word (32 Bits) is stored in [63:32] of
|
||||
* 64 bit buffer
|
||||
*/
|
||||
RowDataPtr[0] = RdBuffer[4];
|
||||
RowDataPtr[1] = RdBuffer[5];
|
||||
RowDataPtr[2] = RdBuffer[6];
|
||||
RowDataPtr[3] = RdBuffer[7];
|
||||
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* This function reads the status row of Ultrascale's EFUSE and updates the
|
||||
* pointer.
|
||||
*
|
||||
* @param Rowdata is a pointer to a 32 bit variable which stores the
|
||||
* status register value read from EFUSE status register.
|
||||
|
||||
* @return None.
|
||||
*
|
||||
* @note Method to read FUSE register in Direct Macro Access way.
|
||||
* For reading the status values we need send the bitstream
|
||||
* in shift DR state.
|
||||
* Shift in MAGIC_CTS_WRITE "FEED28AC" for ultrascale
|
||||
* Read 64 bit data in IR read state.
|
||||
*
|
||||
*****************************************************************************/
|
||||
void JtagRead_Status_Ultrascale(u32 *Rowdata)
|
||||
{
|
||||
u8 WrBuffer[32];
|
||||
u8 RdBuffer [4];
|
||||
u32 Bits = 8;
|
||||
u8 *RowDataPtr = (u8 *)Rowdata;
|
||||
|
||||
/* Go to TLR to clear FUSE_CTS */
|
||||
jtag_navigate (g_port, JS_RESET);
|
||||
|
||||
/* Load FUSE_CTS instruction on IR */
|
||||
Bits = TAP_IR_LENGTH; /* ir length */
|
||||
|
||||
WrBuffer [0] = 0x05; /* FUSE_CTS instruction */
|
||||
jtag_shift (g_port, ATOMIC_IR_SCAN, Bits, WrBuffer, NULL, JS_DRSELECT);
|
||||
|
||||
/* prepare Bit stream data */
|
||||
WrBuffer[0] = 0xff;
|
||||
WrBuffer[1] = 0xff;
|
||||
WrBuffer[2] = 0xff;
|
||||
WrBuffer[3] = 0xff;
|
||||
|
||||
WrBuffer[4] = 0x55;
|
||||
WrBuffer[5] = 0x99;
|
||||
WrBuffer[6] = 0xAA;
|
||||
WrBuffer[7] = 0x66;
|
||||
|
||||
WrBuffer[8] = 0x0c;
|
||||
WrBuffer[9] = 0x00;
|
||||
WrBuffer[10] = 0x01;
|
||||
WrBuffer[11] = 0x80;
|
||||
|
||||
WrBuffer[12] = 0x0c;
|
||||
WrBuffer[13] = 0x41;
|
||||
WrBuffer[14] = 0x04;
|
||||
WrBuffer[15] = 0xc9;
|
||||
|
||||
WrBuffer [16] = 0x04;
|
||||
WrBuffer [17] = 0x00;
|
||||
WrBuffer [18] = 0x00;
|
||||
WrBuffer [19] = 0x00;
|
||||
|
||||
WrBuffer [20] = 0x14;
|
||||
WrBuffer [21] = 0xc0;
|
||||
WrBuffer [22] = 0x05;
|
||||
WrBuffer [23] = 0x80;
|
||||
|
||||
WrBuffer [24] = 0x04;
|
||||
WrBuffer [25] = 0x00;
|
||||
WrBuffer [26] = 0x00;
|
||||
WrBuffer [27] = 0x00;
|
||||
|
||||
WrBuffer [28] = 0x04;
|
||||
WrBuffer [29] = 0x00;
|
||||
WrBuffer [30] = 0x00;
|
||||
WrBuffer [31] = 0x00;
|
||||
|
||||
Bits = 256;
|
||||
jtag_shift (g_port, ATOMIC_DR_SCAN, Bits, WrBuffer, NULL, JS_IDLE);
|
||||
|
||||
WrBuffer [0] = 0x04;
|
||||
Bits = 0x06;
|
||||
jtag_shift (g_port, ATOMIC_IR_SCAN, Bits, WrBuffer, NULL, JS_DRSELECT);
|
||||
|
||||
Bits = 32;
|
||||
jtag_shift (g_port, ATOMIC_DR_SCAN, Bits, NULL, RdBuffer, JS_IDLE);
|
||||
|
||||
RowDataPtr[0] = RdBuffer [0];
|
||||
RowDataPtr[1] = RdBuffer [1];
|
||||
RowDataPtr[2] = RdBuffer [2];
|
||||
RowDataPtr[3] = RdBuffer [3];
|
||||
|
||||
*(u32 *)RowDataPtr = Xilskey_Efuse_ReverseHex(*(u32 *)RowDataPtr);
|
||||
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* This function verifies the AES key of Ultrascale's EFUSE with provided CRC
|
||||
* value.
|
||||
*
|
||||
* @param Crc is a pointer to a 32 bit variable which holds the expected
|
||||
* AES key's CRC.
|
||||
* @param MarginOption is a variable which tells the margin option in
|
||||
* which read operation to be performed.
|
||||
*
|
||||
* @return Returns XST_FAILURE/XST_SUCCESS
|
||||
* - XST_SUCCESS - If CRC is correct
|
||||
* - XST_FAILURE - If CRC is wrong
|
||||
*
|
||||
* @note To verify AES key with provided CRC 256 bits need to be written
|
||||
* with all ZEROS and last 32 bits with CRC.
|
||||
* And then CTS word should be framed and read 9 rows.
|
||||
* The keys are stored in 8 rows (20 to 27) but in UltraScale
|
||||
* the device will read all 1s.
|
||||
* On the 9th read (row 28), the CRC computation takes
|
||||
* place. An extra read after the 9th read is required
|
||||
* to read the computed CRC out (can use last row addr
|
||||
* of 28 or row 0). The FPGA internally compares the
|
||||
* computed CRC with the expected CRC loaded through
|
||||
* the FUSE_KEY operation. If they match, then the expected CRC
|
||||
* is read. If not, the FPGA will return all 1s.
|
||||
*
|
||||
*****************************************************************************/
|
||||
u32 JtagAES_Check_Ultrascale(u32 *Crc, u8 MarginOption)
|
||||
{
|
||||
u8 WrBuffer [32];
|
||||
u8 RdBuffer [8];
|
||||
u32 Bits = 8;
|
||||
u8 *RowDataPtr = (u8 *)Crc;
|
||||
u32 Row;
|
||||
u32 Index;
|
||||
u8 WrBuf[8];
|
||||
|
||||
/* Go to TLR to clear FUSE_CTS */
|
||||
jtag_navigate (g_port, JS_RESET);
|
||||
|
||||
/* Load FUSE_CTS instruction on IR */
|
||||
Bits = TAP_IR_LENGTH; /* IR length */
|
||||
WrBuffer [0] = 0x30; /* FUSE_CTS instruction */
|
||||
jtag_shift (g_port, ATOMIC_IR_SCAN, Bits, WrBuffer, NULL, JS_DRSELECT);
|
||||
|
||||
/* Prepare FUSE_CTS data. */
|
||||
WrBuffer [0] = 0x00;
|
||||
WrBuffer [1] = 0x80;
|
||||
WrBuffer [2] = MarginOption;
|
||||
WrBuffer [3] = 0x01;
|
||||
/* Magic word. */
|
||||
WrBuffer [4] = 0xAC;
|
||||
WrBuffer [5] = 0x28;
|
||||
WrBuffer [6] = 0xED;
|
||||
WrBuffer [7] = 0xFE;
|
||||
|
||||
Bits = 64; /* fuse_cts data length */
|
||||
jtag_shift (g_port, ATOMIC_DR_SCAN, Bits, WrBuffer, NULL, JS_IDLE);
|
||||
|
||||
Bits = TAP_IR_LENGTH; /* Ir length */
|
||||
WrBuffer [0] = 0x31; /* CMD for FUSE Key */
|
||||
jtag_shift (g_port, ATOMIC_IR_SCAN, Bits, WrBuffer, NULL, JS_DRSELECT);
|
||||
|
||||
|
||||
WrBuffer[0] = RowDataPtr[0];
|
||||
WrBuffer[1] = RowDataPtr[1];
|
||||
WrBuffer[2] = RowDataPtr[2];
|
||||
WrBuffer[3] = RowDataPtr[3];
|
||||
for (Index = 4; Index < 32; Index++) {
|
||||
WrBuffer[Index] = 0;
|
||||
}
|
||||
Bits = 256;
|
||||
jtag_shift (g_port, ATOMIC_DR_SCAN, Bits, WrBuffer, NULL, JS_IDLE);
|
||||
Bits = TAP_IR_LENGTH;
|
||||
WrBuffer [0] = 0x30; /* FUSE_CTS instruction */
|
||||
jtag_shift (g_port, ATOMIC_IR_SCAN, Bits, WrBuffer, NULL, JS_DRSELECT);
|
||||
|
||||
WrBuffer [0] = 0x01;
|
||||
WrBuffer [1] = 0x00;
|
||||
WrBuffer [2] = MarginOption;
|
||||
WrBuffer [3] = 0x01;
|
||||
/* Magic word. */
|
||||
WrBuffer [4] = 0xAC;
|
||||
WrBuffer [5] = 0x28;
|
||||
WrBuffer [6] = 0xED;
|
||||
WrBuffer [7] = 0xFE;
|
||||
|
||||
Bits = 64;
|
||||
jtag_shift (g_port, ATOMIC_DR_SCAN, Bits, WrBuffer, NULL, JS_IDLE);
|
||||
/*
|
||||
* Repeat for all AES key Rows 20-27 and repeat one extra read
|
||||
* for getting CRC back.
|
||||
*/
|
||||
for (Row = 20; Row < 29; Row++) {
|
||||
WrBuf[0] = 0x30;
|
||||
Bits = 6;
|
||||
jtag_shift (g_port, ATOMIC_IR_SCAN, Bits, WrBuf, NULL,
|
||||
JS_DRSELECT);
|
||||
|
||||
WrBuffer [0] = (Row << 2) | 0x1; /* Select row number */
|
||||
WrBuffer [1] = 0x00;
|
||||
WrBuffer [2] = MarginOption;
|
||||
WrBuffer [3] = 0x01;
|
||||
/* Magic word */
|
||||
WrBuffer [4] = 0xAC;
|
||||
WrBuffer [5] = 0x28;
|
||||
WrBuffer [6] = 0xED;
|
||||
WrBuffer [7] = 0xFE;
|
||||
Bits = 64;
|
||||
jtag_shift (g_port, ATOMIC_DR_SCAN, Bits, WrBuffer,
|
||||
RdBuffer, JS_IDLE);
|
||||
}
|
||||
|
||||
WrBuf[0] = 0x30;
|
||||
Bits = 6;
|
||||
jtag_shift(g_port, ATOMIC_IR_SCAN, Bits, WrBuf, NULL, JS_DRSELECT);
|
||||
Bits = 64;
|
||||
jtag_shift (g_port, ATOMIC_DR_SCAN, Bits, WrBuffer, RdBuffer, JS_IDLE);
|
||||
if ((RowDataPtr[0] == RdBuffer[4]) &&
|
||||
(RowDataPtr[1] == RdBuffer[5]) &&
|
||||
(RowDataPtr[2] == RdBuffer[6]) &&
|
||||
(RowDataPtr[3] == RdBuffer[7])) {
|
||||
return XST_SUCCESS;
|
||||
}
|
||||
|
||||
return XST_FAILURE;
|
||||
|
||||
}
|
||||
|
|
|
@ -91,6 +91,11 @@ u32 GpioOutPutCh;
|
|||
#define GPIO_TMS_VAL 0x00001300U
|
||||
#define GPIO_MUX_SEL_VAL 0x00001300U
|
||||
|
||||
/**
|
||||
* GPIO channel numbers of Ultrascale
|
||||
*/
|
||||
#define XSK_EFUSEPL_GPIO_CH1 (1) /**< GPIO channel 1 */
|
||||
#define XSK_EFUSEPL_GPIO_CH2 (2) /**< GPIO channel 2 */
|
||||
/**
|
||||
* XEfusePl is the PL eFUSE driver instance. Using this
|
||||
* structure, user can define the eFUSE bits to be
|
||||
|
|
|
@ -41,5 +41,11 @@ int JtagServerInit(XilSKey_EPl *PlInstancePtr);
|
|||
int JtagValidateMioPins(void);
|
||||
void JtagWrite(unsigned char row, unsigned char bit);
|
||||
void JtagRead(unsigned char row, unsigned int * row_data, unsigned char marginOption);
|
||||
void JtagWrite_Ultrascale(u8 Row, u8 Bit, u8 Page, u8 Redundant);
|
||||
void JtagRead_Ultrascale(u8 Row, u32 *RowData, u8 MarginOption,
|
||||
u8 Page, u8 Redundant);
|
||||
void JtagRead_Status_Ultrascale(u32 *Rowdata);
|
||||
void Jtag_Read_Sysmon(u8 Row, u32 *Row_Data);
|
||||
u32 JtagAES_Check_Ultrascale(u32 *Crc, u8 MarginOption);
|
||||
|
||||
#endif /*XILSKEY_JTAG_H*/
|
||||
|
|
|
@ -60,11 +60,18 @@
|
|||
/***************** Macros (Inline Functions) Definitions ********************/
|
||||
|
||||
/************************** Variable Definitions ****************************/
|
||||
#ifdef XSK_ARM_PLATFORM
|
||||
static XAdcPs XAdcInst; /**< XADC driver instance */
|
||||
u16 XAdcDeviceId; /**< XADC Device ID */
|
||||
#else
|
||||
XTmrCtr XTmrCtrInst;
|
||||
#endif
|
||||
u32 TimerTicksfor100ns; /**< Global Variable to store ticks/100ns*/
|
||||
u32 TimerTicksfor500ns; /**< Global Variable for 5 micro secs for microblaze */
|
||||
/************************** Function Prototypes *****************************/
|
||||
static u32 XilSKey_EfusePs_ConvertCharToNibble (char InChar, u8 *Num);
|
||||
extern void Jtag_Read_Sysmon(u8 Row, u32 *Row_Data);
|
||||
static u32 Xilskey_RowCrcCalculation(u32 PrevCRC, u32 Data, u32 Addr);
|
||||
/***************************************************************************/
|
||||
/**
|
||||
* This function is used to initialize the XADC driver
|
||||
|
@ -82,6 +89,7 @@ static u32 XilSKey_EfusePs_ConvertCharToNibble (char InChar, u8 *Num);
|
|||
u32 XilSKey_EfusePs_XAdcInit (void )
|
||||
{
|
||||
u32 Status;
|
||||
#ifdef XSK_ARM_PLATFORM
|
||||
XAdcPs_Config *ConfigPtr;
|
||||
XAdcPs *XAdcInstPtr = &XAdcInst;
|
||||
|
||||
|
@ -118,7 +126,11 @@ u32 XilSKey_EfusePs_XAdcInit (void )
|
|||
*/
|
||||
XAdcPs_SetSequencerMode(XAdcInstPtr, XADCPS_SEQ_MODE_SAFE);
|
||||
|
||||
return XST_SUCCESS;
|
||||
Status = XST_SUCCESS;
|
||||
#else
|
||||
Status = XST_FAILURE;
|
||||
#endif
|
||||
return Status;
|
||||
|
||||
}
|
||||
|
||||
|
@ -144,6 +156,13 @@ u32 XilSKey_EfusePs_XAdcInit (void )
|
|||
|
||||
void XilSKey_EfusePs_XAdcReadTemperatureAndVoltage(XSKEfusePs_XAdc *XAdcInstancePtr)
|
||||
{
|
||||
#ifdef XSK_MICROBLAZE_PLATFORM
|
||||
/* Temperature */
|
||||
Jtag_Read_Sysmon(XSK_SYSMON_TEMP_ROW, &(XAdcInstancePtr->Temp));
|
||||
XAdcInstancePtr->Temp = (XAdcInstancePtr->Temp) >> 6;
|
||||
/* Voltage */
|
||||
Jtag_Read_Sysmon(XSK_SYSMON_VOL_ROW, &(XAdcInstancePtr->V));
|
||||
#else
|
||||
XAdcPs *XAdcInstPtr = &XAdcInst;
|
||||
u8 V, VMin, VMax;
|
||||
|
||||
|
@ -217,6 +236,8 @@ void XilSKey_EfusePs_XAdcReadTemperatureAndVoltage(XSKEfusePs_XAdc *XAdcInstance
|
|||
XAdcInstancePtr->V,
|
||||
(int )XAdcPs_RawToVoltage(XAdcInstancePtr->V));
|
||||
|
||||
#endif
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -256,6 +277,11 @@ void XilSKey_Efuse_StartTimer()
|
|||
* Enable the Timer counter
|
||||
*/
|
||||
Xil_Out32(XSK_GLOBAL_TIMER_CTRL_REG,0x1);
|
||||
#else
|
||||
XTmrCtr_SetOptions(&XTmrCtrInst, XSK_TMRCTR_NUM,
|
||||
XTC_AUTO_RELOAD_OPTION);
|
||||
XTmrCtr_Start(&XTmrCtrInst, XSK_TMRCTR_NUM);
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -274,14 +300,20 @@ void XilSKey_Efuse_StartTimer()
|
|||
|
||||
u64 XilSKey_Efuse_GetTime(void)
|
||||
{
|
||||
volatile u32 t_hi=0, t_lo=0;
|
||||
volatile u64 t=0;
|
||||
do {
|
||||
t_hi = Xil_In32(XSK_GLOBAL_TIMER_COUNT_REG_HIGH);
|
||||
t_lo = Xil_In32(XSK_GLOBAL_TIMER_COUNT_REG_LOW);
|
||||
}while(t_hi != Xil_In32(XSK_GLOBAL_TIMER_COUNT_REG_HIGH));
|
||||
volatile u64 t=0;
|
||||
#ifdef XSK_ARM_PLATFORM
|
||||
volatile u32 t_hi=0, t_lo=0;
|
||||
|
||||
t = (((u64) t_hi) << 32) | (u64) t_lo;
|
||||
do {
|
||||
t_hi = Xil_In32(XSK_GLOBAL_TIMER_COUNT_REG_HIGH);
|
||||
t_lo = Xil_In32(XSK_GLOBAL_TIMER_COUNT_REG_LOW);
|
||||
}while(t_hi != Xil_In32(XSK_GLOBAL_TIMER_COUNT_REG_HIGH));
|
||||
|
||||
t = (((u64) t_hi) << 32) | (u64) t_lo;
|
||||
|
||||
#else
|
||||
t = XTmrCtr_GetValue(&XTmrCtrInst, XSK_TMRCTR_NUM);
|
||||
#endif
|
||||
return t;
|
||||
}
|
||||
/****************************************************************************/
|
||||
|
@ -830,3 +862,145 @@ u32 Xilskey_Timer_Intialise()
|
|||
return RefClk;
|
||||
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
/**
|
||||
* Copies one string to other from specified location
|
||||
*
|
||||
* @param Src is a pointer to Source string.
|
||||
* @param Dst is a pointer to Destination string.
|
||||
* @param From which position to be copied.
|
||||
* @param To which position to be copied.
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
****************************************************************************/
|
||||
void Xilskey_StrCpyRange(u8 *Src, u8 *Dst, u32 From, u32 To)
|
||||
{
|
||||
u32 Index,J = 0;
|
||||
for (Index = From; Index <= To; Index++) {
|
||||
Dst[J++] = Src[Index];
|
||||
}
|
||||
Dst[J] = '\0';
|
||||
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
/**
|
||||
* Calculates CRC value of provided key.
|
||||
*
|
||||
* @param Key is the string contains AES key in hexa decimal of length
|
||||
* less than or equal to 64.
|
||||
*
|
||||
* @return Crc of AES key value.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
****************************************************************************/
|
||||
u32 Xilskey_CrcCalculation(u8 *Key)
|
||||
{
|
||||
u32 Crc = 0;
|
||||
u8 Key_8[8];
|
||||
u8 Key_Hex[4];
|
||||
u32 Index;
|
||||
u32 Key_32;
|
||||
u8 FullKey[64] = {0};
|
||||
u32 Length = strlen((char *)Key);
|
||||
|
||||
|
||||
if (Length > 64) {
|
||||
return XSK_EFUSEPL_ERROR_NOT_VALID_KEY_LENGTH;
|
||||
}
|
||||
if (Length < 64) {
|
||||
strcpy((char *)&FullKey[64-Length + 1], (char *)Key);
|
||||
|
||||
}
|
||||
else {
|
||||
strcpy((char *)FullKey, (char *)Key);
|
||||
}
|
||||
|
||||
for (Index = 0; Index <8;Index++) {
|
||||
Xilskey_StrCpyRange(FullKey, Key_8, ((7 - Index)*8),
|
||||
((((7 - Index) + 1)*8)-1));
|
||||
XilSKey_Efuse_ConvertStringToHexBE((char *)Key_8, Key_Hex, 8);
|
||||
Key_32 = (Key_Hex[0] << 24) | (Key_Hex[1] << 16) |
|
||||
(Key_Hex[2] << 8) | (Key_Hex[3]);
|
||||
Crc = Xilskey_RowCrcCalculation(Crc, Key_32, 20+Index);
|
||||
}
|
||||
|
||||
return Crc;
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
/**
|
||||
* Calculates CRC value for each row of AES key.
|
||||
*
|
||||
* @param PrevCRC holds the prev row's CRC.
|
||||
* @param Data holds the present row's key.
|
||||
* @param Addr stores the current row number.
|
||||
*
|
||||
* @return Crc of current row.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
****************************************************************************/
|
||||
u32 Xilskey_RowCrcCalculation(u32 PrevCRC, u32 Data, u32 Addr)
|
||||
{
|
||||
u32 Crc = PrevCRC;
|
||||
u32 Value = Data;
|
||||
u32 Row = Addr;
|
||||
u32 Index;
|
||||
|
||||
for (Index = 0; Index < 32; Index++) {
|
||||
if ((((Value & 0x1) ^ Crc) & 0x1) != 0) {
|
||||
Crc = ((Crc >> 1) ^ REVERSE_POLYNOMIAL);
|
||||
}
|
||||
else {
|
||||
Crc = Crc >>1;
|
||||
}
|
||||
Value = Value >>1;
|
||||
}
|
||||
|
||||
for (Index = 0; Index < 5; Index++) {
|
||||
if ((((Row & 0x1) ^ Crc) & 0x1) != 0) {
|
||||
Crc = ((Crc >> 1) ^ REVERSE_POLYNOMIAL);
|
||||
}
|
||||
else {
|
||||
Crc = Crc >>1;
|
||||
}
|
||||
Row = Row >> 1;
|
||||
}
|
||||
|
||||
return Crc;
|
||||
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
/**
|
||||
* This API reverse the value.
|
||||
*
|
||||
* @param Input is a 32 bit variable
|
||||
*
|
||||
* @return Reverse the given value.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
****************************************************************************/
|
||||
u32 Xilskey_Efuse_ReverseHex(u32 Input)
|
||||
{
|
||||
u32 Index = 0;
|
||||
u32 Rev = 0;
|
||||
u32 Bit;
|
||||
|
||||
while (Index++ < 32) {
|
||||
Bit = Input & 1;
|
||||
Input = Input >> 1;
|
||||
Rev = Rev ^ Bit;
|
||||
if (Index < 32)
|
||||
Rev = Rev << 1;
|
||||
}
|
||||
|
||||
return Rev;
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue