11 #if (platform != donbfet)
14 # include <iomacros.h>
22 typedef struct Pin Pin;
32 volatile uint8_t * ddr;
33 volatile uint8_t * pin;
34 volatile uint8_t * port;
39 static uint8_t found[CMDDATALEN];
40 static char * tap_shiftir = "1111101100";
41 static uint8_t xdelay = JSCAN_DEFAULT_DELAY;
42 static uint8_t endian = JSCAN_ENDIAN_LITTLE;
43 static char pattern[NPATTERN] = "0110011101001101101000010111001001";
45 static void jscan(uint8_t, uint8_t, uint32_t);
47 static uint8_t setdelay(uint32_t);
48 static uint8_t setpullup(uint32_t);
49 static uint8_t setendian(uint32_t);
51 static uint8_t npins(void);
52 static void listpin(uint8_t);
53 static uint8_t addpin(Pin * );
54 static uint8_t rmpin(uint32_t);
55 static uint8_t newpin(uint32_t);
56 static uint8_t findpin(uint8_t, Pin ** );
58 static void scan(uint8_t);
59 static void loopback(uint8_t);
60 static void getresults(uint8_t);
61 static void clockstrobe(Pin * );
62 static void tdipulse(Pin *, Pin *, uint8_t);
63 static void tapstate(char *, Pin *, Pin * );
64 static void initpins(Pin *, Pin *, Pin *, Pin *, Pin * );
65 static int checkdata(char *, int, Pin *, Pin *, Pin *, int * );
73 "\tThe JScan app adds support for JTAG brute-force scanning.\n"
77 jscan(uint8_t a, uint8_t v, uint32_t l)
81 case JSCAN_CMD_ADDPIN:
82 txdata(a, newpin(l), 1);
85 txdata(a, rmpin(l), 1);
88 txdata(a, setdelay(l), 1);
90 case JSCAN_CMD_PULLUP:
91 txdata(a, setpullup(l), 0);
93 case JSCAN_CMD_LOOPBACK:
96 case JSCAN_CMD_ENDIAN:
97 txdata(a, setendian(l), 1);
102 case JSCAN_CMD_LISTPIN:
105 case JSCAN_CMD_RESULTS:
109 debugstr("Verb unimplemented in JSCAN application.");
140 if(npins() == JSCAN_LIMIT_PINS)
145 if(findpin(cmddata[0], NULL))
150 p = calloc(1, sizeof *p);
154 /* enable pullups by default */
159 p->ddr = (volatile uint8_t * )((uint16_t)cmddata[2] + OFFSETIO);
160 p->pin = (volatile uint8_t * )((uint16_t)cmddata[3] + OFFSETIO);
161 p->port = (volatile uint8_t * )((uint16_t)cmddata[4] + OFFSETIO);
163 /* explicitly set return value */
203 (p->prev)->next = p->next;
205 (p->next)->prev = p->prev;
217 findpin(uint8_t i, Pin ** pp)
251 setpullup(uint32_t l)
258 /* change all or one? */
259 if(cmddata[0] != 0xff)
263 p->pullup = cmddata[1] ? 1 : 0 ;
270 p->pullup = cmddata[1] ? 1 : 0 ;
279 setendian(uint32_t l)
289 case JSCAN_ENDIAN_BIG:
290 endian = JSCAN_ENDIAN_BIG;
292 case JSCAN_ENDIAN_LITTLE:
293 endian = JSCAN_ENDIAN_LITTLE;
330 initpins(NULL, NULL, tdi, NULL, NULL);
332 r = checkdata(pattern, (2*NPATTERN), NULL, tdi, tdo, NULL);
335 if(nb >= (CMDDATALEN-4))
341 /* add the response in couples; TDI first */
342 cmddata[nb++] = tdi->id;
343 cmddata[nb++] = tdo->id;
356 initpins(Pin * tck, Pin * tms, Pin * tdi, Pin * tdo, Pin * nrst)
360 /* XXX test removing syncs */
364 /* set as input by default */
365 *p->ddr &= ~(1 << p->bit);
370 /* set pullup if desired while in input mode */
372 *p->port |= (1 << p->bit);
374 *p->port &= ~(1 << p->bit);
382 *p->ddr |= (1 << p->bit);
384 /* nrst requires output fixed high */
385 *p->port &= ~(1 << p->bit);
386 *p->port |= (1 << p->bit);
388 else if(p == tck || p == tms || p == tdi)
391 *p->ddr |= (1 << p->bit);
396 /* these pins must start low */
397 *p->port &= ~(1 << p->bit);
400 /* tdo should need no special sauce */
410 checkdata(char * pattern, int ntimes, Pin * tck, Pin * tdi, Pin * tdo, int * nreg)
422 np = strlen(pattern);
424 x = (*tdo->pin & (1 << tdo->bit)) >> tdo->bit;
426 tdo_prev = '0' + (x == 1);
428 for(i = 0; i < ntimes; i++)
430 tdipulse(tck, tdi, pattern[w++] - '0');
436 x = (*tdo->pin & (1 << tdo->bit)) >> tdo->bit;
438 tdo_read = '0' + (x == 1);
440 ntoggle += (tdo_read != tdo_prev);
449 memmove(rcv, rcv + 1, np - 1);
450 rcv[np - 1] = tdo_read;
455 if(!memcmp(pattern, rcv, np))
467 return ntoggle > 1 ? ntoggle : 0 ;
471 tdipulse(Pin * tck, Pin * tdi, uint8_t x)
474 *tdi->port |= (1 << tdi->bit);
476 *tdi->port &= ~(1 << tdi->bit);
485 clockstrobe(Pin * tck)
487 *tck->port |= (1 << tck->bit);
490 *tck->port &= ~(1 << tck->bit);
514 /* send back an OK to let the user know we've started */
531 if(tms == nrst || tms == tck)
540 if(tdo == nrst || tdo == tck || tdo == tms)
549 if(tdi == nrst || tdi == tck || tdi == tms || tdi == tdo)
555 initpins(tck, tms, tdi, tdo, nrst);
557 tapstate(tap_shiftir, tck, tms);
559 r = checkdata(pattern, (2*NPATTERN), tck, tdi, tdo, &nreg);
562 /* found potential JTAG */
564 /* can fit around 100 detections; but total should hover around 0.5% of total tests.
565 * so if the number of tests is really high, one could exceed 100 detected JTAGs,
568 if(nfound < (CMDDATALEN-4)-5)
570 /* order is important */
571 found[nfound++] = tck->id;
572 found[nfound++] = tms->id;
573 found[nfound++] = tdi->id;
574 found[nfound++] = tdo->id;
575 found[nfound++] = nrst->id;
597 tapstate(char * s, Pin * tck, Pin * tms)
606 *tms->port |= (1 << tms->bit);
608 *tms->port &= ~(1 << tms->bit);
611 *tck->port &= ~(1 << tck->bit);
613 *tck->port |= (1 << tck->bit);
629 cmddata[nb++] = p->id;
630 cmddata[nb++] = p->bit;
631 cmddata[nb++] = ((uint16_t)(p->ddr)) & 0xff;
632 cmddata[nb++] = ((uint16_t)(p->pin)) & 0xff;
633 cmddata[nb++] = ((uint16_t)(p->port)) & 0xff;
641 getresults(uint8_t a)
643 memcpy(cmddata, found, nfound);
644 txdata(a, OK, nfound);