jtagonizer

yet another JTAG tool
git clone http://frotz.net/git/jtagonizer.git
Log | Files | Refs | README

jtag-core.c (11904B)


      1 // Copyright 2014 Brian Swetland <swetland@frotz.net>
      2 //
      3 // Licensed under the Apache License, Version 2.0 (the "License");
      4 // you may not use this file except in compliance with the License.
      5 // You may obtain a copy of the License at
      6 //
      7 // http://www.apache.org/licenses/LICENSE-2.0
      8 //
      9 // Unless required by applicable law or agreed to in writing, software
     10 // distributed under the License is distributed on an "AS IS" BASIS,
     11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     12 // See the License for the specific language governing permissions and
     13 // limitations under the License.
     14 
     15 #include <stdlib.h>
     16 #include <stdio.h>
     17 #include <string.h>
     18 
     19 #include "jtag-driver.h"
     20 
     21 
     22 #define ZYNQID(code)	((0x1B<<21)|(0x9<<17)|((code)<<12)|(0x49<<1)|1)
     23 #define ZYNQMASK	0x0FFFFFFF
     24 
     25 static JTAG_INFO LIBRARY[] = {
     26 	{ 0x4ba00477, 0xFFFFFFFF, 4, "Cortex A9", "ARM A9" },
     27 // Zynq 7000
     28 	{ ZYNQID(0x02), ZYNQMASK, 6, "XC7X010", "Xilinx 7" },
     29 	{ ZYNQID(0x1b), ZYNQMASK, 6, "XC7X015", "Xilinx 7" },
     30 	{ ZYNQID(0x07), ZYNQMASK, 6, "XC7X020", "Xilinx 7" },
     31 	{ ZYNQID(0x0c), ZYNQMASK, 6, "XC7X030", "Xilinx 7" },
     32 	{ ZYNQID(0x11), ZYNQMASK, 6, "XC7X045", "Xilinx 7" },
     33 // Artix-7
     34 	{ 0x0362D093, 0x0FFFFFFF, 6, "XC7A35T", "Xilinx 7" },
     35 	{ 0x0362C093, 0x0FFFFFFF, 6, "XC7A50T", "Xilinx 7" },
     36 	{ 0x03632093, 0x0FFFFFFF, 6, "XC7A75T", "Xilinx 7" },
     37 	{ 0x03631093, 0x0FFFFFFF, 6, "XC7A100T", "Xilinx 7" },
     38 	{ 0x03636093, 0x0FFFFFFF, 6, "XC7A200T", "Xilinx 7" },
     39 // Kintex-7
     40 	{ 0x03647093, 0x0FFFFFFF, 6, "XC7K70T", "Xilinx 7" },
     41 	{ 0x0364C093, 0x0FFFFFFF, 6, "XC7K160T", "Xilinx 7" },
     42 	{ 0x03651093, 0x0FFFFFFF, 6, "XC7K325T", "Xilinx 7" },
     43 	{ 0x03747093, 0x0FFFFFFF, 6, "XC7K355T", "Xilinx 7" },
     44 	{ 0x03656093, 0x0FFFFFFF, 6, "XC7K410T", "Xilinx 7" },
     45 	{ 0x03752093, 0x0FFFFFFF, 6, "XC7K420T", "Xilinx 7" },
     46 	{ 0x03751093, 0x0FFFFFFF, 6, "XC7K480T", "Xilinx 7" },
     47 // Virtex-7 (only parts with 6bit IR)
     48 	{ 0x03671093, 0x0FFFFFFF, 6, "XC7VT585", "Xilinx 7" },
     49 	{ 0x03667093, 0x0FFFFFFF, 6, "XC7VX330T", "Xilinx 7" },
     50 	{ 0x03682093, 0x0FFFFFFF, 6, "XC7VX415T", "Xilinx 7" },
     51 	{ 0x03687093, 0x0FFFFFFF, 6, "XC7VX485T", "Xilinx 7" },
     52 	{ 0x03692093, 0x0FFFFFFF, 6, "XC7VX550T", "Xilinx 7" },
     53 	{ 0x03691093, 0x0FFFFFFF, 6, "XC7VX690T", "Xilinx 7" },
     54 	{ 0x03696093, 0x0FFFFFFF, 6, "XC7VX980T", "Xilinx 7" },
     55 };
     56 
     57 JTAG_INFO *jtag_lookup_device(unsigned idcode) {
     58 	int n;
     59 	for (n = 0; n < (sizeof(LIBRARY)/sizeof(LIBRARY[0])); n++) {
     60 		if ((idcode & LIBRARY[n].idmask) == LIBRARY[n].idcode) {
     61 			return LIBRARY + n;
     62 		}
     63 	}
     64 	return NULL;
     65 }
     66 
     67 #define TRACE_STATEMACHINE 0
     68 
     69 // configuration and state or IR or DR
     70 typedef struct JREG {
     71 	u8 *prebits;
     72 	u8 *postbits;
     73 	u32 precount;
     74 	u32 postcount;
     75 	u32 scanstate;
     76 	u32 idlestate;
     77 } JREG;
     78 
     79 #define DEVMAX 32
     80 
     81 // configuration and state of JTAG
     82 struct JTAG {
     83 	JDRV *drv;
     84 	JDVT *vt;
     85 
     86 	JREG ir;
     87 	JREG dr;
     88 
     89 	u32 state;
     90 
     91 	int devcount;
     92 	JTAG_INFO devinfo[DEVMAX];
     93 };
     94 
     95 #define _setspeed(khz) \
     96 	jtag->vt->setspeed(jtag->drv, khz)
     97 #define _commit() \
     98 	jtag->vt->commit(jtag->drv)
     99 #define _scan_tms(obit, count, tbits, ioffset, ibits) \
    100 	jtag->vt->scan_tms(jtag->drv, obit, count, tbits, ioffset, ibits)
    101 #define _scan_io(count, obits, ibits) \
    102 	jtag->vt->scan_io(jtag->drv, count, obits, ibits)
    103 #define _close() \
    104 	jtag->vt->close(jtag->drv)
    105 
    106 static u8 ONES[1024];
    107 
    108 void jtag_clear_state(JTAG *jtag) {
    109 	jtag->ir.idlestate = JTAG_IDLE;
    110 	jtag->ir.scanstate = JTAG_IRSHIFT;
    111 	jtag->dr.idlestate = JTAG_IDLE;
    112 	jtag->dr.scanstate = JTAG_DRSHIFT;
    113 	jtag->ir.prebits = 0;
    114 	jtag->ir.precount = 0;
    115 	jtag->ir.postbits = 0;
    116 	jtag->ir.postcount = 0;
    117 	jtag->dr.prebits = 0;
    118 	jtag->dr.precount = 0;
    119 	jtag->dr.postbits = 0;
    120 	jtag->dr.postcount = 0;
    121 }
    122 
    123 int jtag_init(JTAG **_jtag, JDRV *drv, JDVT *vt) {
    124 	JTAG *jtag;
    125 	if ((jtag = malloc(sizeof(JTAG))) == 0) {
    126 		return -1;
    127 	}
    128 	memset(jtag, 0, sizeof(JTAG));
    129 	jtag->drv = drv;
    130 	jtag->vt = vt;
    131 	jtag_clear_state(jtag);
    132 	*_jtag = jtag;
    133 	memset(ONES, 0xFF, sizeof(ONES));
    134 	return 0;
    135 }
    136 
    137 void jtag_close(JTAG *jtag) {
    138 	_close();
    139 	free(jtag);
    140 }
    141 
    142 int jtag_setspeed(JTAG *jtag, int khz) {
    143 	return _setspeed(khz);
    144 }
    145 
    146 void jtag_set_ir_idle(JTAG *jtag, unsigned state) {
    147 	jtag->ir.idlestate = state;
    148 }
    149 
    150 void jtag_set_dr_idle(JTAG *jtag, unsigned state) {
    151 	jtag->dr.idlestate = state;
    152 }
    153 
    154 void jtag_set_ir_prefix(JTAG *jtag, unsigned count, const void *bits) {
    155 	jtag->ir.prebits = count ? (u8*) bits : 0;
    156 	jtag->ir.precount = count;
    157 }
    158 void jtag_set_ir_postfix(JTAG *jtag, unsigned count, const void *bits) {
    159 	jtag->ir.postbits = count ? (u8*) bits : 0;
    160 	jtag->ir.postcount = count;
    161 }
    162 void jtag_set_dr_prefix(JTAG *jtag, unsigned count, const void *bits) {
    163 	jtag->dr.prebits = count ? (u8*) bits : 0;
    164 	jtag->dr.precount = count;
    165 }
    166 void jtag_set_dr_postfix(JTAG *jtag, unsigned count, const void *bits) {
    167 	jtag->dr.postbits = count ? (u8*) bits : 0;
    168 	jtag->dr.postcount = count;
    169 }
    170 
    171 static u32 lastbit(const u8 *bits, u32 count) {
    172 	count -= 1;
    173 	return (bits[count >> 3] >> (count & 7)) & 1;
    174 }
    175 
    176 static const char *JSTATE[16] = {
    177 	"RESET", "IDLE", "DRSELECT", "DRCAPTURE",
    178 	"DRSHIFT", "DREXIT1", "DRPAUSE", "DREXIT2",
    179 	"DRUPDATE", "IRSELECT", "IRCAPTURE", "IRSHIFT",
    180 	"IREXIT1", "IRPAUSE", "IREXIT1", "IRUPDATE"
    181 };
    182 
    183 #define JPATH(x,c) { static u8 out = x; *bits = &out; return c; }
    184 
    185 static u32 jtag_plot(u32 from, u32 to, u8 **bits) {
    186 #if TRACE_STATEMACHINE
    187 	fprintf(stderr,"jtag_plot: move from %s to %s\n",
    188 			JSTATE[from], JSTATE[to]);
    189 #endif
    190 	switch (from) {
    191 	case JTAG_RESET:
    192 		if (to == JTAG_IDLE) JPATH(0x00, 1); // 0
    193 		if (to == JTAG_IRSHIFT) JPATH(0x06, 5); // 01100
    194 		if (to == JTAG_DRSHIFT) JPATH(0x02, 4); // 0100
    195 		break;
    196 	case JTAG_IDLE:
    197 		if (to == JTAG_IRSHIFT) JPATH(0x03, 4); // 1100
    198 		if (to == JTAG_DRSHIFT) JPATH(0x01, 3); // 100
    199 		break;
    200 	case JTAG_IRSHIFT:
    201 		if (to == JTAG_IDLE) JPATH(0x03, 3); // 110
    202 		if (to == JTAG_IRPAUSE) JPATH(0x01, 2); // 10
    203 		break;
    204 	case JTAG_DRSHIFT:
    205 		if (to == JTAG_IDLE) JPATH(0x03, 3); // 110
    206 		if (to == JTAG_DRPAUSE) JPATH(0x01, 2); // 10
    207 		break;
    208 	case JTAG_IRPAUSE:
    209 		if (to == JTAG_IDLE) JPATH(0x03, 3); // 110
    210 		if (to == JTAG_IRSHIFT) JPATH(0x01, 2); // 10
    211 		if (to == JTAG_DRSHIFT) JPATH(0x07, 5); // 11100
    212 		break;
    213 	case JTAG_DRPAUSE:
    214 		if (to == JTAG_IDLE) JPATH(0x03, 3); // 110
    215 		if (to == JTAG_DRSHIFT) JPATH(0x01, 2); // 10
    216 		if (to == JTAG_IRSHIFT) JPATH(0x0F, 6); // 111100
    217 		break;
    218 	}
    219 	if (to == JTAG_RESET) JPATH(0x3F, 6); // 111111
    220 
    221 	if (from == to) return 0;
    222 
    223 	fprintf(stderr,"jtag_plot: cannot move from %s to %s\n",
    224 			JSTATE[from], JSTATE[to]);
    225 	return 0;
    226 };
    227 
    228 void jtag_goto(JTAG *jtag, unsigned state) {
    229 	u32 mcount;
    230 	u8 *mbits;
    231 	mcount = jtag_plot(jtag->state, state, &mbits);
    232 	if (mcount != 0) {
    233 		_scan_tms(0, mcount, mbits, 0, 0);
    234 		jtag->state = state;
    235 	}
    236 }
    237 
    238 void jtag_idle(JTAG *jtag, unsigned count) {
    239 	unsigned zero = 0;
    240 	jtag_goto(jtag, JTAG_IDLE);
    241 	while (count > 0) {
    242 		if (count > 6) {
    243 			_scan_tms(0, 6, (void*) &zero, 0, 0);
    244 			count -= 6;
    245 		} else {
    246 			_scan_tms(0, count, (void*) &zero, 0, 0);
    247 			count = 0;
    248 		}
    249 	}
    250 }
    251 
    252 static void jtag_xr_wr(JTAG *jtag, JREG *xr, u32 count, u8 *wbits) {
    253 	u32 mcount;
    254 	u8 *mbits;
    255 	jtag_goto(jtag, xr->scanstate);
    256 	mcount = jtag_plot(xr->scanstate, xr->idlestate, &mbits);
    257 	if (xr->prebits) {
    258 		_scan_io(xr->precount, xr->prebits, 0);
    259 	}
    260 	if (xr->postbits) {
    261 		_scan_io(count, wbits, 0);
    262 		_scan_io(xr->postcount - 1, xr->postbits, 0);
    263 		_scan_tms(lastbit(xr->postbits, xr->postcount), mcount, mbits, 0, 0);
    264 	} else {
    265 		_scan_io(count - 1, wbits, 0);
    266 		_scan_tms(lastbit(wbits, count), mcount, mbits, 0, 0);
    267 	}
    268 	jtag->state = xr->idlestate;
    269 }
    270 
    271 static void jtag_xr_rd(JTAG *jtag, JREG *xr, u32 count, u8 *rbits) {
    272 	u32 mcount;
    273 	u8 *mbits;
    274 	jtag_goto(jtag, xr->scanstate);
    275 	mcount = jtag_plot(xr->scanstate, xr->idlestate, &mbits);
    276 	if (xr->prebits) {
    277 		_scan_io(xr->precount, xr->prebits, 0);
    278 	}
    279 	if (xr->postbits) {
    280 		_scan_io(count, 0, rbits);
    281 		_scan_io(xr->postcount - 1, xr->postbits, 0);
    282 		_scan_tms(lastbit(xr->postbits, xr->postcount), mcount, mbits, 0, 0);
    283 	} else {
    284 		_scan_io(count - 1, 0, rbits);
    285 		_scan_tms(0, mcount, mbits, count - 1, rbits);
    286 	}
    287 	jtag->state = xr->idlestate;
    288 }
    289 
    290 static void jtag_xr_io(JTAG *jtag, JREG *xr, u32 count, u8 *wbits, u8 *rbits) {
    291 	u32 mcount;
    292 	u8 *mbits;
    293 	jtag_goto(jtag, xr->scanstate);
    294 	mcount = jtag_plot(xr->scanstate, xr->idlestate, &mbits);
    295 	if (xr->prebits) {
    296 		_scan_io(xr->precount, xr->prebits, 0);
    297 	}
    298 	if (xr->postbits) {
    299 		_scan_io(count, (void*) wbits, rbits);
    300 		_scan_io(xr->postcount - 1, xr->postbits, 0);
    301 		_scan_tms(lastbit(xr->postbits, xr->postcount), mcount, mbits, 0, 0);
    302 	} else {
    303 		_scan_io(count - 1, (void*) wbits, rbits);
    304 		_scan_tms(lastbit(wbits, count), mcount, mbits, count - 1, rbits);
    305 	}
    306 	jtag->state = xr->idlestate;
    307 }
    308 
    309 void jtag_ir_wr(JTAG *jtag, unsigned count, const void *wbits) {
    310 	jtag_xr_wr(jtag, &jtag->ir, count, (void*) wbits);
    311 }
    312 void jtag_ir_rd(JTAG *jtag, unsigned count, void *rbits) {
    313 	jtag_xr_rd(jtag, &jtag->ir, count, rbits);
    314 }
    315 void jtag_ir_io(JTAG *jtag, unsigned count, const void *wbits, void *rbits) {
    316 	jtag_xr_io(jtag, &jtag->ir, count, (void*) wbits, rbits);
    317 }
    318 
    319 void jtag_dr_wr(JTAG *jtag, unsigned count, const void *wbits) {
    320 	jtag_xr_wr(jtag, &jtag->dr, count, (void*) wbits);
    321 }
    322 void jtag_dr_rd(JTAG *jtag, unsigned count, void *rbits) {
    323 	jtag_xr_rd(jtag, &jtag->dr, count, rbits);
    324 }
    325 void jtag_dr_io(JTAG *jtag, unsigned count, const void *wbits, void *rbits) {
    326 	jtag_xr_io(jtag, &jtag->dr, count, (void*) wbits, rbits);
    327 }
    328 
    329 int jtag_commit(JTAG *jtag) {
    330 	return _commit();
    331 }
    332 
    333 int jtag_enumerate(JTAG *jtag) {
    334 	JTAG_INFO *info;
    335 	u32 data[DEVMAX];
    336 	int n;
    337 
    338 	jtag_clear_state(jtag);
    339 	jtag->devcount = 0;
    340 
    341 	jtag_goto(jtag, JTAG_RESET);
    342 	jtag_goto(jtag, JTAG_RESET);
    343 	jtag_goto(jtag, JTAG_RESET);
    344 	jtag_dr_io(jtag, DEVMAX * 4 * 8, ONES, data);
    345 	if (jtag_commit(jtag)) {
    346 		return -1;
    347 	}
    348 	for (n = 0; n < DEVMAX; n++) {
    349 		if (data[n] == 0xffffffff) {
    350 			if (n == 0) {
    351 				fprintf(stderr, "no devices found\n");
    352 				return -1;
    353 			}
    354 			jtag->devcount = n;
    355 			return n;
    356 		}
    357 		if (!(data[n] & 1)) {
    358 			fprintf(stderr, "device %d has no idcode\n", n);
    359 			return -1;
    360 		}
    361 		if ((info = jtag_lookup_device(data[n])) == NULL) {
    362 			fprintf(stderr, "device %d (id %08x) unknown\n",
    363 				n, (unsigned) data[n]);
    364 			return -1;
    365 		}
    366 		memcpy(jtag->devinfo + n, info, sizeof(JTAG_INFO));
    367 	}
    368 	fprintf(stderr, "too many devices\n");
    369 	return -1;
    370 }
    371 
    372 void jtag_print_chain(JTAG *jtag) {
    373 	int n;
    374 	for (n = 0; n < jtag->devcount; n++) {
    375 		JTAG_INFO *info = jtag->devinfo + n;
    376 		fprintf(stderr, "device %02d idcode: %08x name: %-16s family: %s\n",
    377 			n, info->idcode, info->name, info->family);
    378 	}
    379 }
    380 
    381 JTAG_INFO *jtag_get_nth_device(JTAG *jtag, int n) {
    382 	if ((n >= jtag->devcount) || (n < 0)) {
    383 		return NULL;
    384 	}
    385 	return jtag->devinfo + n;
    386 }
    387 
    388 int jtag_select_device_nth(JTAG *jtag, int num) {
    389 	u32 irpre = 0;
    390 	u32 irpost = 0;
    391 	u32 drpre = 0;
    392 	u32 drpost = 0;
    393 	int n;
    394 	if ((num >= jtag->devcount) || (num < 0)) {
    395 		return -1;
    396 	}
    397 	for (n = 0; n < jtag->devcount; n++) {
    398 		if (n < num) {
    399 			irpre += jtag->devinfo[n].irsize;
    400 			drpre += 1;
    401 		} else if (n > num) {
    402 			irpost += jtag->devinfo[n].irsize;
    403 			drpost += 1;
    404 		}
    405 	}
    406 	jtag_set_ir_prefix(jtag, irpre, ONES);
    407 	jtag_set_ir_postfix(jtag, irpost, ONES);
    408 	jtag_set_dr_prefix(jtag, drpre, ONES);
    409 	jtag_set_dr_postfix(jtag, drpost, ONES);
    410 	return 0;
    411 }
    412 
    413 int jtag_select_device(JTAG *jtag, unsigned idcode) {
    414 	int n;
    415 	for (n = 0; n < jtag->devcount; n++) {
    416 		if (jtag->devinfo[n].idcode == idcode) {
    417 			return jtag_select_device_nth(jtag, n);
    418 		}
    419 	}
    420 	return -1;
    421 }
    422 
    423 int jtag_select_by_family(JTAG *jtag, const char *family) {
    424 	int i, n;
    425 	int count = 0;
    426 	for (i = 0; i < jtag->devcount; i++) {
    427 		if (!strcmp(jtag->devinfo[i].family, family)) {
    428 			count++;
    429 			n = i;
    430 		}
    431 	}
    432 	if (count == 0) {
    433 		fprintf(stderr, "jtag: no devices of family '%s' found.\n", family);
    434 		return -1;
    435 	}
    436 	if (count > 1) {
    437 		fprintf(stderr, "jtag: multiple devices of family '%s' found.\n", family);
    438 		return -1;
    439 	}
    440 	return jtag_select_device_nth(jtag, n);	
    441 }
    442