1 /*
2  * XCFxxP Flash PROM JTAG programming algorithms
3  *
4  * Copyright (C) 2010 Joris van Rantwijk
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * Programming sequences are based on the Xilinx 1532 BSDL files.
12  *
13  * Note: Some XCFP features are not supported (such as multiple revisions).
14  *       The special PROM registers are written to always select revision 00.
15  *       The default is slave serial mode (FPGA in master serial mode).
16  *       A few other configuration modes may be selected by calling
17  *       setXxxMode() before programming.
18  */
19 
20 #include <stdio.h>
21 #include <string.h>
22 #include <stdexcept>
23 #include "jtag.h"
24 #include "progalgxcfp.h"
25 #include "utilities.h"
26 
27 
28 /* Device identification */
29 #define IDCODE_IS_XCF08P(id)    (((id) & 0x0FFFFFFF) == 0x05057093)
30 #define IDCODE_IS_XCF16P(id)    (((id) & 0x0FFFFFFF) == 0x05058093)
31 #define IDCODE_IS_XCF32P(id)    (((id) & 0x0FFFFFFF) == 0x05059093)
32 
33 
34 /* Note: XCFxxP devices have instruction_length == 16 */
35 static const byte BYPASS[2]             = { 0xff, 0xff };
36 static const byte IDCODE[2]             = { 0xfe, 0x00 };
37 static const byte ISC_ENABLE[2]         = { 0xe8, 0x00 };
38 static const byte ISC_DISABLE[2]        = { 0xf0, 0x00 };
39 static const byte ISC_PROGRAM[2]        = { 0xea, 0x00 };
40 static const byte ISC_READ[2]           = { 0xf8, 0x00 };
41 static const byte ISC_ERASE[2]          = { 0xec, 0x00 };
42 static const byte ISC_ADDRESS_SHIFT[2]  = { 0xeb, 0x00 };
43 static const byte ISC_DATA_SHIFT[2]     = { 0xed, 0x00 };
44 static const byte XSC_CONFIG[2]         = { 0xee, 0x00 };
45 static const byte XSC_OP_STATUS[2]      = { 0xe3, 0x00 };
46 static const byte XSC_UNLOCK[2]         = { 0x55, 0xaa };
47 static const byte XSC_DATA_BTC[2]       = { 0xf2, 0x00 };
48 static const byte XSC_DATA_CCB[2]       = { 0x0c, 0x00 };
49 static const byte XSC_DATA_SUCR[2]      = { 0x0e, 0x00 };
50 static const byte XSC_DATA_DONE[2]      = { 0x09, 0x00 };
51 
52 
ProgAlgXCFP(Jtag & j,unsigned long id)53 ProgAlgXCFP::ProgAlgXCFP(Jtag &j, unsigned long id)
54 {
55   jtag = &j;
56   idcode = id;
57 
58   // size of one array in bytes
59   block_size = 0x100000;
60 
61   if (IDCODE_IS_XCF08P(idcode))
62     narray = 1;
63   else if (IDCODE_IS_XCF16P(idcode))
64     narray = 2;
65   else if (IDCODE_IS_XCF32P(idcode))
66     narray = 4;
67   else
68     {
69       fprintf(stderr, "Unknown XCF device ID 0x%08lx\n", idcode);
70       throw std::invalid_argument("Unknown XCF device");
71     }
72 
73   // default to slave serial mode (FPGA running in master serial mode)
74   ccbParallelMode  = false;
75   ccbMasterMode    = false;
76   ccbFastClock     = true;
77   ccbExternalClock = true;
78 
79   fprintf(stderr, "ProgAlgXCFP $Rev: 760 $\n");
80 }
81 
82 
getSize() const83 unsigned int ProgAlgXCFP::getSize() const
84 {
85     // return storage capacity in bits
86     return narray * block_size * 8;
87 }
88 
erase()89 int ProgAlgXCFP::erase()
90 {
91     return erase((1<<narray) -1);
92 }
93 
erase(int array_mask)94 int ProgAlgXCFP::erase(int array_mask)
95 {
96   Timer timer;
97   byte data[3];
98   byte xcstatus[1];
99   int ret = 0;
100 
101   jtag->tapTestLogicReset();
102   jtag->Usleep(1000);
103 
104   ret = verify_idcode();
105   if (ret)
106     return ret;
107 
108   enable();
109 
110   data[0] = 0x30 | array_mask;
111   data[1] = 0x00;
112   data[2] = 0x00;
113 
114   jtag->shiftIR(XSC_UNLOCK);
115   jtag->shiftDR(data, 0, 24);
116   jtag->cycleTCK(1);
117 
118   if(jtag->getVerbose())
119     {
120       fprintf(stderr, "Erasing");
121       fflush(stderr);
122     }
123 
124   // The ERASE command fails when state goes through READY-TEST-IDLE between
125   // instruction and data.
126   jtag->setPostIRState(Jtag::EXIT1_IR);
127 
128   jtag->shiftIR(ISC_ERASE);
129   jtag->shiftDR(data, 0, 24);
130   jtag->Usleep(10000);
131 
132   // restore default
133   jtag->setPostIRState(Jtag::RUN_TEST_IDLE);
134 
135   for (int i = 0; i < 280; i++)
136     {
137       // we use 280 loops of 500 ms instead of 14000 loops of 10 ms
138       jtag->Usleep(490000);
139       if (jtag->getVerbose())
140         {
141           fprintf(stderr, ".");
142           fflush(stderr);
143         }
144       jtag->shiftIR(XSC_OP_STATUS);
145       jtag->Usleep(10000);
146       jtag->shiftDR(0, xcstatus, 8);
147       if (xcstatus[0] & 0x04)
148         break;
149     }
150 
151   if (xcstatus[0] == 0x36)
152     {
153       if (jtag->getVerbose())
154         fprintf(stderr, "done!");
155     }
156   else
157     {
158       ret = 1;
159       fprintf(stderr, "\nErase failed (status=0x%02x)! Aborting\n", xcstatus[0]);
160     }
161 
162   disable();
163 
164   if (jtag->getVerbose())
165     fprintf(stderr, "Erase time %.3f s\n", timer.elapsed());
166 
167   return ret;
168 }
169 
170 
program(BitFile & file)171 int ProgAlgXCFP::program(BitFile &file)
172 {
173   Timer timer;
174   byte data[32];
175   byte xcstatus[1];
176   int ret = 0;
177 
178   if (file.getOffset() != 0 ||
179       (file.getRLength() != 0 && file.getRLength() != file.getLengthBytes()))
180     throw std::invalid_argument("XCFP does not yet support bitfile subranges");
181 
182   jtag->tapTestLogicReset();
183   jtag->Usleep(1000);
184 
185   ret = verify_idcode();
186   if (ret)
187     return ret;
188 
189   enable();
190 
191   unsigned int used_blocks = (file.getLengthBytes() + block_size - 1) / block_size;
192   if (used_blocks == 0)
193     used_blocks = 1;
194   if (used_blocks > narray)
195     {
196       fprintf(stderr, "Program does not fit in PROM, clipping\n");
197       used_blocks = narray;
198     }
199 
200   for (unsigned int k = 0; k < used_blocks; k++)
201     {
202       for (unsigned int i = 0; i < 32768; i++)
203         {
204           unsigned int p = k * block_size + i * 32;
205 
206           // no need to program after end of bitfile
207           if (p >= file.getLengthBytes())
208             break;
209 
210           if (jtag->getVerbose())
211             {
212               fprintf(stderr, "\rProgramming frames 0x%06x to 0x%06x     ",
213                       p, p+31);
214               fflush(stderr);
215             }
216 
217           jtag->shiftIR(ISC_DATA_SHIFT);
218           if (p + 32 <= file.getLengthBytes())
219             {
220               jtag->shiftDR(file.getData() + p, 0, 256);
221             }
222           else
223             {
224               memset(data, 0xff, 32);
225               if (p < file.getLengthBytes())
226                 memcpy(data, file.getData() + p, file.getLengthBytes() - p);
227               jtag->shiftDR(data, 0, 256);
228             }
229           jtag->cycleTCK(1);
230 
231           if (i == 0)
232             {
233               jtag->longToByteArray(p, data);
234               jtag->shiftIR(ISC_ADDRESS_SHIFT);
235               jtag->shiftDR(data, 0, 24);
236               jtag->cycleTCK(1);
237             }
238 
239           jtag->shiftIR(ISC_PROGRAM);
240           jtag->Usleep((i == 0) ? 1000 : 25);
241 
242           for (int t = 0; t < 100; t++)
243             {
244               jtag->shiftIR(XSC_OP_STATUS);
245               jtag->shiftDR(0, xcstatus, 8);
246               if (xcstatus[0] & 0x04)
247                 break;
248             }
249           if (xcstatus[0] != 0x36)
250             {
251               ret = 1;
252               fprintf(stderr,"\nProgramming failed! Aborting\n");
253               break;
254             }
255         }
256     }
257 
258   if (ret == 0)
259     {
260       unsigned long btc_data = 0xffffffe0 | ((used_blocks-1) << 2);
261 
262       if (jtag->getVerbose())
263         fprintf(stderr, "\nProgramming BTC=0x%08lx\n", btc_data);
264 
265       jtag->longToByteArray(btc_data, data);
266       jtag->shiftIR(XSC_DATA_BTC);
267       jtag->shiftDR(data, 0, 32);
268       jtag->cycleTCK(1);
269       jtag->shiftIR(ISC_PROGRAM);
270       jtag->Usleep(1000);
271 
272       jtag->shiftIR(XSC_DATA_BTC);
273       jtag->cycleTCK(1);
274       jtag->shiftDR(0, data, 32);
275       if (jtag->byteArrayToLong(data) != btc_data)
276         {
277           fprintf(stderr,"Programming BTC failed! Aborting\n");
278           ret = 1;
279         }
280     }
281 
282   if (ret == 0)
283     {
284       uint16_t ccb_data = encodeCCB();
285 
286       if (jtag->getVerbose())
287         fprintf(stderr, "Programming CCB=0x%04x\n", ccb_data);
288 
289       jtag->shortToByteArray(ccb_data, data);
290       jtag->shiftIR(XSC_DATA_CCB);
291       jtag->shiftDR(data, 0, 16);
292       jtag->cycleTCK(1);
293       jtag->shiftIR(ISC_PROGRAM);
294       jtag->Usleep(1000);
295 
296       jtag->shiftIR(XSC_DATA_CCB);
297       jtag->cycleTCK(1);
298       jtag->shiftDR(0, data, 16);
299       if (jtag->byteArrayToShort(data) != ccb_data)
300         {
301           fprintf(stderr,"Programming CCB failed! Aborting\n");
302           ret = 1;
303         }
304     }
305 
306   if (ret == 0)
307     {
308       uint16_t sucr_data = 0xfffc;
309 
310       if (jtag->getVerbose())
311         fprintf(stderr, "Programming SUCR=0x%04x\n", sucr_data);
312 
313       jtag->shortToByteArray(sucr_data, data);
314       jtag->shiftIR(XSC_DATA_SUCR);
315       jtag->shiftDR(data, 0, 16);
316       jtag->cycleTCK(1);
317       jtag->shiftIR(ISC_PROGRAM);
318       jtag->Usleep(1000);
319 
320       jtag->shiftIR(XSC_DATA_SUCR);
321       jtag->cycleTCK(1);
322       jtag->shiftDR(0, data, 16);
323       if (jtag->byteArrayToShort(data) != sucr_data)
324         {
325           fprintf(stderr,"Programming SUCR failed! Aborting\n");
326           ret = 1;
327         }
328     }
329 
330   if (ret == 0)
331     {
332       byte done_data = 0xc0 | (0x0f & (0x0f << narray));
333 
334       if (jtag->getVerbose())
335         fprintf(stderr, "Programming DONE=0x%02x\n", done_data);
336 
337       data[0] = done_data;
338       jtag->shiftIR(XSC_DATA_DONE);
339       jtag->shiftDR(data, 0, 8);
340       jtag->cycleTCK(1);
341       jtag->shiftIR(ISC_PROGRAM);
342       jtag->Usleep(1000);
343 
344       jtag->shiftIR(XSC_DATA_DONE);
345       jtag->cycleTCK(1);
346       jtag->shiftDR(0, data, 8);
347       if (data[0] != done_data)
348         {
349           fprintf(stderr,"Programming DONE failed! Aborting\n");
350           ret = 1;
351         }
352       else
353         {
354           if (jtag->getVerbose())
355             fprintf(stderr, "finished\n");
356         }
357     }
358 
359   disable();
360 
361   if (jtag->getVerbose())
362     fprintf(stderr, "Programming time %.3f s\n", timer.elapsed());
363 
364   return ret;
365 }
366 
367 
verify(BitFile & file)368 int ProgAlgXCFP::verify(BitFile &file)
369 {
370   Timer timer;
371   byte data[32];
372   int ret = 0;
373 
374   if (file.getOffset() != 0 ||
375       (file.getRLength() != 0 && file.getRLength() != file.getLengthBytes()))
376     throw std::invalid_argument("XCFP does not yet support bitfile subranges");
377 
378   jtag->tapTestLogicReset();
379   jtag->Usleep(1000);
380 
381   ret = verify_idcode();
382   if (ret)
383     return ret;
384 
385   enable();
386 
387   unsigned int used_blocks = (file.getLengthBytes() + block_size - 1) / block_size;
388   if (used_blocks == 0)
389     used_blocks = 1;
390   if (used_blocks > narray)
391     {
392       fprintf(stderr, "Program does not fit in PROM, clipping\n");
393       used_blocks = narray;
394     }
395 
396   for (unsigned int k = 0; k < used_blocks; k++)
397     {
398       jtag->longToByteArray(k * block_size, data);
399       jtag->shiftIR(ISC_ADDRESS_SHIFT);
400       jtag->shiftDR(data, 0, 24);
401       jtag->cycleTCK(1);
402 
403       for (unsigned int i = 0; i < 32768; i++)
404         {
405           unsigned int p = k * block_size + i * 32;
406           unsigned int n = 32;
407           if (p >= file.getLengthBytes())
408             break;
409           if (p + n > file.getLengthBytes())
410             n = file.getLengthBytes() - p;
411 
412           if (jtag->getVerbose()) {
413             fprintf(stderr, "\rVerifying frames 0x%06x to 0x%06x     ",
414                     p, p+n-1);
415             fflush(stderr);
416           }
417           jtag->shiftIR(ISC_READ);
418           jtag->Usleep(25);
419 
420           jtag->shiftIR(ISC_DATA_SHIFT);
421           jtag->cycleTCK(1);
422           jtag->shiftDR(0, data, 256);
423 
424           if (memcmp(data, file.getData() + p, n))
425             {
426               ret = 1;
427 	      fprintf(stderr, "\nVerify failed at frame 0x%06x to 0x%06x\n",
428 		      p, p+n-1);
429               break;
430             }
431         }
432 
433       if (ret)
434         break;
435     }
436 
437   if (jtag->getVerbose())
438     fprintf(stderr, "\nVerifying BTC  ");
439   unsigned long btc_data = 0xffffffe0 | ((used_blocks-1) << 2);
440   jtag->shiftIR(XSC_DATA_BTC);
441   jtag->cycleTCK(1);
442   jtag->shiftDR(0, data, 32);
443   if (jtag->getVerbose())
444     fprintf(stderr, "= 0x%08lx\n", jtag->byteArrayToLong(data));
445   if (jtag->byteArrayToLong(data) != btc_data)
446     {
447       fprintf(stderr, "Unexpected value in BTC register\n");
448       ret = 1;
449     }
450 
451   if (jtag->getVerbose())
452     fprintf(stderr, "Verifying CCB  ");
453   jtag->shiftIR(XSC_DATA_CCB);
454   jtag->cycleTCK(1);
455   jtag->shiftDR(0, data, 16);
456   if (jtag->getVerbose())
457     fprintf(stderr, "= 0x%04x\n", jtag->byteArrayToShort(data));
458   if (jtag->byteArrayToShort(data) != encodeCCB())
459     {
460       fprintf(stderr, "Unexpected value in CCB register\n");
461       ret = 1;
462     }
463 
464   if (jtag->getVerbose())
465     fprintf(stderr, "Verifying SUCR ");
466   jtag->shiftIR(XSC_DATA_SUCR);
467   jtag->cycleTCK(1);
468   jtag->shiftDR(0, data, 16);
469   if (jtag->getVerbose())
470     fprintf(stderr, "= 0x%02x%02x\n", data[1], data[0]);
471   if (data[0] != 0xfc || data[1] != 0xff)
472     {
473       fprintf(stderr, "Unexpected value in SUCR register\n");
474       ret = 1;
475     }
476 
477   if (jtag->getVerbose())
478     fprintf(stderr, "Verifying DONE ");
479   byte done_data = 0xc0 | (0x0f & (0x0f << narray));
480   jtag->shiftIR(XSC_DATA_DONE);
481   jtag->cycleTCK(1);
482   jtag->shiftDR(0, data, 8);
483   if (jtag->getVerbose())
484     fprintf(stderr, "= 0x%02x\n", data[0]);
485   if (data[0] != done_data)
486     {
487       fprintf(stderr, "Unexpected value in DONE register\n");
488       ret = 1;
489     }
490 
491   disable();
492 
493   if (jtag->getVerbose() && ret == 0)
494     fprintf(stderr, "Success!\n");
495 
496   if (jtag->getVerbose())
497     fprintf(stderr, "Verify time %.3f s\n", timer.elapsed());
498 
499   return ret;
500 }
501 
502 
read(BitFile & file)503 int ProgAlgXCFP::read(BitFile &file)
504 {
505   Timer timer;
506   byte data[32];
507   int ret = 0;
508 
509   if (file.getOffset() != 0 ||
510       (file.getRLength() != 0 && file.getRLength() != getSize() / 8))
511     throw std::invalid_argument("XCFP does not yet support bitfile subranges");
512 
513   timer.start();
514 
515   jtag->tapTestLogicReset();
516   jtag->Usleep(1000);
517 
518   ret = verify_idcode();
519   if (ret)
520     return ret;
521 
522   enable();
523 
524   jtag->shiftIR(XSC_DATA_BTC);
525   jtag->cycleTCK(1);
526   jtag->shiftDR(0, data, 32);
527   unsigned long btc_data = jtag->byteArrayToLong(data);
528   if (jtag->getVerbose())
529     fprintf(stderr, "BTC  = 0x%08lx\n", btc_data);
530 
531   unsigned int first_block = btc_data & 0x03;
532   unsigned int last_block  = (btc_data & 0x0c) >> 2;
533 
534   if (jtag->getVerbose())
535     fprintf(stderr, "BTC: first_block=%u, last_block=%u, content_len=%u bytes\n", first_block, last_block, (last_block + 1 - first_block) * block_size);
536 
537   if (first_block > last_block || last_block >= narray)
538     {
539       fprintf(stderr, "Invalid data in BTC register: first_block=%u, last_block=%u\n", first_block, last_block);
540       fprintf(stderr, "Reading failed.\n");
541       return 1;
542     }
543 
544   file.setLength((last_block - first_block + 1) * 32768 * 256);
545 
546   for (unsigned int k = first_block; k <= last_block; k++)
547     {
548       jtag->longToByteArray(k * block_size, data);
549       jtag->shiftIR(ISC_ADDRESS_SHIFT);
550       jtag->shiftDR(data, 0, 24);
551       jtag->cycleTCK(1);
552 
553       for (unsigned int i = 0; i < 32768; i++)
554         {
555           if (jtag->getVerbose())
556           {
557               fprintf(stderr, "\rReading frames 0x%06x to 0x%06x     ",
558                       k*block_size+i*32,k*block_size+i*32+31);
559               fflush(stderr);
560           }
561           jtag->shiftIR(ISC_READ);
562           jtag->Usleep(25);
563 
564           unsigned int p = (k - first_block) * block_size + i * 32;
565           jtag->shiftIR(ISC_DATA_SHIFT);
566           jtag->cycleTCK(1);
567           jtag->shiftDR(0, file.getData() + p, 256);
568         }
569     }
570 
571   if (jtag->getVerbose())
572     fprintf(stderr, "done\n");
573 
574   jtag->shiftIR(XSC_DATA_CCB);
575   jtag->cycleTCK(1);
576   jtag->shiftDR(0, data, 16);
577   if (jtag->getVerbose())
578     fprintf(stderr, "CCB  = 0x%04x\n", jtag->byteArrayToShort(data));
579 
580   decodeCCB(jtag->byteArrayToShort(data));
581   if (jtag->getVerbose())
582     fprintf(stderr, "CCB: %s, %s, %s, %s\n",
583             ccbMasterMode ? "master" : "slave",
584             ccbParallelMode ? "parallel" : "serial",
585             ccbExternalClock ? "extclk" : "intclk",
586             ccbFastClock ? "fastclk" : "slowclk" );
587 
588   jtag->shiftIR(XSC_DATA_DONE);
589   jtag->cycleTCK(1);
590   jtag->shiftDR(0, data, 8);
591   if (jtag->getVerbose())
592     fprintf(stderr, "DONE = 0x%02x\n", data[0]);
593 
594   jtag->shiftIR(XSC_DATA_SUCR);
595   jtag->cycleTCK(1);
596   jtag->shiftDR(0, data, 16);
597   if (jtag->getVerbose())
598     fprintf(stderr, "SUCR = 0x%02x%02x\n", data[1], data[0]);
599 
600   disable();
601 
602   if (jtag->getVerbose())
603     fprintf(stderr, "Read time %.3f s\n", timer.elapsed());
604 
605   return ret;
606 }
607 
608 
reconfig(void)609 void ProgAlgXCFP::reconfig(void)
610 {
611   jtag->shiftIR(XSC_CONFIG);
612   jtag->cycleTCK(1);
613   jtag->shiftIR(BYPASS);
614   jtag->cycleTCK(1);
615   jtag->tapTestLogicReset();
616 }
617 
618 
verify_idcode()619 int ProgAlgXCFP::verify_idcode()
620 {
621   byte data[4];
622   jtag->shiftIR(IDCODE);
623   jtag->cycleTCK(1);
624   jtag->shiftDR(0, data, 32);
625   unsigned long devid = jtag->byteArrayToLong(data);
626   if ((devid & 0x0fffffff) != (idcode & 0x0fffffff))
627     {
628       fprintf(stderr, "Failed to verify ID code, got 0x%08lx expected 0x%08lx\n", devid, idcode);
629       return 1;
630     }
631   return 0;
632 }
633 
634 
enable()635 void ProgAlgXCFP::enable()
636 {
637   byte data[1] = { 0x00 };
638   jtag->shiftIR(ISC_ENABLE);
639   jtag->shiftDR(data, 0, 8);
640   jtag->cycleTCK(1);
641 }
642 
643 
disable()644 void ProgAlgXCFP::disable()
645 {
646   jtag->shiftIR(ISC_DISABLE);
647   jtag->Usleep(1000);
648   jtag->shiftIR(BYPASS);
649   jtag->cycleTCK(1);
650   jtag->tapTestLogicReset();
651 }
652 
653 
encodeCCB() const654 uint16_t ProgAlgXCFP::encodeCCB() const
655 {
656   // The CCB register in the XCFnnP PROM deteremines the FPGA configuration
657   // mode, i.e. parallel or serial, master or slave, config clock, etc.
658   // See xcf32p_1532.bsd.
659   uint16_t ccb = 0xffc0;
660   ccb |= ccbParallelMode  ? 0x00 : 0x06;
661   ccb |= ccbMasterMode    ? 0x00 : 0x08;
662   ccb |= ccbFastClock     ? 0x30 : 0x10;
663   ccb |= ccbExternalClock ? 0x01 : 0x00;
664   return ccb;
665 }
666 
667 
decodeCCB(uint16_t ccb)668 void ProgAlgXCFP::decodeCCB(uint16_t ccb)
669 {
670   ccbParallelMode  = ((ccb & 0x06) == 0x00);
671   ccbMasterMode    = ((ccb & 0x08) == 0x00);
672   ccbFastClock     = ((ccb & 0x20) == 0x20);
673   ccbExternalClock = ((ccb & 0x01) == 0x01);
674 }
675 
676