/****************************************************************************** * * Copyright (C) 2013 - 2014 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 THE * XILINX CONSORTIUM 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_jscmd.c * * Contains jtag, efuse and bbram related API's * * @note *
* MODIFICATION HISTORY:
*
* Ver   Who  	Date     Changes
* ----- ---- 	-------- --------------------------------------------------------
* 1.00a rpoolla 04/26/13 First release
* 1.01a hk      09/18/13 Added BBRAM functionality. Following API's added:
*                        int JtagServerInitBbram(XilSKey_Bbram *InstancePtr)
*                        int Bbram_Init(XilSKey_Bbram *InstancePtr)
*                        int Bbram_ProgramKey(XilSKey_Bbram *InstancePtr)
*                        int Bbram_VerifyKey(XilSKey_Bbram *InstancePtr)
*                        void Bbram_DeInit(void)
*
* 
* * ******************************************************************************/ #include #include #include #include #ifdef _WIN32 #include #if defined(_MSC_VER) # pragma warning(disable:4996) /* 'strcpy': This function or variable may be unsafe */ #endif typedef long ssize_t; #else #include #endif #include "xilskey_utils.h" #include "xilskey_jslib.h" #include "xilskey_jscmd.h" #include "xgpiops.h" #include "xilskey_bbram.h" //#define DEBUG_PRINT #ifdef DEBUG_PRINT #define js_printf printf #else void dummy_printf(const char *ctrl1, ...); #define js_printf dummy_printf #endif #define DEFAULT_FREQUENCY 10000000 #define MAX_FREQUENCY 30000000 #define ZYNQ_DAP_ID 0x4ba00477 #define set_last_error(JS, ...) js_set_last_error(&(JS)->js.base, __VA_ARGS__) typedef struct js_port_impl_struct js_port_impl_t; typedef struct js_command_impl_struct js_command_impl_t; typedef struct ftd_async_transfer_struct ftd_async_transfer_t; 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; void dummy_printf(const char *ctrl1, ...) { return; } static int close_port( js_lib_port_t *port_arg); struct js_command_impl_struct { /* Command to execute */ js_lib_command_t lib; /* Intermediatre command processing state */ size_t byte_offset; js_state_t start_state; js_state_t end_state; unsigned int write_bytes; unsigned int read_bytes; unsigned int partial_bytes; int state_bits; }; struct js_zynq { /* Base class - must be first. */ js_lib_server_t js; /* Port list */ js_port_descr_t *port_list; unsigned int port_count; unsigned int port_max; }; struct js_port_impl_struct { /* Base class - must be first. */ js_lib_port_t lib; /* Command sequence after normalization */ js_lib_command_sequence_t *cmdseq; /* Current JTAG state */ js_state_t state; int irPrePadBits; int irPostPadBits; int drPrePadBits; int drPostPadBits; js_node_t root_node_obj; }; static XGpioPs structXGpioPs; int setPin (int pin, int value); int readPin (int pin); u32 Bbram_ReadKey[8]; void GpioConfig(unsigned long addr, unsigned long mask, unsigned long val) { unsigned long current_val = *(volatile unsigned long *)addr; *(volatile unsigned long *) addr = ( val & mask ) | ( current_val & ~mask); } void JtagInitGpio () { js_printf("===== Initializing PS GPIO pins...\n\r"); XGpioPs_Config *ptrConfigPtrPs = XGpioPs_LookupConfig(0); XGpioPs_CfgInitialize(&structXGpioPs,ptrConfigPtrPs,ptrConfigPtrPs->BaseAddr); /* Unlock the SLCR block */ Xil_Out32 (0xF8000000 + 0x8, 0xDF0D); GpioConfig((GPIO_BASE_ADDR+(g_mio_jtag_tdi*4)),GPIO_MASK_VAL, GPIO_TDI_VAL); GpioConfig((GPIO_BASE_ADDR+(g_mio_jtag_tdo*4)),GPIO_MASK_VAL, GPIO_TDO_VAL); GpioConfig((GPIO_BASE_ADDR+(g_mio_jtag_tck*4)),GPIO_MASK_VAL, GPIO_TCK_VAL); GpioConfig((GPIO_BASE_ADDR+(g_mio_jtag_tms*4)),GPIO_MASK_VAL, GPIO_TMS_VAL); GpioConfig((GPIO_BASE_ADDR+(g_mio_jtag_mux_sel*4)),GPIO_MASK_VAL, GPIO_MUX_SEL_VAL); XGpioPs_SetDirectionPin(&structXGpioPs,MIO_TCK,1); XGpioPs_SetOutputEnablePin(&structXGpioPs,MIO_TCK,1); XGpioPs_SetDirectionPin(&structXGpioPs,MIO_TMS,1); XGpioPs_SetOutputEnablePin(&structXGpioPs,MIO_TMS,1); XGpioPs_SetDirectionPin(&structXGpioPs,MIO_TDI,1); XGpioPs_SetOutputEnablePin(&structXGpioPs,MIO_TDI,1); XGpioPs_SetDirectionPin(&structXGpioPs,MIO_MUX_SELECT,1); XGpioPs_SetOutputEnablePin(&structXGpioPs,MIO_MUX_SELECT,1); XGpioPs_WritePin(&structXGpioPs, MIO_MUX_SELECT, g_mux_sel_def_val); XGpioPs_SetDirectionPin(&structXGpioPs,MIO_TDO,0); XGpioPs_SetOutputEnablePin(&structXGpioPs,MIO_TDO,0); } /* initGpio() */ int getByteCountFromBitCount (int bitCount) { int byteCount = bitCount / 8; if (bitCount % 8) { byteCount++; } return (byteCount); } // File generated by JTAG.EXE. This are the tms values and // the corresponding bit counts to navigate quickly from any state // to any state. const unsigned int JTAGNavigateTable [256] = { 0x0101, // Start=00, End=00, TMSValue=01, BitCount= 1 0x0001, // Start=00, End=01, TMSValue=00, BitCount= 1 0x0202, // Start=00, End=02, TMSValue=02, BitCount= 2 0x0203, // Start=00, End=03, TMSValue=02, BitCount= 3 0x0204, // Start=00, End=04, TMSValue=02, BitCount= 4 0x0A04, // Start=00, End=05, TMSValue=0A, BitCount= 4 0x0A05, // Start=00, End=06, TMSValue=0A, BitCount= 5 0x2A06, // Start=00, End=07, TMSValue=2A, BitCount= 6 0x1A05, // Start=00, End=08, TMSValue=1A, BitCount= 5 0x0603, // Start=00, End=09, TMSValue=06, BitCount= 3 0x0604, // Start=00, End=10, TMSValue=06, BitCount= 4 0x0605, // Start=00, End=11, TMSValue=06, BitCount= 5 0x1605, // Start=00, End=12, TMSValue=16, BitCount= 5 0x1606, // Start=00, End=13, TMSValue=16, BitCount= 6 0x5607, // Start=00, End=14, TMSValue=56, BitCount= 7 0x3606, // Start=00, End=15, TMSValue=36, BitCount= 6 0x0703, // Start=01, End=00, TMSValue=07, BitCount= 3 0x0001, // Start=01, End=01, TMSValue=00, BitCount= 1 0x0101, // Start=01, End=02, TMSValue=01, BitCount= 1 0x0102, // Start=01, End=03, TMSValue=01, BitCount= 2 0x0103, // Start=01, End=04, TMSValue=01, BitCount= 3 0x0503, // Start=01, End=05, TMSValue=05, BitCount= 3 0x0504, // Start=01, End=06, TMSValue=05, BitCount= 4 0x1505, // Start=01, End=07, TMSValue=15, BitCount= 5 0x0D04, // Start=01, End=08, TMSValue=0D, BitCount= 4 0x0302, // Start=01, End=09, TMSValue=03, BitCount= 2 0x0303, // Start=01, End=10, TMSValue=03, BitCount= 3 0x0304, // Start=01, End=11, TMSValue=03, BitCount= 4 0x0B04, // Start=01, End=12, TMSValue=0B, BitCount= 4 0x0B05, // Start=01, End=13, TMSValue=0B, BitCount= 5 0x2B06, // Start=01, End=14, TMSValue=2B, BitCount= 6 0x1B05, // Start=01, End=15, TMSValue=1B, BitCount= 5 0x0302, // Start=02, End=00, TMSValue=03, BitCount= 2 0x0303, // Start=02, End=01, TMSValue=03, BitCount= 3 0x0B04, // Start=02, End=02, TMSValue=0B, BitCount= 4 0x0001, // Start=02, End=03, TMSValue=00, BitCount= 1 0x0002, // Start=02, End=04, TMSValue=00, BitCount= 2 0x0202, // Start=02, End=05, TMSValue=02, BitCount= 2 0x0203, // Start=02, End=06, TMSValue=02, BitCount= 3 0x0A04, // Start=02, End=07, TMSValue=0A, BitCount= 4 0x0603, // Start=02, End=08, TMSValue=06, BitCount= 3 0x0101, // Start=02, End=09, TMSValue=01, BitCount= 1 0x0102, // Start=02, End=10, TMSValue=01, BitCount= 2 0x0103, // Start=02, End=11, TMSValue=01, BitCount= 3 0x0503, // Start=02, End=12, TMSValue=05, BitCount= 3 0x0504, // Start=02, End=13, TMSValue=05, BitCount= 4 0x1505, // Start=02, End=14, TMSValue=15, BitCount= 5 0x0D04, // Start=02, End=15, TMSValue=0D, BitCount= 4 0x1F05, // Start=03, End=00, TMSValue=1F, BitCount= 5 0x0303, // Start=03, End=01, TMSValue=03, BitCount= 3 0x0703, // Start=03, End=02, TMSValue=07, BitCount= 3 0x0704, // Start=03, End=03, TMSValue=07, BitCount= 4 0x0001, // Start=03, End=04, TMSValue=00, BitCount= 1 0x0101, // Start=03, End=05, TMSValue=01, BitCount= 1 0x0102, // Start=03, End=06, TMSValue=01, BitCount= 2 0x0503, // Start=03, End=07, TMSValue=05, BitCount= 3 0x0302, // Start=03, End=08, TMSValue=03, BitCount= 2 0x0F04, // Start=03, End=09, TMSValue=0F, BitCount= 4 0x0F05, // Start=03, End=10, TMSValue=0F, BitCount= 5 0x0F06, // Start=03, End=11, TMSValue=0F, BitCount= 6 0x2F06, // Start=03, End=12, TMSValue=2F, BitCount= 6 0x2F07, // Start=03, End=13, TMSValue=2F, BitCount= 7 0xAF08, // Start=03, End=14, TMSValue=AF, BitCount= 8 0x6F07, // Start=03, End=15, TMSValue=6F, BitCount= 7 0x1F05, // Start=04, End=00, TMSValue=1F, BitCount= 5 0x0303, // Start=04, End=01, TMSValue=03, BitCount= 3 0x0703, // Start=04, End=02, TMSValue=07, BitCount= 3 0x0704, // Start=04, End=03, TMSValue=07, BitCount= 4 0x0001, // Start=04, End=04, TMSValue=00, BitCount= 1 0x0101, // Start=04, End=05, TMSValue=01, BitCount= 1 0x0102, // Start=04, End=06, TMSValue=01, BitCount= 2 0x0503, // Start=04, End=07, TMSValue=05, BitCount= 3 0x0302, // Start=04, End=08, TMSValue=03, BitCount= 2 0x0F04, // Start=04, End=09, TMSValue=0F, BitCount= 4 0x0F05, // Start=04, End=10, TMSValue=0F, BitCount= 5 0x0F06, // Start=04, End=11, TMSValue=0F, BitCount= 6 0x2F06, // Start=04, End=12, TMSValue=2F, BitCount= 6 0x2F07, // Start=04, End=13, TMSValue=2F, BitCount= 7 0xAF08, // Start=04, End=14, TMSValue=AF, BitCount= 8 0x6F07, // Start=04, End=15, TMSValue=6F, BitCount= 7 0x0F04, // Start=05, End=00, TMSValue=0F, BitCount= 4 0x0102, // Start=05, End=01, TMSValue=01, BitCount= 2 0x0302, // Start=05, End=02, TMSValue=03, BitCount= 2 0x0303, // Start=05, End=03, TMSValue=03, BitCount= 3 0x0203, // Start=05, End=04, TMSValue=02, BitCount= 3 0x0B04, // Start=05, End=05, TMSValue=0B, BitCount= 4 0x0001, // Start=05, End=06, TMSValue=00, BitCount= 1 0x0202, // Start=05, End=07, TMSValue=02, BitCount= 2 0x0101, // Start=05, End=08, TMSValue=01, BitCount= 1 0x0703, // Start=05, End=09, TMSValue=07, BitCount= 3 0x0704, // Start=05, End=10, TMSValue=07, BitCount= 4 0x0705, // Start=05, End=11, TMSValue=07, BitCount= 5 0x1705, // Start=05, End=12, TMSValue=17, BitCount= 5 0x1706, // Start=05, End=13, TMSValue=17, BitCount= 6 0x5707, // Start=05, End=14, TMSValue=57, BitCount= 7 0x3706, // Start=05, End=15, TMSValue=37, BitCount= 6 0x1F05, // Start=06, End=00, TMSValue=1F, BitCount= 5 0x0303, // Start=06, End=01, TMSValue=03, BitCount= 3 0x0703, // Start=06, End=02, TMSValue=07, BitCount= 3 0x0704, // Start=06, End=03, TMSValue=07, BitCount= 4 0x0102, // Start=06, End=04, TMSValue=01, BitCount= 2 0x0503, // Start=06, End=05, TMSValue=05, BitCount= 3 0x0001, // Start=06, End=06, TMSValue=00, BitCount= 1 0x0101, // Start=06, End=07, TMSValue=01, BitCount= 1 0x0302, // Start=06, End=08, TMSValue=03, BitCount= 2 0x0F04, // Start=06, End=09, TMSValue=0F, BitCount= 4 0x0F05, // Start=06, End=10, TMSValue=0F, BitCount= 5 0x0F06, // Start=06, End=11, TMSValue=0F, BitCount= 6 0x2F06, // Start=06, End=12, TMSValue=2F, BitCount= 6 0x2F07, // Start=06, End=13, TMSValue=2F, BitCount= 7 0xAF08, // Start=06, End=14, TMSValue=AF, BitCount= 8 0x6F07, // Start=06, End=15, TMSValue=6F, BitCount= 7 0x0F04, // Start=07, End=00, TMSValue=0F, BitCount= 4 0x0102, // Start=07, End=01, TMSValue=01, BitCount= 2 0x0302, // Start=07, End=02, TMSValue=03, BitCount= 2 0x0303, // Start=07, End=03, TMSValue=03, BitCount= 3 0x0001, // Start=07, End=04, TMSValue=00, BitCount= 1 0x0202, // Start=07, End=05, TMSValue=02, BitCount= 2 0x0203, // Start=07, End=06, TMSValue=02, BitCount= 3 0x0A04, // Start=07, End=07, TMSValue=0A, BitCount= 4 0x0101, // Start=07, End=08, TMSValue=01, BitCount= 1 0x0703, // Start=07, End=09, TMSValue=07, BitCount= 3 0x0704, // Start=07, End=10, TMSValue=07, BitCount= 4 0x0705, // Start=07, End=11, TMSValue=07, BitCount= 5 0x1705, // Start=07, End=12, TMSValue=17, BitCount= 5 0x1706, // Start=07, End=13, TMSValue=17, BitCount= 6 0x5707, // Start=07, End=14, TMSValue=57, BitCount= 7 0x3706, // Start=07, End=15, TMSValue=37, BitCount= 6 0x0703, // Start=08, End=00, TMSValue=07, BitCount= 3 0x0001, // Start=08, End=01, TMSValue=00, BitCount= 1 0x0101, // Start=08, End=02, TMSValue=01, BitCount= 1 0x0102, // Start=08, End=03, TMSValue=01, BitCount= 2 0x0103, // Start=08, End=04, TMSValue=01, BitCount= 3 0x0503, // Start=08, End=05, TMSValue=05, BitCount= 3 0x0504, // Start=08, End=06, TMSValue=05, BitCount= 4 0x1505, // Start=08, End=07, TMSValue=15, BitCount= 5 0x0D04, // Start=08, End=08, TMSValue=0D, BitCount= 4 0x0302, // Start=08, End=09, TMSValue=03, BitCount= 2 0x0303, // Start=08, End=10, TMSValue=03, BitCount= 3 0x0304, // Start=08, End=11, TMSValue=03, BitCount= 4 0x0B04, // Start=08, End=12, TMSValue=0B, BitCount= 4 0x0B05, // Start=08, End=13, TMSValue=0B, BitCount= 5 0x2B06, // Start=08, End=14, TMSValue=2B, BitCount= 6 0x1B05, // Start=08, End=15, TMSValue=1B, BitCount= 5 0x0101, // Start=09, End=00, TMSValue=01, BitCount= 1 0x0102, // Start=09, End=01, TMSValue=01, BitCount= 2 0x0503, // Start=09, End=02, TMSValue=05, BitCount= 3 0x0504, // Start=09, End=03, TMSValue=05, BitCount= 4 0x0505, // Start=09, End=04, TMSValue=05, BitCount= 5 0x1505, // Start=09, End=05, TMSValue=15, BitCount= 5 0x1506, // Start=09, End=06, TMSValue=15, BitCount= 6 0x5507, // Start=09, End=07, TMSValue=55, BitCount= 7 0x3506, // Start=09, End=08, TMSValue=35, BitCount= 6 0x0D04, // Start=09, End=09, TMSValue=0D, BitCount= 4 0x0001, // Start=09, End=10, TMSValue=00, BitCount= 1 0x0002, // Start=09, End=11, TMSValue=00, BitCount= 2 0x0202, // Start=09, End=12, TMSValue=02, BitCount= 2 0x0203, // Start=09, End=13, TMSValue=02, BitCount= 3 0x0A04, // Start=09, End=14, TMSValue=0A, BitCount= 4 0x0603, // Start=09, End=15, TMSValue=06, BitCount= 3 0x1F05, // Start=10, End=00, TMSValue=1F, BitCount= 5 0x0303, // Start=10, End=01, TMSValue=03, BitCount= 3 0x0703, // Start=10, End=02, TMSValue=07, BitCount= 3 0x0704, // Start=10, End=03, TMSValue=07, BitCount= 4 0x0705, // Start=10, End=04, TMSValue=07, BitCount= 5 0x1705, // Start=10, End=05, TMSValue=17, BitCount= 5 0x1706, // Start=10, End=06, TMSValue=17, BitCount= 6 0x5707, // Start=10, End=07, TMSValue=57, BitCount= 7 0x3706, // Start=10, End=08, TMSValue=37, BitCount= 6 0x0F04, // Start=10, End=09, TMSValue=0F, BitCount= 4 0x0F05, // Start=10, End=10, TMSValue=0F, BitCount= 5 0x0001, // Start=10, End=11, TMSValue=00, BitCount= 1 0x0101, // Start=10, End=12, TMSValue=01, BitCount= 1 0x0102, // Start=10, End=13, TMSValue=01, BitCount= 2 0x0503, // Start=10, End=14, TMSValue=05, BitCount= 3 0x0302, // Start=10, End=15, TMSValue=03, BitCount= 2 0x1F05, // Start=11, End=00, TMSValue=1F, BitCount= 5 0x0303, // Start=11, End=01, TMSValue=03, BitCount= 3 0x0703, // Start=11, End=02, TMSValue=07, BitCount= 3 0x0704, // Start=11, End=03, TMSValue=07, BitCount= 4 0x0705, // Start=11, End=04, TMSValue=07, BitCount= 5 0x1705, // Start=11, End=05, TMSValue=17, BitCount= 5 0x1706, // Start=11, End=06, TMSValue=17, BitCount= 6 0x5707, // Start=11, End=07, TMSValue=57, BitCount= 7 0x3706, // Start=11, End=08, TMSValue=37, BitCount= 6 0x0F04, // Start=11, End=09, TMSValue=0F, BitCount= 4 0x0F05, // Start=11, End=10, TMSValue=0F, BitCount= 5 0x0001, // Start=11, End=11, TMSValue=00, BitCount= 1 0x0101, // Start=11, End=12, TMSValue=01, BitCount= 1 0x0102, // Start=11, End=13, TMSValue=01, BitCount= 2 0x0503, // Start=11, End=14, TMSValue=05, BitCount= 3 0x0302, // Start=11, End=15, TMSValue=03, BitCount= 2 0x0F04, // Start=12, End=00, TMSValue=0F, BitCount= 4 0x0102, // Start=12, End=01, TMSValue=01, BitCount= 2 0x0302, // Start=12, End=02, TMSValue=03, BitCount= 2 0x0303, // Start=12, End=03, TMSValue=03, BitCount= 3 0x0304, // Start=12, End=04, TMSValue=03, BitCount= 4 0x0B04, // Start=12, End=05, TMSValue=0B, BitCount= 4 0x0B05, // Start=12, End=06, TMSValue=0B, BitCount= 5 0x2B06, // Start=12, End=07, TMSValue=2B, BitCount= 6 0x1B05, // Start=12, End=08, TMSValue=1B, BitCount= 5 0x0703, // Start=12, End=09, TMSValue=07, BitCount= 3 0x0704, // Start=12, End=10, TMSValue=07, BitCount= 4 0x0203, // Start=12, End=11, TMSValue=02, BitCount= 3 0x0A04, // Start=12, End=12, TMSValue=0A, BitCount= 4 0x0001, // Start=12, End=13, TMSValue=00, BitCount= 1 0x0202, // Start=12, End=14, TMSValue=02, BitCount= 2 0x0101, // Start=12, End=15, TMSValue=01, BitCount= 1 0x1F05, // Start=13, End=00, TMSValue=1F, BitCount= 5 0x0303, // Start=13, End=01, TMSValue=03, BitCount= 3 0x0703, // Start=13, End=02, TMSValue=07, BitCount= 3 0x0704, // Start=13, End=03, TMSValue=07, BitCount= 4 0x0705, // Start=13, End=04, TMSValue=07, BitCount= 5 0x1705, // Start=13, End=05, TMSValue=17, BitCount= 5 0x1706, // Start=13, End=06, TMSValue=17, BitCount= 6 0x5707, // Start=13, End=07, TMSValue=57, BitCount= 7 0x3706, // Start=13, End=08, TMSValue=37, BitCount= 6 0x0F04, // Start=13, End=09, TMSValue=0F, BitCount= 4 0x0F05, // Start=13, End=10, TMSValue=0F, BitCount= 5 0x0102, // Start=13, End=11, TMSValue=01, BitCount= 2 0x0503, // Start=13, End=12, TMSValue=05, BitCount= 3 0x0001, // Start=13, End=13, TMSValue=00, BitCount= 1 0x0101, // Start=13, End=14, TMSValue=01, BitCount= 1 0x0302, // Start=13, End=15, TMSValue=03, BitCount= 2 0x0F04, // Start=14, End=00, TMSValue=0F, BitCount= 4 0x0102, // Start=14, End=01, TMSValue=01, BitCount= 2 0x0302, // Start=14, End=02, TMSValue=03, BitCount= 2 0x0303, // Start=14, End=03, TMSValue=03, BitCount= 3 0x0304, // Start=14, End=04, TMSValue=03, BitCount= 4 0x0B04, // Start=14, End=05, TMSValue=0B, BitCount= 4 0x0B05, // Start=14, End=06, TMSValue=0B, BitCount= 5 0x2B06, // Start=14, End=07, TMSValue=2B, BitCount= 6 0x1B05, // Start=14, End=08, TMSValue=1B, BitCount= 5 0x0703, // Start=14, End=09, TMSValue=07, BitCount= 3 0x0704, // Start=14, End=10, TMSValue=07, BitCount= 4 0x0001, // Start=14, End=11, TMSValue=00, BitCount= 1 0x0202, // Start=14, End=12, TMSValue=02, BitCount= 2 0x0203, // Start=14, End=13, TMSValue=02, BitCount= 3 0x0A04, // Start=14, End=14, TMSValue=0A, BitCount= 4 0x0101, // Start=14, End=15, TMSValue=01, BitCount= 1 0x0703, // Start=15, End=00, TMSValue=07, BitCount= 3 0x0001, // Start=15, End=01, TMSValue=00, BitCount= 1 0x0101, // Start=15, End=02, TMSValue=01, BitCount= 1 0x0102, // Start=15, End=03, TMSValue=01, BitCount= 2 0x0103, // Start=15, End=04, TMSValue=01, BitCount= 3 0x0503, // Start=15, End=05, TMSValue=05, BitCount= 3 0x0504, // Start=15, End=06, TMSValue=05, BitCount= 4 0x1505, // Start=15, End=07, TMSValue=15, BitCount= 5 0x0D04, // Start=15, End=08, TMSValue=0D, BitCount= 4 0x0302, // Start=15, End=09, TMSValue=03, BitCount= 2 0x0303, // Start=15, End=10, TMSValue=03, BitCount= 3 0x0304, // Start=15, End=11, TMSValue=03, BitCount= 4 0x0B04, // Start=15, End=12, TMSValue=0B, BitCount= 4 0x0B05, // Start=15, End=13, TMSValue=0B, BitCount= 5 0x2B06, // Start=15, End=14, TMSValue=2B, BitCount= 6 0x1B05, // Start=15, End=15, TMSValue=1B, BitCount= 5 }; unsigned int getNavigateTAPValue (unsigned char startState, unsigned char endState) { unsigned char index; unsigned int tableValue; index = (startState << 4) & 0xF0; index |= endState; tableValue = JTAGNavigateTable [index]; return (tableValue); } void navigateTAP (unsigned char startState, unsigned char endState) { unsigned int tableValue = getNavigateTAPValue (startState, endState); unsigned char tmsValue = (tableValue >> 8) & 0x00FF; unsigned char bitCount = tableValue & 0x00FF; unsigned char mask = 0x01; js_printf ("navigate - start=%d, end=%d\n", startState, endState); js_printf ("tmsvalue = 0x%02X, bitCount = %d\n", tmsValue, bitCount); if (endState == JS_RESET) { // initialize state to JS_RESET setPin (MIO_TMS, 1); setPin (MIO_TCK, 1); setPin (MIO_TCK, 0); setPin (MIO_TCK, 1); setPin (MIO_TCK, 0); setPin (MIO_TCK, 1); setPin (MIO_TCK, 0); setPin (MIO_TCK, 1); setPin (MIO_TCK, 0); setPin (MIO_TCK, 1); setPin (MIO_TCK, 0); return; } if (startState != endState) { while (bitCount) { if (tmsValue & mask) { setPin (MIO_TMS, 1); } else { setPin (MIO_TMS, 0); } // pulse tck pin setPin (MIO_TCK, 1); setPin (MIO_TCK, 0); mask <<= 1; bitCount--; } } else { js_printf ("startState == endState; navigateTAP not executed."); } } int setPin (int pin, int value) { int status = 1; XGpioPs_WritePin(&structXGpioPs, pin, value); return (status); } int readPin (int pin) { int retVal = XGpioPs_ReadPin(&structXGpioPs, pin); return (retVal); } void jtagShiftTDI (unsigned char tdiData, unsigned char* tdoData, int clkCount, int exitState) { int count = clkCount; unsigned char mask = 0x01; while (count) { if (tdoData) // read tdo bit { if (readPin (MIO_TDO)) { *(unsigned char*)tdoData |= mask; } else { *(unsigned char*)tdoData &= ~mask; } } if (tdiData & mask) { setPin (MIO_TDI, 1); } else { setPin (MIO_TDI, 0); } if (exitState == 1) { if (count == 1) { setPin (MIO_TMS, 1); } } // pulse tck pin setPin (MIO_TCK, 1); setPin (MIO_TCK, 0); mask <<= 1; count--; } } // This function will be used to shift long bits. Returns a 1 if shift state is to be exited. // If tdoBuf != NULL, data will be read from device. int jtagShiftTDIBits (unsigned char* tdiBuf, unsigned char* tdoBuf, int bitCount, js_state_t endState, unsigned int flags) { unsigned char* tdoByte = NULL; int count = 8; int exitState = 0; int currentByteCount = getByteCountFromBitCount (bitCount); int byteCount = currentByteCount; int index = 0; unsigned char TdiTemp = 0x0; int bitsLeft = 8; if (bitCount % 8) { bitsLeft = bitCount % 8; } if(flags | JS_ONES) TdiTemp = 0xFF; while (index < byteCount) { currentByteCount--; if (currentByteCount == 0) // last byte { if (bitsLeft != 8) { count = bitsLeft; } if (flags & JS_TO_IR) { if (endState != JS_IRSHIFT) { exitState = 1; } } else { if (endState != JS_DRSHIFT) { exitState = 1; } } } if (tdoBuf) // read tdo data { tdoByte = &tdoBuf [index]; } if(tdiBuf != NULL) jtagShiftTDI (tdiBuf [index], tdoByte, count, exitState); else jtagShiftTDI (TdiTemp, tdoByte, count, exitState); if (tdoBuf) js_printf ("tdoBuf=0x%02X\n", *tdoByte); index++; } return (exitState); } int jtag_setPreAndPostPads (js_port_t *port_arg, int irPrePadBits, int irPostPadBits, int drPrePadBits, int drPostPadBits) { int status = 0; js_port_impl_t *port = (js_port_impl_t *)port_arg; port->irPrePadBits = irPrePadBits; port->irPostPadBits = irPostPadBits; port->drPrePadBits = drPrePadBits; port->drPostPadBits = drPostPadBits; return (status); } int jtag_navigate (js_port_t *port, js_state_t state) { int status = 0; js_command_sequence_t *cmds = js_create_command_sequence(port->root_node); if (cmds == NULL) { return -1; } js_add_state_change(cmds, state, 0); status = js_run_command_sequence(cmds); js_delete_command_sequence(cmds); return (status); } // This function takes care of padding // Must be set up with pre/post ir/dr info int jtag_shift (js_port_t *port_arg, unsigned char mode, int bits, unsigned char* wrBuffer, unsigned char* rdBuffer, js_state_t state) { int status = 0; unsigned char* rdPtr; unsigned char* wrPtr; js_command_sequence_t *cmds = js_create_command_sequence(port_arg->root_node); if (cmds == NULL) { return -1; } js_port_impl_t *port = (js_port_impl_t *)port_arg; if (mode == ATOMIC_IR_SCAN) { if (port->irPrePadBits > 0) { js_add_shift (cmds, JS_TO_IR | JS_ONES, port->irPrePadBits, NULL, NULL, JS_IRSHIFT); } if (port->irPostPadBits == 0) { js_add_shift (cmds, JS_TO_IR, bits, ((wrBuffer == NULL) ? NULL : &wrPtr), ((rdBuffer == NULL) ? NULL : &rdPtr), state); } else { js_add_shift (cmds, JS_TO_IR, bits, ((wrBuffer == NULL) ? NULL : &wrPtr), ((rdBuffer == NULL) ? NULL : &rdPtr), JS_IRSHIFT); js_add_shift (cmds, JS_TO_IR | JS_ONES, port->irPostPadBits, NULL, NULL, state); } } else { if (port->drPrePadBits > 0) { js_add_shift (cmds, 0, port->drPrePadBits, NULL, NULL, JS_DRSHIFT); } if (port->drPostPadBits == 0) { js_add_shift (cmds, 0, bits, ((wrBuffer == NULL) ? NULL : &wrPtr), ((rdBuffer == NULL) ? NULL : &rdPtr), state); } else { js_add_shift (cmds, 0, bits, ((wrBuffer == NULL) ? NULL : &wrPtr), ((rdBuffer == NULL) ? NULL : &rdPtr), JS_DRSHIFT); js_add_shift (cmds, 0, port->drPostPadBits, NULL, NULL, state); } } if (wrBuffer) // copy input tdi data to cmd tdi buffer. { memcpy (wrPtr, wrBuffer, getByteCountFromBitCount (bits)); } status = js_run_command_sequence(cmds); if (rdBuffer) // copy cmd tdo buffer to tdo buffer. { memcpy (rdBuffer, rdPtr, getByteCountFromBitCount (bits)); } js_delete_command_sequence(cmds); return (status); } /*static int update_clock_frequency( js_port_impl_t *port) { return 0; }*/ static int get_property( js_lib_port_t *port_arg, js_property_kind_t kind, js_property_value_t *valuep) { js_port_impl_t *port = (js_port_impl_t *)port_arg; js_set_last_error(port->lib.base.server, "unsupported property"); return -1; } static int set_property( js_lib_port_t *port_arg, js_property_kind_t kind, js_property_value_t value) { js_port_impl_t *port = (js_port_impl_t *)port_arg; js_set_last_error(port->lib.base.server, "unsupported property"); return -1; } static int run_command_sequence( js_lib_command_sequence_t *cmds) { js_port_impl_t *port = (js_port_impl_t *)cmds->base.node->port; js_command_impl_t *cmd_start; js_command_impl_t *cmd_end; if (js_clear_command_sequence(&port->cmdseq->base) < 0 || js_lib_normalize_command_sequence(port->cmdseq, cmds) < 0) return -1; cmd_start = (js_command_impl_t *)port->cmdseq->cmd_list; cmd_end = cmd_start + port->cmdseq->cmd_count; js_command_impl_t *cmd = cmd_start; js_state_t state = port->state; while (cmd < cmd_end) { js_command_kind_t kind = cmd->lib.kind; switch (kind) { case JS_CMD_SET_STATE: { navigateTAP (state, cmd->lib.state); state = cmd->lib.state; // save current state break; } case JS_CMD_SHIFT: { if (cmd->lib.flags & JS_TO_IR) { navigateTAP (state, JS_IRSHIFT); state = JS_IRSHIFT; } else { navigateTAP (state, JS_DRSHIFT); state = JS_DRSHIFT; } if (jtagShiftTDIBits (cmd->lib.tdi_buf, cmd->lib.tdo_buf, cmd->lib.count, cmd->lib.state, cmd->lib.flags)) { /* Handle state change after scan */ if (state != cmd->lib.state) { if (cmd->lib.flags & JS_TO_IR) { state = JS_IREXIT1; } else { state = JS_DREXIT1; } navigateTAP (state, cmd->lib.state); state = cmd->lib.state; } } break; } default: fprintf(stderr, "write_commands: unsupported command %d\n", kind); break; } cmd++; } port->state = state; // save current state return 0; } static int get_port_descr_list( js_lib_server_t *server, js_port_descr_t **port_listp) { return 1; } int open_port( js_lib_server_t *server, js_port_descr_t *port_descr, js_lib_port_t **result) { struct js_zynq *js = (struct js_zynq *)server; js_port_impl_t *port; js_node_t *node; port = (js_port_impl_t *)malloc(sizeof *port); if (port == NULL) { js_set_last_error(&server->base, "end of memory"); return -1; } memset(port, 0, sizeof *port); port->lib.base.server = &server->base; /* Initialize root node */ port->lib.base.root_node = node = &port->root_node_obj; node->port = &port->lib.base; node->is_tap = 1; node->is_active = 1; node->idcode = JS_DUMMY_IDCODE; node->name = "whole scan chain"; port->lib.get_property = get_property; port->lib.set_property = set_property; port->lib.run_command_sequence = run_command_sequence; port->lib.close_port = close_port; if ((port->cmdseq = (js_lib_command_sequence_t *)js_create_command_sequence(node)) == NULL) { set_last_error(js, "end of memory"); goto error; } port->cmdseq->cmd_size = sizeof(js_command_impl_t); port->irPrePadBits = 0; port->irPostPadBits = 0; port->drPrePadBits = 0; port->drPostPadBits = 0; // Initialize JTAG drivers setPin (MIO_TCK, 0); setPin (MIO_TMS, 0); setPin (MIO_TDI, 0); // initialize state to JS_RESET port->state = JS_RESET; jtag_navigate (node->port, JS_RESET); *result = &port->lib; return 0; error: return -1; } static int close_port( js_lib_port_t *port_arg) { js_printf ("\n\nClosing Port.\n\n"); js_port_impl_t *port = (js_port_impl_t *)port_arg; int ret = 0; setPin (MIO_TDI, 0); setPin (MIO_TMS, 0); setPin (MIO_TCK, 0); js_delete_command_sequence(&port->cmdseq->base); free (port); return ret; } static void deinit_server( js_lib_server_t *server) { struct js_zynq *js = (struct js_zynq *)server; if (js->port_list) free(js->port_list); free(js); } js_server_t *js_init_zynq() { struct js_zynq *js; if ((js = (struct js_zynq *)malloc(sizeof *js)) == NULL) { return NULL; } memset(js, 0, sizeof *js); js->js.get_port_descr_list = get_port_descr_list; js->js.open_port = open_port; js->js.deinit_server = deinit_server; return &js->js.base; } void JtagWrite(unsigned char row, unsigned char bit) { /* Following is the method to program 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 the command word dma=1; pgm=1; a_row<4:0> & a_bit<4:0> Continuously shift in MAGIC_CTS_WRITE Loop back to E1DR/UDR/SDS/CDR/E1DR/UDR Go to RTI and stay in RTI EXACTLY Tpgm = 12 us (tbd) and immediately exit to SDS Go to TLR to clear FUSE_CTS */ unsigned char wrBuffer [8]; int bits = 0; unsigned long long time = 0; unsigned long long time_start = 0; unsigned long long time_end = 0; unsigned int delay = 0; // program FUSE_USER bit in row 31 bit 0 //Go to TLR to clear FUSE_CTS jtag_navigate (g_port, JS_RESET); //Load FUSE_CTS instruction on IR jtag_setPreAndPostPads (g_port, 0, ZYNQ_DAP_IR_LENGTH, 0, 1); bits = ZYNQ_TAP_IR_LENGTH; // xc7z020 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] = (unsigned char)((row<<3)| 0x3); //Enable DMA, program and select row. wrBuffer [1] = bit; //bit position wrBuffer [2] = 0x00; wrBuffer [3] = 0x00; //Magic word. wrBuffer [4] = 0xAC; wrBuffer [5] = 0x28; wrBuffer [6] = 0x8A; wrBuffer [7] = 0xA0; bits = 64; // fuse_cts data length /* Step to CDR/SDR to shift in the command word * dma=1; pgm=1; a_row<4:0> & a_bit<4:0> * Continuously shift in MAGIC_CTS_WRITE */ 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); //Go to RTI and stay in RTI EXACTLY Tpgm = 12 us (tbd) and immediately exit to SDS time_start = XilSKey_Efuse_GetTime(); jtag_navigate (g_port, JS_IDLE); time_end = XilSKey_Efuse_GetTime(); delay = (u32)((time_end - time_start)/(TimerTicksfor100ns)); //Here we will be providing 12us delay. if(delay < 110) { XilSKey_Efuse_SetTimeOut(&time, 110-delay); while(1) { if(XilSKey_Efuse_IsTimerExpired(time) == 1) break; } } jtag_navigate (g_port, JS_DRSELECT); jtag_navigate (g_port, JS_IRSELECT); jtag_navigate (g_port, JS_RESET); } void JtagRead(unsigned char row, unsigned int * row_data, unsigned char marginOption) { /* Following is the 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 a_row<4:0>; dma=1; pgm=0; tp_sel<1:0>; ecc_dma Shift in MAGIC_CTS_WRITE "A08A28AC" Step to E1DR/UDR to update FUSE_CTS reg Step to SDS/CDR/SDR to shift out captured row, while shifting in a new command with next row address w/ or w/o new tp_sel or ecc_dma setting Captured macro word (32 bits) is stored in jtag_dr[63:32] If ecc_dma = 1, jtag_dr[61:32] = {DED check-sum, SEC syndrome, decoded payload} */ unsigned char wrBuffer [8]; unsigned char rdBuffer [8]; int bits = 8; unsigned char * row_data_ptr = (unsigned char *)row_data; // read 64-bit eFUSE dna //Go to TLR to clear FUSE_CTS jtag_navigate (g_port, JS_RESET); //Load FUSE_CTS instruction on IR jtag_setPreAndPostPads (g_port, 0, ZYNQ_DAP_IR_LENGTH, 0, 1); bits = ZYNQ_TAP_IR_LENGTH; // xc7z020 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] = (unsigned char)((row<<3)| 0x1); //Enable DMA and select the row number. wrBuffer [1] = (unsigned char)(marginOption<<5); wrBuffer [2] = 0x00; wrBuffer [3] = 0x00; //Magic word. wrBuffer [4] = 0xAC; wrBuffer [5] = 0x28; wrBuffer [6] = 0x8A; wrBuffer [7] = 0xA0; bits = 64; // fuse_cts data length jtag_shift (g_port, ATOMIC_DR_SCAN, bits, wrBuffer, NULL, JS_DRSELECT); jtag_shift (g_port, ATOMIC_DR_SCAN, bits, NULL, rdBuffer, JS_DRSELECT); row_data_ptr[0] = rdBuffer [4]; row_data_ptr[1] = rdBuffer [5]; row_data_ptr[2] = rdBuffer [6]; row_data_ptr[3] = rdBuffer [7]; } int JtagValidateMioPins(void) { /* * Make sure that each every MIO pin defined is valid */ if((g_mio_jtag_tdi < 0) || (g_mio_jtag_tdi > 53)) return 1; if((g_mio_jtag_tdo < 0) || (g_mio_jtag_tdo > 53)) return 1; if((g_mio_jtag_tck < 0) || (g_mio_jtag_tck > 53)) return 1; if((g_mio_jtag_tms < 0) || (g_mio_jtag_tms > 53)) return 1; if((g_mio_jtag_mux_sel < 0) || (g_mio_jtag_mux_sel > 53)) return 1; /* * Make sure that MIO pins defined for JTAG operation are unique among themselves */ if((g_mio_jtag_tdi == g_mio_jtag_tdo)|| (g_mio_jtag_tdi == g_mio_jtag_tck)|| (g_mio_jtag_tdi == g_mio_jtag_tms)|| (g_mio_jtag_tdi == g_mio_jtag_mux_sel)) return 1; if((g_mio_jtag_tdo == g_mio_jtag_tck)|| (g_mio_jtag_tdo == g_mio_jtag_tms)|| (g_mio_jtag_tdo == g_mio_jtag_mux_sel)) return 1; if((g_mio_jtag_tck == g_mio_jtag_tms)|| (g_mio_jtag_tck == g_mio_jtag_mux_sel)) return 1; if(g_mio_jtag_tms == g_mio_jtag_mux_sel) return 1; return 0; } 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; g_mio_jtag_mux_sel = InstancePtr->JtagMioMuxSel; g_mux_sel_def_val = InstancePtr->JtagMuxSelLineDefVal; status = JtagValidateMioPins(); if(status != 0) { return 1; } if((g_mux_sel_def_val != 0) && (g_mux_sel_def_val != 1)) { return 1; } JtagInitGpio(); g_js = js_init_zynq(); if (g_js == NULL) { fprintf(stderr, "cannot create JTAG server\n"); return 1; } if (js_open_port(g_js, g_useport, &g_port) < 0) { js_printf("%s\n", js_get_last_error(g_js)); retval = 1; goto do_deinit; } if ((num_taps = js_detect_taps(g_port, &tap_codes)) < 0) { js_printf("detect_taps error: %s\n", js_get_last_error(g_js)); retval = 1; goto do_deinit; } js_printf("idcodes: "); for (i = num_taps; i > 0; i--) { if (i != num_taps){ js_printf(" "); } js_printf("%08x", (unsigned int)tap_codes[i - 1]); } js_printf("\n"); //Check if one of the tap code is for Zynq DAP ID: 4ba00477 for (i = 0; i < num_taps; i++) { if(tap_codes[i] == ZYNQ_DAP_ID){ break; } } if(i == num_taps) { retval = 1; } if (tap_codes){ free(tap_codes); } return retval; do_deinit: if (g_port != NULL) js_close_port(g_port); js_deinit_server(g_js); return retval; } /****************************************************************************/ /** * * This function initializes JTAG server for use in BBRAM algorithm * * @param BBRAM instance pointer * * @return * * - XST_FAILURE - In case of failure * - XST_SUCCESS - In case of Success * * * @note * *****************************************************************************/ int JtagServerInitBbram(XilSKey_Bbram *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; g_mio_jtag_mux_sel = InstancePtr->JtagMioMuxSel; g_mux_sel_def_val = InstancePtr->JtagMuxSelLineDefVal; status = JtagValidateMioPins(); if(status != 0) { return 1; } if((g_mux_sel_def_val != 0) && (g_mux_sel_def_val != 1)) { return 1; } JtagInitGpio(); g_js = js_init_zynq(); if (g_js == NULL) { fprintf(stderr, "cannot create JTAG server\n"); return 1; } if (js_open_port(g_js, g_useport, &g_port) < 0) { js_printf("%s\n", js_get_last_error(g_js)); retval = 1; goto do_deinit; } if ((num_taps = js_detect_taps(g_port, &tap_codes)) < 0) { js_printf("detect_taps error: %s\n", js_get_last_error(g_js)); retval = 1; goto do_deinit; } js_printf("idcodes: "); for (i = num_taps; i > 0; i--) { if (i != num_taps){ js_printf(" "); } js_printf("%08x", (unsigned int)tap_codes[i - 1]); } js_printf("\n"); //Check if one of the tap code is for Zynq DAP ID: 4ba00477 for (i = 0; i < num_taps; i++) { if(tap_codes[i] == ZYNQ_DAP_ID){ break; } } if(i == num_taps) { retval = 1; } if (tap_codes){ free(tap_codes); } return retval; do_deinit: if (g_port != NULL) js_close_port(g_port); js_deinit_server(g_js); return retval; } /****************************************************************************/ /** * * This function implements the BBRAM algorithm initialization * * @param BBRAM instance pointer * * @return * * - XST_FAILURE - In case of failure * - XST_SUCCESS - In case of Success * * * @note * *****************************************************************************/ int Bbram_Init(XilSKey_Bbram *InstancePtr) { u8 IRCaptureStatus = 0; u8 WriteBuffer[4]; unsigned long long Time = 0; jtag_navigate (g_port, JS_RESET); jtag_navigate (g_port, JS_IDLE); /* Load bypass */ jtag_setPreAndPostPads (g_port, IRHEADER, IRTRAILER, DRHEADER, DRTRAILER); WriteBuffer[0] = BYPASS; jtag_shift (g_port, ATOMIC_IR_SCAN, IRLENGTH, WriteBuffer, NULL, JS_IDLE); /* * Load JPROGRAM */ jtag_setPreAndPostPads (g_port, IRHEADER, IRTRAILER, DRHEADER, DRTRAILER); WriteBuffer[0] = JPROGRAM; jtag_shift (g_port, ATOMIC_IR_SCAN, IRLENGTH, WriteBuffer, NULL, JS_IDLE); /* * Load ISC_NOOP */ WriteBuffer[0] = ISC_NOOP; jtag_shift (g_port, ATOMIC_IR_SCAN, IRLENGTH, WriteBuffer, NULL, JS_IDLE); /* * Wait 100 msec */ Time = 0; XilSKey_Efuse_SetTimeOut(&Time, TIMER_100MS); while(1){ if(XilSKey_Efuse_IsTimerExpired(Time) == 1) break; } /* * Load ISC_NOOP */ WriteBuffer[0] = ISC_NOOP; jtag_shift (g_port, ATOMIC_IR_SCAN, IRLENGTH, WriteBuffer, &IRCaptureStatus, JS_IDLE); /* * Read IRCapture status and check for init_complete bit to be set */ if((IRCaptureStatus & INITCOMPLETEMASK) != INITCOMPLETEMASK){ return XST_FAILURE; } return XST_SUCCESS; } /****************************************************************************/ /** * * This function implements the BBRAM program key * * @param BBRAM instance pointer * * @return * * - XST_FAILURE - In case of failure * - XST_SUCCESS - In case of Success * * * @note * *****************************************************************************/ int Bbram_ProgramKey(XilSKey_Bbram *InstancePtr) { u32 KeyCnt; u8 WriteBuffer[4]; u8 TckCnt; /* * Initial state - RTI */ jtag_navigate (g_port, JS_IDLE); /* * Load ISC_ENABLE */ jtag_setPreAndPostPads (g_port, IRHEADER, IRTRAILER, DRHEADER, DRTRAILER); WriteBuffer[0] = ISC_ENABLE; jtag_shift (g_port, ATOMIC_IR_SCAN, IRLENGTH, WriteBuffer, NULL, JS_IRPAUSE); /* * Shift 5 bits (0x15) */ WriteBuffer[0] = DR_EN; jtag_shift (g_port, ATOMIC_DR_SCAN, DRLENGTH_EN, WriteBuffer, NULL, JS_IDLE); /* * Wait 12 TCK */ for(TckCnt = 0; TckCnt < 12; TckCnt++){ setPin (MIO_TCK, 1); setPin (MIO_TCK, 0); } /* * Load ISC_PROGRAM_KEY */ WriteBuffer[0] = ISC_PROGRAM_KEY; jtag_shift (g_port, ATOMIC_IR_SCAN, IRLENGTH, WriteBuffer, NULL, JS_IRPAUSE); /* * Shift 0xFFFFFFFF */ WriteBuffer[0] = 0xFF; WriteBuffer[1] = 0xFF; WriteBuffer[2] = 0xFF; WriteBuffer[3] = 0xFF; jtag_shift (g_port, ATOMIC_DR_SCAN, DRLENGTH_PROGRAM, &WriteBuffer[0], NULL, JS_IDLE); /* * Wait 9 TCK */ for(TckCnt = 0; TckCnt < 9; TckCnt++){ setPin (MIO_TCK, 1); setPin (MIO_TCK, 0); } /* * Load ISC_PROGRAM */ WriteBuffer[0] = ISC_PROGRAM; jtag_shift (g_port, ATOMIC_IR_SCAN, IRLENGTH, WriteBuffer, NULL, JS_IRPAUSE); /* * Shift 0xFFFFFFFF */ WriteBuffer[0] = 0xFF; WriteBuffer[1] = 0xFF; WriteBuffer[2] = 0xFF; WriteBuffer[3] = 0xFF; jtag_shift (g_port, ATOMIC_DR_SCAN, DRLENGTH_PROGRAM, &WriteBuffer[0], NULL, JS_IDLE); /* * Wait 1 TCK */ setPin (MIO_TCK, 1); setPin (MIO_TCK, 0); /* * Program key - 32 bits at a time */ KeyCnt = 0; while(KeyCnt < NUMCHARINKEY){ /* * Load ISC_PROGRAM */ WriteBuffer[0] = ISC_PROGRAM; jtag_shift (g_port, ATOMIC_IR_SCAN, IRLENGTH, WriteBuffer, NULL, JS_IRPAUSE); /* * Copy key from Instance structure */ WriteBuffer[3] = InstancePtr->AESKey[KeyCnt++]; WriteBuffer[2] = InstancePtr->AESKey[KeyCnt++]; WriteBuffer[1] = InstancePtr->AESKey[KeyCnt++]; WriteBuffer[0] = InstancePtr->AESKey[KeyCnt++]; /* * Shift 32 bit key */ jtag_shift (g_port, ATOMIC_DR_SCAN, DRLENGTH_PROGRAM, &WriteBuffer[0], NULL, JS_IDLE); /* * Wait 1 TCK */ setPin (MIO_TCK, 1); setPin (MIO_TCK, 0); } /* * Reset to IDLE */ jtag_navigate (g_port, JS_IDLE); return XST_SUCCESS; } /****************************************************************************/ /** * * This function implements the BBRAM verify key. * Program and verify key have to be done together; * These API's cannot be used independently. * * @param BBRAM instance pointer * * @return * * - XST_FAILURE - In case of failure * - XST_SUCCESS - In case of Success * * * @note * *****************************************************************************/ int Bbram_VerifyKey(XilSKey_Bbram *InstancePtr) { u32 KeyCnt; u32 BufferCnt; u32 KeyCnt_Char; u32 ReadKey_Char; u8 WriteBuffer[5]; u8 ReadBuffer[5]; u8 TckCnt; unsigned long long DataReg = 0; int Status = XST_SUCCESS; /* * Initial state - RTI */ jtag_navigate (g_port, JS_IDLE); jtag_setPreAndPostPads (g_port, IRHEADER, IRTRAILER, DRHEADER, DRTRAILER); /* * Load ISC_ENABLE */ WriteBuffer[0] = ISC_ENABLE; jtag_shift (g_port, ATOMIC_IR_SCAN, IRLENGTH, WriteBuffer, NULL, JS_IRPAUSE); /* * Shift 5 bits (0x15) */ WriteBuffer[0] = DR_EN; jtag_shift (g_port, ATOMIC_DR_SCAN, DRLENGTH_EN, WriteBuffer, NULL, JS_IDLE); /* * Wait 12 TCK */ for(TckCnt = 0; TckCnt < 12; TckCnt++){ setPin (MIO_TCK, 1); setPin (MIO_TCK, 0); } /* * Load ISC_READ */ WriteBuffer[0] = ISC_READ; jtag_shift (g_port, ATOMIC_IR_SCAN, IRLENGTH, WriteBuffer, NULL, JS_IRPAUSE); /* * Shift 0x1FFFFFFFFF */ WriteBuffer[0] = 0xFF; WriteBuffer[1] = 0xFF; WriteBuffer[2] = 0xFF; WriteBuffer[3] = 0xFF; WriteBuffer[4] = 0x1F; /* * Clear Read Buffer */ for(BufferCnt = 0; BufferCnt < 5; BufferCnt++){ ReadBuffer[BufferCnt] = 0xFF; } /* * Shift 37 bits and read 37 bits */ jtag_shift (g_port, ATOMIC_DR_SCAN, DRLENGTH_VERIFY, WriteBuffer, ReadBuffer, JS_IDLE); /* * Combine read bits */ DataReg = ReadBuffer[4]; DataReg = DataReg << 8; DataReg = DataReg | ReadBuffer[3]; DataReg = DataReg << 8; DataReg = DataReg | ReadBuffer[2]; DataReg = DataReg << 8; DataReg = DataReg | ReadBuffer[1]; DataReg = DataReg << 8; DataReg = DataReg | ReadBuffer[0]; if((DataReg & DATAREGCLEAR) != DATAREGCLEAR){ return XST_FAILURE; } /* * Wait 9 TCK */ for(TckCnt = 0; TckCnt < 9; TckCnt++){ setPin (MIO_TCK, 1); setPin (MIO_TCK, 0); } /* * Shift 37 bits for each 32 bits of key to be read. * Consider 32 msb bits of the 37 bits read as key. */ KeyCnt = 0; while(KeyCnt < NUMWORDINKEY){ /* * Load ISC_READ */ WriteBuffer[0] = ISC_READ; jtag_shift (g_port, ATOMIC_IR_SCAN, IRLENGTH, WriteBuffer, NULL, JS_IRPAUSE); WriteBuffer[0] = 0xFF; WriteBuffer[1] = 0xFF; WriteBuffer[2] = 0xFF; WriteBuffer[3] = 0xFF; WriteBuffer[4] = 0x1F; /* * Clear Read Buffer */ for(BufferCnt = 0; BufferCnt < 5; BufferCnt++){ ReadBuffer[BufferCnt] = 0; } /* * Shift 37 bits and read 37 bits */ jtag_shift (g_port, ATOMIC_DR_SCAN, DRLENGTH_VERIFY, WriteBuffer, ReadBuffer, JS_IDLE); /* * Wait 1 TCK */ setPin (MIO_TCK, 1); setPin (MIO_TCK, 0); /* * Combine the 8 bit array and shift out the 5 LSB bits */ DataReg = ReadBuffer[4]; DataReg = DataReg << 8; DataReg = DataReg | ReadBuffer[3]; DataReg = DataReg << 8; DataReg = DataReg | ReadBuffer[2]; DataReg = DataReg << 8; DataReg = DataReg | ReadBuffer[1]; DataReg = DataReg << 8; DataReg = DataReg | ReadBuffer[0]; Bbram_ReadKey[KeyCnt++] = DataReg >> NUMLSBSTATUSBITS; } /* * Compare read key with programmed key */ KeyCnt_Char = 0; for(KeyCnt = 0; KeyCnt < NUMWORDINKEY; KeyCnt++){ ReadKey_Char = Bbram_ReadKey[KeyCnt]; if((ReadKey_Char & 0xFF) != InstancePtr->AESKey[KeyCnt_Char + 3]){ Status = XST_FAILURE; break; } ReadKey_Char = ReadKey_Char >> 8; if((ReadKey_Char & 0xFF) != InstancePtr->AESKey[KeyCnt_Char + 2]){ Status = XST_FAILURE; break; } ReadKey_Char = ReadKey_Char >> 8; if((ReadKey_Char & 0xFF) != InstancePtr->AESKey[KeyCnt_Char + 1]){ Status = XST_FAILURE; break; } ReadKey_Char = ReadKey_Char >> 8; if((ReadKey_Char & 0xFF) != InstancePtr->AESKey[KeyCnt_Char]){ Status = XST_FAILURE; break; } KeyCnt_Char = KeyCnt_Char + 4; } /* * Load ISC_DISABLE */ WriteBuffer[0] = ISC_DISABLE; jtag_shift (g_port, ATOMIC_IR_SCAN, IRLENGTH, WriteBuffer, NULL, JS_IDLE); /* * Wait 12 TCK */ for(TckCnt = 0; TckCnt < 12; TckCnt++){ setPin (MIO_TCK, 1); setPin (MIO_TCK, 0); } return Status; } /****************************************************************************/ /** * * This function does de-initialization * * @param none * * @return * * none * * * @note * *****************************************************************************/ void Bbram_DeInit(void) { u8 WriteBuffer[5]; /* * Load BYPASS */ jtag_setPreAndPostPads (g_port, IRHEADER_BYP, IRTRAILER_BYP, DRHEADER_BYP, DRTRAILER_BYP); WriteBuffer[0] = BYPASS; jtag_shift (g_port, ATOMIC_IR_SCAN, IRLENGTH, WriteBuffer, NULL, JS_IDLE); WriteBuffer[0] = IRDEINIT_L; WriteBuffer[1] = IRDEINIT_H; jtag_shift (g_port, ATOMIC_IR_SCAN, IRDEINITLEN, WriteBuffer, NULL, JS_IDLE); WriteBuffer[0] = DRDEINIT; jtag_shift (g_port, ATOMIC_DR_SCAN, DRDEINITLEN, WriteBuffer, NULL, JS_IDLE); jtag_navigate (g_port, JS_RESET); jtag_navigate (g_port, JS_IDLE); /* * De-initialization */ if (g_port != NULL){ js_close_port(g_port); } js_deinit_server(g_js); }