1 /*
2  * (C) Copyright 2003
3  * Stefan Roese, esd gmbh germany, stefan.roese@esd-electronics.com
4  *
5  * SPDX-License-Identifier:	GPL-2.0+
6  */
7 
8 /*****************************************************************************
9  * file:         micro.c
10  * abstract:     This file contains the function, xsvfExecute(),
11  *               call for interpreting the XSVF commands.
12  * Usage:        Call xsvfExecute() to process XSVF data.
13  *               The XSVF data is retrieved by readByte() in ports.c
14  *               Remove the main function if you already have one.
15  * Options:      XSVF_SUPPORT_COMPRESSION
16  *                   This define supports the XC9500/XL compression scheme.
17  *                   This define adds support for XSDRINC and XSETSDRMASKS.
18  *               XSVF_SUPPORT_ERRORCODES
19  *                   This define causes the xsvfExecute function to return
20  *                   an error code for specific errors.  See error codes below.
21  *                   If this is not defined, the return value defaults to the
22  *                   legacy values for backward compatibility:
23  *                   1 = success;  0 = failure.
24  * Debugging:    DEBUG_MODE (Legacy name)
25  *               Define DEBUG_MODE to compile with debugging features.
26  *               Both micro.c and ports.c must be compiled with the DEBUG_MODE
27  *               defined to enable the standalone main implementation in
28  *               micro.c that reads XSVF from a file.
29  * History:      v2.00   - Original XSVF implementation.
30  *               v4.04   - Added delay at end of XSIR for XC18v00 support.
31  *                         Added new commands for CoolRunner support:
32  *                         XSTATE, XENDIR, XENDDR
33  *               v4.05   - Cleanup micro.c but leave ports.c intact.
34  *               v4.06   - Fix xsvfGotoTapState for retry transition.
35  *               v4.07   - Update example waitTime implementations for
36  *                         compatibility with Virtex-II.
37  *               v4.10   - Add new XSIR2 command that supports a 2-byte
38  *                         IR-length parameter for IR shifts > 255 bits.
39  *               v4.11   - No change.  Update version to match SVF2XSVF xlator.
40  *               v4.14   - Added XCOMMENT.
41  *               v5.00   - Improve XSTATE support.
42  *                         Added XWAIT.
43  *****************************************************************************/
44 
45 #include <common.h>
46 #include <command.h>
47 #include <asm/processor.h>
48 
49 #include "micro.h"
50 #include "lenval.h"
51 #include "ports.h"
52 
53 const unsigned char *xsvfdata;
54 
55 /*============================================================================
56  * XSVF #define
57  ============================================================================*/
58 
59 #define XSVF_VERSION    "5.00"
60 
61 /*****************************************************************************
62  * Define:       XSVF_SUPPORT_COMPRESSION
63  * Description:  Define this to support the XC9500/XL XSVF data compression
64  *               scheme.
65  *               Code size can be reduced by NOT supporting this feature.
66  *               However, you must use the -nc (no compress) option when
67  *               translating SVF to XSVF using the SVF2XSVF translator.
68  *               Corresponding, uncompressed XSVF may be larger.
69  *****************************************************************************/
70 #ifndef XSVF_SUPPORT_COMPRESSION
71 #define XSVF_SUPPORT_COMPRESSION    1
72 #endif
73 
74 /*****************************************************************************
75  * Define:       XSVF_SUPPORT_ERRORCODES
76  * Description:  Define this to support the new XSVF error codes.
77  *               (The original XSVF player just returned 1 for success and
78  *               0 for an unspecified failure.)
79  *****************************************************************************/
80 #ifndef XSVF_SUPPORT_ERRORCODES
81 #define XSVF_SUPPORT_ERRORCODES     1
82 #endif
83 
84 #ifdef  XSVF_SUPPORT_ERRORCODES
85 #define XSVF_ERRORCODE(errorCode)   errorCode
86 #else   /* Use legacy error code */
87 #define XSVF_ERRORCODE(errorCode)   ((errorCode==XSVF_ERROR_NONE)?1:0)
88 #endif  /* XSVF_SUPPORT_ERRORCODES */
89 
90 
91 /*============================================================================
92  * DEBUG_MODE #define
93  ============================================================================*/
94 #define DEBUG_MODE
95 
96 #ifdef  DEBUG_MODE
97 #define XSVFDBG_PRINTF(iDebugLevel,pzFormat) \
98 		{ if ( xsvf_iDebugLevel >= iDebugLevel ) \
99 		    printf( pzFormat ); }
100 #define XSVFDBG_PRINTF1(iDebugLevel,pzFormat,arg1) \
101 		{ if ( xsvf_iDebugLevel >= iDebugLevel ) \
102 		    printf( pzFormat, arg1 ); }
103 #define XSVFDBG_PRINTF2(iDebugLevel,pzFormat,arg1,arg2) \
104 		{ if ( xsvf_iDebugLevel >= iDebugLevel ) \
105 		    printf( pzFormat, arg1, arg2 ); }
106 #define XSVFDBG_PRINTF3(iDebugLevel,pzFormat,arg1,arg2,arg3) \
107 		{ if ( xsvf_iDebugLevel >= iDebugLevel ) \
108 		    printf( pzFormat, arg1, arg2, arg3 ); }
109 #define XSVFDBG_PRINTLENVAL(iDebugLevel,plenVal) \
110 		{ if ( xsvf_iDebugLevel >= iDebugLevel ) \
111 		    xsvfPrintLenVal(plenVal); }
112 #else   /* !DEBUG_MODE */
113 #define XSVFDBG_PRINTF(iDebugLevel,pzFormat)
114 #define XSVFDBG_PRINTF1(iDebugLevel,pzFormat,arg1)
115 #define XSVFDBG_PRINTF2(iDebugLevel,pzFormat,arg1,arg2)
116 #define XSVFDBG_PRINTF3(iDebugLevel,pzFormat,arg1,arg2,arg3)
117 #define XSVFDBG_PRINTLENVAL(iDebugLevel,plenVal)
118 #endif  /* DEBUG_MODE */
119 
120 
121 /*============================================================================
122  * XSVF Type Declarations
123  ============================================================================*/
124 
125 /*****************************************************************************
126  * Struct:       SXsvfInfo
127  * Description:  This structure contains all of the data used during the
128  *               execution of the XSVF.  Some data is persistent, predefined
129  *               information (e.g. lRunTestTime).  The bulk of this struct's
130  *               size is due to the lenVal structs (defined in lenval.h)
131  *               which contain buffers for the active shift data.  The MAX_LEN
132  *               #define in lenval.h defines the size of these buffers.
133  *               These buffers must be large enough to store the longest
134  *               shift data in your XSVF file.  For example:
135  *                   MAX_LEN >= ( longest_shift_data_in_bits / 8 )
136  *               Because the lenVal struct dominates the space usage of this
137  *               struct, the rough size of this struct is:
138  *                   sizeof( SXsvfInfo ) ~= MAX_LEN * 7 (number of lenVals)
139  *               xsvfInitialize() contains initialization code for the data
140  *               in this struct.
141  *               xsvfCleanup() contains cleanup code for the data in this
142  *               struct.
143  *****************************************************************************/
144 typedef struct tagSXsvfInfo
145 {
146 	/* XSVF status information */
147 	unsigned char   ucComplete;         /* 0 = running; 1 = complete */
148 	unsigned char   ucCommand;          /* Current XSVF command byte */
149 	long            lCommandCount;      /* Number of commands processed */
150 	int             iErrorCode;         /* An error code. 0 = no error. */
151 
152 	/* TAP state/sequencing information */
153 	unsigned char   ucTapState;         /* Current TAP state */
154 	unsigned char   ucEndIR;            /* ENDIR TAP state (See SVF) */
155 	unsigned char   ucEndDR;            /* ENDDR TAP state (See SVF) */
156 
157 	/* RUNTEST information */
158 	unsigned char   ucMaxRepeat;        /* Max repeat loops (for xc9500/xl) */
159 	long            lRunTestTime;       /* Pre-specified RUNTEST time (usec) */
160 
161 	/* Shift Data Info and Buffers */
162 	long            lShiftLengthBits;   /* Len. current shift data in bits */
163 	short           sShiftLengthBytes;  /* Len. current shift data in bytes */
164 
165 	lenVal          lvTdi;              /* Current TDI shift data */
166 	lenVal          lvTdoExpected;      /* Expected TDO shift data */
167 	lenVal          lvTdoCaptured;      /* Captured TDO shift data */
168 	lenVal          lvTdoMask;          /* TDO mask: 0=dontcare; 1=compare */
169 
170 #ifdef  XSVF_SUPPORT_COMPRESSION
171 	/* XSDRINC Data Buffers */
172 	lenVal          lvAddressMask;      /* Address mask for XSDRINC */
173 	lenVal          lvDataMask;         /* Data mask for XSDRINC */
174 	lenVal          lvNextData;         /* Next data for XSDRINC */
175 #endif  /* XSVF_SUPPORT_COMPRESSION */
176 } SXsvfInfo;
177 
178 /* Declare pointer to functions that perform XSVF commands */
179 typedef int (*TXsvfDoCmdFuncPtr)( SXsvfInfo* );
180 
181 /*============================================================================
182  * XSVF Command Bytes
183  ============================================================================*/
184 
185 /* encodings of xsvf instructions */
186 #define XCOMPLETE        0
187 #define XTDOMASK         1
188 #define XSIR             2
189 #define XSDR             3
190 #define XRUNTEST         4
191 /* Reserved              5 */
192 /* Reserved              6 */
193 #define XREPEAT          7
194 #define XSDRSIZE         8
195 #define XSDRTDO          9
196 #define XSETSDRMASKS     10
197 #define XSDRINC          11
198 #define XSDRB            12
199 #define XSDRC            13
200 #define XSDRE            14
201 #define XSDRTDOB         15
202 #define XSDRTDOC         16
203 #define XSDRTDOE         17
204 #define XSTATE           18         /* 4.00 */
205 #define XENDIR           19         /* 4.04 */
206 #define XENDDR           20         /* 4.04 */
207 #define XSIR2            21         /* 4.10 */
208 #define XCOMMENT         22         /* 4.14 */
209 #define XWAIT            23         /* 5.00 */
210 /* Insert new commands here */
211 /* and add corresponding xsvfDoCmd function to xsvf_pfDoCmd below. */
212 #define XLASTCMD         24         /* Last command marker */
213 
214 
215 /*============================================================================
216  * XSVF Command Parameter Values
217  ============================================================================*/
218 
219 #define XSTATE_RESET     0          /* 4.00 parameter for XSTATE */
220 #define XSTATE_RUNTEST   1          /* 4.00 parameter for XSTATE */
221 
222 #define XENDXR_RUNTEST   0          /* 4.04 parameter for XENDIR/DR */
223 #define XENDXR_PAUSE     1          /* 4.04 parameter for XENDIR/DR */
224 
225 /* TAP states */
226 #define XTAPSTATE_RESET     0x00
227 #define XTAPSTATE_RUNTEST   0x01    /* a.k.a. IDLE */
228 #define XTAPSTATE_SELECTDR  0x02
229 #define XTAPSTATE_CAPTUREDR 0x03
230 #define XTAPSTATE_SHIFTDR   0x04
231 #define XTAPSTATE_EXIT1DR   0x05
232 #define XTAPSTATE_PAUSEDR   0x06
233 #define XTAPSTATE_EXIT2DR   0x07
234 #define XTAPSTATE_UPDATEDR  0x08
235 #define XTAPSTATE_IRSTATES  0x09    /* All IR states begin here */
236 #define XTAPSTATE_SELECTIR  0x09
237 #define XTAPSTATE_CAPTUREIR 0x0A
238 #define XTAPSTATE_SHIFTIR   0x0B
239 #define XTAPSTATE_EXIT1IR   0x0C
240 #define XTAPSTATE_PAUSEIR   0x0D
241 #define XTAPSTATE_EXIT2IR   0x0E
242 #define XTAPSTATE_UPDATEIR  0x0F
243 
244 /*============================================================================
245  * XSVF Function Prototypes
246  ============================================================================*/
247 
248 int xsvfDoIllegalCmd( SXsvfInfo* pXsvfInfo );   /* Illegal command function */
249 int xsvfDoXCOMPLETE( SXsvfInfo* pXsvfInfo );
250 int xsvfDoXTDOMASK( SXsvfInfo* pXsvfInfo );
251 int xsvfDoXSIR( SXsvfInfo* pXsvfInfo );
252 int xsvfDoXSIR2( SXsvfInfo* pXsvfInfo );
253 int xsvfDoXSDR( SXsvfInfo* pXsvfInfo );
254 int xsvfDoXRUNTEST( SXsvfInfo* pXsvfInfo );
255 int xsvfDoXREPEAT( SXsvfInfo* pXsvfInfo );
256 int xsvfDoXSDRSIZE( SXsvfInfo* pXsvfInfo );
257 int xsvfDoXSDRTDO( SXsvfInfo* pXsvfInfo );
258 int xsvfDoXSETSDRMASKS( SXsvfInfo* pXsvfInfo );
259 int xsvfDoXSDRINC( SXsvfInfo* pXsvfInfo );
260 int xsvfDoXSDRBCE( SXsvfInfo* pXsvfInfo );
261 int xsvfDoXSDRTDOBCE( SXsvfInfo* pXsvfInfo );
262 int xsvfDoXSTATE( SXsvfInfo* pXsvfInfo );
263 int xsvfDoXENDXR( SXsvfInfo* pXsvfInfo );
264 int xsvfDoXCOMMENT( SXsvfInfo* pXsvfInfo );
265 int xsvfDoXWAIT( SXsvfInfo* pXsvfInfo );
266 /* Insert new command functions here */
267 
268 /*============================================================================
269  * XSVF Global Variables
270  ============================================================================*/
271 
272 /* Array of XSVF command functions.  Must follow command byte value order! */
273 /* If your compiler cannot take this form, then convert to a switch statement*/
274 TXsvfDoCmdFuncPtr   xsvf_pfDoCmd[]  =
275 {
276 	xsvfDoXCOMPLETE,        /*  0 */
277 	xsvfDoXTDOMASK,         /*  1 */
278 	xsvfDoXSIR,             /*  2 */
279 	xsvfDoXSDR,             /*  3 */
280 	xsvfDoXRUNTEST,         /*  4 */
281 	xsvfDoIllegalCmd,       /*  5 */
282 	xsvfDoIllegalCmd,       /*  6 */
283 	xsvfDoXREPEAT,          /*  7 */
284 	xsvfDoXSDRSIZE,         /*  8 */
285 	xsvfDoXSDRTDO,          /*  9 */
286 #ifdef  XSVF_SUPPORT_COMPRESSION
287 	xsvfDoXSETSDRMASKS,     /* 10 */
288 	xsvfDoXSDRINC,          /* 11 */
289 #else
290 	xsvfDoIllegalCmd,       /* 10 */
291 	xsvfDoIllegalCmd,       /* 11 */
292 #endif  /* XSVF_SUPPORT_COMPRESSION */
293 	xsvfDoXSDRBCE,          /* 12 */
294 	xsvfDoXSDRBCE,          /* 13 */
295 	xsvfDoXSDRBCE,          /* 14 */
296 	xsvfDoXSDRTDOBCE,       /* 15 */
297 	xsvfDoXSDRTDOBCE,       /* 16 */
298 	xsvfDoXSDRTDOBCE,       /* 17 */
299 	xsvfDoXSTATE,           /* 18 */
300 	xsvfDoXENDXR,           /* 19 */
301 	xsvfDoXENDXR,           /* 20 */
302 	xsvfDoXSIR2,            /* 21 */
303 	xsvfDoXCOMMENT,         /* 22 */
304 	xsvfDoXWAIT             /* 23 */
305 /* Insert new command functions here */
306 };
307 
308 #ifdef  DEBUG_MODE
309 char* xsvf_pzCommandName[]  =
310 {
311 	"XCOMPLETE",
312 	"XTDOMASK",
313 	"XSIR",
314 	"XSDR",
315 	"XRUNTEST",
316 	"Reserved5",
317 	"Reserved6",
318 	"XREPEAT",
319 	"XSDRSIZE",
320 	"XSDRTDO",
321 	"XSETSDRMASKS",
322 	"XSDRINC",
323 	"XSDRB",
324 	"XSDRC",
325 	"XSDRE",
326 	"XSDRTDOB",
327 	"XSDRTDOC",
328 	"XSDRTDOE",
329 	"XSTATE",
330 	"XENDIR",
331 	"XENDDR",
332 	"XSIR2",
333 	"XCOMMENT",
334 	"XWAIT"
335 };
336 
337 char*   xsvf_pzErrorName[]  =
338 {
339 	"No error",
340 	"ERROR:  Unknown",
341 	"ERROR:  TDO mismatch",
342 	"ERROR:  TDO mismatch and exceeded max retries",
343 	"ERROR:  Unsupported XSVF command",
344 	"ERROR:  Illegal state specification",
345 	"ERROR:  Data overflows allocated MAX_LEN buffer size"
346 };
347 
348 char*   xsvf_pzTapState[] =
349 {
350 	"RESET",        /* 0x00 */
351 	"RUNTEST/IDLE", /* 0x01 */
352 	"DRSELECT",     /* 0x02 */
353 	"DRCAPTURE",    /* 0x03 */
354 	"DRSHIFT",      /* 0x04 */
355 	"DREXIT1",      /* 0x05 */
356 	"DRPAUSE",      /* 0x06 */
357 	"DREXIT2",      /* 0x07 */
358 	"DRUPDATE",     /* 0x08 */
359 	"IRSELECT",     /* 0x09 */
360 	"IRCAPTURE",    /* 0x0A */
361 	"IRSHIFT",      /* 0x0B */
362 	"IREXIT1",      /* 0x0C */
363 	"IRPAUSE",      /* 0x0D */
364 	"IREXIT2",      /* 0x0E */
365 	"IRUPDATE"      /* 0x0F */
366 };
367 #endif  /* DEBUG_MODE */
368 
369 /*#ifdef DEBUG_MODE	*/
370 /*    FILE* in;   /XXX* Legacy DEBUG_MODE file pointer */
371 int xsvf_iDebugLevel;
372 /*#endif /XXX* DEBUG_MODE */
373 
374 /*============================================================================
375  * Utility Functions
376  ============================================================================*/
377 
378 /*****************************************************************************
379  * Function:     xsvfPrintLenVal
380  * Description:  Print the lenval value in hex.
381  * Parameters:   plv     - ptr to lenval.
382  * Returns:      void.
383  *****************************************************************************/
384 #ifdef  DEBUG_MODE
xsvfPrintLenVal(lenVal * plv)385 void xsvfPrintLenVal( lenVal *plv )
386 {
387 	int i;
388 
389 	if ( plv )
390 	{
391 		printf( "0x" );
392 		for ( i = 0; i < plv->len; ++i )
393 		{
394 			printf( "%02x", ((unsigned int)(plv->val[ i ])) );
395 		}
396 	}
397 }
398 #endif  /* DEBUG_MODE */
399 
400 
401 /*****************************************************************************
402  * Function:     xsvfInfoInit
403  * Description:  Initialize the xsvfInfo data.
404  * Parameters:   pXsvfInfo   - ptr to the XSVF info structure.
405  * Returns:      int         - 0 = success; otherwise error.
406  *****************************************************************************/
xsvfInfoInit(SXsvfInfo * pXsvfInfo)407 int xsvfInfoInit( SXsvfInfo* pXsvfInfo )
408 {
409 	XSVFDBG_PRINTF1( 4, "    sizeof( SXsvfInfo ) = %d bytes\n",
410 			 sizeof( SXsvfInfo ) );
411 
412 	pXsvfInfo->ucComplete       = 0;
413 	pXsvfInfo->ucCommand        = XCOMPLETE;
414 	pXsvfInfo->lCommandCount    = 0;
415 	pXsvfInfo->iErrorCode       = XSVF_ERROR_NONE;
416 	pXsvfInfo->ucMaxRepeat      = 0;
417 	pXsvfInfo->ucTapState       = XTAPSTATE_RESET;
418 	pXsvfInfo->ucEndIR          = XTAPSTATE_RUNTEST;
419 	pXsvfInfo->ucEndDR          = XTAPSTATE_RUNTEST;
420 	pXsvfInfo->lShiftLengthBits = 0L;
421 	pXsvfInfo->sShiftLengthBytes= 0;
422 	pXsvfInfo->lRunTestTime     = 0L;
423 
424 	return( 0 );
425 }
426 
427 /*****************************************************************************
428  * Function:     xsvfInfoCleanup
429  * Description:  Cleanup the xsvfInfo data.
430  * Parameters:   pXsvfInfo   - ptr to the XSVF info structure.
431  * Returns:      void.
432  *****************************************************************************/
xsvfInfoCleanup(SXsvfInfo * pXsvfInfo)433 void xsvfInfoCleanup( SXsvfInfo* pXsvfInfo )
434 {
435 }
436 
437 /*****************************************************************************
438  * Function:     xsvfGetAsNumBytes
439  * Description:  Calculate the number of bytes the given number of bits
440  *               consumes.
441  * Parameters:   lNumBits    - the number of bits.
442  * Returns:      short       - the number of bytes to store the number of bits.
443  *****************************************************************************/
xsvfGetAsNumBytes(long lNumBits)444 short xsvfGetAsNumBytes( long lNumBits )
445 {
446 	return( (short)( ( lNumBits + 7L ) / 8L ) );
447 }
448 
449 /*****************************************************************************
450  * Function:     xsvfTmsTransition
451  * Description:  Apply TMS and transition TAP controller by applying one TCK
452  *               cycle.
453  * Parameters:   sTms    - new TMS value.
454  * Returns:      void.
455  *****************************************************************************/
xsvfTmsTransition(short sTms)456 void xsvfTmsTransition( short sTms )
457 {
458 	setPort( TMS, sTms );
459 	setPort( TCK, 0 );
460 	setPort( TCK, 1 );
461 }
462 
463 /*****************************************************************************
464  * Function:     xsvfGotoTapState
465  * Description:  From the current TAP state, go to the named TAP state.
466  *               A target state of RESET ALWAYS causes TMS reset sequence.
467  *               All SVF standard stable state paths are supported.
468  *               All state transitions are supported except for the following
469  *               which cause an XSVF_ERROR_ILLEGALSTATE:
470  *                   - Target==DREXIT2;  Start!=DRPAUSE
471  *                   - Target==IREXIT2;  Start!=IRPAUSE
472  * Parameters:   pucTapState     - Current TAP state; returns final TAP state.
473  *               ucTargetState   - New target TAP state.
474  * Returns:      int             - 0 = success; otherwise error.
475  *****************************************************************************/
xsvfGotoTapState(unsigned char * pucTapState,unsigned char ucTargetState)476 int xsvfGotoTapState( unsigned char*   pucTapState,
477 		      unsigned char    ucTargetState )
478 {
479 	int i;
480 	int iErrorCode;
481 
482 	iErrorCode  = XSVF_ERROR_NONE;
483 	if ( ucTargetState == XTAPSTATE_RESET )
484 	{
485 		/* If RESET, always perform TMS reset sequence to reset/sync TAPs */
486 		xsvfTmsTransition( 1 );
487 		for ( i = 0; i < 5; ++i )
488 		{
489 			setPort( TCK, 0 );
490 			setPort( TCK, 1 );
491 		}
492 		*pucTapState    = XTAPSTATE_RESET;
493 		XSVFDBG_PRINTF( 3, "   TMS Reset Sequence -> Test-Logic-Reset\n" );
494 		XSVFDBG_PRINTF1( 3, "   TAP State = %s\n",
495 				 xsvf_pzTapState[ *pucTapState ] );
496 	} else if ( ( ucTargetState != *pucTapState ) &&
497 		  ( ( ( ucTargetState == XTAPSTATE_EXIT2DR ) && ( *pucTapState != XTAPSTATE_PAUSEDR ) ) ||
498 		    ( ( ucTargetState == XTAPSTATE_EXIT2IR ) && ( *pucTapState != XTAPSTATE_PAUSEIR ) ) ) )
499 	{
500 		/* Trap illegal TAP state path specification */
501 		iErrorCode      = XSVF_ERROR_ILLEGALSTATE;
502 	} else {
503 		if ( ucTargetState == *pucTapState )
504 		{
505 			/* Already in target state.  Do nothing except when in DRPAUSE
506 			   or in IRPAUSE to comply with SVF standard */
507 			if ( ucTargetState == XTAPSTATE_PAUSEDR )
508 			{
509 				xsvfTmsTransition( 1 );
510 				*pucTapState    = XTAPSTATE_EXIT2DR;
511 				XSVFDBG_PRINTF1( 3, "   TAP State = %s\n",
512 						 xsvf_pzTapState[ *pucTapState ] );
513 			}
514 			else if ( ucTargetState == XTAPSTATE_PAUSEIR )
515 			{
516 				xsvfTmsTransition( 1 );
517 				*pucTapState    = XTAPSTATE_EXIT2IR;
518 				XSVFDBG_PRINTF1( 3, "   TAP State = %s\n",
519 						 xsvf_pzTapState[ *pucTapState ] );
520 			}
521 		}
522 
523 		/* Perform TAP state transitions to get to the target state */
524 		while ( ucTargetState != *pucTapState )
525 		{
526 			switch ( *pucTapState )
527 			{
528 			case XTAPSTATE_RESET:
529 				xsvfTmsTransition( 0 );
530 				*pucTapState    = XTAPSTATE_RUNTEST;
531 				break;
532 			case XTAPSTATE_RUNTEST:
533 				xsvfTmsTransition( 1 );
534 				*pucTapState    = XTAPSTATE_SELECTDR;
535 				break;
536 			case XTAPSTATE_SELECTDR:
537 				if ( ucTargetState >= XTAPSTATE_IRSTATES )
538 				{
539 					xsvfTmsTransition( 1 );
540 					*pucTapState    = XTAPSTATE_SELECTIR;
541 				}
542 				else
543 				{
544 					xsvfTmsTransition( 0 );
545 					*pucTapState    = XTAPSTATE_CAPTUREDR;
546 				}
547 				break;
548 			case XTAPSTATE_CAPTUREDR:
549 				if ( ucTargetState == XTAPSTATE_SHIFTDR )
550 				{
551 					xsvfTmsTransition( 0 );
552 					*pucTapState    = XTAPSTATE_SHIFTDR;
553 				}
554 				else
555 				{
556 					xsvfTmsTransition( 1 );
557 					*pucTapState    = XTAPSTATE_EXIT1DR;
558 				}
559 				break;
560 			case XTAPSTATE_SHIFTDR:
561 				xsvfTmsTransition( 1 );
562 				*pucTapState    = XTAPSTATE_EXIT1DR;
563 				break;
564 			case XTAPSTATE_EXIT1DR:
565 				if ( ucTargetState == XTAPSTATE_PAUSEDR )
566 				{
567 					xsvfTmsTransition( 0 );
568 					*pucTapState    = XTAPSTATE_PAUSEDR;
569 				}
570 				else
571 				{
572 					xsvfTmsTransition( 1 );
573 					*pucTapState    = XTAPSTATE_UPDATEDR;
574 				}
575 				break;
576 			case XTAPSTATE_PAUSEDR:
577 				xsvfTmsTransition( 1 );
578 				*pucTapState    = XTAPSTATE_EXIT2DR;
579 				break;
580 			case XTAPSTATE_EXIT2DR:
581 				if ( ucTargetState == XTAPSTATE_SHIFTDR )
582 				{
583 					xsvfTmsTransition( 0 );
584 					*pucTapState    = XTAPSTATE_SHIFTDR;
585 				}
586 				else
587 				{
588 					xsvfTmsTransition( 1 );
589 					*pucTapState    = XTAPSTATE_UPDATEDR;
590 				}
591 				break;
592 			case XTAPSTATE_UPDATEDR:
593 				if ( ucTargetState == XTAPSTATE_RUNTEST )
594 				{
595 					xsvfTmsTransition( 0 );
596 					*pucTapState    = XTAPSTATE_RUNTEST;
597 				}
598 				else
599 				{
600 					xsvfTmsTransition( 1 );
601 					*pucTapState    = XTAPSTATE_SELECTDR;
602 				}
603 				break;
604 			case XTAPSTATE_SELECTIR:
605 				xsvfTmsTransition( 0 );
606 				*pucTapState    = XTAPSTATE_CAPTUREIR;
607 				break;
608 			case XTAPSTATE_CAPTUREIR:
609 				if ( ucTargetState == XTAPSTATE_SHIFTIR )
610 				{
611 					xsvfTmsTransition( 0 );
612 					*pucTapState    = XTAPSTATE_SHIFTIR;
613 				}
614 				else
615 				{
616 					xsvfTmsTransition( 1 );
617 					*pucTapState    = XTAPSTATE_EXIT1IR;
618 				}
619 				break;
620 			case XTAPSTATE_SHIFTIR:
621 				xsvfTmsTransition( 1 );
622 				*pucTapState    = XTAPSTATE_EXIT1IR;
623 				break;
624 			case XTAPSTATE_EXIT1IR:
625 				if ( ucTargetState == XTAPSTATE_PAUSEIR )
626 				{
627 					xsvfTmsTransition( 0 );
628 					*pucTapState    = XTAPSTATE_PAUSEIR;
629 				}
630 				else
631 				{
632 					xsvfTmsTransition( 1 );
633 					*pucTapState    = XTAPSTATE_UPDATEIR;
634 				}
635 				break;
636 			case XTAPSTATE_PAUSEIR:
637 				xsvfTmsTransition( 1 );
638 				*pucTapState    = XTAPSTATE_EXIT2IR;
639 				break;
640 			case XTAPSTATE_EXIT2IR:
641 				if ( ucTargetState == XTAPSTATE_SHIFTIR )
642 				{
643 					xsvfTmsTransition( 0 );
644 					*pucTapState    = XTAPSTATE_SHIFTIR;
645 				}
646 				else
647 				{
648 					xsvfTmsTransition( 1 );
649 					*pucTapState    = XTAPSTATE_UPDATEIR;
650 				}
651 				break;
652 			case XTAPSTATE_UPDATEIR:
653 				if ( ucTargetState == XTAPSTATE_RUNTEST )
654 				{
655 					xsvfTmsTransition( 0 );
656 					*pucTapState    = XTAPSTATE_RUNTEST;
657 				}
658 				else
659 				{
660 					xsvfTmsTransition( 1 );
661 					*pucTapState    = XTAPSTATE_SELECTDR;
662 				}
663 				break;
664 			default:
665 				iErrorCode      = XSVF_ERROR_ILLEGALSTATE;
666 				*pucTapState    = ucTargetState;    /* Exit while loop */
667 				break;
668 			}
669 			XSVFDBG_PRINTF1( 3, "   TAP State = %s\n",
670 					 xsvf_pzTapState[ *pucTapState ] );
671 		}
672 	}
673 
674 	return( iErrorCode );
675 }
676 
677 /*****************************************************************************
678  * Function:     xsvfShiftOnly
679  * Description:  Assumes that starting TAP state is SHIFT-DR or SHIFT-IR.
680  *               Shift the given TDI data into the JTAG scan chain.
681  *               Optionally, save the TDO data shifted out of the scan chain.
682  *               Last shift cycle is special:  capture last TDO, set last TDI,
683  *               but does not pulse TCK.  Caller must pulse TCK and optionally
684  *               set TMS=1 to exit shift state.
685  * Parameters:   lNumBits        - number of bits to shift.
686  *               plvTdi          - ptr to lenval for TDI data.
687  *               plvTdoCaptured  - ptr to lenval for storing captured TDO data.
688  *               iExitShift      - 1=exit at end of shift; 0=stay in Shift-DR.
689  * Returns:      void.
690  *****************************************************************************/
xsvfShiftOnly(long lNumBits,lenVal * plvTdi,lenVal * plvTdoCaptured,int iExitShift)691 void xsvfShiftOnly( long    lNumBits,
692 		    lenVal* plvTdi,
693 		    lenVal* plvTdoCaptured,
694 		    int     iExitShift )
695 {
696 	unsigned char*  pucTdi;
697 	unsigned char*  pucTdo;
698 	unsigned char   ucTdiByte;
699 	unsigned char   ucTdoByte;
700 	unsigned char   ucTdoBit;
701 	int             i;
702 
703 	/* assert( ( ( lNumBits + 7 ) / 8 ) == plvTdi->len ); */
704 
705 	/* Initialize TDO storage len == TDI len */
706 	pucTdo  = 0;
707 	if ( plvTdoCaptured )
708 	{
709 		plvTdoCaptured->len = plvTdi->len;
710 		pucTdo              = plvTdoCaptured->val + plvTdi->len;
711 	}
712 
713 	/* Shift LSB first.  val[N-1] == LSB.  val[0] == MSB. */
714 	pucTdi  = plvTdi->val + plvTdi->len;
715 	while ( lNumBits )
716 	{
717 		/* Process on a byte-basis */
718 		ucTdiByte   = (*(--pucTdi));
719 		ucTdoByte   = 0;
720 		for ( i = 0; ( lNumBits && ( i < 8 ) ); ++i )
721 		{
722 			--lNumBits;
723 			if ( iExitShift && !lNumBits )
724 			{
725 				/* Exit Shift-DR state */
726 				setPort( TMS, 1 );
727 			}
728 
729 			/* Set the new TDI value */
730 			setPort( TDI, (short)(ucTdiByte & 1) );
731 			ucTdiByte   >>= 1;
732 
733 			/* Set TCK low */
734 			setPort( TCK, 0 );
735 
736 			if ( pucTdo )
737 			{
738 				/* Save the TDO value */
739 				ucTdoBit    = readTDOBit();
740 				ucTdoByte   |= ( ucTdoBit << i );
741 			}
742 
743 			/* Set TCK high */
744 			setPort( TCK, 1 );
745 		}
746 
747 		/* Save the TDO byte value */
748 		if ( pucTdo )
749 		{
750 			(*(--pucTdo))   = ucTdoByte;
751 		}
752 	}
753 }
754 
755 /*****************************************************************************
756  * Function:     xsvfShift
757  * Description:  Goes to the given starting TAP state.
758  *               Calls xsvfShiftOnly to shift in the given TDI data and
759  *               optionally capture the TDO data.
760  *               Compares the TDO captured data against the TDO expected
761  *               data.
762  *               If a data mismatch occurs, then executes the exception
763  *               handling loop upto ucMaxRepeat times.
764  * Parameters:   pucTapState     - Ptr to current TAP state.
765  *               ucStartState    - Starting shift state: Shift-DR or Shift-IR.
766  *               lNumBits        - number of bits to shift.
767  *               plvTdi          - ptr to lenval for TDI data.
768  *               plvTdoCaptured  - ptr to lenval for storing TDO data.
769  *               plvTdoExpected  - ptr to expected TDO data.
770  *               plvTdoMask      - ptr to TDO mask.
771  *               ucEndState      - state in which to end the shift.
772  *               lRunTestTime    - amount of time to wait after the shift.
773  *               ucMaxRepeat     - Maximum number of retries on TDO mismatch.
774  * Returns:      int             - 0 = success; otherwise TDO mismatch.
775  * Notes:        XC9500XL-only Optimization:
776  *               Skip the waitTime() if plvTdoMask->val[0:plvTdoMask->len-1]
777  *               is NOT all zeros and sMatch==1.
778  *****************************************************************************/
xsvfShift(unsigned char * pucTapState,unsigned char ucStartState,long lNumBits,lenVal * plvTdi,lenVal * plvTdoCaptured,lenVal * plvTdoExpected,lenVal * plvTdoMask,unsigned char ucEndState,long lRunTestTime,unsigned char ucMaxRepeat)779 int xsvfShift( unsigned char*   pucTapState,
780 	       unsigned char    ucStartState,
781 	       long             lNumBits,
782 	       lenVal*          plvTdi,
783 	       lenVal*          plvTdoCaptured,
784 	       lenVal*          plvTdoExpected,
785 	       lenVal*          plvTdoMask,
786 	       unsigned char    ucEndState,
787 	       long             lRunTestTime,
788 	       unsigned char    ucMaxRepeat )
789 {
790 	int             iErrorCode;
791 	int             iMismatch;
792 	unsigned char   ucRepeat;
793 	int             iExitShift;
794 
795 	iErrorCode  = XSVF_ERROR_NONE;
796 	iMismatch   = 0;
797 	ucRepeat    = 0;
798 	iExitShift  = ( ucStartState != ucEndState );
799 
800 	XSVFDBG_PRINTF1( 3, "   Shift Length = %ld\n", lNumBits );
801 	XSVFDBG_PRINTF( 4, "    TDI          = ");
802 	XSVFDBG_PRINTLENVAL( 4, plvTdi );
803 	XSVFDBG_PRINTF( 4, "\n");
804 	XSVFDBG_PRINTF( 4, "    TDO Expected = ");
805 	XSVFDBG_PRINTLENVAL( 4, plvTdoExpected );
806 	XSVFDBG_PRINTF( 4, "\n");
807 
808 	if ( !lNumBits )
809 	{
810 		/* Compatibility with XSVF2.00:  XSDR 0 = no shift, but wait in RTI */
811 		if ( lRunTestTime )
812 		{
813 			/* Wait for prespecified XRUNTEST time */
814 			xsvfGotoTapState( pucTapState, XTAPSTATE_RUNTEST );
815 			XSVFDBG_PRINTF1( 3, "   Wait = %ld usec\n", lRunTestTime );
816 			waitTime( lRunTestTime );
817 		}
818 	}
819 	else
820 	{
821 		do
822 		{
823 			/* Goto Shift-DR or Shift-IR */
824 			xsvfGotoTapState( pucTapState, ucStartState );
825 
826 			/* Shift TDI and capture TDO */
827 			xsvfShiftOnly( lNumBits, plvTdi, plvTdoCaptured, iExitShift );
828 
829 			if ( plvTdoExpected )
830 			{
831 				/* Compare TDO data to expected TDO data */
832 				iMismatch   = !EqualLenVal( plvTdoExpected,
833 							    plvTdoCaptured,
834 							    plvTdoMask );
835 			}
836 
837 			if ( iExitShift )
838 			{
839 				/* Update TAP state:  Shift->Exit */
840 				++(*pucTapState);
841 				XSVFDBG_PRINTF1( 3, "   TAP State = %s\n",
842 						 xsvf_pzTapState[ *pucTapState ] );
843 
844 				if ( iMismatch && lRunTestTime && ( ucRepeat < ucMaxRepeat ) )
845 				{
846 					XSVFDBG_PRINTF( 4, "    TDO Expected = ");
847 					XSVFDBG_PRINTLENVAL( 4, plvTdoExpected );
848 					XSVFDBG_PRINTF( 4, "\n");
849 					XSVFDBG_PRINTF( 4, "    TDO Captured = ");
850 					XSVFDBG_PRINTLENVAL( 4, plvTdoCaptured );
851 					XSVFDBG_PRINTF( 4, "\n");
852 					XSVFDBG_PRINTF( 4, "    TDO Mask     = ");
853 					XSVFDBG_PRINTLENVAL( 4, plvTdoMask );
854 					XSVFDBG_PRINTF( 4, "\n");
855 					XSVFDBG_PRINTF1( 3, "   Retry #%d\n", ( ucRepeat + 1 ) );
856 					/* Do exception handling retry - ShiftDR only */
857 					xsvfGotoTapState( pucTapState, XTAPSTATE_PAUSEDR );
858 					/* Shift 1 extra bit */
859 					xsvfGotoTapState( pucTapState, XTAPSTATE_SHIFTDR );
860 					/* Increment RUNTEST time by an additional 25% */
861 					lRunTestTime    += ( lRunTestTime >> 2 );
862 				}
863 				else
864 				{
865 					/* Do normal exit from Shift-XR */
866 					xsvfGotoTapState( pucTapState, ucEndState );
867 				}
868 
869 				if ( lRunTestTime )
870 				{
871 					/* Wait for prespecified XRUNTEST time */
872 					xsvfGotoTapState( pucTapState, XTAPSTATE_RUNTEST );
873 					XSVFDBG_PRINTF1( 3, "   Wait = %ld usec\n", lRunTestTime );
874 					waitTime( lRunTestTime );
875 				}
876 			}
877 		} while ( iMismatch && ( ucRepeat++ < ucMaxRepeat ) );
878 	}
879 
880 	if ( iMismatch )
881 	{
882 		XSVFDBG_PRINTF( 1, " TDO Expected = ");
883 		XSVFDBG_PRINTLENVAL( 1, plvTdoExpected );
884 		XSVFDBG_PRINTF( 1, "\n");
885 		XSVFDBG_PRINTF( 1, " TDO Captured = ");
886 		XSVFDBG_PRINTLENVAL( 1, plvTdoCaptured );
887 		XSVFDBG_PRINTF( 1, "\n");
888 		XSVFDBG_PRINTF( 1, " TDO Mask     = ");
889 		XSVFDBG_PRINTLENVAL( 1, plvTdoMask );
890 		XSVFDBG_PRINTF( 1, "\n");
891 		if ( ucMaxRepeat && ( ucRepeat > ucMaxRepeat ) )
892 		{
893 			iErrorCode  = XSVF_ERROR_MAXRETRIES;
894 		}
895 		else
896 		{
897 			iErrorCode  = XSVF_ERROR_TDOMISMATCH;
898 		}
899 	}
900 
901 	return( iErrorCode );
902 }
903 
904 /*****************************************************************************
905  * Function:     xsvfBasicXSDRTDO
906  * Description:  Get the XSDRTDO parameters and execute the XSDRTDO command.
907  *               This is the common function for all XSDRTDO commands.
908  * Parameters:   pucTapState         - Current TAP state.
909  *               lShiftLengthBits    - number of bits to shift.
910  *               sShiftLengthBytes   - number of bytes to read.
911  *               plvTdi              - ptr to lenval for TDI data.
912  *               lvTdoCaptured       - ptr to lenval for storing TDO data.
913  *               iEndState           - state in which to end the shift.
914  *               lRunTestTime        - amount of time to wait after the shift.
915  *               ucMaxRepeat         - maximum xc9500/xl retries.
916  * Returns:      int                 - 0 = success; otherwise TDO mismatch.
917  *****************************************************************************/
xsvfBasicXSDRTDO(unsigned char * pucTapState,long lShiftLengthBits,short sShiftLengthBytes,lenVal * plvTdi,lenVal * plvTdoCaptured,lenVal * plvTdoExpected,lenVal * plvTdoMask,unsigned char ucEndState,long lRunTestTime,unsigned char ucMaxRepeat)918 int xsvfBasicXSDRTDO( unsigned char*    pucTapState,
919 		      long              lShiftLengthBits,
920 		      short             sShiftLengthBytes,
921 		      lenVal*           plvTdi,
922 		      lenVal*           plvTdoCaptured,
923 		      lenVal*           plvTdoExpected,
924 		      lenVal*           plvTdoMask,
925 		      unsigned char     ucEndState,
926 		      long              lRunTestTime,
927 		      unsigned char     ucMaxRepeat )
928 {
929 	readVal( plvTdi, sShiftLengthBytes );
930 	if ( plvTdoExpected )
931 	{
932 		readVal( plvTdoExpected, sShiftLengthBytes );
933 	}
934 	return( xsvfShift( pucTapState, XTAPSTATE_SHIFTDR, lShiftLengthBits,
935 			   plvTdi, plvTdoCaptured, plvTdoExpected, plvTdoMask,
936 			   ucEndState, lRunTestTime, ucMaxRepeat ) );
937 }
938 
939 /*****************************************************************************
940  * Function:     xsvfDoSDRMasking
941  * Description:  Update the data value with the next XSDRINC data and address.
942  * Example:      dataVal=0x01ff, nextData=0xab, addressMask=0x0100,
943  *               dataMask=0x00ff, should set dataVal to 0x02ab
944  * Parameters:   plvTdi          - The current TDI value.
945  *               plvNextData     - the next data value.
946  *               plvAddressMask  - the address mask.
947  *               plvDataMask     - the data mask.
948  * Returns:      void.
949  *****************************************************************************/
950 #ifdef  XSVF_SUPPORT_COMPRESSION
xsvfDoSDRMasking(lenVal * plvTdi,lenVal * plvNextData,lenVal * plvAddressMask,lenVal * plvDataMask)951 void xsvfDoSDRMasking( lenVal*  plvTdi,
952 		       lenVal*  plvNextData,
953 		       lenVal*  plvAddressMask,
954 		       lenVal*  plvDataMask )
955 {
956 	int             i;
957 	unsigned char   ucTdi;
958 	unsigned char   ucTdiMask;
959 	unsigned char   ucDataMask;
960 	unsigned char   ucNextData;
961 	unsigned char   ucNextMask;
962 	short           sNextData;
963 
964 	/* add the address Mask to dataVal and return as a new dataVal */
965 	addVal( plvTdi, plvTdi, plvAddressMask );
966 
967 	ucNextData  = 0;
968 	ucNextMask  = 0;
969 	sNextData   = plvNextData->len;
970 	for ( i = plvDataMask->len - 1; i >= 0; --i )
971 	{
972 		/* Go through data mask in reverse order looking for mask (1) bits */
973 		ucDataMask  = plvDataMask->val[ i ];
974 		if ( ucDataMask )
975 		{
976 			/* Retrieve the corresponding TDI byte value */
977 			ucTdi       = plvTdi->val[ i ];
978 
979 			/* For each bit in the data mask byte, look for 1's */
980 			ucTdiMask   = 1;
981 			while ( ucDataMask )
982 			{
983 				if ( ucDataMask & 1 )
984 				{
985 					if ( !ucNextMask )
986 					{
987 						/* Get the next data byte */
988 						ucNextData  = plvNextData->val[ --sNextData ];
989 						ucNextMask  = 1;
990 					}
991 
992 					/* Set or clear the data bit according to the next data */
993 					if ( ucNextData & ucNextMask )
994 					{
995 						ucTdi   |= ucTdiMask;       /* Set bit */
996 					}
997 					else
998 					{
999 						ucTdi   &= ( ~ucTdiMask );  /* Clear bit */
1000 					}
1001 
1002 					/* Update the next data */
1003 					ucNextMask  <<= 1;
1004 				}
1005 				ucTdiMask   <<= 1;
1006 				ucDataMask  >>= 1;
1007 			}
1008 
1009 			/* Update the TDI value */
1010 			plvTdi->val[ i ]    = ucTdi;
1011 		}
1012 	}
1013 }
1014 #endif  /* XSVF_SUPPORT_COMPRESSION */
1015 
1016 /*============================================================================
1017  * XSVF Command Functions (type = TXsvfDoCmdFuncPtr)
1018  * These functions update pXsvfInfo->iErrorCode only on an error.
1019  * Otherwise, the error code is left alone.
1020  * The function returns the error code from the function.
1021  ============================================================================*/
1022 
1023 /*****************************************************************************
1024  * Function:     xsvfDoIllegalCmd
1025  * Description:  Function place holder for illegal/unsupported commands.
1026  * Parameters:   pXsvfInfo   - XSVF information pointer.
1027  * Returns:      int         - 0 = success;  non-zero = error.
1028  *****************************************************************************/
xsvfDoIllegalCmd(SXsvfInfo * pXsvfInfo)1029 int xsvfDoIllegalCmd( SXsvfInfo* pXsvfInfo )
1030 {
1031 	XSVFDBG_PRINTF2( 0, "ERROR:  Encountered unsupported command #%d (%s)\n",
1032 			 ((unsigned int)(pXsvfInfo->ucCommand)),
1033 			 ((pXsvfInfo->ucCommand < XLASTCMD)
1034 			  ? (xsvf_pzCommandName[pXsvfInfo->ucCommand])
1035 			  : "Unknown") );
1036 	pXsvfInfo->iErrorCode   = XSVF_ERROR_ILLEGALCMD;
1037 	return( pXsvfInfo->iErrorCode );
1038 }
1039 
1040 /*****************************************************************************
1041  * Function:     xsvfDoXCOMPLETE
1042  * Description:  XCOMPLETE (no parameters)
1043  *               Update complete status for XSVF player.
1044  * Parameters:   pXsvfInfo   - XSVF information pointer.
1045  * Returns:      int         - 0 = success;  non-zero = error.
1046  *****************************************************************************/
xsvfDoXCOMPLETE(SXsvfInfo * pXsvfInfo)1047 int xsvfDoXCOMPLETE( SXsvfInfo* pXsvfInfo )
1048 {
1049 	pXsvfInfo->ucComplete   = 1;
1050 	return( XSVF_ERROR_NONE );
1051 }
1052 
1053 /*****************************************************************************
1054  * Function:     xsvfDoXTDOMASK
1055  * Description:  XTDOMASK <lenVal.TdoMask[XSDRSIZE]>
1056  *               Prespecify the TDO compare mask.
1057  * Parameters:   pXsvfInfo   - XSVF information pointer.
1058  * Returns:      int         - 0 = success;  non-zero = error.
1059  *****************************************************************************/
xsvfDoXTDOMASK(SXsvfInfo * pXsvfInfo)1060 int xsvfDoXTDOMASK( SXsvfInfo* pXsvfInfo )
1061 {
1062 	readVal( &(pXsvfInfo->lvTdoMask), pXsvfInfo->sShiftLengthBytes );
1063 	XSVFDBG_PRINTF( 4, "    TDO Mask     = ");
1064 	XSVFDBG_PRINTLENVAL( 4, &(pXsvfInfo->lvTdoMask) );
1065 	XSVFDBG_PRINTF( 4, "\n");
1066 	return( XSVF_ERROR_NONE );
1067 }
1068 
1069 /*****************************************************************************
1070  * Function:     xsvfDoXSIR
1071  * Description:  XSIR <(byte)shiftlen> <lenVal.TDI[shiftlen]>
1072  *               Get the instruction and shift the instruction into the TAP.
1073  *               If prespecified XRUNTEST!=0, goto RUNTEST and wait after
1074  *               the shift for XRUNTEST usec.
1075  * Parameters:   pXsvfInfo   - XSVF information pointer.
1076  * Returns:      int         - 0 = success;  non-zero = error.
1077  *****************************************************************************/
xsvfDoXSIR(SXsvfInfo * pXsvfInfo)1078 int xsvfDoXSIR( SXsvfInfo* pXsvfInfo )
1079 {
1080 	unsigned char   ucShiftIrBits;
1081 	short           sShiftIrBytes;
1082 	int             iErrorCode;
1083 
1084 	/* Get the shift length and store */
1085 	readByte( &ucShiftIrBits );
1086 	sShiftIrBytes   = xsvfGetAsNumBytes( ucShiftIrBits );
1087 	XSVFDBG_PRINTF1( 3, "   XSIR length = %d\n",
1088 			 ((unsigned int)ucShiftIrBits) );
1089 
1090 	if ( sShiftIrBytes > MAX_LEN )
1091 	{
1092 		iErrorCode  = XSVF_ERROR_DATAOVERFLOW;
1093 	}
1094 	else
1095 	{
1096 		/* Get and store instruction to shift in */
1097 		readVal( &(pXsvfInfo->lvTdi), xsvfGetAsNumBytes( ucShiftIrBits ) );
1098 
1099 		/* Shift the data */
1100 		iErrorCode  = xsvfShift( &(pXsvfInfo->ucTapState), XTAPSTATE_SHIFTIR,
1101 					 ucShiftIrBits, &(pXsvfInfo->lvTdi),
1102 					 /*plvTdoCaptured*/0, /*plvTdoExpected*/0,
1103 					 /*plvTdoMask*/0, pXsvfInfo->ucEndIR,
1104 					 pXsvfInfo->lRunTestTime, /*ucMaxRepeat*/0 );
1105 	}
1106 
1107 	if ( iErrorCode != XSVF_ERROR_NONE )
1108 	{
1109 		pXsvfInfo->iErrorCode   = iErrorCode;
1110 	}
1111 	return( iErrorCode );
1112 }
1113 
1114 /*****************************************************************************
1115  * Function:     xsvfDoXSIR2
1116  * Description:  XSIR <(2-byte)shiftlen> <lenVal.TDI[shiftlen]>
1117  *               Get the instruction and shift the instruction into the TAP.
1118  *               If prespecified XRUNTEST!=0, goto RUNTEST and wait after
1119  *               the shift for XRUNTEST usec.
1120  * Parameters:   pXsvfInfo   - XSVF information pointer.
1121  * Returns:      int         - 0 = success;  non-zero = error.
1122  *****************************************************************************/
xsvfDoXSIR2(SXsvfInfo * pXsvfInfo)1123 int xsvfDoXSIR2( SXsvfInfo* pXsvfInfo )
1124 {
1125 	long            lShiftIrBits;
1126 	short           sShiftIrBytes;
1127 	int             iErrorCode;
1128 
1129 	/* Get the shift length and store */
1130 	readVal( &(pXsvfInfo->lvTdi), 2 );
1131 	lShiftIrBits    = value( &(pXsvfInfo->lvTdi) );
1132 	sShiftIrBytes   = xsvfGetAsNumBytes( lShiftIrBits );
1133 	XSVFDBG_PRINTF1( 3, "   XSIR2 length = %d\n", (int)lShiftIrBits);
1134 
1135 	if ( sShiftIrBytes > MAX_LEN )
1136 	{
1137 		iErrorCode  = XSVF_ERROR_DATAOVERFLOW;
1138 	}
1139 	else
1140 	{
1141 		/* Get and store instruction to shift in */
1142 		readVal( &(pXsvfInfo->lvTdi), xsvfGetAsNumBytes( lShiftIrBits ) );
1143 
1144 		/* Shift the data */
1145 		iErrorCode  = xsvfShift( &(pXsvfInfo->ucTapState), XTAPSTATE_SHIFTIR,
1146 					 lShiftIrBits, &(pXsvfInfo->lvTdi),
1147 					 /*plvTdoCaptured*/0, /*plvTdoExpected*/0,
1148 					 /*plvTdoMask*/0, pXsvfInfo->ucEndIR,
1149 					 pXsvfInfo->lRunTestTime, /*ucMaxRepeat*/0 );
1150 	}
1151 
1152 	if ( iErrorCode != XSVF_ERROR_NONE )
1153 	{
1154 		pXsvfInfo->iErrorCode   = iErrorCode;
1155 	}
1156 	return( iErrorCode );
1157 }
1158 
1159 /*****************************************************************************
1160  * Function:     xsvfDoXSDR
1161  * Description:  XSDR <lenVal.TDI[XSDRSIZE]>
1162  *               Shift the given TDI data into the JTAG scan chain.
1163  *               Compare the captured TDO with the expected TDO from the
1164  *               previous XSDRTDO command using the previously specified
1165  *               XTDOMASK.
1166  * Parameters:   pXsvfInfo   - XSVF information pointer.
1167  * Returns:      int         - 0 = success;  non-zero = error.
1168  *****************************************************************************/
xsvfDoXSDR(SXsvfInfo * pXsvfInfo)1169 int xsvfDoXSDR( SXsvfInfo* pXsvfInfo )
1170 {
1171 	int iErrorCode;
1172 	readVal( &(pXsvfInfo->lvTdi), pXsvfInfo->sShiftLengthBytes );
1173 	/* use TDOExpected from last XSDRTDO instruction */
1174 	iErrorCode  = xsvfShift( &(pXsvfInfo->ucTapState), XTAPSTATE_SHIFTDR,
1175 				 pXsvfInfo->lShiftLengthBits, &(pXsvfInfo->lvTdi),
1176 				 &(pXsvfInfo->lvTdoCaptured),
1177 				 &(pXsvfInfo->lvTdoExpected),
1178 				 &(pXsvfInfo->lvTdoMask), pXsvfInfo->ucEndDR,
1179 				 pXsvfInfo->lRunTestTime, pXsvfInfo->ucMaxRepeat );
1180 	if ( iErrorCode != XSVF_ERROR_NONE )
1181 	{
1182 		pXsvfInfo->iErrorCode   = iErrorCode;
1183 	}
1184 	return( iErrorCode );
1185 }
1186 
1187 /*****************************************************************************
1188  * Function:     xsvfDoXRUNTEST
1189  * Description:  XRUNTEST <uint32>
1190  *               Prespecify the XRUNTEST wait time for shift operations.
1191  * Parameters:   pXsvfInfo   - XSVF information pointer.
1192  * Returns:      int         - 0 = success;  non-zero = error.
1193  *****************************************************************************/
xsvfDoXRUNTEST(SXsvfInfo * pXsvfInfo)1194 int xsvfDoXRUNTEST( SXsvfInfo* pXsvfInfo )
1195 {
1196 	readVal( &(pXsvfInfo->lvTdi), 4 );
1197 	pXsvfInfo->lRunTestTime = value( &(pXsvfInfo->lvTdi) );
1198 	XSVFDBG_PRINTF1( 3, "   XRUNTEST = %ld\n", pXsvfInfo->lRunTestTime );
1199 	return( XSVF_ERROR_NONE );
1200 }
1201 
1202 /*****************************************************************************
1203  * Function:     xsvfDoXREPEAT
1204  * Description:  XREPEAT <byte>
1205  *               Prespecify the maximum number of XC9500/XL retries.
1206  * Parameters:   pXsvfInfo   - XSVF information pointer.
1207  * Returns:      int         - 0 = success;  non-zero = error.
1208  *****************************************************************************/
xsvfDoXREPEAT(SXsvfInfo * pXsvfInfo)1209 int xsvfDoXREPEAT( SXsvfInfo* pXsvfInfo )
1210 {
1211 	readByte( &(pXsvfInfo->ucMaxRepeat) );
1212 	XSVFDBG_PRINTF1( 3, "   XREPEAT = %d\n",
1213 			 ((unsigned int)(pXsvfInfo->ucMaxRepeat)) );
1214 	return( XSVF_ERROR_NONE );
1215 }
1216 
1217 /*****************************************************************************
1218  * Function:     xsvfDoXSDRSIZE
1219  * Description:  XSDRSIZE <uint32>
1220  *               Prespecify the XRUNTEST wait time for shift operations.
1221  * Parameters:   pXsvfInfo   - XSVF information pointer.
1222  * Returns:      int         - 0 = success;  non-zero = error.
1223  *****************************************************************************/
xsvfDoXSDRSIZE(SXsvfInfo * pXsvfInfo)1224 int xsvfDoXSDRSIZE( SXsvfInfo* pXsvfInfo )
1225 {
1226 	int iErrorCode;
1227 	iErrorCode  = XSVF_ERROR_NONE;
1228 	readVal( &(pXsvfInfo->lvTdi), 4 );
1229 	pXsvfInfo->lShiftLengthBits = value( &(pXsvfInfo->lvTdi) );
1230 	pXsvfInfo->sShiftLengthBytes= xsvfGetAsNumBytes( pXsvfInfo->lShiftLengthBits );
1231 	XSVFDBG_PRINTF1( 3, "   XSDRSIZE = %ld\n", pXsvfInfo->lShiftLengthBits );
1232 	if ( pXsvfInfo->sShiftLengthBytes > MAX_LEN )
1233 	{
1234 		iErrorCode  = XSVF_ERROR_DATAOVERFLOW;
1235 		pXsvfInfo->iErrorCode   = iErrorCode;
1236 	}
1237 	return( iErrorCode );
1238 }
1239 
1240 /*****************************************************************************
1241  * Function:     xsvfDoXSDRTDO
1242  * Description:  XSDRTDO <lenVal.TDI[XSDRSIZE]> <lenVal.TDO[XSDRSIZE]>
1243  *               Get the TDI and expected TDO values.  Then, shift.
1244  *               Compare the expected TDO with the captured TDO using the
1245  *               prespecified XTDOMASK.
1246  * Parameters:   pXsvfInfo   - XSVF information pointer.
1247  * Returns:      int         - 0 = success;  non-zero = error.
1248  *****************************************************************************/
xsvfDoXSDRTDO(SXsvfInfo * pXsvfInfo)1249 int xsvfDoXSDRTDO( SXsvfInfo* pXsvfInfo )
1250 {
1251 	int iErrorCode;
1252 	iErrorCode  = xsvfBasicXSDRTDO( &(pXsvfInfo->ucTapState),
1253 					pXsvfInfo->lShiftLengthBits,
1254 					pXsvfInfo->sShiftLengthBytes,
1255 					&(pXsvfInfo->lvTdi),
1256 					&(pXsvfInfo->lvTdoCaptured),
1257 					&(pXsvfInfo->lvTdoExpected),
1258 					&(pXsvfInfo->lvTdoMask),
1259 					pXsvfInfo->ucEndDR,
1260 					pXsvfInfo->lRunTestTime,
1261 					pXsvfInfo->ucMaxRepeat );
1262 	if ( iErrorCode != XSVF_ERROR_NONE )
1263 	{
1264 		pXsvfInfo->iErrorCode   = iErrorCode;
1265 	}
1266 	return( iErrorCode );
1267 }
1268 
1269 /*****************************************************************************
1270  * Function:     xsvfDoXSETSDRMASKS
1271  * Description:  XSETSDRMASKS <lenVal.AddressMask[XSDRSIZE]>
1272  *                            <lenVal.DataMask[XSDRSIZE]>
1273  *               Get the prespecified address and data mask for the XSDRINC
1274  *               command.
1275  *               Used for xc9500/xl compressed XSVF data.
1276  * Parameters:   pXsvfInfo   - XSVF information pointer.
1277  * Returns:      int         - 0 = success;  non-zero = error.
1278  *****************************************************************************/
1279 #ifdef  XSVF_SUPPORT_COMPRESSION
xsvfDoXSETSDRMASKS(SXsvfInfo * pXsvfInfo)1280 int xsvfDoXSETSDRMASKS( SXsvfInfo* pXsvfInfo )
1281 {
1282 	/* read the addressMask */
1283 	readVal( &(pXsvfInfo->lvAddressMask), pXsvfInfo->sShiftLengthBytes );
1284 	/* read the dataMask    */
1285 	readVal( &(pXsvfInfo->lvDataMask), pXsvfInfo->sShiftLengthBytes );
1286 
1287 	XSVFDBG_PRINTF( 4, "    Address Mask = " );
1288 	XSVFDBG_PRINTLENVAL( 4, &(pXsvfInfo->lvAddressMask) );
1289 	XSVFDBG_PRINTF( 4, "\n" );
1290 	XSVFDBG_PRINTF( 4, "    Data Mask    = " );
1291 	XSVFDBG_PRINTLENVAL( 4, &(pXsvfInfo->lvDataMask) );
1292 	XSVFDBG_PRINTF( 4, "\n" );
1293 
1294 	return( XSVF_ERROR_NONE );
1295 }
1296 #endif  /* XSVF_SUPPORT_COMPRESSION */
1297 
1298 /*****************************************************************************
1299  * Function:     xsvfDoXSDRINC
1300  * Description:  XSDRINC <lenVal.firstTDI[XSDRSIZE]> <byte(numTimes)>
1301  *                       <lenVal.data[XSETSDRMASKS.dataMask.len]> ...
1302  *               Get the XSDRINC parameters and execute the XSDRINC command.
1303  *               XSDRINC starts by loading the first TDI shift value.
1304  *               Then, for numTimes, XSDRINC gets the next piece of data,
1305  *               replaces the bits from the starting TDI as defined by the
1306  *               XSETSDRMASKS.dataMask, adds the address mask from
1307  *               XSETSDRMASKS.addressMask, shifts the new TDI value,
1308  *               and compares the TDO to the expected TDO from the previous
1309  *               XSDRTDO command using the XTDOMASK.
1310  *               Used for xc9500/xl compressed XSVF data.
1311  * Parameters:   pXsvfInfo   - XSVF information pointer.
1312  * Returns:      int         - 0 = success;  non-zero = error.
1313  *****************************************************************************/
1314 #ifdef  XSVF_SUPPORT_COMPRESSION
xsvfDoXSDRINC(SXsvfInfo * pXsvfInfo)1315 int xsvfDoXSDRINC( SXsvfInfo* pXsvfInfo )
1316 {
1317 	int             iErrorCode;
1318 	int             iDataMaskLen;
1319 	unsigned char   ucDataMask;
1320 	unsigned char   ucNumTimes;
1321 	unsigned char   i;
1322 
1323 	readVal( &(pXsvfInfo->lvTdi), pXsvfInfo->sShiftLengthBytes );
1324 	iErrorCode  = xsvfShift( &(pXsvfInfo->ucTapState), XTAPSTATE_SHIFTDR,
1325 				 pXsvfInfo->lShiftLengthBits,
1326 				 &(pXsvfInfo->lvTdi), &(pXsvfInfo->lvTdoCaptured),
1327 				 &(pXsvfInfo->lvTdoExpected),
1328 				 &(pXsvfInfo->lvTdoMask), pXsvfInfo->ucEndDR,
1329 				 pXsvfInfo->lRunTestTime, pXsvfInfo->ucMaxRepeat );
1330 	if ( !iErrorCode )
1331 	{
1332 		/* Calculate number of data mask bits */
1333 		iDataMaskLen    = 0;
1334 		for ( i = 0; i < pXsvfInfo->lvDataMask.len; ++i )
1335 		{
1336 			ucDataMask  = pXsvfInfo->lvDataMask.val[ i ];
1337 			while ( ucDataMask )
1338 			{
1339 				iDataMaskLen    += ( ucDataMask & 1 );
1340 				ucDataMask      >>= 1;
1341 			}
1342 		}
1343 
1344 		/* Get the number of data pieces, i.e. number of times to shift */
1345 		readByte( &ucNumTimes );
1346 
1347 		/* For numTimes, get data, fix TDI, and shift */
1348 		for ( i = 0; !iErrorCode && ( i < ucNumTimes ); ++i )
1349 		{
1350 			readVal( &(pXsvfInfo->lvNextData),
1351 				 xsvfGetAsNumBytes( iDataMaskLen ) );
1352 			xsvfDoSDRMasking( &(pXsvfInfo->lvTdi),
1353 					  &(pXsvfInfo->lvNextData),
1354 					  &(pXsvfInfo->lvAddressMask),
1355 					  &(pXsvfInfo->lvDataMask) );
1356 			iErrorCode  = xsvfShift( &(pXsvfInfo->ucTapState),
1357 						 XTAPSTATE_SHIFTDR,
1358 						 pXsvfInfo->lShiftLengthBits,
1359 						 &(pXsvfInfo->lvTdi),
1360 						 &(pXsvfInfo->lvTdoCaptured),
1361 						 &(pXsvfInfo->lvTdoExpected),
1362 						 &(pXsvfInfo->lvTdoMask),
1363 						 pXsvfInfo->ucEndDR,
1364 						 pXsvfInfo->lRunTestTime,
1365 						 pXsvfInfo->ucMaxRepeat );
1366 		}
1367 	}
1368 	if ( iErrorCode != XSVF_ERROR_NONE )
1369 	{
1370 		pXsvfInfo->iErrorCode   = iErrorCode;
1371 	}
1372 	return( iErrorCode );
1373 }
1374 #endif  /* XSVF_SUPPORT_COMPRESSION */
1375 
1376 /*****************************************************************************
1377  * Function:     xsvfDoXSDRBCE
1378  * Description:  XSDRB/XSDRC/XSDRE <lenVal.TDI[XSDRSIZE]>
1379  *               If not already in SHIFTDR, goto SHIFTDR.
1380  *               Shift the given TDI data into the JTAG scan chain.
1381  *               Ignore TDO.
1382  *               If cmd==XSDRE, then goto ENDDR.  Otherwise, stay in ShiftDR.
1383  *               XSDRB, XSDRC, and XSDRE are the same implementation.
1384  * Parameters:   pXsvfInfo   - XSVF information pointer.
1385  * Returns:      int         - 0 = success;  non-zero = error.
1386  *****************************************************************************/
xsvfDoXSDRBCE(SXsvfInfo * pXsvfInfo)1387 int xsvfDoXSDRBCE( SXsvfInfo* pXsvfInfo )
1388 {
1389 	unsigned char   ucEndDR;
1390 	int             iErrorCode;
1391 	ucEndDR = (unsigned char)(( pXsvfInfo->ucCommand == XSDRE ) ?
1392 				  pXsvfInfo->ucEndDR : XTAPSTATE_SHIFTDR);
1393 	iErrorCode  = xsvfBasicXSDRTDO( &(pXsvfInfo->ucTapState),
1394 					pXsvfInfo->lShiftLengthBits,
1395 					pXsvfInfo->sShiftLengthBytes,
1396 					&(pXsvfInfo->lvTdi),
1397 					/*plvTdoCaptured*/0, /*plvTdoExpected*/0,
1398 					/*plvTdoMask*/0, ucEndDR,
1399 					/*lRunTestTime*/0, /*ucMaxRepeat*/0 );
1400 	if ( iErrorCode != XSVF_ERROR_NONE )
1401 	{
1402 		pXsvfInfo->iErrorCode   = iErrorCode;
1403 	}
1404 	return( iErrorCode );
1405 }
1406 
1407 /*****************************************************************************
1408  * Function:     xsvfDoXSDRTDOBCE
1409  * Description:  XSDRB/XSDRC/XSDRE <lenVal.TDI[XSDRSIZE]> <lenVal.TDO[XSDRSIZE]>
1410  *               If not already in SHIFTDR, goto SHIFTDR.
1411  *               Shift the given TDI data into the JTAG scan chain.
1412  *               Compare TDO, but do NOT use XTDOMASK.
1413  *               If cmd==XSDRTDOE, then goto ENDDR.  Otherwise, stay in ShiftDR.
1414  *               XSDRTDOB, XSDRTDOC, and XSDRTDOE are the same implementation.
1415  * Parameters:   pXsvfInfo   - XSVF information pointer.
1416  * Returns:      int         - 0 = success;  non-zero = error.
1417  *****************************************************************************/
xsvfDoXSDRTDOBCE(SXsvfInfo * pXsvfInfo)1418 int xsvfDoXSDRTDOBCE( SXsvfInfo* pXsvfInfo )
1419 {
1420 	unsigned char   ucEndDR;
1421 	int             iErrorCode;
1422 	ucEndDR = (unsigned char)(( pXsvfInfo->ucCommand == XSDRTDOE ) ?
1423 				  pXsvfInfo->ucEndDR : XTAPSTATE_SHIFTDR);
1424 	iErrorCode  = xsvfBasicXSDRTDO( &(pXsvfInfo->ucTapState),
1425 					pXsvfInfo->lShiftLengthBits,
1426 					pXsvfInfo->sShiftLengthBytes,
1427 					&(pXsvfInfo->lvTdi),
1428 					&(pXsvfInfo->lvTdoCaptured),
1429 					&(pXsvfInfo->lvTdoExpected),
1430 					/*plvTdoMask*/0, ucEndDR,
1431 					/*lRunTestTime*/0, /*ucMaxRepeat*/0 );
1432 	if ( iErrorCode != XSVF_ERROR_NONE )
1433 	{
1434 		pXsvfInfo->iErrorCode   = iErrorCode;
1435 	}
1436 	return( iErrorCode );
1437 }
1438 
1439 /*****************************************************************************
1440  * Function:     xsvfDoXSTATE
1441  * Description:  XSTATE <byte>
1442  *               <byte> == XTAPSTATE;
1443  *               Get the state parameter and transition the TAP to that state.
1444  * Parameters:   pXsvfInfo   - XSVF information pointer.
1445  * Returns:      int         - 0 = success;  non-zero = error.
1446  *****************************************************************************/
xsvfDoXSTATE(SXsvfInfo * pXsvfInfo)1447 int xsvfDoXSTATE( SXsvfInfo* pXsvfInfo )
1448 {
1449 	unsigned char   ucNextState;
1450 	int             iErrorCode;
1451 	readByte( &ucNextState );
1452 	iErrorCode  = xsvfGotoTapState( &(pXsvfInfo->ucTapState), ucNextState );
1453 	if ( iErrorCode != XSVF_ERROR_NONE )
1454 	{
1455 		pXsvfInfo->iErrorCode   = iErrorCode;
1456 	}
1457 	return( iErrorCode );
1458 }
1459 
1460 /*****************************************************************************
1461  * Function:     xsvfDoXENDXR
1462  * Description:  XENDIR/XENDDR <byte>
1463  *               <byte>:  0 = RUNTEST;  1 = PAUSE.
1464  *               Get the prespecified XENDIR or XENDDR.
1465  *               Both XENDIR and XENDDR use the same implementation.
1466  * Parameters:   pXsvfInfo   - XSVF information pointer.
1467  * Returns:      int         - 0 = success;  non-zero = error.
1468  *****************************************************************************/
xsvfDoXENDXR(SXsvfInfo * pXsvfInfo)1469 int xsvfDoXENDXR( SXsvfInfo* pXsvfInfo )
1470 {
1471 	int             iErrorCode;
1472 	unsigned char   ucEndState;
1473 
1474 	iErrorCode  = XSVF_ERROR_NONE;
1475 	readByte( &ucEndState );
1476 	if ( ( ucEndState != XENDXR_RUNTEST ) && ( ucEndState != XENDXR_PAUSE ) )
1477 	{
1478 		iErrorCode  = XSVF_ERROR_ILLEGALSTATE;
1479 	}
1480 	else
1481 	{
1482 
1483 		if ( pXsvfInfo->ucCommand == XENDIR )
1484 		{
1485 			if ( ucEndState == XENDXR_RUNTEST )
1486 			{
1487 				pXsvfInfo->ucEndIR  = XTAPSTATE_RUNTEST;
1488 			}
1489 			else
1490 			{
1491 				pXsvfInfo->ucEndIR  = XTAPSTATE_PAUSEIR;
1492 			}
1493 			XSVFDBG_PRINTF1( 3, "   ENDIR State = %s\n",
1494 					 xsvf_pzTapState[ pXsvfInfo->ucEndIR ] );
1495 		}
1496 		else    /* XENDDR */
1497 		{
1498 			if ( ucEndState == XENDXR_RUNTEST )
1499 			{
1500 				pXsvfInfo->ucEndDR  = XTAPSTATE_RUNTEST;
1501 			}
1502 			else
1503 			{
1504 				pXsvfInfo->ucEndDR  = XTAPSTATE_PAUSEDR;
1505 			}
1506 			XSVFDBG_PRINTF1( 3, "   ENDDR State = %s\n",
1507 					 xsvf_pzTapState[ pXsvfInfo->ucEndDR ] );
1508 		}
1509 	}
1510 
1511 	if ( iErrorCode != XSVF_ERROR_NONE )
1512 	{
1513 		pXsvfInfo->iErrorCode   = iErrorCode;
1514 	}
1515 	return( iErrorCode );
1516 }
1517 
1518 /*****************************************************************************
1519  * Function:     xsvfDoXCOMMENT
1520  * Description:  XCOMMENT <text string ending in \0>
1521  *               <text string ending in \0> == text comment;
1522  *               Arbitrary comment embedded in the XSVF.
1523  * Parameters:   pXsvfInfo   - XSVF information pointer.
1524  * Returns:      int         - 0 = success;  non-zero = error.
1525  *****************************************************************************/
xsvfDoXCOMMENT(SXsvfInfo * pXsvfInfo)1526 int xsvfDoXCOMMENT( SXsvfInfo* pXsvfInfo )
1527 {
1528 	/* Use the comment for debugging */
1529 	/* Otherwise, read through the comment to the end '\0' and ignore */
1530 	unsigned char   ucText;
1531 
1532 	if ( xsvf_iDebugLevel > 0 )
1533 	{
1534 		putc( ' ' );
1535 	}
1536 
1537 	do
1538 	{
1539 		readByte( &ucText );
1540 		if ( xsvf_iDebugLevel > 0 )
1541 		{
1542 			putc( ucText ? ucText : '\n' );
1543 		}
1544 	} while ( ucText );
1545 
1546 	pXsvfInfo->iErrorCode   = XSVF_ERROR_NONE;
1547 
1548 	return( pXsvfInfo->iErrorCode );
1549 }
1550 
1551 /*****************************************************************************
1552  * Function:     xsvfDoXWAIT
1553  * Description:  XWAIT <wait_state> <end_state> <wait_time>
1554  *               If not already in <wait_state>, then go to <wait_state>.
1555  *               Wait in <wait_state> for <wait_time> microseconds.
1556  *               Finally, if not already in <end_state>, then goto <end_state>.
1557  * Parameters:   pXsvfInfo   - XSVF information pointer.
1558  * Returns:      int         - 0 = success;  non-zero = error.
1559  *****************************************************************************/
xsvfDoXWAIT(SXsvfInfo * pXsvfInfo)1560 int xsvfDoXWAIT( SXsvfInfo* pXsvfInfo )
1561 {
1562 	unsigned char   ucWaitState;
1563 	unsigned char   ucEndState;
1564 	long            lWaitTime;
1565 
1566 	/* Get Parameters */
1567 	/* <wait_state> */
1568 	readVal( &(pXsvfInfo->lvTdi), 1 );
1569 	ucWaitState = pXsvfInfo->lvTdi.val[0];
1570 
1571 	/* <end_state> */
1572 	readVal( &(pXsvfInfo->lvTdi), 1 );
1573 	ucEndState = pXsvfInfo->lvTdi.val[0];
1574 
1575 	/* <wait_time> */
1576 	readVal( &(pXsvfInfo->lvTdi), 4 );
1577 	lWaitTime = value( &(pXsvfInfo->lvTdi) );
1578 	XSVFDBG_PRINTF2( 3, "   XWAIT:  state = %s; time = %ld\n",
1579 			 xsvf_pzTapState[ ucWaitState ], lWaitTime );
1580 
1581 	/* If not already in <wait_state>, go to <wait_state> */
1582 	if ( pXsvfInfo->ucTapState != ucWaitState )
1583 	{
1584 		xsvfGotoTapState( &(pXsvfInfo->ucTapState), ucWaitState );
1585 	}
1586 
1587 	/* Wait for <wait_time> microseconds */
1588 	waitTime( lWaitTime );
1589 
1590 	/* If not already in <end_state>, go to <end_state> */
1591 	if ( pXsvfInfo->ucTapState != ucEndState )
1592 	{
1593 		xsvfGotoTapState( &(pXsvfInfo->ucTapState), ucEndState );
1594 	}
1595 
1596 	return( XSVF_ERROR_NONE );
1597 }
1598 
1599 
1600 /*============================================================================
1601  * Execution Control Functions
1602  ============================================================================*/
1603 
1604 /*****************************************************************************
1605  * Function:     xsvfInitialize
1606  * Description:  Initialize the xsvf player.
1607  *               Call this before running the player to initialize the data
1608  *               in the SXsvfInfo struct.
1609  *               xsvfCleanup is called to clean up the data in SXsvfInfo
1610  *               after the XSVF is played.
1611  * Parameters:   pXsvfInfo   - ptr to the XSVF information.
1612  * Returns:      int - 0 = success; otherwise error.
1613  *****************************************************************************/
xsvfInitialize(SXsvfInfo * pXsvfInfo)1614 int xsvfInitialize( SXsvfInfo* pXsvfInfo )
1615 {
1616 	/* Initialize values */
1617 	pXsvfInfo->iErrorCode   = xsvfInfoInit( pXsvfInfo );
1618 
1619 	if ( !pXsvfInfo->iErrorCode )
1620 	{
1621 		/* Initialize the TAPs */
1622 		pXsvfInfo->iErrorCode   = xsvfGotoTapState( &(pXsvfInfo->ucTapState),
1623 							    XTAPSTATE_RESET );
1624 	}
1625 
1626 	return( pXsvfInfo->iErrorCode );
1627 }
1628 
1629 /*****************************************************************************
1630  * Function:     xsvfRun
1631  * Description:  Run the xsvf player for a single command and return.
1632  *               First, call xsvfInitialize.
1633  *               Then, repeatedly call this function until an error is detected
1634  *               or until the pXsvfInfo->ucComplete variable is non-zero.
1635  *               Finally, call xsvfCleanup to cleanup any remnants.
1636  * Parameters:   pXsvfInfo   - ptr to the XSVF information.
1637  * Returns:      int         - 0 = success; otherwise error.
1638  *****************************************************************************/
xsvfRun(SXsvfInfo * pXsvfInfo)1639 int xsvfRun( SXsvfInfo* pXsvfInfo )
1640 {
1641 	/* Process the XSVF commands */
1642 	if ( (!pXsvfInfo->iErrorCode) && (!pXsvfInfo->ucComplete) )
1643 	{
1644 		/* read 1 byte for the instruction */
1645 		readByte( &(pXsvfInfo->ucCommand) );
1646 		++(pXsvfInfo->lCommandCount);
1647 
1648 		if ( pXsvfInfo->ucCommand < XLASTCMD )
1649 		{
1650 			/* Execute the command.  Func sets error code. */
1651 			XSVFDBG_PRINTF1( 2, "  %s\n",
1652 					 xsvf_pzCommandName[pXsvfInfo->ucCommand] );
1653 			/* If your compiler cannot take this form,
1654 			   then convert to a switch statement */
1655 #if 0 /* test-only */
1656 			xsvf_pfDoCmd[ pXsvfInfo->ucCommand ]( pXsvfInfo );
1657 #else
1658 			switch (pXsvfInfo->ucCommand) {
1659 			case 0:
1660 				xsvfDoXCOMPLETE(pXsvfInfo);        /*  0 */
1661 				break;
1662 			case 1:
1663 				xsvfDoXTDOMASK(pXsvfInfo);         /*  1 */
1664 				break;
1665 			case 2:
1666 				xsvfDoXSIR(pXsvfInfo);             /*  2 */
1667 				break;
1668 			case 3:
1669 				xsvfDoXSDR(pXsvfInfo);             /*  3 */
1670 				break;
1671 			case 4:
1672 				xsvfDoXRUNTEST(pXsvfInfo);         /*  4 */
1673 				break;
1674 			case 5:
1675 				xsvfDoIllegalCmd(pXsvfInfo);       /*  5 */
1676 				break;
1677 			case 6:
1678 				xsvfDoIllegalCmd(pXsvfInfo);       /*  6 */
1679 				break;
1680 			case 7:
1681 				xsvfDoXREPEAT(pXsvfInfo);          /*  7 */
1682 				break;
1683 			case 8:
1684 				xsvfDoXSDRSIZE(pXsvfInfo);         /*  8 */
1685 				break;
1686 			case 9:
1687 				xsvfDoXSDRTDO(pXsvfInfo);          /*  9 */
1688 				break;
1689 #ifdef  XSVF_SUPPORT_COMPRESSION
1690 			case 10:
1691 				xsvfDoXSETSDRMASKS(pXsvfInfo);     /* 10 */
1692 				break;
1693 			case 11:
1694 				xsvfDoXSDRINC(pXsvfInfo);          /* 11 */
1695 				break;
1696 #else
1697 			case 10:
1698 				xsvfDoIllegalCmd(pXsvfInfo);       /* 10 */
1699 				break;
1700 			case 11:
1701 				xsvfDoIllegalCmd(pXsvfInfo);       /* 11 */
1702 				break;
1703 #endif  /* XSVF_SUPPORT_COMPRESSION */
1704 			case 12:
1705 				xsvfDoXSDRBCE(pXsvfInfo);          /* 12 */
1706 				break;
1707 			case 13:
1708 				xsvfDoXSDRBCE(pXsvfInfo);          /* 13 */
1709 				break;
1710 			case 14:
1711 				xsvfDoXSDRBCE(pXsvfInfo);          /* 14 */
1712 				break;
1713 			case 15:
1714 				xsvfDoXSDRTDOBCE(pXsvfInfo);       /* 15 */
1715 				break;
1716 			case 16:
1717 				xsvfDoXSDRTDOBCE(pXsvfInfo);       /* 16 */
1718 				break;
1719 			case 17:
1720 				xsvfDoXSDRTDOBCE(pXsvfInfo);       /* 17 */
1721 				break;
1722 			case 18:
1723 				xsvfDoXSTATE(pXsvfInfo);           /* 18 */
1724 				break;
1725 			case 19:
1726 				xsvfDoXENDXR(pXsvfInfo);           /* 19 */
1727 				break;
1728 			case 20:
1729 				xsvfDoXENDXR(pXsvfInfo);           /* 20 */
1730 				break;
1731 			case 21:
1732 				xsvfDoXSIR2(pXsvfInfo);            /* 21 */
1733 				break;
1734 			case 22:
1735 				xsvfDoXCOMMENT(pXsvfInfo);         /* 22 */
1736 				break;
1737 			case 23:
1738 				xsvfDoXWAIT(pXsvfInfo);             /* 23 */
1739 				break;
1740 			}
1741 #endif
1742 		}
1743 		else
1744 		{
1745 			/* Illegal command value.  Func sets error code. */
1746 			xsvfDoIllegalCmd( pXsvfInfo );
1747 		}
1748 	}
1749 
1750 	return( pXsvfInfo->iErrorCode );
1751 }
1752 
1753 /*****************************************************************************
1754  * Function:     xsvfCleanup
1755  * Description:  cleanup remnants of the xsvf player.
1756  * Parameters:   pXsvfInfo   - ptr to the XSVF information.
1757  * Returns:      void.
1758  *****************************************************************************/
xsvfCleanup(SXsvfInfo * pXsvfInfo)1759 void xsvfCleanup( SXsvfInfo* pXsvfInfo )
1760 {
1761 	xsvfInfoCleanup( pXsvfInfo );
1762 }
1763 
1764 
1765 /*============================================================================
1766  * xsvfExecute() - The primary entry point to the XSVF player
1767  ============================================================================*/
1768 
1769 /*****************************************************************************
1770  * Function:     xsvfExecute
1771  * Description:  Process, interpret, and apply the XSVF commands.
1772  *               See port.c:readByte for source of XSVF data.
1773  * Parameters:   none.
1774  * Returns:      int - Legacy result values:  1 == success;  0 == failed.
1775  *****************************************************************************/
xsvfExecute(void)1776 int xsvfExecute(void)
1777 {
1778 	SXsvfInfo   xsvfInfo;
1779 
1780 	xsvfInitialize( &xsvfInfo );
1781 
1782 	while ( !xsvfInfo.iErrorCode && (!xsvfInfo.ucComplete) )
1783 	{
1784 		xsvfRun( &xsvfInfo );
1785 	}
1786 
1787 	if ( xsvfInfo.iErrorCode )
1788 	{
1789 		XSVFDBG_PRINTF1( 0, "%s\n", xsvf_pzErrorName[
1790 					 ( xsvfInfo.iErrorCode < XSVF_ERROR_LAST )
1791 					 ? xsvfInfo.iErrorCode : XSVF_ERROR_UNKNOWN ] );
1792 		XSVFDBG_PRINTF2( 0, "ERROR at or near XSVF command #%ld.  See line #%ld in the XSVF ASCII file.\n",
1793 				 xsvfInfo.lCommandCount, xsvfInfo.lCommandCount );
1794 	}
1795 	else
1796 	{
1797 		XSVFDBG_PRINTF( 0, "SUCCESS - Completed XSVF execution.\n" );
1798 	}
1799 
1800 	xsvfCleanup( &xsvfInfo );
1801 
1802 	return( XSVF_ERRORCODE(xsvfInfo.iErrorCode) );
1803 }
1804 
1805 
1806 /*****************************************************************************
1807  * Function:     do_cpld
1808  * Description:  main function.
1809  *               Specified here for creating stand-alone debug executable.
1810  *               Embedded users should call xsvfExecute() directly.
1811  * Parameters:   iArgc    - number of command-line arguments.
1812  *               ppzArgv  - array of ptrs to strings (command-line arguments).
1813  * Returns:      int      - Legacy return value:  1 = success; 0 = error.
1814  *****************************************************************************/
do_cpld(cmd_tbl_t * cmdtp,int flag,int argc,char * const argv[])1815 int do_cpld(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
1816 {
1817 	int     iErrorCode;
1818 	unsigned long duration;
1819 	unsigned long long startClock, endClock;
1820 
1821 	if (argc == 2)
1822 		xsvfdata = (unsigned char *)simple_strtoul(argv[1], NULL, 16);
1823 	else {
1824 #ifdef CONFIG_SYS_XSVF_DEFAULT_ADDR
1825 		xsvfdata = (unsigned char *)CONFIG_SYS_XSVF_DEFAULT_ADDR;
1826 #else
1827 		printf("Usage:\ncpld %s\n", cmdtp->help);
1828 		return -1;
1829 #endif
1830 	}
1831 
1832 	iErrorCode          = XSVF_ERRORCODE( XSVF_ERROR_NONE );
1833 	xsvf_iDebugLevel    = 0;
1834 
1835 	printf("XSVF Player v%s, Xilinx, Inc.\n", XSVF_VERSION);
1836 	printf("Reading XSVF data @ %p\n", xsvfdata);
1837 
1838 	/* Initialize the I/O.  SetPort initializes I/O on first call */
1839 	setPort( TMS, 1 );
1840 
1841 	/* Execute the XSVF in the file */
1842 	startClock  = get_ticks();
1843 	iErrorCode  = xsvfExecute();
1844 	endClock    = get_ticks();
1845 	duration    = (unsigned long)(endClock - startClock);
1846 	printf("\nExecution Time = %d seconds\n", (int)(duration/get_tbclk()));
1847 
1848 	return( iErrorCode );
1849 }
1850 U_BOOT_CMD(
1851 	cpld,	2,	1,	do_cpld,
1852 	"program onboard CPLD",
1853 	"<xsvf-addr>"
1854 );
1855