From 22b5585a094841862905f075f79f5d1a3ffb0f9f Mon Sep 17 00:00:00 2001
From: Venkata Naga Sai Krishna Kolapalli <venkatan@xilinx.com>
Date: Fri, 3 Apr 2015 17:51:12 +0530
Subject: [PATCH] xilskey_v2_1 : created new v2.1 version for xilskey.

This patch deprecates the old v2.0 version and created
new v2.1 version for xilskey library.

Signed-off-by: Venkata Naga Sai Krishna Kolapalli <venkatan@xilinx.com>
---
 lib/sw_services/xilskey/data/xilskey.mld      |   51 +
 lib/sw_services/xilskey/data/xilskey.tcl      |   86 +
 .../xilskey/examples/xilskey_bbram_example.c  |  154 ++
 .../xilskey/examples/xilskey_efuse_example.c  |  626 ++++++
 .../xilskey/examples/xilskey_input.h          |  396 ++++
 lib/sw_services/xilskey/src/Makefile          |   91 +
 lib/sw_services/xilskey/src/changelog.txt     |   25 +
 .../xilskey/src/include/xilskey_bbram.h       |  203 ++
 .../xilskey/src/include/xilskey_epl.h         |  193 ++
 .../xilskey/src/include/xilskey_eps.h         |  105 +
 .../xilskey/src/include/xilskey_utils.h       |  463 +++++
 lib/sw_services/xilskey/src/xilskey_bbram.c   |  172 ++
 lib/sw_services/xilskey/src/xilskey_epl.c     | 1342 ++++++++++++
 lib/sw_services/xilskey/src/xilskey_eps.c     | 1521 ++++++++++++++
 lib/sw_services/xilskey/src/xilskey_epshw.h   |  484 +++++
 lib/sw_services/xilskey/src/xilskey_js.h      |  391 ++++
 lib/sw_services/xilskey/src/xilskey_jscmd.c   | 1810 +++++++++++++++++
 lib/sw_services/xilskey/src/xilskey_jscmd.h   |  166 ++
 lib/sw_services/xilskey/src/xilskey_jslib.c   |  441 ++++
 lib/sw_services/xilskey/src/xilskey_jslib.h   |  219 ++
 lib/sw_services/xilskey/src/xilskey_jtag.h    |   45 +
 lib/sw_services/xilskey/src/xilskey_utils.c   |  775 +++++++
 22 files changed, 9759 insertions(+)
 create mode 100755 lib/sw_services/xilskey/data/xilskey.mld
 create mode 100755 lib/sw_services/xilskey/data/xilskey.tcl
 create mode 100644 lib/sw_services/xilskey/examples/xilskey_bbram_example.c
 create mode 100644 lib/sw_services/xilskey/examples/xilskey_efuse_example.c
 create mode 100644 lib/sw_services/xilskey/examples/xilskey_input.h
 create mode 100644 lib/sw_services/xilskey/src/Makefile
 create mode 100755 lib/sw_services/xilskey/src/changelog.txt
 create mode 100644 lib/sw_services/xilskey/src/include/xilskey_bbram.h
 create mode 100644 lib/sw_services/xilskey/src/include/xilskey_epl.h
 create mode 100644 lib/sw_services/xilskey/src/include/xilskey_eps.h
 create mode 100644 lib/sw_services/xilskey/src/include/xilskey_utils.h
 create mode 100644 lib/sw_services/xilskey/src/xilskey_bbram.c
 create mode 100644 lib/sw_services/xilskey/src/xilskey_epl.c
 create mode 100644 lib/sw_services/xilskey/src/xilskey_eps.c
 create mode 100644 lib/sw_services/xilskey/src/xilskey_epshw.h
 create mode 100644 lib/sw_services/xilskey/src/xilskey_js.h
 create mode 100644 lib/sw_services/xilskey/src/xilskey_jscmd.c
 create mode 100644 lib/sw_services/xilskey/src/xilskey_jscmd.h
 create mode 100644 lib/sw_services/xilskey/src/xilskey_jslib.c
 create mode 100644 lib/sw_services/xilskey/src/xilskey_jslib.h
 create mode 100644 lib/sw_services/xilskey/src/xilskey_jtag.h
 create mode 100644 lib/sw_services/xilskey/src/xilskey_utils.c

diff --git a/lib/sw_services/xilskey/data/xilskey.mld b/lib/sw_services/xilskey/data/xilskey.mld
new file mode 100755
index 00000000..41436f50
--- /dev/null
+++ b/lib/sw_services/xilskey/data/xilskey.mld
@@ -0,0 +1,51 @@
+###############################################################################
+#
+# 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.
+#
+###############################################################################
+#
+# Modification History
+#
+# Ver   Who  Date     Changes
+# ----- ---- -------- -----------------------------------------------
+# 1.00a rpo  04/24/13 Initial Release
+#
+##############################################################################
+
+OPTION psf_version = 2.1;
+
+BEGIN LIBRARY xilskey
+  OPTION copyfiles = all;
+  OPTION REQUIRES_OS = (standalone);
+  OPTION SUPPORTED_PERIPHERALS = (cortexa9);
+  OPTION APP_LINKER_FLAGS = "-Wl,--start-group,-lxilskey,-lxil,-lgcc,-lc,--end-group";
+  OPTION desc = "Xilinx Secure Key Library ";
+  OPTION VERSION = 2.1;
+  OPTION NAME = xilskey;
+END LIBRARY
diff --git a/lib/sw_services/xilskey/data/xilskey.tcl b/lib/sw_services/xilskey/data/xilskey.tcl
new file mode 100755
index 00000000..ffe47050
--- /dev/null
+++ b/lib/sw_services/xilskey/data/xilskey.tcl
@@ -0,0 +1,86 @@
+###############################################################################
+#
+# 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.
+#
+###############################################################################
+#
+# Modification History
+#
+# Ver   Who  Date     Changes
+# ----- ---- -------- -----------------------------------------------
+# 1.00a rpo  04/25/13 Initial Release
+##############################################################################
+
+#---------------------------------------------
+# skey_drc
+#---------------------------------------------
+proc skey_drc {libhandle} {
+
+}
+
+proc generate {libhandle} {
+
+}
+
+#-------
+# post_generate: called after generate called on all libraries
+#-------
+proc post_generate {libhandle} {
+
+	xgen_opts_file $libhandle
+}
+
+#-------
+# execs_generate: called after BSP's, libraries and drivers have been compiled
+#	This procedure builds the libxilskey.a library
+#-------
+proc execs_generate {libhandle} {
+
+}
+
+proc xgen_opts_file {libhandle} {
+
+
+	# Copy the include files to the include directory
+	set srcdir [file join src include]
+	set dstdir [file join .. .. include]
+
+	# Create dstdir if it does not exist
+	if { ! [file exists $dstdir] } {
+		file mkdir $dstdir
+	}
+
+	# Get list of files in the srcdir
+	set sources [glob -join $srcdir *.h]
+
+	# Copy each of the files in the list to dstdir
+	foreach source $sources {
+		file copy -force $source $dstdir
+	}
+}
diff --git a/lib/sw_services/xilskey/examples/xilskey_bbram_example.c b/lib/sw_services/xilskey/examples/xilskey_bbram_example.c
new file mode 100644
index 00000000..9f0dec0f
--- /dev/null
+++ b/lib/sw_services/xilskey/examples/xilskey_bbram_example.c
@@ -0,0 +1,154 @@
+/******************************************************************************
+*
+* 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_bbram_example.c
+* @note
+*	Example illustrates the method of programming the AES key to BBRAM.
+*	The user key should be mentioned in xilskey_input.h.
+*	BBRAM is a battery backed RAM and there is no restriction on the
+*	number of times key can programmed.
+*	This algorithm only wokrs when program and verify key are done
+*	together and in that order.
+.
+* Procedure:
+* 1. Create a hardware project using the appropriate design.
+* 2. Create a BSP.
+* 3. Create fsbl
+* 4. Create an application project using bbram example and xilskey_input.h
+* 5. The 256 bit key to be programmed has to be mentioned
+* 6. A hardware setup which dedicates four MIO pins for JTAG signals
+*    should be used and the MIO pins should be mentioned in xilskey_input.h
+*    There should be a method to download this example and have the
+*    MIO pins connected to JTAG before running this application.
+* 7. Run the application which will program and verify the BBRAM key
+* 8. After programming and veifying the key, power off.
+* 9. Place a BBRAM key encrypted boot image in one of the boot devices,
+*    set the appropriate boot pins and power on.
+* 10. The bbram example will be run from DDR with the default linker.
+* 11. To run from OCM, modify the linker to map all sections to
+*     ps7_ram_0_S_AXI_BASEADDR instead of ps7_ddr_0_S_AXI_BASEADDR.
+*
+*
+* MODIFICATION HISTORY:
+*
+* Ver   Who  	Date     Changes
+* ----- ---- 	-------- --------------------------------------------------------
+* 1.01a hk      09/18/13 First release
+*
+*
+****************************************************************************/
+/***************************** Include Files *********************************/
+#include "stdio.h"
+#include "xil_io.h"
+#include "xstatus.h"
+#include "xilskey_utils.h"
+#include "xilskey_bbram.h"
+#include "xilskey_input.h"
+/************************** Constant Definitions *****************************/
+/**************************** Type Definitions ******************************/
+/***************** Macros (Inline Functions) Definitions ********************/
+/************************** Variable Definitions ****************************/
+XilSKey_Bbram InstancePtr;
+/************************** Function Prototypes *****************************/
+int XilSKey_Bbram_InitData(XilSKey_Bbram *BbramInstancePtr);
+/***************************************************************************/
+
+int main()
+{
+	int Status;
+	u8 StartProg;
+
+	xil_printf(" BBRAM Example start \r\n");
+
+	Status = XilSKey_Bbram_InitData(&InstancePtr);
+	if(Status != XST_SUCCESS) {
+		xil_printf(" BBRAM Example failed \r\n");
+		return XST_FAILURE;
+	}
+
+	Status = XilSKey_Bbram_Program(&InstancePtr);
+	if(Status != XST_SUCCESS) {
+		xil_printf(" BBRAM Example failed \r\n");
+		return XST_FAILURE;
+	}
+
+	xil_printf(" Successfully programmed and verified BBRAM key \r\n");
+	return XST_SUCCESS;
+
+}
+
+/****************************************************************************/
+/**
+*
+*
+*  Function to initialize BBRAM instance
+*
+*
+* @param	BBRAM instance pointer
+*
+* @return
+*
+*	- XST_SUCCESS - In case of Success
+*	- XST_FAILURE - If initialization fails
+*
+* @note
+*
+*****************************************************************************/
+int XilSKey_Bbram_InitData(XilSKey_Bbram *BbramInstancePtr)
+{
+
+	u32 Status;
+
+	BbramInstancePtr->ForcePowerCycle		= 	XSK_BBRAM_FORCE_PCYCLE_RECONFIG;
+	BbramInstancePtr->JtagDisable			= 	XSK_BBRAM_DISABLE_JTAG_CHAIN;
+	BbramInstancePtr->JtagMioTDI 			=	XSK_BBRAM_MIO_JTAG_TDI;
+	BbramInstancePtr->JtagMioTDO			=	XSK_BBRAM_MIO_JTAG_TDO;
+	BbramInstancePtr->JtagMioTCK			=	XSK_BBRAM_MIO_JTAG_TCK;
+	BbramInstancePtr->JtagMioTMS			=	XSK_BBRAM_MIO_JTAG_TMS;
+	BbramInstancePtr->JtagMioMuxSel 		=	XSK_BBRAM_MIO_JTAG_MUX_SELECT;
+	BbramInstancePtr->JtagMuxSelLineDefVal	=  XSK_BBRAM_MIO_MUX_SEL_DEFAULT_VAL;
+
+	/*
+	 * Convert key given in xilskey_input.h and
+	 * assign it to the variable in instance.
+	 */
+	XilSKey_Efuse_ConvertStringToHexBE(XSK_BBRAM_AES_KEY,
+				&(BbramInstancePtr->AESKey[0]),
+				XSK_BBRAM_AES_KEY_SIZE_IN_BITS);
+
+	Status = XST_SUCCESS;
+	return Status;
+
+}
diff --git a/lib/sw_services/xilskey/examples/xilskey_efuse_example.c b/lib/sw_services/xilskey/examples/xilskey_efuse_example.c
new file mode 100644
index 00000000..1a50d5b3
--- /dev/null
+++ b/lib/sw_services/xilskey/examples/xilskey_efuse_example.c
@@ -0,0 +1,626 @@
+/******************************************************************************
+*
+* 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_efuse_example.c
+* @note
+*
+*  		Contains the api functions for the PS & PL eFUSE functionality.
+*  		eFUSE Application project is capable of programming the PS and PL eFUSE
+*  		bits given by the user. PS eFUSE holds the RSA primary key hash bits and
+*  		user feature bits, which will enable/disable some features in ZYNQ.
+*  		PL eFUSE holds the AES key, user key and some feature bits.
+*  		User has the provision to write PS eFUSE & PL eFUSE independently or
+*  		can combine together. This can be selected by using the compilation
+*  		switch provided in xilskey_input.h. XSK_EFUSEPS_DRIVER should be
+*  		defined to enable PS functionality & XSK_EFUSEPL_DRIVER for PL
+*  		functionality.
+*
+*		eFUSE bits are one-time programmable. Once they are burnt, they
+*		cannot be changed. Make sure you enter the correct information before
+*		you program eFUSE bits.
+*
+*		POR reset is required for the eFUSE values to become into effect.
+*		Please do a POR reset after eFUSE writing.
+*
+*  		All the user configurable parameters for PS & PL eFUSE writing should be
+*  		defined in xilskey_input.h. By default, all the macros will be defined
+*  		with FALSE values.
+*
+*  		For PL eFUSE writing enabling the caches are necessary if the image is
+*  		executing from DDR. This will be done in  BSP by default. User has to
+*  		take care not to disable caches.
+*
+*		eFUSE writing procedure running out of DDR as an application:
+*		(This sequence is same as the existing flow described below)
+*
+*		1)	After providing the required inputs in xilskey_input.h, compile the
+*		   	project.
+*		2)	Take the latest FSBL (.elf) and stitch the <output>.elf	generated
+*			to it using the bootgen utility and generate a bootable	image.
+*		3)	Write the generated binary image into the flash device.
+*			(Ex: QSPI,NAND etc)
+*		4)	Execute image from flash which will write the mentioned eFUSE key
+*			bits.
+*
+*  		eFUSE driver compilation procedure for OCM:
+*
+*		1)	Open the linker script (lscript.ld) in the SDK project.
+*		2)	Now map all the sections points to �ps7_ram_0_S_AXI_BASEADDR�
+*			instead of �ps7_ddr_0_S_AXI_BASEADDR�.
+*
+*		Example: 	Click on the �Memory Region� tab for .text section & select
+*					�ps7_ram_0_S_AXI_BASEADDR� from the drop down list.
+*
+*		3)	Copy the ps7_init.c & ps7_init.h files from the hw_platform folder
+*			into the example folder.
+*		4)	Uncomment calling of �ps7_init()� routine in
+*			�xilskey_efuse_example.c�
+*		5)	Compile the project.
+*		6)	<project name>.elf  will be generated. This will be executed
+*			out of OCM.
+*
+*		SVF File Generation using <output>.elf :
+*
+*		1)	Use the below xmd to create the svf file from the above generated
+*			elf file. Please note that path to the elf file should be given in opt file.
+*
+*						�xmd �tcl efuse.tcl �opt efuse.opt�
+*
+*		2)	Output of the above command will be <O/p file name>.svf.
+*
+*
+* MODIFICATION HISTORY:
+*
+* Ver   Who  	Date     Changes
+* ----- ---- 	-------- --------------------------------------------------------
+* 1.00a rpoolla 04/26/13 First release
+* 1.02a hk      10/28/13 Added use of API's read status and key. PR# 735957.
+*
+*
+****************************************************************************/
+/***************************** Include Files *********************************/
+#include "stdio.h"
+#include "xil_io.h"
+#include "xstatus.h"
+#include "xilskey_utils.h"
+#include "xilskey_eps.h"
+#include "xilskey_epl.h"
+#include "xilskey_input.h"
+/************************** Constant Definitions *****************************/
+/**************************** Type Definitions ******************************/
+/***************** Macros (Inline Functions) Definitions ********************/
+/**
+ * Address for the Reboot Status Register
+ */
+#define REBOOT_STATUS_REG_ADDR 						(0xF8000258)
+/**
+ *  PL eFUSE aes key size in characters
+ */
+#define XSK_EFUSEPL_AES_KEY_STRING_SIZE              (64)
+/**
+ *  PL eFUSE user low key size in characters
+ */
+#define XSK_EFUSEPL_USER_LOW_KEY_STRING_SIZE         (2)
+/**
+ *  PL eFUSE user high key size in characters
+ */
+#define XSK_EFUSEPL_USER_HIGH_KEY_STRING_SIZE        (6)
+/**
+ *  User AES Key size in Bytes
+ */
+#define XSK_EFUSEPL_AES_KEY_SIZE_IN_BITS			(256)
+/**
+ *  User Low Key size in Bytes
+ */
+#define XSK_EFUSEPL_USER_LOW_KEY_SIZE_IN_BITS		(8)
+/**
+ *  User High Key size in Bytes
+ */
+#define XSK_EFUSEPL_USER_HIGH_KEY_SIZE_IN_BITS		(24)
+/**
+ * Key length definition for RSA KEY Hash
+ */
+/**
+ *  PS eFUSE RSA key Hash size in characters
+ */
+#define XSK_EFUSEPL_RSA_KEY_HASH_STRING_SIZE        (64)
+
+/*
+ * PS efuse status bit definitions
+ */
+#define XSK_EFUSEPS_STATUS_WP_BIT_LOW	0x1000
+#define XSK_EFUSEPS_STATUS_WP_BIT_HIGH	0x2000
+#define XSK_EFUSEPS_STATUS_RSA_EN		0x400
+#define XSK_EFUSEPS_STATUS_ROM_128_CRC	0x800
+
+/*
+ * PL efuse status bit definitions
+ */
+#define XSK_EFUSEPL_STATUS_FORCE_PCYCLE_RECONFIG	0x002
+#define XSK_EFUSEPL_STATUS_DISABLE_KEY_WRITE		0x004
+#define XSK_EFUSEPL_STATUS_DISABLE_AES_KEY_READ		0x008
+#define XSK_EFUSEPL_STATUS_DISABLE_USER_KEY_READ	0x010
+#define XSK_EFUSEPL_STATUS_DISABLE_FUSE_CNTRL_WRITE	0x020
+#define XSK_EFUSEPL_STATUS_EFUSE_SEC_ENABLE			0x100
+#define XSK_EFUSEPL_STATUS_JTAG_DISABLE				0x200
+#define XSK_EFUSEPL_STATUS_BBRAM_KEY_DISABLE		0x400
+
+/************************** Variable Definitions ****************************/
+/************************** Function Prototypes *****************************/
+/**
+ * Function used to convert the string to Hex in Little Endian format
+ */
+u32 XilSKey_Efuse_ConvertStringToHexLE(const char * Str, u8 * Buf, u32 Len);
+/**
+ * Function used to convert the string to Hex in Little Endian format
+ */
+u32 XilSKey_Efuse_ConvertStringToHexBE(const char * Str, u8 * Buf, u32 Len);
+/**
+ * Function used to validate the AES & RSA key provided as input
+ */
+u32 XilSKey_Efuse_ValidateKey(const char *Key, u32 Len);
+u32 XilSKey_EfusePs_InitData(XilSKey_EPs *PsInstancePtr);
+u32 XilSKey_EfusePl_InitData(XilSKey_EPl *PlInstancePtr);
+/*extern void ps7_init();*/
+/***************************************************************************/
+int main()
+{
+	u32 PlStatus = 0xFFFF;
+	u32 PsStatus = 0xFFFF;
+	u32 Status = 0;
+
+    /*ps7_init();*/
+#ifdef XSK_EFUSEPS_DRIVER
+	XilSKey_EPs PsInstancePtr;
+	u32 PsStatusBits = 0;
+
+	/**
+	 * Initialize the PS instance pointer with the data
+	 * populated in xilskey_input.h
+	 */
+	PsStatus = XilSKey_EfusePs_InitData(&PsInstancePtr);
+    if(PsStatus != XST_SUCCESS)	{
+		printf("PS Data Initialization failed\r\n");
+        goto EFUSE_ERROR;
+	}
+
+    /*
+     * Read the PS efuse status
+     * Change in these status bits will only be reflected after POR
+     */
+    PsStatus = XilSKey_EfusePs_ReadStatus(&PsInstancePtr, &PsStatusBits);
+    if(PsStatus != XST_SUCCESS)	{
+		printf("PS status read failed\r\n");
+        goto EFUSE_ERROR;
+	}
+
+    /*
+     * Print Efuse PS status bits
+     */
+    xil_printf("EfusePS status bits : 0x%x \n\r", PsStatusBits);
+
+    if((PsStatusBits & XSK_EFUSEPS_STATUS_WP_BIT_LOW) ||
+		(PsStatusBits & XSK_EFUSEPS_STATUS_WP_BIT_HIGH)) {
+	xil_printf("EfusePS status bits : Write protect enabled\n\r");
+    }else {
+	xil_printf("EfusePS status bits : Write protect disabled\n\r");
+    }
+
+    if(PsStatusBits & XSK_EFUSEPS_STATUS_RSA_EN) {
+	xil_printf("EfusePS status bits : RSA authentication of "
+			"fsbl enabled\n\r");
+    }else {
+	xil_printf("EfusePS status bits : RSA authentication of "
+			"fsbl disabled\n\r");
+    }
+
+    if(PsStatusBits & XSK_EFUSEPS_STATUS_ROM_128_CRC) {
+	xil_printf("EfusePS status bits : 128k CRC check on ROM enabled\n\r");
+    }else {
+	xil_printf("EfusePS status bits : 128k CRC check on ROM disabled\n\r");
+    }
+
+    /**
+     * Write the PS eFUSE as defined in xilskeyinput.h
+     */
+   PsStatus = XilSKey_EfusePs_Write(&PsInstancePtr);
+    if (PsStatus != XST_SUCCESS) {
+	printf("PS EFUSE writing failed\n");
+	goto EFUSE_ERROR;
+    }
+
+    u32 Index;
+	/**
+	 *  Clear the structure element of Rsa Key Hash for reading
+	 */
+    for(Index=0;Index<32;Index++){
+        PsInstancePtr.RsaKeyHashValue[Index]=0;
+    }
+    /**
+     * Read the PS eFUSE RSA Key Hash
+     */
+    PsStatus = XilSKey_EfusePs_Read(&PsInstancePtr);
+    if (PsStatus != XST_SUCCESS){
+	printf("PS EFUSE reading failed\n");
+	goto EFUSE_ERROR;
+    }
+
+    /**
+     * Print the read PS eFUSE RSA Key Hash
+     */
+    printf("Read RSA Key Hash: \n");
+
+    for(Index=0;Index<32;Index++){
+	printf("%02x",PsInstancePtr.RsaKeyReadback[Index]);
+    }
+    printf("\n");
+
+#endif /* XSK_EFUSEPS_DRIVER*/
+
+#ifdef XSK_EFUSEPL_DRIVER
+
+    XilSKey_EPl PlInstancePtr;
+    u32 PlStatusBits = 0;
+    int KeyCnt;
+
+    /**
+	 * Initialize the PL data structure based on the xilskey_input.h values
+	 */
+    PlStatus = XilSKey_EfusePl_InitData(&PlInstancePtr);
+    if( PlStatus != XST_SUCCESS) {
+		printf("PL Data Initialization Failed\r\n");
+        goto EFUSE_ERROR;
+	}
+
+     /**
+	 * Call the PL eFUSE programming function to program the eFUSE
+	 * based on the user input
+	 */
+     PlStatus = XilSKey_EfusePl_Program(&PlInstancePtr);
+	if(PlStatus != XST_SUCCESS)	{
+		printf("PL eFUSE programming failed\r\n");
+	}
+
+    /*
+     * Read Efuse PL status bits
+     */
+	PlStatus = XilSKey_EfusePl_ReadStatus(&PlInstancePtr, &PlStatusBits);
+    if( PlStatus != XST_SUCCESS) {
+		printf("PL efuse status read failed\r\n");
+        goto EFUSE_ERROR;
+	}
+
+    /*
+     * Print Efuse PL status bits
+     */
+    xil_printf("EfusePL status bits : 0x%x \n\r", PlStatusBits);
+
+    if(PlStatusBits & XSK_EFUSEPL_STATUS_FORCE_PCYCLE_RECONFIG) {
+	xil_printf("EfusePL status bits : Force power cycle for "
+			"reconfiguration enabled\n\r");
+    }else {
+	xil_printf("EfusePL status bits : Force power cycle for "
+			"reconfiguration disabled\n\r");
+    }
+
+    if(PlStatusBits & XSK_EFUSEPL_STATUS_DISABLE_KEY_WRITE) {
+	xil_printf("EfusePL status bits : Key write disabled \n\r");
+    }else {
+	xil_printf("EfusePL status bits : Key write enabled \n\r");
+    }
+
+    if(PlStatusBits & XSK_EFUSEPL_STATUS_DISABLE_AES_KEY_READ) {
+	xil_printf("EfusePL status bits : AES Key read disabled \n\r");
+    }else {
+	xil_printf("EfusePL status bits : AES Key read enabled \n\r");
+    }
+
+    if(PlStatusBits & XSK_EFUSEPL_STATUS_DISABLE_USER_KEY_READ) {
+	xil_printf("EfusePL status bits : User Key read disabled \n\r");
+    }else {
+	xil_printf("EfusePL status bits : User Key read enabled \n\r");
+    }
+
+    if(PlStatusBits & XSK_EFUSEPL_STATUS_DISABLE_FUSE_CNTRL_WRITE) {
+	xil_printf("EfusePL status bits : Fuse Control write disabled \n\r");
+    }else {
+	xil_printf("EfusePL status bits : Fuse Control write enabled \n\r");
+    }
+
+    if(PlStatusBits & XSK_EFUSEPL_STATUS_EFUSE_SEC_ENABLE) {
+	xil_printf("EfusePL status bits : Efuse secure boot enabled \n\r");
+    }else {
+	xil_printf("EfusePL status bits : Efuse secure boot disabled \n\r");
+    }
+
+    if(PlStatusBits & XSK_EFUSEPL_STATUS_JTAG_DISABLE) {
+	xil_printf("EfusePL status bits : Jtag disabled \n\r");
+    }else {
+	xil_printf("EfusePL status bits : Jtag enabled \n\r");
+    }
+
+    if(PlStatusBits & XSK_EFUSEPL_STATUS_BBRAM_KEY_DISABLE) {
+	xil_printf("EfusePL status bits : BBRAM key disabled \n\r");
+    }else {
+	xil_printf("EfusePL status bits : BBRAM key enabled \n\r");
+    }
+
+    /*
+     * Read Efuse PL key
+     */
+    PlStatus = XilSKey_EfusePl_ReadKey(&PlInstancePtr);
+    if( PlStatus != XST_SUCCESS) {
+		printf("PL efuse key read failed\r\n");
+        goto EFUSE_ERROR;
+	}
+    /*
+     * Print Efuse PL key
+     */
+    xil_printf("EfusePL User key : 0x");
+    for(KeyCnt = 3; KeyCnt >= 0; KeyCnt--)
+    {
+	xil_printf("%02x", PlInstancePtr.UserKeyReadback[KeyCnt]);
+    }
+    xil_printf("\n\r");
+
+    xil_printf("EfusePL AES key : 0x");
+    for(KeyCnt = 31; KeyCnt >= 0; KeyCnt--)
+    {
+	xil_printf("%02x", PlInstancePtr.AESKeyReadback[KeyCnt]);
+    }
+    xil_printf("\n\r");
+
+#endif /*XSK_EFUSEPL_DRIVER*/
+
+EFUSE_ERROR:
+	/**
+	 * Write the error returned in the Reboot Status Register
+	 * Eg: If the reboot status register value is 0xYYYYZZZZ
+	 * then
+	 * - YYYY Represents the PS eFUSE Status.
+	 * - ZZZZ Represents the PL eFUSE Status.
+	 *
+	 * - Value 0x0000ZZZZ
+	 * 	 represents PS eFUSE is successful & PL eFUSE process
+	 * 	 returned with error.
+	 * - Value 0xYYYY0000
+	 * 	 represents PL eFUSE is successful & PS eFUSE process
+	 * 	 returned with error.
+	 * - Value 0xFFFF0000
+	 * 	 represents PS eFUSE is not initiated & PL eFUSE is successful.
+	 * - Value 0x0000FFFF
+	 * 	 represents PL eFUSE is not initiated & PS eFUSE is successful.
+	 * - Value 0xFFFFZZZZ
+	 * 	 represents PS eFUSE is not initiated & PL eFUSE is process
+	 * 	 returned with error.
+	 * - Value 0xYYYYFFFF
+	 * 	 represents PL eFUSE is not initiated & PS eFUSE is process
+	 * 	 returned with error.
+	 */
+	Status = ((PsStatus << 16) + PlStatus);
+
+	printf("eFUSE operations exit status: %08X\r\n", Status);
+
+	/**
+	 * Writing the Exit Status to Reboot Status Register
+	 */
+	Xil_Out32(REBOOT_STATUS_REG_ADDR,Status);
+    while(1);
+    return 0;
+}
+
+
+#ifdef XSK_EFUSEPS_DRIVER
+/****************************************************************************/
+/**
+*
+*
+*  Helper functions to properly initialize the PS eFUSE structure instance
+*
+*
+* @param	PsInstancePtr - Structure Address to update the structure elements
+*
+* @return
+*
+*	- XST_SUCCESS - In case of Success
+*	- XST_FAILURE - If initialization fails
+*
+* @note
+*
+*****************************************************************************/
+
+u32 XilSKey_EfusePs_InitData(XilSKey_EPs *PsInstancePtr)
+{
+	u32 PsStatus;
+
+	PsStatus = XST_SUCCESS;
+
+    /**
+     * Copy the xilskeyinput.h values into PS structure elements
+     */
+	PsInstancePtr->EnableWriteProtect = XSK_EFUSEPS_ENABLE_WRITE_PROTECT;
+	PsInstancePtr->EnableRsaAuth = XSK_EFUSEPS_ENABLE_RSA_AUTH;
+	PsInstancePtr->EnableRom128Crc = XSK_EFUSEPS_ENABLE_ROM_128K_CRC;
+	PsInstancePtr->EnableRsaKeyHash = XSK_EFUSEPS_ENABLE_RSA_KEY_HASH;
+
+	if (PsInstancePtr->EnableRsaKeyHash == TRUE) {
+		/**
+		 * Validation of RSA Hash
+		 */
+		PsStatus = XilSKey_Efuse_ValidateKey(
+						(char *)XSK_EFUSEPS_RSA_KEY_HASH_VALUE,
+						XSK_EFUSEPL_RSA_KEY_HASH_STRING_SIZE);
+		if(PsStatus != XST_SUCCESS)	{
+			return PsStatus;
+		}
+
+		/**
+		 * Convert the input RSA Key Hash string into Hex buffer
+		 */
+		PsStatus = XilSKey_Efuse_ConvertStringToHexBE(
+						XSK_EFUSEPS_RSA_KEY_HASH_VALUE,
+						&(PsInstancePtr->RsaKeyHashValue[0]), 64);
+		if(PsStatus != XST_SUCCESS)	{
+			return PsStatus;
+		}
+	}
+	return PsStatus;
+}
+#endif /* XSK_EFUSEPS_DRIVER*/
+
+
+#ifdef XSK_EFUSEPL_DRIVER
+/****************************************************************************/
+/**
+*
+*
+*  Helper functions to properly initialize the PL eFUSE structure instance
+*
+*
+* @param	PlInstancePtr - Structure Address to update the structure elements
+*
+* @return
+*
+*	- XST_SUCCESS - In case of Success
+*	- XST_FAILURE - If initialization fails
+*
+* @note
+*
+*****************************************************************************/
+
+u32 XilSKey_EfusePl_InitData(XilSKey_EPl *PlInstancePtr)
+{
+
+	u32 PlStatus;
+
+	PlStatus = XST_SUCCESS;
+
+
+    /**
+     * Copy the xilskeyinput.h values into PL eFUSE structure elements
+     */
+
+    /**
+	 * Assign FUSE CNTRL bits[1:5] to the PL eFUSE structure elements.
+	 */
+
+	PlInstancePtr->ForcePowerCycle		= 	XSK_EFUSEPL_FORCE_PCYCLE_RECONFIG;
+	PlInstancePtr->KeyWrite 			= 	XSK_EFUSEPL_DISABLE_KEY_WRITE;
+	PlInstancePtr->AESKeyRead 			= 	XSK_EFUSEPL_DISABLE_AES_KEY_READ;
+	PlInstancePtr->UserKeyRead 			= 	XSK_EFUSEPL_DISABLE_USER_KEY_READ;
+	PlInstancePtr->CtrlWrite 			= 	XSK_EFUSEPL_DISABLE_FUSE_CNTRL_WRITE;
+	/**
+	 * Assign the FUSE CNTRL bits[8:10] into the PL eFUSE structure elements
+	 */
+	PlInstancePtr->UseAESOnly 			= 	XSK_EFUSEPL_FORCE_USE_AES_ONLY;
+	PlInstancePtr->JtagDisable			= 	XSK_EFUSEPL_DISABLE_JTAG_CHAIN;
+	PlInstancePtr->AESKeyExclusive 		= 	XSK_EFUSEPL_BBRAM_KEY_DISABLE;
+
+	PlInstancePtr->JtagMioTDI 			=	XSK_EFUSEPL_MIO_JTAG_TDI;
+	PlInstancePtr->JtagMioTDO			=	XSK_EFUSEPL_MIO_JTAG_TDO;
+	PlInstancePtr->JtagMioTCK			=	XSK_EFUSEPL_MIO_JTAG_TCK;
+	PlInstancePtr->JtagMioTMS			=	XSK_EFUSEPL_MIO_JTAG_TMS;
+	PlInstancePtr->JtagMioMuxSel 		=	XSK_EFUSEPL_MIO_JTAG_MUX_SELECT;
+	PlInstancePtr->JtagMuxSelLineDefVal	=  XSK_EFUSEPL_MIO_MUX_SEL_DEFAULT_VAL;
+
+	/*
+	 * Variable to check whether internal system initialization is done.
+	 */
+	PlInstancePtr->SystemInitDone	=  0;
+
+	/**
+	 * Assign the user selection for AES & USER Low Key (or)
+	 * User High Key (or) both
+	 */
+	PlInstancePtr->ProgAESandUserLowKey	=
+			XSK_EFUSEPL_PROGRAM_AES_AND_USER_LOW_KEY;
+	PlInstancePtr->ProgUserHighKey 		= XSK_EFUSEPL_PROGRAM_USER_HIGH_KEY;
+
+	if (PlInstancePtr->ProgAESandUserLowKey == TRUE) {
+		/**
+		 * Validation of AES Key
+		 */
+		PlStatus = XilSKey_Efuse_ValidateKey((char *)XSK_EFUSEPL_AES_KEY,
+											XSK_EFUSEPL_AES_KEY_STRING_SIZE);
+		if(PlStatus != XST_SUCCESS) {
+			goto PL_INIT_ERROR;
+		}
+		/**
+		 * Validation of User Low Key
+		 */
+		PlStatus = XilSKey_Efuse_ValidateKey((char *)XSK_EFUSEPL_USER_LOW_KEY,
+										XSK_EFUSEPL_USER_LOW_KEY_STRING_SIZE);
+		if(PlStatus != XST_SUCCESS)	{
+			goto PL_INIT_ERROR;
+		}
+
+		/**
+		 * Assign the AES Key Value
+		 */
+		XilSKey_Efuse_ConvertStringToHexLE((char *)XSK_EFUSEPL_AES_KEY ,
+				&PlInstancePtr->AESKey[0],
+				XSK_EFUSEPL_AES_KEY_SIZE_IN_BITS);
+
+		/**
+		 * Assign the User Low key [7:0] bits
+		 */
+		XilSKey_Efuse_ConvertStringToHexLE((char *)XSK_EFUSEPL_USER_LOW_KEY ,
+				&PlInstancePtr->UserKey[0],
+				XSK_EFUSEPL_USER_LOW_KEY_SIZE_IN_BITS);
+	}
+
+	if (PlInstancePtr->ProgUserHighKey == TRUE) {
+		/**
+		 * Validation of User High Key
+		 */
+		PlStatus = XilSKey_Efuse_ValidateKey(
+						(char *)XSK_EFUSEPL_USER_HIGH_KEY,
+						XSK_EFUSEPL_USER_HIGH_KEY_STRING_SIZE);
+		if(PlStatus != XST_SUCCESS) {
+			goto PL_INIT_ERROR;
+		}
+		/**
+		 * Assign the User High key [31:8] bits
+		 */
+		XilSKey_Efuse_ConvertStringToHexLE((char *)XSK_EFUSEPL_USER_HIGH_KEY ,
+						&PlInstancePtr->UserKey[1],
+						XSK_EFUSEPL_USER_HIGH_KEY_SIZE_IN_BITS);
+	}
+
+PL_INIT_ERROR:
+	return PlStatus;
+}
+
+#endif /*XSK_EFUSEPL_DRIVER*/
diff --git a/lib/sw_services/xilskey/examples/xilskey_input.h b/lib/sw_services/xilskey/examples/xilskey_input.h
new file mode 100644
index 00000000..45cc0df7
--- /dev/null
+++ b/lib/sw_services/xilskey/examples/xilskey_input.h
@@ -0,0 +1,396 @@
+/******************************************************************************
+*
+* 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_input.h
+*
+*
+* @note
+*
+*  					User configurable parameters for PS eFUSE
+*  	---------------------------------------------------------------------------
+* 	#define XSK_EFUSEPS_ENABLE_WRITE_PROTECT				FALSE
+*
+*	TRUE to burn the write protect bits in eFUSE array. Write protect
+*	has two bits, when any of the bit is blown, it is considered as write
+*	protected. So, while burning the Write protect bits, even if one bit is
+*	blown, write API returns success. Note that, POR reset is required after
+*	burning, for write protection of the eFUSE bits to come into effect.
+*	It is recommended to do the POR reset after write protection.
+*	Also note that, once write protect bits are burned, no more eFUSE writes
+*	are possible. So, please be sure when burning the write protect bits.
+*	If the Write protect macro is TRUE with other macros, write protect will
+*	be burned in the last, after burning all the defined values, so that for
+*	any error while burning other macros will not effect the total eFUSE array.
+*	FALSE will not modify the write protect bits.
+*
+*	#define XSK_EFUSEPS_ENABLE_RSA_AUTH					FALSE
+*
+*	TRUE to burn the RSA enable bit in PS eFUSE array. After enabling the bit,
+*	every successive boot must be RSA enabled apart from JTAG. Before burning
+*	this bit, make sure that eFUSE array has the valid PPK hash.If the PPK hash
+*	burning is enabled, only after writing the hash successfully, RSA enable
+*	bit will be blown. Note that, for RSA enable bit to take effect, POR reset
+*	is required.
+*	FALSE will not modify the RSA enable bit.
+*
+*	#define XSK_EFUSEPS_ENABLE_ROM_128K_CRC				FALSE
+*	TRUE will burn the ROM 128k crc bit. Every successive boot after this,
+*	BootROM will calculate 128k crc. FALSE will not modify the ROM CRC128K bit.
+*
+*	#define XSK_EFUSEPS_ENABLE_RSA_KEY_HASH				FALSE
+*	TRUE will burn the eFUSE hash, that is given in XSK_EFUSEPS_RSA_KEY_HASH_VALUE
+*	when write API is used. TRUE will read the eFUSE hash when read API is used
+*	and will be read into structure. FALSE will ignore the value given.
+*
+*	#define XSK_EFUSEPS_RSA_KEY_HASH_VALUE
+*			"c8bb4d9e1fcdbd27b99d48a3df5720b98f35bafabb1e10333a78322fb82ce63d"
+*
+*	The value mentioned in this will be converted to hex buffer and written
+*	into the PS eFUSE array when write API used. This value should be the
+*	PPK(Primary Public Key) hash given in string format. It should be 64
+*	characters long, valid characters are 0-9,a-f,A-F. Any other character
+*	is considered as invalid string and will not burn RSA hash.
+*
+* 	Note: When XilSKey_EfusePs_Write() API is used, above mentioned RSA hash
+* 	is written and  XSK_EFUSEPS_ENABLE_RSA_KEY_HASH should have TRUE value.
+*
+* 	   					User configurable parameters for PL eFUSE
+*  	-----------------------------------------------------------------------
+*  	#define 	XSK_EFUSEPL_FORCE_PCYCLE_RECONFIG			FALSE
+*	TRUE then part has to be power cycled to be able to be reconfigured.
+*	FALSE will not set the eFUSE control bit.
+*
+*	#define		XSK_EFUSEPL_DISABLE_KEY_WRITE				FALSE
+*	TRUE will disable eFUSE write to FUSE_AES and FUSE_USER blocks
+*	XFLASE will enable eFUSE write to FUSE_AES and FUSE_USER blocks
+*
+*	#define		XSK_EFUSEPL_DISABLE_AES_KEY_READ			FALSE
+*	TRUE will disable the write to FUSE_AES & FUSE_USER key & disables
+*	read of FUSE_AES.
+*	FALSE will enable eFUSE read from & write to FUSE_AES and FUSE_USER blocks
+*
+*	#define		XSK_EFUSEPL_DISABLE_USER_KEY_READ			FALSE
+*	TRUE will disable the write to FUSE_AES & FUSE_USER key & disables read of
+*	FUSE_USER
+*	FALSE will enable eFUSE read from & write to FUSE_AES and FUSE_USER blocks
+*
+*	Note: If any one of the above two definitions are FALSE then reading of
+*	FUSE_AES & FUSE_USER is not possible
+*
+*	#define		XSK_EFUSEPL_DISABLE_FUSE_CNTRL_WRITE		FALSE
+*	TRUE will disable the eFUSE write to FUSE_CTRL block
+*	FALSE will not set the eFUSE control bit, so that user can write into
+*	FUSE_CTRL block later.
+*
+*	#define		XSK_EFUSEPL_FORCE_USE_AES_ONLY				FALSE
+*	TRUE will force to use secure boot with eFUSE AES key only
+*	FALSE will not set the eFUSE control bit so that user can use non-secure
+*	boot.
+*
+*	#define 	XSK_EFUSEPL_DISABLE_JTAG_CHAIN				FALSE
+*	If TRUE then permanently sets the Zynq ARM DAP controller in bypass mode.
+*	FALSE will allow Zynq ARM DAP visible through JTAG.
+*
+*	#define		XSK_EFUSEPL_BBRAM_KEY_DISABLE				FALSE
+*	XTURE will force eFUSE key to be used if booting Secure Image.
+*	FALSE will not set the eFUSE control bit so that user can use secure boot
+*	with BBRAM key.
+*
+*	Following are the MIO pins used for PL JTAG operations.
+*	User can change these pins as their discretion.
+*	#define		XSK_EFUSEPL_MIO_JTAG_TDI				(17)
+*	#define		XSK_EFUSEPL_MIO_JTAG_TDO				(18)
+*	#define		XSK_EFUSEPL_MIO_JTAG_TCK				(19)
+*	#define		XSK_EFUSEPL_MIO_JTAG_TMS				(20)
+*
+*	MUX selection pin:
+*	#define		XSK_EFUSEPL_MIO_JTAG_MUX_SELECT		(21)
+*	This pin is used to select between the external JTAG or MIO driving JTAG
+*	operations.
+*
+*	#define 	XSK_EFUSEPL_MIO_MUX_SEL_DEFAULT_VAL				LOW
+*	LOW writes zero on the mux select line before writing the PL eFUSE
+*	HIGH writes one on the mux select line before writing the PL eFUSE
+*
+*	#define XSK_EFUSEPL_PROGRAM_AES_AND_USER_LOW_KEY		FALSE
+*	TRUE will burn the AES & User Low hash key, that is given in
+*	XSK_EFUSEPL_AES_KEY & XSK_EFUSEPL_USER_LOW_KEY respectively.
+*	FALSE will ignore the values given.
+*
+*	Note: User cannot write AES Key & User Low Key separately.
+*
+*	#define XSK_EFUSEPL_PROGRAM_USER_HIGH_KEY				FALSE
+*	TRUE will burn the User High hash key, that is given in
+*	XSK_EFUSEPL_AES_KEY & XSK_EFUSEPL_USER_LOW_KEY respectively.
+*	FALSE will ignore the values given.
+*
+*	#define 	XSK_EFUSEPL_AES_KEY
+*		"0000000000000000000000000000000000000000000000000000000000000000"
+*	The value mentioned in this will be converted to hex buffer and written
+*	into the PL eFUSE array when write API used. This value should be the
+*	PPK(Primary Public Key) hash given in string format. It should be 64
+*	characters long, valid characters are 0-9,a-f,A-F. Any other character
+*	is considered as invalid string and will not burn AES Key. Note that,
+*	for writing the AES Key, XSK_EFUSEPL_PROGRAM_AES_AND_USER_LOW_KEY should
+*	have TRUE value.
+*
+*	#define 	XSK_EFUSEPL_USER_LOW_KEY			"00"
+*	The value mentioned in this will be converted to hex buffer and written
+*	into the PL eFUSE array when write API used. This value should be the
+*	User Low Key given in string format. It should be 2 characters long, valid
+*	 characters are 0-9,a-f,A-F. Any other character is considered as invalid
+*	 string and will not burn User Low Key. Note that, for writing the AES Key,
+*	 XSK_EFUSEPL_PROGRAM_AES_AND_USER_LOW_KEY should have TRUE value.
+*
+*
+*	#define 	XSK_EFUSEPL_USER_HIGH_KEY			"000000"
+*	The value mentioned in this will be converted to hex buffer and written
+*	into the PL eFUSE array when write API used. This value should be the User
+*	 High Key given in string format. It should be 6 characters long, valid
+*	 characters are 0-9,a-f,A-F. Any other character is considered as invalid
+*	 string and will not burn User High Key. Note that, for writing the AES
+*	 Key, XSK_EFUSEPL_PROGRAM_USER_HIGH_KEY should have TRUE value.
+*
+* BBRAM related definitions:
+*-----------------------------------------------------------------------------
+*	#define 	XSK_BBRAM_FORCE_PCYCLE_RECONFIG		FALSE
+*			If TRUE then part has to be power cycled to be
+*			able to be reconfigured
+*	#define 	XSK_BBRAM_DISABLE_JTAG_CHAIN		FALSE
+*			If TRUE then permanently sets the Zynq
+* 			ARM DAP controller in bypass mode
+*	MIO pins used for JTAG signals. Can be changed as per hardware.
+*	#define		XSK_BBRAM_MIO_JTAG_TDI		(17)
+*	#define		XSK_BBRAM_MIO_JTAG_TDO		(21)
+*	#define		XSK_BBRAM_MIO_JTAG_TCK		(19)
+*	#define		XSK_BBRAM_MIO_JTAG_TMS		(20)
+*	#define		XSK_BBRAM_MIO_JTAG_MUX_SELECT	(11)
+*	#define 	XSK_BBRAM_MIO_MUX_SEL_DEFAULT_VAL	LOW
+*			Default value to enable the PL JTAG
+* This is the 256 bit key to be programmed into BBRAM.
+* This should entered by user in HEX.
+* #define 	XSK_BBRAM_AES_KEY
+*	"349de4571ae6d88de23de65489acf67000ff5ec901ae3d409aabbce4549812dd"
+* #define	XSK_BBRAM_AES_KEY_SIZE_IN_BITS	256
+*
+* <pre>
+* MODIFICATION HISTORY:
+*
+* Ver   Who  	Date     Changes
+* ----- ---- 	-------- --------------------------------------------------------
+* 1.00a rpoolla 04/26/13 First release
+* 1.01a hk      09/18/13 Added BBRAM related definitions
+* </pre>
+*
+*
+******************************************************************************/
+
+#ifndef XILSKEY_INPUT_H
+#define XILSKEY_INPUT_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/***************************** Include Files *********************************/
+#include "xil_types.h"
+/************************** Constant Definitions *****************************/
+/**************************** Type Definitions ******************************/
+/***************** Macros (Inline Functions) Definitions ********************/
+#define XSK_EFUSEPL_DRIVER
+#define XSK_EFUSEPS_DRIVER
+
+#ifdef XSK_EFUSEPL_DRIVER
+
+/**
+ *  Voltage level definitions
+ */
+#define 	LOW								0
+#define 	HIGH							1
+
+/**
+ * Following defines should be defined either TRUE or FALSE.
+ * --------------------------------------------------------
+ */
+
+#define 	XSK_EFUSEPL_FORCE_PCYCLE_RECONFIG	FALSE /**< If TRUE then part
+											 *  has to be power cycled to be
+											 *  able to be reconfigured
+											 */
+#define		XSK_EFUSEPL_DISABLE_KEY_WRITE		FALSE /**< If TRUE will disable
+												*  eFUSE write to FUSE_AES and
+												*  FUSE_USER blocks
+												*/
+#define		XSK_EFUSEPL_DISABLE_AES_KEY_READ	FALSE /**< If TRUE will disable
+											* eFUSE read to FUSE_AES block and
+											* also disables eFUSEwrite to
+											* FUSE_AES and FUSE_USER blocks
+											*/
+#define		XSK_EFUSEPL_DISABLE_USER_KEY_READ	FALSE /**< If TRUE will disable
+												* eFUSE read to FUSE_USER block
+												* and also disables eFUSE write
+												* to FUSE_AES and FUSE_USER
+												* blocks
+												*/
+#define		XSK_EFUSEPL_DISABLE_FUSE_CNTRL_WRITE 	FALSE /**< If TRUE will
+													* disable eFUSE write to
+													* FUSE_CNTRL block
+													*/
+#define		XSK_EFUSEPL_FORCE_USE_AES_ONLY		FALSE /**< If TRUE will force
+												* to use Secure boot with eFUSE
+												* key only
+												*/
+#define 	XSK_EFUSEPL_DISABLE_JTAG_CHAIN		FALSE /**< If TRUE then
+												* permanently sets the Zynq
+												* ARM DAP controller in bypass
+												* mode
+											*/
+#define		XSK_EFUSEPL_BBRAM_KEY_DISABLE		FALSE /**< If TRUE will force
+												* eFUSE key to be used if
+												* booting Secure Image
+												*/
+
+/**
+ * Following defines should be given in the decimal/hexa-decimal values.
+ * For example :
+ * XSK_EFUSEPL_MIO_JTAG_TCK		34 OR 0x22
+ * XSK_EFUSEPL_MIO_JTAG_TMS		35 OR 0x23
+ * etc...
+ */
+
+#define		XSK_EFUSEPL_MIO_JTAG_TDI	(17) /**< JTAG MIO pin for TDI */
+#define		XSK_EFUSEPL_MIO_JTAG_TDO	(21) /**< JTAG MIO pin for TDO */
+#define		XSK_EFUSEPL_MIO_JTAG_TCK	(19) /**< JTAG MIO pin for TCK */
+#define		XSK_EFUSEPL_MIO_JTAG_TMS	(20) /**< JTAG MIO pin for TMS */
+#define		XSK_EFUSEPL_MIO_JTAG_MUX_SELECT	(11) /**< JTAG MIO pin for
+												 * MUX selection line
+												 */
+/**
+ *
+ */
+#define 	XSK_EFUSEPL_MIO_MUX_SEL_DEFAULT_VAL		LOW /**< Default value to
+													* enable the PL JTAG
+													*/
+
+/**
+ * Following is the define to select if the user wants to select AES key and USER
+ * low key OR USER high key or BOTH
+ */
+
+#define XSK_EFUSEPL_PROGRAM_AES_AND_USER_LOW_KEY		FALSE /**< TRUE burns
+														* the AES & user low key
+														*/
+#define XSK_EFUSEPL_PROGRAM_USER_HIGH_KEY				FALSE /**< TRUE burns
+														* the user high key
+														*/
+/**
+ * Following defines should be given in the form of hex string.
+ * The length of AES_KEY string must me 64 and for USER_KEY must be 8.
+ */
+#define 	XSK_EFUSEPL_AES_KEY			"0000000000000000000000000000000000000000000000000000000000000000"
+#define 	XSK_EFUSEPL_USER_LOW_KEY	"00"
+#define 	XSK_EFUSEPL_USER_HIGH_KEY	"000000"
+
+#endif	/*XSK_EFUSEPL_DRIVER*/
+
+
+/**
+ *  Similarly we can define PS eFUSE related data
+ *  ---------------------------------------------
+ */
+#ifdef XSK_EFUSEPS_DRIVER
+
+#define XSK_EFUSEPS_ENABLE_WRITE_PROTECT	FALSE /**< Enable the eFUSE Array
+											* write protection
+											*/
+#define XSK_EFUSEPS_ENABLE_RSA_AUTH			FALSE /**< Enable the RSA
+											* Authentication eFUSE Bit
+											*/
+#define XSK_EFUSEPS_ENABLE_ROM_128K_CRC		FALSE /**< Enable the ROM
+											* code 128K crc  eFUSE Bit
+											*/
+#define XSK_EFUSEPS_ENABLE_RSA_KEY_HASH		FALSE /**< Enabling this
+											* RsaKeyHashValue[64] is
+											* written to eFUSE array
+											*/
+#define XSK_EFUSEPS_RSA_KEY_HASH_VALUE	"0000000000000000000000000000000000000000000000000000000000000000"
+
+#endif /* End of XSK_EFUSEPS_DRIVER */
+
+/*
+ * Definitions for BBRAM
+ */
+
+/**< If TRUE then part
+  *  has to be power cycled to be
+  *  able to be reconfigured
+  */
+#define 	XSK_BBRAM_FORCE_PCYCLE_RECONFIG		FALSE
+
+/**< If TRUE then
+  * permanently sets the Zynq
+  * ARM DAP controller in bypass
+  * mode
+  */
+#define 	XSK_BBRAM_DISABLE_JTAG_CHAIN		FALSE
+
+#define		XSK_BBRAM_MIO_JTAG_TDI	(17) /**< JTAG MIO pin for TDI */
+#define		XSK_BBRAM_MIO_JTAG_TDO	(21) /**< JTAG MIO pin for TDO */
+#define		XSK_BBRAM_MIO_JTAG_TCK	(19) /**< JTAG MIO pin for TCK */
+#define		XSK_BBRAM_MIO_JTAG_TMS	(20) /**< JTAG MIO pin for TMS */
+#define		XSK_BBRAM_MIO_JTAG_MUX_SELECT	(11) /**< JTAG MIO pin for
+						       * MUX selection line
+						       */
+/**< Default value to
+  * enable the PL JTAG
+  */
+#define 	XSK_BBRAM_MIO_MUX_SEL_DEFAULT_VAL	0
+/**
+ * This is the 256 bit key to be programmed into BBRAM.
+ * This should entered by user in HEX.
+ */
+#define 	XSK_BBRAM_AES_KEY	"349de4571ae6d88de23de65489acf67000ff5ec901ae3d409aabbce4549812dd"
+
+#define		XSK_BBRAM_AES_KEY_SIZE_IN_BITS	256
+
+/*
+ * End of definitions for BBRAM
+ */
+
+/************************** Function Prototypes *****************************/
+/****************************************************************************/
+#ifdef __cplusplus
+}
+#endif
+
+#endif	/*XILSKEY_INPUT_H*/
diff --git a/lib/sw_services/xilskey/src/Makefile b/lib/sw_services/xilskey/src/Makefile
new file mode 100644
index 00000000..9170a092
--- /dev/null
+++ b/lib/sw_services/xilskey/src/Makefile
@@ -0,0 +1,91 @@
+###############################################################################
+#
+# 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.
+#
+###############################################################################
+
+COMPILER=
+ARCHIVER=
+CP=cp
+COMPILER_FLAGS=
+EXTRA_COMPILER_FLAGS=
+
+RELEASEDIR=../../../lib
+INCLUDEDIR=../../../include
+INCLUDES=-I${INCLUDEDIR}
+SKEY_DIR = .
+
+LIB_SRCS = $(SKEY_DIR)/xilskey_eps.c \
+          $(SKEY_DIR)/xilskey_epl.c \
+          $(SKEY_DIR)/xilskey_utils.c \
+          $(SKEY_DIR)/xilskey_jslib.c \
+          $(SKEY_DIR)/xilskey_jscmd.c \
+          $(SKEY_DIR)/xilskey_bbram.c
+
+# create ISF_SRCS based on configured options
+
+SKEY_SRCS = $(LIB_SRCS)
+
+SKEY_OBJS = $(SKEY_SRCS:%.c=%.o)
+
+
+EXPORT_INCLUDE_FILES = $(SKEY_DIR)/include/xilskey_eps.h \
+			$(SKEY_DIR)/include/xilskey_epl.h \
+			$(SKEY_DIR)/include/xilskey_utils.h \
+			$(SKEY_DIR)/include/xilskey_bbram.h
+
+
+libs: libxilskey.a
+	cp libxilskey.a $(RELEASEDIR)
+	make clean
+
+include:
+	@for i in $(EXPORT_INCLUDE_FILES); do \
+	echo ${CP} -r $$i ${INCLUDEDIR}; \
+	${CP} -r $$i ${INCLUDEDIR}; \
+	done
+
+clean:
+	rm -rf obj/*.o
+	rmdir obj
+	rm libxilskey.a
+
+
+libxilskey.a: obj_dir print_msg_isf_base $(SKEY_OBJS)
+	@echo "Creating archive $@"
+	$(ARCHIVER) rc $@ obj/*.o
+
+obj_dir:
+	mkdir obj
+
+print_msg_isf_base:
+	@echo "Compiling Xilinx Secure Key Library..."
+
+.c.o:
+	$(COMPILER) $(COMPILER_FLAGS) $(EXTRA_COMPILER_FLAGS) $(INCLUDES) -c $< -o obj/$(@F)
diff --git a/lib/sw_services/xilskey/src/changelog.txt b/lib/sw_services/xilskey/src/changelog.txt
new file mode 100755
index 00000000..3fa21828
--- /dev/null
+++ b/lib/sw_services/xilskey/src/changelog.txt
@@ -0,0 +1,25 @@
+/*****************************************************************************
+ * MODIFICATION HISTORY:
+ *
+ * Ver   Who  Date     Changes
+ * ----- ---- -------- ---------------------------------------------------
+ *
+ * 1.02a hk   10/28/13  PS eFuse:
+ *			Added API to read status register:
+ *			u32 XilSKey_EfusePs_ReadStatus(
+ *				XilSKey_EPs *InstancePtr, u32 *StatusBits)
+ *                      RSA key read back is stored in RsaKeyReadback in
+ *                      Instance structure instead of RsaKeyHashValue -
+ *			Change in API:
+ *			u32 XilSKey_EfusePs_Read(XilSKey_EPs *PsInstancePtr)
+ *			PL eFUSE:
+ *			Added API's to read status bits and key :
+ * 			u32 XilSKey_EfusePl_ReadKey(XilSKey_EPl *InstancePtr)
+ *			u32 XilSKey_EfusePl_ReadKey(XilSKey_EPl *InstancePtr)
+ * 2.00  hk   23/01/14  Corrected PL voltage checks to VCCINT and VCCAUX.
+ *                        CR#768077
+ *                      Changed PS efuse error codes for voltage out of range
+ * 2.00  hk   02/12/14  Changed makefile to remove '-p' option with mkdir.
+ *                      CR#773090
+ *
+ ********************************************************************************/
diff --git a/lib/sw_services/xilskey/src/include/xilskey_bbram.h b/lib/sw_services/xilskey/src/include/xilskey_bbram.h
new file mode 100644
index 00000000..89065b22
--- /dev/null
+++ b/lib/sw_services/xilskey/src/include/xilskey_bbram.h
@@ -0,0 +1,203 @@
+/******************************************************************************
+*
+* 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_bbram.h
+* @note
+*		 Contains the function prototypes, defines and macros for
+*		 BBRAM functionality.
+*
+* MODIFICATION HISTORY:
+*
+* Ver   Who  	Date     Changes
+* ----- ---- 	-------- --------------------------------------------------------
+* 1.01a hk      09/18/13 First release
+*
+****************************************************************************/
+#ifndef XILSKEY_BBRAM_H
+#define XILSKEY_BBRAM_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+/***************************** Include Files *********************************/
+/************************** Constant Definitions *****************************/
+/**************************** Type Definitions ******************************/
+/***************** Macros (Inline Functions) Definitions ********************/
+/************************** Variable Definitions ****************************/
+typedef struct {
+
+	/**
+	 * If XTRUE then part has to be power cycled to be able to be reconfigured
+	 */
+	u32	ForcePowerCycle;
+	/**
+	 * If XTRUE then permanently sets the Zynq ARM DAP controller in bypass mode
+	 */
+	u32 JtagDisable;
+	/**
+	 * This is for the aes_key value
+	 */;
+	u8 AESKey[32];
+	/**
+	 * TDI MIO Pin Number
+	 */
+	u32 JtagMioTDI;
+	/**
+	 * TDO MIO Pin Number
+	 */
+	u32 JtagMioTDO;
+	/**
+	 * TCK MIO Pin Number
+	 */
+	u32 JtagMioTCK;
+	/**
+	 * TMS MIO Pin Number
+	 */
+	u32 JtagMioTMS;
+	/**
+	 * MUX Selection MIO Pin Number
+	 */
+	u32 JtagMioMuxSel;
+	/**
+	 * Value on the MUX Selection line
+	 */
+	u32	JtagMuxSelLineDefVal;
+
+}XilSKey_Bbram;
+/************************** Constant Definitions *****************************/
+/*
+ * Constant definitions for instruction used in BBRAM key program and verify
+ */
+#define JPROGRAM 0x0B
+#define ISC_NOOP 0x14
+#define ISC_ENABLE 0x10
+#define ISC_PROGRAM_KEY 0x12
+#define ISC_PROGRAM 0x11
+#define ISC_READ 0x15
+#define ISC_DISABLE 0x16
+#define BYPASS 0x3F
+
+/*
+ * Pre and post pads
+ */
+#define IRHEADER	0
+#define IRTRAILER	4
+#define DRHEADER	0
+#define DRTRAILER	1
+
+/*
+ * Pre and post pads for BYPASS in de-init
+ */
+#define IRHEADER_BYP	0
+#define IRTRAILER_BYP	0
+#define DRHEADER_BYP	0
+#define DRTRAILER_BYP	0
+
+/*
+ * Instruction load length
+ */
+#define IRLENGTH	6
+
+/*
+ * Data register lengths for program
+ */
+#define DRLENGTH_PROGRAM	32
+/*
+ * Data register lengths for verify
+ */
+#define DRLENGTH_VERIFY		37
+/*
+ * Data register lengths for data load after ISC_ENABLE
+ */
+#define DRLENGTH_EN		5
+/*
+ * Data register load after ISC_ENABLE
+ */
+#define DR_EN		0x15
+
+/*
+ * Timer function load for 100msec
+ */
+#define TIMER_100MS	1000000
+
+/*
+ * IRCAPTURE status - init complete mask
+ */
+#define INITCOMPLETEMASK	0x10
+
+/*
+ * Number of char's in a KEY
+ */
+#define NUMCHARINKEY	32
+/*
+ * Number of words in a KEY
+ */
+#define NUMWORDINKEY	8
+
+/*
+ * Data register shift before key verify
+ */
+#define DATAREGCLEAR	0x1FFFFFFFE0
+
+/*
+ * Number of LSB status bits in 37 bit read to shifted out
+ */
+#define NUMLSBSTATUSBITS	5
+
+/*
+ * Data and instruction loads in de-init
+ */
+#define IRDEINIT_H		0x03
+#define IRDEINIT_L		0xFF
+#define DRDEINIT		0x00
+
+/*
+ * Data and instruction lenghts in de-init
+ */
+#define IRDEINITLEN		10
+#define DRDEINITLEN		2
+
+/************************** Function Prototypes *****************************/
+/*
+ * Function for BBRAM program and vefiry algorithm
+ */
+int XilSKey_Bbram_Program(XilSKey_Bbram *InstancePtr);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif	/* End of XILSKEY_BBRAM_H */
diff --git a/lib/sw_services/xilskey/src/include/xilskey_epl.h b/lib/sw_services/xilskey/src/include/xilskey_epl.h
new file mode 100644
index 00000000..29d3a734
--- /dev/null
+++ b/lib/sw_services/xilskey/src/include/xilskey_epl.h
@@ -0,0 +1,193 @@
+/******************************************************************************
+*
+* 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_epl.h
+* @note
+*		 Contains the function prototypes, defines and macros for the PL eFUSE
+*		 functionality.
+*
+* MODIFICATION HISTORY:
+*
+* Ver   Who  	Date     Changes
+* ----- ---- 	-------- --------------------------------------------------------
+* 1.00a rpoolla 04/26/13 First release
+* 1.02a hk      10/28/13 Added API's to read status bits and key :
+* 			 u32 XilSKey_EfusePl_ReadKey(XilSKey_EPl *InstancePtr)
+*			 u32 XilSKey_EfusePl_ReadKey(XilSKey_EPl *InstancePtr)
+* 2.00  hk      22/01/14 Corrected PL voltage checks to VCCINT and VCCAUX.
+*                        CR#768077
+*
+*
+****************************************************************************/
+#ifndef XILSKEY_EPL_H
+#define XILSKEY_EPL_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+/***************************** Include Files *********************************/
+
+/************************** Constant Definitions *****************************/
+/**
+ *  AES Key size in Bytes
+ */
+#define XSK_EFUSEPL_AES_KEY_SIZE_IN_BYTES				(32)
+/**
+ *  User Key size in Bytes
+ */
+#define XSK_EFUSEPL_USER_KEY_SIZE_IN_BYTES				(4)
+/**************************** Type Definitions ******************************/
+/***************** Macros (Inline Functions) Definitions ********************/
+
+/************************** Variable Definitions ****************************/
+/**
+ * XSK_EfusePl is the PL eFUSE driver instance. Using this
+ * structure, user can define the eFUSE bits to be
+ * blown.
+ */
+typedef struct {
+	/**
+	 * Following are the FUSE CNTRL bits[1:5, 8-10]
+	 */
+
+	/**
+	 * If XTRUE then part has to be power cycled to be able to be reconfigured
+	 */
+	u32	ForcePowerCycle;
+	/**
+	 * If XTRUE will disable eFUSE write to FUSE_AES and FUSE_USER blocks
+	 */
+	u32 KeyWrite;
+	/**
+	 * If XTRUE will disable eFUSE read to FUSE_AES block and also disables
+	 * eFUSE write to FUSE_AES and FUSE_USER blocks
+	 */
+	u32 AESKeyRead;
+	/**
+	 * If XTRUE will disable eFUSE read to FUSE_USER block and also disables
+	 * eFUSE write to FUSE_AES and FUSE_USER blocks
+	 */
+	u32 UserKeyRead;
+	/**
+	 * If XTRUE will disable eFUSE write to FUSE_CNTRL block
+	 */
+	u32	CtrlWrite;
+	/**
+	 * If XTRUE will force eFUSE key to be used if booting Secure Image
+	 */
+	u32 AESKeyExclusive;
+	/**
+	 * If XTRUE then permanently sets the Zynq ARM DAP controller in bypass mode
+	 */
+	u32 JtagDisable;
+	/**
+	 * If XTRUE will force to use Secure boot with eFUSE key only
+	 */
+	u32 UseAESOnly;
+	/**
+	 * Following is the define to select if the user wants to select AES key
+	 * and User Low Ley
+	 */
+	u32 ProgAESandUserLowKey;
+	/**
+	 * Following is the define to select if the user wants to select
+	 * User Low Ley
+	 */
+	u32 ProgUserHighKey;
+	/**
+	 * This is the REF_CLK value in Hz
+	 */
+	/*u32	RefClk;*/
+	/**
+	 * This is for the aes_key value
+	 */
+	u8 AESKey[XSK_EFUSEPL_AES_KEY_SIZE_IN_BYTES];
+	/**
+	 * This is for the user_key value
+	 */
+	u8 UserKey[XSK_EFUSEPL_USER_KEY_SIZE_IN_BYTES];
+	/**
+	 * TDI MIO Pin Number
+	 */
+	u32 JtagMioTDI;
+	/**
+	 * TDO MIO Pin Number
+	 */
+	u32 JtagMioTDO;
+	/**
+	 * TCK MIO Pin Number
+	 */
+	u32 JtagMioTCK;
+	/**
+	 * TMS MIO Pin Number
+	 */
+	u32 JtagMioTMS;
+	/**
+	 * MUX Selection MIO Pin Number
+	 */
+	u32 JtagMioMuxSel;
+	/**
+	 * Value on the MUX Selection line
+	 */
+	u32	JtagMuxSelLineDefVal;
+	/**
+	 * AES key read
+	 */
+	u8 AESKeyReadback[XSK_EFUSEPL_AES_KEY_SIZE_IN_BYTES];
+	/**
+	 * User key read
+	 */
+	u8 UserKeyReadback[XSK_EFUSEPL_USER_KEY_SIZE_IN_BYTES];
+	/**
+	 * Internal variable to check if timer, XADC and JTAG are initialized.
+	 */
+	u32 SystemInitDone;
+
+}XilSKey_EPl;
+/************************** Function Prototypes *****************************/
+/************************** Constant Definitions *****************************/
+
+u32 XilSKey_EfusePl_Program(XilSKey_EPl *PlInstancePtr);
+
+u32 XilSKey_EfusePl_ReadStatus(XilSKey_EPl *InstancePtr, u32 *StatusBits);
+
+u32 XilSKey_EfusePl_ReadKey(XilSKey_EPl *InstancePtr);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif	/* End of XILSKEY_EPL_H */
diff --git a/lib/sw_services/xilskey/src/include/xilskey_eps.h b/lib/sw_services/xilskey/src/include/xilskey_eps.h
new file mode 100644
index 00000000..2266de26
--- /dev/null
+++ b/lib/sw_services/xilskey/src/include/xilskey_eps.h
@@ -0,0 +1,105 @@
+/******************************************************************************
+*
+* 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_eps.h
+ *
+ *
+ * @note	None.
+ *
+ *
+ * MODIFICATION HISTORY:
+ *
+* Ver   Who  	Date     Changes
+* ----- ---- 	-------- --------------------------------------------------------
+* 1.00a rpoolla 04/26/13 First release
+* 1.02a hk      10/28/13 Added API to read status register:
+*			 u32 XilSKey_EfusePs_ReadStatus(
+*				XilSKey_EPs *InstancePtr, u32 *StatusBits)
+*                        RSA key read back is stored in RsaKeyReadback in
+*                        Instance structure instead of RsaKeyHashValue -
+*			 Change in API:
+*			 u32 XilSKey_EfusePs_Read(XilSKey_EPs *PsInstancePtr)
+* 2.00  hk      23/01/14 Changed PS efuse error codes for voltage out of range
+*
+*
+*****************************************************************************/
+
+#ifndef XILSKEY_EPS_H
+#define XILSKEY_EPS_H
+
+/**
+ * Key length definition for RSA KEY Hash
+ */
+#define XSK_EFUSEPS_RSA_KEY_HASH_LEN_IN_BYTES			(32)
+
+/**
+ * XSKEfusePs is the PS eFUSE driver instance. Using this
+ * structure, user can define the eFUSE bits to be
+ * blown.
+ */
+typedef struct {
+	/**
+	 * EnableWriteProtect:Enable the eFUSE Array write protection
+	 */
+	u32 EnableWriteProtect;
+	/**
+	 * EnableRsaAuth: Enable the RSA Authentication eFUSE Bit
+	 */
+	u32 EnableRsaAuth;
+	/**
+	 * Enable the ROM code 128K crc  eFUSE Bit
+	 */
+	u32 EnableRom128Crc;
+	/**
+	 * EnableRsaKeyHash: Enabling this RsaKeyHashValue[32] is written to
+	 * eFUSE array
+	 */
+	u32 EnableRsaKeyHash;
+	/**
+	 * RsaKeyHashValue: RSA key Hash
+	 */
+	u8 RsaKeyHashValue[XSK_EFUSEPS_RSA_KEY_HASH_LEN_IN_BYTES];
+	/**
+	 * Rsa key read
+	 */
+	u8 RsaKeyReadback[XSK_EFUSEPS_RSA_KEY_HASH_LEN_IN_BYTES];
+} XilSKey_EPs;
+
+/**
+ * PS eFUSE interface functions
+ */
+u32 XilSKey_EfusePs_Write(XilSKey_EPs *PsInstancePtr);
+u32 XilSKey_EfusePs_Read (XilSKey_EPs *PsInstancePtr);
+u32 XilSKey_EfusePs_ReadStatus(XilSKey_EPs *InstancePtr, u32 *StatusBits);
+
+#endif /* XILSKEY_EPS_H */
diff --git a/lib/sw_services/xilskey/src/include/xilskey_utils.h b/lib/sw_services/xilskey/src/include/xilskey_utils.h
new file mode 100644
index 00000000..4ca12dee
--- /dev/null
+++ b/lib/sw_services/xilskey/src/include/xilskey_utils.h
@@ -0,0 +1,463 @@
+/******************************************************************************
+*
+* 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_utils.h
+ *
+ *
+ * @note	None.
+ *
+ *
+ * MODIFICATION HISTORY:
+ *
+* Ver   Who  	Date     Changes
+* ----- ---- 	-------- --------------------------------------------------------
+* 1.00a rpoolla 04/26/13 First release
+* 2.00  hk      23/01/14 Corrected PL voltage checks to VCCINT and VCCAUX.
+*                        CR#768077.
+*                        Changed PS efuse error codes for voltage out of range
+*
+ *****************************************************************************/
+
+#ifndef XILSKEY_UTILS_H
+#define XILSKEY_UTILS_H
+/***************************** Include Files ********************************/
+#include "xadcps.h"
+/************************** Constant Definitions ****************************/
+/**************************** Type Definitions ******************************/
+/***************** Macros (Inline Functions) Definitions ********************/
+/**
+ * The following constants map to the XPAR parameters created in the
+ * xparameters.h file. They are defined here such that a user can easily
+ * change all the needed parameters in one place.
+ */
+#define XADC_DEVICE_ID 		XPAR_XADCPS_0_DEVICE_ID
+
+/**
+ * Temperature and voltage range for PS eFUSE reading and programming
+ * Temperature in Celsius('C) and Voltage(V) is in volts
+ */
+#define XSK_EFUSEPS_TEMP_MIN			(-40)
+#define XSK_EFUSEPS_TEMP_MAX			(125)
+#define XSK_EFUSEPS_READ_VPAUX_MIN		(1.71)
+#define XSK_EFUSEPS_READ_VPAUX_MAX		(1.98)
+#define XSK_EFUSEPS_WRITE_VPAUX_MIN	(1.71)
+#define XSK_EFUSEPS_WRITE_VPAUX_MAX	(1.98)
+
+/**
+ * Converting the celsius temperature to equivalent Binary data for xAdc
+ */
+#define XSK_EFUSEPS_TEMP_MIN_RAW	(XAdcPs_TemperatureToRaw(XSK_EFUSEPS_TEMP_MIN))
+#define XSK_EFUSEPS_TEMP_MAX_RAW	(XAdcPs_TemperatureToRaw(XSK_EFUSEPS_TEMP_MAX))
+
+/**
+ * Converting the voltage to equivalent Binary data for xAdc
+ */
+#define XSK_EFUSEPS_READ_VPAUX_MIN_RAW	(XAdcPs_VoltageToRaw(XSK_EFUSEPS_READ_VPAUX_MIN))
+#define XSK_EFUSEPS_READ_VPAUX_MAX_RAW	(XAdcPs_VoltageToRaw(XSK_EFUSEPS_READ_VPAUX_MAX))
+#define XSK_EFUSEPS_WRITE_VPAUX_MIN_RAW	(XAdcPs_VoltageToRaw(XSK_EFUSEPS_WRITE_VPAUX_MIN))
+#define XSK_EFUSEPS_WRITE_VPAUX_MAX_RAW	(XAdcPs_VoltageToRaw(XSK_EFUSEPS_WRITE_VPAUX_MAX))
+
+/**
+ * Temperature and voltage range for PL eFUSE reading and programming
+ * Temperature in Celsius('C) and Voltage(V) is in volts
+ */
+
+/**
+ * PL eFUSE write Min and Max Temperature and Voltages
+ */
+#define	XSK_EFUSEPL_WRITE_TEMP_MIN 				(15)
+#define	XSK_EFUSEPL_WRITE_TEMP_MAX				(125)
+
+#define	XSK_EFUSEPL_WRITE_VOLTAGE_VCCAUX_MIN 	(1.71)
+#define	XSK_EFUSEPL_WRITE_VOLTAGE_VCCAUX_MAX		(1.98)
+
+#define	XSK_EFUSEPL_WRITE_VOLTAGE_VCCINT_MIN 	(.87)
+#define	XSK_EFUSEPL_WRITE_VOLTAGE_VCCINT_MAX		(1.1)
+
+/**
+ * PL eFUSE read Min and Max Temperature and Voltages
+ */
+#define	XSK_EFUSEPL_READ_TEMP_MIN				(-55)
+#define	XSK_EFUSEPL_READ_TEMP_MAX				(125)
+#define	XSK_EFUSEPL_READ_VOLTAGE_VCCAUX_MIN		(1.62)
+#define	XSK_EFUSEPL_READ_VOLTAGE_VCCAUX_MAX		(1.98)
+
+#define	XSK_EFUSEPL_READ_VOLTAGE_VCCINT_MIN		(.795)
+#define	XSK_EFUSEPL_READ_VOLTAGE_VCCINT_MAX		(1.1)
+
+
+/**
+ * PL eFUSE write Min and Max Temperature and Voltages
+ */
+
+/**
+ * Converting the celsius temperature to equivalent Binary data for xAdc
+ */
+#define	XSK_EFUSEPL_WRITE_TEMP_MIN_RAW 			(XAdcPs_TemperatureToRaw(XSK_EFUSEPL_WRITE_TEMP_MIN))
+#define	XSK_EFUSEPL_WRITE_TEMP_MAX_RAW			(XAdcPs_TemperatureToRaw(XSK_EFUSEPL_WRITE_TEMP_MAX))
+
+/**
+ * Converting the voltage to equivalent Binary data for xAdc
+ */
+#define	XSK_EFUSEPL_WRITE_VOLTAGE_VCCAUX_MIN_RAW (XAdcPs_VoltageToRaw(XSK_EFUSEPL_WRITE_VOLTAGE_VCCAUX_MIN))
+#define	XSK_EFUSEPL_WRITE_VOLTAGE_VCCAUX_MAX_RAW	(XAdcPs_VoltageToRaw(XSK_EFUSEPL_WRITE_VOLTAGE_VCCAUX_MAX))
+
+/**
+ * Converting the voltage to equivalent Binary data for xAdc
+ */
+#define	XSK_EFUSEPL_WRITE_VOLTAGE_VCCINT_MIN_RAW (XAdcPs_VoltageToRaw(XSK_EFUSEPL_WRITE_VOLTAGE_VCCINT_MIN))
+#define	XSK_EFUSEPL_WRITE_VOLTAGE_VCCINT_MAX_RAW	(XAdcPs_VoltageToRaw(XSK_EFUSEPL_WRITE_VOLTAGE_VCCINT_MAX))
+
+/**
+ * PL eFUSE read Min and Max Temperature and Voltages
+ */
+
+/**
+ * Converting the celsius temperature to equivalent Binary data for xAdc
+ */
+#define	XSK_EFUSEPL_READ_TEMP_MIN_RAW	(XAdcPs_TemperatureToRaw(XSK_EFUSEPL_READ_TEMP_MIN))
+#define	XSK_EFUSEPL_READ_TEMP_MAX_RAW	(XAdcPs_TemperatureToRaw(XSK_EFUSEPL_READ_TEMP_MAX))
+
+/**
+ * Converting the voltage to equivalent Binary data for xAdc
+ */
+
+#define	XSK_EFUSEPL_READ_VOLTAGE_VCCAUX_MIN_RAW 	(XAdcPs_VoltageToRaw(XSK_EFUSEPL_READ_VOLTAGE_VCCAUX_MIN))
+#define	XSK_EFUSEPL_READ_VOLTAGE_VCCAUX_MAX_RAW	(XAdcPs_VoltageToRaw(XSK_EFUSEPL_READ_VOLTAGE_VCCAUX_MAX))
+
+/**
+ * Converting the voltage to equivalent Binary data for xAdc
+ */
+#define	XSK_EFUSEPL_READ_VOLTAGE_VCCINT_MIN_RAW 	(XAdcPs_VoltageToRaw(XSK_EFUSEPL_READ_VOLTAGE_VCCINT_MIN))
+#define	XSK_EFUSEPL_READ_VOLTAGE_VCCINT_MAX_RAW	(XAdcPs_VoltageToRaw(XSK_EFUSEPL_READ_VOLTAGE_VCCINT_MAX))
+
+/**
+ * Different voltage types that can be read from xAdc
+ */
+#define XSK_EFUSEPS_VPINT		(1)
+#define XSK_EFUSEPS_VPAUX		(2)
+#define XSK_EFUSEPS_VPDRO		(3)
+#define XSK_EFUSEPS_VINT		(4)
+#define XSK_EFUSEPS_VAUX		(5)
+
+#define XSK_EFUSE_DEBUG_GENERAL	0x00000001    /* general debug  messages */
+
+#if defined (XSK_EFUSE_DEBUG)
+#define xeFUSE_dbg_current_types (XSK_EFUSE_DEBUG_GENERAL)
+#else
+#define xeFUSE_dbg_current_types 0
+#endif
+#ifdef STDOUT_BASEADDRESS
+#define xeFUSE_printf(type,...) \
+		if (((type) & xeFUSE_dbg_current_types))  {xil_printf (__VA_ARGS__); }
+#else
+#define xeFUSE_printf(type, ...)
+#endif
+
+#define XSK_GLOBAL_TIMER_BASE_ADDRESS           (0xF8F00000)
+
+/**
+ * Global_Timer_Counter _Register0 (0xf8f00200)
+ */
+#define XSK_GLOBAL_TIMER_COUNT_REG_LOW          (XSK_GLOBAL_TIMER_BASE_ADDRESS + 0x200)
+
+/**
+ * Global_Timer_Counter _Register1 (0xf8f00204)
+ */
+#define XSK_GLOBAL_TIMER_COUNT_REG_HIGH         (XSK_GLOBAL_TIMER_BASE_ADDRESS + 0x204)
+
+/**
+ * Global_Timer_Control_Register (0xf8f00208)
+ */
+#define XSK_GLOBAL_TIMER_CTRL_REG               (XSK_GLOBAL_TIMER_BASE_ADDRESS + 0x208)
+
+
+/**
+ * System Level Control Registers Start Addr
+ */
+#define XSK_SLCR_START_ADDRESS					(0xF8000000)
+/**
+ * ARM PLL Control Register
+ */
+#define XSK_ARM_PLL_CTRL_REG					(XSK_SLCR_START_ADDRESS + 0x100)
+/**
+ * ARM Clock Control Register
+ */
+#define XSK_ARM_CLK_CTRL_REG					(XSK_SLCR_START_ADDRESS + 0x120)
+
+/**
+ *  PL eFUSE aes key size in characters
+ */
+#define XSK_EFUSEPL_AES_KEY_STRING_SIZE         	(64)
+/**
+ *  PL eFUSE user low key size in characters
+ */
+#define XSK_EFUSEPL_USER_LOW_KEY_STRING_SIZE    	(2)
+/**
+ *  PL eFUSE user high key size in characters
+ */
+#define XSK_EFUSEPL_USER_HIGH_KEY_STRING_SIZE   	(6)
+/**
+ *  AES Key size in Bytes
+ */
+#define XSK_EFUSEPL_AES_KEY_SIZE_IN_BYTES		(32)
+/**
+ *  User Key size in Bytes
+ */
+#define XSK_EFUSEPL_USER_KEY_SIZE_IN_BYTES		(4)
+/**
+ *  AES Key size in Bits
+ */
+#define XSK_EFUSEPL_AES_KEY_SIZE_IN_BITS			(256)
+/**
+ *  User Low Key size in Bytes
+ */
+#define XSK_EFUSEPL_USER_LOW_KEY_SIZE_IN_BITS	(8)
+/**
+ *  User High Key size in Bytes
+ */
+#define XSK_EFUSEPL_USER_HIGH_KEY_SIZE_IN_BITS	(24)
+/**
+ * Key length definition for RSA KEY Hash
+ */
+#define XSK_EFUSEPS_RSA_KEY_HASH_LEN_IN_BYTES	(32)
+/**
+ *  PS eFUSE RSA key Hash size in characters
+ */
+#define XSK_EFUSEPL_RSA_KEY_HASH_STRING_SIZE     (64)
+/************************** Variable Definitions ****************************/
+/**
+ * 	XADC Structure
+ */
+typedef struct
+{
+	/**
+	 * Current temperature
+	 */
+	u32 Temp;
+	/**
+	 * Minimum temperature
+	 */
+	u32 TempMin;
+	/**
+	 * Maximum temperature
+	 */
+	u32 TempMax;
+	/**
+	 * Voltage type to read to select from VCCPINT, VCCPAUX, VCCPDRO
+	 */
+	u32 VType;
+	/**
+	 * Current voltage of Vtype
+	 */
+	u32 V;
+	/**
+	 * Minimum voltage of Vtype
+	 */
+	u32 VMin;
+	/**
+	 * Maximum voltage of Vtype
+	 */
+	u32 VMax;
+} XSKEfusePs_XAdc;
+
+/**
+ * PL EFUSE error codes
+ */
+typedef enum {
+	XSK_EFUSEPL_ERROR_NONE = 0,
+
+	/**
+	 * EFUSE Read error codes
+	 */
+	XSK_EFUSEPL_ERROR_ROW_NOT_ZERO = 0x10,
+	XSK_EFUSEPL_ERROR_READ_ROW_OUT_OF_RANGE,
+	XSK_EFUSEPL_ERROR_READ_MARGIN_OUT_OF_RANGE,
+	XSK_EFUSEPL_ERROR_READ_BUFFER_NULL,
+	XSK_EFUSEPL_ERROR_READ_BIT_VALUE_NOT_SET,
+	XSK_EFUSEPL_ERROR_READ_BIT_OUT_OF_RANGE,
+	XSK_EFUSEPL_ERROR_READ_TMEPERATURE_OUT_OF_RANGE,
+	XSK_EFUSEPL_ERROR_READ_VCCAUX_VOLTAGE_OUT_OF_RANGE,
+	XSK_EFUSEPL_ERROR_READ_VCCINT_VOLTAGE_OUT_OF_RANGE,
+
+	/**
+	 * EFUSE Write error codes
+	 */
+	XSK_EFUSEPL_ERROR_WRITE_ROW_OUT_OF_RANGE,
+	XSK_EFUSEPL_ERROR_WRITE_BIT_OUT_OF_RANGE,
+	XSK_EFUSEPL_ERROR_WRITE_TMEPERATURE_OUT_OF_RANGE,
+	XSK_EFUSEPL_ERROR_WRITE_VCCAUX_VOLTAGE_OUT_OF_RANGE,
+	XSK_EFUSEPL_ERROR_WRITE_VCCINT_VOLTAGE_OUT_OF_RANGE,
+
+	/**
+	 * EFUSE CNTRL error codes
+	 */
+	XSK_EFUSEPL_ERROR_FUSE_CNTRL_WRITE_DISABLED,
+	XSK_EFUSEPL_ERROR_CNTRL_WRITE_BUFFER_NULL,
+
+	/**
+	 * EFUSE KEY error codes
+	 */
+	XSK_EFUSEPL_ERROR_NOT_VALID_KEY_LENGTH,
+	XSK_EFUSEPL_ERROR_ZERO_KEY_LENGTH,
+	XSK_EFUSEPL_ERROR_NOT_VALID_KEY_CHAR,
+	XSK_EFUSEPL_ERROR_NULL_KEY,
+
+	/**
+	 * XSKEfusepl_Program_Efuse() error codes
+	 */
+	XSK_EFUSEPL_ERROR_KEY_VALIDATION = 0xF000,
+	XSK_EFUSEPL_ERROR_PL_STRUCT_NULL = 0x1000,
+	XSK_EFUSEPL_ERROR_JTAG_SERVER_INIT = 0x1100,
+	XSK_EFUSEPL_ERROR_READING_FUSE_CNTRL = 0x1200,
+	XSK_EFUSEPL_ERROR_DATA_PROGRAMMING_NOT_ALLOWED = 0x1300,
+	XSK_EFUSEPL_ERROR_FUSE_CTRL_WRITE_NOT_ALLOWED = 0x1400,
+	XSK_EFUSEPL_ERROR_READING_FUSE_AES_ROW = 0x1500,
+	XSK_EFUSEPL_ERROR_AES_ROW_NOT_EMPTY = 0x1600,
+	XSK_EFUSEPL_ERROR_PROGRAMMING_FUSE_AES_ROW = 0x1700,
+	XSK_EFUSEPL_ERROR_READING_FUSE_USER_DATA_ROW = 0x1800,
+	XSK_EFUSEPL_ERROR_USER_DATA_ROW_NOT_EMPTY = 0x1900,
+	XSK_EFUSEPL_ERROR_PROGRAMMING_FUSE_DATA_ROW = 0x1A00,
+	XSK_EFUSEPL_ERROR_PROGRAMMING_FUSE_CNTRL_ROW = 0x1B00,
+	XSK_EFUSEPL_ERROR_XADC = 0x1C00,
+	XSK_EFUSEPL_ERROR_INVALID_REF_CLK= 0x3000
+}XSKEfusePl_ErrorCodes;
+
+
+/**
+ * PS EFUSE error codes
+ */
+typedef enum {
+	XSK_EFUSEPS_ERROR_NONE = 0,
+
+	/**
+	 * EFUSE Read error codes
+	 */
+	XSK_EFUSEPS_ERROR_ADDRESS_XIL_RESTRICTED = 0x01,
+	XSK_EFUSEPS_ERROR_READ_TMEPERATURE_OUT_OF_RANGE,
+	XSK_EFUSEPS_ERROR_READ_VCCPAUX_VOLTAGE_OUT_OF_RANGE,
+	XSK_EFUSEPS_ERROR_READ_VCCPINT_VOLTAGE_OUT_OF_RANGE,
+
+	/**
+	 * EFUSE Write error codes
+	 */
+	XSK_EFUSEPS_ERROR_WRITE_TEMPERATURE_OUT_OF_RANGE,
+	XSK_EFUSEPS_ERROR_WRITE_VCCPAUX_VOLTAGE_OUT_OF_RANGE,
+	XSK_EFUSEPS_ERROR_WRITE_VCCPINT_VOLTAGE_OUT_OF_RANGE,
+	XSK_EFUSEPS_ERROR_VERIFICATION,
+	XSK_EFUSEPS_ERROR_RSA_HASH_ALREADY_PROGRAMMED,
+
+	/**
+	 * FUSE CNTRL error codes
+	 */
+	XSK_EFUSEPS_ERROR_CONTROLLER_MODE,
+	XSK_EFUSEPS_ERROR_REF_CLOCK,
+	XSK_EFUSEPS_ERROR_READ_MODE,
+
+	/**
+	 * XADC Error Codes
+	 */
+	XSK_EFUSEPS_ERROR_XADC_CONFIG,
+	XSK_EFUSEPS_ERROR_XADC_INITIALIZE,
+	XSK_EFUSEPS_ERROR_XADC_SELF_TEST,
+
+	/**
+	 * Utils Error Codes
+	 */
+	XSK_EFUSEPS_ERROR_PARAMETER_NULL,
+	XSK_EFUSEPS_ERROR_STRING_INVALID,
+
+
+	/**
+	 * XSKEfuse_Write/Read()common error codes
+	 */
+	XSK_EFUSEPS_ERROR_PS_STRUCT_NULL=0x8100,
+	XSK_EFUSEPS_ERROR_XADC_INIT=0x8200,
+	XSK_EFUSEPS_ERROR_CONTROLLER_LOCK=0x8300,
+	XSK_EFUSEPS_ERROR_EFUSE_WRITE_PROTECTED=0x8400,
+	XSK_EFUSEPS_ERROR_CONTROLLER_CONFIG=0x8500,
+	XSK_EFUSEPS_ERROR_PS_PARAMETER_WRONG=0x8600,
+
+	/**
+	 * XSKEfusePs_Write() error codes
+	 */
+	XSK_EFUSEPS_ERROR_WRITE_128K_CRC_BIT=0x9100,
+	XSK_EFUSEPS_ERROR_WRITE_NONSECURE_INITB_BIT=0x9200,
+	XSK_EFUSEPS_ERROR_WRITE_UART_STATUS_BIT=0x9300,
+	XSK_EFUSEPS_ERROR_WRITE_RSA_HASH=0x9400,
+	XSK_EFUSEPS_ERROR_WRITE_RSA_AUTH_BIT=0x9500,
+	XSK_EFUSEPS_ERROR_WRITE_WRITE_PROTECT_BIT=0x9600,
+	XSK_EFUSEPS_ERROR_READ_HASH_BEFORE_PROGRAMMING=0x9700,
+
+	/**
+	 * XSKEfusePs_Read() error codes
+	 */
+	XSK_EFUSEPS_ERROR_READ_RSA_HASH=0xA100,
+
+}XSKEfusePs_ErrorCodes;
+
+/*
+ * For backward compatibility with old error codes
+ */
+
+#define XSK_EFUSEPS_ERROR_READ_VCCAUX_VOLTAGE_OUT_OF_RANGE XSK_EFUSEPS_ERROR_READ_VCCPAUX_VOLTAGE_OUT_OF_RANGE
+#define XSK_EFUSEPS_ERROR_READ_VCCINT_VOLTAGE_OUT_OF_RANGE XSK_EFUSEPS_ERROR_READ_VCCPINT_VOLTAGE_OUT_OF_RANGE
+#define XSK_EFUSEPS_ERROR_WRITE_VCCAUX_VOLTAGE_OUT_OF_RANGE XSK_EFUSEPS_ERROR_WRITE_VCCPAUX_VOLTAGE_OUT_OF_RANGE
+#define XSK_EFUSEPS_ERROR_WRITE_VCCINT_VOLTAGE_OUT_OF_RANGE XSK_EFUSEPS_ERROR_WRITE_VCCPINT_VOLTAGE_OUT_OF_RANGE
+
+
+
+/************************** Function Prototypes *****************************/
+u32 XilSKey_EfusePs_XAdcInit (void );
+void XilSKey_EfusePs_XAdcReadTemperatureAndVoltage(XSKEfusePs_XAdc *XAdcInstancePtr);
+void XilSKey_Efuse_StartTimer(u32 RefClk);
+u64 XilSKey_Efuse_GetTime();
+void XilSKey_Efuse_SetTimeOut(volatile u64* t, u64 us);
+u8 XilSKey_Efuse_IsTimerExpired(u64 t);
+void XilSKey_Efuse_ConvertBitsToBytes(const u8 * Bits, u8 * Bytes, u32 Len);
+void XilSKey_EfusePs_ConvertBytesToBits(const u8 * Bits, u8 * Bytes, u32 Len);
+void XilSKey_EfusePs_ConvertBytesBeToLe(const u8 *Be, u8 *Le, u32 Len);
+u32 XilSKey_Efuse_ValidateKey(const char *key, u32 len);
+u32 XilSKey_Efuse_IsValidChar(const char *c);
+/**
+ * Common functions
+ */
+u32 XilSKey_Efuse_ConvertStringToHexLE(const char * Str, u8 * Buf, u32 Len);
+u32 XilSKey_Efuse_ConvertStringToHexBE(const char * Str, u8 * Buf, u32 Len);
+u32 XilSKey_Efuse_ValidateKey(const char *Key, u32 Len);
+
+/***************************************************************************/
+
+
+
+#endif /* XILSKEY_UTILS_H */
diff --git a/lib/sw_services/xilskey/src/xilskey_bbram.c b/lib/sw_services/xilskey/src/xilskey_bbram.c
new file mode 100644
index 00000000..5e997c1f
--- /dev/null
+++ b/lib/sw_services/xilskey/src/xilskey_bbram.c
@@ -0,0 +1,172 @@
+/******************************************************************************
+*
+* 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_bbram.c
+* @note
+*
+*  			.
+*
+* MODIFICATION HISTORY:
+*
+* Ver   Who  	Date     Changes
+* ----- ---- 	-------- --------------------------------------------------------
+* 1.01a hk      09/18/13 First release
+*
+****************************************************************************/
+/***************************** Include Files *********************************/
+#include "xparameters.h"
+#include "xil_types.h"
+#include "xilskey_utils.h"
+#include "xilskey_bbram.h"
+
+/************************** Constant Definitions *****************************/
+/**************************** Type Definitions ******************************/
+/***************** Macros (Inline Functions) Definitions ********************/
+/************************** Variable Definitions ****************************/
+/************************** Function Prototypes *****************************/
+/**
+ * 	JTAG Server Initialization routine for Bbram
+ */
+extern int JtagServerInitBbram(XilSKey_Bbram *InstancePtr);
+
+/**
+ * BBRAM Algorithm - Initialization
+ */
+extern int Bbram_Init(XilSKey_Bbram *InstancePtr);
+
+/**
+ * BBRAM Algorithm - Program key
+ */
+extern int Bbram_ProgramKey(XilSKey_Bbram *InstancePtr);
+
+/**
+ * BBRAM Algorithm - Verify key
+ */
+extern int Bbram_VerifyKey(XilSKey_Bbram *InstancePtr);
+
+/**
+ * De-initialization
+ */
+extern void Bbram_DeInit(void);
+
+/***************************************************************************/
+/****************************************************************************/
+/**
+*
+* This function implements the BBRAM algorithm for programming and
+* verifying key. The program and verify will only work together in and
+* in that order.
+*
+* @param  BBRAM instance pointer
+*
+* @return
+*
+*	- XST_FAILURE - In case of failure
+*	- XST_SUCCESS - In case of Success
+*
+*
+* @note
+*
+*****************************************************************************/
+int XilSKey_Bbram_Program(XilSKey_Bbram *InstancePtr)
+{
+	u32 ArmPllFdiv;
+	u32 ArmClkDivisor;
+	u32 RefClk;
+	int Status;
+
+	if(NULL == InstancePtr)	{
+		return XST_FAILURE;
+	}
+
+	/**
+	 *  Extract PLL FDIV value from ARM PLL Control Register
+	 */
+	ArmPllFdiv = (Xil_In32(XSK_ARM_PLL_CTRL_REG)>>12 & 0x7F);
+
+	/**
+	 *  Extract Clock divisor value from ARM Clock Control Register
+	 */
+	ArmClkDivisor = (Xil_In32(XSK_ARM_CLK_CTRL_REG)>>8 & 0x3F);
+
+	/**
+	 * Initialize the variables
+	 */
+	RefClk = ((XPAR_PS7_CORTEXA9_0_CPU_CLK_FREQ_HZ * ArmClkDivisor)/
+				ArmPllFdiv);
+
+	/*
+	 * Initialize and start the timer
+	 */
+	XilSKey_Efuse_StartTimer(RefClk);
+
+	/*
+	 * JTAG server initialization
+	 */
+	if(JtagServerInitBbram(InstancePtr) != XST_SUCCESS) {
+		return XST_FAILURE;
+	}
+
+	/*
+	 * BBRAM Algorithm initialization
+	 */
+	Status = Bbram_Init(InstancePtr);
+	if(Status != XST_SUCCESS) {
+		return XST_FAILURE;
+	}
+
+	/*
+	 * BBRAM - Program key
+	 */
+	Status = Bbram_ProgramKey(InstancePtr);
+	if(Status != XST_SUCCESS) {
+		return XST_FAILURE;
+	}
+
+	/*
+	 * BBRAM - Verify key
+	 */
+	Status = Bbram_VerifyKey(InstancePtr);
+	if(Status != XST_SUCCESS) {
+		return XST_FAILURE;
+	}
+
+	/*
+	 * De-initialization
+	 */
+	Bbram_DeInit();
+
+	return XST_SUCCESS;
+}
diff --git a/lib/sw_services/xilskey/src/xilskey_epl.c b/lib/sw_services/xilskey/src/xilskey_epl.c
new file mode 100644
index 00000000..3ee2d171
--- /dev/null
+++ b/lib/sw_services/xilskey/src/xilskey_epl.c
@@ -0,0 +1,1342 @@
+/******************************************************************************
+*
+* 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_epl.c
+* @note
+*
+*  			Contains the function definitions for the PL eFUSE functionality.
+*
+* MODIFICATION HISTORY:
+*
+* Ver   Who  	Date     Changes
+* ----- ---- 	-------- --------------------------------------------------------
+* 1.00a rpoolla 04/26/13 First release
+* 1.02a hk      10/28/13 Added API's to read status bits and key.PR# 735957
+* 2.00  hk      22/01/14 Corrected PL voltage checks to VCCINT and VCCAUX.
+*                        CR#768077
+*
+*
+****************************************************************************/
+/***************************** Include Files *********************************/
+#include "xparameters.h"
+#include "xil_types.h"
+#include "xilskey_utils.h"
+#include "xilskey_epl.h"
+/************************** Constant Definitions *****************************/
+#define XSK_EFUSEPL_ARRAY_FUSE_CNTRL_ROW		(0) /**< Fuse Ctrl Row*/
+#define XSK_EFUSEPL_ARRAY_FUSE_AES_KEY_SIZE		(256) /**< AES Key size*/
+#define XSK_EFUSEPL_ARRAY_FUSE_USER_KEY_SIZE	(32) /**< User key size*/
+#define XSK_EFUSEPL_ARRAY_MAX_ROW				(32) /**< PLeFUSE Max Rows*/
+#define XSK_EFUSEPL_ARRAY_MAX_COL				(32) /**< PLeFUSE Max Columns*/
+#define XSK_EFUSEPL_ARRAY_AES_DATA_ROW_START	(20) /**< AES Data Start Row*/
+#define XSK_EFUSEPL_ARRAY_AES_DATA_ROW_END		(30) /**< AES Data End Row*/
+#define XSK_EFUSEPL_ARRAY_USER_DATA_START_ROW	(31) /**< User Data Start Row*/
+#define XSK_EFUSEPL_ARRAY_AES_DATA_BITS_IN_30th_ROW	(16) /**< AES Data bits
+															* count in 30th Row
+															*/
+#define XSK_EFUSEPL_ARRAY_USER_DATA_BITS_IN_30th_ROW (8) /**< User Data bits
+															* count in 30th Row
+															*/
+#define XSK_EFUSEPL_ARRAY_MAX_PAYLAOD_BITS_IN_A_ROW	(24)/**< Max Pay load
+															* in Row
+															*/
+#define XSK_EFUSEPL_ARRAY_MAX_ECC_BITS_IN_A_ROW		(6)	/**< Max ECC bits
+															 * in a Row
+															 */
+#define XSK_EFUSEPL_ARRAY_ECC_START_BIT_IN_A_ROW	(24)/**< ECC Start Bit
+															 * position in
+															 * a Row
+															 */
+#define XSK_EFUSEPL_ARRAY_ECC_END_BIT_IN_A_ROW		(29)/**< ECC End Bit
+															 * position in
+															 * a Row
+															 */
+#define XSK_EFUSEPL_ARRAY_FUSE_CNTRL_MAX_BITS		(11)/**< Fuse Control max
+															 * bits
+															 */
+#define XSK_EFUSEPL_ARRAY_FUSE_CNTRL_REDUNDENT_INDEX (14)/**< Redundant bit
+															 * Index
+															 */
+#define XSK_EFUSEPL_ARRAY_FUSE_CNTRL_START_BIT	(0)	 /**< Fuse Control
+															* Start bit
+															*/
+#define XSK_EFUSEPL_ARRAY_FUSE_CNTRL_END_BIT	(10) /**< Fuse Control
+															* Start bit
+															*/
+#define XSK_EFUSEPL_ARRAY_UNSUPPORTED_BIT6		(6)	 /**< Unsupported bit*/
+#define XSK_EFUSEPL_ARRAY_UNSUPPORTED_BIT7		(7)	 /**< Unsupporte bit*/
+#define XSK_EFUSEPL_ARRAY_FUSE_CNTRL_REDUNDENT_START_BIT	(14)/**< Redundant
+															 * bit start Index
+															 */
+#define XSK_EFUSEPL_ARRAY_UNSUPPORTED_RED_FOR_BIT6	(20)/**< Unsupported bit*/
+#define XSK_EFUSEPL_ARRAY_UNSUPPORTED_RED_FOR_BIT7	(21)/**< Unsupported bit*/
+#define XSK_EFUSEPL_ARRAY_FUSE_CNTRL_REDUNDENT_END_BIT	(24)/**< Redundant bit
+															 * End Index
+															 */
+#define XSK_EFUSEPL_MAX_REF_CLK_FREQ	60000000 /**< Max Ref Clk Frequency */
+#define XSK_EFUSEPL_MIN_REF_CLK_FREQ	20000000 /**< Min Ref Clk Frequency */
+/**************************** Type Definitions ******************************/
+/**
+ * Read or Write eFUSE Margin Options
+ */
+typedef enum {
+	XSK_EFUSEPL_READ_NORMAL = 0x1,	/**< Margin 1*/
+	XSK_EFUSEPL_READ_MARGIN_1 = 0x2, /**< Margin 2*/
+	XSK_EFUSEPL_READ_MARGIN_2 = 0x4, /**< Margin 4*/
+	XSK_EFUSEPL_READ_MARGIN_MAX = 0x7 /**< Max Margin 7*/
+}XSK_EfusePl_MarginOption;
+/**
+ * Fuse Control Row Bit Indices
+ */
+typedef enum {
+	XSK_EFUSEPL_CNTRL_FORCE_PCYCLE_RECONFIG = 0x01,/**< Bit1 of Fuse Ctrl Row*/
+	XSK_EFUSEPL_CNTRL_DISABLE_KEY_WRITE,		   /**< Bit2 of Fuse Ctrl Row*/
+	XSK_EFUSEPL_CNTRL_DISABLE_AES_KEY_READ,		   /**< Bit3 of Fuse Ctrl Row*/
+	XSK_EFUSEPL_CNTRL_DISABLE_USER_KEY_READ,       /**< Bit4 of Fuse Ctrl Row*/
+	XSK_EFUSEPL_CNTRL_DISABLE_FUSE_CNTRL_WRITE,    /**< Bit5 of Fuse Ctrl Row*/
+	XSK_EFUSEPL_CNTRL_FORCE_USE_AES_ONLY = 0x08,   /**< Bit8 of Fuse Ctrl Row*/
+	XSK_EFUSEPL_CNTRL_JTAG_CHAIN_DISABLE,          /**< Bit9 of Fuse Ctrl Row*/
+	XSK_EFUSEPL_CNTRL_BBRAM_KEY_DISABLE           /**< Bit10 of Fuse Ctrl Row*/
+}XSKEfusePl_FuseCntrlBits;
+/***************** Macros (Inline Functions) Definitions ********************/
+
+
+/************************** Variable Definitions ****************************/
+u32 ErrorCode;	/**< Global variable which holds the error key*/
+static u8 AesDataInBytes[XSK_EFUSEPL_ARRAY_FUSE_AES_KEY_SIZE];
+static u8 UserDataInBytes[XSK_EFUSEPL_ARRAY_FUSE_USER_KEY_SIZE];
+
+/************************** Function Prototypes *****************************/
+/**
+ * PL eFUSE interface functions
+ */
+static u8 XilSKey_EfusePl_ProgramBit(u8 Row, u8 Bit);
+
+static u8 XilSKey_EfusePl_ProgramRow(u8 Row, u8 *RowData);
+
+static u8 XilSKey_EfusePl_ProgramControlRegister(u8 *CtrlData);
+
+static u8 XilSKey_EfusePl_ReadBit(u8 Row, u8 Bit, u8 MarginOption, u8 *BitData);
+
+static u8 XilSKey_EfusePl_ReadRow(u32 Row, u8 MarginOption, u8 *RowData);
+
+static u8 XilSKey_EfusePl_ReadControlRegister(u8 *CtrlData);
+
+static u8 XilSKey_EfusePl_VerifyBit(u8 Row, u8 Bit, u8 MarginOption);
+
+static u8 XilSKey_EfusePl_IsVectorAllZeros(u8 *RowDataPtr);
+
+static void XilSKey_EfusePl_CalculateEcc(u8 *RowData, u8 *ECCData);
+/**
+ * 	JTAG Server Initialization routine
+ */
+extern int JtagServerInit(XilSKey_EPl *PlInstancePtr);
+/**
+ * 	JTAG Server Write routine
+ */
+extern void JtagWrite(unsigned char row, unsigned char bit);
+/**
+ * 	JTAG Server Read routine
+ */
+extern void JtagRead(unsigned char row, unsigned int * row_data, unsigned char marginOption);
+/***************************************************************************/
+/****************************************************************************/
+/**
+*
+*
+*	Programs PL eFUSE with input data given
+*
+*
+* @param	InstancePtr - Input data to be written to PL eFUSE
+*
+* @return
+*
+*	- XST_FAILURE - In case of failure
+*	- XST_SUCCESS - In case of Success
+*
+*
+* @note		Updates the global variable ErrorCode with error code(if any).
+*
+*****************************************************************************/
+u32 XilSKey_EfusePl_Program(XilSKey_EPl *InstancePtr)
+{
+	u32 Row = 0;
+	u8 RowData[XSK_EFUSEPL_ARRAY_MAX_COL]={0};
+	u8 CtrlData[XSK_EFUSEPL_ARRAY_FUSE_CNTRL_MAX_BITS]={0};
+	u32 Index = 0;
+	u32 Status;
+	u32 RefClk;
+	u32 ArmPllFDiv,ArmClkDivisor;
+	ErrorCode = XSK_EFUSEPL_ERROR_NONE;
+
+
+	if(NULL == InstancePtr)	{
+		return XSK_EFUSEPL_ERROR_PL_STRUCT_NULL;
+	}
+
+	if(!(InstancePtr->SystemInitDone))
+	{
+		/**
+		 *  Extract PLL FDIV value from ARM PLL Control Register
+		 */
+		ArmPllFDiv = (Xil_In32(XSK_ARM_PLL_CTRL_REG)>>12 & 0x7F);
+
+		/**
+		 *  Extract Clock divisor value from ARM Clock Control Register
+		 */
+		ArmClkDivisor = (Xil_In32(XSK_ARM_CLK_CTRL_REG)>>8 & 0x3F);
+
+		/**
+		 * Initialize the variables
+		 */
+		RefClk = ((XPAR_PS7_CORTEXA9_0_CPU_CLK_FREQ_HZ *
+				ArmClkDivisor)/ ArmPllFDiv);
+
+		/**
+		 * Return error if the reference clock frequency is not in
+		 * between 20 & 60MHz
+		 */
+		if((RefClk < XSK_EFUSEPL_MIN_REF_CLK_FREQ) ||
+				(RefClk > XSK_EFUSEPL_MAX_REF_CLK_FREQ)) {
+			return XSK_EFUSEPL_ERROR_INVALID_REF_CLK;
+		}
+		/**
+		 * Initialize the system ,
+		 * which means initialize the timer, xadc, and jtag
+		 * server using the passed info.
+		 */
+
+		XilSKey_Efuse_StartTimer(RefClk);
+
+		Status = XilSKey_EfusePs_XAdcInit();
+		if(Status != XST_SUCCESS) {
+			ErrorCode = Status;
+			return (XSK_EFUSEPL_ERROR_XADC + ErrorCode);
+		}
+		/**
+		 * Start using the Jtag server to read the JTAG ID and
+		 * compare with the stored ID, if it not matches return with
+		 * unique error code.
+		 * By reading the Jtag ID we will be sure that the JTAG related
+		 * stuff is working as expected.
+		 */
+		if(JtagServerInit(InstancePtr) != XST_SUCCESS) {
+			return XSK_EFUSEPL_ERROR_JTAG_SERVER_INIT;
+		}
+
+		InstancePtr->SystemInitDone = 1;
+
+	}
+
+	/**
+	 *	Read the FUSE_CNTL register bits [5:2], and if any of them is found to
+	 *	be set to 1 then we can not write to the eFUSE, so return with unique
+	 *	error.
+	 *
+	 *	If everything is well above then start programming with FUSE_AES key as
+	 *	passed to this function, followed by FUSE_USER if selected.
+	 *
+	 *	AES key is 256 bits, but has to be written across many rows, in the PL
+	 *	eFUSE each row has 24 bits of data bits and 6 bits of ecc bits.
+	 *	So for 256 bits we will need full 10 rows(240 bits) and extra 1 row for
+	 *	remaining 16 bits, but rest 8 bits will be taken from the FUSE_USER key
+	 *	value[7:0]
+	 *
+	 *	check if FUSE_CNTRL allows us to read and write the AES and USER eFUSE
+	 *	array.
+	 */
+
+
+	if(XilSKey_EfusePl_ReadControlRegister(CtrlData) != XST_SUCCESS) {
+		return (XSK_EFUSEPL_ERROR_READING_FUSE_CNTRL + ErrorCode);
+	}
+
+	if (((CtrlData[XSK_EFUSEPL_CNTRL_DISABLE_AES_KEY_READ] == TRUE) ||
+		(CtrlData[XSK_EFUSEPL_CNTRL_DISABLE_USER_KEY_READ] == TRUE)||
+		(CtrlData[XSK_EFUSEPL_CNTRL_DISABLE_KEY_WRITE]== TRUE)) &&
+		((InstancePtr->ProgAESandUserLowKey == TRUE) ||
+		(InstancePtr->ProgUserHighKey == TRUE))) {
+		return (XSK_EFUSEPL_ERROR_DATA_PROGRAMMING_NOT_ALLOWED + ErrorCode);
+	}
+
+	if((CtrlData[XSK_EFUSEPL_CNTRL_DISABLE_KEY_WRITE] == TRUE) &&
+	    ((InstancePtr->ForcePowerCycle == TRUE)||
+	     (InstancePtr->KeyWrite == TRUE)||
+	     (InstancePtr->AESKeyRead == TRUE)||
+	     (InstancePtr->UserKeyRead == TRUE)||
+	     (InstancePtr->UseAESOnly == TRUE)||
+	     (InstancePtr->JtagDisable == TRUE)||
+	     (InstancePtr->AESKeyExclusive == TRUE))) {
+		return (XSK_EFUSEPL_ERROR_FUSE_CTRL_WRITE_NOT_ALLOWED + ErrorCode);
+	}
+	/**
+	 * convert each aes data bits to bytes.
+	 */
+	XilSKey_Efuse_ConvertBitsToBytes(&InstancePtr->AESKey[0],
+									AesDataInBytes,
+									XSK_EFUSEPL_ARRAY_FUSE_AES_KEY_SIZE);
+
+	/**
+	 * convert each user data bits to bytes.
+	 */
+	XilSKey_Efuse_ConvertBitsToBytes(&InstancePtr->UserKey[0],
+									UserDataInBytes,
+									XSK_EFUSEPL_ARRAY_FUSE_USER_KEY_SIZE);
+
+
+	if(InstancePtr->ProgAESandUserLowKey == TRUE) {
+		/**
+		 * check if row 20 to 30 are empty before programming AES and
+		 * USER low key.
+		 */
+		for(Row=XSK_EFUSEPL_ARRAY_AES_DATA_ROW_START;
+			Row<=XSK_EFUSEPL_ARRAY_AES_DATA_ROW_END;
+			Row++) {
+			if(XilSKey_EfusePl_ReadRow(Row, XSK_EFUSEPL_READ_NORMAL,
+										   RowData) != XST_SUCCESS) {
+				return (XSK_EFUSEPL_ERROR_READING_FUSE_AES_ROW + ErrorCode);
+			}
+			if(XilSKey_EfusePl_IsVectorAllZeros(RowData) != XST_SUCCESS) {
+				return (XSK_EFUSEPL_ERROR_AES_ROW_NOT_EMPTY + ErrorCode);
+			}
+		}
+
+		/**
+		 * program AES_KEY 256 bits and USER_KEY lower 8 bits first.
+		 */
+		for(Row=XSK_EFUSEPL_ARRAY_AES_DATA_ROW_START;
+				Row<=XSK_EFUSEPL_ARRAY_AES_DATA_ROW_END;
+				Row++) {
+			if(Row < XSK_EFUSEPL_ARRAY_AES_DATA_ROW_END) {
+				/**
+				 * prepare row data for row from 20 to 29.
+				 */
+				for(Index=0;
+					Index<XSK_EFUSEPL_ARRAY_MAX_PAYLAOD_BITS_IN_A_ROW;
+					Index++) {
+						RowData[Index] = AesDataInBytes[
+					                     (Index +
+										 ((Row -
+										 XSK_EFUSEPL_ARRAY_AES_DATA_ROW_START) *
+								XSK_EFUSEPL_ARRAY_MAX_PAYLAOD_BITS_IN_A_ROW))];
+				}
+			}
+			else
+			{
+				/**
+				 * prepare row data for row 30.
+				 */
+				for(Index=0;
+					Index<XSK_EFUSEPL_ARRAY_MAX_PAYLAOD_BITS_IN_A_ROW;
+					Index++) {
+					if(Index < XSK_EFUSEPL_ARRAY_AES_DATA_BITS_IN_30th_ROW) {
+						RowData[Index] =
+								AesDataInBytes[
+						            (Index +
+								((Row -
+						              XSK_EFUSEPL_ARRAY_AES_DATA_ROW_START) *
+						         XSK_EFUSEPL_ARRAY_MAX_PAYLAOD_BITS_IN_A_ROW))];
+					}
+					else {
+						RowData[Index] =
+								UserDataInBytes[Index -
+								   XSK_EFUSEPL_ARRAY_AES_DATA_BITS_IN_30th_ROW];
+					}
+				}
+			}
+
+			if(XilSKey_EfusePl_ProgramRow(Row, RowData) != XST_SUCCESS) {
+				return (XSK_EFUSEPL_ERROR_PROGRAMMING_FUSE_AES_ROW +
+						ErrorCode);
+			}
+		}
+	}
+
+	if(InstancePtr->ProgUserHighKey == TRUE) {
+		/**
+		 * check if 31 is empty before programming USER high key.
+		 */
+		if(XilSKey_EfusePl_ReadRow(XSK_EFUSEPL_ARRAY_USER_DATA_START_ROW,
+									   XSK_EFUSEPL_READ_NORMAL, RowData) !=
+									   XST_SUCCESS) {
+			return (XSK_EFUSEPL_ERROR_READING_FUSE_USER_DATA_ROW + ErrorCode);
+		}
+
+
+		if(XilSKey_EfusePl_IsVectorAllZeros(RowData) != XST_SUCCESS) {
+			return (XSK_EFUSEPL_ERROR_USER_DATA_ROW_NOT_EMPTY + ErrorCode);
+		}
+
+		/**
+		 * Program USER_KEY high 24 bits next.
+		 * Prepare row data for row 31.
+		 */
+
+		for(Index=0; Index<XSK_EFUSEPL_ARRAY_MAX_PAYLAOD_BITS_IN_A_ROW; Index++) {
+			RowData[Index] =
+					UserDataInBytes[Index +
+					              XSK_EFUSEPL_ARRAY_USER_DATA_BITS_IN_30th_ROW];
+		}
+
+		if(XilSKey_EfusePl_ProgramRow(XSK_EFUSEPL_ARRAY_USER_DATA_START_ROW,
+										RowData) != XST_SUCCESS) {
+			return (XSK_EFUSEPL_ERROR_PROGRAMMING_FUSE_DATA_ROW + ErrorCode);
+		}
+	}
+	CtrlData[XSK_EFUSEPL_CNTRL_FORCE_PCYCLE_RECONFIG] = InstancePtr->ForcePowerCycle;
+	CtrlData[XSK_EFUSEPL_CNTRL_DISABLE_KEY_WRITE] 	= InstancePtr->KeyWrite;
+	CtrlData[XSK_EFUSEPL_CNTRL_DISABLE_AES_KEY_READ] = InstancePtr->AESKeyRead;
+	CtrlData[XSK_EFUSEPL_CNTRL_DISABLE_USER_KEY_READ] = InstancePtr->UserKeyRead;
+	CtrlData[XSK_EFUSEPL_CNTRL_DISABLE_FUSE_CNTRL_WRITE] = InstancePtr->CtrlWrite;
+	CtrlData[XSK_EFUSEPL_CNTRL_FORCE_USE_AES_ONLY] = InstancePtr->UseAESOnly;
+	CtrlData[XSK_EFUSEPL_CNTRL_JTAG_CHAIN_DISABLE] = InstancePtr->JtagDisable;
+	CtrlData[XSK_EFUSEPL_CNTRL_BBRAM_KEY_DISABLE] = InstancePtr->AESKeyExclusive;
+
+	if(XilSKey_EfusePl_ProgramControlRegister(CtrlData) != XST_SUCCESS)	{
+			return (XSK_EFUSEPL_ERROR_PROGRAMMING_FUSE_CNTRL_ROW + ErrorCode);
+	}
+	/**
+	 * If everything is ok then return PASS.
+	 */
+	return XST_SUCCESS;
+}
+/****************************************************************************/
+/**
+*
+* Checks whether data bits (0-29) of an PL eFUSE row are all zeroes or not
+*
+*
+*
+* @param	RowDataPtr - row data pointer
+*
+* @return
+*
+*	- XST_FAILURE - In case of failure
+*	- XST_SUCCESS - In case of Success
+*
+* @note		None.
+*
+*****************************************************************************/
+u8 XilSKey_EfusePl_IsVectorAllZeros(u8 *RowDataPtr)
+{
+	u32 Index;
+	for(Index=0; Index<=XSK_EFUSEPL_ARRAY_ECC_END_BIT_IN_A_ROW; Index++) {
+		if(RowDataPtr[Index] != 0) {
+			return XST_FAILURE;
+		}
+	}
+	return XST_SUCCESS;
+}
+
+/****************************************************************************/
+/**
+*
+* Programs a bit of PL eFUSE row
+*
+*
+*
+* @param Row - row number
+* @param Bit - bit position
+*
+* @return
+*
+*	- XST_FAILURE - In case of failure
+*	- XST_SUCCESS - In case of Success
+*
+*
+* @note		Updates the global variable ErrorCode with error code(if any).
+*
+*****************************************************************************/
+u8 XilSKey_EfusePl_ProgramBit(u8 Row, u8 Bit)
+{
+	XSKEfusePs_XAdc PL_XAdc;
+	/**
+	 *Check if the row position is valid.
+	 */
+	if( (Row > XSK_EFUSEPL_ARRAY_USER_DATA_START_ROW) ||
+			( (Row > XSK_EFUSEPL_ARRAY_FUSE_CNTRL_ROW)
+		     && (Row < XSK_EFUSEPL_ARRAY_AES_DATA_ROW_START)
+			)
+	  )
+	{
+		ErrorCode = XSK_EFUSEPL_ERROR_WRITE_ROW_OUT_OF_RANGE;
+		return XST_FAILURE;
+	}
+
+	/**
+	 * Check if the bit position is valid.
+	 */
+	if((Bit < XSK_EFUSEPL_ARRAY_FUSE_CNTRL_START_BIT) ||
+	   (Bit > XSK_EFUSEPL_ARRAY_ECC_END_BIT_IN_A_ROW)) {
+		ErrorCode = XSK_EFUSEPL_ERROR_WRITE_BIT_OUT_OF_RANGE;
+		return XST_FAILURE;
+	}
+
+	/**
+	 * If row=0 then bit should be either 1 to 5 and 8 to 10, 15 to 19 and
+	 * 22 to 24 rest all are not supported
+	 */
+	if(Row == XSK_EFUSEPL_ARRAY_FUSE_CNTRL_ROW) {
+
+		if((Bit == XSK_EFUSEPL_ARRAY_FUSE_CNTRL_START_BIT) ||
+			(Bit == XSK_EFUSEPL_ARRAY_UNSUPPORTED_BIT6) ||
+			(Bit == XSK_EFUSEPL_ARRAY_UNSUPPORTED_BIT7)||
+			(Bit == XSK_EFUSEPL_ARRAY_UNSUPPORTED_RED_FOR_BIT6)||
+			(Bit == XSK_EFUSEPL_ARRAY_UNSUPPORTED_RED_FOR_BIT7)) {
+			ErrorCode = XSK_EFUSEPL_ERROR_WRITE_BIT_OUT_OF_RANGE;
+			return XST_FAILURE;
+		}
+
+		if((Bit > XSK_EFUSEPL_ARRAY_FUSE_CNTRL_END_BIT) &&
+		   (Bit < XSK_EFUSEPL_ARRAY_FUSE_CNTRL_REDUNDENT_START_BIT)) {
+			ErrorCode = XSK_EFUSEPL_ERROR_WRITE_BIT_OUT_OF_RANGE;
+			return XST_FAILURE;
+		}
+
+		if(Bit > XSK_EFUSEPL_ARRAY_FUSE_CNTRL_REDUNDENT_END_BIT){
+			ErrorCode = XSK_EFUSEPL_ERROR_WRITE_BIT_OUT_OF_RANGE;
+			return XST_FAILURE;
+		}
+	}
+
+	/**
+	 * Monitor the Voltage and temperature using XADC, if out of range return
+	 * unique error.
+	 */
+	PL_XAdc.VType = XSK_EFUSEPS_VAUX;
+	XilSKey_EfusePs_XAdcReadTemperatureAndVoltage(&PL_XAdc);
+	if((PL_XAdc.Temp < XSK_EFUSEPL_WRITE_TEMP_MIN_RAW) ||
+		(PL_XAdc.Temp > XSK_EFUSEPL_WRITE_TEMP_MAX_RAW)) {
+		ErrorCode = XSK_EFUSEPL_ERROR_WRITE_TMEPERATURE_OUT_OF_RANGE;
+		return XST_FAILURE;
+	}
+
+	if((PL_XAdc.V < XSK_EFUSEPL_WRITE_VOLTAGE_VCCAUX_MIN_RAW) ||
+		(PL_XAdc.V > XSK_EFUSEPL_WRITE_VOLTAGE_VCCAUX_MAX_RAW)) {
+		ErrorCode = XSK_EFUSEPL_ERROR_WRITE_VCCAUX_VOLTAGE_OUT_OF_RANGE;
+		return XST_FAILURE;
+	}
+
+	PL_XAdc.VType = XSK_EFUSEPS_VINT;
+	XilSKey_EfusePs_XAdcReadTemperatureAndVoltage(&PL_XAdc);
+	if((PL_XAdc.V < XSK_EFUSEPL_WRITE_VOLTAGE_VCCINT_MIN_RAW) ||
+	   (PL_XAdc.V > XSK_EFUSEPL_WRITE_VOLTAGE_VCCINT_MAX_RAW)) {
+		ErrorCode = XSK_EFUSEPL_ERROR_WRITE_VCCINT_VOLTAGE_OUT_OF_RANGE;
+		return XST_FAILURE;
+	}
+
+	JtagWrite(Row, Bit);
+	return XST_SUCCESS;
+}
+/****************************************************************************/
+/**
+*
+* Programs PL eFUSE row
+*
+*
+*
+* @param	Row	- 		row number
+* @param	RowData-	row data pointer
+*
+* @return
+*
+*	- XST_FAILURE - In case of failure
+*	- XST_SUCCESS - In case of Success
+*
+*
+* @note		Updates the global variable ErrorCode with error code(if any).
+*
+*****************************************************************************/
+
+u8 XilSKey_EfusePl_ProgramRow(u8 Row, u8 *RowData)
+{
+	u32 Bit = 0;
+	u8 ECCData[XSK_EFUSEPL_ARRAY_MAX_ECC_BITS_IN_A_ROW] = {0};
+
+	/**
+	 * check if row_data is not NULL
+	 */
+	if(NULL == RowData) {
+		ErrorCode = XSK_EFUSEPL_ERROR_READ_BUFFER_NULL;
+		return XST_FAILURE;
+	}
+
+	if(Row == XSK_EFUSEPL_ARRAY_FUSE_CNTRL_ROW) {
+		ErrorCode = XSK_EFUSEPL_ERROR_WRITE_ROW_OUT_OF_RANGE;
+		return XST_FAILURE;
+	}
+
+	for(Bit=0; Bit < XSK_EFUSEPL_ARRAY_MAX_PAYLAOD_BITS_IN_A_ROW ; Bit++ ) {
+		if(RowData[Bit]) {
+			if(XilSKey_EfusePl_ProgramBit(Row, Bit) != XST_SUCCESS) {
+				return XST_FAILURE;
+			}
+
+			if(XilSKey_EfusePl_VerifyBit(Row, Bit, XSK_EFUSEPL_READ_NORMAL)
+											!= XST_SUCCESS) {
+				return XST_FAILURE;
+			}
+
+			if(XilSKey_EfusePl_VerifyBit(Row,Bit,XSK_EFUSEPL_READ_MARGIN_1)
+											!= XST_SUCCESS) {
+				return XST_FAILURE;
+			}
+		}
+	}
+
+	XilSKey_EfusePl_CalculateEcc(RowData, ECCData);
+	for(Bit=XSK_EFUSEPL_ARRAY_ECC_START_BIT_IN_A_ROW;
+		Bit <= XSK_EFUSEPL_ARRAY_ECC_END_BIT_IN_A_ROW;
+		Bit++) {
+		if(ECCData[Bit - XSK_EFUSEPL_ARRAY_ECC_START_BIT_IN_A_ROW]) {
+			if(XilSKey_EfusePl_ProgramBit(Row, Bit) != XST_SUCCESS) {
+				return XST_FAILURE;
+			}
+
+			if(XilSKey_EfusePl_VerifyBit(Row, Bit, XSK_EFUSEPL_READ_NORMAL)
+											!= XST_SUCCESS) {
+				return XST_FAILURE;
+			}
+
+			if(XilSKey_EfusePl_VerifyBit(Row,Bit,XSK_EFUSEPL_READ_MARGIN_1)
+											!= XST_SUCCESS) {
+				return XST_FAILURE;
+			}
+
+		}
+	}
+
+	return XST_SUCCESS;
+}
+/****************************************************************************/
+/**
+*
+* Programs PL eFUSE Control Register
+*
+*
+*
+* @param	CtrlData - Control data pointer
+*
+* @return
+*
+*	- XST_FAILURE - In case of failure
+*	- XST_SUCCESS - In case of Success
+*
+*
+* @note		Updates the global variable ErrorCode with error code(if any).
+*
+*****************************************************************************/
+u8 XilSKey_EfusePl_ProgramControlRegister(u8 *CtrlData)
+{
+	u8 TmpCtrlData[XSK_EFUSEPL_ARRAY_FUSE_CNTRL_MAX_BITS]={0};
+	u32 Index = 0;
+
+	/**
+	 * check if cntrl_data is not NULL
+	 */
+	if(NULL == CtrlData) {
+		ErrorCode = XSK_EFUSEPL_ERROR_CNTRL_WRITE_BUFFER_NULL;
+		return XST_FAILURE;
+	}
+
+	/**
+	 *	Read the FUSE_CNTRL register
+	 */
+	if(XilSKey_EfusePl_ReadControlRegister(TmpCtrlData) != XST_SUCCESS)	{
+		return XST_FAILURE;
+	}
+
+	/**
+	 * check if FUSE_CNTRL allows us to write FUSE_CNTRL eFUSE array.
+	 */
+	if(TmpCtrlData[XSK_EFUSEPL_CNTRL_DISABLE_FUSE_CNTRL_WRITE] == TRUE) {
+		/**
+		 * This means we cannot program FUSE_CNTRL register
+		 */
+		ErrorCode = XSK_EFUSEPL_ERROR_FUSE_CNTRL_WRITE_DISABLED;
+		return XST_FAILURE;
+	}
+
+
+	for(Index=1;Index<XSK_EFUSEPL_ARRAY_FUSE_CNTRL_MAX_BITS;Index++)	{
+
+		if((Index == 6) || (Index == 7)) {
+			continue;
+		}
+
+		if((CtrlData[Index] == TRUE) && (TmpCtrlData[Index] == FALSE)) {
+			if(XilSKey_EfusePl_ProgramBit(XSK_EFUSEPL_ARRAY_FUSE_CNTRL_ROW,
+											  Index) != XST_SUCCESS) {
+				return XST_FAILURE;
+			}
+
+			if(XilSKey_EfusePl_VerifyBit(XSK_EFUSEPL_ARRAY_FUSE_CNTRL_ROW,
+							Index, XSK_EFUSEPL_READ_NORMAL) != XST_SUCCESS) {
+				return XST_FAILURE;
+			}
+
+			if(XilSKey_EfusePl_VerifyBit(XSK_EFUSEPL_ARRAY_FUSE_CNTRL_ROW,
+							Index, XSK_EFUSEPL_READ_MARGIN_1) != XST_SUCCESS) {
+				return XST_FAILURE;
+			}
+			if(XilSKey_EfusePl_ProgramBit(XSK_EFUSEPL_ARRAY_FUSE_CNTRL_ROW,
+							Index +
+							XSK_EFUSEPL_ARRAY_FUSE_CNTRL_REDUNDENT_START_BIT)
+							!= XST_SUCCESS) {
+				return XST_FAILURE;
+			}
+
+			if(XilSKey_EfusePl_VerifyBit(XSK_EFUSEPL_ARRAY_FUSE_CNTRL_ROW,
+							(Index +
+							XSK_EFUSEPL_ARRAY_FUSE_CNTRL_REDUNDENT_START_BIT),
+							XSK_EFUSEPL_READ_NORMAL) != XST_SUCCESS) {
+				return XST_FAILURE;
+			}
+
+			if(XilSKey_EfusePl_VerifyBit(XSK_EFUSEPL_ARRAY_FUSE_CNTRL_ROW,
+							(Index +
+							XSK_EFUSEPL_ARRAY_FUSE_CNTRL_REDUNDENT_START_BIT),
+							XSK_EFUSEPL_READ_MARGIN_1) != XST_SUCCESS) {
+				return XST_FAILURE;
+			}
+
+		}
+	}
+
+	return XST_SUCCESS;
+}
+/****************************************************************************/
+/**
+*
+*	Reads a PL eFUSE bit & stores.
+*
+*
+* @param	Row			-	row number
+* @param	Bit			- 	bit position in the specified row
+* @param	MarginOption-	Margin Option(One of the reading method of PLeFUSE)
+* @param	BitData		- 	Place holder to store the read value
+*
+* @return
+*
+*	- XST_FAILURE - In case of failure
+*	- XST_SUCCESS - In case of Success
+*
+*
+* @note		Updates the global variable ErrorCode with error code(if any).
+*
+*****************************************************************************/
+
+u8 XilSKey_EfusePl_ReadBit(u8 Row, u8 Bit, u8 MarginOption, u8 *BitData)
+{
+	u8 RowData[XSK_EFUSEPL_ARRAY_MAX_COL]={0};
+
+	/**
+	 * check if row_data is not NULL
+	 */
+	if(NULL == BitData)	{
+		ErrorCode = XSK_EFUSEPL_ERROR_READ_BUFFER_NULL;
+		return XST_FAILURE;
+	}
+	/**
+	 *Check if the bit position is valid.
+	 */
+
+	if((Bit < XSK_EFUSEPL_ARRAY_FUSE_CNTRL_START_BIT) ||
+		(Bit > XSK_EFUSEPL_ARRAY_ECC_END_BIT_IN_A_ROW)) {
+		ErrorCode = XSK_EFUSEPL_ERROR_READ_BIT_OUT_OF_RANGE;
+		return XST_FAILURE;
+	}
+
+
+	/**
+	 * If row=0 then bit should be either 1 to 5 and 8 to 10, 15 to 19 and
+	 * 22 to 24 rest all are not supported
+	 */
+	if(Row == XSK_EFUSEPL_ARRAY_FUSE_CNTRL_ROW) {
+
+		if((Bit == XSK_EFUSEPL_ARRAY_FUSE_CNTRL_START_BIT) ||
+			(Bit == XSK_EFUSEPL_ARRAY_UNSUPPORTED_BIT6) ||
+			(Bit == XSK_EFUSEPL_ARRAY_UNSUPPORTED_BIT7)||
+			(Bit == XSK_EFUSEPL_ARRAY_UNSUPPORTED_RED_FOR_BIT6)||
+			(Bit == XSK_EFUSEPL_ARRAY_UNSUPPORTED_RED_FOR_BIT7)) {
+			ErrorCode = XSK_EFUSEPL_ERROR_READ_BIT_OUT_OF_RANGE;
+			return XST_FAILURE;
+		}
+
+		if((Bit > XSK_EFUSEPL_ARRAY_FUSE_CNTRL_END_BIT) &&
+			(Bit < XSK_EFUSEPL_ARRAY_FUSE_CNTRL_REDUNDENT_START_BIT)) {
+			ErrorCode = XSK_EFUSEPL_ERROR_READ_BIT_OUT_OF_RANGE;
+			return XST_FAILURE;
+		}
+
+		if(Bit > XSK_EFUSEPL_ARRAY_FUSE_CNTRL_REDUNDENT_END_BIT) {
+			ErrorCode = XSK_EFUSEPL_ERROR_READ_BIT_OUT_OF_RANGE;
+			return XST_FAILURE;
+		}
+	}
+
+	if(XilSKey_EfusePl_ReadRow(Row, MarginOption,RowData) != XST_SUCCESS) {
+		return XST_FAILURE;
+	}
+
+	*BitData = RowData[Bit];
+
+	return XST_SUCCESS;
+}
+
+/****************************************************************************/
+/**
+*
+*	Reads row data of a specified row
+*
+*
+* @param	Row				- 	row number
+* @param	MarginOption	-	Margin Option(One of the reading method of PLeFUSE)
+* @param	RowDataBytes	-	To store the read data bytes of specified row.
+*
+* @return
+*
+*	- XST_FAILURE - In case of failure
+*	- XST_SUCCESS - In case of Success
+*
+*
+* @note		Read data will be stored @row_data_bytes
+*
+*****************************************************************************/
+
+u8 XilSKey_EfusePl_ReadRow(u32 Row, u8 MarginOption, u8 *RowDataBytes)
+{
+	XSKEfusePs_XAdc PL_XAdc;
+	u32 RowDataBits=0;
+
+	/**
+	 * Check if the row position is valid.
+	 */
+	if((Row > XSK_EFUSEPL_ARRAY_USER_DATA_START_ROW) ||
+		((Row > XSK_EFUSEPL_ARRAY_FUSE_CNTRL_ROW) &&
+		(Row < XSK_EFUSEPL_ARRAY_AES_DATA_ROW_START))) {
+		ErrorCode = XSK_EFUSEPL_ERROR_READ_ROW_OUT_OF_RANGE;
+		return XST_FAILURE;
+	}
+
+	/**
+	 * Check the read margin option.
+	 */
+	if( (MarginOption != XSK_EFUSEPL_READ_NORMAL ) &&
+		(MarginOption != XSK_EFUSEPL_READ_MARGIN_1)&&
+		(MarginOption != XSK_EFUSEPL_READ_MARGIN_2))
+	{
+		ErrorCode = XSK_EFUSEPL_ERROR_READ_MARGIN_OUT_OF_RANGE;
+		return XST_FAILURE;
+	}
+
+	/**
+	 * check if row_data is not NULL
+	 */
+	if(NULL == RowDataBytes)
+	{
+		ErrorCode = XSK_EFUSEPL_ERROR_READ_BUFFER_NULL;
+		return XST_FAILURE;
+	}
+
+
+	/**
+	 * Monitor the Voltage and temperature using XADC, if out of range return
+	 * unique error.
+	 */
+	PL_XAdc.VType = XSK_EFUSEPS_VAUX;
+	XilSKey_EfusePs_XAdcReadTemperatureAndVoltage(&PL_XAdc);
+	if((PL_XAdc.Temp < XSK_EFUSEPL_READ_TEMP_MIN_RAW) ||
+		(PL_XAdc.Temp > XSK_EFUSEPL_READ_TEMP_MAX_RAW)) {
+		ErrorCode = XSK_EFUSEPL_ERROR_READ_TMEPERATURE_OUT_OF_RANGE;
+		return XST_FAILURE;
+	}
+
+	if((PL_XAdc.V < XSK_EFUSEPL_READ_VOLTAGE_VCCAUX_MIN_RAW) ||
+		(PL_XAdc.V > XSK_EFUSEPL_READ_VOLTAGE_VCCAUX_MAX_RAW)) {
+		ErrorCode = XSK_EFUSEPL_ERROR_READ_VCCAUX_VOLTAGE_OUT_OF_RANGE;
+		return XST_FAILURE;
+	}
+
+	PL_XAdc.VType = XSK_EFUSEPS_VINT;
+	XilSKey_EfusePs_XAdcReadTemperatureAndVoltage(&PL_XAdc);
+	if((PL_XAdc.V < XSK_EFUSEPL_READ_VOLTAGE_VCCINT_MIN_RAW) ||
+		(PL_XAdc.V > XSK_EFUSEPL_READ_VOLTAGE_VCCINT_MAX_RAW)) {
+		ErrorCode = XSK_EFUSEPL_ERROR_READ_VCCINT_VOLTAGE_OUT_OF_RANGE;
+		return XST_FAILURE;
+	}
+
+	/**
+	 * Here we have to use the impact algorithm to read the eFUSE row.
+	 * and return the data in row_data.
+	 */
+
+	if((MarginOption & XSK_EFUSEPL_READ_NORMAL) == XSK_EFUSEPL_READ_NORMAL) {
+
+		JtagRead(Row, (unsigned int *)&RowDataBits, 0);
+	}
+	else if((MarginOption & XSK_EFUSEPL_READ_MARGIN_1) ==
+							XSK_EFUSEPL_READ_MARGIN_1) {
+		JtagRead(Row, (unsigned int *)&RowDataBits, 1);
+	}
+	else if((MarginOption & XSK_EFUSEPL_READ_MARGIN_2) ==
+							XSK_EFUSEPL_READ_MARGIN_2) {
+		JtagRead(Row, (unsigned int *)&RowDataBits, 2);
+	}
+
+	XilSKey_Efuse_ConvertBitsToBytes((u8 *)&RowDataBits, RowDataBytes, 32);
+
+	return XST_SUCCESS;
+}
+/****************************************************************************/
+/**
+*
+*	Reads PL eFUSE Control Register data
+*
+*
+* @param	CtrlData	-	Place holder to store the read data (control register)
+*
+* @return
+*
+*	- XST_FAILURE - In case of failure
+*	- XST_SUCCESS - In case of Success
+*
+*
+* @note		Updates the global variable ErrorCode with error code (if any)
+*
+*****************************************************************************/
+
+u8 XilSKey_EfusePl_ReadControlRegister(u8 *CtrlData)
+{
+	u8 RowData[XSK_EFUSEPL_ARRAY_MAX_COL]={0};
+	u32 Index=0;
+
+	/**
+	 * check if cntrl_data is not NULL
+	 */
+	if(NULL == CtrlData) {
+		ErrorCode = XSK_EFUSEPL_ERROR_READ_BUFFER_NULL;
+		return XST_FAILURE;
+	}
+
+	if(XilSKey_EfusePl_ReadRow(XSK_EFUSEPL_ARRAY_FUSE_CNTRL_ROW,
+									 XSK_EFUSEPL_READ_NORMAL,
+									 RowData) != XST_SUCCESS)
+	{
+		return XST_FAILURE;
+	}
+
+	for(Index=0; Index < XSK_EFUSEPL_ARRAY_FUSE_CNTRL_MAX_BITS; Index++)
+	{
+		CtrlData[Index] = RowData[Index] |
+						  RowData[Index +
+							  XSK_EFUSEPL_ARRAY_FUSE_CNTRL_REDUNDENT_START_BIT];
+	}
+
+	return XST_SUCCESS;
+}
+
+/****************************************************************************/
+/**
+*
+*
+*	Verify the PL eFUSE bit blown by reading it back
+*
+*
+* @param	Row			 - row number
+* @param	Bit			 - bit position of the specified row
+* @param	MarginOption - Margin Option(One of the reading method of PLeFUSE)
+*
+* @return
+*
+*	- XST_FAILURE - In case of failure
+*	- XST_SUCCESS - In case of Success
+*
+*
+* @note		Updates the global variable ErrorCode with error code(if any).
+*
+*****************************************************************************/
+u8 XilSKey_EfusePl_VerifyBit(u8 Row, u8 Bit, u8 MarginOption)
+{
+	u8 BitData = 0;
+	if(XilSKey_EfusePl_ReadBit(Row, Bit, MarginOption, &BitData)
+									!= XST_SUCCESS)	{
+		return XST_FAILURE;
+	}
+
+	if(BitData == FALSE) {
+		ErrorCode = XSK_EFUSEPL_ERROR_READ_BIT_VALUE_NOT_SET;
+		return XST_FAILURE;
+	}
+	return XST_SUCCESS;
+}
+/****************************************************************************/
+/**
+*
+*	Calculates and stores the ECC data of row data
+*
+*
+* @param	RowData	- Pointer to row data on which ECC will be calculated
+* @param	ECCData	- Pointer to store the calculated ECC
+*
+* @return
+*
+*	None
+*
+* @note		None.
+*
+*****************************************************************************/
+void XilSKey_EfusePl_CalculateEcc(u8 *RowData, u8 *ECCData)
+{
+	ECCData[0] = 	RowData[0] ^ RowData[1] ^ RowData[2] ^
+					RowData[3] ^ RowData[8] ^ RowData[9] ^
+					RowData[10] ^ RowData[11] ^ RowData[12] ^
+					RowData[13] ^ RowData[14] ^ RowData[15] ^
+					RowData[16] ^ RowData[17];
+
+	ECCData[1] = 	RowData[1] ^ RowData[2] ^ RowData[3] ^
+					RowData[5] ^ RowData[6] ^ RowData[7] ^
+					RowData[11] ^ RowData[12] ^ RowData[13] ^
+					RowData[14] ^ RowData[18] ^ RowData[19] ^
+					RowData[20];
+
+	ECCData[2] = 	RowData[0] ^ RowData[2] ^ RowData[3] ^
+					RowData[4] ^ RowData[6] ^ RowData[7] ^
+					RowData[9] ^ RowData[10] ^ RowData[13] ^
+					RowData[15] ^ RowData[18] ^ RowData[21] ^
+					RowData[22];
+
+	ECCData[3] = 	RowData[0] ^ RowData[1] ^ RowData[3] ^
+					RowData[4] ^ RowData[5] ^ RowData[7] ^
+					RowData[8] ^ RowData[10] ^ RowData[12] ^
+					RowData[16] ^ RowData[19] ^ RowData[21] ^
+					RowData[23];
+
+	ECCData[4] = 	RowData[0] ^ RowData[1] ^ RowData[2] ^
+					RowData[4] ^ RowData[5] ^ RowData[6] ^
+					RowData[8] ^ RowData[9] ^ RowData[11] ^
+					RowData[17] ^ RowData[20] ^ RowData[22] ^
+					RowData[23];
+
+	/**
+	 * This is the DED data
+	 */
+
+	ECCData[5] = 	RowData[0] ^ RowData[1] ^ RowData[2] ^
+					RowData[3] ^ RowData[4] ^ RowData[5] ^
+					RowData[6] ^ RowData[7] ^ RowData[8] ^
+					RowData[9] ^ RowData[10] ^ RowData[11] ^
+					RowData[12] ^ RowData[13] ^ RowData[14] ^
+					RowData[15] ^ RowData[16] ^ RowData[17] ^
+					RowData[18] ^ RowData[19] ^ RowData[20] ^
+					RowData[21] ^ RowData[22] ^ RowData[23] ^
+					ECCData[0] ^ ECCData[1] ^ ECCData[2] ^
+					ECCData[3] ^ ECCData[4];
+}
+
+/****************************************************************************/
+/**
+*
+*
+*	Reads the PL efuse status bits
+*
+*
+* @param	InstancePtr - Input data to be written to PL eFUSE
+* @param	StatusBits - Variable to store the status bits read.
+*
+* @return
+*
+*	- XST_FAILURE - In case of failure
+*	- XST_SUCCESS - In case of Success
+*
+*
+* @note		Updates the global variable ErrorCode with error code(if any).
+*
+*****************************************************************************/
+u32 XilSKey_EfusePl_ReadStatus(XilSKey_EPl *InstancePtr, u32 *StatusBits)
+{
+	u32 RefClk;
+	u32 ArmPllFdiv;
+	u32 ArmClkDivisor;
+	unsigned int RowData;
+	u32 Status;
+	XSKEfusePs_XAdc PL_XAdc;
+
+	if(NULL == InstancePtr)	{
+		return XSK_EFUSEPL_ERROR_PL_STRUCT_NULL;
+	}
+
+	if(!(InstancePtr->SystemInitDone))
+	{
+
+		/**
+		 *  Extract PLL FDIV value from ARM PLL Control Register
+		 */
+		ArmPllFdiv = (Xil_In32(XSK_ARM_PLL_CTRL_REG)>>12 & 0x7F);
+
+		/**
+		 *  Extract Clock divisor value from ARM Clock Control Register
+		 */
+		ArmClkDivisor = (Xil_In32(XSK_ARM_CLK_CTRL_REG)>>8 & 0x3F);
+
+		/**
+		 * Initialize the variables
+		 */
+		RefClk = ((XPAR_PS7_CORTEXA9_0_CPU_CLK_FREQ_HZ * ArmClkDivisor)/
+					ArmPllFdiv);
+
+		/**
+		 * Return error if the reference clock frequency is not in
+		 * between 20 & 60MHz
+		 */
+		if((RefClk < XSK_EFUSEPL_MIN_REF_CLK_FREQ) ||
+				(RefClk > XSK_EFUSEPL_MAX_REF_CLK_FREQ)) {
+			return XSK_EFUSEPL_ERROR_INVALID_REF_CLK;
+		}
+
+		/**
+		 * Initialize the timer, XADC and jtag server
+		 */
+
+		XilSKey_Efuse_StartTimer(RefClk);
+
+		Status = XilSKey_EfusePs_XAdcInit();
+		if(Status != XST_SUCCESS) {
+			ErrorCode = Status;
+			return (XSK_EFUSEPL_ERROR_XADC + ErrorCode);
+		}
+
+		if(JtagServerInit(InstancePtr) != XST_SUCCESS) {
+			return XSK_EFUSEPL_ERROR_JTAG_SERVER_INIT;
+		}
+
+		InstancePtr->SystemInitDone = 1;
+
+	}
+
+	/**
+	 * Monitor the Voltage and temperature using XADC, if out of range return
+	 * unique error.
+	 */
+	PL_XAdc.VType = XSK_EFUSEPS_VAUX;
+	XilSKey_EfusePs_XAdcReadTemperatureAndVoltage(&PL_XAdc);
+	if((PL_XAdc.Temp < XSK_EFUSEPL_READ_TEMP_MIN_RAW) ||
+		(PL_XAdc.Temp > XSK_EFUSEPL_READ_TEMP_MAX_RAW)) {
+		ErrorCode = XSK_EFUSEPL_ERROR_READ_TMEPERATURE_OUT_OF_RANGE;
+		return XST_FAILURE;
+	}
+
+	if((PL_XAdc.V < XSK_EFUSEPL_READ_VOLTAGE_VCCAUX_MIN_RAW) ||
+		(PL_XAdc.V > XSK_EFUSEPL_READ_VOLTAGE_VCCAUX_MAX_RAW)) {
+		ErrorCode = XSK_EFUSEPL_ERROR_READ_VCCAUX_VOLTAGE_OUT_OF_RANGE;
+		return XST_FAILURE;
+	}
+	PL_XAdc.VType = XSK_EFUSEPS_VINT;
+	XilSKey_EfusePs_XAdcReadTemperatureAndVoltage(&PL_XAdc);
+	if((PL_XAdc.V < XSK_EFUSEPL_READ_VOLTAGE_VCCINT_MIN_RAW) ||
+		(PL_XAdc.V > XSK_EFUSEPL_READ_VOLTAGE_VCCINT_MAX_RAW)) {
+		ErrorCode = XSK_EFUSEPL_ERROR_READ_VCCINT_VOLTAGE_OUT_OF_RANGE;
+		return XST_FAILURE;
+	}
+
+	/*
+	 * Read row 0 for status bits
+	 */
+	JtagRead(0, &RowData, 0);
+
+	*StatusBits = RowData & 0xFFFFFF;
+
+	return XST_SUCCESS;
+
+}
+
+/****************************************************************************/
+/**
+*
+*
+*	Reads the PL efuse key (AES and user)
+*
+*
+* @param	InstancePtr - Input data to be written to PL eFUSE
+*
+* @return
+*
+*	- XST_FAILURE - In case of failure
+*	- XST_SUCCESS - In case of Success
+*
+*
+* @note		Updates the global variable ErrorCode with error code(if any).
+*
+*****************************************************************************/
+u32 XilSKey_EfusePl_ReadKey(XilSKey_EPl *InstancePtr)
+{
+	u32 RefClk;
+	u32 ArmPllFdiv;
+	u32 ArmClkDivisor;
+	u32 RowCount;
+	unsigned int RowData;
+	u32 KeyCnt;
+	u32 Status;
+	XSKEfusePs_XAdc PL_XAdc;
+
+	if(NULL == InstancePtr)	{
+		return XSK_EFUSEPL_ERROR_PL_STRUCT_NULL;
+	}
+
+	if(!(InstancePtr->SystemInitDone))
+	{
+
+		/**
+		 *  Extract PLL FDIV value from ARM PLL Control Register
+		 */
+		ArmPllFdiv = (Xil_In32(XSK_ARM_PLL_CTRL_REG)>>12 & 0x7F);
+
+		/**
+		 *  Extract Clock divisor value from ARM Clock Control Register
+		 */
+		ArmClkDivisor = (Xil_In32(XSK_ARM_CLK_CTRL_REG)>>8 & 0x3F);
+
+		/**
+		 * Initialize the variables
+		 */
+		RefClk = ((XPAR_PS7_CORTEXA9_0_CPU_CLK_FREQ_HZ * ArmClkDivisor)/
+					ArmPllFdiv);
+
+		/**
+		 * Return error if the reference clock frequency is not in
+		 * between 20 & 60MHz
+		 */
+		if((RefClk < XSK_EFUSEPL_MIN_REF_CLK_FREQ) ||
+				(RefClk > XSK_EFUSEPL_MAX_REF_CLK_FREQ)) {
+			return XSK_EFUSEPL_ERROR_INVALID_REF_CLK;
+		}
+
+		/**
+		 * Initialize the timer and jtag server
+		 */
+
+		XilSKey_Efuse_StartTimer(RefClk);
+
+		Status = XilSKey_EfusePs_XAdcInit();
+		if(Status != XST_SUCCESS) {
+			ErrorCode = Status;
+			return (XSK_EFUSEPL_ERROR_XADC + ErrorCode);
+		}
+
+		if(JtagServerInit(InstancePtr) != XST_SUCCESS) {
+			return XSK_EFUSEPL_ERROR_JTAG_SERVER_INIT;
+		}
+
+		InstancePtr->SystemInitDone = 1;
+
+	}
+
+	/**
+	 * Monitor the Voltage and temperature using XADC, if out of range return
+	 * unique error.
+	 */
+	PL_XAdc.VType = XSK_EFUSEPS_VAUX;
+	XilSKey_EfusePs_XAdcReadTemperatureAndVoltage(&PL_XAdc);
+	if((PL_XAdc.Temp < XSK_EFUSEPL_READ_TEMP_MIN_RAW) ||
+		(PL_XAdc.Temp > XSK_EFUSEPL_READ_TEMP_MAX_RAW)) {
+		ErrorCode = XSK_EFUSEPL_ERROR_READ_TMEPERATURE_OUT_OF_RANGE;
+		return XST_FAILURE;
+	}
+
+	if((PL_XAdc.V < XSK_EFUSEPL_READ_VOLTAGE_VCCAUX_MIN_RAW) ||
+		(PL_XAdc.V > XSK_EFUSEPL_READ_VOLTAGE_VCCAUX_MAX_RAW)) {
+		ErrorCode = XSK_EFUSEPL_ERROR_READ_VCCAUX_VOLTAGE_OUT_OF_RANGE;
+		return XST_FAILURE;
+	}
+
+	PL_XAdc.VType = XSK_EFUSEPS_VINT;
+	XilSKey_EfusePs_XAdcReadTemperatureAndVoltage(&PL_XAdc);
+	if((PL_XAdc.V < XSK_EFUSEPL_READ_VOLTAGE_VCCINT_MIN_RAW) ||
+		(PL_XAdc.V > XSK_EFUSEPL_READ_VOLTAGE_VCCINT_MAX_RAW)) {
+		ErrorCode = XSK_EFUSEPL_ERROR_READ_VCCINT_VOLTAGE_OUT_OF_RANGE;
+		return XST_FAILURE;
+	}
+
+	/*
+	 * Read AES key and User Key and
+	 * store them in the variables in instance structure
+	 */
+
+	/*
+	 * AES key 4 bytes
+	 */
+	KeyCnt = 0;
+
+	/*
+	 * Read row 20 to 29
+	 */
+	for(RowCount = 20; RowCount <= 29; RowCount++)
+	{
+		JtagRead(RowCount, &RowData, 0);
+		InstancePtr->AESKeyReadback[KeyCnt++] = (u8)(RowData & 0xFF);
+		RowData = RowData >> 8;
+		InstancePtr->AESKeyReadback[KeyCnt++] = (u8)(RowData & 0xFF);
+		RowData = RowData >> 8;
+		InstancePtr->AESKeyReadback[KeyCnt++] = (u8)(RowData & 0xFF);
+	}
+
+	/*
+	 * Read row 30
+	 */
+	JtagRead(30, &RowData, 0);
+	InstancePtr->AESKeyReadback[KeyCnt++] = (u8)(RowData & 0xFF);
+	RowData = RowData >> 8;
+	InstancePtr->AESKeyReadback[KeyCnt++] = (u8)(RowData & 0xFF);
+
+	/*
+	 * User key 4 bytes
+	 */
+	KeyCnt = 0;
+	RowData = RowData >> 8;
+	InstancePtr->UserKeyReadback[KeyCnt++] = (u8)(RowData & 0xFF);
+
+	/*
+	 * Read row 31
+	 */
+	JtagRead(31, &RowData, 0);
+	InstancePtr->UserKeyReadback[KeyCnt++] = (u8)(RowData & 0xFF);
+	RowData = RowData >> 8;
+	InstancePtr->UserKeyReadback[KeyCnt++] = (u8)(RowData & 0xFF);
+	RowData = RowData >> 8;
+	InstancePtr->UserKeyReadback[KeyCnt++] = (u8)(RowData & 0xFF);
+
+	return XST_SUCCESS;
+
+}
\ No newline at end of file
diff --git a/lib/sw_services/xilskey/src/xilskey_eps.c b/lib/sw_services/xilskey/src/xilskey_eps.c
new file mode 100644
index 00000000..702d51a8
--- /dev/null
+++ b/lib/sw_services/xilskey/src/xilskey_eps.c
@@ -0,0 +1,1521 @@
+/******************************************************************************
+*
+* 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_eps.c
+ * This file contains the PS eFUSE API's to program/read the eFUSE array.
+ *
+ * @note	None.
+ *
+ *
+ * MODIFICATION HISTORY:
+ *
+* Ver   Who  	Date     Changes
+* ----- ---- 	-------- --------------------------------------------------------
+* 1.00a rpoolla 04/26/13 First release
+* 1.02a hk      10/28/13 Added API to read status register.PR# 735957
+* 2.00  hk      23/01/14 Changed PS efuse error codes for voltage out of range.
+*
+*
+*****************************************************************************/
+
+/***************************** Include Files *********************************/
+#include "xil_io.h"
+#include "xil_types.h"
+#include "xstatus.h"
+#include "xilskey_utils.h"
+#include "xilskey_epshw.h"
+#include "xilskey_eps.h"
+/************************** Constant Definitions *****************************/
+
+/**************************** Type Definitions ******************************/
+
+/***************** Macros (Inline Functions) Definitions ********************/
+
+/************************** Variable Definitions ****************************/
+u8 Matrix[31][5]; /**< PS eFUSE Matrix*/
+u8 ErrorCodeIndex[32]; /**< Error Code Array */
+/************************** Function Prototypes *****************************/
+static u32 XilSKey_EfusePs_WriteWithXadcCheckAndVerify(u32 EfuseAddress, u32 RefClk);
+static u32 XilSKey_EfusePs_WriteRsaKeyHash(u8 *RsaKeyHashBuf, u32 RefClk);
+static u32 XilSKey_EfusePs_ReadRsaKeyHash(u8 *RsaKeyHashBuf, u32 RefClk);
+static u32 XilSKey_EfusePs_ReadWithXadcCheck(u32 EfuseAddress, u32 RefClk, u8 *Data);
+static u32 XilSKey_EfusePs_VerifyWithXadcCheck(u32 EfuseAddress, u32 RefClk);
+static u32 XilSKey_EfusePs_CheckRsaHashForAllZeros(u32 RefClk);
+static void XilSKey_EfusePs_SetControllerMode (u8 Mode);
+static void XilSKey_EfusePs_SetControllerReadMode (u8 ReadMode);
+static u8 XilSKey_EfusePs_IsReadModeSupported (u8 ReadMode);
+
+/***************************************************************************/
+/**
+* This function is used to write to the PS eFUSE.
+*
+* @param  InstancePtr is the pointer to the PsEfuseHandle which describes
+* 	  which PS eFUSE bit should be burned.
+*
+* @return
+* 		- XST_SUCCESS.
+* 		- Incase of error, value is as defined in xeFUSE_error.h.
+* 		Error value is a combination of Upper 8 bit value and
+* 		Lower 8 bit value. For example, 0x8A03 should be checked
+* 		in error.h as 0x8A00 and 0x03. Upper 8 bit value signifies
+* 		the major error and lower 8 bit values tells more precisely.
+*
+****************************************************************************/
+u32 XilSKey_EfusePs_Write(XilSKey_EPs *InstancePtr)
+{
+	u32 Status, StatusRedundantBit, RetValue;
+	u32 RefClk;
+	u32 ArmPllFDiv,ArmClkDivisor;
+
+	RetValue = XST_SUCCESS;
+
+
+	if (NULL == InstancePtr) {
+		return XSK_EFUSEPS_ERROR_PS_STRUCT_NULL;
+	}
+
+	/**
+	 *  Extract PLL FDIV value from ARM PLL Control Register
+	 */
+	ArmPllFDiv = (Xil_In32(XSK_ARM_PLL_CTRL_REG)>>12 & 0x7F);
+	/**
+	 *  Extract Clock divisor value from ARM Clock Control Register
+	 */
+	ArmClkDivisor = (Xil_In32(XSK_ARM_CLK_CTRL_REG)>>8 & 0x3F);
+
+	/**
+	 * Initialize the variables
+	 */
+	RefClk = ((XPAR_PS7_CORTEXA9_0_CPU_CLK_FREQ_HZ * ArmClkDivisor)/
+				ArmPllFDiv);
+
+	/**
+	 *  Check the variables
+	 */
+
+	if (((InstancePtr->EnableWriteProtect != TRUE) &&
+		 (InstancePtr->EnableWriteProtect != FALSE)) ||
+		((InstancePtr->EnableRsaAuth != TRUE) &&
+		 (InstancePtr->EnableRsaAuth != FALSE)) ||
+		((InstancePtr->EnableRom128Crc != TRUE) &&
+		 (InstancePtr->EnableRom128Crc != FALSE)) ||
+		((InstancePtr->EnableRsaKeyHash != TRUE) &&
+		 (InstancePtr->EnableRsaKeyHash != FALSE)) ) {
+		return XSK_EFUSEPS_ERROR_PS_PARAMETER_WRONG;
+	}
+
+	/**
+	 * XAdc Initialization
+	 */
+	Status = XilSKey_EfusePs_XAdcInit();
+	if (Status != XST_SUCCESS) {
+		RetValue = XSK_EFUSEPS_ERROR_XADC_INIT;
+		goto ExitFinal;
+	}
+
+	xeFUSE_printf(XSK_EFUSE_DEBUG_GENERAL,"Writing PS EFUSE \n");
+	/**
+	 *  Unlock the eFUSE controller
+	 */
+	XSK_EFUSEPS_CONTROLER_UNLOCK();
+
+	/**
+	 *  Check if the controller is unlocked
+	 */
+	if (XSK_EFUSEPS_CONTROLER_LOCK_STATUS() == TRUE) {
+		RetValue = XSK_EFUSEPS_ERROR_CONTROLLER_LOCK;
+		goto ExitFinal;
+	}
+
+	/**
+	 *  If eFUSE Array is write protected
+	 *  no more writes are possible
+	 */
+
+	if (XilSKey_EfusePs_IsEfuseWriteProtected() == TRUE) {
+		RetValue = XSK_EFUSEPS_ERROR_EFUSE_WRITE_PROTECTED;
+		goto ExitCtrlLock;
+	}
+
+	/**
+	 *  Configure the eFUSE controller with mode, strobe width values.
+	 */
+	Status = XilSKey_EfusePs_ControllerConfig(XSK_EFUSEPS_SINGLE_MODE,
+			RefClk, XSK_EFUSEPS_READ_MODE_NORMAL);
+	if (Status != XST_SUCCESS) {
+		RetValue = XSK_EFUSEPS_ERROR_CONTROLLER_CONFIG + Status;
+		goto ExitCtrlResetStatus;
+	}
+
+	/**
+	 * Enable Programming, write and read
+	 */
+	XilSKey_EfusePs_ControllerSetReadWriteEnable(XSK_EFUSEPS_ENABLE_PROGRAMMING |
+			XSK_EFUSEPS_ENABLE_READ | XSK_EFUSEPS_ENABLE_WRITE);
+
+	/**
+	 * Initialize the timer for delay while programming the eFUSE
+	 */
+	XilSKey_Efuse_StartTimer(RefClk);
+
+	/**
+	 * Program the eFUSE based
+	 * on the structure values
+	 */
+
+	/**
+	 * Program the eFUSE bit 0xA to enable
+	 * ROM 128K CRC
+	 */
+	if (InstancePtr->EnableRom128Crc) {
+		Status = XilSKey_EfusePs_WriteWithXadcCheckAndVerify(
+				XSK_EFUSEPS_APB_ROM_128K_CRC_ENABLE, RefClk);
+		if (Status != XST_SUCCESS) {
+			RetValue = XSK_EFUSEPS_ERROR_WRITE_128K_CRC_BIT + Status;
+			goto ExitCtrlResetStatus;
+		}
+	}
+
+	/**
+	 *  Program the RSA key Hash value in eFUSE Array \
+	 */
+	if (InstancePtr->EnableRsaKeyHash) {
+		/**
+		 * Check if all the hash eFUSE bits are zero or not
+		 */
+		/* NEW: Changed the ReadRsaKeyHash to new function
+		 * XilSKey_EfusePs_CheckRsaHashForAllZeros because of 2 bugs
+		 * 1. If we are using ReadRsaKeyHash function here, if only 1 bit is
+		 * written it will correct it and allow to write
+		 * 2. Controller is in SINGLE mode, so even if 2nd half is written
+		 * we will continue to write
+		 * */
+		Status = XilSKey_EfusePs_CheckRsaHashForAllZeros(RefClk);
+		if (Status != XST_SUCCESS) {
+
+			RetValue = XSK_EFUSEPS_ERROR_READ_HASH_BEFORE_PROGRAMMING + Status;
+			goto ExitCtrlResetStatus;
+		}
+
+		/**
+		 * Program the RSA hash
+		 */
+		Status = XilSKey_EfusePs_WriteRsaKeyHash(
+				InstancePtr->RsaKeyHashValue, RefClk);
+		if (Status != XST_SUCCESS) {
+			RetValue = XSK_EFUSEPS_ERROR_WRITE_RSA_HASH + Status;
+			goto ExitCtrlResetStatus;
+		}
+	}
+
+	/**
+	 * Program the eFUSE bit 0xB to enable
+	 * RSA authentication
+	 */
+	if (InstancePtr->EnableRsaAuth) {
+		Status = XilSKey_EfusePs_WriteWithXadcCheckAndVerify(
+				XSK_EFUSEPS_APB_RSA_AUTH_ENABLE, RefClk);
+		if (Status != XST_SUCCESS) {
+			RetValue = XSK_EFUSEPS_ERROR_WRITE_RSA_AUTH_BIT + Status;
+			goto ExitCtrlResetStatus;
+		}
+	}
+
+	/**
+	 *  Program the eFUSE bit 0x8,0x9 to enable
+	 * eFUSE Array Write Protection
+	 *
+	 * Once enabled the write protection, we will not be
+	 * able to program any PS eFUSE afterwards
+	 */
+
+	/**
+	 *  SLCR reset is required for write protect
+	 *  to take into effect
+	 */
+	if (InstancePtr->EnableWriteProtect) {
+		Status = XilSKey_EfusePs_WriteWithXadcCheckAndVerify(
+				XSK_EFUSEPS_APB_WRITE_PROTECTION_ADDR_1, RefClk);
+
+		StatusRedundantBit = XilSKey_EfusePs_WriteWithXadcCheckAndVerify(
+				XSK_EFUSEPS_APB_WRITE_PROTECTION_ADDR_2, RefClk);
+
+
+		/* NEW: Error only if burning of the both the bits are not success */
+		if ((Status != XST_SUCCESS) && (StatusRedundantBit != XST_SUCCESS)) {
+			RetValue = XSK_EFUSEPS_ERROR_WRITE_WRITE_PROTECT_BIT + Status;
+			goto ExitCtrlResetStatus;
+		}
+	}
+
+ExitCtrlResetStatus:
+	/**
+	 * Disable Programming, write and read
+	 */
+	XilSKey_EfusePs_ControllerSetReadWriteEnable(0);
+
+ExitCtrlLock:
+	/**
+	 *  Lock the eFUSE controller
+	 */
+	XSK_EFUSEPS_CONTROLER_LOCK();
+
+ExitFinal:
+	return RetValue;
+}
+
+/***************************************************************************/
+/**
+* This function is used to read the PS eFUSE.
+*
+* @param  InstancePtr is the pointer to the PsEfuseHandle which describes
+* 	  which PS eFUSE should be burned.
+*
+* @return
+* 		- XST_SUCCESS no errors occured.
+* 		- Incase of error, value is as defined in xeFUSE_error.h.
+* 		Error value is a combination of Upper 8 bit value and
+* 		Lower 8 bit value. For example, 0x8A03 should be checked
+* 		in error.h as 0x8A00 and 0x03. Upper 8 bit value signifies
+* 		the major error and lower 8 bit values tells more precisely.
+*
+****************************************************************************/
+u32 XilSKey_EfusePs_Read(XilSKey_EPs *InstancePtr)
+{
+
+	u32 Status, RetValue;
+	u32 RefClk;
+	u32 ArmPllFDiv,ArmClkDivisor;
+
+	RetValue = XST_SUCCESS;
+
+
+	if (NULL == InstancePtr) {
+		return XSK_EFUSEPS_ERROR_PS_STRUCT_NULL;
+	}
+
+	/**
+	 *  Extract PLL FDIV value from ARM PLL Control Register
+	 */
+	ArmPllFDiv = (Xil_In32(XSK_ARM_PLL_CTRL_REG)>>12 & 0x7F);
+	/**
+	 *  Extract Clock divisor value from ARM Clock Control Register
+	 */
+	ArmClkDivisor = (Xil_In32(XSK_ARM_CLK_CTRL_REG)>>8 & 0x3F);
+
+	/**
+	 * Initialize the variables
+	 */
+	RefClk = ((XPAR_PS7_CORTEXA9_0_CPU_CLK_FREQ_HZ * ArmClkDivisor)/
+			   ArmPllFDiv);
+
+	/**
+	 * Check the variables
+	 */
+
+	if ((InstancePtr->EnableRsaKeyHash != TRUE) &&
+		(InstancePtr->EnableRsaKeyHash != FALSE)) {
+		return XSK_EFUSEPS_ERROR_PS_PARAMETER_WRONG;
+	}
+
+	/**
+	 * XAdc Initialization
+	 */
+	Status = XilSKey_EfusePs_XAdcInit();
+	if (Status != XST_SUCCESS) {
+		RetValue = XSK_EFUSEPS_ERROR_XADC_INIT;
+		goto ExitFinal;
+	}
+
+	/**
+	 *  Unlock the eFUSE controller
+	 */
+	XSK_EFUSEPS_CONTROLER_UNLOCK();
+
+	/**
+	 *  Check if the controller is unlocked
+	 */
+	if (XSK_EFUSEPS_CONTROLER_LOCK_STATUS() == TRUE) {
+		RetValue = XSK_EFUSEPS_ERROR_CONTROLLER_LOCK;
+		goto ExitFinal;
+	}
+
+	/**
+	 *  Configure the eFUSE controller with mode, strobe width values
+	 */
+	Status = XilSKey_EfusePs_ControllerConfig(XSK_EFUSEPS_REDUNDANCY_MODE,
+			RefClk, XSK_EFUSEPS_READ_MODE_NORMAL);
+	if (Status != XST_SUCCESS) {
+		RetValue = XSK_EFUSEPS_ERROR_CONTROLLER_CONFIG + Status;
+		goto ExitCtrlLock;
+	}
+
+	/**
+	 * Enable eFUSE reading only
+	 */
+	XilSKey_EfusePs_ControllerSetReadWriteEnable(XSK_EFUSEPS_ENABLE_READ);
+
+	/**
+	 *  Read the eFUSE
+	 */
+
+	/**
+	 *  Read the RSA key Hash value from eFUSE Array
+	 */
+	if (InstancePtr->EnableRsaKeyHash) {
+		Status = XilSKey_EfusePs_ReadRsaKeyHash(
+				InstancePtr->RsaKeyReadback, RefClk);
+		if (Status != XST_SUCCESS) {
+			RetValue = XSK_EFUSEPS_ERROR_READ_RSA_HASH + Status;
+			goto ExitCtrlResetStatus;
+		}
+	}
+
+ExitCtrlResetStatus:
+	/**
+	 * Disable Programming, write and read
+	 */
+	XilSKey_EfusePs_ControllerSetReadWriteEnable(0);
+
+ExitCtrlLock:
+	/**
+	 *  Lock the eFUSE controller
+	 */
+	XSK_EFUSEPS_CONTROLER_LOCK();
+
+ExitFinal:
+	return RetValue;
+}
+
+/***************************************************************************/
+/**
+* This function is used to check the RSA Hash for all zeros.
+*
+* @param RefClk is the reference clock frequency. Clock frequency can be
+* 				between 20MHz to 60MHz specified in Hz
+*
+* @return
+* 		- XST_SUCCESS if RSA Hash eFUSE bits are all zeros.
+*		- XSK_EFUSEPS_ERROR_RSA_HASH_ALREADY_PROGRAMMED if any RSA hash
+*		  eFUSE bit is set
+*		- Other errors because of internal controller functions and
+*		  can be checked in xeFUSE_error.h
+*
+****************************************************************************/
+
+static u32 XilSKey_EfusePs_CheckRsaHashForAllZeros(u32 RefClk)
+{
+	u32 EfuseAddress,Status,RetValue;
+	u32 LoopIndex;
+	u8 Data;
+
+	RetValue = XST_SUCCESS;
+
+	/**
+	 * Set the controller to read in redundancy mode
+	 */
+	Status = XilSKey_EfusePs_ControllerConfig(XSK_EFUSEPS_REDUNDANCY_MODE,
+			RefClk, XSK_EFUSEPS_READ_MODE_NORMAL);
+	if (Status != XST_SUCCESS) {
+		return Status;
+	}
+
+	/**
+	 * Check the Hash eFUSE Bits for all Zero's
+	 */
+	LoopIndex = 0;
+	EfuseAddress=XSK_EFUSEPS_APB_CUSTOMER_KEY_FIRST_HALF_START_ADDR;
+	while (LoopIndex < (XSK_EFUSEPS_HAMMING_LOOPS*XSK_EFUSEPS_HAMMING_LENGTH)) {
+		/**
+		 *  Escape the Xilinx Reserved Bits
+		 */
+		while (XilSKey_EfusePs_IsAddressXilRestricted(EfuseAddress) == TRUE) {
+			EfuseAddress += 4;
+		}
+		Status = XilSKey_EfusePs_ReadWithXadcCheck(EfuseAddress, RefClk, &Data);
+		if (Status != XST_SUCCESS) {
+			RetValue = Status;
+			goto ExitControllerReset;
+		}
+		/**
+		 * Data value of 1 indicates Hash is already written
+		 */
+		if (Data != 0) {
+			RetValue = XSK_EFUSEPS_ERROR_RSA_HASH_ALREADY_PROGRAMMED;
+			goto ExitControllerReset;
+		}
+		EfuseAddress += 4;
+		LoopIndex++;
+	} /* End of  while (LoopIndex < (XSK_EFUSEPS_HAMMING_LOOPS* ....) */
+
+ExitControllerReset:
+	/**
+	 * Set the controller back to single mode
+	 */
+	Status = XilSKey_EfusePs_ControllerConfig(XSK_EFUSEPS_SINGLE_MODE,
+			RefClk, XSK_EFUSEPS_READ_MODE_NORMAL);
+	if (Status != XST_SUCCESS) {
+		return Status;
+	}
+
+	return RetValue;
+}
+
+/***************************************************************************/
+/**
+* This function is used to to write the Single eFUSE which checks for
+* XADC temperature and voltage and verifies the written bit in the eFUSE
+* Verification of the bit is done by reading the bit in margin 1  mode and
+* normal mode.
+* Temperature and voltage are read from XADC and verified for the
+* correct range
+*
+* @param EfuseAddress is the address of the eFUSE bit to be written
+* @param RefClk is the reference clock frequency. Clock frequency can be
+* 				between 20MHz to 60MHz specified in Hz
+* @return
+* 		- XST_SUCCESS no errors occured
+*		- an error XSK_EFUSEPS_ERROR_WRITE_VCCPAUX_VOLTAGE_OUT_OF_RANGE when
+*		  voltage not in range
+*		- an error XSK_EFUSEPS_ERROR_WRITE_TEMPERATURE_OUT_OF_RANGE when
+*		  temperature not in range
+*		- Other errors because of internal functions and
+*		  can be checked in xeFUSE_error.h
+****************************************************************************/
+static u32
+XilSKey_EfusePs_WriteWithXadcCheckAndVerify(u32 EfuseAddress, u32 RefClk)
+{
+	XSKEfusePs_XAdc XAdcInstancePtr;
+	u32 Status, StatusLowerAddr, RedundantEfuseAddress;
+
+	/**
+	 * If the eFUSE bit is already programmed, no need to program again.
+	 * That is taken care in eFUSE controller write function
+	 */
+	XAdcInstancePtr.VType = XSK_EFUSEPS_VPAUX;
+	XilSKey_EfusePs_XAdcReadTemperatureAndVoltage(&XAdcInstancePtr);
+
+	/**
+	 * Check the temperature and voltage
+	 */
+	if ((XAdcInstancePtr.Temp < XSK_EFUSEPS_TEMP_MIN_RAW) ||
+			((XAdcInstancePtr.Temp > XSK_EFUSEPS_TEMP_MAX_RAW))) {
+		return XSK_EFUSEPS_ERROR_WRITE_TEMPERATURE_OUT_OF_RANGE;
+	}
+
+	if ((XAdcInstancePtr.V < XSK_EFUSEPS_WRITE_VPAUX_MIN_RAW) ||
+			((XAdcInstancePtr.V > XSK_EFUSEPS_WRITE_VPAUX_MAX_RAW))) {
+		return XSK_EFUSEPS_ERROR_WRITE_VCCPAUX_VOLTAGE_OUT_OF_RANGE;
+	}
+
+	/**
+	 * Write the eFUSE bit
+	 */
+	StatusLowerAddr = XilSKey_EfusePs_WriteEfuseBit(EfuseAddress);
+
+	/**
+	 * verify only if programming is success
+	 * verification of lower address is checked while
+	 * higher address verification
+	 */
+	if (StatusLowerAddr == XST_SUCCESS) {
+		StatusLowerAddr = XilSKey_EfusePs_VerifyWithXadcCheck(EfuseAddress,
+															 RefClk);
+	}
+
+	/**
+	 * Write the Redundant eFUSE bit address
+	 */
+	RedundantEfuseAddress  = XSK_EFUSEPS_APB_MIRROR_ADDRESS(EfuseAddress);
+	Status = XilSKey_EfusePs_WriteEfuseBit(RedundantEfuseAddress);
+	if (Status != XST_SUCCESS) {
+		/**
+		 * if higher address is not success, check lower address and return
+		 */
+		if (StatusLowerAddr != XST_SUCCESS) {
+			return Status;
+		} else {
+			/**
+			 *  Successfully written lower address, so success
+			 */
+			return XST_SUCCESS;
+		}
+	}
+
+	Status = XilSKey_EfusePs_VerifyWithXadcCheck(RedundantEfuseAddress,
+												RefClk);
+	if (Status != XST_SUCCESS) {
+		/**
+		 * if higher address is not success, check lower address and return
+		 */
+		if (StatusLowerAddr != XST_SUCCESS) {
+			return Status;
+		} else {
+			/**
+			 *  Succesfully written lower address, so success
+			 */
+			return XST_SUCCESS;
+		}
+	}
+
+	/**
+	 * Ideal case where lower and higher address is written properly
+	 */
+	return XST_SUCCESS;
+}
+
+
+/***************************************************************************/
+/**
+* This function is used to write the RSA hash in the eFUSE Array in Little
+* Endian.
+*
+* @param RsaKeyHashBuf is the buffer containing the RSA hash to be written
+* 		 to the eFUSE array.
+* @param RefClk is the reference clock frequency. Clock frequency can be
+* 				between 20MHz to 60MHz specified in Hz
+* @return
+* 		- XST_SUCCESS no errors occurred.
+*		- Other errors because of internal controller functions and
+*		  can be checked in xeFUSE_error.h
+*
+****************************************************************************/
+static u32 XilSKey_EfusePs_WriteRsaKeyHash(u8 *RsaKeyHashBuf, u32 RefClk)
+{
+	int LoopIndex,BitIndex;
+	u8 DataBytes[XSK_EFUSEPS_RSA_KEY_HASH_LEN_BITS], Ecc[32];
+	u32 EfuseAddress, Status;
+
+
+	/**
+	 * Convert the RSA Key hash to bit data
+	 */
+	 XilSKey_Efuse_ConvertBitsToBytes(RsaKeyHashBuf, DataBytes,
+			 (XSK_EFUSEPS_RSA_KEY_HASH_LEN_IN_BYTES*8));
+
+	/**
+	 * Prepare the hamming matrix for encoding the RSA Key hash
+	 */
+	XilSKey_EfusePs_GenerateMatrixMap();
+
+	/**
+	 * Encode the RSA Key hash with (31,26) hamming and write into
+	 * the eFUSE array
+	 */
+	LoopIndex=0;
+	EfuseAddress=XSK_EFUSEPS_APB_CUSTOMER_KEY_FIRST_HALF_START_ADDR;
+	while (LoopIndex < XSK_EFUSEPS_HAMMING_LOOPS) {
+		/**
+		 *  Encode the data
+		 */
+		XilSKey_EfusePs_EccEncode(DataBytes + (LoopIndex*26), Ecc);
+		/* Write 31 bit Row in eFUSE Array */
+		for (BitIndex=0;BitIndex<31;BitIndex++) {
+			/**
+			 *  Escape the Xilinx Reserved Bits
+			 */
+			if (XilSKey_EfusePs_IsAddressXilRestricted(EfuseAddress) == TRUE) {
+				xeFUSE_printf(XSK_EFUSE_DEBUG_GENERAL,
+							  "Discarding eFUSE Address %0x\n",
+							  EfuseAddress);
+				EfuseAddress = EfuseAddress+4;
+			}
+
+			/**
+			 *  Write the eFUSE bit only if the value is one
+			 */
+			if (Ecc[BitIndex] & 0x1) {
+				xeFUSE_printf(XSK_EFUSE_DEBUG_GENERAL,
+							 "Writing eFUSE Addr %0x, LoopIndex %0x, "
+							 "BitIndex %0x\n",
+							  EfuseAddress, LoopIndex, BitIndex);
+				Status = XilSKey_EfusePs_WriteWithXadcCheckAndVerify(
+												EfuseAddress, RefClk);
+				if (Status != XST_SUCCESS) {
+					return Status;
+				}
+			} /* End of (Ecc[BitIndex] & 0x1) */
+			/**
+			 *  Ready for next eFUSE Bit
+			 */
+			EfuseAddress += 4;
+
+		} /* End of for(BitIndex=0;BitIndex<31;BitIndex++) */
+		LoopIndex++;
+	} /* End of  while(LoopIndex < XSK_EFUSEPS_HAMMING_LOOPS) */
+
+	return XST_SUCCESS;
+}
+
+/***************************************************************************/
+/**
+* This function is used to Read the RSA hash in the eFUSE Array in Little
+* Endian.
+*
+* @param    RsaKeyHashBuf is the output buffer where RSA hash is copied
+* 			from the eFUSE array after hamming decode.
+* @param	RefClk is the reference clock frequency. Clock frequency can be
+* 				between 20MHz to 60MHz specified in Hz
+* @return
+* 		- XST_SUCCESS no errors occurred.
+*		- Other errors because of internal controller functions and
+*		  can be checked in xeFUSEutils.h
+****************************************************************************/
+static u32 XilSKey_EfusePs_ReadRsaKeyHash(u8 *RsaKeyHashBuf, u32 RefClk)
+{
+	int LoopIndex, BitIndex, Index;
+	u8 DataBytes[260], Recover[32], Syndrome[5], Pos;
+	u32 EfuseAddress, Status;
+
+	/**
+	 * Prepare the hamming matrix for encoding the RSA Key hash
+	 */
+	XilSKey_EfusePs_GenerateMatrixMap();
+
+	/**
+	 * Encode the RSA Key hash with (31,26) hamming and write to
+	 * the eFUSE array
+	 */
+	LoopIndex=0;
+	EfuseAddress=XSK_EFUSEPS_APB_CUSTOMER_KEY_FIRST_HALF_START_ADDR;
+	while (LoopIndex < XSK_EFUSEPS_HAMMING_LOOPS) {
+		/**
+		 * Write 31 bit Row in eFUSE Array
+		 */
+		for (BitIndex=0;BitIndex<31;BitIndex++) {
+			/**
+			 *  Escape the Xilinx Reserved Bits
+			 */
+			if (XilSKey_EfusePs_IsAddressXilRestricted(EfuseAddress) == TRUE) {
+				xeFUSE_printf(XSK_EFUSE_DEBUG_GENERAL,
+						"Discarding eFUSE Address %0x\n",
+						EfuseAddress);
+				EfuseAddress += 4;
+			}
+			xeFUSE_printf(XSK_EFUSE_DEBUG_GENERAL,
+					"Reading eFUSE Addr %0x, LoopIndex %0x, "
+					"BitIndex %0x\n",
+					 EfuseAddress, LoopIndex, BitIndex);
+			Status = XilSKey_EfusePs_ReadWithXadcCheck(
+										EfuseAddress,
+										RefClk,
+										Recover+BitIndex);
+			if (Status != XST_SUCCESS) {
+				return Status;
+			}
+			EfuseAddress += 4;
+		} /* End of for(BitIndex=0;BitIndex<31;BitIndex++) */
+
+		/**
+		 *  Decode the data
+		 */
+		Pos = XilSKey_EfusePs_EccDecode(Recover, Syndrome);
+		/**
+		 *  Repair the corrupt bit
+		 */
+		if(Pos < 31)
+		{
+			Recover[Pos] = (Recover[Pos] + 1)% 2;
+		}
+		/**
+		 *  Copy the data
+		 */
+		for(Index=0;Index<26;Index++)
+		{
+			*(DataBytes + (LoopIndex * 26) + Index) = Recover[Index];
+		}
+		LoopIndex++;
+	} /* End of  while(LoopIndex < XSK_EFUSEPS_HAMMING_LOOPS) */
+
+	/**
+	 * Convert the bit data to RSA key hash
+	 */
+	XilSKey_EfusePs_ConvertBytesToBits(DataBytes,
+									  RsaKeyHashBuf,
+									  (XSK_EFUSEPS_RSA_KEY_HASH_LEN_BITS));
+
+	return XST_SUCCESS;
+}
+
+/***************************************************************************/
+/**
+* This function is used to read the PS eFUSE bit. Reading of the eFUSE bit
+* is done in NORMAL read mode. Temperature and voltage must be in specified
+* range for reading.
+*
+* @param EfuseAddress is the address of the eFUSE bit
+* @param RefClk is the reference clock frequency. Clock frequency can be
+* 				between 20MHz to 60MHz specified in Hz
+* @param Data is where the read data is stored. It will have values 0 or 1
+* @return
+* 		- XST_SUCCESS no errors occurred.
+*		- an error XSK_EFUSEPS_ERROR_READ_VCCPAUX_VOLTAGE_OUT_OF_RANGE when
+*		  voltage not in range
+*		- an error XSK_EFUSEPS_ERROR_READ_TMEPERATURE_OUT_OF_RANGE when
+*		  temperature not in range
+*		- Other errors because of internal controller functions and
+*		  can be checked in xeFUSE_error.h
+****************************************************************************/
+static u32
+XilSKey_EfusePs_ReadWithXadcCheck(u32 EfuseAddress, u32 RefClk, u8 *Data)
+{
+	XSKEfusePs_XAdc XAdcInstancePtr;
+	u32 Status;
+
+	XAdcInstancePtr.VType = XSK_EFUSEPS_VPAUX;
+	XilSKey_EfusePs_XAdcReadTemperatureAndVoltage(&XAdcInstancePtr);
+
+	/**
+	 * Check the temperature and voltage
+	 */
+	if ((XAdcInstancePtr.Temp < XSK_EFUSEPS_TEMP_MIN_RAW) ||
+			((XAdcInstancePtr.Temp > XSK_EFUSEPS_TEMP_MAX_RAW))) {
+		return XSK_EFUSEPS_ERROR_READ_TMEPERATURE_OUT_OF_RANGE;
+	}
+
+	if ((XAdcInstancePtr.V < XSK_EFUSEPS_READ_VPAUX_MIN_RAW) ||
+			((XAdcInstancePtr.V > XSK_EFUSEPS_READ_VPAUX_MAX_RAW))) {
+		return XSK_EFUSEPS_ERROR_READ_VCCPAUX_VOLTAGE_OUT_OF_RANGE;
+	}
+
+	/**
+	 * Read the eFUSE bit
+	 */
+	Status = XilSKey_EfusePs_ReadEfuseBit(EfuseAddress, Data);
+	if (Status != XST_SUCCESS) {
+		return Status;
+	}
+
+	return XST_SUCCESS;
+}
+
+/***************************************************************************/
+/**
+* This function is used to verify the written eFUSE bit. It is checked
+* against the value of 1 only. Verification of the eFUSE bit is done by reading
+* in MARGIN 2 mode which was highest margin.
+*
+* @param EfuseAddress is the address of the eFUSE bit
+* @param RefClk is the reference clock frequency. Clock frequency can be
+* 				between 20MHz to 60MHz specified in Hz
+* @return
+* 		- XST_SUCCESS no errors occurred.
+*		- XST_FAILURE an error occurred during verifying the PS eFUSE.
+*		- an error XSK_EFUSEPS_ERROR_READ_VCCPAUX_VOLTAGE_OUT_OF_RANGE when
+*		  voltage not in range
+*		- an error XSK_EFUSEPS_ERROR_READ_TMEPERATURE_OUT_OF_RANGE when
+*		  temperature not in range
+*		- an error XSK_EFUSEPS_ERROR_VERIFICATION when verification fails
+*		- Other errors because of internal controller functions and
+*		  can be checked in xeFUSE_error.h
+****************************************************************************/
+static u32 XilSKey_EfusePs_VerifyWithXadcCheck(u32 EfuseAddress, u32 RefClk)
+{
+	XSKEfusePs_XAdc XAdcInstancePtr;
+	u32 Status;
+	u8 Data;
+
+	XAdcInstancePtr.VType = XSK_EFUSEPS_VPAUX;
+	XilSKey_EfusePs_XAdcReadTemperatureAndVoltage(&XAdcInstancePtr);
+
+	/**
+	 * Check the temperature and voltage
+	 */
+	if ((XAdcInstancePtr.Temp < XSK_EFUSEPS_TEMP_MIN_RAW) ||
+			((XAdcInstancePtr.Temp > XSK_EFUSEPS_TEMP_MAX_RAW))) {
+		return XSK_EFUSEPS_ERROR_READ_TMEPERATURE_OUT_OF_RANGE;
+	}
+
+	if ((XAdcInstancePtr.V < XSK_EFUSEPS_READ_VPAUX_MIN_RAW) ||
+			((XAdcInstancePtr.V > XSK_EFUSEPS_READ_VPAUX_MAX_RAW))) {
+		return XSK_EFUSEPS_ERROR_READ_VCCPAUX_VOLTAGE_OUT_OF_RANGE;
+	}
+
+
+	/**
+	 * Read the eFUSE bit in Margin_1 mode
+	 */
+	Status = XilSKey_EfusePs_ControllerConfig(XSK_EFUSEPS_SINGLE_MODE,
+							RefClk, XSK_EFUSEPS_READ_MODE_MARGIN_1);
+	if (Status != XST_SUCCESS) {
+		return Status;
+	}
+	Status = XilSKey_EfusePs_ReadEfuseBit(EfuseAddress, &Data);
+	if (Status != XST_SUCCESS) {
+		return Status;
+	}
+
+	if (0 == ((Data) & 0x1)) {
+		return XSK_EFUSEPS_ERROR_VERIFICATION;
+	}
+
+
+	/**
+	 * Read the eFUSE bit in Normal Mode
+	 */
+	Status = XilSKey_EfusePs_ControllerConfig(XSK_EFUSEPS_SINGLE_MODE,
+							RefClk, XSK_EFUSEPS_READ_MODE_NORMAL);
+	if (Status != XST_SUCCESS) {
+		return Status;
+	}
+
+	Status = XilSKey_EfusePs_ReadEfuseBit(EfuseAddress, &Data);
+	if (Status != XST_SUCCESS) {
+		return Status;
+	}
+
+	if (0 == ((Data) & 0x1)) {
+		return XSK_EFUSEPS_ERROR_VERIFICATION;
+	}
+
+	return XST_SUCCESS;
+}
+
+/*****************************************************************************/
+/**
+* This function is used to generate the matrix map of the G and H for
+* hamming code (31,26). G is [31,5] and defined as [A|I], I is identity
+* matrix of [5,5].
+*
+* @return None
+*
+* TDD Cases:
+* 		Check the generated matrix
+* 		Check the memory corruption of the generated matrix
+*
+****************************************************************************/
+
+void XilSKey_EfusePs_GenerateMatrixMap()
+{
+
+	u8 y, x, Index;
+	u8 DataIndex, ParityIndex;
+
+	/* Matrix[31][5]={0} */
+	for(y = 0; y < 5; y++) {
+		for(x = 0; x < 31; x++) {
+			Matrix[x][y] = 0;
+		}
+	}
+
+	/* Generate Hamming Code Matrix for both Encoding and Decoding */
+	for(y = 0; y < 5; y++) {
+		Index = 0;
+		for(x = 1; x < 32; x++) {
+			if ((x != 1) && (x != 2) && (x != 4) && (x != 8) && (x != 16)) {
+				if ( ((x & (1 << y)) >> y) == 1)
+					Matrix[Index++][y] = 1;
+				else
+					Matrix[Index++][y] = 0;
+			}
+		}
+	}
+
+	/* Fill Identity Matrix */
+	for(y = 0; y < 5; y++) {
+		for(x = 0; x < 5; x++) {
+			if (x == y) Matrix[26+x][y] = 1;
+			else Matrix[26+x][y] = 0;
+		}
+	}
+#if 0
+// Print out format index
+	for(x = 1; x < 27; x++) {
+		printf("%*dd", 3, x);
+	}
+	printf("\n");
+
+	for(y = 0; y < 5; y++) {
+		for(x = 0; x < 31; x++) {
+			printf("%*d", 4, Matrix[x][y]);
+		}
+		printf("\n");
+	}
+
+#endif
+
+	/* Create Error Code Map Index */
+	ErrorCodeIndex[0] = -1; /* No Error */
+	DataIndex = 0;
+	ParityIndex = 26;
+	for(x = 1; x < 32; x++) {
+		if ((x != 1) && (x!= 2) && (x!= 4) && (x!= 8) && (x != 16)) {
+			ErrorCodeIndex[x] = DataIndex;
+			DataIndex ++;
+		} else {
+			ErrorCodeIndex[x] = ParityIndex;
+			ParityIndex ++;
+		}
+	}
+}
+
+
+/***************************************************************************/
+/**
+* This function is used to encode the incoming data byte. It uses
+* hamming (31,26) algorithm. 26 bits are encoded to 31 bits
+*
+* @param InData is 26 bit input data with each bit represented in one byte
+*
+* @param Ecc is the 31 bit encoded data with each bit represented in one byte
+*
+* @return None
+*
+* TDD Cases:
+* 		Check the parameters
+* 		Check the encoded data for different input data
+* 		Check the input data for boundary cases
+* 		Check for memory corruption
+*
+****************************************************************************/
+void XilSKey_EfusePs_EccEncode(const u8 *InData, u8 *Ecc)
+{
+	u8  x, y, Index;
+
+	for(x = 0; x < 26; x++)
+		Ecc[x] = InData[x];
+	for(y = 0; y < 5; y++) {
+		Ecc[y+26] = 0;
+		for( Index =0; Index < 26; Index++)
+			Ecc[y+26] += Matrix[Index][y] * InData[Index];
+		Ecc[y+26] %= 2;
+	}
+}
+
+
+/***************************************************************************/
+/**
+* This function is used to decode the incoming encoded byte.
+*
+* @param Corrupt is the input encoded data. It has 26 bit data with
+* 		 5 bit parity data
+*
+* @param Syndrome is the output updated with the parity error
+* 		 information.
+*
+* @return position of the error in the data byte
+*
+* TDD Cases:
+* 		Check the parameters
+* 		Check the decode with out any error
+* 		Check the decode with 1 bit error
+* 		Check the decode with 2 bit error
+* 		Check the decode for boundary cases
+* 		Check for memory corruption
+*
+****************************************************************************/
+u8 XilSKey_EfusePs_EccDecode(const u8 *Corrupt, u8 *Syndrome)
+{
+	u8 x, y;
+	u8 Pos;
+
+	// Calculate Error Syndrome
+	for(y = 0; y < 5; y++) {
+		Syndrome[y] = 0;
+		for( x =0; x < 31; x++)
+			Syndrome[y] += Matrix[x][y] * Corrupt[x];
+		Syndrome[y] %= 2;
+	}
+	Pos = (Syndrome[4] << 4) + (Syndrome[3] << 3) +
+			(Syndrome[2] << 2) + (Syndrome[1] << 1) + Syndrome[0];
+	Pos = ErrorCodeIndex[Pos];
+
+	return Pos;
+}
+
+/***************************************************************************/
+/**
+* This function is used to set the controller mode to Redundancy/Single mode.
+*
+* @param Mode is mode of the controller to the set.
+* 		- REDUNDANCY_MODE
+* 		- SINGLE_MODE
+*
+* @return None
+*
+****************************************************************************/
+
+static void XilSKey_EfusePs_SetControllerMode (u8 Mode)
+{
+	u32 RegVal;
+	if(Mode == XSK_EFUSEPS_REDUNDANCY_MODE) {
+		/**
+		 *  Configuration Reg - Redundancy Mode
+		 */
+		RegVal = Xil_In32(XSK_EFUSEPS_CONFIG_REG);
+		RegVal |= XSK_EFUSEPS_CONFIG_REDUNDANCY;
+		Xil_Out32(XSK_EFUSEPS_CONFIG_REG, RegVal);
+	}
+	else if(Mode == XSK_EFUSEPS_SINGLE_MODE)	{
+		/**
+		 *  Configuration Reg - Single Mode
+		 */
+		RegVal = Xil_In32(XSK_EFUSEPS_CONFIG_REG);
+		RegVal &= ~XSK_EFUSEPS_CONFIG_REDUNDANCY;
+		Xil_Out32(XSK_EFUSEPS_CONFIG_REG, RegVal);
+	}
+	return ;
+}
+
+
+/***************************************************************************/
+/**
+* This function is used to set the controller read mode to
+* Normal/Margin 1/Margin 2.
+*
+* @param ReadMode is the read mode of the controller
+* 		- XSK_EFUSEPS_READ_MODE_NORMAL
+* 		- XSK_EFUSEPS_READ_MODE_MARGIN_1
+* 		- XSK_EFUSEPS_READ_MODE_MARGIN_2
+*
+* @return  None
+*
+****************************************************************************/
+
+static void XilSKey_EfusePs_SetControllerReadMode (u8 ReadMode)
+{
+
+	u32 RegVal;
+
+	/**
+	 * Read Configuration Reg
+	 */
+	RegVal = Xil_In32(XSK_EFUSEPS_CONFIG_REG);
+	/**
+	 *  Reset the read mode
+	 */
+	RegVal &= ~XSK_EFUSEPS_CONFIG_MARGIN_RD;
+	if (ReadMode == XSK_EFUSEPS_READ_MODE_NORMAL) {
+		/**
+		 *  Set to Normal read mode
+		 */
+		RegVal |= XSK_EFUSEPS_CONFIG_RD_NORMAL;
+	}
+	else if (ReadMode == XSK_EFUSEPS_READ_MODE_MARGIN_1)	{
+		/**
+		 *  Set to Margin 1 read mode
+		 */
+		RegVal |= XSK_EFUSEPS_CONFIG_RD_MARGIN_1;
+	}
+	else if (ReadMode == XSK_EFUSEPS_READ_MODE_MARGIN_2)	{
+		/**
+		 * Set to Margin 2 read mode
+		 */
+		RegVal |= XSK_EFUSEPS_CONFIG_RD_MARGIN_2;
+	}
+	Xil_Out32(XSK_EFUSEPS_CONFIG_REG, RegVal);
+	return ;
+}
+
+/***************************************************************************/
+/**
+* This function is used to check the read mode supported
+*
+* @param ReadMode is input read mode to be checked against
+*
+* @return
+* 		- XST_SUCCESS if read mode is supported
+*		- XST_FAILURE if read mode is not supported
+*
+****************************************************************************/
+
+static u8 XilSKey_EfusePs_IsReadModeSupported (u8 ReadMode)
+{
+	if ((ReadMode == XSK_EFUSEPS_READ_MODE_NORMAL)   ||
+		(ReadMode == XSK_EFUSEPS_READ_MODE_MARGIN_1) ||
+		(ReadMode == XSK_EFUSEPS_READ_MODE_MARGIN_2)) {
+		return TRUE;
+	}
+
+	return FALSE;
+}
+
+
+/***************************************************************************/
+/**
+* This function is used to set the controller mode, read mode along with
+* the read and program strobe width values based on the reference clock.
+*
+* @param CtrlMode is the mode of the controller
+* 		- XSK_EFUSEPS_REDUNDANCY_MODE
+* 		- XSK_EFUSEPS_SINGLE_MODE
+*
+* @param RefClk is the CPU 1x reference clock frequency. Clock frequency can be
+* 		 between 20MHz to 100MHz specified in Hz
+*
+* @param ReadMode is the read mode of the controller
+* 		- XSK_EFUSEPS_READ_MODE_NORMAL
+* 		- XSK_EFUSEPS_READ_MODE_MARGIN_1
+* 		- XSK_EFUSEPS_READ_MODE_MARGIN_2
+*
+* @return
+* 		- XST_SUCCESS no errors occured.
+*		- an error when controller mode is not supported
+*		- an error when reference clock is not supported
+*		- an error when read mode is not supported
+*
+* Test Cases:
+	Check single mode in CFG Reg
+	Check redundancy mode in CFG Reg
+	Check strobe width values for write mode
+	Check strobe width values for various read mode
+	Check Normal Read mode setting in CFG Reg
+	Check Margin 1 Read mode setting in CFG Reg
+	Check Margin 2 Read mode setting in CFG Reg
+	Boundary Conditions
+
+*
+****************************************************************************/
+u32 XilSKey_EfusePs_ControllerConfig(u8 CtrlMode, u32 RefClk, u8 ReadMode)
+{
+	u32 RdStrWdthVal=0, PrgmStrWdthVal=0;
+
+	/**
+	 *  Check the parameters
+	 *  Mode can be Single or Redundancy mode
+	 */
+
+	if ((CtrlMode != XSK_EFUSEPS_SINGLE_MODE) &&
+			(CtrlMode != XSK_EFUSEPS_REDUNDANCY_MODE)) {
+		return XSK_EFUSEPS_ERROR_CONTROLLER_MODE;
+	}
+
+
+	/**
+	 *  Ref Clock should be between 20MHz - 60MHz
+	 */
+	if ((RefClk < XSK_EFUSEPS_REFCLK_LOW_FREQ) ||
+			(RefClk > XSK_EFUSEPS_REFCLK_HIGH_FREQ)) {
+		return XSK_EFUSEPS_ERROR_REF_CLOCK;
+	}
+
+	/**
+	 *  3 read modes are supported
+	 */
+	if (!XilSKey_EfusePs_IsReadModeSupported(ReadMode)) {
+		return XSK_EFUSEPS_ERROR_READ_MODE;
+	}
+
+	/**
+	 *  Set the controller mode
+	 */
+	XilSKey_EfusePs_SetControllerMode(CtrlMode);
+
+	/**
+	 * Set the controller read mode
+	 */
+	XilSKey_EfusePs_SetControllerReadMode(ReadMode);
+
+
+#if 0
+	u32 RegVal;
+	/* Commented as we are not supporting Reference Freq > 60MHz */
+	/**
+	 *  Set TSU_H_A to 1 if RefClk > 80MHz
+	 */
+	RegVal = Xil_In32(XSK_EFUSEPS_CONFIG_REG);
+	if (RefClk > 80000000) {
+		RegVal |= XSK_EFUSEPS_CONFIG_TSU_H_A;
+	}
+	Xil_Out32(XSK_EFUSEPS_CONFIG_REG, RegVal);
+#endif
+	/**
+	 * Program the Strobe width values for read and write
+	 * 12ms is required for write and 150ns is required for read
+	 * PGM_STBW = ceiling(12us/ref_clk period)
+	 * RD_STBW = ceiling(150ns/ref_clk period)
+	 */
+	PrgmStrWdthVal = XSK_EFUSEPS_PRGM_STROBE_WIDTH(RefClk);
+	Xil_Out32(XSK_EFUSEPS_PGM_STBW_REG, PrgmStrWdthVal);
+
+	RdStrWdthVal = XSK_EFUSEPS_RD_STROBE_WIDTH(RefClk);
+	Xil_Out32(XSK_EFUSEPS_RD_STBW_REG, RdStrWdthVal);
+
+	return XST_SUCCESS;
+}
+
+/***************************************************************************/
+/**
+* This function is used to check whether eFuse bit is xilinx reserved bit or
+* not
+*
+* @param Addr is the address of the eFuse bit.
+*
+* @return
+* 		- XST_SUCCESS if address corresponds to restricted eFuse bit.
+*		- XST_FAILURE is address corresponds to non-restricted eFuse bit.
+*
+* Test Cases:
+* 		with different address values
+* 		Boundary values for addr
+*
+****************************************************************************/
+
+u8 XilSKey_EfusePs_IsAddressXilRestricted (u32 Addr)
+{
+	/**
+	 *  Check for xilinx test bits
+	 */
+	if(	(Addr == XSK_EFUSEPS_APB_XILINX_RSVD_TEST_BIT_x20)  ||
+		(Addr == XSK_EFUSEPS_APB_XILINX_RSVD_TEST_BIT_x41)  ||
+		(Addr == XSK_EFUSEPS_APB_XILINX_RSVD_TEST_BIT_x62)  ||
+		(Addr == XSK_EFUSEPS_APB_XILINX_RSVD_TEST_BIT_x83)  ||
+		(Addr == XSK_EFUSEPS_APB_XILINX_RSVD_TEST_BIT_xA4)  ||
+		(Addr == XSK_EFUSEPS_APB_XILINX_RSVD_TEST_BIT_xC5)  ||
+		(Addr == XSK_EFUSEPS_APB_XILINX_RSVD_TEST_BIT_xE6)  ||
+		(Addr == XSK_EFUSEPS_APB_XILINX_RSVD_TEST_BIT_x107) ||
+		(Addr == XSK_EFUSEPS_APB_XILINX_RSVD_TEST_BIT_x128) ||
+		(Addr == XSK_EFUSEPS_APB_XILINX_RSVD_TEST_BIT_x149) ||
+
+		(Addr == XSK_EFUSEPS_APB_XILINX_RSVD_TEST_BIT_x23F)  ||
+		(Addr == XSK_EFUSEPS_APB_XILINX_RSVD_TEST_BIT_x25E)  ||
+		(Addr == XSK_EFUSEPS_APB_XILINX_RSVD_TEST_BIT_x27D)  ||
+		(Addr == XSK_EFUSEPS_APB_XILINX_RSVD_TEST_BIT_x29C)  ||
+		(Addr == XSK_EFUSEPS_APB_XILINX_RSVD_TEST_BIT_x2BB)  ||
+		(Addr == XSK_EFUSEPS_APB_XILINX_RSVD_TEST_BIT_x2DA)  ||
+		(Addr == XSK_EFUSEPS_APB_XILINX_RSVD_TEST_BIT_x2F9)  ||
+		(Addr == XSK_EFUSEPS_APB_XILINX_RSVD_TEST_BIT_x318)  ||
+		(Addr == XSK_EFUSEPS_APB_XILINX_RSVD_TEST_BIT_x337)  ||
+		(Addr == XSK_EFUSEPS_APB_XILINX_RSVD_TEST_BIT_x356)	)
+	{
+		return TRUE;
+	}
+
+	/**
+	 *  Check for xilinx reserved bits
+	 */
+	if ( ((Addr >= XSK_EFUSEPS_APB_TRIM_BITS_START_ADDR) &&
+		  (Addr <= XSK_EFUSEPS_APB_TRIM_BITS_END_ADDR)) ||
+		 ((Addr >= XSK_EFUSEPS_APB_XILINX_RSVD_BITS_START_ADDR) &&
+		  (Addr <= XSK_EFUSEPS_APB_XILINX_RSVD_BITS_END_ADDR)) ||
+		 ((Addr >= XSK_EFUSEPS_APB_BISR_BITS_START_ADDR) &&
+		  (Addr <= XSK_EFUSEPS_APB_BISR_BITS_END_ADDR)) ||
+		 ((Addr >= XSK_EFUSEPS_APB_TRIM_BITS_START_ADDR_2ND_HALF) &&
+		  (Addr <= XSK_EFUSEPS_APB_TRIM_BITS_END_ADDR_2ND_HALF)) ||
+		 ((Addr >= XSK_EFUSEPS_APB_XILINX_RSVD_BITS_START_ADDR_2ND_HALF) &&
+		  (Addr <= XSK_EFUSEPS_APB_XILINX_RSVD_BITS_END_ADDR_2ND_HALF)) ||
+		 ((Addr >= XSK_EFUSEPS_APB_BISR_BITS_START_ADDR_2ND_HALF) &&
+		  (Addr <= XSK_EFUSEPS_APB_BISR_BITS_END_ADDR_2ND_HALF))
+		) {
+		return TRUE;
+	}
+
+	return FALSE;
+}
+
+/***************************************************************************/
+/**
+* This function is used to enable the read/write/program the eFUSE
+* array.
+*
+* @param ReadWriteEnable
+* 			0x1 - Enable programming
+* 			0x2 - Enable read
+* 			0x4 - Enable write
+* @return
+*
+* Test Cases
+*
+****************************************************************************/
+
+void XilSKey_EfusePs_ControllerSetReadWriteEnable(u32 ReadWriteEnable)
+{
+	u32 RegVal;
+
+	RegVal = Xil_In32(XSK_EFUSEPS_CONTROL_REG);
+
+	/**
+	 *  Reset the values
+	 * Disable programming
+	 * Disable reading
+	 * Disable writing
+	 */
+	RegVal &= ~XSK_EFUSEPS_CONTROL_PS_EN;
+	RegVal |= XSK_EFUSEPS_CONTROL_RD_DIS | XSK_EFUSEPS_CONTROL_WR_DIS;
+
+	if (ReadWriteEnable & XSK_EFUSEPS_ENABLE_PROGRAMMING) {
+		RegVal |= XSK_EFUSEPS_CONTROL_PS_EN;
+	}
+
+	if (ReadWriteEnable & XSK_EFUSEPS_ENABLE_READ) {
+		RegVal &= ~XSK_EFUSEPS_CONTROL_RD_DIS;
+	}
+
+	if (ReadWriteEnable & XSK_EFUSEPS_ENABLE_WRITE) {
+		RegVal &= ~XSK_EFUSEPS_CONTROL_WR_DIS;
+	}
+
+	Xil_Out32(XSK_EFUSEPS_CONTROL_REG, RegVal);
+
+	return;
+}
+
+
+/***************************************************************************/
+/**
+* This function is used to read the eFuse bit value. Before using this
+* function set the controller mode and read mode as required. Also, strobe
+* width values are to be set properly based on the reference clock for
+* successful reading
+*
+* @param Addr is the address of the eFuse bit.
+*
+* @param Data has the read eFuse value stored in it.
+*
+* @return
+* 		- XST_SUCCESS for succesfully reading the value.
+*		- an error when addr is restricted
+*
+* Test Cases
+	Read in Single mode
+	Read in redundancy mode
+	Read for restricted address
+	Boundary Checks for address
+*
+****************************************************************************/
+
+u32 XilSKey_EfusePs_ReadEfuseBit(u32 Addr, u8 *Data)
+{
+	if(XilSKey_EfusePs_IsAddressXilRestricted(Addr) != FALSE) {
+		return XSK_EFUSEPS_ERROR_ADDRESS_XIL_RESTRICTED;
+	}
+
+	*Data = Xil_In32(Addr) & 0x1;
+
+	xeFUSE_printf(XSK_EFUSE_DEBUG_GENERAL,"Reading Addr %0x, Data %0x\n", Addr, *Data);
+
+	return XST_SUCCESS;
+}
+
+/***************************************************************************/
+/**
+* This function is used to program the eFuse bit value. Before using this
+* function set the controller mode and read mode as required. Also, strobe
+* width values are to be set properly based on the reference clock for
+* successful programming
+*
+* @param Addr is the address of the eFuse bit.
+*
+* @return
+* 		- XST_SUCCESS after successful writing.
+*		- an error when addr is restricted
+*
+* Test Cases
+	Write in Single mode
+	Write in redundancy mode
+	Write for restricted address
+	Boundary Checks for address
+	Strobe width are not proper (Check if it makes sense)
+*
+****************************************************************************/
+
+u32 XilSKey_EfusePs_WriteEfuseBit(u32 Addr)
+{
+
+	u64 time = 0;
+
+	/**
+	 *  Check if Address is restricted
+	 */
+
+	if(XilSKey_EfusePs_IsAddressXilRestricted(Addr) != FALSE) {
+		return XSK_EFUSEPS_ERROR_ADDRESS_XIL_RESTRICTED;
+	}
+
+	/**
+	 * Send success when bit is already programmed
+	 */
+	if ((Xil_In32(Addr)&0x1) == 1) {
+		xeFUSE_printf(XSK_EFUSE_DEBUG_GENERAL,
+				"Addr %0x already programmed\n", Addr);
+		return XST_SUCCESS;
+	}
+
+	Xil_Out32(Addr, 0x1);
+
+	/**
+	 * Providing 15us delay
+	 * Timer takes 100ns as slice. 15us = 150 * 100ns
+	 */
+	XilSKey_Efuse_SetTimeOut(&time, 150);
+	while(1) {
+		if(XilSKey_Efuse_IsTimerExpired(time) == 1)
+			break;
+	}
+
+	xeFUSE_printf(XSK_EFUSE_DEBUG_GENERAL,
+			"Writing Addr %0x, Data %0x\n", Addr, Xil_In32(Addr));
+
+	return XST_SUCCESS;
+}
+
+/***************************************************************************/
+/**
+* This function is used to read the PS efuse status register.
+*
+* @param  InstancePtr is the pointer to the PsEfuseHandle which describes
+* 	  which PS eFUSE bit should be burned.
+* @param  StatusBits - variable to store the status register read.
+*
+* @return
+* 		- XST_SUCCESS.
+* 		- XST_FAILURE
+*
+****************************************************************************/
+u32 XilSKey_EfusePs_ReadStatus(XilSKey_EPs *InstancePtr, u32 *StatusBits)
+{
+	u32 RetValue;
+
+	RetValue = XST_SUCCESS;
+
+	/**
+	 *  Unlock the eFUSE controller
+	 */
+	XSK_EFUSEPS_CONTROLER_UNLOCK();
+
+	/**
+	 *  Check if the controller is unlocked
+	 */
+	if (XSK_EFUSEPS_CONTROLER_LOCK_STATUS() == TRUE) {
+		RetValue = XSK_EFUSEPS_ERROR_CONTROLLER_LOCK;
+		goto ExitFinal;
+	}
+
+	/**
+	 *  Read the eFUSE status
+	 */
+	*StatusBits = Xil_In32(XSK_EFUSEPS_STATUS_REG);
+
+ExitFinal:
+	return RetValue;
+}
diff --git a/lib/sw_services/xilskey/src/xilskey_epshw.h b/lib/sw_services/xilskey/src/xilskey_epshw.h
new file mode 100644
index 00000000..1647a635
--- /dev/null
+++ b/lib/sw_services/xilskey/src/xilskey_epshw.h
@@ -0,0 +1,484 @@
+/******************************************************************************
+*
+* 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_epshw.h
+ *
+ *
+ * @note	None.
+ *
+ *
+ * MODIFICATION HISTORY:
+ *
+* Ver   Who  	Date     Changes
+* ----- ---- 	-------- --------------------------------------------------------
+* 1.00a rpoolla 04/26/13 First release
+ *
+ *****************************************************************************/
+
+#ifndef XILSKEY_EPSHW_H
+#define XILSKEY_EPSHW_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "xil_types.h"
+#include "xilskey_utils.h"
+
+/**
+ * Rsa Key hash length in bytes
+ */
+#define XSK_EFUSEPS_RSA_KEY_HASH_LEN_BITS		(256)
+
+#define XSK_EFUSEPS_HAMMING_LOOPS				(10)
+#define XSK_EFUSEPS_HAMMING_LENGTH 				(31)
+#define XSK_EFUSEPS_HAMMING_DATA				(26)
+
+#define XSK_EFUSEPS_SINGLE_MODE                 (0x0)
+#define XSK_EFUSEPS_REDUNDANCY_MODE             (0x1)
+
+#define XSK_EFUSEPS_READ_MODE_NORMAL			(0x1)
+#define XSK_EFUSEPS_READ_MODE_MARGIN_1			(0x2)
+#define XSK_EFUSEPS_READ_MODE_MARGIN_2			(0x3)
+
+#define XSK_EFUSEPS_ENABLE_PROGRAMMING			(0x1)
+#define XSK_EFUSEPS_ENABLE_READ					(0x2)
+#define XSK_EFUSEPS_ENABLE_WRITE				(0x4)
+
+#define XSK_EFUSEPS_PRGM_STROBE_WIDTH(RefClk)	((12 * (RefClk))/1000000)
+/**
+ *  Modified to have max of 32 bit value
+ */
+#define XSK_EFUSEPS_RD_STROBE_WIDTH(RefClk)		((15 * (RefClk))/100000000)
+
+
+#define XSK_EFUSEPS_REFCLK_LOW_FREQ				(20000000)
+#define XSK_EFUSEPS_REFCLK_HIGH_FREQ			(60000000)
+
+/**
+ * PSS eFUSE Register addresses
+ */
+/**
+ * eFuse base address
+ */
+#define XSK_EFUSEPS_BASE_ADDRESS                (0xF800D000)
+
+#define XSK_EFUSEPS_WR_LOCK_REG_OFFSET   		(0x0)
+	/**
+	 * WR_UNLOCK    Write 0xDF0D to allow write offset
+	 */
+#define XSK_EFUSEPS_WR_UNLOCK_REG_OFFSET  		(0x4)
+	/**
+	 * WR_LOCKSTA   Write protection status offset
+	 */
+#define XSK_EFUSEPS_WR_LOCK_STATUS_REG_OFFSET	(0x8)
+	/**
+	 * CFG  Configuration register offset
+	 */
+#define XSK_EFUSEPS_CONFIG_REG_OFFSET    		(0xC)
+	/**
+	 * STATUS       Status register offset
+	 */
+#define XSK_EFUSEPS_STATUS_REG_OFFSET  			(0x10)
+	/**
+	 * CONTROL      Control register offset
+	 */
+#define XSK_EFUSEPS_CONTROL_REG_OFFSET    		(0x14)
+	/**
+	 * PGM_STBW     eFuse program strobe width register offset
+	 */
+#define XSK_EFUSEPS_PGM_STBW_REG_OFFSET 		(0x18)
+	/**
+	 * RD_STBW      eFuse read strobe width register offset
+	 */
+#define XSK_EFUSEPS_RD_STBW_REG_OFFSET    		(0x1C)
+	/* WR_LOCK      Write 0x767B to disallow write */
+
+#define XSK_EFUSEPS_WR_LOCK_REG   		   (XSK_EFUSEPS_BASE_ADDRESS + XSK_EFUSEPS_WR_LOCK_REG_OFFSET)
+	/**
+	 * WR_UNLOCK    Write 0xDF0D to allow write
+	 */
+#define XSK_EFUSEPS_WR_UNLOCK_REG         (XSK_EFUSEPS_BASE_ADDRESS + XSK_EFUSEPS_WR_UNLOCK_REG_OFFSET)
+	/**
+	 *  WR_LOCKSTA   Write protection status
+	 */
+#define XSK_EFUSEPS_WR_LOCK_STATUS_REG    (XSK_EFUSEPS_BASE_ADDRESS + XSK_EFUSEPS_WR_LOCK_STATUS_REG_OFFSET)
+	/**
+	 *  CFG  Configuration register
+	 */
+#define XSK_EFUSEPS_CONFIG_REG            (XSK_EFUSEPS_BASE_ADDRESS + XSK_EFUSEPS_CONFIG_REG_OFFSET)
+	/**
+	 *  STATUS       Status register
+	 */
+#define XSK_EFUSEPS_STATUS_REG            (XSK_EFUSEPS_BASE_ADDRESS + XSK_EFUSEPS_STATUS_REG_OFFSET)
+	/**
+	 *  CONTROL      Control register
+	 */
+#define XSK_EFUSEPS_CONTROL_REG           (XSK_EFUSEPS_BASE_ADDRESS + XSK_EFUSEPS_CONTROL_REG_OFFSET)
+	/**
+	 * PGM_STBW     eFuse program strobe width register
+	 */
+#define XSK_EFUSEPS_PGM_STBW_REG          (XSK_EFUSEPS_BASE_ADDRESS + XSK_EFUSEPS_PGM_STBW_REG_OFFSET)
+	/**
+	 *  RD_STBW      eFuse read strobe width register
+	 */
+#define XSK_EFUSEPS_RD_STBW_REG           (XSK_EFUSEPS_BASE_ADDRESS + XSK_EFUSEPS_RD_STBW_REG_OFFSET)
+
+
+/**< PSS eFUSE register bit defines & description */
+
+/**< XSK_EFUSEPS_WR_LOCK_STATUS_REG (Write Protection Status Register) */
+/** Current state of write protection mode of eFuse subsystem:-
+* 0 Region is writable
+* 1 Region is not writable. Any attempted writes are ignored, but reads will complete as normal.
+*/
+#define XSK_EFUSEPS_WR_LOCK_STATUS_BIT		(0x1)
+/**< XSK_EFUSEPS_CONFIG_REG (Configuration Register) */
+/** Redundancy mode, if set, else single mode.
+*  This bit only applies to APB access.
+*  BISR and eFuse reader always work in redundancy mode.
+*/
+#define XSK_EFUSEPS_CONFIG_REDUNDANCY		(0x00010000)
+/** eFuse read/program setup/hold control between address and strobe assert
+*  1 b0  1 ref clock cycle
+*  1 b1  2 ref clock cycles
+*/
+#define XSK_EFUSEPS_CONFIG_TSU_H_A		(0x00002000)
+/** eFuse read/program setup/hold control between csb and strobe assert
+*  1 b0  1 ref clock cycle
+*  1 b1  2 ref clock cycles
+*/
+#define XSK_EFUSEPS_CONFIG_TSU_H_CS		(0x00001000)
+/**< eFuse program setup/hold control between ps and csb active.*/
+#define XSK_EFUSEPS_CONFIG_TSU_H_PS		(0x00000F00)
+/** eFuse read margin control:
+* 00  normal, 01  margin 1, 10  margin 2, 11 - undefined
+*/
+#define XSK_EFUSEPS_CONFIG_MARGIN_RD		(0x00000030)
+#define XSK_EFUSEPS_CONFIG_RD_NORMAL		(0x00000000)
+#define XSK_EFUSEPS_CONFIG_RD_MARGIN_1		(0x00000010)
+#define XSK_EFUSEPS_CONFIG_RD_MARGIN_2		(0x00000020)
+/** Reference clock scaler
+*  2 b00  bypass clock divider
+*  2 b01  div 2
+*  2 b10  div 4
+*  2 h11  div 8
+*/
+#define XSK_EFUSEPS_CONFIG_CLK_DIV		(0x00000003)
+
+
+/**< XSK_EFUSEPS_STATUS_REG (Status Register)*/
+/** Status Register containing BISR Controller status, trim value,
+*  and security debug info.
+*/
+
+/**
+ *  Build in self test finished at boot time
+ */
+#define XSK_EFUSEPS_STATUS_BISR_DONE		(0x80000000)
+/**
+ *  Build in self test finished successfully
+ */
+#define XSK_EFUSEPS_STATUS_BISR_GO			(0x40000000)
+/**
+ *  eFuse box is blank, i.e., not yet been written to, if set
+ */
+#define XSK_EFUSEPS_STATUS_BISR_BLANK		(0x00100000)
+/** Security debug status, with authentication
+*  0  security debug enabled
+*  1  security debug disabled
+*/
+#define XSK_EFUSEPS_STATUS_SDEBUG_DIS		(0x00010000)
+/** eFuse write protection, if either bit is set,
+ * writes to the eFuse box are disabled
+ */
+#define XSK_EFUSEPS_STATUS_WR_PROTECT		(0x00003000)
+/**
+ *  Analog trim value
+ */
+#define XSK_EFUSEPS_STATUS_TRIM			(0x000000FC)
+
+
+/**
+ *  XSK_EFUSEPS_CONTROL_REG (Control register for eFuse program,
+ *  read and write control)
+ *  eFuse ps control, enable programming if set.
+ */
+#define XSK_EFUSEPS_CONTROL_PS_EN		(0x00000010)
+/**
+ *  eFuse write disable, if set.
+ */
+#define XSK_EFUSEPS_CONTROL_WR_DIS		(0x00000002)
+/**
+ *  eFuse read disable, if set
+ */
+#define XSK_EFUSEPS_CONTROL_RD_DIS		(0x00000001)
+
+
+#define XSK_EFUSEPS_APB_START_ADDR_OFFSET      		(0x1000)
+/**
+ * eFuse memory APB Customer key second half start address offset
+ */
+#define XSK_EFUSEPS_APB_WRITE_PROTECTION_ADDR_1_OFFSET 	(0x20)
+/**
+ * eFuse memory APB Customer key second half start address offset
+ */
+#define XSK_EFUSEPS_APB_WRITE_PROTECTION_ADDR_2_OFFSET 	(0x24)
+/**
+ * eFUSE APB address for ROM 128k CRC enable offset
+ */
+#define XSK_EFUSEPS_APB_ROM_128K_CRC_ENABLE_OFFSET 		(0x28)
+/**
+ * eFUSE APB address for RSA authentication enable offset
+ */
+#define XSK_EFUSEPS_APB_RSA_AUTH_ENABLE_OFFSET 			(0x2C)
+/**
+ * eFUSE APB address for RSA uart status enable on MIO48 offset
+ */
+#define XSK_EFUSEPS_APB_ROM_UART_STATUS_ENABLE_OFFSET 		(0x5C0)
+/**
+ * eFUSE APB address for non-secure INIT_B signaling offset
+ */
+#define XSK_EFUSEPS_APB_ROM_NONSECURE_INITB_ENABLE_OFFSET (0x5C4)
+
+/** eFUSE bits from 0 to 0x1F and 0x180 to 0x1FF in the First half,
+*  and bits from 0x200 to 0x21F and 0x380 to 0x3FF in the
+*  Second half(if Single mode is enabled)
+*/
+/**
+ *  If Redundant mode is enabled only First half addresses are valid.
+ *  eFuse memory APB Customer key first half start address
+ */
+#define XSK_EFUSEPS_APB_CUSTOMER_KEY_FIRST_HALF_START_ADDR_OFFSET	(0x80)
+/**
+ *  eFuse memory APB Customer key first half end address
+ */
+#define XSK_EFUSEPS_APB_CUSTOMER_KEY_FIRST_HALF_END_ADDR_OFFSET	(0x580)
+/**
+ * If Single mode is enabled both First and Second half addresses are valid.
+ * eFuse memory APB Customer key second half start address
+ */
+#define XSK_EFUSEPS_APB_CUSTOMER_KEY_SECND_HALF_START_ADDR_OFFSET	(0x880)
+/**
+ *  eFuse memory APB Customer key second half end address
+ */
+#define XSK_EFUSEPS_APB_CUSTOMER_KEY_SECND_HALF_END_ADDR_OFFSET	(0xE00)
+/**
+ * Mirror Address = addr + 2nd half start address + mirror offset
+ */
+#define XSK_EFUSEPS_APB_MIRROR_ADDRESS(Addr)	(Addr + 0x87C - (2*(Addr%128)))
+
+/**
+ * Following are the Xilinx reserved Tests bits in the First half of the eFUSE block.
+ */
+#define XSK_EFUSEPS_APB_XILINX_RSVD_TEST_BIT_x20_OFFSET				(0x80)
+#define XSK_EFUSEPS_APB_XILINX_RSVD_TEST_BIT_x41_OFFSET				(0x104)
+#define XSK_EFUSEPS_APB_XILINX_RSVD_TEST_BIT_x62_OFFSET				(0x188)
+#define XSK_EFUSEPS_APB_XILINX_RSVD_TEST_BIT_x83_OFFSET				(0x20C)
+#define XSK_EFUSEPS_APB_XILINX_RSVD_TEST_BIT_xA4_OFFSET				(0x290)
+#define XSK_EFUSEPS_APB_XILINX_RSVD_TEST_BIT_xC5_OFFSET				(0x314)
+#define XSK_EFUSEPS_APB_XILINX_RSVD_TEST_BIT_xE6_OFFSET				(0x398)
+#define XSK_EFUSEPS_APB_XILINX_RSVD_TEST_BIT_x107_OFFSET				(0x41C)
+#define XSK_EFUSEPS_APB_XILINX_RSVD_TEST_BIT_x128_OFFSET				(0x4A0)
+#define XSK_EFUSEPS_APB_XILINX_RSVD_TEST_BIT_x149_OFFSET				(0x524)
+
+/**
+ *  Following are the Xilinx reserved Tests bits in the First half of the eFUSE block.
+ */
+#define XSK_EFUSEPS_APB_XILINX_RSVD_TEST_BIT_x23F_OFFSET				(0x8FC)
+#define XSK_EFUSEPS_APB_XILINX_RSVD_TEST_BIT_x25E_OFFSET				(0x978)
+#define XSK_EFUSEPS_APB_XILINX_RSVD_TEST_BIT_x27D_OFFSET				(0x9F4)
+#define XSK_EFUSEPS_APB_XILINX_RSVD_TEST_BIT_x29C_OFFSET				(0xA70)
+#define XSK_EFUSEPS_APB_XILINX_RSVD_TEST_BIT_x2BB_OFFSET				(0xAEC)
+#define XSK_EFUSEPS_APB_XILINX_RSVD_TEST_BIT_x2DA_OFFSET				(0xB68)
+#define XSK_EFUSEPS_APB_XILINX_RSVD_TEST_BIT_x2F9_OFFSET				(0xBE4)
+#define XSK_EFUSEPS_APB_XILINX_RSVD_TEST_BIT_x318_OFFSET				(0xC60)
+#define XSK_EFUSEPS_APB_XILINX_RSVD_TEST_BIT_x337_OFFSET				(0xCDC)
+#define XSK_EFUSEPS_APB_XILINX_RSVD_TEST_BIT_x356_OFFSET				(0xD58)
+
+#define XSK_EFUSEPS_APB_TRIM_BITS_END_ADDR_OFFSET  					(0x1C)
+#define XSK_EFUSEPS_APB_XILINX_RSVD_BITS_START_ADDR_OFFSET  			(0x40)
+#define XSK_EFUSEPS_APB_XILINX_RSVD_BITS_END_ADDR_OFFSET  				(0x7C)
+#define XSK_EFUSEPS_APB_BISR_BITS_START_ADDR_OFFSET  					(0x600)
+#define XSK_EFUSEPS_APB_BISR_BITS_END_ADDR_OFFSET  					(0x7FC)
+
+/**
+ *  Following are the Xilinx reserved Tests bits in the Second half of the eFUSE block.
+ */
+#define XSK_EFUSEPS_APB_TRIM_BITS_START_ADDR_2ND_HALF_OFFSET  			(0x860)
+#define XSK_EFUSEPS_APB_TRIM_BITS_END_ADDR_2ND_HALF_OFFSET  			(0x87C)
+#define XSK_EFUSEPS_APB_XILINX_RSVD_BITS_START_ADDR_2ND_HALF_OFFSET  	(0x800)
+#define XSK_EFUSEPS_APB_XILINX_RSVD_BITS_END_ADDR_2ND_HALF_OFFSET		(0x83C)
+#define XSK_EFUSEPS_APB_BISR_BITS_START_ADDR_2ND_HALF_OFFSET  			(0xE00)
+#define XSK_EFUSEPS_APB_BISR_BITS_END_ADDR_2ND_HALF_OFFSET  			(0xFFC)
+
+
+
+
+/**
+ * eFuse memory APB start address
+ */
+#define XSK_EFUSEPS_APB_START_ADDR      			(XSK_EFUSEPS_BASE_ADDRESS + XSK_EFUSEPS_APB_START_ADDR_OFFSET)
+/*
+ * eFuse memory APB Customer key second half start address
+ */
+#define XSK_EFUSEPS_APB_WRITE_PROTECTION_ADDR_1 	(XSK_EFUSEPS_APB_START_ADDR + XSK_EFUSEPS_APB_WRITE_PROTECTION_ADDR_1_OFFSET)
+/*
+ * eFuse memory APB Customer key second half start address
+ */
+#define XSK_EFUSEPS_APB_WRITE_PROTECTION_ADDR_2 	(XSK_EFUSEPS_APB_START_ADDR + XSK_EFUSEPS_APB_WRITE_PROTECTION_ADDR_2_OFFSET)
+/*
+ * eFUSE APB address for ROM 128k CRC enable
+ */
+#define XSK_EFUSEPS_APB_ROM_128K_CRC_ENABLE 		(XSK_EFUSEPS_APB_START_ADDR + XSK_EFUSEPS_APB_ROM_128K_CRC_ENABLE_OFFSET)
+/*
+ * eFUSE APB address for RSA authentication enable
+ */
+#define XSK_EFUSEPS_APB_RSA_AUTH_ENABLE 			(XSK_EFUSEPS_APB_START_ADDR + XSK_EFUSEPS_APB_RSA_AUTH_ENABLE_OFFSET)
+/*
+ * eFUSE APB address for RSA uart status enable on MIO48
+ */
+#define XSK_EFUSEPS_APB_ROM_UART_STATUS_ENABLE 	(XSK_EFUSEPS_APB_START_ADDR + XSK_EFUSEPS_APB_ROM_UART_STATUS_ENABLE_OFFSET)
+/*
+ * eFUSE APB address for non-secure INIT_B signaling
+ */
+#define XSK_EFUSEPS_APB_ROM_NONSECURE_INITB_ENABLE (XSK_EFUSEPS_APB_START_ADDR + XSK_EFUSEPS_APB_ROM_NONSECURE_INITB_ENABLE_OFFSET)
+
+/** eFUSE bits from 0 to 0x1F and 0x180 to 0x1FF in the First half,
+*  and bits from 0x200 to 0x21F and 0x380 to 0x3FF in the
+*  Second half(if Single mode is enabled)
+*/
+/**
+ *  If Redundant mode is enabled only First half addresses are valid.
+ *
+ *  eFuse memory APB Customer key first half start address
+ */
+#define XSK_EFUSEPS_APB_CUSTOMER_KEY_FIRST_HALF_START_ADDR	(XSK_EFUSEPS_APB_START_ADDR + XSK_EFUSEPS_APB_CUSTOMER_KEY_FIRST_HALF_START_ADDR_OFFSET)
+/**
+ *  eFuse memory APB Customer key first half end address
+ */
+#define XSK_EFUSEPS_APB_CUSTOMER_KEY_FIRST_HALF_END_ADDR	(XSK_EFUSEPS_APB_START_ADDR + XSK_EFUSEPS_APB_CUSTOMER_KEY_FIRST_HALF_END_ADDR_OFFSET)
+/**
+ *  If Single mode is enabled both First and Second half addresses are valid.
+ *
+ *  eFuse memory APB Customer key second half start address
+ */
+#define XSK_EFUSEPS_APB_CUSTOMER_KEY_SECND_HALF_START_ADDR	(XSK_EFUSEPS_APB_START_ADDR + XSK_EFUSEPS_APB_CUSTOMER_KEY_SECND_HALF_START_ADDR_OFFSET)
+/*
+ * eFuse memory APB Customer key second half end address
+ */
+#define XSK_EFUSEPS_APB_CUSTOMER_KEY_SECND_HALF_END_ADDR	(XSK_EFUSEPS_APB_START_ADDR + XSK_EFUSEPS_APB_CUSTOMER_KEY_SECND_HALF_END_ADDR_OFFSET)
+/*
+ * Mirror Address = addr + 2nd half start address + mirror offset
+ */
+#define XSK_EFUSEPS_APB_MIRROR_ADDRESS(Addr)	(Addr + 0x87C - (2*(Addr%128)))
+
+/**
+ *  Following are the Xilinx reserved Tests bits in the First half of the eFUSE block.
+ */
+#define XSK_EFUSEPS_APB_XILINX_RSVD_TEST_BIT_x20		(XSK_EFUSEPS_APB_START_ADDR + XSK_EFUSEPS_APB_XILINX_RSVD_TEST_BIT_x20_OFFSET)
+#define XSK_EFUSEPS_APB_XILINX_RSVD_TEST_BIT_x41		(XSK_EFUSEPS_APB_START_ADDR + XSK_EFUSEPS_APB_XILINX_RSVD_TEST_BIT_x41_OFFSET)
+#define XSK_EFUSEPS_APB_XILINX_RSVD_TEST_BIT_x62		(XSK_EFUSEPS_APB_START_ADDR + XSK_EFUSEPS_APB_XILINX_RSVD_TEST_BIT_x62_OFFSET)
+#define XSK_EFUSEPS_APB_XILINX_RSVD_TEST_BIT_x83		(XSK_EFUSEPS_APB_START_ADDR + XSK_EFUSEPS_APB_XILINX_RSVD_TEST_BIT_x83_OFFSET)
+#define XSK_EFUSEPS_APB_XILINX_RSVD_TEST_BIT_xA4		(XSK_EFUSEPS_APB_START_ADDR + XSK_EFUSEPS_APB_XILINX_RSVD_TEST_BIT_xA4_OFFSET)
+#define XSK_EFUSEPS_APB_XILINX_RSVD_TEST_BIT_xC5		(XSK_EFUSEPS_APB_START_ADDR + XSK_EFUSEPS_APB_XILINX_RSVD_TEST_BIT_xC5_OFFSET)
+#define XSK_EFUSEPS_APB_XILINX_RSVD_TEST_BIT_xE6		(XSK_EFUSEPS_APB_START_ADDR + XSK_EFUSEPS_APB_XILINX_RSVD_TEST_BIT_xE6_OFFSET)
+#define XSK_EFUSEPS_APB_XILINX_RSVD_TEST_BIT_x107		(XSK_EFUSEPS_APB_START_ADDR + XSK_EFUSEPS_APB_XILINX_RSVD_TEST_BIT_x107_OFFSET)
+#define XSK_EFUSEPS_APB_XILINX_RSVD_TEST_BIT_x128		(XSK_EFUSEPS_APB_START_ADDR + XSK_EFUSEPS_APB_XILINX_RSVD_TEST_BIT_x128_OFFSET)
+#define XSK_EFUSEPS_APB_XILINX_RSVD_TEST_BIT_x149		(XSK_EFUSEPS_APB_START_ADDR + XSK_EFUSEPS_APB_XILINX_RSVD_TEST_BIT_x149_OFFSET)
+
+/**
+ * Following are the Xilinx reserved Tests bits in the First half of the eFUSE block.
+ */
+#define XSK_EFUSEPS_APB_XILINX_RSVD_TEST_BIT_x23F		(XSK_EFUSEPS_APB_START_ADDR + XSK_EFUSEPS_APB_XILINX_RSVD_TEST_BIT_x23F_OFFSET)
+#define XSK_EFUSEPS_APB_XILINX_RSVD_TEST_BIT_x25E		(XSK_EFUSEPS_APB_START_ADDR + XSK_EFUSEPS_APB_XILINX_RSVD_TEST_BIT_x25E_OFFSET)
+#define XSK_EFUSEPS_APB_XILINX_RSVD_TEST_BIT_x27D		(XSK_EFUSEPS_APB_START_ADDR + XSK_EFUSEPS_APB_XILINX_RSVD_TEST_BIT_x27D_OFFSET)
+#define XSK_EFUSEPS_APB_XILINX_RSVD_TEST_BIT_x29C		(XSK_EFUSEPS_APB_START_ADDR + XSK_EFUSEPS_APB_XILINX_RSVD_TEST_BIT_x29C_OFFSET)
+#define XSK_EFUSEPS_APB_XILINX_RSVD_TEST_BIT_x2BB		(XSK_EFUSEPS_APB_START_ADDR + XSK_EFUSEPS_APB_XILINX_RSVD_TEST_BIT_x2BB_OFFSET)
+#define XSK_EFUSEPS_APB_XILINX_RSVD_TEST_BIT_x2DA		(XSK_EFUSEPS_APB_START_ADDR + XSK_EFUSEPS_APB_XILINX_RSVD_TEST_BIT_x2DA_OFFSET)
+#define XSK_EFUSEPS_APB_XILINX_RSVD_TEST_BIT_x2F9		(XSK_EFUSEPS_APB_START_ADDR + XSK_EFUSEPS_APB_XILINX_RSVD_TEST_BIT_x2F9_OFFSET)
+#define XSK_EFUSEPS_APB_XILINX_RSVD_TEST_BIT_x318		(XSK_EFUSEPS_APB_START_ADDR + XSK_EFUSEPS_APB_XILINX_RSVD_TEST_BIT_x318_OFFSET)
+#define XSK_EFUSEPS_APB_XILINX_RSVD_TEST_BIT_x337		(XSK_EFUSEPS_APB_START_ADDR + XSK_EFUSEPS_APB_XILINX_RSVD_TEST_BIT_x337_OFFSET)
+#define XSK_EFUSEPS_APB_XILINX_RSVD_TEST_BIT_x356		(XSK_EFUSEPS_APB_START_ADDR + XSK_EFUSEPS_APB_XILINX_RSVD_TEST_BIT_x356_OFFSET)
+
+/**
+ * Following are the Xilinx reserved Tests bits in the First half of the eFUSE block.
+ */
+#define XSK_EFUSEPS_APB_TRIM_BITS_START_ADDR  			(XSK_EFUSEPS_APB_START_ADDR)
+#define XSK_EFUSEPS_APB_TRIM_BITS_END_ADDR  			(XSK_EFUSEPS_APB_START_ADDR + XSK_EFUSEPS_APB_TRIM_BITS_END_ADDR_OFFSET)
+#define XSK_EFUSEPS_APB_XILINX_RSVD_BITS_START_ADDR  	(XSK_EFUSEPS_APB_START_ADDR + XSK_EFUSEPS_APB_XILINX_RSVD_BITS_START_ADDR_OFFSET)
+#define XSK_EFUSEPS_APB_XILINX_RSVD_BITS_END_ADDR  	(XSK_EFUSEPS_APB_START_ADDR + XSK_EFUSEPS_APB_XILINX_RSVD_BITS_END_ADDR_OFFSET)
+#define XSK_EFUSEPS_APB_BISR_BITS_START_ADDR  			(XSK_EFUSEPS_APB_START_ADDR + XSK_EFUSEPS_APB_BISR_BITS_START_ADDR_OFFSET)
+#define XSK_EFUSEPS_APB_BISR_BITS_END_ADDR  			(XSK_EFUSEPS_APB_START_ADDR + XSK_EFUSEPS_APB_BISR_BITS_END_ADDR_OFFSET)
+
+/**
+ *  Following are the Xilinx reserved Tests bits in the Second half of the eFUSE block.
+ */
+#define XSK_EFUSEPS_APB_TRIM_BITS_START_ADDR_2ND_HALF  		(XSK_EFUSEPS_APB_START_ADDR + XSK_EFUSEPS_APB_TRIM_BITS_START_ADDR_2ND_HALF_OFFSET)
+#define XSK_EFUSEPS_APB_TRIM_BITS_END_ADDR_2ND_HALF  			(XSK_EFUSEPS_APB_START_ADDR + XSK_EFUSEPS_APB_TRIM_BITS_END_ADDR_2ND_HALF_OFFSET)
+#define XSK_EFUSEPS_APB_XILINX_RSVD_BITS_START_ADDR_2ND_HALF  	(XSK_EFUSEPS_APB_START_ADDR + XSK_EFUSEPS_APB_XILINX_RSVD_BITS_START_ADDR_2ND_HALF_OFFSET)
+#define XSK_EFUSEPS_APB_XILINX_RSVD_BITS_END_ADDR_2ND_HALF  	(XSK_EFUSEPS_APB_START_ADDR + XSK_EFUSEPS_APB_XILINX_RSVD_BITS_END_ADDR_2ND_HALF_OFFSET)
+#define XSK_EFUSEPS_APB_BISR_BITS_START_ADDR_2ND_HALF  		(XSK_EFUSEPS_APB_START_ADDR + XSK_EFUSEPS_APB_BISR_BITS_START_ADDR_2ND_HALF_OFFSET)
+#define XSK_EFUSEPS_APB_BISR_BITS_END_ADDR_2ND_HALF  			(XSK_EFUSEPS_APB_START_ADDR + XSK_EFUSEPS_APB_BISR_BITS_END_ADDR_2ND_HALF_OFFSET)
+
+/***************** Macros (Inline Functions) Definitions ********************/
+#define XSK_EFUSEPS_CONTROLER_LOCK()     	Xil_Out32(XSK_EFUSEPS_WR_LOCK_REG,0x767B)
+#define XSK_EFUSEPS_CONTROLER_UNLOCK()   	Xil_Out32(XSK_EFUSEPS_WR_UNLOCK_REG,0xDF0D)
+#define XSK_EFUSEPS_CONTROLER_LOCK_STATUS() (Xil_In32(XSK_EFUSEPS_WR_LOCK_STATUS_REG) & 0x1)
+#define XSK_EFUSEPS_CONTROLER_OP_MODE()     ((Xil_In32(XSK_EFUSEPS_CONFIG_REG) & XSK_EFUSEPS_CONFIG_REDUNDANCY)? 1 : 0)
+
+/***************************************************************************/
+/**
+* This macro is used to check whether eFuse is write protected or not
+*
+* @return
+* 		- TRUE if eFuse is write protected.
+*		- FALSE is eFuse is not write protected.
+****************************************************************************/
+
+#define XilSKey_EfusePs_IsEfuseWriteProtected()     ((Xil_In32(XSK_EFUSEPS_STATUS_REG) & XSK_EFUSEPS_STATUS_WR_PROTECT)? TRUE : FALSE)
+/************************** Function Prototypes ******************************/
+void XilSKey_EfusePs_GenerateMatrixMap();
+u8 XilSKey_EfusePs_EccDecode(const u8 *Corrupt, u8 *Syndrome);
+void XilSKey_EfusePs_EccEncode(const u8 *InData, u8 *Ecc);
+u32 XilSKey_EfusePs_ControllerConfig(u8 CtrlMode, u32 RefClk, u8 ReadMode);
+u8 XilSKey_EfusePs_IsAddressXilRestricted (u32 Addr);
+void XilSKey_EfusePs_ControllerSetReadWriteEnable(u32 ReadWriteEnable);
+u32 XilSKey_EfusePs_ReadEfuseBit(u32 Addr, u8 *Data);
+u32 XilSKey_EfusePs_WriteEfuseBit(u32 Addr);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif  /* End of XILSKEY_EPSHW_H */
diff --git a/lib/sw_services/xilskey/src/xilskey_js.h b/lib/sw_services/xilskey/src/xilskey_js.h
new file mode 100644
index 00000000..f9469d1e
--- /dev/null
+++ b/lib/sw_services/xilskey/src/xilskey_js.h
@@ -0,0 +1,391 @@
+/******************************************************************************
+*
+* 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.
+*
+******************************************************************************/
+
+/*
+ * JTAG server interface
+ *
+ * This interface is intended to be a common abstraction of JTAG cable
+ * implementations.
+ *
+ * Interface usage steps:
+ *
+ * 1. Initialize server implementation instance using implementation
+ *    specific js_init_*() function.
+ *
+ * 2. Enumerate available ports using js_get_port_descr_list().
+ *
+ * 3. Open selected port using js_open_port().
+ *
+ * 4. Optional: get or set properties using js_get_property() or
+ *    js_set_property().
+ *
+ * 5. Optional: enumerate scan chain using js_detect_taps() or
+ *    manually.  Add nodes for each TAP controller (API TDB).
+ *
+ * 6. Build command sequence(s) object using
+ *    js_create_command_sequence(), js_add_state_change(), and
+ *    js_add_shift().
+ *
+ * 7. Run sequence using js_run_command_sequence().
+ *
+ * 8. Repeat #6 and #7 as needed, possibly deleting or clearing
+ *    command sequence objects as needed using
+ *    js_delete_command_sequence() and js_clear_command_sequence().
+ *
+ * 9. Close port using js_close_port().
+ *
+ * 10. Delete server using js_deinit_server().
+ */
+
+#ifndef XILSKEY_JS_H
+#define XILSKEY_JS_H
+
+#include <stdlib.h>
+
+#if defined(_MSC_VER) && _MSC_VER < 1600
+   typedef signed __int8 int8_t;
+   typedef unsigned __int8 uint8_t;
+   typedef signed __int16 int16_t;
+   typedef unsigned __int16 uint16_t;
+   typedef signed __int32 int32_t;
+   typedef unsigned __int32 uint32_t;
+   typedef signed __int64 int64_t;
+   typedef unsigned __int64 uint64_t;
+#else
+#  include <stdint.h>
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * IEEE 1149.1 defined dummy idcode value.
+ */
+#define JS_DUMMY_IDCODE 0x000000ff
+
+typedef struct js_server_struct js_server_t;
+typedef struct js_port_descr_struct js_port_descr_t;
+typedef struct js_port_struct js_port_t;
+typedef struct js_node_struct js_node_t;
+typedef struct js_command_sequence_struct js_command_sequence_t;
+
+
+/*
+ * JTAG property kinds
+ */
+typedef enum {
+    JS_PROP_FREQUENCY
+} js_property_kind_t;
+
+typedef long js_property_value_t;
+
+
+/*
+ * JTAG port description
+ *
+ * This is retrieved by calling js_get_port_descr_list(), and is needed for
+ * js_open_port() to indicate which port to use.
+ */
+struct js_port_descr_struct {
+    char manufacturer[64];
+    char serial[64];
+    char port[64];
+    char description[128];
+    void *handle;
+};
+
+
+/*
+ * JTAG port
+ *
+ * This is retrieved by calling js_open_port().
+ */
+struct js_port_struct {
+    /* Server associated with port */
+    js_server_t *server;
+
+    /* Node representing the whole scan chain */
+    js_node_t *root_node;
+};
+
+
+/*
+ * JTAG node information
+ *
+ * Nodes typically represent a TAP controller.  A node can also
+ * represent a collection of TAP controllers, i.e. the whole scan
+ * chain or a device containing multiple TAP controllers.  For scan
+ * chains containing JTAG multiplexers a node can represent the
+ * branches on the multiplexer.
+ */
+struct js_node_struct {
+    /* Associated port */
+    js_port_t *port;
+
+    /* Node represents one or more TAP controllers */
+    int is_tap:1;
+
+    /* Node is a multiplexer (child nodes are branches) */
+    int is_mux:1;
+
+    /* Node is a branch on a multiplexer */
+    int is_branch:1;
+
+    /* This branch is part of the scan chain */
+    int is_active:1;
+
+    /* IDCODE of the TAP (JS_DUMMY_IDCODE if unknown or NA) */
+    uint32_t idcode;
+
+    /* Instruction register length in bits */
+    int irlen;
+
+    /* Name of node */
+    const char *name;
+
+    /* Parent node */
+    js_node_t **parent;
+
+    /* Child nodes */
+    js_node_t **child_list;
+    unsigned int child_count;
+};
+
+
+/*
+ * JTAG states
+ *
+ * To simply the interface only a subset of the JTAG states are make
+ * accessible.
+ */
+/*typedef enum {
+    JS_RESET,
+    JS_IDLE,
+    JS_SHIFT_DR,
+    JS_PAUSE_DR,
+    JS_SHIFT_IR,
+    JS_PAUSE_IR,
+    JS_STATE_MAX
+} js_state_t;*/
+typedef enum {
+    JS_RESET,
+    JS_IDLE,
+    JS_DRSELECT,
+    JS_DRCAPTURE,
+    JS_DRSHIFT,
+    JS_DREXIT1,
+    JS_DRPAUSE,
+    JS_DREXIT2,
+    JS_DRUPDATE,
+    JS_IRSELECT,
+    JS_IRCAPTURE,
+    JS_IRSHIFT,
+    JS_IREXIT1,
+    JS_IRPAUSE,
+    JS_IREXIT2,
+    JS_IRUPDATE,
+    JS_STATE_MAX
+} js_state_t;
+
+
+
+/*
+ * JTAG command sequence object
+ *
+ * Commands are added to this object for later execution.
+ */
+struct js_command_sequence_struct {
+    js_node_t *node;
+};
+
+
+/***********************************************************************
+ * JTAG server implementation specific functions
+ ***********************************************************************/
+
+/*
+ * Get list of available JTAG ports supported by this server
+ */
+extern int js_get_port_descr_list(
+    js_server_t *server,
+    js_port_descr_t **port_listp);
+
+/*
+ * Open a specific JTAG port for this server instance
+ */
+extern int js_open_port(
+    js_server_t *server,
+    js_port_descr_t *port_descr,
+    js_port_t **port);
+
+/*
+ * Delete server instance
+ */
+extern void js_deinit_server(
+    js_server_t *server);
+
+/*
+ * Get property value
+ */
+extern int js_get_property(
+    js_port_t *port,
+    js_property_kind_t kind,
+    js_property_value_t *valuep);
+
+/*
+ * Set property value
+ */
+extern int js_set_property(
+    js_port_t *port,
+    js_property_kind_t kind,
+    js_property_value_t value);
+
+/*
+ * Execute pending commands
+ */
+extern int js_run_command_sequence(
+    js_command_sequence_t *commands);
+
+/*
+ * Open a specific JTAG port for this server instance
+ */
+extern int js_close_port(
+        js_port_t *port);
+
+
+/***********************************************************************
+ * JTAG server library functions
+ ***********************************************************************/
+
+/*
+ * Retrieve information about the last error as a string.
+ *
+ * Returns NULL if no error occured since last call to
+ * set_last_error(server, NULL).
+ */
+const char *js_get_last_error(
+    js_server_t *server);
+
+
+/*
+ * Set error information
+ */
+void js_set_last_error(
+    js_server_t *server,
+    const char *fmt,
+    ...);
+
+
+/*
+ * Allocate command sequence object
+ */
+extern js_command_sequence_t *js_create_command_sequence(
+    js_node_t *node);
+
+
+/*
+ * CLear command sequence
+ *
+ * This function allows a command sequence object to be reused for a
+ * difference sequence.
+ */
+extern int js_clear_command_sequence(
+    js_command_sequence_t *cmdseq);
+
+
+/*
+ * Delete command sequence
+ */
+extern int js_delete_command_sequence(
+    js_command_sequence_t *cmdseq);
+
+
+/*
+ * Adds command to move JTAG state machine to <state> and cycle TCK
+ * <clock> times.  The <clock> argument is only applicable for when
+ * <state> is one of the stable states JS_RESET, JS_IDLE, JS_PAUSE_IR
+ * or JS_PAUSE_DR.
+ */
+extern int js_add_state_change(
+    js_command_sequence_t *cmdseq,
+    js_state_t state,
+    unsigned int clocks);
+
+/*
+ * Adds command to
+ *  1. move state machine to either JS_SHIFT_IR if (<flags> &
+ *     JS_TO_IR) != 0 or JS_SHIFT_DR if (<flags> & JS_TO_IR) == 0,
+ *  2. shift <bits> number of bits in from tdi_buffer to TDI and out
+ *     from TDO to tdo_buffer, and
+ *  3. move state machine to <state>.
+ *
+ * If <tdi_buffer> is NULL then <bits> number of ones if (<flags> &
+ *     JS_ONES) != 0 or zeroes if (<flags> & JS_ONES) == 0 are shifted
+ *     to TDI.
+ *
+ * If <tdo_buffer> is NULL then TDO bits are ignored.
+ *
+ * Both state transtions are optional if the state machine is
+ * already in the correct state.
+ */
+enum {
+    JS_TO_IR = 1,
+    JS_ONES = 2
+};
+extern int js_add_shift(
+    js_command_sequence_t *cmdseq,
+    unsigned int flags,
+    size_t bits,
+    unsigned char **tdi_buffer,
+    unsigned char **tdo_buffer,
+    js_state_t state);
+
+
+/*
+ * Auto detect TAPs on scan chain.
+ *
+ * This typically involes a reset of the scan chain followed by
+ * reading data registers.
+ *
+ * The result is allocated using malloc() and the caller is resposible
+ * for freeing the buffer when it is no longer needed.
+ */
+extern int js_detect_taps(
+    js_port_t *port,
+    uint32_t **resultp);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* XILSKEY_JS_H */
diff --git a/lib/sw_services/xilskey/src/xilskey_jscmd.c b/lib/sw_services/xilskey/src/xilskey_jscmd.c
new file mode 100644
index 00000000..ee0eadc5
--- /dev/null
+++ b/lib/sw_services/xilskey/src/xilskey_jscmd.c
@@ -0,0 +1,1810 @@
+/******************************************************************************
+*
+* 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);
+
+}
\ No newline at end of file
diff --git a/lib/sw_services/xilskey/src/xilskey_jscmd.h b/lib/sw_services/xilskey/src/xilskey_jscmd.h
new file mode 100644
index 00000000..0bf73228
--- /dev/null
+++ b/lib/sw_services/xilskey/src/xilskey_jscmd.h
@@ -0,0 +1,166 @@
+/******************************************************************************
+*
+* 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.
+*
+******************************************************************************/
+
+#ifndef XILSKEY_JSCMD_H
+#define XILSKEY_JSCMD_H
+
+#include "xilskey_js.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern js_server_t *js_init_zynq(void);
+void initGPIO ();
+int jtag_setPreAndPostPads (js_port_t *port_arg, int irPrePadBits, int irPostPadBits, int drPrePadBits, int drPostPadBits);
+int jtag_navigate (js_port_t *port, js_state_t state);
+int jtag_shift (js_port_t *port, unsigned char mode, int bits, unsigned char* wrBuffer, unsigned char* rdBuffer, js_state_t state);
+unsigned int g_mio_jtag_tdi;
+unsigned int g_mio_jtag_tdo;
+unsigned int g_mio_jtag_tck;
+unsigned int g_mio_jtag_tms;
+unsigned int g_mio_jtag_mux_sel;
+unsigned int g_mux_sel_def_val;
+
+// MIO assignments
+#define MIO_TDI    			g_mio_jtag_tdi
+#define MIO_TDO    			g_mio_jtag_tdo
+#define MIO_TCK    			g_mio_jtag_tck
+#define MIO_TMS    			g_mio_jtag_tms
+#define MIO_MUX_SELECT		g_mio_jtag_mux_sel
+
+#define ZYNQ_TAP_IR_LENGTH		(6)
+#define ZYNQ_DAP_IR_LENGTH		(4)
+
+#define ATOMIC_DR_SCAN                 0x40
+#define ATOMIC_IR_SCAN                 0x50
+
+#define GPIO_BASE_ADDR		0xF8000700
+#define GPIO_MASK_VAL		0x00003FFFU
+#define GPIO_TDI_VAL		0x00001300U
+#define GPIO_TDO_VAL		0x00001301U
+#define GPIO_TCK_VAL		0x00001300U
+#define GPIO_TMS_VAL		0x00001300U
+#define GPIO_MUX_SEL_VAL	0x00001300U
+
+/**
+ * XEfusePl is the PL eFUSE driver instance. Using this
+ * structure, user can define the eFUSE bits to be
+ * blown.
+ */
+typedef struct {
+	/**
+	 * Following are the FUSE CNTRL bits[1:5, 8-10]
+	 */
+
+	/**
+	 * If XTRUE then part has to be power cycled to be able to be reconfigured
+	 */
+	u32	ForcePowerCycle;
+	/**
+	 * If XTRUE will disable eFUSE write to FUSE_AES and FUSE_USER blocks
+	 */
+	u32 KeyWrite;
+	/**
+	 * If XTRUE will disable eFUSE read to FUSE_AES block and also disables eFUSE write to FUSE_AES and FUSE_USER blocks
+	 */
+	u32 AESKeyRead;
+	/**
+	 * If XTRUE will disable eFUSE read to FUSE_USER block and also disables eFUSE write to FUSE_AES and FUSE_USER blocks
+	 */
+	u32 UserKeyRead;
+	/**
+	 * If XTRUE will disable eFUSE write to FUSE_CNTRL block
+	 */
+	u32	CtrlWrite;
+	/**
+	 * If XTRUE will force eFUSE key to be used if booting Secure Image
+	 */
+	u32 AESKeyExclusive;
+	/**
+	 * If XTRUE then permanently sets the Zynq ARM DAP controller in bypass mode
+	 */
+	u32 JtagDisable;
+	/**
+	 * If XTRUE will force to use Secure boot with eFUSE key only
+	 */
+	u32 UseAESOnly;
+	/**
+	 * Following is the define to select if the user wants to select AES key and USER low key OR USER high key or BOTH
+	 */
+	u32 ProgAESandUserLowKey;
+	u32 ProgUserHighKey;
+
+	/**
+	 * This is the REF_CLK value in Hz
+	 */
+	/*u32	RefClk;*/
+	/**
+	 * This is for the aes_key value
+	 */
+	u8 AESKey[XSK_EFUSEPL_AES_KEY_SIZE_IN_BYTES];
+	/**
+	 * This is for the user_key value
+	 */
+	u8 UserKey[XSK_EFUSEPL_USER_KEY_SIZE_IN_BYTES];
+	/**
+	 * TDI MIO Pin Number
+	 */
+	u32 JtagMioTDI;
+	/**
+	 * TDO MIO Pin Number
+	 */
+	u32 JtagMioTDO;
+	/**
+	 * TCK MIO Pin Number
+	 */
+	u32 JtagMioTCK;
+	/**
+	 * TMS MIO Pin Number
+	 */
+	u32 JtagMioTMS;
+	/**
+	 * MUX Selection MIO Pin Number
+	 */
+	u32 JtagMioMuxSel;
+	/**
+	 * Value on the MUX Selection line
+	 */
+	u32	JtagMuxSelLineDefVal;
+
+}XilSKey_EPl;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /*XILSKEY_JSCMD_H*/
diff --git a/lib/sw_services/xilskey/src/xilskey_jslib.c b/lib/sw_services/xilskey/src/xilskey_jslib.c
new file mode 100644
index 00000000..1bdd6c5f
--- /dev/null
+++ b/lib/sw_services/xilskey/src/xilskey_jslib.c
@@ -0,0 +1,441 @@
+/******************************************************************************
+*
+* 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.
+*
+******************************************************************************/
+
+#include <stdio.h>
+#include <stdarg.h>
+#include <string.h>
+#include <assert.h>
+#include "xilskey_jslib.h"
+
+#define MAX_TAPS 16
+
+
+js_lib_state_info_t js_lib_state_info[] = {
+    /* JS_RESET */
+    {
+        "reset",
+        { 0x01, 0x00, 0x02, 0x0a, 0x06, 0x16 },
+        {    1,    1,    4,    5,    5,    6 },
+        JS_RESET
+    },
+
+    /* JS_IDLE */
+    {
+        "idle",
+        { 0x07, 0x00, 0x01, 0x05, 0x03, 0x0b },
+        {    3,    1,    3,    4,    4,    5 },
+        JS_IDLE
+    },
+
+    /* JS_SHIFT_DR */
+    {
+        "shift dr",
+        { 0x1f, 0x03, 0x05, 0x01, 0x0f, 0x2f },
+        {    5,    3,    4,    2,    6,    7 },
+        JS_DRPAUSE
+    },
+
+    /* JS_PAUSE_DR */
+    {
+        "pause dr",
+        { 0x1f, 0x03, 0x01, 0x00, 0x0f, 0x2f },
+        {    5,    3,    2,    1,    6,    7 },
+        JS_DRPAUSE
+    },
+
+    /* JS_SHIFT_IR */
+    {
+        "shift ir",
+        { 0x1f, 0x03, 0x07, 0x01, 0x05, 0x01 },
+        {    5,    4,    5,    6,    4,    2 },
+        JS_IRPAUSE
+    },
+
+    /* JS_PAUSE_IR */
+    {
+        "pause ir",
+        { 0x1f, 0x03, 0x07, 0x17, 0x01, 0x00 },
+        {    5,    3,    5,    6,    2,    1 },
+        JS_IRPAUSE
+    }
+};
+
+
+const char *js_get_last_error(
+    js_server_t *server)
+{
+    js_lib_server_t *js = (js_lib_server_t *)server;
+
+    if (js->last_error[0] == '\0')
+        return NULL;
+    return js->last_error;
+}
+
+
+void js_set_last_error(
+    js_server_t *server,
+    const char *fmt,
+    ...)
+{
+    js_lib_server_t *js = (js_lib_server_t *)server;
+    va_list ap;
+
+    va_start(ap, fmt);
+    vsnprintf(js->last_error, sizeof js->last_error, fmt, ap);
+    va_end(ap);
+}
+
+
+js_command_sequence_t *js_create_command_sequence(
+    js_node_t *node)
+{
+    js_lib_command_sequence_t *cmds;
+
+    cmds = (js_lib_command_sequence_t *)malloc(sizeof *cmds);
+    if (cmds == NULL)
+        return NULL;
+    memset(cmds, 0, sizeof *cmds);
+    cmds->base.node = node;
+    cmds->cmd_size = sizeof *cmds->cmd_list;
+    return &cmds->base;
+}
+
+
+static void free_buffers(
+    js_lib_command_buffer_t *buf)
+{
+    while (buf != NULL) {
+        js_lib_command_buffer_t *next = buf->next;
+        free(buf);
+        buf = next;
+    }
+}
+
+
+int js_clear_command_sequence(
+    js_command_sequence_t *cmdseq)
+{
+    js_lib_command_sequence_t *cmds = (js_lib_command_sequence_t *)cmdseq;
+    js_lib_command_buffer_t *buf = cmds->buf_head;
+
+    cmds->cmd_count = 0;
+    if (buf) {
+        /* Free all buffers except to first one.  Keep the first one
+         * since it is the larges and can be reused for future
+         * commands */
+        free_buffers(buf->next);
+        buf->next = NULL;
+        buf->buf_free = buf->buf_start;
+    }
+    return 0;
+}
+
+
+int js_delete_command_sequence(
+    js_command_sequence_t *cmdseq)
+{
+    js_lib_command_sequence_t *cmds = (js_lib_command_sequence_t *)cmdseq;
+    if (cmds->cmd_list)
+        free(cmds->cmd_list);
+    free_buffers(cmds->buf_head);
+    free(cmds);
+    return 0;
+}
+
+
+static js_lib_command_t *get_command(
+    js_lib_command_sequence_t *cmds)
+{
+    js_lib_command_t *list = cmds->cmd_list;
+    unsigned int count = cmds->cmd_count;
+
+    assert(cmds->cmd_size >= sizeof *list);
+    if (count == cmds->cmd_max) {
+        unsigned int max = count ? count * 2 : 1;
+        list = (js_lib_command_t *)realloc(list, max * cmds->cmd_size);
+        if (list == NULL) {
+            js_set_last_error(cmds->base.node->port->server, "end of memory");
+            return NULL;
+        }
+        cmds->cmd_list = list;
+        cmds->cmd_max = max;
+    }
+    cmds->cmd_count = count + 1;
+    return (js_lib_command_t *)((char *)list + count * cmds->cmd_size);
+}
+
+
+int js_add_state_change(
+    js_command_sequence_t *cmdseq,
+    js_state_t state,
+    unsigned int clocks)
+{
+    js_lib_command_sequence_t *cmds = (js_lib_command_sequence_t *)cmdseq;
+    js_lib_command_t *cmd = get_command(cmds);
+    if (cmd == NULL)
+        return -1;
+    if (clocks != 0 && js_lib_state_info[state].stable_state != state) {
+        js_set_last_error(cmds->base.node->port->server, "non zero clocks in unstable state");
+        return -1;
+    }
+    cmd->kind = JS_CMD_SET_STATE;
+    cmd->state = state;
+    cmd->count = clocks;
+    cmd->tdi_buf = NULL;
+    cmd->tdo_buf = NULL;
+    return 0;
+}
+
+
+static unsigned char *get_buffer(
+    js_lib_command_sequence_t *cmds,
+    size_t size)
+{
+    js_lib_command_buffer_t *buf = cmds->buf_head;
+    unsigned char *ret;
+
+    assert(buf == NULL || buf->buf_start <= buf->buf_free);
+    assert(buf == NULL || buf->buf_free < buf->buf_end);
+    if (buf == NULL || buf->buf_free + size > buf->buf_end) {
+        size_t buf_size = buf ? buf->buf_end - buf->buf_start : 1;
+        while (buf_size < size * 2)
+            buf_size *= 2;
+        buf = (js_lib_command_buffer_t *)malloc(buf_size + sizeof *buf);
+        if (buf == NULL)
+            return NULL;
+        buf->buf_free = buf->buf_start;
+        buf->buf_end = buf->buf_start + buf_size;
+        buf->next = cmds->buf_head;
+        cmds->buf_head = buf;
+    }
+    ret = buf->buf_free;
+    buf->buf_free += size;
+    return ret;
+}
+
+
+int js_add_shift(
+    js_command_sequence_t *cmdseq,
+    unsigned int flags,
+    size_t bits,
+    unsigned char **tdi_buffer,
+    unsigned char **tdo_buffer,
+    js_state_t state)
+{
+    js_lib_command_sequence_t *cmds = (js_lib_command_sequence_t *)cmdseq;
+    js_lib_command_t *cmd = get_command(cmds);
+    if (cmd == NULL)
+        return -1;
+    if (bits <= 0) {
+        js_set_last_error(cmds->base.node->port->server, "bits argument must be > 0");
+        return -1;
+    }
+    cmd->kind = JS_CMD_SHIFT;
+    cmd->flags = flags;
+    cmd->state = state;
+    cmd->count = bits;
+    if (tdi_buffer != NULL) {
+        *tdi_buffer = cmd->tdi_buf = get_buffer(cmds, (bits + 7) / 8 + 2);
+    } else {
+        cmd->tdi_buf = NULL;
+    }
+    if (tdo_buffer != NULL) {
+        *tdo_buffer = cmd->tdo_buf = get_buffer(cmds, (bits + 7) / 8 + 2);
+    } else {
+        cmd->tdo_buf = NULL;
+    }
+    return 0;
+}
+
+
+int js_detect_taps(
+    js_port_t *port,
+    uint32_t **resultp)
+{
+    js_command_sequence_t *cmds;
+    unsigned char *dummycodes;
+    unsigned char *idcodes;
+    uint32_t *result = NULL;
+    int max = 0;
+    int ind = 0;
+    int i;
+
+    cmds = js_create_command_sequence(port->root_node);
+    if (cmds == NULL)
+        return -1;
+
+    if (js_add_state_change(cmds, JS_RESET, 0) < 0 ||
+        js_add_shift(cmds, 0, MAX_TAPS * 4 * 8, &dummycodes, &idcodes, JS_IDLE) < 0)
+        goto return_error;
+
+    for (i = 0; i < MAX_TAPS; i += 4) {
+        dummycodes[i+0] = (JS_DUMMY_IDCODE) & 0xff;
+        dummycodes[i+1] = (JS_DUMMY_IDCODE >> 8) & 0xff;
+        dummycodes[i+2] = (JS_DUMMY_IDCODE >> 16) & 0xff;
+        dummycodes[i+3] = (JS_DUMMY_IDCODE >> 24) & 0xff;
+    }
+
+    if (js_run_command_sequence(cmds) < 0)
+        goto return_error;
+
+    i = 0;
+    while (i < MAX_TAPS * 4 * 8) {
+        int lsb = (idcodes[i / 8] >> (i % 8)) & 1;
+        uint32_t idcode;
+        if (lsb) {
+            int j;
+            idcode = lsb;
+            i++;
+            for (j = 1; j < 32; j++) {
+                lsb = (idcodes[i / 8] >> (i % 8)) & 1;
+                idcode |= (uint32_t)lsb << j;
+                i++;
+            }
+            if (idcode == JS_DUMMY_IDCODE)
+                break;
+        } else {
+            /* TAP in BYPASS mode */
+            idcode = JS_DUMMY_IDCODE;
+            i++;
+        }
+
+        if (ind == max) {
+            uint32_t *new_result;
+            max = max ? max * 2 : 1;
+            new_result = (uint32_t *)realloc(result, max * sizeof *result);
+            if (new_result == NULL) {
+                free(result);
+                goto return_error;
+            }
+            result = new_result;
+        }
+        result[ind++] = idcode;
+    }
+    js_delete_command_sequence(cmds);
+    *resultp = result;
+    return ind;
+
+return_error:
+    js_delete_command_sequence(cmds);
+    return -1;
+}
+
+
+int js_get_port_descr_list(
+    js_server_t *server,
+    js_port_descr_t **port_listp)
+{
+    js_lib_server_t *js = (js_lib_server_t *)server;
+
+    return js->get_port_descr_list(js, port_listp);
+}
+
+
+int js_open_port(
+    js_server_t *server,
+    js_port_descr_t *port_descr,
+    js_port_t **port)
+{
+    js_lib_server_t *js = (js_lib_server_t *)server;
+    js_lib_port_t *result;
+    int ret;
+
+    ret = js->open_port(js, port_descr, &result);
+    *port = (js_port_t *)result;
+    return ret;
+}
+
+
+void js_deinit_server(
+    js_server_t *server)
+{
+    js_lib_server_t *js = (js_lib_server_t *)server;
+
+    return js->deinit_server(js);
+}
+
+
+int js_get_property(
+    js_port_t *port_arg,
+    js_property_kind_t kind,
+    js_property_value_t *valuep)
+{
+    js_lib_port_t *port = (js_lib_port_t *)port_arg;
+
+    return port->get_property(port, kind, valuep);
+}
+
+
+int js_set_property(
+    js_port_t *port_arg,
+    js_property_kind_t kind,
+    js_property_value_t value)
+{
+    js_lib_port_t *port = (js_lib_port_t *)port_arg;
+
+    return port->set_property(port, kind, value);
+}
+
+
+int js_run_command_sequence(
+    js_command_sequence_t *commands)
+{
+    js_lib_command_sequence_t *cmds = (js_lib_command_sequence_t *)commands;
+    js_lib_port_t *port = (js_lib_port_t *)commands->node->port;
+
+    return port->run_command_sequence(cmds);
+}
+
+
+int js_close_port(
+        js_port_t *port_arg)
+{
+    js_lib_port_t *port = (js_lib_port_t *)port_arg;
+
+    return port->close_port(port);
+}
+
+
+int js_lib_normalize_command_sequence(
+    js_lib_command_sequence_t *dest_seq,
+    js_lib_command_sequence_t *src_seq)
+{
+    js_lib_command_t *src_cmd = src_seq->cmd_list;
+    js_lib_command_t *src_end = src_cmd + src_seq->cmd_count;
+
+    while (src_cmd < src_end) {
+        js_lib_command_t *new_cmd = get_command(dest_seq);
+        *new_cmd = *src_cmd;
+        src_cmd++;
+    }
+    return 0;
+}
diff --git a/lib/sw_services/xilskey/src/xilskey_jslib.h b/lib/sw_services/xilskey/src/xilskey_jslib.h
new file mode 100644
index 00000000..7a1b03a0
--- /dev/null
+++ b/lib/sw_services/xilskey/src/xilskey_jslib.h
@@ -0,0 +1,219 @@
+/******************************************************************************
+*
+* 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.
+*
+******************************************************************************/
+
+/*
+ * JTAG server implementation library interface
+ *
+ * This library interface is intended to be use by JTAG server
+ * implementations only, i.e. not used by JTAG server clients.
+ */
+
+#include "xilskey_js.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+typedef struct js_lib_server_struct js_lib_server_t;
+typedef struct js_lib_port_struct js_lib_port_t;
+typedef struct js_lib_command_sequence_struct js_lib_command_sequence_t;
+typedef struct js_lib_command_struct js_lib_command_t;
+typedef struct js_lib_command_buffer_struct js_lib_command_buffer_t;
+typedef struct js_lib_state_info_struct js_lib_state_info_t;
+
+
+
+/*
+ * JTAG server object
+ *
+ * Server instances are created by implementation specific create
+ * functions, typically named js_create_<implementation-name>.
+ *
+ * TODO: Add a way to schedule a command sequence to be repeated at
+ * regular intervals.  This is useful to poll for events, like
+ * breakpoint hit.
+ */
+struct js_server_struct {
+    char dummy;
+};
+
+
+/*
+ * JTAG server library object
+ */
+struct js_lib_server_struct {
+    /* Public part of object */
+    js_server_t base;
+
+    /* See js_get_port_descr_list() */
+    int (*get_port_descr_list)(
+        js_lib_server_t *server,
+        js_port_descr_t **port_listp);
+
+    /* See js_open_port() */
+    int (*open_port)(
+        js_lib_server_t *server,
+        js_port_descr_t *port_descr,
+        js_lib_port_t **port);
+
+    /* See js_deinit_server() */
+    void (*deinit_server)(
+        js_lib_server_t *server);
+
+    /* Error of last command */
+    char last_error[100];
+};
+
+struct js_lib_port_struct {
+    /* Base class - must be first. */
+    js_port_t base;
+
+    /* See js_get_property() */
+    int (*get_property)(
+        js_lib_port_t *port,
+        js_property_kind_t kind,
+        js_property_value_t *valuep);
+
+    /* See js_set_property() */
+    int (*set_property)(
+        js_lib_port_t *port,
+        js_property_kind_t kind,
+        js_property_value_t value);
+
+    /* See js_run_command_sequence() */
+    int (*run_command_sequence)(
+        js_lib_command_sequence_t *commands);
+
+    /* See js_close_port() */
+    int (*close_port)(
+        js_lib_port_t *port);
+};
+
+
+struct js_lib_command_buffer_struct {
+    js_lib_command_buffer_t *next;
+
+    /* First available byte in buffer */
+    unsigned char *buf_free;
+
+    /* End of buffer */
+    unsigned char *buf_end;
+
+    /* Start of buffer (must be last) */
+    unsigned char buf_start[1];
+};
+
+
+/*
+ * JTAG command sequence library object
+ */
+struct js_lib_command_sequence_struct {
+    /* Client visible part */
+    js_command_sequence_t base;
+
+    /* Array of commands */
+    js_lib_command_t *cmd_list;
+
+    /* Count of added commands */
+    unsigned int cmd_count;
+
+    /* Command list capacity */
+    unsigned int cmd_max;
+
+    /* Size of command objects  */
+    unsigned int cmd_size;
+
+    /* Command buffer pool */
+    js_lib_command_buffer_t *buf_head;
+};
+
+
+/*
+ * JTAG command object
+ *
+ * Command object are added to JTAG command sequence object using
+ * js_add_* functions.
+ *
+ * TODO: Add commands to get/set GPIO pins, conditional execution and
+ * loops.
+ */
+typedef enum {
+    JS_CMD_SET_STATE,
+    JS_CMD_SHIFT
+} js_command_kind_t;
+
+struct js_lib_command_struct {
+    /* Command to execute */
+    js_command_kind_t kind;
+
+    /* Flags for command */
+    unsigned int flags;
+
+    /* State after command */
+    js_state_t state;
+
+    /* Command specific count */
+    size_t count;
+
+    /* TDI buffer pointer */
+    unsigned char *tdi_buf;
+
+    /* TDO buffer pointer */
+    unsigned char *tdo_buf;
+};
+
+
+struct js_lib_state_info_struct {
+    /* Name of state */
+    const char *name;
+
+    /* TMS bits to move to other state */
+    unsigned char state_tms[JS_STATE_MAX];
+
+    /* Clocks to move to other state */
+    unsigned char state_clk[JS_STATE_MAX];
+
+    /* Nearest stable state */
+    js_state_t stable_state;
+};
+
+
+extern js_lib_state_info_t js_lib_state_info[JS_STATE_MAX];
+
+extern int js_lib_normalize_command_sequence(
+    js_lib_command_sequence_t *dest,
+    js_lib_command_sequence_t *src);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/lib/sw_services/xilskey/src/xilskey_jtag.h b/lib/sw_services/xilskey/src/xilskey_jtag.h
new file mode 100644
index 00000000..de994267
--- /dev/null
+++ b/lib/sw_services/xilskey/src/xilskey_jtag.h
@@ -0,0 +1,45 @@
+/******************************************************************************
+*
+* 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.
+*
+******************************************************************************/
+
+#ifndef XILSKEY_JTAG_H
+#define XILSKEY_JTAG_H
+
+#include "xil_types.h"
+
+void JtagInitGpio();
+void GpioConfig(volatile unsigned long *addr, unsigned long mask, unsigned long val);
+int JtagServerInit(XilSKey_EPl *PlInstancePtr);
+int JtagValidateMioPins(void);
+void JtagWrite(unsigned char row, unsigned char bit);
+void JtagRead(unsigned char row, unsigned int * row_data, unsigned char marginOption);
+
+#endif /*XILSKEY_JTAG_H*/
diff --git a/lib/sw_services/xilskey/src/xilskey_utils.c b/lib/sw_services/xilskey/src/xilskey_utils.c
new file mode 100644
index 00000000..dd0cd301
--- /dev/null
+++ b/lib/sw_services/xilskey/src/xilskey_utils.c
@@ -0,0 +1,775 @@
+/******************************************************************************
+*
+* 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_utils.c
+ *
+ *
+ * @note	None.
+ *
+ *
+ * MODIFICATION HISTORY:
+ *
+* Ver   Who  	Date     Changes
+* ----- ---- 	-------- --------------------------------------------------------
+* 1.00a rpoolla 04/26/13 First release
+* 2.00  hk      22/01/14 Corrected PL voltage checks to VCCINT and VCCAUX.
+*                        CR#768077
+ *
+ *****************************************************************************/
+
+/***************************** Include Files ********************************/
+#include "xil_io.h"
+#include "xil_types.h"
+#include "xilskey_utils.h"
+/************************** Constant Definitions ****************************/
+
+/**************************** Type Definitions ******************************/
+
+/***************** Macros (Inline Functions) Definitions ********************/
+
+/************************** Variable Definitions ****************************/
+static XAdcPs XAdcInst;     /**< XADC driver instance */
+u16 XAdcDeviceId;	/**< XADC Device ID */
+u32 TimerTicksfor100ns; /**< Global Variable to store ticks/100ns*/
+/************************** Function Prototypes *****************************/
+static u32 XilSKey_EfusePs_ConvertCharToNibble (char InChar, u8 *Num);
+/***************************************************************************/
+/**
+* This function is used to initialize the XADC driver
+*
+* @return
+* 		- XST_SUCCESS in case of no errors.
+* 		- XSK_EFUSEPS_ERROR_XADC_CONFIG Error occurred with XADC config.
+* 		- XSK_EFUSEPS_ERROR_XADC_INITIALIZE Error occurred while XADC initialization
+* 		- XSK_EFUSEPS_ERROR_XADC_SELF_TEST Error occurred in XADC self test.
+*
+* TDD Cases:
+*
+****************************************************************************/
+
+u32 XilSKey_EfusePs_XAdcInit (void )
+{
+	u32 Status;
+	XAdcPs_Config *ConfigPtr;
+	XAdcPs *XAdcInstPtr = &XAdcInst;
+
+	/**
+	 * specify the Device ID that is
+	 * generated in xparameters.h
+	 */
+	XAdcDeviceId=XADC_DEVICE_ID;
+
+	/**
+	 * Initialize the XAdc driver.
+	 */
+	ConfigPtr = XAdcPs_LookupConfig(XAdcDeviceId);
+	if (NULL == ConfigPtr) {
+		return XSK_EFUSEPS_ERROR_XADC_CONFIG;
+	}
+
+	Status = XAdcPs_CfgInitialize(XAdcInstPtr, ConfigPtr,
+			ConfigPtr->BaseAddress);
+	if (Status != XST_SUCCESS) {
+		return XSK_EFUSEPS_ERROR_XADC_INITIALIZE;
+	}
+	/**
+	 * Self Test the XADC/ADC device
+	 */
+	Status = XAdcPs_SelfTest(XAdcInstPtr);
+	if (Status != XST_SUCCESS) {
+		return XSK_EFUSEPS_ERROR_XADC_SELF_TEST;
+	}
+
+	/**
+	 * Disable the Channel Sequencer before configuring the Sequence
+	 * registers.
+	 */
+	XAdcPs_SetSequencerMode(XAdcInstPtr, XADCPS_SEQ_MODE_SAFE);
+
+	return XST_SUCCESS;
+
+}
+
+/***************************************************************************/
+/**
+* This function is used to copy the min, max and current value of the
+* temperature and voltage which are read from XADC.
+*
+* @param XAdcInstancePtr Pointer to the XSKEfusePs_XAdc. User has to
+* 		 fill the VType to specify the type of voltage. Valid values
+* 		 for VType are
+* 		 	- XSK_EFUSEPS_VPINT
+* 		 	- XSK_EFUSEPS_VPDRO
+* 		 	- XSK_EFUSEPS_VPAUX
+*                       - XSK_EFUSEPS_VINT
+*                       - XSK_EFUSEPS_VAUX
+*
+* @return none
+*
+* TDD Cases:
+*
+****************************************************************************/
+
+void XilSKey_EfusePs_XAdcReadTemperatureAndVoltage(XSKEfusePs_XAdc *XAdcInstancePtr)
+{
+	XAdcPs *XAdcInstPtr = &XAdcInst;
+	u8 V, VMin, VMax;
+
+
+	if (NULL == XAdcInstPtr) {
+		return;
+	}
+
+	/**
+	 * Read the on-chip Temperature Data (Current/Maximum/Minimum)
+	 * from the ADC data registers.
+	 */
+	XAdcInstancePtr->Temp = XAdcPs_GetAdcData(XAdcInstPtr, XADCPS_CH_TEMP);
+
+	XAdcInstancePtr->TempMin =
+			XAdcPs_GetMinMaxMeasurement(XAdcInstPtr, XADCPS_MIN_TEMP);
+
+	XAdcInstancePtr->TempMax =
+			XAdcPs_GetMinMaxMeasurement(XAdcInstPtr, XADCPS_MAX_TEMP);
+
+	xeFUSE_printf(XSK_EFUSE_DEBUG_GENERAL,
+				"Read Temperature Value: %0x -> %d in Centigrades \n",
+				XAdcInstancePtr->Temp,
+				(int )XAdcPs_RawToTemperature(XAdcInstancePtr->Temp));
+
+	/**
+	 * Read the VccPint Voltage Data (Current/Maximum/Minimum) from the
+	 * ADC data registers.
+	 */
+
+	switch (XAdcInstancePtr->VType)
+	{
+	case XSK_EFUSEPS_VINT:
+		V = XADCPS_CH_VCCINT;
+		VMax = XADCPS_MAX_VCCINT;
+		VMin = XADCPS_MIN_VCCINT;
+		break;
+
+	case XSK_EFUSEPS_VAUX:
+		V = XADCPS_CH_VCCAUX;
+		VMax = XADCPS_MAX_VCCAUX;
+		VMin = XADCPS_MIN_VCCAUX;
+		break;
+
+	case XSK_EFUSEPS_VPAUX:
+		V = XADCPS_CH_VCCPAUX;
+		VMax = XADCPS_MAX_VCCPAUX;
+		VMin = XADCPS_MIN_VCCPAUX;
+		break;
+
+	case XSK_EFUSEPS_VPDRO:
+		V = XADCPS_CH_VCCPDRO;
+		VMax = XADCPS_MAX_VCCPDRO;
+		VMin = XADCPS_MIN_VCCPDRO;
+		break;
+
+	case XSK_EFUSEPS_VPINT:
+	default:
+		V = XADCPS_CH_VCCPINT;
+		VMax = XADCPS_MAX_VCCPINT;
+		VMin = XADCPS_MIN_VCCPINT;
+		break;
+	}
+
+	XAdcInstancePtr->V = XAdcPs_GetAdcData(XAdcInstPtr, V);
+	XAdcInstancePtr->VMin = XAdcPs_GetMinMaxMeasurement(XAdcInstPtr, VMin);
+	XAdcInstancePtr->VMax = XAdcPs_GetMinMaxMeasurement(XAdcInstPtr, VMax);
+
+	xeFUSE_printf(XSK_EFUSE_DEBUG_GENERAL,
+				"Read Voltage Value: %0x -> %d in Volts \n",
+				XAdcInstancePtr->V,
+				(int )XAdcPs_RawToVoltage(XAdcInstancePtr->V));
+
+	return;
+}
+
+/****************************************************************************/
+/**
+*
+* Initializes the global timer & starts it.
+* Calculates the timer ticks for 1us.
+*
+*
+*
+* @param	RefClk - reference clock
+*
+* @return
+*
+*	None
+*
+* @note		None.
+*
+*****************************************************************************/
+void XilSKey_Efuse_StartTimer(u32 RefClk)
+{
+		u32 arm_pll_fdiv,arm_clk_divisor;
+		TimerTicksfor100ns = 0;
+		/**
+		 *  Extract PLL FDIV value from ARM PLL Control Register
+		 */
+		arm_pll_fdiv = (Xil_In32(XSK_ARM_PLL_CTRL_REG)>>12 & 0x7F);
+		/**
+		 *  Extract Clock divisor value from ARM Clock Control Register
+		 */
+		arm_clk_divisor = (Xil_In32(XSK_ARM_CLK_CTRL_REG)>>8 & 0x3F);
+		/**
+		 * Calculate the Timer ticks per 100ns
+		 */
+		TimerTicksfor100ns =
+				(((RefClk * arm_pll_fdiv)/arm_clk_divisor)/2)/10000000;
+        /**
+         * Disable the Timer counter
+         */
+        Xil_Out32(XSK_GLOBAL_TIMER_CTRL_REG,0);
+        /**
+         * Write the lower 32 bit timer counter register.
+         */
+        Xil_Out32(XSK_GLOBAL_TIMER_COUNT_REG_LOW, 0x0);
+        /**
+         * Write the upper 32 bit timer counter register.
+         */
+        Xil_Out32(XSK_GLOBAL_TIMER_COUNT_REG_HIGH, 0x0);
+        /**
+         * Enable the Timer counter
+         */
+        Xil_Out32(XSK_GLOBAL_TIMER_CTRL_REG,0x1);
+}
+
+/****************************************************************************/
+/**
+*
+* Returns the timer ticks from start of timer to till now.
+*
+* @return
+*
+*	t - Timer ticks lapsed till now.
+*
+* @note		None.
+*
+*****************************************************************************/
+
+u64 XilSKey_Efuse_GetTime(void)
+{
+        volatile u32 t_hi=0, t_lo=0;
+        volatile u64 t=0;
+        do {
+                t_hi = Xil_In32(XSK_GLOBAL_TIMER_COUNT_REG_HIGH);
+                t_lo = Xil_In32(XSK_GLOBAL_TIMER_COUNT_REG_LOW);
+        }while(t_hi != Xil_In32(XSK_GLOBAL_TIMER_COUNT_REG_HIGH));
+
+        t = (((u64) t_hi) << 32) | (u64) t_lo;
+        return t;
+}
+/****************************************************************************/
+/**
+*
+* Calculates the timer ticks to wait to set the time out
+*
+* @param	t  - timer ticks to wait to set the timeout
+* @param	us - Timeout period in us
+*
+*
+* @return
+*	t  - timer ticks to wait to set the timeout
+*
+* @note		None.
+*
+*****************************************************************************/
+void XilSKey_Efuse_SetTimeOut(volatile u64* t, u64 us)
+{
+        volatile u64 t_end;
+        t_end = XilSKey_Efuse_GetTime();
+        /**
+         * us: time to wait in microseconds. Convert to clock ticks and
+         * add to current time.
+         */
+		t_end += (us * TimerTicksfor100ns);
+        *t = t_end;
+}
+
+/****************************************************************************/
+/**
+*
+* Checks whether the timer has been expired or not
+*
+* @param	t - timeout value in us
+*
+* @return
+*
+*	t_end - Returns the global timer value in case of timer expired
+*
+* @note		None.
+*
+*****************************************************************************/
+
+u8 XilSKey_Efuse_IsTimerExpired(u64 t)
+{
+        u64 t_end;
+        t_end = XilSKey_Efuse_GetTime();
+        return t_end >= t;
+}
+
+/****************************************************************************/
+/**
+ * Converts the char into the equivalent nibble.
+ *	Ex: 'a' -> 0xa, 'A' -> 0xa, '9'->0x9
+ *
+ * @param InChar is input character. It has to be between 0-9,a-f,A-F
+ * @param Num is the output nibble.
+ * @return
+ * 		- XST_SUCCESS no errors occured.
+ *		- XST_FAILURE an error when input parameters are not valid
+ ****************************************************************************/
+static u32 XilSKey_EfusePs_ConvertCharToNibble (char InChar, u8 *Num)
+{
+	/**
+	 * Convert the char to nibble
+	 */
+	if ((InChar >= '0') && (InChar <= '9'))
+		*Num = InChar - '0';
+	else if ((InChar >= 'a') && (InChar <= 'f'))
+		*Num = InChar - 'a' + 10;
+	else if ((InChar >= 'A') && (InChar <= 'F'))
+		*Num = InChar - 'A' + 10;
+	else
+		return XSK_EFUSEPS_ERROR_STRING_INVALID;
+
+	return XST_SUCCESS;
+}
+
+/****************************************************************************/
+/**
+ * Converts the string into the equivalent Hex buffer.
+ *	Ex: "abc123" -> {0xab, 0xc1, 0x23}
+ *
+ * @param	Str is a Input String. Will support the lower and upper case values.
+ * 		Value should be between 0-9, a-f and A-F
+ *
+ * @param	Buf is Output buffer.
+ * @param	Len of the input string. Should have even values
+ * @return
+ * 		- XST_SUCCESS no errors occured.
+ *		- XST_FAILURE an error when input parameters are not valid
+ *		- an error when input buffer has invalid values
+ *
+ *	TDD Test Cases:
+	---Initialization---
+	Len is odd
+	Len is zero
+	Str is NULL
+	Buf is NULL
+	---Functionality---
+	Str input with only numbers
+	Str input with All values in A-F
+	Str input with All values in a-f
+	Str input with values in a-f, 0-9, A-F
+	Str input with values in a-z, 0-9, A-Z
+	Boundary Cases
+	Memory Bounds of buffer checking
+  ****************************************************************************/
+
+u32 XilSKey_Efuse_ConvertStringToHexBE(const char * Str, u8 * Buf, u32 Len)
+{
+	u32 ConvertedLen=0;
+	u8 LowerNibble, UpperNibble;
+
+	/**
+	 * Check the parameters
+	 */
+	if (Str == NULL)
+		return XSK_EFUSEPS_ERROR_PARAMETER_NULL;
+
+	if (Buf == NULL)
+		return XSK_EFUSEPS_ERROR_PARAMETER_NULL;
+
+	/**
+	 * Len has to be multiple of 2
+	 */
+	if ((Len == 0) || (Len%2 == 1))
+		return XSK_EFUSEPS_ERROR_PARAMETER_NULL;
+
+	ConvertedLen = 0;
+	while (ConvertedLen < Len) {
+		/**
+		 * Convert char to nibble
+		 */
+		if (XilSKey_EfusePs_ConvertCharToNibble (Str[ConvertedLen],&UpperNibble)
+				==XST_SUCCESS) {
+			/**
+			 * Convert char to nibble
+			 */
+			if (XilSKey_EfusePs_ConvertCharToNibble (Str[ConvertedLen+1],
+					&LowerNibble)==XST_SUCCESS) {
+				/**
+				 * Merge upper and lower nibble to Hex
+				 */
+				Buf[ConvertedLen/2] =
+						(UpperNibble << 4) | LowerNibble;
+			}
+			else {
+				/**
+				 * Error converting Lower nibble
+				 */
+				return XSK_EFUSEPS_ERROR_STRING_INVALID;
+			}
+		}
+		else {
+			/**
+			 * Error converting Upper nibble
+			 */
+			return XSK_EFUSEPS_ERROR_STRING_INVALID;
+		}
+		/**
+		 * Converted upper and lower nibbles
+		 */
+		xeFUSE_printf(XSK_EFUSE_DEBUG_GENERAL,"Converted %c%c to %0x\n",
+				Str[ConvertedLen],Str[ConvertedLen+1],Buf[ConvertedLen/2]);
+		ConvertedLen += 2;
+	}
+
+	return XST_SUCCESS;
+}
+
+
+/****************************************************************************/
+/**
+ * Converts the string into the equivalent Hex buffer.
+ *	Ex: "abc123" -> {0x23, 0xc1, 0xab}
+ *
+ * @param	Str is a Input String. Will support the lower and upper case values.
+ * 		Value should be between 0-9, a-f and A-F
+ *
+ * @param	Buf is Output buffer.
+ * @param	Len of the input string. Should have even values
+ * @return
+ * 		- XST_SUCCESS no errors occured.
+ *		- XST_FAILURE an error when input parameters are not valid
+ *		- an error when input buffer has invalid values
+ *
+ *	TDD Test Cases:
+	---Initialization---
+	Len is odd
+	Len is zero
+	Str is NULL
+	Buf is NULL
+	---Functionality---
+	Str input with only numbers
+	Str input with All values in A-F
+	Str input with All values in a-f
+	Str input with values in a-f, 0-9, A-F
+	Str input with values in a-z, 0-9, A-Z
+	Boundary Cases
+	Memory Bounds of buffer checking
+  ****************************************************************************/
+
+
+u32 XilSKey_Efuse_ConvertStringToHexLE(const char * Str, u8 * Buf, u32 Len)
+{
+	u32 ConvertedLen=0;
+		u8 LowerNibble, UpperNibble;
+		u32 index;
+
+		/**
+		 * Check the parameters
+		 */
+		if (Str == NULL)
+			return XSK_EFUSEPS_ERROR_PARAMETER_NULL;
+
+		if (Buf == NULL)
+			return XSK_EFUSEPS_ERROR_PARAMETER_NULL;
+
+		/**
+		 * Len has to be multiple of 2
+		 */
+		if ((Len == 0) || (Len%2 == 1))
+			return XSK_EFUSEPS_ERROR_PARAMETER_NULL;
+
+		index = (Len/8) - 1;
+		ConvertedLen = 0;
+		while (ConvertedLen < Len) {
+			/**
+			 * Convert char to nibble
+			 */
+			if (XilSKey_EfusePs_ConvertCharToNibble (Str[ConvertedLen],
+										&UpperNibble) == XST_SUCCESS) {
+				/**
+				 * Convert char to nibble
+				 */
+				if (XilSKey_EfusePs_ConvertCharToNibble (Str[ConvertedLen+1],
+						&LowerNibble)==XST_SUCCESS)	{
+					/**
+					 * Merge upper and lower nibble to Hex
+					 */
+					Buf[index--] =
+							(UpperNibble << 4) | LowerNibble;
+				}
+				else {
+					/**
+					 * Error converting Lower nibble
+					 */
+					return XSK_EFUSEPS_ERROR_STRING_INVALID;
+				}
+			}
+			else {
+				/**
+				 * Error converting Upper nibble
+				 */
+				return XSK_EFUSEPS_ERROR_STRING_INVALID;
+			}
+			/**
+			 * Converted upper and lower nibbles
+			 */
+			ConvertedLen += 2;
+		}
+
+		return XST_SUCCESS;
+}
+
+/***************************************************************************/
+/**
+* This function is used to convert the Big Endian Byte data to
+* Little Endian Byte data
+* For ex: 1234567890abcdef -> 78563412efcdab90
+*
+* @param Be Big endian data
+* @param Le Little endian data
+* @param Len Length of data to be converted and it should be multiple of 4
+* @return
+* 		- XST_SUCCESS no errors occurred.
+*		- XST_FAILURE an error occurred during reading the PS eFUSE.
+*
+* TDD Test Cases:
+*
+****************************************************************************/
+void XilSKey_EfusePs_ConvertBytesBeToLe(const u8 *Be, u8 *Le, u32 Len)
+{
+	u32 Index;
+
+	if ((Be == NULL) || (Le == NULL) || (Len == 0))
+		return;
+
+	for (Index=0;Index<Len;Index=Index+4) {
+		Le[Index+3]=Be[Index];
+		Le[Index+2]=Be[Index+1];
+		Le[Index+1]=Be[Index+2];
+		Le[Index]=Be[Index+3];
+	}
+	return ;
+}
+
+/****************************************************************************/
+/**
+ * Convert the Bits to Bytes in Little Endian format
+ *       Ex: 0x5C -> {0, 0, 1, 1, 1, 0, 1, 0}
+ *
+ * @param       Bits Input Buffer.
+ * @param       Bytes is Output buffer.
+ * @param       Len of the input buffer in bits
+ * @return		None
+  Test Cases:
+	Input with All Zeroes
+	Input with All Ones
+	Input Little Endian (General Cases )
+	Input Check Big Endian - False case
+	Check for Len not a multiple of 8
+	Check for Len 0
+	Memory Bounds of buffer checking
+ ****************************************************************************/
+void XilSKey_Efuse_ConvertBitsToBytes(const u8 * Bits, u8 * Bytes, u32 Len)
+{
+	u8 Data=0;
+	u32 Index=0, BitIndex=0, ByteIndex=0;
+
+	/**
+	 * Make sure the bytes array is 0'ed first.
+	 */
+	for(Index=0;Index<Len;Index++) {
+		Bytes[Index] = 0;
+	}
+
+	while(Len) {
+		/**
+		 * Convert 8 Bit One Byte to 1 Bit 8 Bytes
+		 */
+		for(Index=0;Index<8;Index++) {
+			/**
+			 * Convert from LSB -> MSB - Little Endian
+			 */
+			Data = (Bits[BitIndex] >> Index) & 0x1;
+			Bytes[ByteIndex] = Data;
+			ByteIndex++;
+			Len--;
+			/**
+			 * If len is not Byte aligned
+			 */
+			if(Len == 0)
+				return;
+		}
+		BitIndex++;
+	}
+	return ;
+}
+
+/****************************************************************************/
+/**
+ * Convert the Bytes to Bits in little endian format
+ * 0th byte is LSB, 7th byte is MSB
+ *       Ex: {0, 0, 1, 1, 1, 0, 1, 0} -> 0x5C
+ *
+ * @param        Bytes Input Buffer.
+ * @param        Bits is Output buffer.
+ * @param        Len of the input buffer.
+ * @return       None
+  Test Cases:
+	Input with All Zeroes
+	Input with All Ones
+	Input Little Endian (General Cases )
+	Input Check Big Endian - False case
+	Check for Len not a multiple of 8
+	Check for Len 0
+	Memory Bounds of buffer checking
+ ****************************************************************************/
+void XilSKey_EfusePs_ConvertBytesToBits(const u8 * Bytes, u8 * Bits , u32 Len)
+{
+	u8 Tmp=0;
+	u32 Index=0, BitIndex=0, ByteIndex=0;
+
+	/**
+	 * Make sure the bits array is 0 first.
+	 */
+	for(Index=0;Index<((Len%8)?((Len/8)+1):(Len/8));Index++) {
+		Bits[Index] = 0;
+	}
+
+	while(Len) {
+		/**
+		 * Convert 1 Bit 8 Bytes to 8 Bit 1 Byte
+		 */
+		for(Index=0;Index<8;Index++) {
+			/**
+			 * Store from LSB -> MSB - Little Endian
+			 */
+			Tmp = (Bytes[ByteIndex]) & 0x1;
+			Bits[BitIndex] |= (Tmp << Index);
+			ByteIndex++;
+			Len--;
+			/**
+			 * If Len is not Byte aligned
+			 */
+			if(Len == 0)
+				return;
+		}
+		BitIndex++;
+	}
+	return;
+}
+
+/****************************************************************************/
+/**
+ * Validate the key for proper characters & proper length
+ *
+ *
+ * @param        Key - Hash Key
+ * @param        Len - Valid length of key
+ *
+ * @return
+ *			XST_SUCCESS	- In case of Success
+ *			XST_FAILURE - In case of Failure
+ ****************************************************************************/
+u32 XilSKey_Efuse_ValidateKey(const char *Key, u32 Len)
+{
+	int i;
+    /**
+     * Make sure passed key is not NULL
+     */
+    if(Key == NULL) {
+	return (XSK_EFUSEPL_ERROR_KEY_VALIDATION +
+			XSK_EFUSEPL_ERROR_NULL_KEY);
+    }
+
+    if(Len == 0) {
+	return (XSK_EFUSEPL_ERROR_KEY_VALIDATION +
+			XSK_EFUSEPL_ERROR_ZERO_KEY_LENGTH);
+    }
+
+	/**
+	 * Make sure the key has valid length
+	 */
+    if (strlen(Key) != Len) {
+		return (XSK_EFUSEPL_ERROR_KEY_VALIDATION +
+				XSK_EFUSEPL_ERROR_NOT_VALID_KEY_LENGTH);
+    }
+
+    /**
+     * Make sure the key has valid characters
+     */
+	for(i=0;i<strlen(Key);i++) {
+		if(XilSKey_Efuse_IsValidChar(&Key[i]) != XST_SUCCESS)
+			return (XSK_EFUSEPL_ERROR_KEY_VALIDATION +
+					XSK_EFUSEPL_ERROR_NOT_VALID_KEY_CHAR);
+	}
+    return XSK_EFUSEPL_ERROR_NONE;
+}
+/****************************************************************************/
+/**
+ * Checks whether the passed character is a valid hash key character
+ *
+ *
+ * @param        c - Character to check proper value
+ *
+ * @return
+ *			XST_SUCCESS	- In case of Success
+ *			XST_FAILURE - In case of Failure
+ ****************************************************************************/
+
+u32 XilSKey_Efuse_IsValidChar(const char *c)
+{
+    char ValidChars[] = "0123456789abcdefABCDEF";
+    char *RetVal;
+
+    if(c == NULL)
+	return XST_FAILURE;
+
+    RetVal = strchr(ValidChars, (int)*c);
+    if(RetVal == NULL) {
+	return XST_FAILURE;
+    }
+    else {
+	return XST_SUCCESS;
+    }
+}