xref: /openbmc/u-boot/drivers/fpga/ivm_core.c (revision e8f80a5a)
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Porting to u-boot:
4  *
5  * (C) Copyright 2010
6  * Stefano Babic, DENX Software Engineering, sbabic@denx.de.
7  *
8  * Lattice ispVME Embedded code to load Lattice's FPGA:
9  *
10  * Copyright 2009 Lattice Semiconductor Corp.
11  *
12  * ispVME Embedded allows programming of Lattice's suite of FPGA
13  * devices on embedded systems through the JTAG port.  The software
14  * is distributed in source code form and is open to re - distribution
15  * and modification where applicable.
16  *
17  * Revision History of ivm_core.c module:
18  * 4/25/06 ht   Change some variables from unsigned short or int
19  *              to long int to make the code compiler independent.
20  * 5/24/06 ht   Support using RESET (TRST) pin as a special purpose
21  *              control pin such as triggering the loading of known
22  *              state exit.
23  * 3/6/07 ht added functions to support output to terminals
24  *
25  * 09/11/07 NN Type cast mismatch variables
26  *		   Moved the sclock() function to hardware.c
27  * 08/28/08 NN Added Calculate checksum support.
28  * 4/1/09 Nguyen replaced the recursive function call codes on
29  *        the ispVMLCOUNT function
30  */
31 
32 #include <common.h>
33 #include <linux/string.h>
34 #include <malloc.h>
35 #include <lattice.h>
36 
37 #define vme_out_char(c)	printf("%c", c)
38 #define vme_out_hex(c)	printf("%x", c)
39 #define vme_out_string(s) printf("%s", s)
40 
41 /*
42  *
43  * Global variables used to specify the flow control and data type.
44  *
45  *	g_usFlowControl:	flow control register. Each bit in the
46  *                               register can potentially change the
47  *                               personality of the embedded engine.
48  *	g_usDataType:		holds the data type of the current row.
49  *
50  */
51 
52 static unsigned short g_usFlowControl;
53 unsigned short g_usDataType;
54 
55 /*
56  *
57  * Global variables used to specify the ENDDR and ENDIR.
58  *
59  *	g_ucEndDR:		the state that the device goes to after SDR.
60  *	g_ucEndIR:		the state that the device goes to after SIR.
61  *
62  */
63 
64 unsigned char g_ucEndDR = DRPAUSE;
65 unsigned char g_ucEndIR = IRPAUSE;
66 
67 /*
68  *
69  * Global variables used to support header/trailer.
70  *
71  *	g_usHeadDR:		the number of lead devices in bypass.
72  *	g_usHeadIR:		the sum of IR length of lead devices.
73  *	g_usTailDR:		the number of tail devices in bypass.
74  *	g_usTailIR:		the sum of IR length of tail devices.
75  *
76  */
77 
78 static unsigned short g_usHeadDR;
79 static unsigned short g_usHeadIR;
80 static unsigned short g_usTailDR;
81 static unsigned short g_usTailIR;
82 
83 /*
84  *
85  * Global variable to store the number of bits of data or instruction
86  * to be shifted into or out from the device.
87  *
88  */
89 
90 static unsigned short g_usiDataSize;
91 
92 /*
93  *
94  * Stores the frequency. Default to 1 MHz.
95  *
96  */
97 
98 static int g_iFrequency = 1000;
99 
100 /*
101  *
102  * Stores the maximum amount of ram needed to hold a row of data.
103  *
104  */
105 
106 static unsigned short g_usMaxSize;
107 
108 /*
109  *
110  * Stores the LSH or RSH value.
111  *
112  */
113 
114 static unsigned short g_usShiftValue;
115 
116 /*
117  *
118  * Stores the current repeat loop value.
119  *
120  */
121 
122 static unsigned short g_usRepeatLoops;
123 
124 /*
125  *
126  * Stores the current vendor.
127  *
128  */
129 
130 static signed char g_cVendor = LATTICE;
131 
132 /*
133  *
134  * Stores the VME file CRC.
135  *
136  */
137 
138 unsigned short g_usCalculatedCRC;
139 
140 /*
141  *
142  * Stores the Device Checksum.
143  *
144  */
145 /* 08/28/08 NN Added Calculate checksum support. */
146 unsigned long g_usChecksum;
147 static unsigned int g_uiChecksumIndex;
148 
149 /*
150  *
151  * Stores the current state of the JTAG state machine.
152  *
153  */
154 
155 static signed char g_cCurrentJTAGState;
156 
157 /*
158  *
159  * Global variables used to support looping.
160  *
161  *	g_pucHeapMemory:	holds the entire repeat loop.
162  *	g_iHeapCounter:		points to the current byte in the repeat loop.
163  *	g_iHEAPSize:		the current size of the repeat in bytes.
164  *
165  */
166 
167 unsigned char *g_pucHeapMemory;
168 unsigned short g_iHeapCounter;
169 unsigned short g_iHEAPSize;
170 static unsigned short previous_size;
171 
172 /*
173  *
174  * Global variables used to support intelligent programming.
175  *
176  *	g_usIntelDataIndex:     points to the current byte of the
177  *                               intelligent buffer.
178  *	g_usIntelBufferSize:	holds the size of the intelligent
179  *                               buffer.
180  *
181  */
182 
183 unsigned short g_usIntelDataIndex;
184 unsigned short g_usIntelBufferSize;
185 
186 /*
187  *
188  * Supported VME versions.
189  *
190  */
191 
192 const char *const g_szSupportedVersions[] = {
193 	"__VME2.0", "__VME3.0", "____12.0", "____12.1", 0};
194 
195 /*
196  *
197  * Holds the maximum size of each respective buffer. These variables are used
198  * to write the HEX files when converting VME to HEX.
199  *
200 */
201 
202 static unsigned short g_usTDOSize;
203 static unsigned short g_usMASKSize;
204 static unsigned short g_usTDISize;
205 static unsigned short g_usDMASKSize;
206 static unsigned short g_usLCOUNTSize;
207 static unsigned short g_usHDRSize;
208 static unsigned short g_usTDRSize;
209 static unsigned short g_usHIRSize;
210 static unsigned short g_usTIRSize;
211 static unsigned short g_usHeapSize;
212 
213 /*
214  *
215  * Global variables used to store data.
216  *
217  *	g_pucOutMaskData:	local RAM to hold one row of MASK data.
218  *	g_pucInData:		local RAM to hold one row of TDI data.
219  *	g_pucOutData:		local RAM to hold one row of TDO data.
220  *	g_pucHIRData:		local RAM to hold the current SIR header.
221  *	g_pucTIRData:		local RAM to hold the current SIR trailer.
222  *	g_pucHDRData:		local RAM to hold the current SDR header.
223  *	g_pucTDRData:		local RAM to hold the current SDR trailer.
224  *	g_pucIntelBuffer:	local RAM to hold the current intelligent buffer
225  *	g_pucOutDMaskData:	local RAM to hold one row of DMASK data.
226  *
227  */
228 
229 unsigned char	*g_pucOutMaskData	= NULL,
230 		*g_pucInData		= NULL,
231 		*g_pucOutData		= NULL,
232 		*g_pucHIRData		= NULL,
233 		*g_pucTIRData		= NULL,
234 		*g_pucHDRData		= NULL,
235 		*g_pucTDRData		= NULL,
236 		*g_pucIntelBuffer	= NULL,
237 		*g_pucOutDMaskData	= NULL;
238 
239 /*
240  *
241  * JTAG state machine transition table.
242  *
243  */
244 
245 struct {
246 	 unsigned char  CurState;  /* From this state */
247 	 unsigned char  NextState; /* Step to this state */
248 	 unsigned char  Pattern;   /* The tragetory of TMS */
249 	 unsigned char  Pulses;    /* The number of steps */
250 } g_JTAGTransistions[25] = {
251 { RESET,	RESET,		0xFC, 6 },	/* Transitions from RESET */
252 { RESET,	IDLE,		0x00, 1 },
253 { RESET,	DRPAUSE,	0x50, 5 },
254 { RESET,	IRPAUSE,	0x68, 6 },
255 { IDLE,		RESET,		0xE0, 3 },	/* Transitions from IDLE */
256 { IDLE,		DRPAUSE,	0xA0, 4 },
257 { IDLE,		IRPAUSE,	0xD0, 5 },
258 { DRPAUSE,	RESET,		0xF8, 5 },	/* Transitions from DRPAUSE */
259 { DRPAUSE,	IDLE,		0xC0, 3 },
260 { DRPAUSE,	IRPAUSE,	0xF4, 7 },
261 { DRPAUSE,	DRPAUSE,	0xE8, 6 },/* 06/14/06 Support POLL STATUS LOOP*/
262 { IRPAUSE,	RESET,		0xF8, 5 },	/* Transitions from IRPAUSE */
263 { IRPAUSE,	IDLE,		0xC0, 3 },
264 { IRPAUSE,	DRPAUSE,	0xE8, 6 },
265 { DRPAUSE,	SHIFTDR,	0x80, 2 }, /* Extra transitions using SHIFTDR */
266 { IRPAUSE,	SHIFTDR,	0xE0, 5 },
267 { SHIFTDR,	DRPAUSE,	0x80, 2 },
268 { SHIFTDR,	IDLE,		0xC0, 3 },
269 { IRPAUSE,	SHIFTIR,	0x80, 2 },/* Extra transitions using SHIFTIR */
270 { SHIFTIR,	IRPAUSE,	0x80, 2 },
271 { SHIFTIR,	IDLE,		0xC0, 3 },
272 { DRPAUSE,	DRCAPTURE,	0xE0, 4 }, /* 11/15/05 Support DRCAPTURE*/
273 { DRCAPTURE, DRPAUSE,	0x80, 2 },
274 { IDLE,     DRCAPTURE,	0x80, 2 },
275 { IRPAUSE,  DRCAPTURE,  0xE0, 4 }
276 };
277 
278 /*
279  *
280  * List to hold all LVDS pairs.
281  *
282  */
283 
284 LVDSPair *g_pLVDSList;
285 unsigned short g_usLVDSPairCount;
286 
287 /*
288  *
289  * Function prototypes.
290  *
291  */
292 
293 static signed char ispVMDataCode(void);
294 static long int ispVMDataSize(void);
295 static void ispVMData(unsigned char *Data);
296 static signed char ispVMShift(signed char Code);
297 static signed char ispVMAmble(signed char Code);
298 static signed char ispVMLoop(unsigned short a_usLoopCount);
299 static signed char ispVMBitShift(signed char mode, unsigned short bits);
300 static void ispVMComment(unsigned short a_usCommentSize);
301 static void ispVMHeader(unsigned short a_usHeaderSize);
302 static signed char ispVMLCOUNT(unsigned short a_usCountSize);
303 static void ispVMClocks(unsigned short Clocks);
304 static void ispVMBypass(signed char ScanType, unsigned short Bits);
305 static void ispVMStateMachine(signed char NextState);
306 static signed char ispVMSend(unsigned short int);
307 static signed char ispVMRead(unsigned short int);
308 static signed char ispVMReadandSave(unsigned short int);
309 static signed char ispVMProcessLVDS(unsigned short a_usLVDSCount);
310 static void ispVMMemManager(signed char types, unsigned short size);
311 
312 /*
313  *
314  * External variables and functions in hardware.c module
315  *
316  */
317 static signed char g_cCurrentJTAGState;
318 
319 #ifdef DEBUG
320 
321 /*
322  *
323  * GetState
324  *
325  * Returns the state as a string based on the opcode. Only used
326  * for debugging purposes.
327  *
328  */
329 
GetState(unsigned char a_ucState)330 const char *GetState(unsigned char a_ucState)
331 {
332 	switch (a_ucState) {
333 	case RESET:
334 		return "RESET";
335 	case IDLE:
336 		return "IDLE";
337 	case IRPAUSE:
338 		return "IRPAUSE";
339 	case DRPAUSE:
340 		return "DRPAUSE";
341 	case SHIFTIR:
342 		return "SHIFTIR";
343 	case SHIFTDR:
344 		return "SHIFTDR";
345 	case DRCAPTURE:/* 11/15/05 support DRCAPTURE*/
346 		return "DRCAPTURE";
347 	default:
348 		break;
349 	}
350 
351 	return 0;
352 }
353 
354 /*
355  *
356  * PrintData
357  *
358  * Prints the data. Only used for debugging purposes.
359  *
360  */
361 
PrintData(unsigned short a_iDataSize,unsigned char * a_pucData)362 void PrintData(unsigned short a_iDataSize, unsigned char *a_pucData)
363 {
364 	/* 09/11/07 NN added local variables initialization */
365 	unsigned short usByteSize  = 0;
366 	unsigned short usBitIndex  = 0;
367 	signed short usByteIndex   = 0;
368 	unsigned char ucByte       = 0;
369 	unsigned char ucFlipByte   = 0;
370 
371 	if (a_iDataSize % 8) {
372 		/* 09/11/07 NN Type cast mismatch variables */
373 		usByteSize = (unsigned short)(a_iDataSize / 8 + 1);
374 	} else {
375 		/* 09/11/07 NN Type cast mismatch variables */
376 		usByteSize = (unsigned short)(a_iDataSize / 8);
377 	}
378 	puts("(");
379 	/* 09/11/07 NN Type cast mismatch variables */
380 	for (usByteIndex = (signed short)(usByteSize - 1);
381 		usByteIndex >= 0; usByteIndex--) {
382 		ucByte = a_pucData[usByteIndex];
383 		ucFlipByte = 0x00;
384 
385 		/*
386 		*
387 		* Flip each byte.
388 		*
389 		*/
390 
391 		for (usBitIndex = 0; usBitIndex < 8; usBitIndex++) {
392 			ucFlipByte <<= 1;
393 			if (ucByte & 0x1) {
394 				ucFlipByte |= 0x1;
395 			}
396 
397 			ucByte >>= 1;
398 		}
399 
400 		/*
401 		*
402 		* Print the flipped byte.
403 		*
404 		*/
405 
406 		printf("%.02X", ucFlipByte);
407 		if ((usByteSize - usByteIndex) % 40 == 39) {
408 			puts("\n\t\t");
409 		}
410 		if (usByteIndex < 0)
411 			break;
412 	}
413 	puts(")");
414 }
415 #endif /* DEBUG */
416 
ispVMMemManager(signed char cTarget,unsigned short usSize)417 void ispVMMemManager(signed char cTarget, unsigned short usSize)
418 {
419 	switch (cTarget) {
420 	case XTDI:
421 	case TDI:
422 		if (g_pucInData != NULL) {
423 			if (previous_size == usSize) {/*memory exist*/
424 				break;
425 			} else {
426 				free(g_pucInData);
427 				g_pucInData = NULL;
428 			}
429 		}
430 		g_pucInData = (unsigned char *) malloc(usSize / 8 + 2);
431 		previous_size = usSize;
432 	case XTDO:
433 	case TDO:
434 		if (g_pucOutData != NULL) {
435 			if (previous_size == usSize) { /*already exist*/
436 				break;
437 			} else {
438 				free(g_pucOutData);
439 				g_pucOutData = NULL;
440 			}
441 		}
442 		g_pucOutData = (unsigned char *) malloc(usSize / 8 + 2);
443 		previous_size = usSize;
444 		break;
445 	case MASK:
446 		if (g_pucOutMaskData != NULL) {
447 			if (previous_size == usSize) {/*already allocated*/
448 				break;
449 			} else {
450 				free(g_pucOutMaskData);
451 				g_pucOutMaskData = NULL;
452 			}
453 		}
454 		g_pucOutMaskData = (unsigned char *) malloc(usSize / 8 + 2);
455 		previous_size = usSize;
456 		break;
457 	case HIR:
458 		if (g_pucHIRData != NULL) {
459 			free(g_pucHIRData);
460 			g_pucHIRData = NULL;
461 		}
462 		g_pucHIRData = (unsigned char *) malloc(usSize / 8 + 2);
463 		break;
464 	case TIR:
465 		if (g_pucTIRData != NULL) {
466 			free(g_pucTIRData);
467 			g_pucTIRData = NULL;
468 		}
469 		g_pucTIRData = (unsigned char *) malloc(usSize / 8 + 2);
470 		break;
471 	case HDR:
472 		if (g_pucHDRData != NULL) {
473 			free(g_pucHDRData);
474 			g_pucHDRData = NULL;
475 		}
476 		g_pucHDRData = (unsigned char *) malloc(usSize / 8 + 2);
477 		break;
478 	case TDR:
479 		if (g_pucTDRData != NULL) {
480 			free(g_pucTDRData);
481 			g_pucTDRData = NULL;
482 		}
483 		g_pucTDRData = (unsigned char *) malloc(usSize / 8 + 2);
484 		break;
485 	case HEAP:
486 		if (g_pucHeapMemory != NULL) {
487 			free(g_pucHeapMemory);
488 			g_pucHeapMemory = NULL;
489 		}
490 		g_pucHeapMemory = (unsigned char *) malloc(usSize + 2);
491 		break;
492 	case DMASK:
493 		if (g_pucOutDMaskData != NULL) {
494 			if (previous_size == usSize) { /*already allocated*/
495 				break;
496 			} else {
497 				free(g_pucOutDMaskData);
498 				g_pucOutDMaskData = NULL;
499 			}
500 		}
501 		g_pucOutDMaskData = (unsigned char *) malloc(usSize / 8 + 2);
502 		previous_size = usSize;
503 		break;
504 	case LHEAP:
505 		if (g_pucIntelBuffer != NULL) {
506 			free(g_pucIntelBuffer);
507 			g_pucIntelBuffer = NULL;
508 		}
509 		g_pucIntelBuffer = (unsigned char *) malloc(usSize + 2);
510 		break;
511 	case LVDS:
512 		if (g_pLVDSList != NULL) {
513 			free(g_pLVDSList);
514 			g_pLVDSList = NULL;
515 		}
516 		g_pLVDSList = (LVDSPair *) malloc(usSize * sizeof(LVDSPair));
517 		if (g_pLVDSList)
518 			memset(g_pLVDSList, 0, usSize * sizeof(LVDSPair));
519 		break;
520 	default:
521 		return;
522     }
523 }
524 
ispVMFreeMem(void)525 void ispVMFreeMem(void)
526 {
527 	if (g_pucHeapMemory != NULL) {
528 		free(g_pucHeapMemory);
529 		g_pucHeapMemory = NULL;
530 	}
531 
532 	if (g_pucOutMaskData != NULL) {
533 		free(g_pucOutMaskData);
534 		g_pucOutMaskData = NULL;
535 	}
536 
537 	if (g_pucInData != NULL) {
538 		free(g_pucInData);
539 		g_pucInData = NULL;
540 	}
541 
542 	if (g_pucOutData != NULL) {
543 		free(g_pucOutData);
544 		g_pucOutData = NULL;
545 	}
546 
547 	if (g_pucHIRData != NULL) {
548 		free(g_pucHIRData);
549 		g_pucHIRData = NULL;
550 	}
551 
552 	if (g_pucTIRData != NULL) {
553 		free(g_pucTIRData);
554 		g_pucTIRData = NULL;
555 	}
556 
557 	if (g_pucHDRData != NULL) {
558 		free(g_pucHDRData);
559 		g_pucHDRData = NULL;
560 	}
561 
562 	if (g_pucTDRData != NULL) {
563 		free(g_pucTDRData);
564 		g_pucTDRData = NULL;
565 	}
566 
567 	if (g_pucOutDMaskData != NULL) {
568 		free(g_pucOutDMaskData);
569 		g_pucOutDMaskData = NULL;
570 	}
571 
572 	if (g_pucIntelBuffer != NULL) {
573 		free(g_pucIntelBuffer);
574 		g_pucIntelBuffer = NULL;
575 	}
576 
577 	if (g_pLVDSList != NULL) {
578 		free(g_pLVDSList);
579 		g_pLVDSList = NULL;
580 	}
581 }
582 
583 
584 /*
585  *
586  * ispVMDataSize
587  *
588  * Returns a VME-encoded number, usually used to indicate the
589  * bit length of an SIR/SDR command.
590  *
591  */
592 
ispVMDataSize()593 long int ispVMDataSize()
594 {
595 	/* 09/11/07 NN added local variables initialization */
596 	long int iSize           = 0;
597 	signed char cCurrentByte = 0;
598 	signed char cIndex       = 0;
599 	cIndex = 0;
600 	while ((cCurrentByte = GetByte()) & 0x80) {
601 		iSize |= ((long int) (cCurrentByte & 0x7F)) << cIndex;
602 		cIndex += 7;
603 	}
604 	iSize |= ((long int) (cCurrentByte & 0x7F)) << cIndex;
605 	return iSize;
606 }
607 
608 /*
609  *
610  * ispVMCode
611  *
612  * This is the heart of the embedded engine. All the high-level opcodes
613  * are extracted here. Once they have been identified, then it
614  * will call other functions to handle the processing.
615  *
616  */
617 
ispVMCode()618 signed char ispVMCode()
619 {
620 	/* 09/11/07 NN added local variables initialization */
621 	unsigned short iRepeatSize = 0;
622 	signed char cOpcode	   = 0;
623 	signed char cRetCode       = 0;
624 	unsigned char ucState      = 0;
625 	unsigned short usDelay     = 0;
626 	unsigned short usToggle    = 0;
627 	unsigned char usByte       = 0;
628 
629 	/*
630 	*
631 	* Check the compression flag only if this is the first time
632 	* this function is entered. Do not check the compression flag if
633 	* it is being called recursively from other functions within
634 	* the embedded engine.
635 	*
636 	*/
637 
638 	if (!(g_usDataType & LHEAP_IN) && !(g_usDataType & HEAP_IN)) {
639 		usByte = GetByte();
640 		if (usByte == 0xf1) {
641 			g_usDataType |= COMPRESS;
642 		} else if (usByte == 0xf2) {
643 			g_usDataType &= ~COMPRESS;
644 		} else {
645 			return VME_INVALID_FILE;
646 		}
647 	}
648 
649 	/*
650 	*
651 	* Begin looping through all the VME opcodes.
652 	*
653 	*/
654 
655 	while ((cOpcode = GetByte()) >= 0) {
656 
657 		switch (cOpcode) {
658 		case STATE:
659 
660 			/*
661 			 * Step the JTAG state machine.
662 			 */
663 
664 			ucState = GetByte();
665 
666 			/*
667 			 * Step the JTAG state machine to DRCAPTURE
668 			 * to support Looping.
669 			 */
670 
671 			if ((g_usDataType & LHEAP_IN) &&
672 				 (ucState == DRPAUSE) &&
673 				 (g_cCurrentJTAGState == ucState)) {
674 				ispVMStateMachine(DRCAPTURE);
675 			}
676 
677 			ispVMStateMachine(ucState);
678 
679 #ifdef DEBUG
680 			if (g_usDataType & LHEAP_IN) {
681 				debug("LDELAY %s ", GetState(ucState));
682 			} else {
683 				debug("STATE %s;\n", GetState(ucState));
684 			}
685 #endif /* DEBUG */
686 			break;
687 		case SIR:
688 		case SDR:
689 		case XSDR:
690 
691 #ifdef DEBUG
692 			switch (cOpcode) {
693 			case SIR:
694 				puts("SIR ");
695 				break;
696 			case SDR:
697 			case XSDR:
698 				if (g_usDataType & LHEAP_IN) {
699 					puts("LSDR ");
700 				} else {
701 					puts("SDR ");
702 				}
703 				break;
704 			}
705 #endif /* DEBUG */
706 			/*
707 			*
708 			* Shift in data into the device.
709 			*
710 			*/
711 
712 			cRetCode = ispVMShift(cOpcode);
713 			if (cRetCode != 0) {
714 				return cRetCode;
715 			}
716 			break;
717 		case WAIT:
718 
719 			/*
720 			*
721 			* Observe delay.
722 			*
723 			*/
724 
725 			/* 09/11/07 NN Type cast mismatch variables */
726 			usDelay = (unsigned short) ispVMDataSize();
727 			ispVMDelay(usDelay);
728 
729 #ifdef DEBUG
730 			if (usDelay & 0x8000) {
731 
732 				/*
733 				 * Since MSB is set, the delay time must be
734 				 * decoded to millisecond. The SVF2VME encodes
735 				 * the MSB to represent millisecond.
736 				 */
737 
738 				usDelay &= ~0x8000;
739 				if (g_usDataType & LHEAP_IN) {
740 					printf("%.2E SEC;\n",
741 						(float) usDelay / 1000);
742 				} else {
743 					printf("RUNTEST %.2E SEC;\n",
744 						(float) usDelay / 1000);
745 				}
746 			} else {
747 				/*
748 				 * Since MSB is not set, the delay time
749 				 * is given as microseconds.
750 				 */
751 
752 				if (g_usDataType & LHEAP_IN) {
753 					printf("%.2E SEC;\n",
754 						(float) usDelay / 1000000);
755 				} else {
756 					printf("RUNTEST %.2E SEC;\n",
757 						(float) usDelay / 1000000);
758 				}
759 			}
760 #endif /* DEBUG */
761 			break;
762 		case TCK:
763 
764 			/*
765 			 * Issue clock toggles.
766 			*/
767 
768 			/* 09/11/07 NN Type cast mismatch variables */
769 			usToggle = (unsigned short) ispVMDataSize();
770 			ispVMClocks(usToggle);
771 
772 #ifdef DEBUG
773 			printf("RUNTEST %d TCK;\n", usToggle);
774 #endif /* DEBUG */
775 			break;
776 		case ENDDR:
777 
778 			/*
779 			*
780 			* Set the ENDDR.
781 			*
782 			*/
783 
784 			g_ucEndDR = GetByte();
785 
786 #ifdef DEBUG
787 			printf("ENDDR %s;\n", GetState(g_ucEndDR));
788 #endif /* DEBUG */
789 			break;
790 		case ENDIR:
791 
792 			/*
793 			*
794 			* Set the ENDIR.
795 			*
796 			*/
797 
798 			g_ucEndIR = GetByte();
799 
800 #ifdef DEBUG
801 			printf("ENDIR %s;\n", GetState(g_ucEndIR));
802 #endif /* DEBUG */
803 			break;
804 		case HIR:
805 		case TIR:
806 		case HDR:
807 		case TDR:
808 
809 #ifdef DEBUG
810 			switch (cOpcode) {
811 			case HIR:
812 				puts("HIR ");
813 				break;
814 			case TIR:
815 				puts("TIR ");
816 				break;
817 			case HDR:
818 				puts("HDR ");
819 				break;
820 			case TDR:
821 				puts("TDR ");
822 				break;
823 			}
824 #endif /* DEBUG */
825 			/*
826 			 * Set the header/trailer of the device in order
827 			 * to bypass
828 			 * successfully.
829 			 */
830 
831 			cRetCode = ispVMAmble(cOpcode);
832 			if (cRetCode != 0) {
833 				return cRetCode;
834 			}
835 
836 #ifdef DEBUG
837 			puts(";\n");
838 #endif /* DEBUG */
839 			break;
840 		case MEM:
841 
842 			/*
843 			 * The maximum RAM required to support
844 			 * processing one row of the VME file.
845 			 */
846 
847 			/* 09/11/07 NN Type cast mismatch variables */
848 			g_usMaxSize = (unsigned short) ispVMDataSize();
849 
850 #ifdef DEBUG
851 			printf("// MEMSIZE %d\n", g_usMaxSize);
852 #endif /* DEBUG */
853 			break;
854 		case VENDOR:
855 
856 			/*
857 			*
858 			* Set the VENDOR type.
859 			*
860 			*/
861 
862 			cOpcode = GetByte();
863 			switch (cOpcode) {
864 			case LATTICE:
865 #ifdef DEBUG
866 				puts("// VENDOR LATTICE\n");
867 #endif /* DEBUG */
868 				g_cVendor = LATTICE;
869 				break;
870 			case ALTERA:
871 #ifdef DEBUG
872 				puts("// VENDOR ALTERA\n");
873 #endif /* DEBUG */
874 				g_cVendor = ALTERA;
875 				break;
876 			case XILINX:
877 #ifdef DEBUG
878 				puts("// VENDOR XILINX\n");
879 #endif /* DEBUG */
880 				g_cVendor = XILINX;
881 				break;
882 			default:
883 				break;
884 			}
885 			break;
886 		case SETFLOW:
887 
888 			/*
889 			 * Set the flow control. Flow control determines
890 			 * the personality of the embedded engine.
891 			 */
892 
893 			/* 09/11/07 NN Type cast mismatch variables */
894 			g_usFlowControl |= (unsigned short) ispVMDataSize();
895 			break;
896 		case RESETFLOW:
897 
898 			/*
899 			*
900 			* Unset the flow control.
901 			*
902 			*/
903 
904 			/* 09/11/07 NN Type cast mismatch variables */
905 			g_usFlowControl &= (unsigned short) ~(ispVMDataSize());
906 			break;
907 		case HEAP:
908 
909 			/*
910 			*
911 			* Allocate heap size to store loops.
912 			*
913 			*/
914 
915 			cRetCode = GetByte();
916 			if (cRetCode != SECUREHEAP) {
917 				return VME_INVALID_FILE;
918 			}
919 			/* 09/11/07 NN Type cast mismatch variables */
920 			g_iHEAPSize = (unsigned short) ispVMDataSize();
921 
922 			/*
923 			 * Store the maximum size of the HEAP buffer.
924 			 * Used to convert VME to HEX.
925 			 */
926 
927 			if (g_iHEAPSize > g_usHeapSize) {
928 				g_usHeapSize = g_iHEAPSize;
929 			}
930 
931 			ispVMMemManager(HEAP, (unsigned short) g_iHEAPSize);
932 			break;
933 		case REPEAT:
934 
935 			/*
936 			*
937 			* Execute loops.
938 			*
939 			*/
940 
941 			g_usRepeatLoops = 0;
942 
943 			/* 09/11/07 NN Type cast mismatch variables */
944 			iRepeatSize = (unsigned short) ispVMDataSize();
945 
946 			cRetCode = ispVMLoop((unsigned short) iRepeatSize);
947 			if (cRetCode != 0) {
948 				return cRetCode;
949 			}
950 			break;
951 		case ENDLOOP:
952 
953 			/*
954 			*
955 			* Exit point from processing loops.
956 			*
957 			*/
958 
959 			return cRetCode;
960 		case ENDVME:
961 
962 			/*
963 			 * The only valid exit point that indicates
964 			 * end of programming.
965 			 */
966 
967 			return cRetCode;
968 		case SHR:
969 
970 			/*
971 			*
972 			* Right-shift address.
973 			*
974 			*/
975 
976 			g_usFlowControl |= SHIFTRIGHT;
977 
978 			/* 09/11/07 NN Type cast mismatch variables */
979 			g_usShiftValue = (unsigned short) (g_usRepeatLoops *
980 				(unsigned short)GetByte());
981 			break;
982 		case SHL:
983 
984 			/*
985 			 * Left-shift address.
986 			 */
987 
988 			g_usFlowControl |= SHIFTLEFT;
989 
990 			/* 09/11/07 NN Type cast mismatch variables */
991 			g_usShiftValue = (unsigned short) (g_usRepeatLoops *
992 				(unsigned short)GetByte());
993 			break;
994 		case FREQUENCY:
995 
996 			/*
997 			*
998 			* Set the frequency.
999 			*
1000 			*/
1001 
1002 			/* 09/11/07 NN Type cast mismatch variables */
1003 			g_iFrequency = (int) (ispVMDataSize() / 1000);
1004 			if (g_iFrequency == 1)
1005 				g_iFrequency = 1000;
1006 
1007 #ifdef DEBUG
1008 			printf("FREQUENCY %.2E HZ;\n",
1009 				(float) g_iFrequency * 1000);
1010 #endif /* DEBUG */
1011 			break;
1012 		case LCOUNT:
1013 
1014 			/*
1015 			*
1016 			* Process LCOUNT command.
1017 			*
1018 			*/
1019 
1020 			cRetCode = ispVMLCOUNT((unsigned short)ispVMDataSize());
1021 			if (cRetCode != 0) {
1022 				return cRetCode;
1023 			}
1024 			break;
1025 		case VUES:
1026 
1027 			/*
1028 			*
1029 			* Set the flow control to verify USERCODE.
1030 			*
1031 			*/
1032 
1033 			g_usFlowControl |= VERIFYUES;
1034 			break;
1035 		case COMMENT:
1036 
1037 			/*
1038 			*
1039 			* Display comment.
1040 			*
1041 			*/
1042 
1043 			ispVMComment((unsigned short) ispVMDataSize());
1044 			break;
1045 		case LVDS:
1046 
1047 			/*
1048 			*
1049 			* Process LVDS command.
1050 			*
1051 			*/
1052 
1053 			ispVMProcessLVDS((unsigned short) ispVMDataSize());
1054 			break;
1055 		case HEADER:
1056 
1057 			/*
1058 			*
1059 			* Discard header.
1060 			*
1061 			*/
1062 
1063 			ispVMHeader((unsigned short) ispVMDataSize());
1064 			break;
1065 		/* 03/14/06 Support Toggle ispENABLE signal*/
1066 		case ispEN:
1067 			ucState = GetByte();
1068 			if ((ucState == ON) || (ucState == 0x01))
1069 				writePort(g_ucPinENABLE, 0x01);
1070 			else
1071 				writePort(g_ucPinENABLE, 0x00);
1072 			ispVMDelay(1);
1073 			break;
1074 		/* 05/24/06 support Toggle TRST pin*/
1075 		case TRST:
1076 			ucState = GetByte();
1077 			if (ucState == 0x01)
1078 				writePort(g_ucPinTRST, 0x01);
1079 			else
1080 				writePort(g_ucPinTRST, 0x00);
1081 			ispVMDelay(1);
1082 			break;
1083 		default:
1084 
1085 			/*
1086 			*
1087 			* Invalid opcode encountered.
1088 			*
1089 			*/
1090 
1091 #ifdef DEBUG
1092 			printf("\nINVALID OPCODE: 0x%.2X\n", cOpcode);
1093 #endif /* DEBUG */
1094 
1095 			return VME_INVALID_FILE;
1096 		}
1097 	}
1098 
1099 	/*
1100 	*
1101 	* Invalid exit point. Processing the token 'ENDVME' is the only
1102 	* valid way to exit the embedded engine.
1103 	*
1104 	*/
1105 
1106 	return VME_INVALID_FILE;
1107 }
1108 
1109 /*
1110  *
1111  * ispVMDataCode
1112  *
1113  * Processes the TDI/TDO/MASK/DMASK etc of an SIR/SDR command.
1114  *
1115  */
1116 
ispVMDataCode()1117 signed char ispVMDataCode()
1118 {
1119 	/* 09/11/07 NN added local variables initialization */
1120 	signed char cDataByte    = 0;
1121 	signed char siDataSource = 0;  /*source of data from file by default*/
1122 
1123 	if (g_usDataType & HEAP_IN) {
1124 		siDataSource = 1;  /*the source of data from memory*/
1125 	}
1126 
1127 	/*
1128 	*
1129 	* Clear the data type register.
1130 	*
1131 	**/
1132 
1133 	g_usDataType &= ~(MASK_DATA + TDI_DATA +
1134 		TDO_DATA + DMASK_DATA + CMASK_DATA);
1135 
1136 	/*
1137 	 * Iterate through SIR/SDR command and look for TDI,
1138 	 * TDO, MASK, etc.
1139 	 */
1140 
1141 	while ((cDataByte = GetByte()) >= 0) {
1142 			ispVMMemManager(cDataByte, g_usMaxSize);
1143 			switch (cDataByte) {
1144 			case TDI:
1145 
1146 				/*
1147 				 * Store the maximum size of the TDI buffer.
1148 				 * Used to convert VME to HEX.
1149 				 */
1150 
1151 				if (g_usiDataSize > g_usTDISize) {
1152 					g_usTDISize = g_usiDataSize;
1153 				}
1154 				/*
1155 				 * Updated data type register to indicate that
1156 				 * TDI data is currently being used. Process the
1157 				 * data in the VME file into the TDI buffer.
1158 				 */
1159 
1160 				g_usDataType |= TDI_DATA;
1161 				ispVMData(g_pucInData);
1162 				break;
1163 			case XTDO:
1164 
1165 				/*
1166 				 * Store the maximum size of the TDO buffer.
1167 				 * Used to convert VME to HEX.
1168 				 */
1169 
1170 				if (g_usiDataSize > g_usTDOSize) {
1171 					g_usTDOSize = g_usiDataSize;
1172 				}
1173 
1174 				/*
1175 				 * Updated data type register to indicate that
1176 				 * TDO data is currently being used.
1177 				 */
1178 
1179 				g_usDataType |= TDO_DATA;
1180 				break;
1181 			case TDO:
1182 
1183 				/*
1184 				 * Store the maximum size of the TDO buffer.
1185 				 * Used to convert VME to HEX.
1186 				 */
1187 
1188 				if (g_usiDataSize > g_usTDOSize) {
1189 					g_usTDOSize = g_usiDataSize;
1190 				}
1191 
1192 				/*
1193 				 * Updated data type register to indicate
1194 				 * that TDO data is currently being used.
1195 				 * Process the data in the VME file into the
1196 				 * TDO buffer.
1197 				 */
1198 
1199 				g_usDataType |= TDO_DATA;
1200 				ispVMData(g_pucOutData);
1201 				break;
1202 			case MASK:
1203 
1204 				/*
1205 				 * Store the maximum size of the MASK buffer.
1206 				 * Used to convert VME to HEX.
1207 				 */
1208 
1209 				if (g_usiDataSize > g_usMASKSize) {
1210 					g_usMASKSize = g_usiDataSize;
1211 				}
1212 
1213 				/*
1214 				 * Updated data type register to indicate that
1215 				 * MASK data is currently being used. Process
1216 				 * the data in the VME file into the MASK buffer
1217 				 */
1218 
1219 				g_usDataType |= MASK_DATA;
1220 				ispVMData(g_pucOutMaskData);
1221 				break;
1222 			case DMASK:
1223 
1224 				/*
1225 				 * Store the maximum size of the DMASK buffer.
1226 				 * Used to convert VME to HEX.
1227 				 */
1228 
1229 				if (g_usiDataSize > g_usDMASKSize) {
1230 					g_usDMASKSize = g_usiDataSize;
1231 				}
1232 
1233 				/*
1234 				 * Updated data type register to indicate that
1235 				 * DMASK data is currently being used. Process
1236 				 * the data in the VME file into the DMASK
1237 				 * buffer.
1238 				 */
1239 
1240 				g_usDataType |= DMASK_DATA;
1241 				ispVMData(g_pucOutDMaskData);
1242 				break;
1243 			case CMASK:
1244 
1245 				/*
1246 				 * Updated data type register to indicate that
1247 				 * MASK data is currently being used. Process
1248 				 * the data in the VME file into the MASK buffer
1249 				 */
1250 
1251 				g_usDataType |= CMASK_DATA;
1252 				ispVMData(g_pucOutMaskData);
1253 				break;
1254 			case CONTINUE:
1255 				return 0;
1256 			default:
1257 				/*
1258 				 * Encountered invalid opcode.
1259 				 */
1260 				return VME_INVALID_FILE;
1261 			}
1262 
1263 			switch (cDataByte) {
1264 			case TDI:
1265 
1266 				/*
1267 				 * Left bit shift. Used when performing
1268 				 * algorithm looping.
1269 				 */
1270 
1271 				if (g_usFlowControl & SHIFTLEFT) {
1272 					ispVMBitShift(SHL, g_usShiftValue);
1273 					g_usFlowControl &= ~SHIFTLEFT;
1274 				}
1275 
1276 				/*
1277 				 * Right bit shift. Used when performing
1278 				 * algorithm looping.
1279 				 */
1280 
1281 				if (g_usFlowControl & SHIFTRIGHT) {
1282 					ispVMBitShift(SHR, g_usShiftValue);
1283 					g_usFlowControl &= ~SHIFTRIGHT;
1284 				}
1285 			default:
1286 				break;
1287 			}
1288 
1289 			if (siDataSource) {
1290 				g_usDataType |= HEAP_IN; /*restore from memory*/
1291 			}
1292 	}
1293 
1294 	if (siDataSource) {  /*fetch data from heap memory upon return*/
1295 		g_usDataType |= HEAP_IN;
1296 	}
1297 
1298 	if (cDataByte < 0) {
1299 
1300 		/*
1301 		 * Encountered invalid opcode.
1302 		 */
1303 
1304 		return VME_INVALID_FILE;
1305 	} else {
1306 		return 0;
1307 	}
1308 }
1309 
1310 /*
1311  *
1312  * ispVMData
1313  * Extract one row of data operand from the current data type opcode. Perform
1314  * the decompression if necessary. Extra RAM is not required for the
1315  * decompression process. The decompression scheme employed in this module
1316  * is on row by row basis. The format of the data stream:
1317  * [compression code][compressed data stream]
1318  * 0x00    --No compression
1319  * 0x01    --Compress by 0x00.
1320  *           Example:
1321  *           Original stream:   0x000000000000000000000001
1322  *           Compressed stream: 0x01000901
1323  *           Detail:            0x01 is the code, 0x00 is the key,
1324  *                              0x09 is the count of 0x00 bytes,
1325  *                              0x01 is the uncompressed byte.
1326  * 0x02    --Compress by 0xFF.
1327  *           Example:
1328  *           Original stream:   0xFFFFFFFFFFFFFFFFFFFFFF01
1329  *           Compressed stream: 0x02FF0901
1330  *           Detail:            0x02 is the code, 0xFF is the key,
1331  *                              0x09 is the count of 0xFF bytes,
1332  *                              0x01 is the uncompressed byte.
1333  * 0x03
1334  * : :
1335  * 0xFE   -- Compress by nibble blocks.
1336  *           Example:
1337  *           Original stream:   0x84210842108421084210
1338  *           Compressed stream: 0x0584210
1339  *           Detail:            0x05 is the code, means 5 nibbles block.
1340  *                              0x84210 is the 5 nibble blocks.
1341  *                              The whole row is 80 bits given by g_usiDataSize.
1342  *                              The number of times the block repeat itself
1343  *                              is found by g_usiDataSize/(4*0x05) which is 4.
1344  * 0xFF   -- Compress by the most frequently happen byte.
1345  *           Example:
1346  *           Original stream:   0x04020401030904040404
1347  *           Compressed stream: 0xFF04(0,1,0x02,0,1,0x01,1,0x03,1,0x09,0,0,0)
1348  *                          or: 0xFF044090181C240
1349  *           Detail:            0xFF is the code, 0x04 is the key.
1350  *                              a bit of 0 represent the key shall be put into
1351  *                              the current bit position and a bit of 1
1352  *                              represent copying the next of 8 bits of data
1353  *                              in.
1354  *
1355  */
1356 
ispVMData(unsigned char * ByteData)1357 void ispVMData(unsigned char *ByteData)
1358 {
1359 	/* 09/11/07 NN added local variables initialization */
1360 	unsigned short size               = 0;
1361 	unsigned short i, j, m, getData   = 0;
1362 	unsigned char cDataByte           = 0;
1363 	unsigned char compress            = 0;
1364 	unsigned short FFcount            = 0;
1365 	unsigned char compr_char          = 0xFF;
1366 	unsigned short index              = 0;
1367 	signed char compression           = 0;
1368 
1369 	/*convert number in bits to bytes*/
1370 	if (g_usiDataSize % 8 > 0) {
1371 		/* 09/11/07 NN Type cast mismatch variables */
1372 		size = (unsigned short)(g_usiDataSize / 8 + 1);
1373 	} else {
1374 		/* 09/11/07 NN Type cast mismatch variables */
1375 		size = (unsigned short)(g_usiDataSize / 8);
1376 	}
1377 
1378 	/*
1379 	 * If there is compression, then check if compress by key
1380 	 * of 0x00 or 0xFF or by other keys or by nibble blocks
1381 	 */
1382 
1383 	if (g_usDataType & COMPRESS) {
1384 		compression = 1;
1385 		compress = GetByte();
1386 		if ((compress  == VAR) && (g_usDataType & HEAP_IN)) {
1387 			getData = 1;
1388 			g_usDataType &= ~(HEAP_IN);
1389 			compress = GetByte();
1390 		}
1391 
1392 		switch (compress) {
1393 		case 0x00:
1394 			/* No compression */
1395 			compression = 0;
1396 			break;
1397 		case 0x01:
1398 			/* Compress by byte 0x00 */
1399 			compr_char = 0x00;
1400 			break;
1401 		case 0x02:
1402 			/* Compress by byte 0xFF */
1403 			compr_char = 0xFF;
1404 			break;
1405 		case 0xFF:
1406 			/* Huffman encoding */
1407 			compr_char = GetByte();
1408 			i = 8;
1409 			for (index = 0; index < size; index++) {
1410 				ByteData[index] = 0x00;
1411 				if (i > 7) {
1412 					cDataByte = GetByte();
1413 					i = 0;
1414 				}
1415 				if ((cDataByte << i++) & 0x80)
1416 					m = 8;
1417 				else {
1418 					ByteData[index] = compr_char;
1419 					m = 0;
1420 				}
1421 
1422 				for (j = 0; j < m; j++) {
1423 					if (i > 7) {
1424 						cDataByte = GetByte();
1425 						i = 0;
1426 					}
1427 					ByteData[index] |=
1428 					((cDataByte << i++) & 0x80) >> j;
1429 				}
1430 			}
1431 			size = 0;
1432 			break;
1433 		default:
1434 			for (index = 0; index < size; index++)
1435 				ByteData[index] = 0x00;
1436 			for (index = 0; index < compress; index++) {
1437 				if (index % 2 == 0)
1438 					cDataByte = GetByte();
1439 				for (i = 0; i < size * 2 / compress; i++) {
1440 					j = (unsigned short)(index +
1441 						(i * (unsigned short)compress));
1442 					/*clear the nibble to zero first*/
1443 					if (j%2) {
1444 						if (index % 2)
1445 							ByteData[j/2] |=
1446 								cDataByte & 0xF;
1447 						else
1448 							ByteData[j/2] |=
1449 								cDataByte >> 4;
1450 					} else {
1451 						if (index % 2)
1452 							ByteData[j/2] |=
1453 								cDataByte << 4;
1454 						else
1455 							ByteData[j/2] |=
1456 							cDataByte & 0xF0;
1457 					}
1458 				}
1459 			}
1460 			size = 0;
1461 			break;
1462 		}
1463 	}
1464 
1465 	FFcount = 0;
1466 
1467 	/* Decompress by byte 0x00 or 0xFF */
1468 	for (index = 0; index < size; index++) {
1469 		if (FFcount <= 0) {
1470 			cDataByte = GetByte();
1471 			if ((cDataByte == VAR) && (g_usDataType&HEAP_IN) &&
1472 				!getData && !(g_usDataType&COMPRESS)) {
1473 				getData = 1;
1474 				g_usDataType &= ~(HEAP_IN);
1475 				cDataByte = GetByte();
1476 			}
1477 			ByteData[index] = cDataByte;
1478 			if ((compression) && (cDataByte == compr_char))
1479 				/* 09/11/07 NN Type cast mismatch variables */
1480 				FFcount = (unsigned short) ispVMDataSize();
1481 				/*The number of 0xFF or 0x00 bytes*/
1482 		} else {
1483 			FFcount--; /*Use up the 0xFF chain first*/
1484 			ByteData[index] = compr_char;
1485 		}
1486 	}
1487 
1488 	if (getData) {
1489 		g_usDataType |= HEAP_IN;
1490 		getData = 0;
1491 	}
1492 }
1493 
1494 /*
1495  *
1496  * ispVMShift
1497  *
1498  * Processes the SDR/XSDR/SIR commands.
1499  *
1500  */
1501 
ispVMShift(signed char a_cCode)1502 signed char ispVMShift(signed char a_cCode)
1503 {
1504 	/* 09/11/07 NN added local variables initialization */
1505 	unsigned short iDataIndex  = 0;
1506 	unsigned short iReadLoop   = 0;
1507 	signed char cRetCode       = 0;
1508 
1509 	cRetCode = 0;
1510 	/* 09/11/07 NN Type cast mismatch variables */
1511 	g_usiDataSize = (unsigned short) ispVMDataSize();
1512 
1513 	/*clear the flags first*/
1514 	g_usDataType &= ~(SIR_DATA + EXPRESS + SDR_DATA);
1515 	switch (a_cCode) {
1516 	case SIR:
1517 		g_usDataType |= SIR_DATA;
1518 		/*
1519 		 * 1/15/04 If performing cascading, then go directly to SHIFTIR.
1520 		 *  Else, go to IRPAUSE before going to SHIFTIR
1521 		 */
1522 		if (g_usFlowControl & CASCADE) {
1523 			ispVMStateMachine(SHIFTIR);
1524 		} else {
1525 			ispVMStateMachine(IRPAUSE);
1526 			ispVMStateMachine(SHIFTIR);
1527 			if (g_usHeadIR > 0) {
1528 				ispVMBypass(HIR, g_usHeadIR);
1529 				sclock();
1530 			}
1531 		}
1532 		break;
1533 	case XSDR:
1534 		g_usDataType |= EXPRESS; /*mark simultaneous in and out*/
1535 	case SDR:
1536 		g_usDataType |= SDR_DATA;
1537 		/*
1538 		 * 1/15/04 If already in SHIFTDR, then do not move state or
1539 		 * shift in header.  This would imply that the previously
1540 		 * shifted frame was a cascaded frame.
1541 		 */
1542 		if (g_cCurrentJTAGState != SHIFTDR) {
1543 			/*
1544 			 * 1/15/04 If performing cascading, then go directly
1545 			 * to SHIFTDR.  Else, go to DRPAUSE before going
1546 			 * to SHIFTDR
1547 			 */
1548 			if (g_usFlowControl & CASCADE) {
1549 				if (g_cCurrentJTAGState == DRPAUSE) {
1550 					ispVMStateMachine(SHIFTDR);
1551 					/*
1552 					 * 1/15/04 If cascade flag has been seat
1553 					 * and the current state is DRPAUSE,
1554 					 * this implies that the first cascaded
1555 					 * frame is about to be shifted in.  The
1556 					 * header must be shifted prior to
1557 					 * shifting the first cascaded frame.
1558 					 */
1559 					if (g_usHeadDR > 0) {
1560 						ispVMBypass(HDR, g_usHeadDR);
1561 						sclock();
1562 					}
1563 				} else {
1564 					ispVMStateMachine(SHIFTDR);
1565 				}
1566 			} else {
1567 				ispVMStateMachine(DRPAUSE);
1568 				ispVMStateMachine(SHIFTDR);
1569 				if (g_usHeadDR > 0) {
1570 					ispVMBypass(HDR, g_usHeadDR);
1571 					sclock();
1572 				}
1573 			}
1574 		}
1575 		break;
1576 	default:
1577 		return VME_INVALID_FILE;
1578 	}
1579 
1580 	cRetCode = ispVMDataCode();
1581 
1582 	if (cRetCode != 0) {
1583 		return VME_INVALID_FILE;
1584 	}
1585 
1586 #ifdef DEBUG
1587 	printf("%d ", g_usiDataSize);
1588 
1589 	if (g_usDataType & TDI_DATA) {
1590 		puts("TDI ");
1591 		PrintData(g_usiDataSize, g_pucInData);
1592 	}
1593 
1594 	if (g_usDataType & TDO_DATA) {
1595 		puts("\n\t\tTDO ");
1596 		PrintData(g_usiDataSize, g_pucOutData);
1597 	}
1598 
1599 	if (g_usDataType & MASK_DATA) {
1600 		puts("\n\t\tMASK ");
1601 		PrintData(g_usiDataSize, g_pucOutMaskData);
1602 	}
1603 
1604 	if (g_usDataType & DMASK_DATA) {
1605 		puts("\n\t\tDMASK ");
1606 		PrintData(g_usiDataSize, g_pucOutDMaskData);
1607 	}
1608 
1609 	puts(";\n");
1610 #endif /* DEBUG */
1611 
1612 	if (g_usDataType & TDO_DATA || g_usDataType & DMASK_DATA) {
1613 		if (g_usDataType & DMASK_DATA) {
1614 			cRetCode = ispVMReadandSave(g_usiDataSize);
1615 			if (!cRetCode) {
1616 				if (g_usTailDR > 0) {
1617 					sclock();
1618 					ispVMBypass(TDR, g_usTailDR);
1619 				}
1620 				ispVMStateMachine(DRPAUSE);
1621 				ispVMStateMachine(SHIFTDR);
1622 				if (g_usHeadDR > 0) {
1623 					ispVMBypass(HDR, g_usHeadDR);
1624 					sclock();
1625 				}
1626 				for (iDataIndex = 0;
1627 					iDataIndex < g_usiDataSize / 8 + 1;
1628 					iDataIndex++)
1629 					g_pucInData[iDataIndex] =
1630 						g_pucOutData[iDataIndex];
1631 				g_usDataType &= ~(TDO_DATA + DMASK_DATA);
1632 				cRetCode = ispVMSend(g_usiDataSize);
1633 			}
1634 		} else {
1635 			cRetCode = ispVMRead(g_usiDataSize);
1636 			if (cRetCode == -1 && g_cVendor == XILINX) {
1637 				for (iReadLoop = 0; iReadLoop < 30;
1638 					iReadLoop++) {
1639 					cRetCode = ispVMRead(g_usiDataSize);
1640 					if (!cRetCode) {
1641 						break;
1642 					} else {
1643 						/* Always DRPAUSE */
1644 						ispVMStateMachine(DRPAUSE);
1645 						/*
1646 						 * Bypass other devices
1647 						 * when appropriate
1648 						 */
1649 						ispVMBypass(TDR, g_usTailDR);
1650 						ispVMStateMachine(g_ucEndDR);
1651 						ispVMStateMachine(IDLE);
1652 						ispVMDelay(1000);
1653 					}
1654 				}
1655 			}
1656 		}
1657 	} else { /*TDI only*/
1658 		cRetCode = ispVMSend(g_usiDataSize);
1659 	}
1660 
1661 	/*transfer the input data to the output buffer for the next verify*/
1662 	if ((g_usDataType & EXPRESS) || (a_cCode == SDR)) {
1663 		if (g_pucOutData) {
1664 			for (iDataIndex = 0; iDataIndex < g_usiDataSize / 8 + 1;
1665 				iDataIndex++)
1666 				g_pucOutData[iDataIndex] =
1667 					g_pucInData[iDataIndex];
1668 		}
1669 	}
1670 
1671 	switch (a_cCode) {
1672 	case SIR:
1673 		/* 1/15/04 If not performing cascading, then shift ENDIR */
1674 		if (!(g_usFlowControl & CASCADE)) {
1675 			if (g_usTailIR > 0) {
1676 				sclock();
1677 				ispVMBypass(TIR, g_usTailIR);
1678 			}
1679 			ispVMStateMachine(g_ucEndIR);
1680 		}
1681 		break;
1682 	case XSDR:
1683 	case SDR:
1684 		/* 1/15/04 If not performing cascading, then shift ENDDR */
1685 		if (!(g_usFlowControl & CASCADE)) {
1686 			if (g_usTailDR > 0) {
1687 				sclock();
1688 				ispVMBypass(TDR, g_usTailDR);
1689 			}
1690 			ispVMStateMachine(g_ucEndDR);
1691 		}
1692 		break;
1693 	default:
1694 		break;
1695 	}
1696 
1697 	return cRetCode;
1698 }
1699 
1700 /*
1701  *
1702  * ispVMAmble
1703  *
1704  * This routine is to extract Header and Trailer parameter for SIR and
1705  * SDR operations.
1706  *
1707  * The Header and Trailer parameter are the pre-amble and post-amble bit
1708  * stream need to be shifted into TDI or out of TDO of the devices. Mostly
1709  * is for the purpose of bypassing the leading or trailing devices. ispVM
1710  * supports only shifting data into TDI to bypass the devices.
1711  *
1712  * For a single device, the header and trailer parameters are all set to 0
1713  * as default by ispVM. If it is for multiple devices, the header and trailer
1714  * value will change as specified by the VME file.
1715  *
1716  */
1717 
ispVMAmble(signed char Code)1718 signed char ispVMAmble(signed char Code)
1719 {
1720 	signed char compress = 0;
1721 	/* 09/11/07 NN Type cast mismatch variables */
1722 	g_usiDataSize = (unsigned short)ispVMDataSize();
1723 
1724 #ifdef DEBUG
1725 	printf("%d", g_usiDataSize);
1726 #endif /* DEBUG */
1727 
1728 	if (g_usiDataSize) {
1729 
1730 		/*
1731 		 * Discard the TDI byte and set the compression bit in the data
1732 		 * type register to false if compression is set because TDI data
1733 		 * after HIR/HDR/TIR/TDR is not compressed.
1734 		 */
1735 
1736 		GetByte();
1737 		if (g_usDataType & COMPRESS) {
1738 			g_usDataType &= ~(COMPRESS);
1739 			compress = 1;
1740 		}
1741 	}
1742 
1743 	switch (Code) {
1744 	case HIR:
1745 
1746 		/*
1747 		 * Store the maximum size of the HIR buffer.
1748 		 * Used to convert VME to HEX.
1749 		 */
1750 
1751 		if (g_usiDataSize > g_usHIRSize) {
1752 			g_usHIRSize = g_usiDataSize;
1753 		}
1754 
1755 		/*
1756 		 * Assign the HIR value and allocate memory.
1757 		 */
1758 
1759 		g_usHeadIR = g_usiDataSize;
1760 		if (g_usHeadIR) {
1761 			ispVMMemManager(HIR, g_usHeadIR);
1762 			ispVMData(g_pucHIRData);
1763 
1764 #ifdef DEBUG
1765 			puts(" TDI ");
1766 			PrintData(g_usHeadIR, g_pucHIRData);
1767 #endif /* DEBUG */
1768 		}
1769 		break;
1770 	case TIR:
1771 
1772 		/*
1773 		 * Store the maximum size of the TIR buffer.
1774 		 * Used to convert VME to HEX.
1775 		 */
1776 
1777 		if (g_usiDataSize > g_usTIRSize) {
1778 			g_usTIRSize = g_usiDataSize;
1779 		}
1780 
1781 		/*
1782 		 * Assign the TIR value and allocate memory.
1783 		 */
1784 
1785 		g_usTailIR = g_usiDataSize;
1786 		if (g_usTailIR) {
1787 			ispVMMemManager(TIR, g_usTailIR);
1788 			ispVMData(g_pucTIRData);
1789 
1790 #ifdef DEBUG
1791 			puts(" TDI ");
1792 			PrintData(g_usTailIR, g_pucTIRData);
1793 #endif /* DEBUG */
1794 		}
1795 		break;
1796 	case HDR:
1797 
1798 		/*
1799 		 * Store the maximum size of the HDR buffer.
1800 		 * Used to convert VME to HEX.
1801 		 */
1802 
1803 		if (g_usiDataSize > g_usHDRSize) {
1804 			g_usHDRSize = g_usiDataSize;
1805 		}
1806 
1807 		/*
1808 		 * Assign the HDR value and allocate memory.
1809 		 *
1810 		 */
1811 
1812 		g_usHeadDR = g_usiDataSize;
1813 		if (g_usHeadDR) {
1814 			ispVMMemManager(HDR, g_usHeadDR);
1815 			ispVMData(g_pucHDRData);
1816 
1817 #ifdef DEBUG
1818 			puts(" TDI ");
1819 			PrintData(g_usHeadDR, g_pucHDRData);
1820 #endif /* DEBUG */
1821 		}
1822 		break;
1823 	case TDR:
1824 
1825 		/*
1826 		 * Store the maximum size of the TDR buffer.
1827 		 * Used to convert VME to HEX.
1828 		 */
1829 
1830 		if (g_usiDataSize > g_usTDRSize) {
1831 			g_usTDRSize = g_usiDataSize;
1832 		}
1833 
1834 		/*
1835 		 * Assign the TDR value and allocate memory.
1836 		 *
1837 		 */
1838 
1839 		g_usTailDR = g_usiDataSize;
1840 		if (g_usTailDR) {
1841 			ispVMMemManager(TDR, g_usTailDR);
1842 			ispVMData(g_pucTDRData);
1843 
1844 #ifdef DEBUG
1845 			puts(" TDI ");
1846 			PrintData(g_usTailDR, g_pucTDRData);
1847 #endif /* DEBUG */
1848 		}
1849 		break;
1850 	default:
1851 		break;
1852 	}
1853 
1854 	/*
1855 	*
1856 	* Re-enable compression if it was previously set.
1857 	*
1858 	**/
1859 
1860 	if (compress) {
1861 		g_usDataType |= COMPRESS;
1862 	}
1863 
1864 	if (g_usiDataSize) {
1865 		Code = GetByte();
1866 		if (Code == CONTINUE) {
1867 			return 0;
1868 		} else {
1869 
1870 			/*
1871 			 * Encountered invalid opcode.
1872 			 */
1873 
1874 			return VME_INVALID_FILE;
1875 		}
1876 	}
1877 
1878 	return 0;
1879 }
1880 
1881 /*
1882  *
1883  * ispVMLoop
1884  *
1885  * Perform the function call upon by the REPEAT opcode.
1886  * Memory is to be allocated to store the entire loop from REPEAT to ENDLOOP.
1887  * After the loop is stored then execution begin. The REPEATLOOP flag is set
1888  * on the g_usFlowControl register to indicate the repeat loop is in session
1889  * and therefore fetch opcode from the memory instead of from the file.
1890  *
1891  */
1892 
ispVMLoop(unsigned short a_usLoopCount)1893 signed char ispVMLoop(unsigned short a_usLoopCount)
1894 {
1895 	/* 09/11/07 NN added local variables initialization */
1896 	signed char cRetCode      = 0;
1897 	unsigned short iHeapIndex = 0;
1898 	unsigned short iLoopIndex = 0;
1899 
1900 	g_usShiftValue = 0;
1901 	for (iHeapIndex = 0; iHeapIndex < g_iHEAPSize; iHeapIndex++) {
1902 		g_pucHeapMemory[iHeapIndex] = GetByte();
1903 	}
1904 
1905 	if (g_pucHeapMemory[iHeapIndex - 1] != ENDLOOP) {
1906 		return VME_INVALID_FILE;
1907 	}
1908 
1909 	g_usFlowControl |= REPEATLOOP;
1910 	g_usDataType |= HEAP_IN;
1911 
1912 	for (iLoopIndex = 0; iLoopIndex < a_usLoopCount; iLoopIndex++) {
1913 		g_iHeapCounter = 0;
1914 		cRetCode = ispVMCode();
1915 		g_usRepeatLoops++;
1916 		if (cRetCode < 0) {
1917 			break;
1918 		}
1919 	}
1920 
1921 	g_usDataType &= ~(HEAP_IN);
1922 	g_usFlowControl &= ~(REPEATLOOP);
1923 	return cRetCode;
1924 }
1925 
1926 /*
1927  *
1928  * ispVMBitShift
1929  *
1930  * Shift the TDI stream left or right by the number of bits. The data in
1931  * *g_pucInData is of the VME format, so the actual shifting is the reverse of
1932  * IEEE 1532 or SVF format.
1933  *
1934  */
1935 
ispVMBitShift(signed char mode,unsigned short bits)1936 signed char ispVMBitShift(signed char mode, unsigned short bits)
1937 {
1938 	/* 09/11/07 NN added local variables initialization */
1939 	unsigned short i       = 0;
1940 	unsigned short size    = 0;
1941 	unsigned short tmpbits = 0;
1942 
1943 	if (g_usiDataSize % 8 > 0) {
1944 		/* 09/11/07 NN Type cast mismatch variables */
1945 		size = (unsigned short)(g_usiDataSize / 8 + 1);
1946 	} else {
1947 		/* 09/11/07 NN Type cast mismatch variables */
1948 		size = (unsigned short)(g_usiDataSize / 8);
1949 	}
1950 
1951 	switch (mode) {
1952 	case SHR:
1953 		for (i = 0; i < size; i++) {
1954 			if (g_pucInData[i] != 0) {
1955 				tmpbits = bits;
1956 				while (tmpbits > 0) {
1957 					g_pucInData[i] <<= 1;
1958 					if (g_pucInData[i] == 0) {
1959 						i--;
1960 						g_pucInData[i] = 1;
1961 					}
1962 					tmpbits--;
1963 				}
1964 			}
1965 		}
1966 		break;
1967 	case SHL:
1968 		for (i = 0; i < size; i++) {
1969 			if (g_pucInData[i] != 0) {
1970 				tmpbits = bits;
1971 				while (tmpbits > 0) {
1972 					g_pucInData[i] >>= 1;
1973 					if (g_pucInData[i] == 0) {
1974 						i--;
1975 						g_pucInData[i] = 8;
1976 					}
1977 					tmpbits--;
1978 				}
1979 			}
1980 		}
1981 		break;
1982 	default:
1983 		return VME_INVALID_FILE;
1984 	}
1985 
1986 	return 0;
1987 }
1988 
1989 /*
1990  *
1991  * ispVMComment
1992  *
1993  * Displays the SVF comments.
1994  *
1995  */
1996 
ispVMComment(unsigned short a_usCommentSize)1997 void ispVMComment(unsigned short a_usCommentSize)
1998 {
1999 	char cCurByte = 0;
2000 	for (; a_usCommentSize > 0; a_usCommentSize--) {
2001 		/*
2002 		*
2003 		* Print character to the terminal.
2004 		*
2005 		**/
2006 		cCurByte = GetByte();
2007 		vme_out_char(cCurByte);
2008 	}
2009 	cCurByte = '\n';
2010 	vme_out_char(cCurByte);
2011 }
2012 
2013 /*
2014  *
2015  * ispVMHeader
2016  *
2017  * Iterate the length of the header and discard it.
2018  *
2019  */
2020 
ispVMHeader(unsigned short a_usHeaderSize)2021 void ispVMHeader(unsigned short a_usHeaderSize)
2022 {
2023 	for (; a_usHeaderSize > 0; a_usHeaderSize--) {
2024 		GetByte();
2025 	}
2026 }
2027 
2028 /*
2029  *
2030  * ispVMCalculateCRC32
2031  *
2032  * Calculate the 32-bit CRC.
2033  *
2034  */
2035 
ispVMCalculateCRC32(unsigned char a_ucData)2036 void ispVMCalculateCRC32(unsigned char a_ucData)
2037 {
2038 	/* 09/11/07 NN added local variables initialization */
2039 	unsigned char ucIndex          = 0;
2040 	unsigned char ucFlipData       = 0;
2041 	unsigned short usCRCTableEntry = 0;
2042 	unsigned int crc_table[16] = {
2043 		0x0000, 0xCC01, 0xD801,
2044 		0x1400, 0xF001, 0x3C00,
2045 		0x2800, 0xE401, 0xA001,
2046 		0x6C00, 0x7800, 0xB401,
2047 		0x5000, 0x9C01, 0x8801,
2048 		0x4400
2049 	};
2050 
2051 	for (ucIndex = 0; ucIndex < 8; ucIndex++) {
2052 		ucFlipData <<= 1;
2053 		if (a_ucData & 0x01) {
2054 			ucFlipData |= 0x01;
2055 		}
2056 		a_ucData >>= 1;
2057 	}
2058 
2059 	/* 09/11/07 NN Type cast mismatch variables */
2060 	usCRCTableEntry = (unsigned short)(crc_table[g_usCalculatedCRC & 0xF]);
2061 	g_usCalculatedCRC = (unsigned short)((g_usCalculatedCRC >> 4) & 0x0FFF);
2062 	g_usCalculatedCRC = (unsigned short)(g_usCalculatedCRC ^
2063 			usCRCTableEntry ^ crc_table[ucFlipData & 0xF]);
2064 	usCRCTableEntry = (unsigned short)(crc_table[g_usCalculatedCRC & 0xF]);
2065 	g_usCalculatedCRC = (unsigned short)((g_usCalculatedCRC >> 4) & 0x0FFF);
2066 	g_usCalculatedCRC = (unsigned short)(g_usCalculatedCRC ^
2067 		usCRCTableEntry ^ crc_table[(ucFlipData >> 4) & 0xF]);
2068 }
2069 
2070 /*
2071  *
2072  * ispVMLCOUNT
2073  *
2074  * Process the intelligent programming loops.
2075  *
2076  */
2077 
ispVMLCOUNT(unsigned short a_usCountSize)2078 signed char ispVMLCOUNT(unsigned short a_usCountSize)
2079 {
2080 	unsigned short usContinue	  = 1;
2081 	unsigned short usIntelBufferIndex = 0;
2082 	unsigned short usCountIndex       = 0;
2083 	signed char cRetCode              = 0;
2084 	signed char cRepeatHeap           = 0;
2085 	signed char cOpcode               = 0;
2086 	unsigned char ucState             = 0;
2087 	unsigned short usDelay            = 0;
2088 	unsigned short usToggle           = 0;
2089 
2090 	g_usIntelBufferSize = (unsigned short)ispVMDataSize();
2091 
2092 	/*
2093 	 * Allocate memory for intel buffer.
2094 	 *
2095 	 */
2096 
2097 	ispVMMemManager(LHEAP, g_usIntelBufferSize);
2098 
2099 	/*
2100 	 * Store the maximum size of the intelligent buffer.
2101 	 * Used to convert VME to HEX.
2102 	 */
2103 
2104 	if (g_usIntelBufferSize > g_usLCOUNTSize) {
2105 		g_usLCOUNTSize = g_usIntelBufferSize;
2106 	}
2107 
2108 	/*
2109 	 * Copy intel data to the buffer.
2110 	 */
2111 
2112 	for (usIntelBufferIndex = 0; usIntelBufferIndex < g_usIntelBufferSize;
2113 		usIntelBufferIndex++) {
2114 		g_pucIntelBuffer[usIntelBufferIndex] = GetByte();
2115 	}
2116 
2117 	/*
2118 	 * Set the data type register to get data from the intelligent
2119 	 * data buffer.
2120 	 */
2121 
2122 	g_usDataType |= LHEAP_IN;
2123 
2124 	/*
2125 	*
2126 	* If the HEAP_IN flag is set, temporarily unset the flag so data will be
2127 	* retrieved from the status buffer.
2128 	*
2129 	**/
2130 
2131 	if (g_usDataType & HEAP_IN) {
2132 		g_usDataType &= ~HEAP_IN;
2133 		cRepeatHeap = 1;
2134 	}
2135 
2136 #ifdef DEBUG
2137 	printf("LCOUNT %d;\n", a_usCountSize);
2138 #endif /* DEBUG */
2139 
2140 	/*
2141 	 * Iterate through the intelligent programming command.
2142 	*/
2143 
2144 	for (usCountIndex = 0; usCountIndex < a_usCountSize; usCountIndex++) {
2145 
2146 		/*
2147 		*
2148 		* Initialize the intel data index to 0 before each iteration.
2149 		*
2150 		**/
2151 
2152 		g_usIntelDataIndex = 0;
2153 		cOpcode            = 0;
2154 		ucState            = 0;
2155 		usDelay            = 0;
2156 		usToggle           = 0;
2157 		usContinue		   = 1;
2158 
2159 		/*
2160 		*
2161 		* Begin looping through all the VME opcodes.
2162 		*
2163 		*/
2164 		/*
2165 		* 4/1/09 Nguyen replaced the recursive function call codes on
2166 		*        the ispVMLCOUNT function
2167 		*
2168 		*/
2169 		while (usContinue) {
2170 			cOpcode = GetByte();
2171 			switch (cOpcode) {
2172 			case HIR:
2173 			case TIR:
2174 			case HDR:
2175 			case TDR:
2176 				/*
2177 				 * Set the header/trailer of the device in order
2178 				 * to bypass successfully.
2179 				 */
2180 
2181 				ispVMAmble(cOpcode);
2182 			break;
2183 			case STATE:
2184 
2185 				/*
2186 				 * Step the JTAG state machine.
2187 				 */
2188 
2189 				ucState = GetByte();
2190 				/*
2191 				 * Step the JTAG state machine to DRCAPTURE
2192 				 * to support Looping.
2193 				 */
2194 
2195 				if ((g_usDataType & LHEAP_IN) &&
2196 					 (ucState == DRPAUSE) &&
2197 					 (g_cCurrentJTAGState == ucState)) {
2198 					ispVMStateMachine(DRCAPTURE);
2199 				}
2200 				ispVMStateMachine(ucState);
2201 #ifdef DEBUG
2202 				printf("LDELAY %s ", GetState(ucState));
2203 #endif /* DEBUG */
2204 				break;
2205 			case SIR:
2206 #ifdef DEBUG
2207 				printf("SIR ");
2208 #endif /* DEBUG */
2209 				/*
2210 				 * Shift in data into the device.
2211 				 */
2212 
2213 				cRetCode = ispVMShift(cOpcode);
2214 				break;
2215 			case SDR:
2216 
2217 #ifdef DEBUG
2218 				printf("LSDR ");
2219 #endif /* DEBUG */
2220 				/*
2221 				 * Shift in data into the device.
2222 				 */
2223 
2224 				cRetCode = ispVMShift(cOpcode);
2225 				break;
2226 			case WAIT:
2227 
2228 				/*
2229 				*
2230 				* Observe delay.
2231 				*
2232 				*/
2233 
2234 				usDelay = (unsigned short)ispVMDataSize();
2235 				ispVMDelay(usDelay);
2236 
2237 #ifdef DEBUG
2238 				if (usDelay & 0x8000) {
2239 
2240 					/*
2241 					 * Since MSB is set, the delay time must
2242 					 * be decoded to millisecond. The
2243 					 * SVF2VME encodes the MSB to represent
2244 					 * millisecond.
2245 					 */
2246 
2247 					usDelay &= ~0x8000;
2248 					printf("%.2E SEC;\n",
2249 						(float) usDelay / 1000);
2250 				} else {
2251 					/*
2252 					 * Since MSB is not set, the delay time
2253 					 * is given as microseconds.
2254 					 */
2255 
2256 					printf("%.2E SEC;\n",
2257 						(float) usDelay / 1000000);
2258 				}
2259 #endif /* DEBUG */
2260 				break;
2261 			case TCK:
2262 
2263 				/*
2264 				 * Issue clock toggles.
2265 				 */
2266 
2267 				usToggle = (unsigned short)ispVMDataSize();
2268 				ispVMClocks(usToggle);
2269 
2270 #ifdef DEBUG
2271 				printf("RUNTEST %d TCK;\n", usToggle);
2272 #endif /* DEBUG */
2273 				break;
2274 			case ENDLOOP:
2275 
2276 				/*
2277 				 * Exit point from processing loops.
2278 				 */
2279 				usContinue = 0;
2280 				break;
2281 
2282 			case COMMENT:
2283 
2284 				/*
2285 				 * Display comment.
2286 				 */
2287 
2288 				ispVMComment((unsigned short) ispVMDataSize());
2289 				break;
2290 			case ispEN:
2291 				ucState = GetByte();
2292 				if ((ucState == ON) || (ucState == 0x01))
2293 					writePort(g_ucPinENABLE, 0x01);
2294 				else
2295 					writePort(g_ucPinENABLE, 0x00);
2296 				ispVMDelay(1);
2297 				break;
2298 			case TRST:
2299 				if (GetByte() == 0x01)
2300 					writePort(g_ucPinTRST, 0x01);
2301 				else
2302 					writePort(g_ucPinTRST, 0x00);
2303 				ispVMDelay(1);
2304 				break;
2305 			default:
2306 
2307 				/*
2308 				 * Invalid opcode encountered.
2309 				 */
2310 
2311 				debug("\nINVALID OPCODE: 0x%.2X\n", cOpcode);
2312 
2313 				return VME_INVALID_FILE;
2314 			}
2315 		}
2316 		if (cRetCode >= 0) {
2317 			/*
2318 			 * Break if intelligent programming is successful.
2319 			 */
2320 
2321 			break;
2322 		}
2323 
2324 	}
2325 	/*
2326 	 * If HEAP_IN flag was temporarily disabled,
2327 	 * re-enable it before exiting
2328 	 */
2329 
2330 	if (cRepeatHeap) {
2331 		g_usDataType |= HEAP_IN;
2332 	}
2333 
2334 	/*
2335 	 * Set the data type register to not get data from the
2336 	 * intelligent data buffer.
2337 	 */
2338 
2339 	g_usDataType &= ~LHEAP_IN;
2340 	return cRetCode;
2341 }
2342 /*
2343  *
2344  * ispVMClocks
2345  *
2346  * Applies the specified number of pulses to TCK.
2347  *
2348  */
2349 
ispVMClocks(unsigned short Clocks)2350 void ispVMClocks(unsigned short Clocks)
2351 {
2352 	unsigned short iClockIndex = 0;
2353 	for (iClockIndex = 0; iClockIndex < Clocks; iClockIndex++) {
2354 		sclock();
2355 	}
2356 }
2357 
2358 /*
2359  *
2360  * ispVMBypass
2361  *
2362  * This procedure takes care of the HIR, HDR, TIR, TDR for the
2363  * purpose of putting the other devices into Bypass mode. The
2364  * current state is checked to find out if it is at DRPAUSE or
2365  * IRPAUSE. If it is at DRPAUSE, perform bypass register scan.
2366  * If it is at IRPAUSE, scan into instruction registers the bypass
2367  * instruction.
2368  *
2369  */
2370 
ispVMBypass(signed char ScanType,unsigned short Bits)2371 void ispVMBypass(signed char ScanType, unsigned short Bits)
2372 {
2373 	/* 09/11/07 NN added local variables initialization */
2374 	unsigned short iIndex       = 0;
2375 	unsigned short iSourceIndex = 0;
2376 	unsigned char cBitState     = 0;
2377 	unsigned char cCurByte      = 0;
2378 	unsigned char *pcSource    = NULL;
2379 
2380 	if (Bits <= 0) {
2381 		return;
2382 	}
2383 
2384 	switch (ScanType) {
2385 	case HIR:
2386 		pcSource = g_pucHIRData;
2387 		break;
2388 	case TIR:
2389 		pcSource = g_pucTIRData;
2390 		break;
2391 	case HDR:
2392 		pcSource = g_pucHDRData;
2393 		break;
2394 	case TDR:
2395 		pcSource = g_pucTDRData;
2396 		break;
2397 	default:
2398 		break;
2399 	}
2400 
2401 	iSourceIndex = 0;
2402 	cBitState = 0;
2403 	for (iIndex = 0; iIndex < Bits - 1; iIndex++) {
2404 		/* Scan instruction or bypass register */
2405 		if (iIndex % 8 == 0) {
2406 			cCurByte = pcSource[iSourceIndex++];
2407 		}
2408 		cBitState = (unsigned char) (((cCurByte << iIndex % 8) & 0x80)
2409 			? 0x01 : 0x00);
2410 		writePort(g_ucPinTDI, cBitState);
2411 		sclock();
2412 	}
2413 
2414 	if (iIndex % 8 == 0)  {
2415 		cCurByte = pcSource[iSourceIndex++];
2416 	}
2417 
2418 	cBitState = (unsigned char) (((cCurByte << iIndex % 8) & 0x80)
2419 		? 0x01 : 0x00);
2420 	writePort(g_ucPinTDI, cBitState);
2421 }
2422 
2423 /*
2424  *
2425  * ispVMStateMachine
2426  *
2427  * This procedure steps all devices in the daisy chain from a given
2428  * JTAG state to the next desirable state. If the next state is TLR,
2429  * the JTAG state machine is brute forced into TLR by driving TMS
2430  * high and pulse TCK 6 times.
2431  *
2432  */
2433 
ispVMStateMachine(signed char cNextJTAGState)2434 void ispVMStateMachine(signed char cNextJTAGState)
2435 {
2436 	/* 09/11/07 NN added local variables initialization */
2437 	signed char cPathIndex  = 0;
2438 	signed char cStateIndex = 0;
2439 
2440 	if ((g_cCurrentJTAGState == cNextJTAGState) &&
2441 		(cNextJTAGState != RESET)) {
2442 		return;
2443 	}
2444 
2445 	for (cStateIndex = 0; cStateIndex < 25; cStateIndex++) {
2446 		if ((g_cCurrentJTAGState ==
2447 			 g_JTAGTransistions[cStateIndex].CurState) &&
2448 			(cNextJTAGState ==
2449 				 g_JTAGTransistions[cStateIndex].NextState)) {
2450 			break;
2451 		}
2452 	}
2453 
2454 	g_cCurrentJTAGState = cNextJTAGState;
2455 	for (cPathIndex = 0;
2456 		cPathIndex < g_JTAGTransistions[cStateIndex].Pulses;
2457 		cPathIndex++) {
2458 		if ((g_JTAGTransistions[cStateIndex].Pattern << cPathIndex)
2459 			& 0x80) {
2460 			writePort(g_ucPinTMS, (unsigned char) 0x01);
2461 		} else {
2462 			writePort(g_ucPinTMS, (unsigned char) 0x00);
2463 		}
2464 		sclock();
2465 	}
2466 
2467 	writePort(g_ucPinTDI, 0x00);
2468 	writePort(g_ucPinTMS, 0x00);
2469 }
2470 
2471 /*
2472  *
2473  * ispVMStart
2474  *
2475  * Enable the port to the device and set the state to RESET (TLR).
2476  *
2477  */
2478 
ispVMStart()2479 void ispVMStart()
2480 {
2481 #ifdef DEBUG
2482 	printf("// ISPVM EMBEDDED ADDED\n");
2483 	printf("STATE RESET;\n");
2484 #endif
2485 	g_usFlowControl	= 0;
2486 	g_usDataType = g_uiChecksumIndex = g_cCurrentJTAGState = 0;
2487 	g_usHeadDR = g_usHeadIR = g_usTailDR = g_usTailIR = 0;
2488 	g_usMaxSize = g_usShiftValue = g_usRepeatLoops = 0;
2489 	g_usTDOSize =  g_usMASKSize = g_usTDISize = 0;
2490 	g_usDMASKSize = g_usLCOUNTSize = g_usHDRSize = 0;
2491 	g_usTDRSize = g_usHIRSize = g_usTIRSize =  g_usHeapSize	= 0;
2492 	g_pLVDSList = NULL;
2493 	g_usLVDSPairCount = 0;
2494 	previous_size = 0;
2495 
2496 	ispVMStateMachine(RESET);    /*step devices to RESET state*/
2497 }
2498 
2499 /*
2500  *
2501  * ispVMEnd
2502  *
2503  * Set the state of devices to RESET to enable the devices and disable
2504  * the port.
2505  *
2506  */
2507 
ispVMEnd()2508 void ispVMEnd()
2509 {
2510 #ifdef DEBUG
2511 	printf("// ISPVM EMBEDDED ADDED\n");
2512 	printf("STATE RESET;\n");
2513 	printf("RUNTEST 1.00E-001 SEC;\n");
2514 #endif
2515 
2516 	ispVMStateMachine(RESET);   /*step devices to RESET state */
2517 	ispVMDelay(1000);              /*wake up devices*/
2518 }
2519 
2520 /*
2521  *
2522  * ispVMSend
2523  *
2524  * Send the TDI data stream to devices. The data stream can be
2525  * instructions or data.
2526  *
2527  */
2528 
ispVMSend(unsigned short a_usiDataSize)2529 signed char ispVMSend(unsigned short a_usiDataSize)
2530 {
2531 	/* 09/11/07 NN added local variables initialization */
2532 	unsigned short iIndex       = 0;
2533 	unsigned short iInDataIndex = 0;
2534 	unsigned char cCurByte      = 0;
2535 	unsigned char cBitState     = 0;
2536 
2537 	for (iIndex = 0; iIndex < a_usiDataSize - 1; iIndex++) {
2538 		if (iIndex % 8 == 0) {
2539 			cCurByte = g_pucInData[iInDataIndex++];
2540 		}
2541 		cBitState = (unsigned char)(((cCurByte << iIndex % 8) & 0x80)
2542 			? 0x01 : 0x00);
2543 		writePort(g_ucPinTDI, cBitState);
2544 		sclock();
2545 	}
2546 
2547 	if (iIndex % 8 == 0) {
2548 		/* Take care of the last bit */
2549 		cCurByte = g_pucInData[iInDataIndex];
2550 	}
2551 
2552 	cBitState = (unsigned char) (((cCurByte << iIndex % 8) & 0x80)
2553 		? 0x01 : 0x00);
2554 
2555 	writePort(g_ucPinTDI, cBitState);
2556 	if (g_usFlowControl & CASCADE) {
2557 		/*1/15/04 Clock in last bit for the first n-1 cascaded frames */
2558 		sclock();
2559 	}
2560 
2561 	return 0;
2562 }
2563 
2564 /*
2565  *
2566  * ispVMRead
2567  *
2568  * Read the data stream from devices and verify.
2569  *
2570  */
2571 
ispVMRead(unsigned short a_usiDataSize)2572 signed char ispVMRead(unsigned short a_usiDataSize)
2573 {
2574 	/* 09/11/07 NN added local variables initialization */
2575 	unsigned short usDataSizeIndex    = 0;
2576 	unsigned short usErrorCount       = 0;
2577 	unsigned short usLastBitIndex     = 0;
2578 	unsigned char cDataByte           = 0;
2579 	unsigned char cMaskByte           = 0;
2580 	unsigned char cInDataByte         = 0;
2581 	unsigned char cCurBit             = 0;
2582 	unsigned char cByteIndex          = 0;
2583 	unsigned short usBufferIndex      = 0;
2584 	unsigned char ucDisplayByte       = 0x00;
2585 	unsigned char ucDisplayFlag       = 0x01;
2586 	char StrChecksum[256]            = {0};
2587 	unsigned char g_usCalculateChecksum = 0x00;
2588 
2589 	/* 09/11/07 NN Type cast mismatch variables */
2590 	usLastBitIndex = (unsigned short)(a_usiDataSize - 1);
2591 
2592 #ifndef DEBUG
2593 	/*
2594 	 * If mask is not all zeros, then set the display flag to 0x00,
2595 	 * otherwise it shall be set to 0x01 to indicate that data read
2596 	 * from the device shall be displayed. If DEBUG is defined,
2597 	 * always display data.
2598 	 */
2599 
2600 	for (usDataSizeIndex = 0; usDataSizeIndex < (a_usiDataSize + 7) / 8;
2601 		usDataSizeIndex++) {
2602 		if (g_usDataType & MASK_DATA) {
2603 			if (g_pucOutMaskData[usDataSizeIndex] != 0x00) {
2604 				ucDisplayFlag = 0x00;
2605 				break;
2606 			}
2607 		} else if (g_usDataType & CMASK_DATA) {
2608 			g_usCalculateChecksum = 0x01;
2609 			ucDisplayFlag = 0x00;
2610 			break;
2611 		} else {
2612 			ucDisplayFlag = 0x00;
2613 			break;
2614 		}
2615 	}
2616 #endif /* DEBUG */
2617 
2618 	/*
2619 	*
2620 	* Begin shifting data in and out of the device.
2621 	*
2622 	**/
2623 
2624 	for (usDataSizeIndex = 0; usDataSizeIndex < a_usiDataSize;
2625 		usDataSizeIndex++) {
2626 		if (cByteIndex == 0) {
2627 
2628 			/*
2629 			 * Grab byte from TDO buffer.
2630 			 */
2631 
2632 			if (g_usDataType & TDO_DATA) {
2633 				cDataByte = g_pucOutData[usBufferIndex];
2634 			}
2635 
2636 			/*
2637 			 * Grab byte from MASK buffer.
2638 			 */
2639 
2640 			if (g_usDataType & MASK_DATA) {
2641 				cMaskByte = g_pucOutMaskData[usBufferIndex];
2642 			} else {
2643 				cMaskByte = 0xFF;
2644 			}
2645 
2646 			/*
2647 			 * Grab byte from CMASK buffer.
2648 			 */
2649 
2650 			if (g_usDataType & CMASK_DATA) {
2651 				cMaskByte = 0x00;
2652 				g_usCalculateChecksum = 0x01;
2653 			}
2654 
2655 			/*
2656 			 * Grab byte from TDI buffer.
2657 			 */
2658 
2659 			if (g_usDataType & TDI_DATA) {
2660 				cInDataByte = g_pucInData[usBufferIndex];
2661 			}
2662 
2663 			usBufferIndex++;
2664 		}
2665 
2666 		cCurBit = readPort();
2667 
2668 		if (ucDisplayFlag) {
2669 			ucDisplayByte <<= 1;
2670 			ucDisplayByte |= cCurBit;
2671 		}
2672 
2673 		/*
2674 		 * Check if data read from port matches with expected TDO.
2675 		 */
2676 
2677 		if (g_usDataType & TDO_DATA) {
2678 			/* 08/28/08 NN Added Calculate checksum support. */
2679 			if (g_usCalculateChecksum) {
2680 				if (cCurBit == 0x01)
2681 					g_usChecksum +=
2682 						(1 << (g_uiChecksumIndex % 8));
2683 				g_uiChecksumIndex++;
2684 			} else {
2685 				if ((((cMaskByte << cByteIndex) & 0x80)
2686 					? 0x01 : 0x00)) {
2687 					if (cCurBit != (unsigned char)
2688 					(((cDataByte << cByteIndex) & 0x80)
2689 						? 0x01 : 0x00)) {
2690 						usErrorCount++;
2691 					}
2692 				}
2693 			}
2694 		}
2695 
2696 		/*
2697 		 * Write TDI data to the port.
2698 		 */
2699 
2700 		writePort(g_ucPinTDI,
2701 			(unsigned char)(((cInDataByte << cByteIndex) & 0x80)
2702 				? 0x01 : 0x00));
2703 
2704 		if (usDataSizeIndex < usLastBitIndex) {
2705 
2706 			/*
2707 			 * Clock data out from the data shift register.
2708 			 */
2709 
2710 			sclock();
2711 		} else if (g_usFlowControl & CASCADE) {
2712 
2713 			/*
2714 			 * Clock in last bit for the first N - 1 cascaded frames
2715 			 */
2716 
2717 			sclock();
2718 		}
2719 
2720 		/*
2721 		 * Increment the byte index. If it exceeds 7, then reset it back
2722 		 * to zero.
2723 		 */
2724 
2725 		cByteIndex++;
2726 		if (cByteIndex >= 8) {
2727 			if (ucDisplayFlag) {
2728 
2729 			/*
2730 			 * Store displayed data in the TDO buffer. By reusing
2731 			 * the TDO buffer to store displayed data, there is no
2732 			 * need to allocate a buffer simply to hold display
2733 			 * data. This will not cause any false verification
2734 			 * errors because the true TDO byte has already
2735 			 * been consumed.
2736 			 */
2737 
2738 				g_pucOutData[usBufferIndex - 1] = ucDisplayByte;
2739 				ucDisplayByte = 0;
2740 			}
2741 
2742 			cByteIndex = 0;
2743 		}
2744 		/* 09/12/07 Nguyen changed to display the 1 bit expected data */
2745 		else if (a_usiDataSize == 1) {
2746 			if (ucDisplayFlag) {
2747 
2748 				/*
2749 				 * Store displayed data in the TDO buffer.
2750 				 * By reusing the TDO buffer to store displayed
2751 				 * data, there is no need to allocate
2752 				 * a buffer simply to hold display data. This
2753 				 * will not cause any false verification errors
2754 				 * because the true TDO byte has already
2755 				 * been consumed.
2756 				 */
2757 
2758 				/*
2759 				 * Flip ucDisplayByte and store it in cDataByte.
2760 				 */
2761 				cDataByte = 0x00;
2762 				for (usBufferIndex = 0; usBufferIndex < 8;
2763 					usBufferIndex++) {
2764 					cDataByte <<= 1;
2765 					if (ucDisplayByte & 0x01) {
2766 						cDataByte |= 0x01;
2767 					}
2768 					ucDisplayByte >>= 1;
2769 				}
2770 				g_pucOutData[0] = cDataByte;
2771 				ucDisplayByte = 0;
2772 			}
2773 
2774 			cByteIndex = 0;
2775 		}
2776 	}
2777 
2778 	if (ucDisplayFlag) {
2779 
2780 #ifdef DEBUG
2781 		debug("RECEIVED TDO (");
2782 #else
2783 		vme_out_string("Display Data: 0x");
2784 #endif /* DEBUG */
2785 
2786 		/* 09/11/07 NN Type cast mismatch variables */
2787 		for (usDataSizeIndex = (unsigned short)
2788 				((a_usiDataSize + 7) / 8);
2789 			usDataSizeIndex > 0 ; usDataSizeIndex--) {
2790 			cMaskByte = g_pucOutData[usDataSizeIndex - 1];
2791 			cDataByte = 0x00;
2792 
2793 			/*
2794 			 * Flip cMaskByte and store it in cDataByte.
2795 			 */
2796 
2797 			for (usBufferIndex = 0; usBufferIndex < 8;
2798 				usBufferIndex++) {
2799 				cDataByte <<= 1;
2800 				if (cMaskByte & 0x01) {
2801 					cDataByte |= 0x01;
2802 				}
2803 				cMaskByte >>= 1;
2804 			}
2805 #ifdef DEBUG
2806 			printf("%.2X", cDataByte);
2807 			if ((((a_usiDataSize + 7) / 8) - usDataSizeIndex)
2808 				% 40 == 39) {
2809 				printf("\n\t\t");
2810 			}
2811 #else
2812 			vme_out_hex(cDataByte);
2813 #endif /* DEBUG */
2814 		}
2815 
2816 #ifdef DEBUG
2817 		printf(")\n\n");
2818 #else
2819 		vme_out_string("\n\n");
2820 #endif /* DEBUG */
2821 		/* 09/02/08 Nguyen changed to display the data Checksum */
2822 		if (g_usChecksum != 0) {
2823 			g_usChecksum &= 0xFFFF;
2824 			sprintf(StrChecksum, "Data Checksum: %.4lX\n\n",
2825 				g_usChecksum);
2826 			vme_out_string(StrChecksum);
2827 			g_usChecksum = 0;
2828 		}
2829 	}
2830 
2831 	if (usErrorCount > 0) {
2832 		if (g_usFlowControl & VERIFYUES) {
2833 			vme_out_string(
2834 				"USERCODE verification failed.   "
2835 				"Continue programming......\n\n");
2836 			g_usFlowControl &= ~(VERIFYUES);
2837 			return 0;
2838 		} else {
2839 
2840 #ifdef DEBUG
2841 			printf("TOTAL ERRORS: %d\n", usErrorCount);
2842 #endif /* DEBUG */
2843 
2844 			return VME_VERIFICATION_FAILURE;
2845 		}
2846 	} else {
2847 		if (g_usFlowControl & VERIFYUES) {
2848 			vme_out_string("USERCODE verification passed.    "
2849 				"Programming aborted.\n\n");
2850 			g_usFlowControl &= ~(VERIFYUES);
2851 			return 1;
2852 		} else {
2853 			return 0;
2854 		}
2855 	}
2856 }
2857 
2858 /*
2859  *
2860  * ispVMReadandSave
2861  *
2862  * Support dynamic I/O.
2863  *
2864  */
2865 
ispVMReadandSave(unsigned short int a_usiDataSize)2866 signed char ispVMReadandSave(unsigned short int a_usiDataSize)
2867 {
2868 	/* 09/11/07 NN added local variables initialization */
2869 	unsigned short int usDataSizeIndex = 0;
2870 	unsigned short int usLastBitIndex  = 0;
2871 	unsigned short int usBufferIndex   = 0;
2872 	unsigned short int usOutBitIndex   = 0;
2873 	unsigned short int usLVDSIndex     = 0;
2874 	unsigned char cDataByte            = 0;
2875 	unsigned char cDMASKByte           = 0;
2876 	unsigned char cInDataByte          = 0;
2877 	unsigned char cCurBit              = 0;
2878 	unsigned char cByteIndex           = 0;
2879 	signed char cLVDSByteIndex         = 0;
2880 
2881 	/* 09/11/07 NN Type cast mismatch variables */
2882 	usLastBitIndex = (unsigned short) (a_usiDataSize - 1);
2883 
2884 	/*
2885 	*
2886 	* Iterate through the data bits.
2887 	*
2888 	*/
2889 
2890 	for (usDataSizeIndex = 0; usDataSizeIndex < a_usiDataSize;
2891 		usDataSizeIndex++) {
2892 		if (cByteIndex == 0) {
2893 
2894 			/*
2895 			 * Grab byte from DMASK buffer.
2896 			 */
2897 
2898 			if (g_usDataType & DMASK_DATA) {
2899 				cDMASKByte = g_pucOutDMaskData[usBufferIndex];
2900 			} else {
2901 				cDMASKByte = 0x00;
2902 			}
2903 
2904 			/*
2905 			 * Grab byte from TDI buffer.
2906 			 */
2907 
2908 			if (g_usDataType & TDI_DATA) {
2909 				cInDataByte = g_pucInData[usBufferIndex];
2910 			}
2911 
2912 			usBufferIndex++;
2913 		}
2914 
2915 		cCurBit = readPort();
2916 		cDataByte = (unsigned char)(((cInDataByte << cByteIndex) & 0x80)
2917 			? 0x01 : 0x00);
2918 
2919 		/*
2920 		 * Initialize the byte to be zero.
2921 		 */
2922 
2923 		if (usOutBitIndex % 8 == 0) {
2924 			g_pucOutData[usOutBitIndex / 8] = 0x00;
2925 		}
2926 
2927 		/*
2928 		 * Use TDI, DMASK, and device TDO to create new TDI (actually
2929 		 * stored in g_pucOutData).
2930 		 */
2931 
2932 		if ((((cDMASKByte << cByteIndex) & 0x80) ? 0x01 : 0x00)) {
2933 
2934 			if (g_pLVDSList) {
2935 				for (usLVDSIndex = 0;
2936 					 usLVDSIndex < g_usLVDSPairCount;
2937 					usLVDSIndex++) {
2938 					if (g_pLVDSList[usLVDSIndex].
2939 						usNegativeIndex ==
2940 						usDataSizeIndex) {
2941 						g_pLVDSList[usLVDSIndex].
2942 							ucUpdate = 0x01;
2943 						break;
2944 					}
2945 				}
2946 			}
2947 
2948 			/*
2949 			 * DMASK bit is 1, use TDI.
2950 			 */
2951 
2952 			g_pucOutData[usOutBitIndex / 8] |= (unsigned char)
2953 				(((cDataByte & 0x1) ? 0x01 : 0x00) <<
2954 				(7 - usOutBitIndex % 8));
2955 		} else {
2956 
2957 			/*
2958 			 * DMASK bit is 0, use device TDO.
2959 			 */
2960 
2961 			g_pucOutData[usOutBitIndex / 8] |= (unsigned char)
2962 				(((cCurBit & 0x1) ? 0x01 : 0x00) <<
2963 				(7 - usOutBitIndex % 8));
2964 		}
2965 
2966 		/*
2967 		 * Shift in TDI in order to get TDO out.
2968 		 */
2969 
2970 		usOutBitIndex++;
2971 		writePort(g_ucPinTDI, cDataByte);
2972 		if (usDataSizeIndex < usLastBitIndex) {
2973 			sclock();
2974 		}
2975 
2976 		/*
2977 		 * Increment the byte index. If it exceeds 7, then reset it back
2978 		 * to zero.
2979 		 */
2980 
2981 		cByteIndex++;
2982 		if (cByteIndex >= 8) {
2983 			cByteIndex = 0;
2984 		}
2985 	}
2986 
2987 	/*
2988 	 * If g_pLVDSList exists and pairs need updating, then update
2989 	 * the negative-pair to receive the flipped positive-pair value.
2990 	 */
2991 
2992 	if (g_pLVDSList) {
2993 		for (usLVDSIndex = 0; usLVDSIndex < g_usLVDSPairCount;
2994 			usLVDSIndex++) {
2995 			if (g_pLVDSList[usLVDSIndex].ucUpdate) {
2996 
2997 				/*
2998 				 * Read the positive value and flip it.
2999 				 */
3000 
3001 				cDataByte = (unsigned char)
3002 				 (((g_pucOutData[g_pLVDSList[usLVDSIndex].
3003 					usPositiveIndex / 8]
3004 					<< (g_pLVDSList[usLVDSIndex].
3005 					usPositiveIndex % 8)) & 0x80) ?
3006 					0x01 : 0x00);
3007 				/* 09/11/07 NN Type cast mismatch variables */
3008 				cDataByte = (unsigned char) (!cDataByte);
3009 
3010 				/*
3011 				 * Get the byte that needs modification.
3012 				 */
3013 
3014 				cInDataByte =
3015 				g_pucOutData[g_pLVDSList[usLVDSIndex].
3016 					usNegativeIndex / 8];
3017 
3018 				if (cDataByte) {
3019 
3020 					/*
3021 					 * Copy over the current byte and
3022 					 * set the negative bit to 1.
3023 					 */
3024 
3025 					cDataByte = 0x00;
3026 					for (cLVDSByteIndex = 7;
3027 						cLVDSByteIndex >= 0;
3028 						cLVDSByteIndex--) {
3029 						cDataByte <<= 1;
3030 						if (7 -
3031 						(g_pLVDSList[usLVDSIndex].
3032 							usNegativeIndex % 8) ==
3033 							cLVDSByteIndex) {
3034 
3035 							/*
3036 							 * Set negative bit to 1
3037 							 */
3038 
3039 							cDataByte |= 0x01;
3040 						} else if (cInDataByte & 0x80) {
3041 							cDataByte |= 0x01;
3042 						}
3043 
3044 						cInDataByte <<= 1;
3045 					}
3046 
3047 					/*
3048 					 * Store the modified byte.
3049 					 */
3050 
3051 					g_pucOutData[g_pLVDSList[usLVDSIndex].
3052 					usNegativeIndex / 8] = cDataByte;
3053 				} else {
3054 
3055 					/*
3056 					 * Copy over the current byte and set
3057 					 * the negative bit to 0.
3058 					 */
3059 
3060 					cDataByte = 0x00;
3061 					for (cLVDSByteIndex = 7;
3062 						cLVDSByteIndex >= 0;
3063 						cLVDSByteIndex--) {
3064 						cDataByte <<= 1;
3065 						if (7 -
3066 						(g_pLVDSList[usLVDSIndex].
3067 						usNegativeIndex % 8) ==
3068 						cLVDSByteIndex) {
3069 
3070 							/*
3071 							 * Set negative bit to 0
3072 							 */
3073 
3074 							cDataByte |= 0x00;
3075 						} else if (cInDataByte & 0x80) {
3076 							cDataByte |= 0x01;
3077 						}
3078 
3079 						cInDataByte <<= 1;
3080 					}
3081 
3082 					/*
3083 					 * Store the modified byte.
3084 					 */
3085 
3086 					g_pucOutData[g_pLVDSList[usLVDSIndex].
3087 					usNegativeIndex / 8] = cDataByte;
3088 				}
3089 
3090 				break;
3091 			}
3092 		}
3093 	}
3094 
3095 	return 0;
3096 }
3097 
ispVMProcessLVDS(unsigned short a_usLVDSCount)3098 signed char ispVMProcessLVDS(unsigned short a_usLVDSCount)
3099 {
3100 	unsigned short usLVDSIndex = 0;
3101 
3102 	/*
3103 	 * Allocate memory to hold LVDS pairs.
3104 	 */
3105 
3106 	ispVMMemManager(LVDS, a_usLVDSCount);
3107 	g_usLVDSPairCount = a_usLVDSCount;
3108 
3109 #ifdef DEBUG
3110 	printf("LVDS %d (", a_usLVDSCount);
3111 #endif /* DEBUG */
3112 
3113 	/*
3114 	 * Iterate through each given LVDS pair.
3115 	 */
3116 
3117 	for (usLVDSIndex = 0; usLVDSIndex < g_usLVDSPairCount; usLVDSIndex++) {
3118 
3119 		/*
3120 		 * Assign the positive and negative indices of the LVDS pair.
3121 		 */
3122 
3123 		/* 09/11/07 NN Type cast mismatch variables */
3124 		g_pLVDSList[usLVDSIndex].usPositiveIndex =
3125 			(unsigned short) ispVMDataSize();
3126 		/* 09/11/07 NN Type cast mismatch variables */
3127 		g_pLVDSList[usLVDSIndex].usNegativeIndex =
3128 			(unsigned short)ispVMDataSize();
3129 
3130 #ifdef DEBUG
3131 		if (usLVDSIndex < g_usLVDSPairCount - 1) {
3132 			printf("%d:%d, ",
3133 				g_pLVDSList[usLVDSIndex].usPositiveIndex,
3134 				g_pLVDSList[usLVDSIndex].usNegativeIndex);
3135 		} else {
3136 			printf("%d:%d",
3137 				g_pLVDSList[usLVDSIndex].usPositiveIndex,
3138 				g_pLVDSList[usLVDSIndex].usNegativeIndex);
3139 		}
3140 #endif /* DEBUG */
3141 
3142 	}
3143 
3144 #ifdef DEBUG
3145 	printf(");\n");
3146 #endif /* DEBUG */
3147 
3148 	return 0;
3149 }
3150