static bool cmd_jtag_scan(target *t, int argc, char **argv) { (void)t; uint8_t *irlens = NULL; gdb_outf("Target voltage: %s\n", platform_target_voltage()); if (argc > 1) { /* Accept a list of IR lengths on command line */ irlens = alloca(argc); for (int i = 1; i < argc; i++) irlens[i-1] = atoi(argv[i]); irlens[argc-1] = 0; } int devs = jtag_scan(irlens); if(devs < 0) { gdb_out("JTAG device scan failed!\n"); return false; } if(devs == 0) { gdb_out("JTAG scan found no devices!\n"); return false; } gdb_outf("Device IR Len IDCODE Description\n"); for(int i = 0; i < jtag_dev_count; i++) gdb_outf("%d\t%d\t0x%08lX %s\n", i, jtag_devs[i].ir_len, jtag_devs[i].idcode, jtag_devs[i].descr); gdb_out("\n"); cmd_targets(NULL); return true; }
static bool cmd_traceswo(void) { extern char serial_no[9]; traceswo_init(); gdb_outf("%s:%02X:%02X\n", serial_no, 5, 0x85); return true; }
static bool stm32f4_cmd_erase_mass(target *t) { const char spinner[] = "|/-\\"; int spinindex = 0; gdb_out("Erasing flash... This may take a few seconds. "); stm32f4_flash_unlock(t); /* Flash mass erase start instruction */ target_mem_write32(t, FLASH_CR, FLASH_CR_MER); target_mem_write32(t, FLASH_CR, FLASH_CR_STRT | FLASH_CR_MER); /* Read FLASH_SR to poll for BSY bit */ while (target_mem_read32(t, FLASH_SR) & FLASH_SR_BSY) { gdb_outf("\b%c", spinner[spinindex++ % 4]); if(target_check_error(t)) { gdb_out("\n"); return false; } } gdb_out("\n"); /* Check for error */ uint16_t sr = target_mem_read32(t, FLASH_SR); if ((sr & SR_ERROR_MASK) || !(sr & SR_EOP)) return false; return true; }
static bool nrf51_cmd_read_hwid(target *t) { uint32_t hwid = target_mem_read32(t, NRF51_FICR_CONFIGID) & 0xFFFF; gdb_outf("Hardware ID: 0x%04X\n", hwid); return true; }
static bool stm32f4_cmd_option(target *t, int argc, char *argv[]) { uint32_t start, val; int len; if (t->idcode == 0x449) { start = 0x1FFF0000; len = 0x20; } else { start = 0x1FFFC000; len = 0x10; } if ((argc == 2) && !strcmp(argv[1], "erase")) { stm32f4_option_write(t, 0x0fffaaed); } else if ((argc == 3) && !strcmp(argv[1], "write")) { val = strtoul(argv[2], NULL, 0); stm32f4_option_write(t, val); } else { gdb_out("usage: monitor option erase\n"); gdb_out("usage: monitor option write <value>\n"); } for (int i = 0; i < len; i += 8) { uint32_t addr = start + i; val = target_mem_read32(t, addr); gdb_outf("0x%08X: 0x%04X\n", addr, val & 0xFFFF); } return true; }
bool cmd_version(void) { gdb_outf("Black Magic Probe (Firmware " FIRMWARE_VERSION ") (Hardware Version %d)\n", platform_hwversion()); gdb_out("Copyright (C) 2015 Black Sphere Technologies Ltd.\n"); gdb_out("License GPLv3+: GNU GPL version 3 or later " "<http://gnu.org/licenses/gpl.html>\n\n"); return true; }
bool cmd_help(target *t) { struct target_command_s *tc; const struct command_s *c; gdb_out("General commands:\n"); for(c = cmd_list; c->cmd; c++) gdb_outf("\t%s -- %s\n", c->cmd, c->help); if (!t) return -1; for (tc = t->commands; tc; tc = tc->next) { gdb_outf("%s specific commands:\n", tc->specific_name); for(c = tc->cmds; c->cmd; c++) gdb_outf("\t%s -- %s\n", c->cmd, c->help); } return true; }
static bool stm32f1_cmd_option(target *t, int argc, char *argv[]) { uint32_t addr, val; uint32_t flash_obp_rdp_key; ADIv5_AP_t *ap = adiv5_target_ap(t); uint32_t rdprt; switch(t->idcode) { case 0x422: /* STM32F30x */ case 0x432: /* STM32F37x */ case 0x440: /* STM32F0 */ flash_obp_rdp_key = FLASH_OBP_RDP_KEY_F3; break; default: flash_obp_rdp_key = FLASH_OBP_RDP_KEY; } rdprt = (adiv5_ap_mem_read(ap, FLASH_OBR) & FLASH_OBR_RDPRT); stm32f1_flash_unlock(ap); adiv5_ap_mem_write(ap, FLASH_OPTKEYR, KEY1); adiv5_ap_mem_write(ap, FLASH_OPTKEYR, KEY2); if ((argc == 2) && !strcmp(argv[1], "erase")) { stm32f1_option_erase(t); stm32f1_option_write_erased(t, FLASH_OBP_RDP, flash_obp_rdp_key); } else if (rdprt) { gdb_out("Device is Read Protected\n"); gdb_out("Use \"monitor option erase\" to unprotect, erasing device\n"); return true; } else if (argc == 3) { addr = strtol(argv[1], NULL, 0); val = strtol(argv[2], NULL, 0); stm32f1_option_write(t, addr, val); } else { gdb_out("usage: monitor option erase\n"); gdb_out("usage: monitor option <addr> <value>\n"); } if (0 && flash_obp_rdp_key == FLASH_OBP_RDP_KEY_F3) { /* Reload option bytes on F0 and F3*/ val = adiv5_ap_mem_read(ap, FLASH_CR); val |= FLASH_CR_OBL_LAUNCH; stm32f1_option_write(t, FLASH_CR, val); val &= ~FLASH_CR_OBL_LAUNCH; stm32f1_option_write(t, FLASH_CR, val); } for (int i = 0; i < 0xf; i += 4) { addr = 0x1ffff800 + i; val = adiv5_ap_mem_read(ap, addr); gdb_outf("0x%08X: 0x%04X\n", addr, val & 0xFFFF); gdb_outf("0x%08X: 0x%04X\n", addr + 2, val >> 16); } return true; }
bool cmd_swdp_scan(void) { gdb_outf("Target voltage: %s\n", platform_target_voltage()); if(adiv5_swdp_scan() < 0) { gdb_out("SW-DP scan failed!\n"); return false; } //gdb_outf("SW-DP detected IDCODE: 0x%08X\n", adiv5_dp_list->idcode); cmd_targets(NULL); return true; }
bool cmd_help(target *t) { const struct command_s *c; gdb_out("General commands:\n"); for(c = cmd_list; c->cmd; c++) gdb_outf("\t%s -- %s\n", c->cmd, c->help); if (!t) return -1; target_command_help(t); return true; }
bool cmd_targets(target *cur_target) { struct target_s *t; int i; if(!target_list) { gdb_out("No usable targets found.\n"); return false; } gdb_out("Available Targets:\n"); gdb_out("No. Att Driver\n"); for(t = target_list, i = 1; t; t = t->next, i++) gdb_outf("%2d %c %s\n", i, t==cur_target?'*':' ', t->driver); return true; }
static bool cmd_jtag_scan(target *t, int argc, char **argv) { (void)t; uint8_t irlens[argc]; gdb_outf("Target voltage: %s\n", platform_target_voltage()); if (argc > 1) { /* Accept a list of IR lengths on command line */ for (int i = 1; i < argc; i++) irlens[i-1] = atoi(argv[i]); irlens[argc-1] = 0; } if(connect_assert_srst) platform_srst_set_val(true); /* will be deasserted after attach */ int devs = -1; volatile struct exception e; TRY_CATCH (e, EXCEPTION_ALL) { devs = jtag_scan(argc > 1 ? irlens : NULL); }
bool cmd_morse(void) { if(morse_msg) gdb_outf("%s\n", morse_msg); return true; }
bool stm32f1_probe(target *t) { size_t flash_size; size_t block_size = 0x400; t->idcode = target_mem_read32(t, DBGMCU_IDCODE) & 0xfff; switch(t->idcode) { case 0x410: /* Medium density */ case 0x412: /* Low denisty */ case 0x420: /* Value Line, Low-/Medium density */ t->driver = "STM32F1 medium density"; target_add_ram(t, 0x20000000, 0x5000); stm32f1_add_flash(t, 0x8000000, 0x20000, 0x400); target_add_commands(t, stm32f1_cmd_list, "STM32 LD/MD"); return true; case 0x414: /* High density */ case 0x418: /* Connectivity Line */ case 0x428: /* Value Line, High Density */ t->driver = "STM32F1 high density"; target_add_ram(t, 0x20000000, 0x10000); stm32f1_add_flash(t, 0x8000000, 0x80000, 0x800); target_add_commands(t, stm32f1_cmd_list, "STM32 HD/CL"); return true; case 0x422: /* STM32F30x */ case 0x432: /* STM32F37x */ t->driver = "STM32F3"; target_add_ram(t, 0x20000000, 0x10000); stm32f1_add_flash(t, 0x8000000, 0x80000, 0x800); target_add_commands(t, stm32f1_cmd_list, "STM32F3"); return true; } t->idcode = target_mem_read32(t, DBGMCU_IDCODE_F0) & 0xfff; switch(t->idcode) { case 0x444: /* STM32F03 RM0091 Rev.7 */ t->driver = "STM32F03"; break; case 0x445: /* STM32F04 RM0091 Rev.7 */ t->driver = "STM32F04"; break; case 0x440: /* STM32F05 RM0091 Rev.7 */ t->driver = "STM32F05"; break; case 0x448: /* STM32F07 RM0091 Rev.7 */ t->driver = "STM32F07"; block_size = 0x800; break; case 0x442: /* STM32F09 RM0091 Rev.7 */ t->driver = "STM32F09"; block_size = 0x800; break; default: /* NONE */ return false; } flash_size = (target_mem_read32(t, FLASHSIZE_F0) & 0xffff) *0x400; gdb_outf("flash size %d block_size %d\n", flash_size, block_size); target_add_ram(t, 0x20000000, 0x5000); stm32f1_add_flash(t, 0x8000000, flash_size, block_size); target_add_commands(t, stm32f1_cmd_list, "STM32F0"); return true; }