jtag-dap.c (11701B)
1 /* jtag-dap.c 2 * 3 * Copyright 2015 Brian Swetland <swetland@frotz.net> 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 18 #include <stdio.h> 19 #include <stdlib.h> 20 #include <string.h> 21 22 #include <fw/types.h> 23 #include "debugger.h" 24 #include "jtag.h" 25 #include "dap-registers.h" 26 27 #define CSW_ERRORS (DPCSW_STICKYERR | DPCSW_STICKYCMP | DPCSW_STICKYORUN) 28 #define CSW_ENABLES (DPCSW_CSYSPWRUPREQ | DPCSW_CDBGPWRUPREQ | DPCSW_ORUNDETECT) 29 30 typedef struct DAP { 31 jtag_txn *jtag; 32 u32 cached_ir; 33 u32 ir_pre, ir_post; 34 u32 dr_pre, dr_post; 35 } DAP; 36 37 void dap_init_jtag(DAP *dap) { 38 jtag_txn_init(dap->jtag); 39 dap->cached_ir = 0xFFFFFFFF; 40 dap->jtag->ir_pre = dap->ir_pre; 41 dap->jtag->ir_post = dap->ir_post; 42 dap->jtag->dr_pre = dap->dr_pre; 43 dap->jtag->dr_post = dap->dr_post; 44 dap->jtag->state = JTAG_IDLE; 45 } 46 47 void dap_init(DAP *dap, jtag_txn *t, u32 ir_pre, u32 ir_post, u32 dr_pre, u32 dr_post) { 48 dap->jtag = t; 49 dap->ir_pre = ir_pre; 50 dap->ir_post = ir_post; 51 dap->dr_pre = dr_pre; 52 dap->dr_post = dr_post; 53 dap_init_jtag(dap); 54 } 55 56 static void q_dap_ir_wr(DAP *dap, u32 ir) { 57 if (dap->cached_ir != ir) { 58 dap->cached_ir = ir; 59 jtag_ir(dap->jtag, 4, ir); 60 } 61 } 62 63 // force ir write even if redundant 64 // used for a timing hack 65 static void _q_dap_ir_wr(DAP *dap, u32 ir) { 66 dap->cached_ir = ir; 67 jtag_ir(dap->jtag, 4, ir); 68 } 69 70 static void q_dap_dr_io(DAP *dap, u32 bitcount, u64 wdata, u64 *rdata) { 71 if (rdata) { 72 *rdata = 0; 73 } 74 jtag_dr(dap->jtag, bitcount, wdata, rdata); 75 } 76 77 static void q_dap_abort(DAP *dap) { 78 jtag_ir(dap->jtag, 4, DAP_IR_ABORT); 79 jtag_dr(dap->jtag, 35, 8, NULL); 80 dap->cached_ir = 0xFFFFFFFF; 81 } 82 83 static int dap_commit_jtag(DAP *dap) { 84 int r = jtag_txn_exec(dap->jtag); 85 dap_init_jtag(dap); 86 return r; 87 } 88 89 // queue a DPCSW status query, commit jtag txn 90 static int dap_commit(DAP *dap) { 91 u64 a, b; 92 q_dap_ir_wr(dap, DAP_IR_DPACC); 93 q_dap_dr_io(dap, 35, XPACC_RD(DPACC_CSW), &a); 94 q_dap_dr_io(dap, 35, XPACC_RD(DPACC_RDBUFF), &b); 95 dap->cached_ir = 0xFFFFFFFF; 96 if (dap_commit_jtag(dap)) { 97 return -1; 98 } 99 #if 0 100 xprintf(XCORE, "DP_CSW %08x(%x) RDBUF %08x(%x)\n", 101 ((u32) (a >> 3)), ((u32) (a & 7)), 102 ((u32) (b >> 3)), ((u32) (b & 7))); 103 #endif 104 if (XPACC_STATUS(a) != XPACC_OK) { 105 xprintf(XCORE, "dap: invalid txn status\n"); 106 return -1; 107 } 108 if (XPACC_STATUS(b) != XPACC_OK) { 109 xprintf(XCORE, "dap: cannot read status\n"); 110 return -1; 111 } 112 b >>= 3; 113 if (b & DPCSW_STICKYORUN) { 114 xprintf(XCORE, "dap: overrun\n"); 115 return -1; 116 } 117 if (b & DPCSW_STICKYERR) { 118 xprintf(XCORE, "dap: error\n"); 119 return -1; 120 } 121 return 0; 122 } 123 124 int dap_dp_rd(DAP *dap, u32 addr, u32 *val) { 125 u64 u; 126 q_dap_ir_wr(dap, DAP_IR_DPACC); 127 q_dap_dr_io(dap, 35, XPACC_RD(addr), NULL); 128 q_dap_dr_io(dap, 35, XPACC_RD(DPACC_RDBUFF), &u); 129 if (dap_commit_jtag(dap)) { 130 return -1; 131 } 132 if (XPACC_STATUS(u) != XPACC_OK) { 133 return -1; 134 } 135 *val = u >> 3; 136 return 0; 137 } 138 139 static void q_dap_dp_wr(DAP *dap, u32 addr, u32 val) { 140 q_dap_ir_wr(dap, DAP_IR_DPACC); 141 q_dap_dr_io(dap, 35, XPACC_WR(addr, val), NULL); 142 //q_dap_dr_io(dap, 35, XPACC_RD(DPACC_RDBUFF), &s->u); 143 } 144 145 int dap_dp_wr(DAP *dap, u32 addr, u32 val) { 146 q_dap_dp_wr(dap, addr, val); 147 return dap_commit_jtag(dap); 148 } 149 150 int dap_ap_rd(DAP *dap, u32 apnum, u32 addr, u32 *val) { 151 u64 u; 152 q_dap_ir_wr(dap, DAP_IR_DPACC); 153 q_dap_dp_wr(dap, DPACC_SELECT, DPSEL_APSEL(apnum) | DPSEL_APBANKSEL(addr)); 154 q_dap_ir_wr(dap, DAP_IR_APACC); 155 q_dap_dr_io(dap, 35, XPACC_RD(addr), NULL); 156 q_dap_ir_wr(dap, DAP_IR_DPACC); 157 q_dap_dr_io(dap, 35, XPACC_RD(DPACC_RDBUFF), &u); 158 // TODO: redundant ir wr 159 if (dap_commit(dap)) { 160 return -1; 161 } 162 *val = (u >> 3); 163 return 0; 164 } 165 166 void q_dap_ap_wr(DAP *dap, u32 apnum, u32 addr, u32 val) { 167 q_dap_ir_wr(dap, DAP_IR_DPACC); 168 q_dap_dp_wr(dap, DPACC_SELECT, DPSEL_APSEL(apnum) | DPSEL_APBANKSEL(addr)); 169 q_dap_ir_wr(dap, DAP_IR_APACC); 170 q_dap_dr_io(dap, 35, XPACC_WR(addr, val), NULL); 171 } 172 173 int dap_ap_wr(DAP *dap, u32 apnum, u32 addr, u32 val) { 174 q_dap_ap_wr(dap, apnum, addr, val); 175 return dap_commit(dap); 176 } 177 178 int dap_mem_wr32(DAP *dap, u32 n, u32 addr, u32 val) { 179 if (addr & 3) 180 return -1; 181 q_dap_ap_wr(dap, n, APACC_CSW, 182 0x23000000 | APCSW_DBGSWEN | APCSW_INCR_NONE | APCSW_SIZE32); //XXX 183 q_dap_ap_wr(dap, n, APACC_TAR, addr); 184 q_dap_ap_wr(dap, n, APACC_DRW, val); 185 return dap_commit(dap); 186 } 187 188 int dap_mem_rd32(DAP *dap, u32 n, u32 addr, u32 *val) { 189 if (addr & 3) 190 return -1; 191 q_dap_ap_wr(dap, n, APACC_CSW, 192 0x23000000 | APCSW_DBGSWEN | APCSW_INCR_NONE | APCSW_SIZE32); //XXX 193 q_dap_ap_wr(dap, n, APACC_TAR, addr); 194 if (dap_ap_rd(dap, n, APACC_DRW, val)) 195 return -1; 196 return 0; 197 } 198 199 200 int dap_attach(DAP *dap) { 201 unsigned n; 202 u32 x; 203 204 // make sure we abort any ongoing transactions first 205 q_dap_abort(dap); 206 207 // attempt to power up and clear errors 208 for (n = 0; n < 10; n++) { 209 if (dap_dp_wr(dap, DPACC_CSW, CSW_ERRORS | CSW_ENABLES)) 210 continue; 211 if (dap_dp_rd(dap, DPACC_CSW, &x)) 212 continue; 213 if (x & CSW_ERRORS) 214 continue; 215 if (!(x & DPCSW_CSYSPWRUPACK)) 216 continue; 217 if (!(x & DPCSW_CDBGPWRUPACK)) 218 continue; 219 return 0; 220 } 221 xprintf(XCORE, "dap: attach failed\n"); 222 return -1; 223 } 224 225 void dap_clear_errors(DAP *dap) { 226 q_dap_dp_wr(dap, DPACC_CSW, CSW_ERRORS | CSW_ENABLES); 227 } 228 229 static int read4xid(DAP *dap, u32 n, u32 addr, u32 *val) { 230 u32 a,b,c,d; 231 if (dap_mem_rd32(dap, n, addr + 0x00, &a)) return -1; 232 if (dap_mem_rd32(dap, n, addr + 0x04, &b)) return -1; 233 if (dap_mem_rd32(dap, n, addr + 0x08, &c)) return -1; 234 if (dap_mem_rd32(dap, n, addr + 0x0C, &d)) return -1; 235 *val = (a & 0xFF) | ((b & 0xFF) << 8) | ((c & 0xFF) << 16) | ((d & 0xFF) << 24); 236 return 0; 237 } 238 239 static int readinfo(DAP *dap, u32 n, u32 base, u32 *cid, u32 *pid0, u32 *pid1) { 240 if (read4xid(dap, n, base + 0xFF0, cid)) return -1; 241 if (read4xid(dap, n, base + 0xFE0, pid0)) return -1; 242 if (read4xid(dap, n, base + 0xFD0, pid1)) return -1; 243 return 0; 244 } 245 246 static void dumptable(DAP *dap, u32 n, u32 base) { 247 u32 cid, pid0, pid1, memtype; 248 u32 x, addr; 249 int i; 250 251 xprintf(XCORE, "TABLE @%08x ", base); 252 if (readinfo(dap, n, base, &cid, &pid0, &pid1)) { 253 xprintf(XCORE, "<error reading cid & pid>\n"); 254 return; 255 } 256 if (dap_mem_rd32(dap, n, base + 0xFCC, &memtype)) { 257 xprintf(XCORE, "<error reading memtype>\n"); 258 return; 259 } 260 xprintf(XCORE, "CID %08x PID %08x %08x %dKB%s\n", cid, pid1, pid0, 261 4 * (1 + ((pid1 & 0xF0) >> 4)), 262 (memtype & 1) ? " SYSMEM": ""); 263 for (i = 0; i < 128; i++) { 264 if (dap_mem_rd32(dap, n, base + i * 4, &x)) break; 265 if (x == 0) break; 266 if ((x & 3) != 3) continue; 267 addr = base + (x & 0xFFFFF000); 268 if (readinfo(dap, n, addr, &cid, &pid0, &pid1)) { 269 xprintf(XCORE, " <error reading cid & pid>\n"); 270 continue; 271 } 272 xprintf(XCORE, " %02d: @%08x CID %08x PID %08x %08x %dKB\n", 273 i, addr, cid, pid1, pid0, 274 4 * (1 + ((pid1 & 0xF0) >> 4))); 275 if (((cid >> 12) & 0xF) == 1) { 276 dumptable(dap, n, addr); 277 } 278 } 279 } 280 281 int dap_probe(DAP *dap) { 282 unsigned n; 283 u32 x, y; 284 285 for (n = 0; n < 256; n++) { 286 if (dap_ap_rd(dap, n, APACC_IDR, &x)) 287 break; 288 if (x == 0) 289 break; 290 y = 0; 291 dap_ap_rd(dap, n, APACC_BASE, &y); 292 xprintf(XCORE, "AP%d ID=%08x BASE=%08x\n", n, x, y); 293 if (y && (y != 0xFFFFFFFF)) { 294 dumptable(dap, n, y & 0xFFFFF000); 295 } 296 if (dap_ap_rd(dap, n, APACC_CSW, &x) == 0) 297 xprintf(XCORE, "AP%d CSW=%08x\n", n, x); 298 } 299 return 0; 300 } 301 302 static int jtag_error = 0; 303 304 #include "ti-icepick.h" 305 306 #define IDCODE_ARM_M3 0x4ba00477 307 #define IPCODE_TI_ICEPICK 0x41611cc0 308 #define IDCODE_CC1310 0x2b9be02f 309 #define IDCODE_CC2650 0x8b99a02f 310 311 int connect_ti(void) { 312 u64 x0, x1; 313 int retry = 5; 314 jtag_txn t; 315 316 while (retry > 0) { 317 jtag_txn_init(&t); 318 jtag_any_to_rti(&t); 319 320 // Enable 4-wire JTAG 321 jtag_ir(&t, 6, 0x3F); 322 jtag_cjtag_open(&t); 323 jtag_cjtag_cmd(&t, 2, 9); 324 jtag_ir(&t, 6, 0x3F); 325 326 // sit in IDLE for a bit (not sure if useful) 327 jtag_txn_append(&t, 64, 0, 0, NULL); 328 329 // Read IDCODE and IPCODE 330 jtag_ir(&t, 6, IP_IR_IDCODE); 331 jtag_dr(&t, 32, 0x00000000, &x0); 332 jtag_ir(&t, 6, IP_IR_IPCODE); 333 jtag_dr(&t, 32, 0x00000000, &x1); 334 jtag_txn_exec(&t); 335 336 if (x1 == IPCODE_TI_ICEPICK) { 337 if (x0 == IDCODE_CC1310) { 338 break; 339 } 340 if (x0 == IDCODE_CC2650) { 341 break; 342 } 343 xprintf(XCORE, "wat!\n"); 344 } 345 retry--; 346 } 347 if (retry == 0) { 348 //xprintf(XCORE, "cannot connect (%08x %08x)\n", (u32)x0, (u32)x1); 349 return -1; 350 } 351 xprintf(XSWD, "attach: IDCODE %08x %08x\n", (u32)x0, (u32)x1); 352 353 jtag_txn_init(&t); 354 t.state = JTAG_IDLE; 355 356 // enable router access 357 jtag_ir(&t, 6, IP_IR_CONNECT); 358 jtag_dr(&t, 8, IP_CONNECT_WR_KEY, NULL); 359 360 // add ARM DAP to the scan chain 361 jtag_ir(&t, 6, IP_IR_ROUTER); 362 jtag_dr_p(&t, 32, IP_RTR_WR | IP_RTR_BLK(IP_BLK_DEBUG_TLCB) | 363 IP_RTR_REG(IP_DBG_TAP0) | 364 IP_RTR_VAL(IP_DBG_SELECT_TAP | IP_DBG_INHIBIT_SLEEP | IP_DBG_FORCE_ACTIVE), NULL); 365 366 // commit router changes by going to IDLE state 367 jtag_txn_move(&t, JTAG_IDLE); 368 369 // idle for a few clocks to let the new TAP path settle 370 jtag_txn_append(&t, 8, 0, 0, NULL); 371 jtag_txn_exec(&t); 372 373 #if 0 374 jtag_txn_init(&t); 375 t.state = JTAG_IDLE; 376 t.ir_pre = 4; 377 t.dr_pre = 1; 378 jtag_ir(&t, 6, IP_IR_ROUTER); 379 jtag_dr(&t, 32, IP_RTR_WR | IP_RTR_BLK(IP_BLK_CONTROL) | IP_RTR_REG(IP_CTL_CONTROL) | 380 IP_RTR_VAL(IP_CTL_SYSTEM_RESET), NULL); 381 jtag_txn_exec(&t); 382 #endif 383 384 // we should now be stable, try to read DAP IDCODE 385 jtag_txn_init(&t); 386 t.state = JTAG_IDLE; 387 t.ir_post = 6; 388 t.dr_post = 1; 389 jtag_ir(&t, 4, 0xE); // IDCODE 390 jtag_dr(&t, 32, 0, &x0); 391 jtag_txn_exec(&t); 392 393 if (x0 != IDCODE_ARM_M3) { 394 xprintf(XDATA, "cannot find DAP (%08x)\n", (u32)x0); 395 return -1; 396 } 397 398 return 0; 399 } 400 401 int _attach(void) { 402 jtag_txn t; 403 DAP dap; 404 jtag_error = -1; 405 if (connect_ti()) { 406 return -1; 407 } 408 dap_init(&dap, &t, 0, 6, 0, 1); 409 if (dap_attach(&dap)) { 410 return -1; 411 } 412 xprintf(XSWD, "attach: JTAG DAP ok\n"); 413 jtag_error = 0; 414 return 0; 415 } 416 417 static int _mem_rd_32(u32 addr, u32 *val) { 418 jtag_txn t; 419 DAP dap; 420 if ((addr & 3) || jtag_error) { 421 return -1; 422 } 423 dap_init(&dap, &t, 0, 6, 0, 1); 424 jtag_error = dap_mem_rd32(&dap, 0, addr, val); 425 return jtag_error; 426 } 427 428 static int _mem_wr_32(u32 addr, u32 val) { 429 jtag_txn t; 430 DAP dap; 431 if ((addr & 3) || jtag_error) { 432 return -1; 433 } 434 dap_init(&dap, &t, 0, 6, 0, 1); 435 jtag_error = dap_mem_wr32(&dap, 0, addr, val); 436 return jtag_error; 437 } 438 439 static int _mem_rd_32_c(u32 addr, u32 *data, int count) { 440 jtag_txn t; 441 DAP dap; 442 if ((addr & 3) || jtag_error) { 443 return -1; 444 } 445 dap_init(&dap, &t, 0, 6, 0, 1); 446 while (count > 0) { 447 if (dap_mem_rd32(&dap, 0, addr, data)) { 448 jtag_error = -1; 449 return -1; 450 } 451 addr += 4; 452 data++; 453 count--; 454 } 455 return 0; 456 } 457 458 static int _mem_wr_32_c(u32 addr, u32 *data, int count) { 459 jtag_txn t; 460 DAP dap; 461 if ((addr & 3) || jtag_error) { 462 return -1; 463 } 464 dap_init(&dap, &t, 0, 6, 0, 1); 465 while (count > 0) { 466 if (dap_mem_wr32(&dap, 0, addr, *data)) { 467 jtag_error = -1; 468 return -1; 469 } 470 addr += 4; 471 data++; 472 count--; 473 } 474 return 0; 475 } 476 477 static int _clear_error(void) { 478 if (jtag_error) { 479 //XXX this is a lighter weight operation in SWDP 480 _attach(); 481 } 482 return jtag_error; 483 } 484 485 static int _error(void) { 486 return jtag_error; 487 } 488 489 debug_transport JTAG_TRANSPORT = { 490 .attach = _attach, 491 .error = _error, 492 .clear_error = _clear_error, 493 .mem_rd_32 = _mem_rd_32, 494 .mem_wr_32 = _mem_wr_32, 495 .mem_rd_32_c = _mem_rd_32_c, 496 .mem_wr_32_c = _mem_wr_32_c, 497 };