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