embeddedsw/lib/sw_services/xilskey/src/xilskey_jscmd.c
Harini Katakam 2e6c402ee2 xilskey: Add check for JS_ONES flag in jtag lib
Add check for JS_ONES flag and handle it.

Signed-off-by: Harini Katakam <harinik@xilinx.com>
2014-11-25 21:38:25 +05:30

1810 lines
No EOL
50 KiB
C
Executable file

/******************************************************************************
*
* 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
* <pre>
* 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)
*
* </pre>
*
*
******************************************************************************/
#include <stdio.h>
#include <stdarg.h>
#include <string.h>
#include <assert.h>
#ifdef _WIN32
#include <Windows.h>
#if defined(_MSC_VER)
# pragma warning(disable:4996) /* 'strcpy': This function or variable may be unsafe */
#endif
typedef long ssize_t;
#else
#include <unistd.h>
#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);
}