debugger-commands.c (26768B)
1 /* debugger-commands.); 2 * 3 * Copyright 2011 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 <unistd.h> 21 #include <string.h> 22 #include <ctype.h> 23 #include <stdarg.h> 24 #include <errno.h> 25 26 #include <fcntl.h> 27 #include <sys/time.h> 28 29 #include <fw/types.h> 30 #include <protocol/rswdp.h> 31 #include "rswdp.h" 32 #include "arm-v7m.h" 33 34 #include "debugger.h" 35 #include "lkdebug.h" 36 37 #define _AGENT_HOST_ 1 38 #include <agent/flash.h> 39 40 extern struct debugger_command debugger_commands[]; 41 42 long long now() { 43 struct timeval tv; 44 gettimeofday(&tv, 0); 45 return ((long long) tv.tv_usec) + ((long long) tv.tv_sec) * 1000000LL; 46 } 47 48 extern int disassemble_thumb2(u32 addr, u16 op0, u16 op1, 49 char *text, int len) __attribute__ ((weak)); 50 51 int disassemble(u32 addr) { 52 #if WITH_THUMB2_DISASSEMBLE 53 char text[128]; 54 int r; 55 union { 56 u32 w[2]; 57 u16 h[4]; 58 } mem; 59 60 if (!disassemble_thumb2) 61 return -1; 62 63 if (addr & 2) { 64 if (swdp_ahb_read32(addr & (~3), mem.w, 2)) 65 return -1; 66 r = disassemble_thumb2(addr, mem.h[1], mem.h[2], text, 128); 67 } else { 68 if (swdp_ahb_read32(addr & (~3), mem.w, 1)) 69 return -1; 70 r = disassemble_thumb2(addr, mem.h[0], mem.h[1], text, 128); 71 } 72 if (r > 0) 73 xprintf(XDATA, "%s\n", text); 74 return r; 75 #else 76 return -1; 77 #endif 78 } 79 80 int do_exit(int argc, param *argv) { 81 exit(0); 82 return 0; 83 } 84 85 int do_attach(int argc, param *argv) { 86 if (argc > 0) { 87 if (!strcmp(argv[0].s, "pico0")) { 88 swdp_targetsel(0x01002927, 1); 89 ACTIVE_TRANSPORT = &SWDP_TRANSPORT; 90 } else if (!strcmp(argv[0].s, "pico1")) { 91 swdp_targetsel(0x11002927, 1); 92 ACTIVE_TRANSPORT = &SWDP_TRANSPORT; 93 } else if (!strcmp(argv[0].s, "picor")) { 94 swdp_targetsel(0xF1002927, 1); 95 ACTIVE_TRANSPORT = &SWDP_TRANSPORT; 96 } else if (!strcmp(argv[0].s, "swd")) { 97 swdp_targetsel(0, 0); 98 ACTIVE_TRANSPORT = &SWDP_TRANSPORT; 99 } else if (!strcmp(argv[0].s, "swdx")) { 100 swdp_targetsel(0xffffffff, 1); 101 ACTIVE_TRANSPORT = &SWDP_TRANSPORT; 102 } else if (!strcmp(argv[0].s, "jtag")) { 103 ACTIVE_TRANSPORT = &JTAG_TRANSPORT; 104 } else { 105 xprintf(XCORE, "unknown transport '%s'\n", argv[0].s); 106 } 107 } 108 return swdp_reset(); 109 } 110 111 int debug_target(const char* name) { 112 if (!strcmp(name,"pico")) { 113 xprintf(XDATA, "target: RPxxxx MCUs\n"); 114 xprintf(XDATA, "target: use 'attach pico0', 'attach pico1' to change cores\n"); 115 xprintf(XDATA, "target: use 'attach picor' to enter rescue (reset-stop-in-rom)\n"); 116 swdp_targetsel(0x01002927, 1); 117 return 0; 118 } else { 119 xprintf(XDATA, "target: unknown target '%s'\n", name); 120 return -1; 121 } 122 } 123 124 static u32 lastregs[19]; 125 126 int do_regs(int argc, param *argv) { 127 if (swdp_core_read_all(lastregs)) 128 return -1; 129 130 xprintf(XDATA, "r0 %08x r4 %08x r8 %08x ip %08x psr %08x\n", 131 lastregs[0], lastregs[4], lastregs[8], 132 lastregs[12], lastregs[16]); 133 xprintf(XDATA, "r1 %08x r5 %08x r9 %08x sp %08x msp %08x\n", 134 lastregs[1], lastregs[5], lastregs[9], 135 lastregs[13], lastregs[17]); 136 xprintf(XDATA, "r2 %08x r6 %08x 10 %08x lr %08x psp %08x\n", 137 lastregs[2], lastregs[6], lastregs[10], 138 lastregs[14], lastregs[18]); 139 xprintf(XDATA, "r3 %08x r7 %08x 11 %08x pc %08x\n", 140 lastregs[3], lastregs[7], lastregs[11], 141 lastregs[15]); 142 disassemble(lastregs[15]); 143 return 0; 144 } 145 146 int do_stop(int argc, param *argv) { 147 swdp_core_halt(); 148 do_regs(0, 0); 149 return 0; 150 } 151 152 int do_resume(int argc, param *argv) { 153 swdp_core_resume(); 154 return 0; 155 } 156 157 int do_step(int argc, param *argv) { 158 if (argc > 0) { 159 u32 pc; 160 do { 161 swdp_core_step(); 162 swdp_core_wait_for_halt(); 163 if (swdp_core_read(15, &pc)) { 164 xprintf(XCORE, "step: error\n"); 165 return -1; 166 } 167 fflush(stdout); 168 } while (pc != argv[0].n); 169 } else { 170 swdp_core_step(); 171 swdp_core_wait_for_halt(); 172 } 173 do_regs(0, 0); 174 return 0; 175 } 176 177 struct { 178 const char *name; 179 unsigned n; 180 } core_regmap[] = { 181 { "r0", 0 }, 182 { "r1", 1 }, 183 { "r2", 2 }, 184 { "r3", 3 }, 185 { "r4", 4 }, 186 { "r5", 5 }, 187 { "r6", 6 }, 188 { "r7", 7 }, 189 { "r8", 8 }, 190 { "r9", 9 }, 191 { "r10", 10 }, 192 { "r11", 11 }, 193 { "r12", 12 }, 194 { "r13", 13 }, { "sp", 13 }, 195 { "r14", 14 }, { "lr", 14 }, 196 { "r15", 15 }, { "pc", 15 }, 197 { "psr", 16 }, 198 { "msp", 17 }, 199 { "psp", 18 }, 200 }; 201 202 int read_memory_word(u32 addr, u32 *value) { 203 return swdp_ahb_read(addr, value); 204 } 205 206 int read_register(const char *name, u32 *value) { 207 int n; 208 for (n = 0; n < (sizeof(core_regmap) / sizeof(core_regmap[0])); n++) { 209 if (!strcasecmp(name, core_regmap[n].name)) { 210 if (swdp_core_read(core_regmap[n].n, value)) 211 return -1; 212 return 0; 213 } 214 } 215 return ERROR_UNKNOWN; 216 } 217 218 int do_dr(int argc, param *argv) { 219 unsigned n; 220 u32 x = 0xeeeeeeee; 221 if (argc < 1) 222 return -1; 223 for (n = 0; n < (sizeof(core_regmap) / sizeof(core_regmap[0])); n++) { 224 if (!strcasecmp(argv[0].s, core_regmap[n].name)) { 225 swdp_core_read(core_regmap[n].n, &x); 226 xprintf(XDATA, "%s: %08x\n", argv[0].s, x); 227 return 0; 228 } 229 } 230 swdp_ahb_read(argv[0].n, &x); 231 xprintf(XDATA, "%08x: %08x\n", argv[0].n, x); 232 return 0; 233 } 234 235 int do_wr(int argc, param *argv) { 236 unsigned n; 237 if (argc < 2) 238 return -1; 239 for (n = 0; n < (sizeof(core_regmap) / sizeof(core_regmap[0])); n++) { 240 if (!strcasecmp(argv[0].s, core_regmap[n].name)) { 241 swdp_core_write(core_regmap[n].n, argv[1].n); 242 xprintf(XDATA, "%s<<%08x\n", argv[0].s, argv[1].n); 243 return 0; 244 } 245 } 246 swdp_ahb_write(argv[0].n, argv[1].n); 247 xprintf(XDATA, "%08x<<%08x\n", argv[0].n, argv[1].n); 248 return 0; 249 } 250 251 int do_text(int argc, param *argv) { 252 u8 data[1024], *x; 253 u32 addr; 254 255 if (argc < 1) 256 return -1; 257 addr = argv[0].n; 258 memset(data, 0, sizeof(data)); 259 260 if (swdp_ahb_read32(addr, (void*) data, sizeof(data)/4)) 261 return -1; 262 263 data[sizeof(data)-1] = 0; 264 for (x = data; *x; x++) { 265 if ((*x >= ' ') && (*x < 128)) 266 continue; 267 if (*x == '\n') 268 continue; 269 *x = '.'; 270 } 271 xprintf(XDATA, "%08x: %s\n", addr, (char*) data); 272 return 0; 273 } 274 275 static u32 lastaddr = 0x20000000; 276 static u32 lastcount = 0x40; 277 278 int do_dw(int argc, param *argv) { 279 u32 data[4096]; 280 u32 addr = lastaddr; 281 u32 count = lastcount; 282 unsigned n; 283 284 if (argc > 0) addr = argv[0].n; 285 if (argc > 1) count = argv[1].n; 286 287 memset(data, 0xee, 256 *4); 288 289 /* word align */ 290 addr = (addr + 3) & ~3; 291 count = (count + 3) & ~3; 292 if (count > sizeof(data)) 293 count = sizeof(data); 294 295 lastaddr = addr + count; 296 lastcount = count; 297 298 count /= 4; 299 if (swdp_ahb_read32(addr, data, count)) 300 return -1; 301 302 for (n = 0; count > 0; n += 4, addr += 16) { 303 switch (count) { 304 case 1: 305 count = 0; 306 xprintf(XDATA, "%08x: %08x\n", addr, data[n]); 307 break; 308 case 2: 309 count = 0; 310 xprintf(XDATA, "%08x: %08x %08x\n", 311 addr, data[n], data[n+1]); 312 break; 313 case 3: 314 count = 0; 315 xprintf(XDATA, "%08x: %08x %08x %08x\n", 316 addr, data[n], data[n+1], data[n+2]); 317 break; 318 default: 319 count -= 4; 320 xprintf(XDATA, "%08x: %08x %08x %08x %08x\n", 321 addr, data[n], data[n+1], data[n+2], data[n+3]); 322 break; 323 } 324 } 325 return 0; 326 } 327 328 329 int do_db(int argc, param *argv) { 330 u32 addr, count; 331 u8 data[1024]; 332 char line[256]; 333 unsigned n, m, xfer; 334 335 if (argc < 2) 336 return -1; 337 338 addr = argv[0].n; 339 count = argv[1].n; 340 341 if (count > 1024) 342 count = 1024; 343 344 memset(data, 0xee, 1024); 345 // todo: fix this 346 swdp_ahb_write(AHB_CSW, AHB_CSW_MDEBUG | AHB_CSW_PRIV | 347 AHB_CSW_DBG_EN | AHB_CSW_8BIT); 348 for (n = 0; n < count; n++) { 349 u32 tmp; 350 if (swdp_ahb_read(addr + n, &tmp)) { 351 swdp_reset(); 352 break; 353 } 354 data[n] = tmp >> (8 * (n & 3)); 355 } 356 swdp_ahb_write(AHB_CSW, AHB_CSW_MDEBUG | AHB_CSW_PRIV | 357 AHB_CSW_DBG_EN | AHB_CSW_32BIT); 358 359 for (n = 0; count > 0; count -= xfer) { 360 xfer = (count > 16) ? 16 : count; 361 char *p = line + sprintf(line, "%08x:", addr + n); 362 for (m = 0; m < xfer; m++) { 363 p += sprintf(p, " %02x", data[n++]); 364 } 365 xprintf(XDATA, "%s\n", line); 366 } 367 return 0; 368 } 369 370 // vector catch flags to apply 371 u32 vcflags = DEMCR_VC_HARDERR | DEMCR_VC_BUSERR | DEMCR_VC_STATERR | DEMCR_VC_CHKERR; 372 373 int do_reset(int argc, param *argv) { 374 swdp_core_halt(); 375 swdp_ahb_write(DEMCR, DEMCR_TRCENA | vcflags); 376 /* core reset and sys reset */ 377 swdp_ahb_write(0xe000ed0c, 0x05fa0005); 378 swdp_ahb_write(DEMCR, DEMCR_TRCENA | vcflags); 379 return 0; 380 } 381 382 int do_reset_hw(int argc, param *argv) { 383 swdp_target_reset(1); 384 usleep(10000); 385 swdp_target_reset(0); 386 usleep(10000); 387 return 0; 388 } 389 390 extern int swd_verbose; 391 392 int wait_for_stop() { 393 u32 x; 394 unsigned m = 0; 395 unsigned xr = -1; 396 for (unsigned n = 0; n < 100; n++) { 397 if (swdp_ahb_read(DHCSR, &x) == 0) { 398 if (x & DHCSR_S_HALT) { 399 xprintf(XSWD,"CPU HALTED (%u,%u)\n", n,m); 400 unsigned y = -1, z = -1; 401 swdp_ahb_read(DFSR, &y); 402 swdp_ahb_read(DEMCR, &z); 403 xprintf(XSWD,"DHCSR %08x (%08x)\nDFSR %08x\nDEMCR %08x\n", x, xr, y, z); 404 return 0; 405 } 406 if (x & DHCSR_S_RESET_ST) { 407 xr = x; 408 m++; 409 continue; 410 } 411 //xprintf(XSWD,"??? %08x\n", x); 412 swdp_ahb_write(DHCSR, DHCSR_DBGKEY | DHCSR_C_HALT | DHCSR_C_DEBUGEN); 413 } else { 414 swdp_reset(); 415 } 416 } 417 xprintf(XSWD,"CPU DID NOT HALT\n"); 418 return -1; 419 } 420 421 int do_reset_stop(int argc, param *argv) { 422 swdp_core_halt(); 423 wait_for_stop(); 424 425 // enable vector-trap on reset, enable DWT/FPB 426 swdp_ahb_write(DEMCR, DEMCR_VC_CORERESET | DEMCR_TRCENA | vcflags); 427 428 swdp_ahb_write(0xe00ee08, 0x00010002); 429 // core reset and sys reset 430 //swdp_ahb_write(0xe000ed0c, 0x05fa0005); 431 // sys reset 432 // TRM says requesting both at once is unpredictable... 433 swdp_ahb_write(0xe000ed0c, 0x05fa0004); 434 435 swd_verbose = 0; 436 wait_for_stop(); 437 swd_verbose = 1; 438 439 //swdp_core_wait_for_halt(); 440 //do_stop(0,0); 441 //swdp_ahb_write(DEMCR, DEMCR_TRCENA | vcflags); 442 return 0; 443 } 444 445 int do_watch_pc(int argc, param *argv) { 446 if (argc < 1) 447 return -1; 448 return swdp_watchpoint_pc(0, argv[0].n); 449 } 450 451 int do_watch_rw(int argc, param *argv) { 452 if (argc < 1) 453 return -1; 454 return swdp_watchpoint_rw(0, argv[0].n); 455 } 456 457 int do_watch_off(int argc, param *argv) { 458 return swdp_watchpoint_disable(0); 459 } 460 461 int do_print(int argc, param *argv) { 462 while (argc-- > 0) 463 xprintf(XCORE, "%08x\n", argv++[0].n); 464 return 0; 465 } 466 467 int do_echo(int argc, param *argv) { 468 while (argc-- > 0) { 469 unsigned int argn = argv[0].n; 470 const char *arg = argv++[0].s; 471 472 if (arg[0] == '$') { 473 xprintf(XCORE, "%08x\n", argn); 474 } else { 475 xprintf(XCORE, "%s\n", arg); 476 } 477 } 478 return 0; 479 } 480 481 int do_bootloader(int argc, param *argv) { 482 return swdp_bootloader(); 483 } 484 485 int do_setclock(int argc, param *argv) { 486 if (argc < 1) 487 return -1; 488 return swdp_set_clock(argv[0].n); 489 } 490 491 int do_swoclock(int argc, param *argv) { 492 if (argc < 1) 493 return -1; 494 return swo_set_clock(argv[0].n); 495 } 496 497 int do_help(int argc, param *argv) { 498 struct debugger_command *cmd; 499 for (cmd = debugger_commands; cmd->func != NULL; cmd++) { 500 xprintf(XCORE, "%-16s: %s\n", cmd->name, cmd->help); 501 } 502 503 return 0; 504 } 505 506 void *get_builtin_file(const char *fn, size_t *sz); 507 const char *get_builtin_filename(unsigned n); 508 509 void *load_file(const char *fn, size_t *_sz) { 510 int fd; 511 off_t sz; 512 void *data = NULL; 513 fd = open(fn, O_RDONLY); 514 if (fd < 0) goto fail; 515 sz = lseek(fd, 0, SEEK_END); 516 if (sz < 0) goto fail; 517 if (lseek(fd, 0, SEEK_SET)) goto fail; 518 if ((data = malloc(sz + 4)) == NULL) goto fail; 519 if (read(fd, data, sz) != sz) goto fail; 520 *_sz = sz; 521 return data; 522 fail: 523 if (data) free(data); 524 if (fd >= 0) close(fd); 525 return NULL; 526 } 527 528 int do_upload(int argc, param *argv) { 529 u32 addr; 530 size_t sz; 531 long long t0, t1; 532 int fd, r; 533 void *data; 534 char *x; 535 536 if (argc != 3) { 537 xprintf(XCORE, "error: usage: upload <file> <addr> <length>\n"); 538 return -1; 539 } 540 541 if ((fd = open(argv[0].s, O_CREAT | O_TRUNC | O_WRONLY, 0644)) < 0) { 542 xprintf(XCORE, "error: cannot open '%s'\n", argv[0].s); 543 return -1; 544 } 545 addr = argv[1].n; 546 sz = argv[2].n; 547 addr = (addr + 3) & ~3; 548 sz = (sz + 3) & ~3; 549 550 if ((data = malloc(sz)) == NULL) { 551 xprintf(XCORE, "out of memory\n"); 552 close(fd); 553 return -1; 554 } 555 556 xprintf(XCORE, "reading %d bytes...\n", sz); 557 t0 = now(); 558 if (swdp_ahb_read32(addr, (void*) data, sz / 4)) { 559 xprintf(XCORE, "error: failed to read data\n"); 560 free(data); 561 close(fd); 562 return -1; 563 } 564 t1 = now(); 565 xprintf(XCORE, "%lld uS -> %lld B/s\n", (t1 - t0), 566 (((long long)sz) * 1000000LL) / (t1 - t0)); 567 568 x = data; 569 while (sz > 0) { 570 r = write(fd, x, sz); 571 if (r < 0) { 572 if (errno == EINTR) continue; 573 xprintf(XCORE, "write error\n"); 574 break; 575 } 576 x += r; 577 sz -= r; 578 } 579 close(fd); 580 free(data); 581 return 0; 582 } 583 int do_download(int argc, param *argv) { 584 u32 addr; 585 void *data; 586 size_t sz; 587 long long t0, t1; 588 589 if (argc != 2) { 590 xprintf(XCORE, "error: usage: download <file> <addr>\n"); 591 return -1; 592 } 593 594 if ((data = load_file(argv[0].s, &sz)) == NULL) { 595 xprintf(XCORE, "error: cannot read '%s'\n", argv[0].s); 596 return -1; 597 } 598 sz = (sz + 3) & ~3; 599 addr = argv[1].n; 600 601 xprintf(XCORE, "sending %d bytes...\n", sz); 602 t0 = now(); 603 if (swdp_ahb_write32(addr, (void*) data, sz / 4)) { 604 xprintf(XCORE, "error: failed to write data\n"); 605 free(data); 606 return -1; 607 } 608 t1 = now(); 609 xprintf(XCORE, "%lld uS -> %lld B/s\n", (t1 - t0), 610 (((long long)sz) * 1000000LL) / (t1 - t0)); 611 free(data); 612 return 0; 613 } 614 615 int do_run(int argc, param *argv) { 616 u32 addr; 617 void *data; 618 size_t sz; 619 u32 sp, pc; 620 if (argc != 2) { 621 xprintf(XCORE, "error: usage: run <file> <addr>\n"); 622 return -1; 623 } 624 if ((data = load_file(argv[0].s, &sz)) == NULL) { 625 xprintf(XCORE, "error: cannot read '%s'\n", argv[0].s); 626 return -1; 627 } 628 swdp_core_halt(); 629 sz = (sz + 3) & ~3; 630 addr = argv[1].n; 631 if (swdp_ahb_write32(addr, (void*) data, sz / 4)) { 632 xprintf(XCORE, "error: failed to write data\n"); 633 free(data); 634 return -1; 635 } 636 memcpy(&sp, data, 4); 637 memcpy(&pc, ((char*) data) + 4, 4); 638 swdp_core_write(13, sp); 639 swdp_core_write(15, pc); 640 swdp_ahb_write(0xe000ed0c, 0x05fa0002); 641 swdp_core_write(16, 0x01000000); 642 swdp_core_resume(); 643 free(data); 644 return 0; 645 } 646 647 648 void *load_agent(const char *arch, size_t *_sz) { 649 void *data; 650 size_t sz; 651 char name[256]; 652 if (arch == NULL) return NULL; 653 snprintf(name, 256, "agent-%s.bin", arch); 654 if ((data = get_builtin_file(name, &sz))) { 655 void *copy = malloc(sz + 4); 656 if (copy == NULL) return NULL; 657 memcpy(copy, data, sz); 658 *_sz = sz; 659 return copy; 660 } 661 snprintf(name, sizeof(name), "out/agent-%s.bin", arch); 662 return load_file(name, _sz); 663 } 664 665 static flash_agent *AGENT = NULL; 666 static size_t AGENT_sz = 0; 667 static char *AGENT_arch = NULL; 668 669 int do_setarch(int argc, param *argv) { 670 unsigned n; 671 char *x; 672 const char *name; 673 if (argc != 1) { 674 if (AGENT_arch) { 675 xprintf(XCORE, "current flash agent is '%s'\n", AGENT_arch); 676 } else { 677 xprintf(XCORE, "no flash agent selected\n"); 678 } 679 fail_load: 680 xprintf(XCORE, "error: set architecture with: arch <name> (omit the .bin)\n"); 681 for (n = 0; (name = get_builtin_filename(n)) != NULL; n++) { 682 if (strncmp(name, "agent-", 6)) { 683 continue; 684 } 685 xprintf(XCORE, " %s\n", name + 6); 686 } 687 goto fail; 688 } 689 if ((x = strdup(argv[0].s)) == NULL) { 690 goto fail; 691 } 692 free(AGENT_arch); 693 free(AGENT); 694 AGENT_arch = x; 695 696 if ((AGENT = load_agent(AGENT_arch, &AGENT_sz)) == NULL) { 697 xprintf(XCORE, "error: cannot load flash agent for architecture '%s'\n", AGENT_arch); 698 goto fail_load; 699 } 700 701 // sanity check 702 if ((AGENT_sz < sizeof(flash_agent)) || 703 (AGENT->magic != AGENT_MAGIC) || 704 (AGENT->version != AGENT_VERSION)) { 705 xprintf(XCORE, "error: invalid agent image\n"); 706 free(AGENT); 707 AGENT = NULL; 708 goto fail; 709 } 710 711 xprintf(XCORE, "flash agent '%s' loaded.\n", AGENT_arch); 712 return 0; 713 714 fail: 715 if (AGENT) { 716 free(AGENT); 717 AGENT = NULL; 718 } 719 if (AGENT_arch) { 720 free(AGENT_arch); 721 AGENT_arch = NULL; 722 } 723 AGENT_sz = 0; 724 return -1; 725 } 726 727 int invoke(u32 agent, u32 func, u32 r0, u32 r1, u32 r2, u32 r3) { 728 swdp_core_write(0, r0); 729 swdp_core_write(1, r1); 730 swdp_core_write(2, r2); 731 swdp_core_write(3, r3); 732 swdp_core_write(13, agent - 4); 733 swdp_core_write(14, agent | 1); // include T bit 734 swdp_core_write(15, func | 1); // include T bit 735 736 // if the target has bogus data at 0, the processor may be in 737 // pending-exception state after reset-stop, so we will clear 738 // any exceptions and then set the PSR to something reasonable 739 740 // Write VECTCLRACTIVE to AIRCR 741 swdp_ahb_write(0xe000ed0c, 0x05fa0002); 742 swdp_core_write(16, 0x01000000); 743 744 // todo: readback and verify? 745 746 xprintf(XCORE, "invoke <func@%08x>(0x%x,0x%x,0x%x,0x%x)\n", func, r0, r1, r2, r3); 747 748 swdp_core_resume(); 749 if (swdp_core_wait_for_halt() == 0) { 750 // todo: timeout after a few seconds? 751 u32 pc = 0xffffffff, res = 0xffffffff; 752 swdp_core_read(0, &res); 753 swdp_core_read(15, &pc); 754 if (pc != agent) { 755 xprintf(XCORE, "error: pc (%08x) is not at %08x\n", pc, agent); 756 return -1; 757 } 758 if (res) xprintf(XCORE, "failure code %08x\n", res); 759 return res; 760 } 761 xprintf(XCORE, "interrupted\n"); 762 return -1; 763 } 764 765 int run_flash_agent(u32 flashaddr, void *data, size_t data_sz) { 766 u8 buffer[4096]; 767 flash_agent *agent; 768 size_t agent_sz; 769 int r; 770 771 if (AGENT == NULL) { 772 xprintf(XCORE, "error: no flash agent selected\n"); 773 xprintf(XCORE, "error: set architecture with: arch <name>\n"); 774 goto fail; 775 } 776 if (AGENT_sz > sizeof(buffer)) { 777 xprintf(XCORE, "error: flash agent too large\n"); 778 goto fail; 779 } 780 781 memcpy(buffer, AGENT, AGENT_sz); 782 agent_sz = AGENT_sz; 783 agent = (void*) buffer; 784 785 // replace magic with bkpt instructions 786 agent->magic = 0xbe00be00; 787 788 if (do_attach(0,0)) { 789 xprintf(XCORE, "error: failed to attach\n"); 790 goto fail; 791 } 792 do_reset_stop(0,0); 793 794 if (agent->flags & FLAG_BOOT_ROM_HACK) { 795 xprintf(XCORE, "executing boot rom\n"); 796 if (swdp_watchpoint_rw(0, 0)) { 797 goto fail; 798 } 799 swdp_core_resume(); 800 swdp_core_wait_for_halt(); 801 swdp_watchpoint_disable(0); 802 // todo: timeout? 803 // todo: confirm halted 804 } 805 806 if (swdp_ahb_write32(agent->load_addr, (void*) agent, agent_sz / 4)) { 807 xprintf(XCORE, "error: failed to download agent\n"); 808 goto fail; 809 } 810 r = invoke(agent->load_addr, agent->setup, agent->load_addr, 0, 0, 0); 811 if (r != 0) { 812 if (r == ERR_INVALID) { 813 xprintf(XCORE, "agent: unsupported part\n"); 814 } 815 goto fail; 816 } 817 if (swdp_ahb_read32(agent->load_addr + 16, (void*) &agent->data_addr, 4)) { 818 goto fail; 819 } 820 xprintf(XCORE, "agent %d @%08x, buffer %dK @%08x, flash %dK @%08x\n", 821 agent_sz, agent->load_addr, 822 agent->data_size / 1024, agent->data_addr, 823 agent->flash_size / 1024, agent->flash_addr); 824 825 if ((flashaddr == 0) && (data == NULL) && (data_sz == 0xFFFFFFFF)) { 826 // erase all 827 flashaddr = agent->flash_addr; 828 data_sz = agent->flash_size; 829 } 830 831 if ((flashaddr < agent->flash_addr) || 832 (data_sz > agent->flash_size) || 833 ((flashaddr + data_sz) > (agent->flash_addr + agent->flash_size))) { 834 xprintf(XCORE, "invalid flash address %08x..%08x\n", 835 flashaddr, flashaddr + data_sz); 836 goto fail; 837 } 838 839 if (data == NULL) { 840 // erase 841 if (invoke(agent->load_addr, agent->erase, flashaddr, data_sz, 0, 0)) { 842 xprintf(XCORE, "failed to erase %d bytes at %08x\n", data_sz, flashaddr); 843 goto fail; 844 } 845 } else { 846 // write 847 u8 *ptr = (void*) data; 848 u32 xfer; 849 xprintf(XCORE, "flashing %d bytes at %08x...\n", data_sz, flashaddr); 850 if (invoke(agent->load_addr, agent->erase, flashaddr, data_sz, 0, 0)) { 851 xprintf(XCORE, "failed to erase %d bytes at %08x\n", data_sz, flashaddr); 852 goto fail; 853 } 854 while (data_sz > 0) { 855 if (data_sz > agent->data_size) { 856 xfer = agent->data_size; 857 } else { 858 xfer = data_sz; 859 } 860 if (swdp_ahb_write32(agent->data_addr, (void*) ptr, xfer / 4)) { 861 xprintf(XCORE, "download to %08x failed\n", agent->data_addr); 862 goto fail; 863 } 864 if (invoke(agent->load_addr, agent->write, 865 flashaddr, agent->data_addr, xfer, 0)) { 866 xprintf(XCORE, "failed to flash %d bytes to %08x\n", xfer, flashaddr); 867 goto fail; 868 } 869 ptr += xfer; 870 data_sz -= xfer; 871 flashaddr += xfer; 872 } 873 } 874 875 if (data) free(data); 876 return 0; 877 fail: 878 if (data) free(data); 879 return -1; 880 } 881 882 int do_flash(int argc, param *argv) { 883 void *data = NULL; 884 size_t data_sz; 885 if (argc != 2) { 886 xprintf(XCORE, "error: usage: flash <file> <addr>\n"); 887 return -1; 888 } 889 if ((data = load_file(argv[0].s, &data_sz)) == NULL) { 890 xprintf(XCORE, "error: cannot load '%s'\n", argv[0].s); 891 return -1; 892 } 893 // word align 894 data_sz = (data_sz + 3) & ~3; 895 return run_flash_agent(argv[1].n, data, data_sz); 896 } 897 898 int do_erase(int argc, param *argv) { 899 if ((argc == 1) && !strcmp(argv[0].s, "all")) { 900 return run_flash_agent(0, NULL, 0xFFFFFFFF); 901 } 902 if (argc != 2) { 903 xprintf(XCORE, "error: usage: erase <addr> <length> | erase all\n"); 904 return -1; 905 } 906 return run_flash_agent(argv[0].n, NULL, argv[1].n); 907 } 908 909 int do_log(int argc, param *argv) { 910 unsigned flags = 0; 911 while (argc > 0) { 912 if (!strcmp(argv[0].s, "gdb")) { 913 flags |= LF_GDB; 914 } else if (!strcmp(argv[0].s, "swd")) { 915 flags |= LF_SWD; 916 } else { 917 xprintf(XCORE, "error: allowed flags: gdb swd\n"); 918 return -1; 919 } 920 argc--; 921 argv++; 922 } 923 log_flags = flags; 924 return 0; 925 } 926 927 int do_finfo(int argc, param *argv) { 928 u32 cfsr = 0, hfsr = 0, dfsr = 0, mmfar = 0, bfar = 0; 929 swdp_ahb_read(CFSR, &cfsr); 930 swdp_ahb_read(HFSR, &hfsr); 931 swdp_ahb_read(DFSR, &dfsr); 932 swdp_ahb_read(MMFAR, &mmfar); 933 swdp_ahb_read(BFAR, &bfar); 934 935 xprintf(XDATA, "CFSR %08x MMFAR %08x\n", cfsr, mmfar); 936 xprintf(XDATA, "HFSR %08x BFAR %08x\n", hfsr, bfar); 937 xprintf(XDATA, "DFSR %08x\n", dfsr); 938 939 if (cfsr & CFSR_IACCVIOL) xprintf(XDATA, ">MM: Inst Access Violation\n"); 940 if (cfsr & CFSR_DACCVIOL) xprintf(XDATA, ">MM: Data Access Violation\n"); 941 if (cfsr & CFSR_MUNSTKERR) xprintf(XDATA, ">MM: Derived MM Fault on Exception Return\n"); 942 if (cfsr & CFSR_MSTKERR) xprintf(XDATA, ">MM: Derived MM Fault on Exception Entry\n"); 943 if (cfsr & CFSR_MLSPERR) xprintf(XDATA, ">MM: MM Fault During Lazy FP Save\n"); 944 if (cfsr & CFSR_MMARVALID) xprintf(XDATA, ">MM: MMFAR has valid contents\n"); 945 946 if (cfsr & CFSR_IBUSERR) xprintf(XDATA, ">BF: Bus Fault on Instruction Prefetch\n"); 947 if (cfsr & CFSR_PRECISERR) xprintf(XDATA, ">BF: Precise Data Access Error, Addr in BFAR\n"); 948 if (cfsr & CFSR_IMPRECISERR) xprintf(XDATA, ">BF: Imprecise Data Access Error\n"); 949 if (cfsr & CFSR_UNSTKERR) xprintf(XDATA, ">BF: Derived Bus Fault on Exception Return\n"); 950 if (cfsr & CFSR_STKERR) xprintf(XDATA, ">BF: Derived Bus Fault on Exception Entry\n"); 951 if (cfsr & CFSR_LSPERR) xprintf(XDATA, ">BF: Bus Fault During Lazy FP Save\n"); 952 if (cfsr & CFSR_BFARVALID) xprintf(XDATA, ">BF: BFAR has valid contents\n"); 953 954 if (cfsr & CFSR_UNDEFINSTR) xprintf(XDATA, ">UF: Undefined Instruction Usage Fault\n"); 955 if (cfsr & CFSR_INVSTATE) xprintf(XDATA, ">UF: EPSR.T or ESPR.IT invalid\n"); 956 if (cfsr & CFSR_INVPC) xprintf(XDATA, ">UF: Integrity Check Error on EXC_RETURN\n"); 957 if (cfsr & CFSR_NOCP) xprintf(XDATA, ">UF: Coprocessor Error\n"); 958 if (cfsr & CFSR_UNALIGNED) xprintf(XDATA, ">UF: Unaligned Access Error\n"); 959 if (cfsr & CFSR_DIVBYZERO) xprintf(XDATA, ">UF: Divide by Zero\n"); 960 961 if (hfsr & HFSR_VECTTBL) xprintf(XDATA, ">HF: Vector Table Read Fault\n"); 962 if (hfsr & HFSR_FORCED) xprintf(XDATA, ">HF: Exception Escalated to Hard Fault\n"); 963 if (hfsr & HFSR_DEBUGEVT) xprintf(XDATA, ">HF: Debug Event\n"); 964 965 // clear sticky fault bits 966 swdp_ahb_write(CFSR, CFSR_ALL); 967 swdp_ahb_write(HFSR, HFSR_ALL); 968 return 0; 969 } 970 971 extern int swdp_step_no_ints; 972 973 int do_maskints(int argc, param *argv) { 974 if (argc != 1) { 975 xprintf(XCORE, "usage: maskints [on|off|always]\n"); 976 return -1; 977 } 978 if (!strcmp(argv[0].s, "on")) { 979 swdp_step_no_ints = 1; 980 xprintf(XCORE, "maskints: while stepping\n"); 981 } else if (!strcmp(argv[0].s, "always")) { 982 swdp_step_no_ints = 2; 983 xprintf(XCORE, "maskints: always\n"); 984 } else { 985 swdp_step_no_ints = 0; 986 xprintf(XCORE, "maskints: never\n"); 987 } 988 return 0; 989 } 990 991 int do_threads(int argc, param *argv) { 992 if (argc == 1) { 993 if (strcmp(argv[0].s, "clear")) { 994 xprintf(XCORE, "usage: threads [clear]\n"); 995 return -1; 996 } 997 swdp_core_halt(); 998 clear_lk_threads(); 999 return 0; 1000 } 1001 lkthread_t *t; 1002 swdp_core_halt(); 1003 t = find_lk_threads(1); 1004 dump_lk_threads(t); 1005 free_lk_threads(t); 1006 return 0; 1007 } 1008 1009 int remote_msg(u32 cmd) { 1010 unsigned timeout = 250; 1011 u32 n = 0; 1012 if (swdp_ahb_write(DCRDR, cmd)) goto fail; 1013 if (swdp_ahb_read(DEMCR, &n)) goto fail; 1014 if (swdp_ahb_write(DEMCR, n | DEMCR_MON_PEND)) goto fail; 1015 while (timeout > 0) { 1016 if (swdp_ahb_read(DCRDR, &n)) goto fail; 1017 if (!(n & 0x80000000)) return 0; 1018 timeout--; 1019 } 1020 xprintf(XCORE, "console write timeout\n"); 1021 return -1; 1022 fail: 1023 xprintf(XCORE, "console write io error\n"); 1024 return -1; 1025 } 1026 1027 int do_wconsole(int argc, param *argv) { 1028 if (argc != 1) return -1; 1029 const char *line = argv[0].s; 1030 while (*line) { 1031 if (remote_msg(0x80000000 | *line)) return -1; 1032 line++; 1033 } 1034 if (remote_msg(0x80000000 | '\r')) return -1; 1035 return 0; 1036 } 1037 1038 1039 struct debugger_command debugger_commands[] = { 1040 { "exit", "", do_exit, "" }, 1041 { "attach", "", do_attach, "attach/reattach to sw-dp" }, 1042 { "regs", "", do_regs, "show cpu registers" }, 1043 { "finfo", "", do_finfo, "Fault Information" }, 1044 { "stop", "", do_stop, "halt cpu" }, 1045 { "step", "", do_step, "single-step cpu" }, 1046 { "go", "", do_resume, "resume cpu" }, 1047 { "dw", "", do_dw, "dump words" }, 1048 { "db", "", do_db, "dump bytes" }, 1049 { "dr", "", do_dr, "dump register" }, 1050 { "wr", "", do_wr, "write register" }, 1051 { "download", "", do_download, "download file to device" }, 1052 { "upload", "", do_upload, "upload device memory to file" }, 1053 { "run", "", do_run, "download file and execute it" }, 1054 { "flash", "", do_flash, "write file to device flash" }, 1055 { "erase", "", do_erase, "erase flash" }, 1056 { "reset", "", do_reset, "reset target" }, 1057 { "reset-stop", "", do_reset_stop, "reset target and halt cpu" }, 1058 { "reset-hw", "", do_reset_hw, "strobe /RESET pin" }, 1059 { "watch-pc", "", do_watch_pc, "set watchpoint at addr" }, 1060 { "watch-rw", "", do_watch_rw, "set watchpoint at addr" }, 1061 { "watch-off", "", do_watch_off, "disable watchpoint" }, 1062 { "log", "", do_log, "enable/disable logging" }, 1063 { "maskints", "", do_maskints, "enable/disable IRQ mask during step" }, 1064 { "print", "", do_print, "print numeric arguments" }, 1065 { "echo", "", do_echo, "echo command line" }, 1066 { "bootloader", "", do_bootloader, "reboot into bootloader" }, 1067 { "setclock", "", do_setclock, "set SWD clock rate (khz)" }, 1068 { "swoclock", "", do_swoclock, "set SWO clock rate (khz)" }, 1069 { "arch", "", do_setarch, "set architecture for flash agent" }, 1070 { "threads", "", do_threads, "thread dump" }, 1071 { "text", "", do_text, "dump text" }, 1072 { "wconsole", "", do_wconsole, "write to remote console" }, 1073 { "help", "", do_help, "help" }, 1074 { 0, 0, 0, 0 }, 1075 }; 1076