From fc3abf26ef07b40398aecfcb0544278895caad54 Mon Sep 17 00:00:00 2001 From: Uwe Bonnes Date: Fri, 27 Sep 2019 12:31:08 +0200 Subject: [PATCH 1/5] stm32_mem: Fix native crashing in dfu-detach when repeatedly flashed. --- scripts/stm32_mem.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/scripts/stm32_mem.py b/scripts/stm32_mem.py index a9695d39..1c8495ae 100755 --- a/scripts/stm32_mem.py +++ b/scripts/stm32_mem.py @@ -174,7 +174,10 @@ if __name__ == "__main__": print("Failed to read device state! Assuming APP_IDLE") state = dfu.STATE_APP_IDLE if state == dfu.STATE_APP_IDLE: - dfudev.detach() + try: + dfudev.detach() + except: + pass dfudev.release() print("Invoking DFU Device") timeout = 0 From f010a567bd1617feac89cc3a568196870d89f72b Mon Sep 17 00:00:00 2001 From: Uwe Bonnes Date: Fri, 27 Sep 2019 12:44:07 +0200 Subject: [PATCH 2/5] adiv5: Reject APs duplicating last AP. Seen with TM4C129 on black MSP432R401 Launchpad. Scanning of APs is aborted, so valid APs after duplicated APs are ignored. --- src/target/adiv5.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/target/adiv5.c b/src/target/adiv5.c index 54d633b4..f56ce0cf 100644 --- a/src/target/adiv5.c +++ b/src/target/adiv5.c @@ -485,6 +485,7 @@ void adiv5_dp_init(ADIv5_DP_t *dp) DEBUG("TARGETID %08" PRIx32 "\n", dp->targetid); } /* Probe for APs on this DP */ + uint32_t last_base = 0; for(int i = 0; i < 256; i++) { ADIv5_AP_t *ap = NULL; if (adiv5_ap_setup(i)) @@ -496,6 +497,13 @@ void adiv5_dp_init(ADIv5_DP_t *dp) else continue; } + if (ap->base == last_base) { + DEBUG("AP %d: Duplicate base\n", i); + adiv5_ap_cleanup(i); + /* FIXME: Should we expect valid APs behind duplicate ones? */ + return; + } + last_base = ap->base; extern void kinetis_mdm_probe(ADIv5_AP_t *); kinetis_mdm_probe(ap); From 1cf0b8ac1336d4bf46c475e64a0110447731e245 Mon Sep 17 00:00:00 2001 From: Uwe Bonnes Date: Fri, 27 Sep 2019 14:02:18 +0200 Subject: [PATCH 3/5] Make all arguments for all commands (struct *t, int argc, const char **argv). -Wall on gcc8 otherwise warns without -Wno-cast-function-type but older GCCs/CLang choke on that argument: error: unknown warning option '-Wno-cast-function-type'; did you mean '-Wno-bad-function-cast'? [-Werror,-Wunknown-warning-option] This adds 24 byte to the binary, as some functions are now called with additional dummy arguments: "Pushing and popping garbage to keep the system happy" --- src/Makefile | 2 +- src/command.c | 45 +++++++++++----- src/platforms/libftdi/Makefile.inc | 1 - src/platforms/pc-stlinkv2/Makefile.inc | 1 - src/target/efm32.c | 18 ++++--- src/target/kinetis.c | 12 +++-- src/target/msp432.c | 10 ++-- src/target/nrf51.c | 54 +++++++++++++------- src/target/sam3x.c | 12 +++-- src/target/samd.c | 71 ++++++++++++++++---------- src/target/stm32f1.c | 10 ++-- src/target/stm32f4.c | 6 ++- src/target/stm32h7.c | 26 +++++++--- src/target/stm32l4.c | 18 ++++--- 14 files changed, 185 insertions(+), 101 deletions(-) diff --git a/src/Makefile b/src/Makefile index 71e5bac2..7a76aca3 100644 --- a/src/Makefile +++ b/src/Makefile @@ -8,7 +8,7 @@ MAKEFLAGS += --no-print-dir Q := @ endif -CFLAGS += -Wall -Wextra -Werror -Wno-char-subscripts -Wno-cast-function-type \ +CFLAGS += -Wall -Wextra -Werror -Wno-char-subscripts \ -std=gnu99 -g3 -MD \ -I. -Iinclude -Iplatforms/common -I$(PLATFORM_DIR) diff --git a/src/command.c b/src/command.c index 52eb5d8c..29d2e0fc 100644 --- a/src/command.c +++ b/src/command.c @@ -43,16 +43,16 @@ struct command_s { const char *help; }; -static bool cmd_version(void); -static bool cmd_help(target *t); +static bool cmd_version(target *t, int argc, char **argv); +static bool cmd_help(target *t, int argc, char **argv); static bool cmd_jtag_scan(target *t, int argc, char **argv); -static bool cmd_swdp_scan(void); -static bool cmd_targets(void); -static bool cmd_morse(void); +static bool cmd_swdp_scan(target *t, int argc, char **argv); +static bool cmd_targets(target *t, int argc, char **argv); +static bool cmd_morse(target *t, int argc, char **argv); static bool cmd_halt_timeout(target *t, int argc, const char **argv); static bool cmd_connect_srst(target *t, int argc, const char **argv); -static bool cmd_hard_srst(void); +static bool cmd_hard_srst(target *t, int argc, const char **argv); #ifdef PLATFORM_HAS_POWER_SWITCH static bool cmd_target_power(target *t, int argc, const char **argv); #endif @@ -122,8 +122,11 @@ int command_process(target *t, char *cmd) return target_command(t, argc, argv); } -bool cmd_version(void) +bool cmd_version(target *t, int argc, char **argv) { + (void)t; + (void)argc; + (void)argv; #if defined PC_HOSTED gdb_outf("Black Magic Probe, PC-Hosted for " PLATFORM_IDENT ", Version " FIRMWARE_VERSION "\n"); @@ -137,8 +140,10 @@ bool cmd_version(void) return true; } -bool cmd_help(target *t) +bool cmd_help(target *t, int argc, char **argv) { + (void)argc; + (void)argv; const struct command_s *c; gdb_out("General commands:\n"); @@ -189,13 +194,16 @@ static bool cmd_jtag_scan(target *t, int argc, char **argv) gdb_out("JTAG device scan failed!\n"); return false; } - cmd_targets(); + cmd_targets(NULL, 0, NULL); morse(NULL, false); return true; } -bool cmd_swdp_scan(void) +bool cmd_swdp_scan(target *t, int argc, char **argv) { + (void)t; + (void)argc; + (void)argv; gdb_outf("Target voltage: %s\n", platform_target_voltage()); if(connect_assert_srst) @@ -221,7 +229,7 @@ bool cmd_swdp_scan(void) return false; } - cmd_targets(); + cmd_targets(NULL, 0, NULL); morse(NULL, false); return true; @@ -235,8 +243,11 @@ static void display_target(int i, target *t, void *context) (target_core_name(t)) ? target_core_name(t): ""); } -bool cmd_targets(void) +bool cmd_targets(target *t, int argc, char **argv) { + (void)t; + (void)argc; + (void)argv; gdb_out("Available Targets:\n"); gdb_out("No. Att Driver\n"); if (!target_foreach(display_target, NULL)) { @@ -247,8 +258,11 @@ bool cmd_targets(void) return true; } -bool cmd_morse(void) +bool cmd_morse(target *t, int argc, char **argv) { + (void)t; + (void)argc; + (void)argv; if(morse_msg) gdb_outf("%s\n", morse_msg); return true; @@ -301,8 +315,11 @@ static bool cmd_halt_timeout(target *t, int argc, const char **argv) return true; } -static bool cmd_hard_srst(void) +static bool cmd_hard_srst(target *t, int argc, const char **argv) { + (void)t; + (void)argc; + (void)argv; target_list_free(); platform_srst_set_val(true); platform_srst_set_val(false); diff --git a/src/platforms/libftdi/Makefile.inc b/src/platforms/libftdi/Makefile.inc index 0ddabe89..b890e860 100644 --- a/src/platforms/libftdi/Makefile.inc +++ b/src/platforms/libftdi/Makefile.inc @@ -3,7 +3,6 @@ CFLAGS += -DPC_HOSTED -DNO_LIBOPENCM3 -DENABLE_DEBUG LDFLAGS += -lftdi1 ifneq (, $(findstring mingw, $(SYS))) LDFLAGS += -lusb-1.0 -lws2_32 -CFLAGS += -Wno-cast-function-type else ifneq (, $(findstring cygwin, $(SYS))) LDFLAGS += -lusb-1.0 -lws2_32 endif diff --git a/src/platforms/pc-stlinkv2/Makefile.inc b/src/platforms/pc-stlinkv2/Makefile.inc index 8762885d..25fde894 100644 --- a/src/platforms/pc-stlinkv2/Makefile.inc +++ b/src/platforms/pc-stlinkv2/Makefile.inc @@ -5,7 +5,6 @@ CFLAGS +=-I ./target LDFLAGS += -lusb-1.0 ifneq (, $(findstring mingw, $(SYS))) LDFLAGS += -lws2_32 -CFLAGS += -Wno-cast-function-type else ifneq (, $(findstring cygwin, $(SYS))) LDFLAGS += -lws2_32 endif diff --git a/src/target/efm32.c b/src/target/efm32.c index 4405d99a..6bd114e5 100644 --- a/src/target/efm32.c +++ b/src/target/efm32.c @@ -53,9 +53,9 @@ static const uint16_t efm32_flash_write_stub[] = { #include "flashstub/efm32.stub" }; -static bool efm32_cmd_erase_all(target *t); -static bool efm32_cmd_serial(target *t); -static bool efm32_cmd_efm_info(target *t); +static bool efm32_cmd_erase_all(target *t, int argc, const char **argv); +static bool efm32_cmd_serial(target *t, int argc, const char **argv); +static bool efm32_cmd_efm_info(target *t, int argc, const char **argv); const struct command_s efm32_cmd_list[] = { {"erase_mass", (cmd_handler)efm32_cmd_erase_all, "Erase entire flash memory"}, @@ -698,8 +698,10 @@ static int efm32_flash_write(struct target_flash *f, /** * Uses the MSC ERASEMAIN0 command to erase the entire flash */ -static bool efm32_cmd_erase_all(target *t) +static bool efm32_cmd_erase_all(target *t, int argc, const char **argv) { + (void)argc; + (void)argv; efm32_device_t const* device = efm32_get_device(t->driver[2] - 32); if (device == NULL) { return true; @@ -732,8 +734,10 @@ static bool efm32_cmd_erase_all(target *t) /** * Reads the 40-bit unique number */ -static bool efm32_cmd_serial(target *t) +static bool efm32_cmd_serial(target *t, int argc, const char **argv) { + (void)argc; + (void)argv; uint64_t unique = 0; uint8_t di_version = t->driver[0] - 48; /* di version hidden in driver str */ @@ -755,8 +759,10 @@ static bool efm32_cmd_serial(target *t) /** * Prints various information we know about the device */ -static bool efm32_cmd_efm_info(target *t) +static bool efm32_cmd_efm_info(target *t, int argc, const char **argv) { + (void)argc; + (void)argv; uint8_t di_version = t->driver[0] - 48; /* hidden in driver str */ switch (di_version) { diff --git a/src/target/kinetis.c b/src/target/kinetis.c index 6820f379..e0b1530b 100644 --- a/src/target/kinetis.c +++ b/src/target/kinetis.c @@ -343,8 +343,8 @@ static int kl_gen_flash_done(struct target_flash *f) #define KINETIS_MDM_IDR_K22F 0x1c0000 #define KINETIS_MDM_IDR_KZ03 0x1c0020 -static bool kinetis_mdm_cmd_erase_mass(target *t); -static bool kinetis_mdm_cmd_ke04_mode(target *t); +static bool kinetis_mdm_cmd_erase_mass(target *t, int argc, const char **argv); +static bool kinetis_mdm_cmd_ke04_mode(target *t, int argc, const char **argv); const struct command_s kinetis_mdm_cmd_list[] = { {"erase_mass", (cmd_handler)kinetis_mdm_cmd_erase_mass, "Erase entire flash memory"}, @@ -395,15 +395,19 @@ void kinetis_mdm_probe(ADIv5_AP_t *ap) /* This is needed as a separate command, as there's no way to * * tell a KE04 from other kinetis in kinetis_mdm_probe() */ static bool ke04_mode = false; -static bool kinetis_mdm_cmd_ke04_mode(target *t) +static bool kinetis_mdm_cmd_ke04_mode(target *t, int argc, const char **argv) { + (void)argc; + (void)argv; /* Set a flag to ignore part of the status and assert reset */ ke04_mode = true; tc_printf(t, "Mass erase for KE04 now allowed\n"); return true; } -static bool kinetis_mdm_cmd_erase_mass(target *t) +static bool kinetis_mdm_cmd_erase_mass(target *t, int argc, const char **argv) { + (void)argc; + (void)argv; ADIv5_AP_t *ap = t->priv; /* Keep the MCU in reset as stated in KL25PxxM48SF0RM */ diff --git a/src/target/msp432.c b/src/target/msp432.c index 96acfed2..f1b3eb37 100644 --- a/src/target/msp432.c +++ b/src/target/msp432.c @@ -135,9 +135,9 @@ static inline uint32_t msp432_sector_unprotect(struct msp432_flash *mf, target_a /* Optional commands handlers */ /* Erase all of main flash */ -static bool msp432_cmd_erase_main(target *t); +static bool msp432_cmd_erase_main(target *t, int argc, const char **argv); /* Erase a single (4KB) sector */ -static bool msp432_cmd_sector_erase(target *t, int argc, char *argv[]); +static bool msp432_cmd_sector_erase(target *t, int argc, const char **argv); /* Optional commands structure*/ const struct command_s msp432_cmd_list[] = { @@ -308,8 +308,10 @@ static int msp432_flash_write(struct target_flash *f, target_addr dest, } /* Optional commands handlers */ -static bool msp432_cmd_erase_main(target *t) +static bool msp432_cmd_erase_main(target *t, int argc, const char **argv) { + (void)argc; + (void)argv; /* The mass erase routine in ROM will also erase the Info Flash. */ /* Usually, this is not wanted, so go sector by sector... */ @@ -327,7 +329,7 @@ static bool msp432_cmd_erase_main(target *t) return ret; } -static bool msp432_cmd_sector_erase(target *t, int argc, char *argv[]) +static bool msp432_cmd_sector_erase(target *t, int argc, const char **argv) { if (argc < 2) tc_printf(t, "usage: monitor sector_erase \n"); diff --git a/src/target/nrf51.c b/src/target/nrf51.c index 5f105d8c..3b004244 100644 --- a/src/target/nrf51.c +++ b/src/target/nrf51.c @@ -30,14 +30,14 @@ static int nrf51_flash_erase(struct target_flash *f, target_addr addr, size_t le static int nrf51_flash_write(struct target_flash *f, target_addr dest, const void *src, size_t len); -static bool nrf51_cmd_erase_all(target *t); -static bool nrf51_cmd_read_hwid(target *t); -static bool nrf51_cmd_read_fwid(target *t); -static bool nrf51_cmd_read_deviceid(target *t); -static bool nrf51_cmd_read_deviceaddr(target *t); -static bool nrf51_cmd_read_deviceinfo(target *t); -static bool nrf51_cmd_read_help(target *t); -static bool nrf51_cmd_read(target *t, int argc, const char *argv[]); +static bool nrf51_cmd_erase_all(target *t, int argc, const char **argv); +static bool nrf51_cmd_read_hwid(target *t, int argc, const char **argv); +static bool nrf51_cmd_read_fwid(target *t, int argc, const char **argv); +static bool nrf51_cmd_read_deviceid(target *t, int argc, const char **argv); +static bool nrf51_cmd_read_deviceaddr(target *t, int argc, const char **argv); +static bool nrf51_cmd_read_deviceinfo(target *t, int argc, const char **argv); +static bool nrf51_cmd_read_help(target *t, int argc, const char **argv); +static bool nrf51_cmd_read(target *t, int argc, const char **argv); const struct command_s nrf51_cmd_list[] = { {"erase_mass", (cmd_handler)nrf51_cmd_erase_all, "Erase entire flash memory"}, @@ -215,8 +215,10 @@ static int nrf51_flash_write(struct target_flash *f, return 0; } -static bool nrf51_cmd_erase_all(target *t) +static bool nrf51_cmd_erase_all(target *t, int argc, const char **argv) { + (void)argc; + (void)argv; tc_printf(t, "erase..\n"); /* Enable erase */ @@ -238,22 +240,28 @@ static bool nrf51_cmd_erase_all(target *t) return true; } -static bool nrf51_cmd_read_hwid(target *t) +static bool nrf51_cmd_read_hwid(target *t, int argc, const char **argv) { + (void)argc; + (void)argv; uint32_t hwid = target_mem_read32(t, NRF51_FICR_CONFIGID) & 0xFFFF; tc_printf(t, "Hardware ID: 0x%04X\n", hwid); return true; } -static bool nrf51_cmd_read_fwid(target *t) +static bool nrf51_cmd_read_fwid(target *t, int argc, const char **argv) { + (void)argc; + (void)argv; uint32_t fwid = (target_mem_read32(t, NRF51_FICR_CONFIGID) >> 16) & 0xFFFF; tc_printf(t, "Firmware ID: 0x%04X\n", fwid); return true; } -static bool nrf51_cmd_read_deviceid(target *t) +static bool nrf51_cmd_read_deviceid(target *t, int argc, const char **argv) { + (void)argc; + (void)argv; uint32_t deviceid_low = target_mem_read32(t, NRF51_FICR_DEVICEID_LOW); uint32_t deviceid_high = target_mem_read32(t, NRF51_FICR_DEVICEID_HIGH); @@ -262,8 +270,10 @@ static bool nrf51_cmd_read_deviceid(target *t) return true; } -static bool nrf51_cmd_read_deviceinfo(target *t) +static bool nrf51_cmd_read_deviceinfo(target *t, int argc, const char **argv) { + (void)argc; + (void)argv; struct deviceinfo{ uint32_t part; union{ @@ -311,8 +321,10 @@ static bool nrf51_cmd_read_deviceinfo(target *t) return true; } -static bool nrf51_cmd_read_deviceaddr(target *t) +static bool nrf51_cmd_read_deviceaddr(target *t, int argc, const char **argv) { + (void)argc; + (void)argv; uint32_t addr_type = target_mem_read32(t, NRF51_FICR_DEVICEADDRTYPE); uint32_t addr_low = target_mem_read32(t, NRF51_FICR_DEVICEADDR_LOW); uint32_t addr_high = target_mem_read32(t, NRF51_FICR_DEVICEADDR_HIGH) & 0xFFFF; @@ -325,8 +337,10 @@ static bool nrf51_cmd_read_deviceaddr(target *t) return true; } -static bool nrf51_cmd_read_help(target *t) +static bool nrf51_cmd_read_help(target *t, int argc, const char **argv) { + (void)argc; + (void)argv; const struct command_s *c; tc_printf(t, "Read commands:\n"); @@ -335,7 +349,7 @@ static bool nrf51_cmd_read_help(target *t) return true; } -static bool nrf51_cmd_read(target *t, int argc, const char *argv[]) +static bool nrf51_cmd_read(target *t, int argc, const char **argv) { const struct command_s *c; if (argc > 1) { @@ -347,13 +361,13 @@ static bool nrf51_cmd_read(target *t, int argc, const char *argv[]) return !c->handler(t, argc - 1, &argv[1]); } } - return nrf51_cmd_read_help(t); + return nrf51_cmd_read_help(t, 0, NULL); } #include "adiv5.h" #define NRF52_MDM_IDR 0x02880000 -static bool nrf51_mdm_cmd_erase_mass(target *t); +static bool nrf51_mdm_cmd_erase_mass(target *t, int argc, const char **argv); const struct command_s nrf51_mdm_cmd_list[] = { {"erase_mass", (cmd_handler)nrf51_mdm_cmd_erase_mass, "Erase entire flash memory"}, @@ -390,8 +404,10 @@ void nrf51_mdm_probe(ADIv5_AP_t *ap) #define MDM_PROT_EN ADIV5_AP_REG(0x0C) -static bool nrf51_mdm_cmd_erase_mass(target *t) +static bool nrf51_mdm_cmd_erase_mass(target *t, int argc, const char **argv) { + (void)argc; + (void)argv; ADIv5_AP_t *ap = t->priv; uint32_t status = adiv5_ap_read(ap, MDM_STATUS); diff --git a/src/target/sam3x.c b/src/target/sam3x.c index 4abea750..2dae6029 100644 --- a/src/target/sam3x.c +++ b/src/target/sam3x.c @@ -33,8 +33,8 @@ static int sam3_flash_erase(struct target_flash *f, target_addr addr, size_t len static int sam3x_flash_write(struct target_flash *f, target_addr dest, const void *src, size_t len); -static bool sam3x_cmd_gpnvm_get(target *t); -static bool sam3x_cmd_gpnvm_set(target *t, int argc, char *argv[]); +static bool sam3x_cmd_gpnvm_get(target *t, int argc, const char **argv); +static bool sam3x_cmd_gpnvm_set(target *t, int argc, const char **argv); const struct command_s sam3x_cmd_list[] = { {"gpnvm_get", (cmd_handler)sam3x_cmd_gpnvm_get, "Get GPVNM value"}, @@ -338,8 +338,10 @@ static int sam3x_flash_write(struct target_flash *f, target_addr dest, return 0; } -static bool sam3x_cmd_gpnvm_get(target *t) +static bool sam3x_cmd_gpnvm_get(target *t, int argc, const char **argv) { + (void)argc; + (void)argv; uint32_t base = sam3x_flash_base(t); sam3x_flash_cmd(t, base, EEFC_FCR_FCMD_GGPB, 0); @@ -348,7 +350,7 @@ static bool sam3x_cmd_gpnvm_get(target *t) return true; } -static bool sam3x_cmd_gpnvm_set(target *t, int argc, char *argv[]) +static bool sam3x_cmd_gpnvm_set(target *t, int argc, const char **argv) { uint32_t bit, cmd; uint32_t base = sam3x_flash_base(t); @@ -361,7 +363,7 @@ static bool sam3x_cmd_gpnvm_set(target *t, int argc, char *argv[]) cmd = atol(argv[2]) ? EEFC_FCR_FCMD_SGPB : EEFC_FCR_FCMD_CGPB; sam3x_flash_cmd(t, base, cmd, bit); - sam3x_cmd_gpnvm_get(t); + sam3x_cmd_gpnvm_get(t, 0, NULL); return true; } diff --git a/src/target/samd.c b/src/target/samd.c index 3117f2ae..f5d4282d 100644 --- a/src/target/samd.c +++ b/src/target/samd.c @@ -41,15 +41,15 @@ static int samd_flash_erase(struct target_flash *t, target_addr addr, size_t len static int samd_flash_write(struct target_flash *f, target_addr dest, const void *src, size_t len); -static bool samd_cmd_erase_all(target *t); -static bool samd_cmd_lock_flash(target *t); -static bool samd_cmd_unlock_flash(target *t); -static bool samd_cmd_unlock_bootprot(target *t); -static bool samd_cmd_lock_bootprot(target *t); -static bool samd_cmd_read_userrow(target *t); -static bool samd_cmd_serial(target *t); -static bool samd_cmd_mbist(target *t); -static bool samd_cmd_ssb(target *t); +static bool samd_cmd_erase_all(target *t, int argc, const char **argv); +static bool samd_cmd_lock_flash(target *t, int argc, const char **argv); +static bool samd_cmd_unlock_flash(target *t, int argc, const char **argv); +static bool samd_cmd_unlock_bootprot(target *t, int argc, const char **argv); +static bool samd_cmd_lock_bootprot(target *t, int argc, const char **argv); +static bool samd_cmd_read_userrow(target *t, int argc, const char **argv); +static bool samd_cmd_serial(target *t, int argc, const char **argv); +static bool samd_cmd_mbist(target *t, int argc, const char **argv); +static bool samd_cmd_ssb(target *t, int argc, const char **argv); const struct command_s samd_cmd_list[] = { {"erase_mass", (cmd_handler)samd_cmd_erase_all, "Erase entire flash memory"}, @@ -273,8 +273,7 @@ samd20_revB_halt_resume(target *t, bool step) * function allows users to attach on a temporary basis so they can * rescue the device. */ -static bool -samd_protected_attach(target *t) +static bool samd_protected_attach(target *t) { /** * TODO: Notify the user that we're not really attached and @@ -525,8 +524,10 @@ static int samd_flash_write(struct target_flash *f, /** * Uses the Device Service Unit to erase the entire flash */ -static bool samd_cmd_erase_all(target *t) +static bool samd_cmd_erase_all(target *t, int argc, const char **argv) { + (void)argc; + (void)argv; /* Clear the DSU status bits */ target_mem_write32(t, SAMD_DSU_CTRLSTAT, SAMD_STATUSA_DONE | SAMD_STATUSA_PERR | @@ -566,8 +567,9 @@ static bool samd_cmd_erase_all(target *t) * * 0x0000 = Lock, 0xFFFF = Unlock (default) */ -static bool samd_set_flashlock(target *t, uint16_t value) +static bool samd_set_flashlock(target *t, uint16_t value, const char **argv) { + (void)argv; uint32_t high = target_mem_read32(t, SAMD_NVM_USER_ROW_HIGH); uint32_t low = target_mem_read32(t, SAMD_NVM_USER_ROW_LOW); @@ -598,18 +600,23 @@ static bool samd_set_flashlock(target *t, uint16_t value) return true; } -static bool samd_cmd_lock_flash(target *t) +static bool samd_cmd_lock_flash(target *t, int argc, const char **argv) { - return samd_set_flashlock(t, 0x0000); + (void)argc; + (void)argv; + return samd_set_flashlock(t, 0x0000, NULL); } -static bool samd_cmd_unlock_flash(target *t) +static bool samd_cmd_unlock_flash(target *t, int argc, const char **argv) { - return samd_set_flashlock(t, 0xFFFF); + (void)argc; + (void)argv; + return samd_set_flashlock(t, 0xFFFF, NULL); } -static bool samd_set_bootprot(target *t, uint16_t value) +static bool samd_set_bootprot(target *t, uint16_t value, const char **argv) { + (void)argv; uint32_t high = target_mem_read32(t, SAMD_NVM_USER_ROW_HIGH); uint32_t low = target_mem_read32(t, SAMD_NVM_USER_ROW_LOW); @@ -640,18 +647,24 @@ static bool samd_set_bootprot(target *t, uint16_t value) return true; } -static bool samd_cmd_lock_bootprot(target *t) +static bool samd_cmd_lock_bootprot(target *t, int argc, const char **argv) { - return samd_set_bootprot(t, 0); + (void)argc; + (void)argv; + return samd_set_bootprot(t, 0, NULL); } -static bool samd_cmd_unlock_bootprot(target *t) +static bool samd_cmd_unlock_bootprot(target *t, int argc, const char **argv) { - return samd_set_bootprot(t, 7); + (void)argc; + (void)argv; + return samd_set_bootprot(t, 7, NULL); } -static bool samd_cmd_read_userrow(target *t) +static bool samd_cmd_read_userrow(target *t, int argc, const char **argv) { + (void)argc; + (void)argv; tc_printf(t, "User Row: 0x%08x%08x\n", target_mem_read32(t, SAMD_NVM_USER_ROW_HIGH), target_mem_read32(t, SAMD_NVM_USER_ROW_LOW)); @@ -662,8 +675,10 @@ static bool samd_cmd_read_userrow(target *t) /** * Reads the 128-bit serial number from the NVM */ -static bool samd_cmd_serial(target *t) +static bool samd_cmd_serial(target *t, int argc, const char **argv) { + (void)argc; + (void)argv; tc_printf(t, "Serial Number: 0x"); for (uint32_t i = 0; i < 4; i++) { @@ -693,8 +708,10 @@ static uint32_t samd_flash_size(target *t) /** * Runs the Memory Built In Self Test (MBIST) */ -static bool samd_cmd_mbist(target *t) +static bool samd_cmd_mbist(target *t, int argc, const char **argv) { + (void)argc; + (void)argv; /* Write the memory parameters to the DSU */ target_mem_write32(t, SAMD_DSU_ADDRESS, 0); target_mem_write32(t, SAMD_DSU_LENGTH, samd_flash_size(t)); @@ -731,8 +748,10 @@ static bool samd_cmd_mbist(target *t) /** * Sets the security bit */ -static bool samd_cmd_ssb(target *t) +static bool samd_cmd_ssb(target *t, int argc, const char **argv) { + (void)argc; + (void)argv; /* Issue the ssb command */ target_mem_write32(t, SAMD_NVMC_CTRLA, SAMD_CTRLA_CMD_KEY | SAMD_CTRLA_CMD_SSB); diff --git a/src/target/stm32f1.c b/src/target/stm32f1.c index 0719dd0a..0774257a 100644 --- a/src/target/stm32f1.c +++ b/src/target/stm32f1.c @@ -39,8 +39,8 @@ #include "target_internal.h" #include "cortexm.h" -static bool stm32f1_cmd_erase_mass(target *t); -static bool stm32f1_cmd_option(target *t, int argc, char *argv[]); +static bool stm32f1_cmd_erase_mass(target *t, int argc, const char **argv); +static bool stm32f1_cmd_option(target *t, int argc, const char **argv); const struct command_s stm32f1_cmd_list[] = { {"erase_mass", (cmd_handler)stm32f1_cmd_erase_mass, "Erase entire flash memory"}, @@ -249,8 +249,10 @@ static int stm32f1_flash_write(struct target_flash *f, return 0; } -static bool stm32f1_cmd_erase_mass(target *t) +static bool stm32f1_cmd_erase_mass(target *t, int argc, const char **argv) { + (void)argc; + (void)argv; stm32f1_flash_unlock(t); /* Flash mass erase start instruction */ @@ -326,7 +328,7 @@ static bool stm32f1_option_write(target *t, uint32_t addr, uint16_t value) return true; } -static bool stm32f1_cmd_option(target *t, int argc, char *argv[]) +static bool stm32f1_cmd_option(target *t, int argc, const char **argv) { uint32_t addr, val; uint32_t flash_obp_rdp_key; diff --git a/src/target/stm32f4.c b/src/target/stm32f4.c index 338cb10d..10b71023 100644 --- a/src/target/stm32f4.c +++ b/src/target/stm32f4.c @@ -37,7 +37,7 @@ #include "target_internal.h" #include "cortexm.h" -static bool stm32f4_cmd_erase_mass(target *t); +static bool stm32f4_cmd_erase_mass(target *t, int argc, const char **argv); static bool stm32f4_cmd_option(target *t, int argc, char *argv[]); static bool stm32f4_cmd_psize(target *t, int argc, char *argv[]); @@ -456,8 +456,10 @@ static int stm32f4_flash_write(struct target_flash *f, return 0; } -static bool stm32f4_cmd_erase_mass(target *t) +static bool stm32f4_cmd_erase_mass(target *t, int argc, const char **argv) { + (void)argc; + (void)argv; const char spinner[] = "|/-\\"; int spinindex = 0; struct target_flash *f = t->flash; diff --git a/src/target/stm32h7.c b/src/target/stm32h7.c index 15d9614d..f9e0ac1f 100644 --- a/src/target/stm32h7.c +++ b/src/target/stm32h7.c @@ -30,12 +30,12 @@ #include "target_internal.h" #include "cortexm.h" -static bool stm32h7_cmd_erase_mass(target *t); +static bool stm32h7_cmd_erase_mass(target *t, int argc, const char **argv); /* static bool stm32h7_cmd_option(target *t, int argc, char *argv[]); */ -static bool stm32h7_uid(target *t); -static bool stm32h7_crc(target *t); +static bool stm32h7_uid(target *t, int argc, const char **argv); +static bool stm32h7_crc(target *t, int argc, const char **argv); static bool stm32h7_cmd_psize(target *t, int argc, char *argv[]); -static bool stm32h7_cmd_rev(target *t); +static bool stm32h7_cmd_rev(target *t, int argc, const char **argv); const struct command_s stm32h7_cmd_list[] = { {"erase_mass", (cmd_handler)stm32h7_cmd_erase_mass, @@ -430,8 +430,10 @@ static bool stm32h7_cmd_erase(target *t, int bank_mask) return result; } -static bool stm32h7_cmd_erase_mass(target *t) +static bool stm32h7_cmd_erase_mass(target *t, int argc, const char **argv) { + (void)argc; + (void)argv; tc_printf(t, "Erasing flash... This may take a few seconds. "); return stm32h7_cmd_erase(t, 3); } @@ -439,8 +441,10 @@ static bool stm32h7_cmd_erase_mass(target *t) /* Print the Unique device ID. * Can be reused for other STM32 devices With uid as parameter. */ -static bool stm32h7_uid(target *t) +static bool stm32h7_uid(target *t, int argc, const char **argv) { + (void)argc; + (void)argv; uint32_t uid = 0x1ff1e800; int i; tc_printf(t, "0x"); @@ -483,8 +487,10 @@ static int stm32h7_crc_bank(target *t, uint32_t bank) return 0; } -static bool stm32h7_crc(target *t) +static bool stm32h7_crc(target *t, int argc, const char **argv) { + (void)argc; + (void)argv; if (stm32h7_crc_bank(t, BANK1_START) ) return false; uint32_t crc1 = target_mem_read32(t, FPEC1_BASE + FLASH_CRCDATA); if (stm32h7_crc_bank(t, BANK2_START) ) return false; @@ -494,6 +500,8 @@ static bool stm32h7_crc(target *t) } static bool stm32h7_cmd_psize(target *t, int argc, char *argv[]) { + (void)argc; + (void)argv; if (argc == 1) { enum align psize = ALIGN_DWORD; for (struct target_flash *f = t->flash; f; f = f->next) { @@ -538,8 +546,10 @@ static const struct stm32h7xx_rev { { 0x2001, 'X' }, { 0x2003, 'V' } }; -static bool stm32h7_cmd_rev(target *t) +static bool stm32h7_cmd_rev(target *t, int argc, const char **argv) { + (void)argc; + (void)argv; /* DBGMCU identity code register */ uint32_t dbgmcu_idc = target_mem_read32(t, DBGMCU_IDC); uint16_t rev_id = (dbgmcu_idc >> 16) & 0xFFFF; diff --git a/src/target/stm32l4.c b/src/target/stm32l4.c index 0a0a6d20..02375ff7 100644 --- a/src/target/stm32l4.c +++ b/src/target/stm32l4.c @@ -38,9 +38,9 @@ #include "target_internal.h" #include "cortexm.h" -static bool stm32l4_cmd_erase_mass(target *t); -static bool stm32l4_cmd_erase_bank1(target *t); -static bool stm32l4_cmd_erase_bank2(target *t); +static bool stm32l4_cmd_erase_mass(target *t, int argc, const char **argv); +static bool stm32l4_cmd_erase_bank1(target *t, int argc, const char **argv); +static bool stm32l4_cmd_erase_bank2(target *t, int argc, const char **argv); static bool stm32l4_cmd_option(target *t, int argc, char *argv[]); const struct command_s stm32l4_cmd_list[] = { @@ -484,18 +484,24 @@ static bool stm32l4_cmd_erase(target *t, uint32_t action) return true; } -static bool stm32l4_cmd_erase_mass(target *t) +static bool stm32l4_cmd_erase_mass(target *t, int argc, const char **argv) { + (void)argc; + (void)argv; return stm32l4_cmd_erase(t, FLASH_CR_MER1 | FLASH_CR_MER2); } -static bool stm32l4_cmd_erase_bank1(target *t) +static bool stm32l4_cmd_erase_bank1(target *t, int argc, const char **argv) { + (void)argc; + (void)argv; return stm32l4_cmd_erase(t, FLASH_CR_MER1); } -static bool stm32l4_cmd_erase_bank2(target *t) +static bool stm32l4_cmd_erase_bank2(target *t, int argc, const char **argv) { + (void)argc; + (void)argv; return stm32l4_cmd_erase(t, FLASH_CR_MER2); } From 0599d2161c61fe9b18eab25ebf5cf389f5b92f80 Mon Sep 17 00:00:00 2001 From: Uwe Bonnes Date: Fri, 27 Sep 2019 14:52:59 +0200 Subject: [PATCH 4/5] pc-stlinkv2: Recognize another error and try to handle failing memread. --- src/platforms/pc-stlinkv2/stlinkv2.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/platforms/pc-stlinkv2/stlinkv2.c b/src/platforms/pc-stlinkv2/stlinkv2.c index 86c7a1ec..a3ef5813 100644 --- a/src/platforms/pc-stlinkv2/stlinkv2.c +++ b/src/platforms/pc-stlinkv2/stlinkv2.c @@ -84,6 +84,7 @@ #define STLINK_SWD_AP_STICKY_ERROR 0x19 #define STLINK_SWD_AP_STICKYORUN_ERROR 0x1a #define STLINK_BAD_AP_ERROR 0x1d +#define STLINK_TOO_MANY_AP_ERROR 0x29 #define STLINK_JTAG_UNKNOWN_CMD 0x42 #define STLINK_CORE_RUNNING 0x80 @@ -502,6 +503,11 @@ static int stlink_usb_error_check(uint8_t *data, bool verbose) case STLINK_BAD_AP_ERROR: /* ADIV5 probe 256 APs, most of them are non exisitant.*/ return STLINK_ERROR_FAIL; + case STLINK_TOO_MANY_AP_ERROR: + /* TI TM4C duplicates AP. Error happens at AP9.*/ + if (verbose) + DEBUG("STLINK_TOO_MANY_AP_ERROR\n"); + return STLINK_ERROR_FAIL; case STLINK_JTAG_UNKNOWN_CMD : if (verbose) DEBUG("STLINK_JTAG_UNKNOWN_CMD\n"); @@ -1230,6 +1236,15 @@ void stlink_readmem(ADIv5_AP_t *ap, void *dest, uint32_t src, size_t len) for (size_t i = 0; i < len ; i++) { DEBUG_STLINK("%02x", *p++); } + } else { + /* FIXME: What is the right measure when failing? + * + * E.g. TM4C129 gets here when NRF probe reads 0x10000010 + * Approach taken: + * Fill the memory with some fixed pattern so hopefully + * the caller notices the error*/ + DEBUG("stlink_readmem failed\n"); + memset(dest, 0xff, len); } DEBUG_STLINK("\n"); } From 12a2659671665973670778bc11f56853d0f7236a Mon Sep 17 00:00:00 2001 From: Uwe Bonnes Date: Fri, 27 Sep 2019 17:25:00 +0200 Subject: [PATCH 5/5] pc-stlinkv2: StlinkV3 seems only to work with STM devices, --- src/platforms/pc-stlinkv2/README.md | 8 +++++--- src/platforms/pc-stlinkv2/stlinkv2.c | 13 ++++++++++--- 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/src/platforms/pc-stlinkv2/README.md b/src/platforms/pc-stlinkv2/README.md index 2d145ad0..ad2f78d8 100644 --- a/src/platforms/pc-stlinkv2/README.md +++ b/src/platforms/pc-stlinkv2/README.md @@ -5,11 +5,13 @@ functionality that BMP needs. This branch implements blackmagic debug probe for the STM Stlink as a proof of concept. Use at your own risk, but report or better fix problems. -Run the resulting blackmagic_stlinkv2 executabel to start the gdb server +Run the resulting blackmagic_stlinkv2 executable to start the gdb server -CrosscCompling for windows with mingw succeeds. +Crosscompling for windows with mingw succeeds. -Drawback: JTAG does not work for chains with multiple devices. +Drawback: +- JTAG does not work for chains with multiple devices. +- STLinkV3 does only work on STM32 devices. This branch may get forced push. In case of problems: - git reset --hard master diff --git a/src/platforms/pc-stlinkv2/stlinkv2.c b/src/platforms/pc-stlinkv2/stlinkv2.c index a3ef5813..0e1723bd 100644 --- a/src/platforms/pc-stlinkv2/stlinkv2.c +++ b/src/platforms/pc-stlinkv2/stlinkv2.c @@ -535,7 +535,7 @@ static int send_recv_retry(uint8_t *txbuf, size_t txsize, gettimeofday(&now, NULL); timersub(&now, &start, &diff); if ((diff.tv_sec >= 1) || (res != STLINK_ERROR_WAIT)) { - DEBUG("write_retry failed"); + DEBUG("write_retry failed. "); return res; } } @@ -558,7 +558,7 @@ static int read_retry(uint8_t *txbuf, size_t txsize, gettimeofday(&now, NULL); timersub(&now, &start, &diff); if ((diff.tv_sec >= 1) || (res != STLINK_ERROR_WAIT)) { - DEBUG("read_retry failed"); + DEBUG("read_retry failed. "); return res; } } @@ -1172,7 +1172,14 @@ bool adiv5_ap_setup(int ap) uint8_t data[2]; send_recv_retry(cmd, 16, data, 2); DEBUG_STLINK("Open AP %d\n", ap); - return (stlink_usb_error_check(data, true))? false: true; + int res = stlink_usb_error_check(data, true); + if (res) { + if (Stlink.ver_hw == 30) { + DEBUG("STLINKV3 only connects to STM8/32!\n"); + } + return false; + } + return true; } void adiv5_ap_cleanup(int ap)