Beispiel #1
0
/**
*
* 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;

}
Beispiel #2
0
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];
}
Beispiel #3
0
int jtag_dr(unsigned sz, unsigned bits, unsigned *out) {
	int r;
	if ((r = jtag_move(SHIFTDR)) < 0) return r;
	if ((r = jtag_shift(sz, bits, out)) < 0) return r;
	if ((r = jtag_move(DONE)) < 0) return r;
	return 0;
}
Beispiel #4
0
int jtag_ir(unsigned sz, unsigned bits) {
	int r;
	if ((r = jtag_move(SHIFTIR)) < 0) return r;
	if ((r = jtag_shift(sz, bits, 0)) < 0) return r;
	if ((r = jtag_move(DONE)) < 0) return r;
	return 0;
}
Beispiel #5
0
/**
*
* 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);

}
Beispiel #6
0
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);
}
Beispiel #7
0
/**
*
* 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;

}
Beispiel #8
0
/**
*
* 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;

}