void target_command_help(target *t) { for (struct target_command_s *tc = t->commands; tc; tc = tc->next) { tc_printf(t, "%s specific commands:\n", tc->specific_name); for(const struct command_s *c = tc->cmds; c->cmd; c++) tc_printf(t, "\t%s -- %s\n", c->cmd, c->help); } }
static bool stm32f1_cmd_option(target *t, int argc, char *argv[]) { uint32_t addr, val; uint32_t flash_obp_rdp_key; uint32_t rdprt; switch(t->idcode) { case 0x422: /* STM32F30x */ case 0x432: /* STM32F37x */ case 0x438: /* STM32F303x6/8 and STM32F328 */ case 0x440: /* STM32F0 */ case 0x446: /* STM32F303xD/E and STM32F398xE */ flash_obp_rdp_key = FLASH_OBP_RDP_KEY_F3; break; default: flash_obp_rdp_key = FLASH_OBP_RDP_KEY; } rdprt = target_mem_read32(t, FLASH_OBR) & FLASH_OBR_RDPRT; stm32f1_flash_unlock(t); target_mem_write32(t, FLASH_OPTKEYR, KEY1); target_mem_write32(t, 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) { tc_printf(t, "Device is Read Protected\n"); tc_printf(t, "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 { tc_printf(t, "usage: monitor option erase\n"); tc_printf(t, "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 = target_mem_read32(t, 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 = target_mem_read32(t, addr); tc_printf(t, "0x%08X: 0x%04X\n", addr, val & 0xFFFF); tc_printf(t, "0x%08X: 0x%04X\n", addr + 2, val >> 16); } return true; }
static bool msp432_cmd_sector_erase(target *t, int argc, char *argv[]) { if (argc < 2) tc_printf(t, "usage: monitor sector_erase <addr>\n"); uint32_t addr = strtoul(argv[1], NULL, 0); /* Find the flash structure (for the rigth protect register) */ struct target_flash *f = get_target_flash(t, addr); if (f) return msp432_sector_erase(f, addr); tc_printf(t, "Invalid sector address\n"); return false; }
static bool nrf51_cmd_read_hwid(target *t) { uint32_t hwid = target_mem_read32(t, NRF51_FICR_CONFIGID) & 0xFFFF; tc_printf(t, "Hardware ID: 0x%04X\n", hwid); return true; }
static int tc_motdof(char *r) { if (strcmp(r, TC_ERRCMD) != 0) tc_printf("%s", r); return 0; }
int tc_query_printer(struct tnt_reply *r, void *ptr, char **e) { (void)ptr; (void)e; tc_printf("%s OK, %d rows affected\n", tc_query_op(r), r->count); tc_print_list(TNT_REPLY_LIST(r)); return 0; }
static bool sam3x_cmd_gpnvm_get(target *t) { uint32_t base = sam3x_flash_base(t); sam3x_flash_cmd(t, base, EEFC_FCR_FCMD_GGPB, 0); tc_printf(t, "GPNVM: 0x%08X\n", target_mem_read32(t, EEFC_FRR(base))); return true; }
static bool kinetis_cmd_unsafe(target *t, int argc, char *argv[]) { if (argc == 1) tc_printf(t, "Allow programming security byte: %s\n", unsafe_enabled ? "enabled" : "disabled"); else unsafe_enabled = argv[1][0] == 'e'; return true; }
static bool stm32l4_cmd_option(target *t, int argc, char *argv[]) { uint32_t addr, val; (void) argc; (void) argv; for (int i = 0; i < 0x23; i += 8) { addr = 0x1fff7800 + i; val = target_mem_read32(t, addr); tc_printf(t, "0x%08X: 0x%08x\n", addr, val); } for (int i = 8; i < 0x23; i += 8) { addr = 0x1ffff800 + i; val = target_mem_read32(t, addr); tc_printf(t, "0x%08X: 0x%08X\n", addr, val); } return true; }
/** * Reads the 40-bit unique number */ static bool efm32_cmd_serial(target *t) { /* Read the extended unique identifier */ uint64_t eui = efm32_read_eui(t); /* 64 bits of unique number */ tc_printf(t, "Unique Number: 0x%016llx\n", eui); return true; }
void tc_error(char *fmt, ...) { char msg[256]; va_list args; tc_shutdown(); va_start(args, fmt); vsnprintf(msg, sizeof(msg), fmt, args); va_end(args); tc_printf("error: %s\n", msg); exit(1); }
static bool sam3x_cmd_gpnvm_set(target *t, int argc, char *argv[]) { uint32_t bit, cmd; uint32_t base = sam3x_flash_base(t); if (argc != 3) { tc_printf(t, "usage: monitor gpnvm_set <bit> <val>\n"); return false; } bit = atol(argv[1]); cmd = atol(argv[2]) ? EEFC_FCR_FCMD_SGPB : EEFC_FCR_FCMD_CGPB; sam3x_flash_cmd(t, base, cmd, bit); sam3x_cmd_gpnvm_get(t); return true; }
static bool nrf51_cmd_erase_all(target *t) { tc_printf(t, "erase..\n"); /* Enable erase */ target_mem_write32(t, NRF51_NVMC_CONFIG, NRF51_NVMC_CONFIG_EEN); /* Poll for NVMC_READY */ while (target_mem_read32(t, NRF51_NVMC_READY) == 0) if(target_check_error(t)) return false; /* Erase all */ target_mem_write32(t, NRF51_NVMC_ERASEALL, 1); /* Poll for NVMC_READY */ while (target_mem_read32(t, NRF51_NVMC_READY) == 0) if(target_check_error(t)) return false; return true; }
/** * Uses the MSC ERASEMAIN0 command to erase the entire flash */ static bool efm32_cmd_erase_all(target *t) { /* Set WREN bit to enabel MSC write and erase functionality */ target_mem_write32(t, EFM32_MSC_WRITECTRL, 1); /* Unlock mass erase */ target_mem_write32(t, EFM32_MSC_MASSLOCK, EFM32_MSC_MASSLOCK_LOCKKEY); /* Erase operation */ target_mem_write32(t, EFM32_MSC_WRITECMD, EFM32_MSC_WRITECMD_ERASEMAIN0); /* Poll MSC Busy */ while ((target_mem_read32(t, EFM32_MSC_STATUS) & EFM32_MSC_STATUS_BUSY)) { if (target_check_error(t)) return false; } /* Relock mass erase */ target_mem_write32(t, EFM32_MSC_MASSLOCK, 0); tc_printf(t, "Erase successful!\n"); return true; }
static bool kinetis_mdm_cmd_erase_mass(target *t) { ADIv5_AP_t *ap = t->priv; uint32_t status, control; status = adiv5_ap_read(ap, MDM_STATUS); control = adiv5_ap_read(ap, MDM_CONTROL); tc_printf(t, "Requesting mass erase (status = 0x%"PRIx32")\n", status); if (!(status & MDM_STATUS_MASS_ERASE_ENABLED)) { tc_printf(t, "ERROR: Mass erase disabled!\n"); return false; } if (!(status & MDM_STATUS_FLASH_READY)) { tc_printf(t, "ERROR: Flash not ready!\n"); return false; } if (status & MDM_STATUS_MASS_ERASE_ACK) { tc_printf(t, "ERROR: Mass erase already in progress!\n"); return false; } adiv5_ap_write(ap, MDM_CONTROL, MDM_CONTROL_MASS_ERASE); do { status = adiv5_ap_read(ap, MDM_STATUS); } while (!(status & MDM_STATUS_MASS_ERASE_ACK)); tc_printf(t, "Mass erase acknowledged\n"); do { control = adiv5_ap_read(ap, MDM_CONTROL); } while (!(control & MDM_CONTROL_MASS_ERASE)); tc_printf(t, "Mass erase complete\n"); return true; }
static bool stm32f4_cmd_option(target *t, int argc, char *argv[]) { uint32_t start = 0x1FFFC000, val[3]; int count = 0, readcount = 1; switch (t->idcode) { case ID_STM32F72X: /* STM32F72|3 */ readcount++; /* fall through.*/ case ID_STM32F74X: case ID_STM32F76X: /* F7 Devices have option bytes at 0x1FFF0000. */ start = 0x1FFF0000; readcount++; break; case ID_STM32F42X: case ID_STM32F46X: readcount++; } if ((argc == 2) && !strcmp(argv[1], "erase")) { stm32f4_option_write_default(t); } else if ((argc > 1) && !strcmp(argv[1], "write")) { val[0] = strtoul(argv[2], NULL, 0); count++; if (argc > 2) { val[1] = strtoul(argv[3], NULL, 0); count ++; } if (argc > 3) { val[2] = strtoul(argv[4], NULL, 0); count ++; } if (optcr_mask(t, val)) stm32f4_option_write(t, val, count); else tc_printf(t, "error\n"); } else { tc_printf(t, "usage: monitor option erase\n"); tc_printf(t, "usage: monitor option write <OPTCR>"); if (readcount > 1) tc_printf(t, " <OPTCR1>"); if (readcount > 2) tc_printf(t, " <OPTCR2>"); tc_printf(t, "\n"); } val[0] = (target_mem_read32(t, start + 8) & 0xffff) << 16; val[0] |= (target_mem_read32(t, start ) & 0xffff); if (readcount > 1) { if (start == 0x1FFFC000) /* F4 */ { val[1] = target_mem_read32(t, start + 8 - 0x10000); val[1] &= 0xffff; } else { val[1] = (target_mem_read32(t, start + 0x18) & 0xffff) << 16; val[1] |= (target_mem_read32(t, start + 0x10) & 0xffff); } } if (readcount > 2) { val[2] = (target_mem_read32(t, start + 0x28) & 0xffff) << 16; val[2] |= (target_mem_read32(t, start + 0x20) & 0xffff); } optcr_mask(t, val); tc_printf(t, "OPTCR: 0x%08X ", val[0]); if (readcount > 1) tc_printf(t, "OPTCR1: 0x%08X ", val[1]); if (readcount > 2) tc_printf(t, "OPTCR2: 0x%08X" , val[2]); tc_printf(t, "\n"); return true; }
int tc_query_admin_printer(char *r, char **e) { (void)e; tc_printf("%s", r); return 0; }
bool efm32_probe(target *t) { /* Read the IDCODE register from the SW-DP */ ADIv5_AP_t *ap = cortexm_ap(t); uint32_t ap_idcode = ap->dp->idcode; /* Check the idcode is silabs. See AN0062 Section 2.2 */ if (ap_idcode == 0x2BA01477) { /* Cortex M3, Cortex M4 */ } else if (ap_idcode == 0x0BC11477) { /* Cortex M0+ */ } else { return false; } /* Read the part number and family */ uint16_t part_number = efm32_read_part_number(t); uint8_t part_family = efm32_read_part_family(t); uint16_t radio_number, radio_number_short; /* optional, for ezr parts */ uint32_t flash_page_size; uint16_t flash_kb; switch(part_family) { case EFM32_DI_PART_FAMILY_GECKO: sprintf(variant_string, "EFM32 Gecko"); flash_page_size = 512; break; case EFM32_DI_PART_FAMILY_GIANT_GECKO: sprintf(variant_string, "EFM32 Giant Gecko"); flash_page_size = 2048; /* Could be 2048 or 4096, assume 2048 */ break; case EFM32_DI_PART_FAMILY_TINY_GECKO: sprintf(variant_string, "EFM32 Tiny Gecko"); flash_page_size = 512; break; case EFM32_DI_PART_FAMILY_LEOPARD_GECKO: sprintf(variant_string, "EFM32 Leopard Gecko"); flash_page_size = 2048; /* Could be 2048 or 4096, assume 2048 */ break; case EFM32_DI_PART_FAMILY_WONDER_GECKO: sprintf(variant_string, "EFM32 Wonder Gecko"); flash_page_size = 2048; break; case EFM32_DI_PART_FAMILY_ZERO_GECKO: sprintf(variant_string, "EFM32 Zero Gecko"); flash_page_size = 1024; break; case EFM32_DI_PART_FAMILY_HAPPY_GECKO: sprintf(variant_string, "EFM32 Happy Gecko"); flash_page_size = 1024; break; case EFM32_DI_PART_FAMILY_EZR_WONDER_GECKO: radio_number = efm32_read_radio_part_number(t); /* on-chip radio */ radio_number_short = radio_number % 100; flash_kb = efm32_read_flash_size(t); sprintf(variant_string, "EZR32WG%dF%dR%d (radio si%d)", part_number, flash_kb, radio_number_short, radio_number); flash_page_size = 2048; break; case EFM32_DI_PART_FAMILY_EZR_LEOPARD_GECKO: radio_number = efm32_read_radio_part_number(t); /* on-chip radio */ radio_number_short = radio_number % 100; flash_kb = efm32_read_flash_size(t); sprintf(variant_string, "EZR32LG%dF%dR%d (radio si%d)", part_number, flash_kb, radio_number_short, radio_number); flash_page_size = 2048; break; default: /* Unknown family */ return false; } /* Read memory sizes, convert to bytes */ uint32_t flash_size = efm32_read_flash_size(t) * 0x400; uint32_t ram_size = efm32_read_ram_size(t) * 0x400; /* Setup Target */ t->target_options |= CORTEXM_TOPT_INHIBIT_SRST; t->driver = variant_string; tc_printf(t, "flash size %d page size %d\n", flash_size, flash_page_size); target_add_ram (t, SRAM_BASE, ram_size); efm32_add_flash(t, 0x00000000, flash_size, flash_page_size); target_add_commands(t, efm32_cmd_list, "EFM32"); 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 */ case 0x439: /* STM32F302C8 */ 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; tc_printf(t, "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; }