From ceaee2a11ebd009dc678c85843525f48e5dae27f Mon Sep 17 00:00:00 2001 From: Uwe Bonnes Date: Wed, 7 Oct 2020 16:52:51 +0200 Subject: [PATCH 01/28] hosted: Hint about BMPs in bootloader mode. --- src/platforms/hosted/platform.c | 10 +++++++--- src/platforms/hosted/platform.h | 1 + 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/src/platforms/hosted/platform.c b/src/platforms/hosted/platform.c index e5bd906b..dd46589d 100644 --- a/src/platforms/hosted/platform.c +++ b/src/platforms/hosted/platform.c @@ -161,9 +161,13 @@ static int find_debuggers( BMP_CL_OPTIONS_t *cl_opts,bmp_info_t *info) } /* Either serial and/or ident_string match or are not given. * Check type.*/ - if ((desc.idVendor == VENDOR_ID_BMP) && - (desc.idProduct == PRODUCT_ID_BMP)) { - type = BMP_TYPE_BMP; + if (desc.idVendor == VENDOR_ID_BMP) { + if (desc.idProduct == PRODUCT_ID_BMP) { + type = BMP_TYPE_BMP; + } else if (desc.idProduct == PRODUCT_ID_BMP_BL) { + DEBUG_WARN("BMP in botloader mode found. Restart or reflash!\n"); + continue; + } } else if ((strstr(manufacturer, "CMSIS")) || (strstr(product, "CMSIS"))) { type = BMP_TYPE_CMSIS_DAP; } else if (desc.idVendor == VENDOR_ID_STLINK) { diff --git a/src/platforms/hosted/platform.h b/src/platforms/hosted/platform.h index e36d7b96..edbc16d2 100644 --- a/src/platforms/hosted/platform.h +++ b/src/platforms/hosted/platform.h @@ -15,6 +15,7 @@ void platform_buffer_flush(void); #define SET_RUN_STATE(x) #define VENDOR_ID_BMP 0x1d50 +#define PRODUCT_ID_BMP_BL 0x6017 #define PRODUCT_ID_BMP 0x6018 typedef enum bmp_type_s { From a254bc630869290d20ca979f1ed293d7138f624c Mon Sep 17 00:00:00 2001 From: "David A. Aguirre Morales" Date: Tue, 6 Oct 2020 19:40:40 -0500 Subject: [PATCH 02/28] Fix icdi usb error https://github.com/blacksphere/blackmagic/issues/740 https://github.com/blacksphere/blackmagic/pull/748 --- src/platforms/common/cdcacm.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/platforms/common/cdcacm.c b/src/platforms/common/cdcacm.c index 7fe4dc3a..35163369 100644 --- a/src/platforms/common/cdcacm.c +++ b/src/platforms/common/cdcacm.c @@ -58,7 +58,11 @@ static const struct usb_device_descriptor dev = { .bDeviceClass = 0xEF, /* Miscellaneous Device */ .bDeviceSubClass = 2, /* Common Class */ .bDeviceProtocol = 1, /* Interface Association */ +#ifdef LM4F + .bMaxPacketSize0 = 64, /*Fixed for icdi*/ +#else .bMaxPacketSize0 = 32, +#endif .idVendor = 0x1D50, .idProduct = 0x6018, .bcdDevice = 0x0100, From 9bb2807706f44ecbafc501f1b5b0f05670853e58 Mon Sep 17 00:00:00 2001 From: Uwe Bonnes Date: Wed, 30 Sep 2020 16:40:47 +0200 Subject: [PATCH 03/28] adiv5/romtable: Prepare CortexM devices to read the ROMTABLE It seems, writing to DHCSR fails silent when the device is sleeping. Reading DHCS during sleep may return nonsense. Repeated write may at some point catch the device running and succeed. With devices sleeping for long time and running on faster clock the chance for a successful hotplug gets smaller. - Try hard to halt a sleeping device - Prepare vector catch and enable all debug units by TRACENA - Release reset - Apply device specific fixes -- STM32F7: Store old value of DBGMCU_CR, enable debug in sleep in DBGMCU before reading PIDR and restore DBGMCU on detach. Signed-off-by: Uwe Bonnes --- src/target/adiv5.c | 120 +++++++++++++++++++++++++++++++++++++++++++ src/target/adiv5.h | 2 + src/target/cortexm.c | 4 ++ src/target/stm32f4.c | 5 +- src/target/stm32h7.c | 11 ++-- 5 files changed, 134 insertions(+), 8 deletions(-) diff --git a/src/target/adiv5.c b/src/target/adiv5.c index 5f032a3b..3cbf1bf1 100644 --- a/src/target/adiv5.c +++ b/src/target/adiv5.c @@ -36,6 +36,13 @@ * are consistently named and accessible when needed in the codebase. */ +/* Values from ST RM0436 (STM32MP157), 66.9 APx_IDR + * and ST RM0438 (STM32L5) 52.3.1, AP_IDR */ +#define ARM_AP_TYPE_AHB 1 +#define ARM_AP_TYPE_APB 3 +#define ARM_AP_TYPE_AXI 4 +#define ARM_AP_TYPE_AHB5 5 + /* ROM table CIDR values */ #define CIDR0_OFFSET 0xFF0 /* DBGCID0 */ #define CIDR1_OFFSET 0xFF4 /* DBGCID1 */ @@ -299,6 +306,99 @@ uint64_t adiv5_ap_read_pidr(ADIv5_AP_t *ap, uint32_t addr) return pidr; } +/* Prepare to read SYSROM and SYSROM PIDR + * + * Try hard to halt, if not connecting under reset + * Request TRCENA and default vector catch + * release from reset when connecting under reset. + * + * E.g. Stm32F7 + * - fails reading romtable in WFI + * - fails with some AP accesses when romtable is read under reset. + * - fails reading some ROMTABLE entries w/o TRCENA + * - fails reading outside SYSROM when halted from WFI and + * DBGMCU_CR not set. + * + * Keep a copy of DEMCR at startup to restore with exit, to + * not interrupt tracing initialed by the CPU. + */ +static bool cortexm_prepare(ADIv5_AP_t *ap) +{ + platform_timeout to ; + platform_timeout_set(&to, cortexm_wait_timeout); + uint32_t dhcsr_ctl = CORTEXM_DHCSR_DBGKEY | CORTEXM_DHCSR_C_DEBUGEN | + CORTEXM_DHCSR_C_HALT; + uint32_t dhcsr_valid = CORTEXM_DHCSR_S_HALT | CORTEXM_DHCSR_C_DEBUGEN; +#ifdef PLATFORM_HAS_DEBUG + uint32_t start_time = platform_time_ms(); +#endif + uint32_t dhcsr; + bool reset_seen = false; + while (true) { + adiv5_mem_write(ap, CORTEXM_DHCSR, &dhcsr_ctl, sizeof(dhcsr_ctl)); + dhcsr = adiv5_mem_read32(ap, CORTEXM_DHCSR); + /* On a sleeping STM32F7, invalid DHCSR reads with e.g. 0xffffffff and + * 0x0xA05F0000 may happen. + * M23/33 will have S_SDE set when debug is allowed + */ + if ((dhcsr != 0xffffffff) && /* Invalid read */ + ((dhcsr & 0xf000fff0) == 0)) {/* Check RAZ bits */ + if ((dhcsr & CORTEXM_DHCSR_S_RESET_ST) && !reset_seen) { + if (connect_assert_srst) + break; + reset_seen = true; + continue; + } + if ((dhcsr & dhcsr_valid) == dhcsr_valid) { /* Halted */ + DEBUG_INFO("Halt via DHCSR: success %08" PRIx32 " after %" + PRId32 "ms\n", + dhcsr, platform_time_ms() - start_time); + break; + } + } + if (platform_timeout_is_expired(&to)) { + DEBUG_WARN("Halt via DHCSR: Failure DHCSR %08" PRIx32 " after % " + PRId32 "ms\nTry again, evt. with longer timeout or " + "connect under reset\n", + dhcsr, platform_time_ms() - start_time); + return false; + } + } + ap->ap_cortexm_demcr = adiv5_mem_read32(ap, CORTEXM_DEMCR); + uint32_t demcr = CORTEXM_DEMCR_TRCENA | CORTEXM_DEMCR_VC_HARDERR | + CORTEXM_DEMCR_VC_CORERESET; + adiv5_mem_write(ap, CORTEXM_DEMCR, &demcr, sizeof(demcr)); + platform_timeout_set(&to, cortexm_wait_timeout); + platform_srst_set_val(false); + while (1) { + dhcsr = adiv5_mem_read32(ap, CORTEXM_DHCSR); + if (!(dhcsr & CORTEXM_DHCSR_S_RESET_ST)) + break; + if (platform_timeout_is_expired(&to)) { + DEBUG_WARN("Error releasing from srst\n"); + return false; + } + } + /* Apply device specific settings for successfull Romtable scan + * + * STM32F7 in WFI will not read ROMTABLE when using WFI + */ + if ((ap->dp->targetid >> 1 & 0x7ff) == 0x20) { + uint32_t dbgmcu_cr = 7; + uint32_t dbgmcu_cr_addr = 0xE0042004; + switch ((ap->dp->targetid >> 16) & 0xfff) { + case 0x449: + case 0x451: + case 0x452: + ap->ap_storage = adiv5_mem_read32(ap, dbgmcu_cr_addr); + dbgmcu_cr = ap->ap_storage | 7; + adiv5_mem_write(ap, dbgmcu_cr_addr, &dbgmcu_cr, sizeof(dbgmcu_cr)); + break; + } + } + return true; +} + static bool adiv5_component_probe(ADIv5_AP_t *ap, uint32_t addr, int recursion, int num_entry) { (void) num_entry; @@ -490,6 +590,26 @@ ADIv5_AP_t *adiv5_new_ap(ADIv5_DP_t *dp, uint8_t apsel) DEBUG_INFO("AP %3d: IDR=%08"PRIx32" CFG=%08"PRIx32" BASE=%08" PRIx32 " CSW=%08"PRIx32"\n", apsel, ap->idr, cfg, ap->base, ap->csw); #endif + if (!apsel && ((ap->idr & 0xf) == ARM_AP_TYPE_AHB)) { + /* Test for protected Atmel devices. Access outside DSU fails. + * For protected device, continue with Rom Table anyways. + */ + adiv5_dp_error(ap->dp); + adiv5_mem_read32(ap, CORTEXM_DHCSR); + if ( adiv5_dp_error(ap->dp) & ADIV5_DP_CTRLSTAT_STICKYERR) { + uint32_t err = adiv5_dp_error(ap->dp); + if (err & ADIV5_DP_CTRLSTAT_STICKYERR) { + DEBUG_WARN("...\nHit error on DHCSR read. Suspect protected Atmel " + "part, skipping to PIDR check.\n"); + } + } else { + if (!cortexm_prepare(ap)) { + free(ap); + return NULL; + } + } + } + adiv5_ap_ref(ap); return ap; } diff --git a/src/target/adiv5.h b/src/target/adiv5.h index e337e3de..68e370bb 100644 --- a/src/target/adiv5.h +++ b/src/target/adiv5.h @@ -181,6 +181,8 @@ struct ADIv5_AP_s { uint32_t idr; uint32_t base; uint32_t csw; + uint32_t ap_cortexm_demcr; /* Copy of demcr when starting */ + uint32_t ap_storage; /* E.g to hold STM32F7 initial DBGMCU_CR value.*/ }; #if PC_HOSTED == 0 diff --git a/src/target/cortexm.c b/src/target/cortexm.c index 840200d1..6e22cb5f 100644 --- a/src/target/cortexm.c +++ b/src/target/cortexm.c @@ -265,6 +265,7 @@ static void cortexm_priv_free(void *priv) static bool cortexm_forced_halt(target *t) { + DEBUG_WARN("cortexm_forced_halt\n"); target_halt_request(t); platform_srst_set_val(false); uint32_t dhcsr = 0; @@ -490,6 +491,9 @@ void cortexm_detach(target *t) for(i = 0; i < priv->hw_watchpoint_max; i++) target_mem_write32(t, CORTEXM_DWT_FUNC(i), 0); + /* Restort DEMCR*/ + ADIv5_AP_t *ap = cortexm_ap(t); + target_mem_write32(t, CORTEXM_DEMCR, ap->ap_cortexm_demcr); /* Disable debug */ target_mem_write32(t, CORTEXM_DHCSR, CORTEXM_DHCSR_DBGKEY); /* Add some clock cycles to get the CPU running again.*/ diff --git a/src/target/stm32f4.c b/src/target/stm32f4.c index a593dd37..b05adc38 100644 --- a/src/target/stm32f4.c +++ b/src/target/stm32f4.c @@ -197,7 +197,8 @@ char *stm32f4_get_chip_name(uint32_t idcode) static void stm32f7_detach(target *t) { - target_mem_write32(t, DBGMCU_CR, t->target_storage); + ADIv5_AP_t *ap = cortexm_ap(t); + target_mem_write32(t, DBGMCU_CR, ap->ap_storage); cortexm_detach(t); } @@ -306,8 +307,6 @@ static bool stm32f4_attach(target *t) bool use_dual_bank = false; target_mem_map_free(t); if (is_f7) { - t->target_storage = target_mem_read32(t, DBGMCU_CR); - target_mem_write32(t, DBGMCU_CR, DBG_SLEEP); target_add_ram(t, 0x00000000, 0x4000); /* 16 k ITCM Ram */ target_add_ram(t, 0x20000000, 0x20000); /* 128 k DTCM Ram */ target_add_ram(t, 0x20020000, 0x60000); /* 384 k Ram */ diff --git a/src/target/stm32h7.c b/src/target/stm32h7.c index d71393cf..16fa1c1f 100644 --- a/src/target/stm32h7.c +++ b/src/target/stm32h7.c @@ -188,11 +188,6 @@ static bool stm32h7_attach(target *t) { if (!cortexm_attach(t)) return false; - /* RM0433 Rev 4 is not really clear, what bits are needed. - * Set all possible relevant bits for now. */ - uint32_t dbgmcu_cr = target_mem_read32(t, DBGMCU_CR); - t->target_storage = dbgmcu_cr; - target_mem_write32(t, DBGMCU_CR, DBGSLEEP_D1 | D1DBGCKEN); /* If IWDG runs as HARDWARE watchdog (44.3.4) erase * will be aborted by the Watchdog and erase fails! * Setting IWDG_KR to 0xaaaa does not seem to help!*/ @@ -234,6 +229,12 @@ bool stm32h7_probe(target *t) t->attach = stm32h7_attach; t->detach = stm32h7_detach; target_add_commands(t, stm32h7_cmd_list, stm32h74_driver_str); + t->target_storage = target_mem_read32(t, DBGMCU_CR); + /* RM0433 Rev 4 is not really clear, what bits are needed in DBGMCU_CR. + * Maybe more flags needed? + */ + uint32_t dbgmcu_cr = DBGSLEEP_D1 | D1DBGCKEN; + target_mem_write32(t, DBGMCU_CR, dbgmcu_cr); return true; } return false; From 159196c2ad60756982648a08777ca46f1d301854 Mon Sep 17 00:00:00 2001 From: Uwe Bonnes Date: Wed, 30 Sep 2020 16:56:52 +0200 Subject: [PATCH 04/28] Cortexm: Remove forced_halt. --- src/target/adiv5.c | 12 +++-------- src/target/cortexm.c | 51 +++++++++++++++----------------------------- src/target/cortexm.h | 2 +- 3 files changed, 21 insertions(+), 44 deletions(-) diff --git a/src/target/adiv5.c b/src/target/adiv5.c index 3cbf1bf1..ec5cead3 100644 --- a/src/target/adiv5.c +++ b/src/target/adiv5.c @@ -465,7 +465,7 @@ static bool adiv5_component_probe(ADIv5_AP_t *ap, uint32_t addr, int recursion, } /* Probe recursively */ - res |= adiv5_component_probe( + adiv5_component_probe( ap, addr + (entry & ADIV5_ROM_ROMENTRY_OFFSET), recursion + 1, i); } @@ -524,7 +524,7 @@ static bool adiv5_component_probe(ADIv5_AP_t *ap, uint32_t addr, int recursion, switch (pidr_pn_bits[i].arch) { case aa_cortexm: DEBUG_INFO("%s-> cortexm_probe\n", indent + 1); - cortexm_probe(ap, false); + cortexm_probe(ap); break; case aa_cortexa: DEBUG_INFO("\n -> cortexa_probe\n"); @@ -615,7 +615,6 @@ ADIv5_AP_t *adiv5_new_ap(ADIv5_DP_t *dp, uint8_t apsel) void adiv5_dp_init(ADIv5_DP_t *dp) { - volatile bool probed = false; volatile uint32_t ctrlstat = 0; adiv5_dp_ref(dp); #if PC_HOSTED == 1 @@ -745,12 +744,7 @@ void adiv5_dp_init(ADIv5_DP_t *dp) */ /* The rest should only be added after checking ROM table */ - probed |= adiv5_component_probe(ap, ap->base, 0, 0); - if (!probed && (dp->idcode & 0xfff) == 0x477) { - DEBUG_INFO("-> cortexm_probe forced\n"); - cortexm_probe(ap, true); - probed = true; - } + adiv5_component_probe(ap, ap->base, 0, 0); } adiv5_dp_unref(dp); } diff --git a/src/target/cortexm.c b/src/target/cortexm.c index 6e22cb5f..de2729a0 100644 --- a/src/target/cortexm.c +++ b/src/target/cortexm.c @@ -263,29 +263,7 @@ static void cortexm_priv_free(void *priv) free(priv); } -static bool cortexm_forced_halt(target *t) -{ - DEBUG_WARN("cortexm_forced_halt\n"); - target_halt_request(t); - platform_srst_set_val(false); - uint32_t dhcsr = 0; - uint32_t start_time = platform_time_ms(); - const uint32_t dhcsr_halted_bits = CORTEXM_DHCSR_S_HALT | CORTEXM_DHCSR_S_REGRDY | - CORTEXM_DHCSR_C_HALT | CORTEXM_DHCSR_C_DEBUGEN; - /* Try hard to halt the target. STM32F7 in WFI - needs multiple writes!*/ - while (platform_time_ms() < start_time + cortexm_wait_timeout) { - dhcsr = target_mem_read32(t, CORTEXM_DHCSR); - if ((dhcsr & dhcsr_halted_bits) == dhcsr_halted_bits) - break; - target_halt_request(t); - } - if ((dhcsr & dhcsr_halted_bits) != dhcsr_halted_bits) - return false; - return true; -} - -bool cortexm_probe(ADIv5_AP_t *ap, bool forced) +bool cortexm_probe(ADIv5_AP_t *ap) { target *t; @@ -393,14 +371,6 @@ bool cortexm_probe(ADIv5_AP_t *ap, bool forced) target_check_error(t); } - /* Only force halt if read ROM Table failed and there is no DPv2 - * targetid! - * So long, only STM32L0 is expected to enter this cause. - */ - if (forced && !ap->dp->targetid) - if (!cortexm_forced_halt(t)) - return false; - #define PROBE(x) \ do { if ((x)(t)) {target_halt_resume(t, 0); return true;} else target_check_error(t); } while (0) @@ -439,9 +409,6 @@ bool cortexm_attach(target *t) target_check_error(t); target_halt_request(t); - if (!cortexm_forced_halt(t)) - return false; - /* Request halt on reset */ target_mem_write32(t, CORTEXM_DEMCR, priv->demcr); @@ -475,6 +442,22 @@ bool cortexm_attach(target *t) target_mem_write32(t, CORTEXM_FPB_CTRL, CORTEXM_FPB_CTRL_KEY | CORTEXM_FPB_CTRL_ENABLE); + uint32_t dhcsr = target_mem_read32(t, CORTEXM_DHCSR); + dhcsr = target_mem_read32(t, CORTEXM_DHCSR); + if (dhcsr & CORTEXM_DHCSR_S_RESET_ST) { + platform_srst_set_val(false); + platform_timeout timeout; + platform_timeout_set(&timeout, 1000); + while (1) { + uint32_t dhcsr = target_mem_read32(t, CORTEXM_DHCSR); + if (!(dhcsr & CORTEXM_DHCSR_S_RESET_ST)) + break; + if (platform_timeout_is_expired(&timeout)) { + DEBUG_WARN("Error releasing from srst\n"); + return false; + } + } + } return true; } diff --git a/src/target/cortexm.h b/src/target/cortexm.h index 95952f5b..f230e0b5 100644 --- a/src/target/cortexm.h +++ b/src/target/cortexm.h @@ -171,7 +171,7 @@ extern long cortexm_wait_timeout; #define CORTEXM_TOPT_INHIBIT_SRST (1 << 2) -bool cortexm_probe(ADIv5_AP_t *ap, bool forced); +bool cortexm_probe(ADIv5_AP_t *ap); ADIv5_AP_t *cortexm_ap(target *t); bool cortexm_attach(target *t); From c456fc7f6122ec9d0fff891b5b79f4a0aded63f7 Mon Sep 17 00:00:00 2001 From: Uwe Bonnes Date: Tue, 10 Mar 2020 16:04:25 +0100 Subject: [PATCH 05/28] adiv5: Store AP designer and partno in the AP structure. --- src/target/adiv5.c | 15 ++++++++++----- src/target/adiv5.h | 2 ++ 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/src/target/adiv5.c b/src/target/adiv5.c index ec5cead3..6200e5ab 100644 --- a/src/target/adiv5.c +++ b/src/target/adiv5.c @@ -433,8 +433,10 @@ static bool adiv5_component_probe(ADIv5_AP_t *ap, uint32_t addr, int recursion, /* ROM table */ if (cid_class == cidc_romtab) { + uint16_t designer = ((pidr >> 24) & 0xf00) | ((pidr >> 12) & 0x7f); + uint16_t partno = pidr & 0xfff; +#if defined(ENABLE_DEBUG) && defined(PLATFORM_HAS_DEBUG) /* Check SYSMEM bit */ -#if defined(ENABLE_DEBUG) uint32_t memtype = adiv5_mem_read32(ap, addr | ADIV5_ROM_MEMTYPE) & ADIV5_ROM_MEMTYPE_SYSMEM; @@ -442,11 +444,14 @@ static bool adiv5_component_probe(ADIv5_AP_t *ap, uint32_t addr, int recursion, DEBUG_WARN("Fault reading ROM table entry\n"); } - DEBUG_INFO("ROM: Table BASE=0x%" PRIx32 " SYSMEM=0x%" PRIx32 - ", PIDR 0x%02" PRIx32 "%08" PRIx32 "\n", addr, - memtype, (uint32_t)(pidr >> 32), (uint32_t)pidr); + DEBUG_INFO("ROM: Table BASE=0x%" PRIx32 " SYSMEM=0x%" PRIx32 ", designer %3" + PRIx32 " Partno %3" PRIx32 "\n", addr, memtype, designer, + partno); #endif - + if (recursion == 0) { + ap->ap_designer = designer; + ap->ap_partno = partno; + } for (int i = 0; i < 960; i++) { adiv5_dp_error(ap->dp); uint32_t entry = adiv5_mem_read32(ap, addr + i*4); diff --git a/src/target/adiv5.h b/src/target/adiv5.h index 68e370bb..8ba602f5 100644 --- a/src/target/adiv5.h +++ b/src/target/adiv5.h @@ -183,6 +183,8 @@ struct ADIv5_AP_s { uint32_t csw; uint32_t ap_cortexm_demcr; /* Copy of demcr when starting */ uint32_t ap_storage; /* E.g to hold STM32F7 initial DBGMCU_CR value.*/ + uint16_t ap_designer; + uint16_t ap_partno; }; #if PC_HOSTED == 0 From 44bfb62715823004589127a1c8115f049e21d19e Mon Sep 17 00:00:00 2001 From: Uwe Bonnes Date: Wed, 25 Mar 2020 23:07:14 +0100 Subject: [PATCH 06/28] Adiv5: Print Designer/Partno when device is not recognized t->idcode is now 16 bit. --- src/command.c | 15 ++++++++++++--- src/include/target.h | 2 ++ src/platforms/pc/cl_utils.c | 15 ++++++++++++--- src/target/adiv5.c | 7 +++++-- src/target/cortexm.c | 3 ++- src/target/nrf51.c | 1 - src/target/sam3x.c | 20 ++++++++++---------- src/target/sam4l.c | 16 ++++++++-------- src/target/target.c | 10 ++++++++++ src/target/target_internal.h | 3 ++- 10 files changed, 63 insertions(+), 29 deletions(-) diff --git a/src/command.c b/src/command.c index 2758d31b..caaaa57a 100644 --- a/src/command.c +++ b/src/command.c @@ -257,9 +257,18 @@ bool cmd_swdp_scan(target *t, int argc, char **argv) static void display_target(int i, target *t, void *context) { (void)context; - gdb_outf("%2d %c %s %s\n", i, target_attached(t)?'*':' ', - target_driver_name(t), - (target_core_name(t)) ? target_core_name(t): ""); + if (!strcmp(target_driver_name(t), "ARM Cortex-M")) { + gdb_outf("***%2d%sUnknown %s Designer %3x Partno %3x %s\n", + i, target_attached(t)?" * ":" ", + target_driver_name(t), + target_designer(t), + target_idcode(t), + (target_core_name(t)) ? target_core_name(t): ""); + } else { + gdb_outf("%2d %c %s %s\n", i, target_attached(t)?'*':' ', + target_driver_name(t), + (target_core_name(t)) ? target_core_name(t): ""); + } } bool cmd_targets(target *t, int argc, char **argv) diff --git a/src/include/target.h b/src/include/target.h index 106ac273..7c71340f 100644 --- a/src/include/target.h +++ b/src/include/target.h @@ -51,6 +51,8 @@ void target_detach(target *t); bool target_attached(target *t); const char *target_driver_name(target *t); const char *target_core_name(target *t); +unsigned int target_designer(target *t); +unsigned int target_idcode(target *t); /* Memory access functions */ bool target_mem_map(target *t, char *buf, size_t len); diff --git a/src/platforms/pc/cl_utils.c b/src/platforms/pc/cl_utils.c index f6efc7d3..60191f14 100644 --- a/src/platforms/pc/cl_utils.c +++ b/src/platforms/pc/cl_utils.c @@ -265,9 +265,18 @@ void cl_init(BMP_CL_OPTIONS_t *opt, int argc, char **argv) static void display_target(int i, target *t, void *context) { (void)context; - DEBUG_INFO("*** %2d %c %s %s\n", i, target_attached(t)?'*':' ', - target_driver_name(t), - (target_core_name(t)) ? target_core_name(t): ""); + if (!strcmp(target_driver_name(t), "ARM Cortex-M")) { + DEBUG_INFO("***%2d%sUnknown %s Designer %3x Partno %3x %s\n", + i, target_attached(t)?" * ":" ", + target_driver_name(t), + target_designer(t), + target_idcode(t), + (target_core_name(t)) ? target_core_name(t): ""); + } else { + DEBUG_INFO("*** %2d %c %s %s\n", i, target_attached(t)?'*':' ', + target_driver_name(t), + (target_core_name(t)) ? target_core_name(t): ""); + } } int cl_execute(BMP_CL_OPTIONS_t *opt) diff --git a/src/target/adiv5.c b/src/target/adiv5.c index 6200e5ab..53db2091 100644 --- a/src/target/adiv5.c +++ b/src/target/adiv5.c @@ -198,7 +198,10 @@ static const struct { {0x00d, 0x00, 0, aa_nosupport, cidc_unknown, PIDR_PN_BIT_STRINGS("CoreSight ETM11", "(Embedded Trace)")}, {0x00e, 0x00, 0, aa_nosupport, cidc_unknown, PIDR_PN_BIT_STRINGS("Cortex-M7 FBP", "(Flash Patch and Breakpoint)")}, {0x101, 0x00, 0, aa_nosupport, cidc_unknown, PIDR_PN_BIT_STRINGS("System TSGEN", "(Time Stamp Generator)")}, + {0x471, 0x00, 0, aa_nosupport, cidc_unknown, PIDR_PN_BIT_STRINGS("Cortex-M0 ROM", "(Cortex-M0 ROM)")}, {0x490, 0x00, 0, aa_nosupport, cidc_unknown, PIDR_PN_BIT_STRINGS("Cortex-A15 GIC", "(Generic Interrupt Controller)")}, + {0x4c0, 0x00, 0, aa_nosupport, cidc_unknown, PIDR_PN_BIT_STRINGS("Cortex-M0+ ROM", "(Cortex-M0+ ROM)")}, + {0x4c4, 0x00, 0, aa_nosupport, cidc_unknown, PIDR_PN_BIT_STRINGS("Cortex-M4 ROM", "(Cortex-M4 ROM)")}, {0x4c7, 0x00, 0, aa_nosupport, cidc_unknown, PIDR_PN_BIT_STRINGS("Cortex-M7 PPB", "(Private Peripheral Bus ROM Table)")}, {0x906, 0x14, 0, aa_nosupport, cidc_unknown, PIDR_PN_BIT_STRINGS("CoreSight CTI", "(Cross Trigger)")}, {0x907, 0x00, 0, aa_nosupport, cidc_unknown, PIDR_PN_BIT_STRINGS("CoreSight ETB", "(Trace Buffer)")}, @@ -444,8 +447,8 @@ static bool adiv5_component_probe(ADIv5_AP_t *ap, uint32_t addr, int recursion, DEBUG_WARN("Fault reading ROM table entry\n"); } - DEBUG_INFO("ROM: Table BASE=0x%" PRIx32 " SYSMEM=0x%" PRIx32 ", designer %3" - PRIx32 " Partno %3" PRIx32 "\n", addr, memtype, designer, + DEBUG_INFO("ROM: Table BASE=0x%" PRIx32 " SYSMEM=0x%08" PRIx32 + ", designer %3x Partno %3x\n", addr, memtype, designer, partno); #endif if (recursion == 0) { diff --git a/src/target/cortexm.c b/src/target/cortexm.c index de2729a0..d2f7671b 100644 --- a/src/target/cortexm.c +++ b/src/target/cortexm.c @@ -273,6 +273,8 @@ bool cortexm_probe(ADIv5_AP_t *ap) } adiv5_ap_ref(ap); + t->t_designer = ap->ap_designer; + t->idcode = ap->ap_partno; struct cortexm_priv *priv = calloc(1, sizeof(*priv)); if (!priv) { /* calloc failed: heap exhaustion */ DEBUG_WARN("calloc: failed in %s\n", __func__); @@ -370,7 +372,6 @@ bool cortexm_probe(ADIv5_AP_t *ap) } else { target_check_error(t); } - #define PROBE(x) \ do { if ((x)(t)) {target_halt_resume(t, 0); return true;} else target_check_error(t); } while (0) diff --git a/src/target/nrf51.c b/src/target/nrf51.c index 9fa73580..e8a02b09 100644 --- a/src/target/nrf51.c +++ b/src/target/nrf51.c @@ -132,7 +132,6 @@ bool nrf51_probe(target *t) if ((info_part != 0xffffffff) && (info_part != 0) && ((info_part & 0x00ff000) == 0x52000)) { uint32_t ram_size = target_mem_read32(t, NRF52_INFO_RAM); - t->idcode = info_part; t->driver = "Nordic nRF52"; t->target_options |= CORTEXM_TOPT_INHIBIT_SRST; target_add_ram(t, 0x20000000, ram_size * 1024); diff --git a/src/target/sam3x.c b/src/target/sam3x.c index 0537c11a..c869d722 100644 --- a/src/target/sam3x.c +++ b/src/target/sam3x.c @@ -170,9 +170,9 @@ static void sam4_add_flash(target *t, target_add_flash(t, f); } -static size_t sam_flash_size(uint32_t idcode) +static size_t sam_flash_size(uint32_t cidr) { - switch (idcode & CHIPID_CIDR_NVPSIZ_MASK) { + switch (cidr & CHIPID_CIDR_NVPSIZ_MASK) { case CHIPID_CIDR_NVPSIZ_8K: return 0x2000; case CHIPID_CIDR_NVPSIZ_16K: @@ -197,9 +197,9 @@ static size_t sam_flash_size(uint32_t idcode) bool sam3x_probe(target *t) { - t->idcode = target_mem_read32(t, SAM3X_CHIPID_CIDR); - size_t size = sam_flash_size(t->idcode); - switch (t->idcode & (CHIPID_CIDR_ARCH_MASK | CHIPID_CIDR_EPROC_MASK)) { + uint32_t cidr = target_mem_read32(t, SAM3X_CHIPID_CIDR); + size_t size = sam_flash_size(cidr); + switch (cidr & (CHIPID_CIDR_ARCH_MASK | CHIPID_CIDR_EPROC_MASK)) { case CHIPID_CIDR_ARCH_SAM3XxC | CHIPID_CIDR_EPROC_CM3: case CHIPID_CIDR_ARCH_SAM3XxE | CHIPID_CIDR_EPROC_CM3: case CHIPID_CIDR_ARCH_SAM3XxG | CHIPID_CIDR_EPROC_CM3: @@ -212,9 +212,9 @@ bool sam3x_probe(target *t) return true; } - t->idcode = target_mem_read32(t, SAM34NSU_CHIPID_CIDR); - size = sam_flash_size(t->idcode); - switch (t->idcode & (CHIPID_CIDR_ARCH_MASK | CHIPID_CIDR_EPROC_MASK)) { + cidr = target_mem_read32(t, SAM34NSU_CHIPID_CIDR); + size = sam_flash_size(cidr); + switch (cidr & (CHIPID_CIDR_ARCH_MASK | CHIPID_CIDR_EPROC_MASK)) { case CHIPID_CIDR_ARCH_SAM3NxA | CHIPID_CIDR_EPROC_CM3: case CHIPID_CIDR_ARCH_SAM3NxB | CHIPID_CIDR_EPROC_CM3: case CHIPID_CIDR_ARCH_SAM3NxC | CHIPID_CIDR_EPROC_CM3: @@ -224,7 +224,7 @@ bool sam3x_probe(target *t) t->driver = "Atmel SAM3N/S"; target_add_ram(t, 0x20000000, 0x200000); /* These devices only have a single bank */ - size = sam_flash_size(t->idcode); + size = sam_flash_size(cidr); sam3_add_flash(t, SAM3N_EEFC_BASE, 0x400000, size); target_add_commands(t, sam3x_cmd_list, "SAM3N/S"); return true; @@ -248,7 +248,7 @@ bool sam3x_probe(target *t) case CHIPID_CIDR_ARCH_SAM4SDC | CHIPID_CIDR_EPROC_CM4: t->driver = "Atmel SAM4S"; target_add_ram(t, 0x20000000, 0x400000); - size_t size = sam_flash_size(t->idcode); + size_t size = sam_flash_size(cidr); if (size <= 0x80000) { /* Smaller devices have a single bank */ sam4_add_flash(t, SAM4S_EEFC_BASE(0), 0x400000, size); diff --git a/src/target/sam4l.c b/src/target/sam4l.c index 06b96db1..bab336cd 100644 --- a/src/target/sam4l.c +++ b/src/target/sam4l.c @@ -186,13 +186,13 @@ static void sam4l_add_flash(target *t, uint32_t addr, size_t length) } /* Return size of RAM */ -static size_t sam_ram_size(uint32_t idcode) { - return __ram_size[((idcode >> CHIPID_CIDR_SRAMSIZ_SHIFT) & CHIPID_CIDR_SRAMSIZ_MASK)]; +static size_t sam_ram_size(uint32_t cidr) { + return __ram_size[((cidr >> CHIPID_CIDR_SRAMSIZ_SHIFT) & CHIPID_CIDR_SRAMSIZ_MASK)]; } /* Return size of FLASH */ -static size_t sam_nvp_size(uint32_t idcode) { - return __nvp_size[((idcode >> CHIPID_CIDR_NVPSIZ_SHIFT) & CHIPID_CIDR_NVPSIZ_MASK)]; +static size_t sam_nvp_size(uint32_t cidr) { + return __nvp_size[((cidr >> CHIPID_CIDR_NVPSIZ_SHIFT) & CHIPID_CIDR_NVPSIZ_MASK)]; } #define SMAP_BASE 0x400a3000 @@ -228,14 +228,14 @@ bool sam4l_probe(target *t) { size_t ram_size, flash_size; - t->idcode = target_mem_read32(t, SAM4L_CHIPID_CIDR); - if (((t->idcode >> CHIPID_CIDR_ARCH_SHIFT) & CHIPID_CIDR_ARCH_MASK) == SAM4L_ARCH) { + uint32_t cidr = target_mem_read32(t, SAM4L_CHIPID_CIDR); + if (((cidr >> CHIPID_CIDR_ARCH_SHIFT) & CHIPID_CIDR_ARCH_MASK) == SAM4L_ARCH) { t->driver = "Atmel SAM4L"; /* this function says we need to do "extra" stuff after reset */ t->extended_reset = sam4l_extended_reset; - ram_size = sam_ram_size(t->idcode); + ram_size = sam_ram_size(cidr); target_add_ram(t, 0x20000000, ram_size); - flash_size = sam_nvp_size(t->idcode); + flash_size = sam_nvp_size(cidr); sam4l_add_flash(t, 0x0, flash_size); DEBUG_INFO("\nSAM4L: RAM = 0x%x (%dK), FLASH = 0x%x (%dK)\n", (unsigned int) ram_size, (unsigned int) (ram_size / 1024), diff --git a/src/target/target.c b/src/target/target.c index e1f7a657..5a5ec388 100644 --- a/src/target/target.c +++ b/src/target/target.c @@ -502,6 +502,16 @@ const char *target_core_name(target *t) return t->core; } +unsigned int target_designer(target *t) +{ + return t->t_designer; +} + +unsigned int target_idcode(target *t) +{ + return t->idcode; +} + uint32_t target_mem_read32(target *t, uint32_t addr) { uint32_t ret; diff --git a/src/target/target_internal.h b/src/target/target_internal.h index c2288af2..66ff2019 100644 --- a/src/target/target_internal.h +++ b/src/target/target_internal.h @@ -111,7 +111,8 @@ struct target_s { /* target-defined options */ unsigned target_options; - uint32_t idcode; + uint16_t t_designer; + uint16_t idcode; uint32_t target_storage; struct target_ram *ram; From 91d1ef8bf6abc5f5ffff19b1b2712750e8bc302c Mon Sep 17 00:00:00 2001 From: Uwe Bonnes Date: Wed, 30 Sep 2020 19:03:34 +0200 Subject: [PATCH 07/28] target/stm32: Use t->idcode with probe. --- src/target/adiv5.h | 3 +++ src/target/stm32f1.c | 7 ++----- src/target/stm32f4.c | 16 ++++------------ src/target/stm32h7.c | 5 +---- src/target/stm32l0.c | 11 +---------- src/target/stm32l4.c | 9 +-------- 6 files changed, 12 insertions(+), 39 deletions(-) diff --git a/src/target/adiv5.h b/src/target/adiv5.h index 8ba602f5..9f57ca8e 100644 --- a/src/target/adiv5.h +++ b/src/target/adiv5.h @@ -86,6 +86,9 @@ #define ADIV5_AP_BASE ADIV5_AP_REG(0xF8) #define ADIV5_AP_IDR ADIV5_AP_REG(0xFC) +/* Known designers seen in SYSROM-PIDR. Ignore Bit 7 from the designer bits*/ +#define AP_DESIGNER_ARM 0x43b + /* AP Control and Status Word (CSW) */ #define ADIV5_AP_CSW_DBGSWENABLE (1u << 31) /* Bits 30:24 - Prot, Implementation defined, for Cortex-M3: */ diff --git a/src/target/stm32f1.c b/src/target/stm32f1.c index 4aac170d..731973d1 100644 --- a/src/target/stm32f1.c +++ b/src/target/stm32f1.c @@ -118,9 +118,10 @@ static void stm32f1_add_flash(target *t, bool stm32f1_probe(target *t) { + if (t->t_designer == AP_DESIGNER_ARM) + t->idcode = target_mem_read32(t, DBGMCU_IDCODE) & 0xfff; 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 density */ @@ -167,10 +168,6 @@ bool stm32f1_probe(target *t) 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, STM32F030x[4|6] RM0360 Rev. 4*/ t->driver = "STM32F03"; flash_size = 0x8000; diff --git a/src/target/stm32f4.c b/src/target/stm32f4.c index b05adc38..33691c7b 100644 --- a/src/target/stm32f4.c +++ b/src/target/stm32f4.c @@ -204,22 +204,15 @@ static void stm32f7_detach(target *t) bool stm32f4_probe(target *t) { - ADIv5_AP_t *ap = cortexm_ap(t); - uint32_t idcode; - - idcode = (ap->dp->targetid >> 16) & 0xfff; - if (!idcode) - idcode = target_mem_read32(t, DBGMCU_IDCODE) & 0xFFF; - - if (idcode == ID_STM32F20X) { + if (t->idcode == ID_STM32F20X) { /* F405 revision A have a wrong IDCODE, use ARM_CPUID to make the * distinction with F205. Revision is also wrong (0x2000 instead * of 0x1000). See F40x/F41x errata. */ uint32_t cpuid = target_mem_read32(t, ARM_CPUID); if ((cpuid & 0xFFF0) == 0xC240) - idcode = ID_STM32F40X; + t->idcode = ID_STM32F40X; } - switch(idcode) { + switch(t->idcode) { case ID_STM32F74X: /* F74x RM0385 Rev.4 */ case ID_STM32F76X: /* F76x F77x RM0410 */ case ID_STM32F72X: /* F72x F73x RM0431 */ @@ -235,8 +228,7 @@ bool stm32f4_probe(target *t) case ID_STM32F412: /* F412 RM0402 Rev.4, 256 kB Ram */ case ID_STM32F401E: /* F401 D/E RM0368 Rev.3 */ case ID_STM32F413: /* F413 RM0430 Rev.2, 320 kB Ram, 1.5 MB flash. */ - t->idcode = idcode; - t->driver = stm32f4_get_chip_name(idcode); + t->driver = stm32f4_get_chip_name(t->idcode); t->attach = stm32f4_attach; target_add_commands(t, stm32f4_cmd_list, t->driver); return true; diff --git a/src/target/stm32h7.c b/src/target/stm32h7.c index 16fa1c1f..e72d99ae 100644 --- a/src/target/stm32h7.c +++ b/src/target/stm32h7.c @@ -221,10 +221,7 @@ static void stm32h7_detach(target *t) bool stm32h7_probe(target *t) { - ADIv5_AP_t *ap = cortexm_ap(t); - uint32_t idcode = (ap->dp->targetid >> 16) & 0xfff; - if (idcode == ID_STM32H74x) { - t->idcode = idcode; + if (t->idcode == ID_STM32H74x) { t->driver = stm32h74_driver_str; t->attach = stm32h7_attach; t->detach = stm32h7_detach; diff --git a/src/target/stm32l0.c b/src/target/stm32l0.c index 088bd03b..54b21596 100644 --- a/src/target/stm32l0.c +++ b/src/target/stm32l0.c @@ -268,31 +268,22 @@ static void stm32l_add_eeprom(target *t, uint32_t addr, size_t length) STM32L0xx parts as well as the STM32L1xx's. */ bool stm32l0_probe(target* t) { - uint32_t idcode; - - idcode = target_mem_read32(t, STM32L1_DBGMCU_IDCODE_PHYS) & 0xfff; - switch (idcode) { + switch (t->idcode) { case 0x416: /* CAT. 1 device */ case 0x429: /* CAT. 2 device */ case 0x427: /* CAT. 3 device */ case 0x436: /* CAT. 4 device */ case 0x437: /* CAT. 5 device */ - t->idcode = idcode; t->driver = "STM32L1x"; target_add_ram(t, 0x20000000, 0x14000); stm32l_add_flash(t, 0x8000000, 0x80000, 0x100); //stm32l_add_eeprom(t, 0x8080000, 0x4000); target_add_commands(t, stm32lx_cmd_list, "STM32L1x"); return true; - } - - idcode = target_mem_read32(t, STM32L0_DBGMCU_IDCODE_PHYS) & 0xfff; - switch (idcode) { case 0x457: /* STM32L0xx Cat1 */ case 0x425: /* STM32L0xx Cat2 */ case 0x417: /* STM32L0xx Cat3 */ case 0x447: /* STM32L0xx Cat5 */ - t->idcode = idcode; t->driver = "STM32L0x"; target_add_ram(t, 0x20000000, 0x5000); stm32l_add_flash(t, 0x8000000, 0x10000, 0x80); diff --git a/src/target/stm32l4.c b/src/target/stm32l4.c index f3d91631..7d47f84a 100644 --- a/src/target/stm32l4.c +++ b/src/target/stm32l4.c @@ -373,18 +373,11 @@ static void stm32l4_detach(target *t) bool stm32l4_probe(target *t) { - uint32_t idcode_reg = STM32L4_DBGMCU_IDCODE_PHYS; - ADIv5_AP_t *ap = cortexm_ap(t); - if (ap->dp->idcode == 0x0BC11477) - idcode_reg = STM32G0_DBGMCU_IDCODE_PHYS; - uint32_t idcode = target_mem_read32(t, idcode_reg) & 0xfff; - - struct stm32l4_info const *chip = stm32l4_get_chip_info(idcode); + struct stm32l4_info const *chip = stm32l4_get_chip_info(t->idcode); if( !chip->idcode ) /* Not found */ return false; - t->idcode = idcode; t->driver = chip->designator; t->attach = stm32l4_attach; t->detach = stm32l4_detach; From 877b4be8ee6947bcf27bfb20da6c8605dc8231a4 Mon Sep 17 00:00:00 2001 From: Uwe Bonnes Date: Wed, 30 Sep 2020 17:44:11 +0200 Subject: [PATCH 08/28] cortexm: Restrict probing by using the ap_designer. More designers need to be observed and reported by users and added. Request users to send needed data. --- src/target/adiv5.c | 2 +- src/target/adiv5.h | 10 ++++++ src/target/cortexm.c | 81 +++++++++++++++++++++++++++++++------------- src/target/lpc11xx.c | 2 +- 4 files changed, 70 insertions(+), 25 deletions(-) diff --git a/src/target/adiv5.c b/src/target/adiv5.c index 53db2091..49023eba 100644 --- a/src/target/adiv5.c +++ b/src/target/adiv5.c @@ -204,7 +204,7 @@ static const struct { {0x4c4, 0x00, 0, aa_nosupport, cidc_unknown, PIDR_PN_BIT_STRINGS("Cortex-M4 ROM", "(Cortex-M4 ROM)")}, {0x4c7, 0x00, 0, aa_nosupport, cidc_unknown, PIDR_PN_BIT_STRINGS("Cortex-M7 PPB", "(Private Peripheral Bus ROM Table)")}, {0x906, 0x14, 0, aa_nosupport, cidc_unknown, PIDR_PN_BIT_STRINGS("CoreSight CTI", "(Cross Trigger)")}, - {0x907, 0x00, 0, aa_nosupport, cidc_unknown, PIDR_PN_BIT_STRINGS("CoreSight ETB", "(Trace Buffer)")}, + {0x907, 0x21, 0, aa_nosupport, cidc_unknown, PIDR_PN_BIT_STRINGS("CoreSight ETB", "(Trace Buffer)")}, {0x908, 0x12, 0, aa_nosupport, cidc_unknown, PIDR_PN_BIT_STRINGS("CoreSight CSTF", "(Trace Funnel)")}, {0x910, 0x00, 0, aa_nosupport, cidc_unknown, PIDR_PN_BIT_STRINGS("CoreSight ETM9", "(Embedded Trace)")}, {0x912, 0x11, 0, aa_nosupport, cidc_unknown, PIDR_PN_BIT_STRINGS("CoreSight TPIU", "(Trace Port Interface Unit)")}, diff --git a/src/target/adiv5.h b/src/target/adiv5.h index 9f57ca8e..39d4d5ab 100644 --- a/src/target/adiv5.h +++ b/src/target/adiv5.h @@ -87,7 +87,17 @@ #define ADIV5_AP_IDR ADIV5_AP_REG(0xFC) /* Known designers seen in SYSROM-PIDR. Ignore Bit 7 from the designer bits*/ +#define AP_DESIGNER_FREESCALE 0x00e +#define AP_DESIGNER_TEXAS 0x017 +#define AP_DESIGNER_ATMEL 0x01f +#define AP_DESIGNER_STM 0x020 +#define AP_DESIGNER_CYPRESS 0x034 +#define AP_DESIGNER_INFINEON 0x041 +#define AP_DESIGNER_NORDIC 0x244 #define AP_DESIGNER_ARM 0x43b +/*LPC845 with designer 501. Strange!? */ +#define AP_DESIGNER_SPECULAR 0x501 +#define AP_DESIGNER_ENERGY_MICRO 0x673 /* AP Control and Status Word (CSW) */ #define ADIV5_AP_CSW_DBGSWENABLE (1u << 31) diff --git a/src/target/cortexm.c b/src/target/cortexm.c index d2f7671b..f2bf5259 100644 --- a/src/target/cortexm.c +++ b/src/target/cortexm.c @@ -1,9 +1,9 @@ /* * This file is part of the Black Magic Debug project. * - * Copyright (C) 2012 Black Sphere Technologies Ltd. + * Copyright (C) 2012-2020 Black Sphere Technologies Ltd. * Written by Gareth McMullin , - * Koen De Vleeschauwer and Uwe Bonne + * Koen De Vleeschauwer and Uwe Bonnes * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -35,6 +35,7 @@ #include "cortexm.h" #include "platform.h" #include "command.h" +#include "gdb_packet.h" #include @@ -375,28 +376,62 @@ bool cortexm_probe(ADIv5_AP_t *ap) #define PROBE(x) \ do { if ((x)(t)) {target_halt_resume(t, 0); return true;} else target_check_error(t); } while (0) - PROBE(stm32f1_probe); - PROBE(stm32f4_probe); - PROBE(stm32h7_probe); - PROBE(stm32l0_probe); /* STM32L0xx & STM32L1xx */ - PROBE(stm32l4_probe); - PROBE(lpc11xx_probe); - PROBE(lpc15xx_probe); - PROBE(lpc43xx_probe); - PROBE(lpc546xx_probe); - PROBE(sam3x_probe); - PROBE(sam4l_probe); - PROBE(nrf51_probe); - PROBE(samd_probe); - PROBE(samx5x_probe); - PROBE(lmi_probe); - PROBE(kinetis_probe); - PROBE(efm32_probe); - PROBE(msp432_probe); - PROBE(ke04_probe); - PROBE(lpc17xx_probe); + switch (ap->ap_designer) { + case AP_DESIGNER_FREESCALE: + PROBE(kinetis_probe); + break; + case AP_DESIGNER_STM: + PROBE(stm32f1_probe); + PROBE(stm32f4_probe); + PROBE(stm32h7_probe); + PROBE(stm32l0_probe); + PROBE(stm32l4_probe); + break; + case AP_DESIGNER_CYPRESS: + DEBUG_WARN("Unhandled Cypress device\n"); + break; + case AP_DESIGNER_INFINEON: + DEBUG_WARN("Unhandled Infineon device\n"); + break; + case AP_DESIGNER_NORDIC: + PROBE(nrf51_probe); + break; + case AP_DESIGNER_ATMEL: + PROBE(sam4l_probe); + PROBE(samd_probe); + PROBE(samx5x_probe); + break; + case AP_DESIGNER_ARM: + if (ap->ap_partno == 0x4c3) /* Care for STM32F1 clones */ + PROBE(stm32f1_probe); + PROBE(sam3x_probe); + PROBE(lpc11xx_probe); /* LPC24C11 */ + break; + case AP_DESIGNER_ENERGY_MICRO: + PROBE(efm32_probe); + break; + case AP_DESIGNER_TEXAS: + PROBE(msp432_probe); + break; + case AP_DESIGNER_SPECULAR: + PROBE(lpc11xx_probe); /* LPC845 */ + break; + default: +#if PC_HOSTED == 0 + gdb_outf("Please report Designer %3x and Partno %3x and the probed " + "device\n", ap->ap_designer, ap->ap_partno); +#else + DEBUG_WARN("Please report Designer %3x and Partno %3x and the probed " + "device\n", ap->ap_designer, ap->ap_partno); +#endif + PROBE(lpc11xx_probe); /* Let's get feedback if LPC11 is also Specular*/ + PROBE(lpc15xx_probe); + PROBE(lpc43xx_probe); + PROBE(lmi_probe); + PROBE(ke04_probe); + PROBE(lpc17xx_probe); + } #undef PROBE - return true; } diff --git a/src/target/lpc11xx.c b/src/target/lpc11xx.c index ba2dc6a4..5cad1e77 100644 --- a/src/target/lpc11xx.c +++ b/src/target/lpc11xx.c @@ -137,7 +137,7 @@ lpc11xx_probe(target *t) target_add_commands(t, lpc11xx_cmd_list, "LPC8N04"); return true; } - if (idcode) { + if ((t->t_designer != AP_DESIGNER_SPECULAR) && !idcode) { DEBUG_INFO("LPC11xx: Unknown IDCODE 0x%08" PRIx32 "\n", idcode); } idcode = target_mem_read32(t, LPC8XX_DEVICE_ID); From 4108b649c2785c5b118e3ce6b290cd608fc6044d Mon Sep 17 00:00:00 2001 From: Richard Meadows <962920+richardeoin@users.noreply.github.com> Date: Sat, 10 Oct 2020 20:49:50 +0200 Subject: [PATCH 09/28] stm32h7: Add support for new product lines Add support for: * STM32H7B3/B0/A3 (RM0455) * STM32H723/33/25/35/30 (RM0468) Successfully tested with: * STM32H7A3ZIT (RM0455) * STM32H747XIH (check for regressions) --- src/target/stm32h7.c | 49 ++++++++++++++++++++++++++++---------------- 1 file changed, 31 insertions(+), 18 deletions(-) diff --git a/src/target/stm32h7.c b/src/target/stm32h7.c index e72d99ae..a867ed48 100644 --- a/src/target/stm32h7.c +++ b/src/target/stm32h7.c @@ -57,7 +57,7 @@ static int stm32h7_flash_erase(struct target_flash *f, target_addr addr, static int stm32h7_flash_write(struct target_flash *f, target_addr dest, const void *src, size_t len); -static const char stm32h74_driver_str[] = "STM32H74x"; +static const char stm32h7_driver_str[] = "STM32H7"; enum stm32h7_regs { @@ -142,14 +142,14 @@ enum stm32h7_regs #define D3DBGCKEN (1 << 22) -#define FLASH_SIZE_REG 0x1ff1e880 - #define BANK1_START 0x08000000 #define NUM_SECTOR_PER_BANK 8 #define FLASH_SECTOR_SIZE 0x20000 #define BANK2_START 0x08100000 enum ID_STM32H7 { - ID_STM32H74x = 0x450, + ID_STM32H74x = 0x450, /* RM0433, RM0399 */ + ID_STM32H7Bx = 0x480, /* RM0455 */ + ID_STM32H72x = 0x483, /* RM0468 */ }; struct stm32h7_flash { @@ -221,11 +221,12 @@ static void stm32h7_detach(target *t) bool stm32h7_probe(target *t) { - if (t->idcode == ID_STM32H74x) { - t->driver = stm32h74_driver_str; + uint32_t idcode = t->idcode; + if (idcode == ID_STM32H74x || idcode == ID_STM32H7Bx || idcode == ID_STM32H72x) { + t->driver = stm32h7_driver_str; t->attach = stm32h7_attach; t->detach = stm32h7_detach; - target_add_commands(t, stm32h7_cmd_list, stm32h74_driver_str); + target_add_commands(t, stm32h7_cmd_list, stm32h7_driver_str); t->target_storage = target_mem_read32(t, DBGMCU_CR); /* RM0433 Rev 4 is not really clear, what bits are needed in DBGMCU_CR. * Maybe more flags needed? @@ -437,7 +438,12 @@ static bool stm32h7_uid(target *t, int argc, const char **argv) { (void)argc; (void)argv; + uint32_t uid = 0x1ff1e800; + if (t->idcode == ID_STM32H7Bx) { + uid = 0x08fff800; /* 7B3/7A3/7B0 */ + } + int i; tc_printf(t, "0x"); for (i = 0; i < 12; i = i + 4) { @@ -553,21 +559,28 @@ static bool stm32h7_cmd_rev(target *t, int argc, const char **argv) switch (dev_id) { case 0x450: tc_printf(t, "STM32H742/743/753/750\n"); + + /* Print revision */ + char rev = '?'; + for (size_t i = 0; + i < sizeof(stm32h7xx_revisions)/sizeof(struct stm32h7xx_rev); i++) { + /* Check for matching revision */ + if (stm32h7xx_revisions[i].rev_id == rev_id) { + rev = stm32h7xx_revisions[i].revision; + } + } + tc_printf(t, "Revision %c\n", rev); + break; + + case 0x480: + tc_printf(t, "STM32H7B3/7A3/7B0\n"); + break; + case 0x483: + tc_printf(t, "STM32H723/733/725/735/730\n"); break; default: tc_printf(t, "Unknown STM32H7. This driver may not support it!\n"); } - /* Print revision */ - char rev = '?'; - for (size_t i = 0; - i < sizeof(stm32h7xx_revisions)/sizeof(struct stm32h7xx_rev); i++) { - /* Check for matching revision */ - if (stm32h7xx_revisions[i].rev_id == rev_id) { - rev = stm32h7xx_revisions[i].revision; - } - } - tc_printf(t, "Revision %c\n", rev); - return true; } From 87b546777a68463484ef9e115fda914645dcea45 Mon Sep 17 00:00:00 2001 From: Uwe Bonnes Date: Fri, 16 Oct 2020 12:07:55 +0200 Subject: [PATCH 10/28] nrf51: Be more verbose about the protection status. --- src/target/nrf51.c | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/src/target/nrf51.c b/src/target/nrf51.c index e8a02b09..038e8a8b 100644 --- a/src/target/nrf51.c +++ b/src/target/nrf51.c @@ -378,6 +378,12 @@ const struct command_s nrf51_mdm_cmd_list[] = { {NULL, NULL, NULL} }; +#define MDM_POWER_EN ADIV5_DP_REG(0x01) +#define MDM_SELECT_AP ADIV5_DP_REG(0x02) +#define MDM_STATUS ADIV5_AP_REG(0x08) +#define MDM_CONTROL ADIV5_AP_REG(0x04) +#define MDM_PROT_EN ADIV5_AP_REG(0x0C) + void nrf51_mdm_probe(ADIv5_AP_t *ap) { switch(ap->idr) { @@ -396,18 +402,16 @@ void nrf51_mdm_probe(ADIv5_AP_t *ap) t->priv = ap; t->priv_free = (void*)adiv5_ap_unref; - t->driver = "Nordic nRF52 Access Port"; + uint32_t status = adiv5_ap_read(ap, MDM_PROT_EN); + status = adiv5_ap_read(ap, MDM_PROT_EN); + if (status) + t->driver = "Nordic nRF52 Access Port"; + else + t->driver = "Nordic nRF52 Access Port (protected)"; t->regs_size = 4; target_add_commands(t, nrf51_mdm_cmd_list, t->driver); } -#define MDM_POWER_EN ADIV5_DP_REG(0x01) -#define MDM_SELECT_AP ADIV5_DP_REG(0x02) -#define MDM_STATUS ADIV5_AP_REG(0x08) -#define MDM_CONTROL ADIV5_AP_REG(0x04) -#define MDM_PROT_EN ADIV5_AP_REG(0x0C) - - static bool nrf51_mdm_cmd_erase_mass(target *t, int argc, const char **argv) { (void)argc; From 7ccf0d3e033378041ce2701cdfe1f08ca43f7c6a Mon Sep 17 00:00:00 2001 From: Uwe Bonnes Date: Fri, 9 Oct 2020 12:10:05 +0200 Subject: [PATCH 11/28] jtag_dev_t: Make dev, idcode and desc less generic. No codechange intended. --- src/platforms/hosted/dap.c | 14 +++++++------- src/platforms/hosted/stlinkv2.c | 4 ++-- src/target/adiv5_jtagdp.c | 2 +- src/target/jtag_scan.c | 12 ++++++------ src/target/jtag_scan.h | 6 +++--- 5 files changed, 19 insertions(+), 19 deletions(-) diff --git a/src/platforms/hosted/dap.c b/src/platforms/hosted/dap.c index fefaf353..a2d6e1cc 100644 --- a/src/platforms/hosted/dap.c +++ b/src/platforms/hosted/dap.c @@ -340,7 +340,7 @@ uint32_t dap_read_reg(ADIv5_DP_t *dp, uint8_t reg) uint8_t buf[8]; uint8_t dap_index = 0; if (dp->dev) - dap_index = dp->dev->dev; + dap_index = dp->dev->jd_dev; buf[0] = ID_DAP_TRANSFER; buf[1] = dap_index; buf[2] = 0x01; // Request size @@ -359,7 +359,7 @@ void dap_write_reg(ADIv5_DP_t *dp, uint8_t reg, uint32_t data) buf[0] = ID_DAP_TRANSFER; uint8_t dap_index = 0; if (dp->dev) - dap_index = dp->dev->dev; + dap_index = dp->dev->jd_dev; buf[1] = dap_index; buf[2] = 0x01; // Request size buf[3] = reg & ~DAP_TRANSFER_RnW;; @@ -391,7 +391,7 @@ unsigned int dap_read_block(ADIv5_AP_t *ap, void *dest, uint32_t src, unsigned int sz = len >> align; uint8_t dap_index = 0; if (ap->dp->dev) - dap_index = ap->dp->dev->dev; + dap_index = ap->dp->dev->jd_dev; buf[0] = ID_DAP_TRANSFER_BLOCK; buf[1] = dap_index; buf[2] = sz & 0xff; @@ -427,7 +427,7 @@ unsigned int dap_write_block(ADIv5_AP_t *ap, uint32_t dest, const void *src, unsigned int sz = len >> align; uint8_t dap_index = 0; if (ap->dp->dev) - dap_index = ap->dp->dev->dev; + dap_index = ap->dp->dev->jd_dev; buf[0] = ID_DAP_TRANSFER_BLOCK; buf[1] = dap_index; buf[2] = sz & 0xff; @@ -528,7 +528,7 @@ static uint8_t *mem_access_setup(ADIv5_AP_t *ap, uint8_t *p, } uint8_t dap_index = 0; if (ap->dp->dev) - dap_index = ap->dp->dev->dev; + dap_index = ap->dp->dev->jd_dev; *p++ = ID_DAP_TRANSFER; *p++ = dap_index; *p++ = 3; /* Nr transfers */ @@ -564,7 +564,7 @@ uint32_t dap_ap_read(ADIv5_AP_t *ap, uint16_t addr) buf[0] = ID_DAP_TRANSFER; uint8_t dap_index = 0; if (ap->dp->dev) - dap_index = ap->dp->dev->dev; + dap_index = ap->dp->dev->jd_dev; *p++ = ID_DAP_TRANSFER; *p++ = dap_index; *p++ = 2; /* Nr transfers */ @@ -585,7 +585,7 @@ void dap_ap_write(ADIv5_AP_t *ap, uint16_t addr, uint32_t value) uint8_t buf[63], *p = buf; uint8_t dap_index = 0; if (ap->dp->dev) - dap_index = ap->dp->dev->dev; + dap_index = ap->dp->dev->jd_dev; *p++ = ID_DAP_TRANSFER; *p++ = dap_index; *p++ = 2; /* Nr transfers */ diff --git a/src/platforms/hosted/stlinkv2.c b/src/platforms/hosted/stlinkv2.c index 9a645d6f..fce2fbc0 100644 --- a/src/platforms/hosted/stlinkv2.c +++ b/src/platforms/hosted/stlinkv2.c @@ -1041,10 +1041,10 @@ int jtag_scan_stlinkv2(bmp_info_t *info, const uint8_t *irlens) jtag_dev_count = stlink_read_idcodes(info, idcodes); /* Check for known devices and handle accordingly */ for(int i = 0; i < jtag_dev_count; i++) - jtag_devs[i].idcode = idcodes[i]; + jtag_devs[i].jd_idcode = idcodes[i]; for(int i = 0; i < jtag_dev_count; i++) for(int j = 0; dev_descr[j].idcode; j++) - if((jtag_devs[i].idcode & dev_descr[j].idmask) == + if((jtag_devs[i].jd_idcode & dev_descr[j].idmask) == dev_descr[j].idcode) { if(dev_descr[j].handler) dev_descr[j].handler(&jtag_devs[i]); diff --git a/src/target/adiv5_jtagdp.c b/src/target/adiv5_jtagdp.c index e4fa9c70..9b02bbef 100644 --- a/src/target/adiv5_jtagdp.c +++ b/src/target/adiv5_jtagdp.c @@ -51,7 +51,7 @@ void adiv5_jtag_dp_handler(jtag_dev_t *dev) dp->dev = dev; if ((PC_HOSTED == 0 ) || (!platform_jtag_dp_init(dp))) { - dp->idcode = dev->idcode; + dp->idcode = dev->jd_idcode; dp->dp_read = fw_adiv5_jtagdp_read; dp->error = adiv5_jtagdp_error; dp->low_access = fw_adiv5_jtagdp_low_access; diff --git a/src/target/jtag_scan.c b/src/target/jtag_scan.c index 38fb4ffc..69114d4a 100644 --- a/src/target/jtag_scan.c +++ b/src/target/jtag_scan.c @@ -94,7 +94,7 @@ int jtag_scan(const uint8_t *irlens) } jtag_devs[jtag_dev_count].ir_len = *irlens; jtag_devs[jtag_dev_count].ir_prescan = j; - jtag_devs[jtag_dev_count].dev = jtag_dev_count; + jtag_devs[jtag_dev_count].jd_dev = jtag_dev_count; j += *irlens; irlens++; jtag_dev_count++; @@ -117,7 +117,7 @@ int jtag_scan(const uint8_t *irlens) if(jtag_devs[jtag_dev_count].ir_len == 1) break; jtag_devs[++jtag_dev_count].ir_len = 1; jtag_devs[jtag_dev_count].ir_prescan = j; - jtag_devs[jtag_dev_count].dev = jtag_dev_count; + jtag_devs[jtag_dev_count].jd_dev = jtag_dev_count; } else jtag_devs[jtag_dev_count].ir_len++; j++; } @@ -169,9 +169,9 @@ int jtag_scan(const uint8_t *irlens) jtagtap_shift_dr(); for(i = 0; i < jtag_dev_count; i++) { if(!jtag_proc.jtagtap_next(0, 1)) continue; - jtag_devs[i].idcode = 1; + jtag_devs[i].jd_idcode = 1; for(j = 2; j; j <<= 1) - if(jtag_proc.jtagtap_next(0, 1)) jtag_devs[i].idcode |= j; + if(jtag_proc.jtagtap_next(0, 1)) jtag_devs[i].jd_idcode |= j; } DEBUG_INFO("Return to Run-Test/Idle\n"); @@ -181,11 +181,11 @@ int jtag_scan(const uint8_t *irlens) /* Check for known devices and handle accordingly */ for(i = 0; i < jtag_dev_count; i++) for(j = 0; dev_descr[j].idcode; j++) - if((jtag_devs[i].idcode & dev_descr[j].idmask) == + if((jtag_devs[i].jd_idcode & dev_descr[j].idmask) == dev_descr[j].idcode) { jtag_devs[i].current_ir = -1; /* Save description in table */ - jtag_devs[i].descr = dev_descr[j].descr; + jtag_devs[i].jd_descr = dev_descr[j].descr; /* Call handler to initialise/probe device further */ if(dev_descr[j].handler) dev_descr[j].handler(&jtag_devs[i]); diff --git a/src/target/jtag_scan.h b/src/target/jtag_scan.h index 5134ec1d..30ced851 100644 --- a/src/target/jtag_scan.h +++ b/src/target/jtag_scan.h @@ -27,7 +27,7 @@ typedef struct jtag_dev_s { union { - uint8_t dev; + uint8_t jd_dev; uint8_t dr_prescan; }; uint8_t dr_postscan; @@ -35,8 +35,8 @@ typedef struct jtag_dev_s { uint8_t ir_len; uint8_t ir_prescan; uint8_t ir_postscan; - uint32_t idcode; - const char *descr; + uint32_t jd_idcode; + const char *jd_descr; uint32_t current_ir; } jtag_dev_t; From ba26adce53ba0fe4f8dd477a37f88dfd28094729 Mon Sep 17 00:00:00 2001 From: Uwe Bonnes Date: Fri, 9 Oct 2020 13:14:57 +0200 Subject: [PATCH 12/28] remote.h: Remove typo. --- src/remote.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/remote.h b/src/remote.h index 550f7ebe..caf56c51 100644 --- a/src/remote.h +++ b/src/remote.h @@ -147,7 +147,7 @@ #define REMOTE_MEM_READ_STR (char []){ REMOTE_SOM, REMOTE_HL_PACKET, REMOTE_MEM_READ, \ HEX_U32(address), HEX_U32(count), REMOTE_EOM, 0 } #define REMOTE_DP_READ_STR (char []){ REMOTE_SOM, REMOTE_HL_PACKET, REMOTE_DP_READ, \ - 'f', 'f','%', '0', '4', 'x', REMOTE_EOM, 0 } + '%', '0', '4', 'x', REMOTE_EOM, 0 } #define REMOTE_LOW_ACCESS_STR (char []){ REMOTE_SOM, REMOTE_HL_PACKET, REMOTE_LOW_ACCESS, \ '%','0', '2', 'x', '%', '0', '4', 'x', HEX_U32(csw), REMOTE_EOM, 0 } #define REMOTE_AP_READ_STR (char []){ REMOTE_SOM, REMOTE_HL_PACKET, REMOTE_AP_READ, \ From 752d14ca3ee944ecb75031631f00110fc39987cb Mon Sep 17 00:00:00 2001 From: Uwe Bonnes Date: Fri, 9 Oct 2020 13:15:12 +0200 Subject: [PATCH 13/28] remote.c: Add comments. --- src/remote.c | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/src/remote.c b/src/remote.c index 83418920..765afc3a 100644 --- a/src/remote.c +++ b/src/remote.c @@ -142,7 +142,7 @@ void remotePacketProcessSWD(uint8_t i, char *packet) bool badParity; switch (packet[1]) { - case REMOTE_INIT: /* SS = initialise ================================= */ + case REMOTE_INIT: /* SS = initialise =============================== */ if (i==2) { swdptap_init(); _respond(REMOTE_RESP_OK, 0); @@ -151,26 +151,26 @@ void remotePacketProcessSWD(uint8_t i, char *packet) } break; - case REMOTE_IN_PAR: /* = In parity ================================== */ + case REMOTE_IN_PAR: /* SI = In parity ============================= */ ticks=remotehston(2,&packet[2]); badParity = swd_proc.swdptap_seq_in_parity(¶m, ticks); _respond(badParity?REMOTE_RESP_PARERR:REMOTE_RESP_OK,param); break; - case REMOTE_IN: /* = In ========================================= */ + case REMOTE_IN: /* Si = In ======================================= */ ticks=remotehston(2,&packet[2]); param = swd_proc.swdptap_seq_in(ticks); _respond(REMOTE_RESP_OK,param); break; - case REMOTE_OUT: /* = Out ======================================== */ + case REMOTE_OUT: /* So= Out ====================================== */ ticks=remotehston(2,&packet[2]); param=remotehston(-1, &packet[4]); swd_proc.swdptap_seq_out(param, ticks); _respond(REMOTE_RESP_OK, 0); break; - case REMOTE_OUT_PAR: /* = Out parity ================================= */ + case REMOTE_OUT_PAR: /* SO = Out parity ========================== */ ticks=remotehston(2,&packet[2]); param=remotehston(-1, &packet[4]); swd_proc.swdptap_seq_out_parity(param, ticks); @@ -191,19 +191,19 @@ void remotePacketProcessJTAG(uint8_t i, char *packet) uint64_t DI; switch (packet[1]) { - case REMOTE_INIT: /* = initialise ================================= */ + case REMOTE_INIT: /* JS = initialise ============================= */ jtagtap_init(); remote_dp.dp_read = fw_adiv5_jtagdp_read; remote_dp.low_access = fw_adiv5_jtagdp_low_access; _respond(REMOTE_RESP_OK, 0); break; - case REMOTE_RESET: /* = reset ================================= */ + case REMOTE_RESET: /* JR = reset ================================= */ jtag_proc.jtagtap_reset(); _respond(REMOTE_RESP_OK, 0); break; - case REMOTE_TMS: /* = TMS Sequence ================================== */ + case REMOTE_TMS: /* JT = TMS Sequence ============================ */ ticks=remotehston(2,&packet[2]); MS=remotehston(2,&packet[4]); @@ -215,7 +215,7 @@ void remotePacketProcessJTAG(uint8_t i, char *packet) } break; - case REMOTE_TDITDO_TMS: /* = TDI/TDO ========================================= */ + case REMOTE_TDITDO_TMS: /* JD = TDI/TDO ========================================= */ case REMOTE_TDITDO_NOTMS: if (i<5) { @@ -232,7 +232,7 @@ void remotePacketProcessJTAG(uint8_t i, char *packet) } break; - case REMOTE_NEXT: /* = NEXT ======================================== */ + case REMOTE_NEXT: /* JN = NEXT ======================================== */ if (i!=4) { _respond(REMOTE_RESP_ERR,REMOTE_ERROR_WRONGLEN); } else { @@ -309,16 +309,16 @@ void remotePacketProcessHL(uint8_t i, char *packet) remote_ap.apsel = remotehston(2, packet); remote_ap.dp = &remote_dp; switch (index) { - case REMOTE_HL_CHECK: + case REMOTE_HL_CHECK: /* HC = Check availability of HL commands*/ _respond(REMOTE_RESP_OK, 0); break; - case REMOTE_DP_READ: + case REMOTE_DP_READ: /* Hd = Read from DP register */ packet += 2; uint16_t addr16 = remotehston(4, packet); uint32_t data = adiv5_dp_read(&remote_dp, addr16); _respond_buf(REMOTE_RESP_OK, (uint8_t*)&data, 4); break; - case REMOTE_LOW_ACCESS: + case REMOTE_LOW_ACCESS: /* HL = Low level access */ packet += 2; addr16 = remotehston(4, packet); packet += 4; @@ -326,13 +326,13 @@ void remotePacketProcessHL(uint8_t i, char *packet) data = remote_dp.low_access(&remote_dp, remote_ap.apsel, addr16, value); _respond_buf(REMOTE_RESP_OK, (uint8_t*)&data, 4); break; - case REMOTE_AP_READ: + case REMOTE_AP_READ: /* Ha = Read from AP register*/ packet += 2; addr16 = remotehston(4, packet); data = adiv5_ap_read(&remote_ap, addr16); _respond_buf(REMOTE_RESP_OK, (uint8_t*)&data, 4); break; - case REMOTE_AP_WRITE: + case REMOTE_AP_WRITE: /* Ha = Write to AP register*/ packet += 2; addr16 = remotehston(4, packet); packet += 4; @@ -340,12 +340,12 @@ void remotePacketProcessHL(uint8_t i, char *packet) adiv5_ap_write(&remote_ap, addr16, value); _respond(REMOTE_RESP_OK, 0); break; - case REMOTE_AP_MEM_READ: + case REMOTE_AP_MEM_READ: /* HM = Read from Mem and set csw */ packet += 2; remote_ap.csw = remotehston(8, packet); packet += 6; /*fall through*/ - case REMOTE_MEM_READ: + case REMOTE_MEM_READ: /* Hh = Read from Mem */ packet += 2; uint32_t address = remotehston(8, packet); packet += 8; @@ -359,12 +359,12 @@ void remotePacketProcessHL(uint8_t i, char *packet) _respond(REMOTE_RESP_ERR, 0); remote_ap.dp->fault = 0; break; - case REMOTE_AP_MEM_WRITE_SIZED: + case REMOTE_AP_MEM_WRITE_SIZED: /* Hm = Write to memory and set csw */ packet += 2; remote_ap.csw = remotehston(8, packet); packet += 6; /*fall through*/ - case REMOTE_MEM_WRITE_SIZED: + case REMOTE_MEM_WRITE_SIZED: /* HH = Write to memory*/ packet += 2; enum align align = remotehston(2, packet); packet += 2; From 0f5fb6b9a0f09f25466f9786731ad39eeba70ec9 Mon Sep 17 00:00:00 2001 From: Uwe Bonnes Date: Fri, 9 Oct 2020 14:03:22 +0200 Subject: [PATCH 14/28] remote: Initialise dp_read and low_access with SWD_INIT. Before "mon s" after "mon j" failed. --- src/remote.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/remote.c b/src/remote.c index 765afc3a..87e86205 100644 --- a/src/remote.c +++ b/src/remote.c @@ -126,12 +126,10 @@ static void _respondS(char respCode, const char *s) } static ADIv5_DP_t remote_dp = { - .dp_read = firmware_swdp_read, .ap_read = firmware_ap_read, .ap_write = firmware_ap_write, .mem_read = firmware_mem_read, .mem_write_sized = firmware_mem_write_sized, - .low_access = firmware_swdp_low_access, }; @@ -144,6 +142,8 @@ void remotePacketProcessSWD(uint8_t i, char *packet) switch (packet[1]) { case REMOTE_INIT: /* SS = initialise =============================== */ if (i==2) { + remote_dp.dp_read = firmware_swdp_read; + remote_dp.low_access = firmware_swdp_low_access; swdptap_init(); _respond(REMOTE_RESP_OK, 0); } else { @@ -192,9 +192,9 @@ void remotePacketProcessJTAG(uint8_t i, char *packet) switch (packet[1]) { case REMOTE_INIT: /* JS = initialise ============================= */ - jtagtap_init(); remote_dp.dp_read = fw_adiv5_jtagdp_read; remote_dp.low_access = fw_adiv5_jtagdp_low_access; + jtagtap_init(); _respond(REMOTE_RESP_OK, 0); break; From 6e2a0740644a0285ea5f45c65b81e4fe7ce8b830 Mon Sep 17 00:00:00 2001 From: Uwe Bonnes Date: Fri, 9 Oct 2020 15:52:09 +0200 Subject: [PATCH 15/28] bmp_remote: Deny high level JTAG for now. jtag_devs and jtag_dev_count needs to be known on th firmware side and remote_dp->dev needs to be filled with jtag_dev_t. --- src/platforms/hosted/bmp_remote.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/platforms/hosted/bmp_remote.c b/src/platforms/hosted/bmp_remote.c index 9b679473..b12f5aec 100644 --- a/src/platforms/hosted/bmp_remote.c +++ b/src/platforms/hosted/bmp_remote.c @@ -345,6 +345,10 @@ void remote_adiv5_dp_defaults(ADIv5_DP_t *dp) "Please update BMP firmware for substantial speed increase!\n"); return; } + if (dp->dev) { + DEBUG_WARN("Falling back to ll as high level JTAG is not yet possible!\n"); + return; + } dp->low_access = remote_adiv5_low_access; dp->dp_read = remote_adiv5_dp_read; dp->ap_write = remote_adiv5_ap_write; From 3d92b82678182acda2bb43786143100d2b9b6577 Mon Sep 17 00:00:00 2001 From: Uwe Bonnes Date: Fri, 9 Oct 2020 16:34:43 +0200 Subject: [PATCH 16/28] jtag: Use index and not device structure for jtag_dev_write_ir and jtag_dev_shift_dr --- src/platforms/hosted/bmp_remote.c | 2 +- src/platforms/hosted/dap.c | 21 +++++++-------------- src/platforms/hosted/stlinkv2.c | 2 +- src/target/adiv5.h | 11 ++--------- src/target/adiv5_jtagdp.c | 14 +++++++------- src/target/adiv5_swdp.c | 1 + src/target/jtag_devs.h | 2 +- src/target/jtag_scan.c | 8 +++++--- src/target/jtag_scan.h | 4 ++-- 9 files changed, 27 insertions(+), 38 deletions(-) diff --git a/src/platforms/hosted/bmp_remote.c b/src/platforms/hosted/bmp_remote.c index b12f5aec..47abab8f 100644 --- a/src/platforms/hosted/bmp_remote.c +++ b/src/platforms/hosted/bmp_remote.c @@ -345,7 +345,7 @@ void remote_adiv5_dp_defaults(ADIv5_DP_t *dp) "Please update BMP firmware for substantial speed increase!\n"); return; } - if (dp->dev) { + if (dp->dp_jd_index < JTAG_MAX_DEVS) { DEBUG_WARN("Falling back to ll as high level JTAG is not yet possible!\n"); return; } diff --git a/src/platforms/hosted/dap.c b/src/platforms/hosted/dap.c index a2d6e1cc..03844d11 100644 --- a/src/platforms/hosted/dap.c +++ b/src/platforms/hosted/dap.c @@ -339,8 +339,7 @@ uint32_t dap_read_reg(ADIv5_DP_t *dp, uint8_t reg) { uint8_t buf[8]; uint8_t dap_index = 0; - if (dp->dev) - dap_index = dp->dev->jd_dev; + dap_index = dp->dp_jd_index; buf[0] = ID_DAP_TRANSFER; buf[1] = dap_index; buf[2] = 0x01; // Request size @@ -358,8 +357,7 @@ void dap_write_reg(ADIv5_DP_t *dp, uint8_t reg, uint32_t data) buf[0] = ID_DAP_TRANSFER; uint8_t dap_index = 0; - if (dp->dev) - dap_index = dp->dev->jd_dev; + dap_index = dp->dp_jd_index; buf[1] = dap_index; buf[2] = 0x01; // Request size buf[3] = reg & ~DAP_TRANSFER_RnW;; @@ -390,8 +388,7 @@ unsigned int dap_read_block(ADIv5_AP_t *ap, void *dest, uint32_t src, uint8_t buf[1024]; unsigned int sz = len >> align; uint8_t dap_index = 0; - if (ap->dp->dev) - dap_index = ap->dp->dev->jd_dev; + dap_index = ap->dp->dp_jd_index; buf[0] = ID_DAP_TRANSFER_BLOCK; buf[1] = dap_index; buf[2] = sz & 0xff; @@ -426,8 +423,7 @@ unsigned int dap_write_block(ADIv5_AP_t *ap, uint32_t dest, const void *src, uint8_t buf[1024]; unsigned int sz = len >> align; uint8_t dap_index = 0; - if (ap->dp->dev) - dap_index = ap->dp->dev->jd_dev; + dap_index = ap->dp->dp_jd_index; buf[0] = ID_DAP_TRANSFER_BLOCK; buf[1] = dap_index; buf[2] = sz & 0xff; @@ -527,8 +523,7 @@ static uint8_t *mem_access_setup(ADIv5_AP_t *ap, uint8_t *p, break; } uint8_t dap_index = 0; - if (ap->dp->dev) - dap_index = ap->dp->dev->jd_dev; + dap_index = ap->dp->dp_jd_index; *p++ = ID_DAP_TRANSFER; *p++ = dap_index; *p++ = 3; /* Nr transfers */ @@ -563,8 +558,7 @@ uint32_t dap_ap_read(ADIv5_AP_t *ap, uint16_t addr) uint8_t buf[63], *p = buf; buf[0] = ID_DAP_TRANSFER; uint8_t dap_index = 0; - if (ap->dp->dev) - dap_index = ap->dp->dev->jd_dev; + dap_index = ap->dp->dp_jd_index; *p++ = ID_DAP_TRANSFER; *p++ = dap_index; *p++ = 2; /* Nr transfers */ @@ -584,8 +578,7 @@ void dap_ap_write(ADIv5_AP_t *ap, uint16_t addr, uint32_t value) DEBUG_PROBE("dap_ap_write addr %04x value %08x\n", addr, value); uint8_t buf[63], *p = buf; uint8_t dap_index = 0; - if (ap->dp->dev) - dap_index = ap->dp->dev->jd_dev; + dap_index = ap->dp->dp_jd_index; *p++ = ID_DAP_TRANSFER; *p++ = dap_index; *p++ = 2; /* Nr transfers */ diff --git a/src/platforms/hosted/stlinkv2.c b/src/platforms/hosted/stlinkv2.c index fce2fbc0..42941c8f 100644 --- a/src/platforms/hosted/stlinkv2.c +++ b/src/platforms/hosted/stlinkv2.c @@ -1047,7 +1047,7 @@ int jtag_scan_stlinkv2(bmp_info_t *info, const uint8_t *irlens) if((jtag_devs[i].jd_idcode & dev_descr[j].idmask) == dev_descr[j].idcode) { if(dev_descr[j].handler) - dev_descr[j].handler(&jtag_devs[i]); + dev_descr[j].handler(i, dev_descr[j].idcode); break; } diff --git a/src/target/adiv5.h b/src/target/adiv5.h index 39d4d5ab..ee296d31 100644 --- a/src/target/adiv5.h +++ b/src/target/adiv5.h @@ -174,15 +174,8 @@ typedef struct ADIv5_DP_s { void (*mem_read)(ADIv5_AP_t *ap, void *dest, uint32_t src, size_t len); void (*mem_write_sized)(ADIv5_AP_t *ap, uint32_t dest, const void *src, size_t len, enum align align); -#if PC_HOSTED == 1 - jtag_dev_t *dev; + uint8_t dp_jd_index; uint8_t fault; -#else - union { - jtag_dev_t *dev; - uint8_t fault; - }; -#endif } ADIv5_DP_t; struct ADIv5_AP_s { @@ -270,7 +263,7 @@ ADIv5_AP_t *adiv5_new_ap(ADIv5_DP_t *dp, uint8_t apsel); void adiv5_ap_ref(ADIv5_AP_t *ap); void adiv5_ap_unref(ADIv5_AP_t *ap); -void adiv5_jtag_dp_handler(jtag_dev_t *dev); +void adiv5_jtag_dp_handler(uint8_t jd_index, uint32_t j_idcode); int platform_jtag_dp_init(ADIv5_DP_t *dp); void adiv5_mem_write(ADIv5_AP_t *ap, uint32_t dest, const void *src, size_t len); diff --git a/src/target/adiv5_jtagdp.c b/src/target/adiv5_jtagdp.c index 9b02bbef..12dad85a 100644 --- a/src/target/adiv5_jtagdp.c +++ b/src/target/adiv5_jtagdp.c @@ -41,7 +41,7 @@ static uint32_t adiv5_jtagdp_error(ADIv5_DP_t *dp); static void adiv5_jtagdp_abort(ADIv5_DP_t *dp, uint32_t abort); -void adiv5_jtag_dp_handler(jtag_dev_t *dev) +void adiv5_jtag_dp_handler(uint8_t jd_index, uint32_t j_idcode) { ADIv5_DP_t *dp = (void*)calloc(1, sizeof(*dp)); if (!dp) { /* calloc failed: heap exhaustion */ @@ -49,9 +49,9 @@ void adiv5_jtag_dp_handler(jtag_dev_t *dev) return; } - dp->dev = dev; + dp->dp_jd_index = jd_index; if ((PC_HOSTED == 0 ) || (!platform_jtag_dp_init(dp))) { - dp->idcode = dev->jd_idcode; + dp->idcode = j_idcode; dp->dp_read = fw_adiv5_jtagdp_read; dp->error = adiv5_jtagdp_error; dp->low_access = fw_adiv5_jtagdp_low_access; @@ -85,11 +85,11 @@ uint32_t fw_adiv5_jtagdp_low_access(ADIv5_DP_t *dp, uint8_t RnW, request = ((uint64_t)value << 3) | ((addr >> 1) & 0x06) | (RnW?1:0); - jtag_dev_write_ir(&jtag_proc, dp->dev, APnDP ? IR_APACC : IR_DPACC); + jtag_dev_write_ir(&jtag_proc, dp->dp_jd_index, APnDP ? IR_APACC : IR_DPACC); platform_timeout_set(&timeout, 2000); do { - jtag_dev_shift_dr(&jtag_proc, dp->dev, (uint8_t*)&response, + jtag_dev_shift_dr(&jtag_proc, dp->dp_jd_index, (uint8_t*)&response, (uint8_t*)&request, 35); ack = response & 0x07; } while(!platform_timeout_is_expired(&timeout) && (ack == JTAGDP_ACK_WAIT)); @@ -106,6 +106,6 @@ uint32_t fw_adiv5_jtagdp_low_access(ADIv5_DP_t *dp, uint8_t RnW, static void adiv5_jtagdp_abort(ADIv5_DP_t *dp, uint32_t abort) { uint64_t request = (uint64_t)abort << 3; - jtag_dev_write_ir(&jtag_proc, dp->dev, IR_ABORT); - jtag_dev_shift_dr(&jtag_proc, dp->dev, NULL, (const uint8_t*)&request, 35); + jtag_dev_write_ir(&jtag_proc, dp->dp_jd_index, IR_ABORT); + jtag_dev_shift_dr(&jtag_proc, dp->dp_jd_index, NULL, (const uint8_t*)&request, 35); } diff --git a/src/target/adiv5_swdp.c b/src/target/adiv5_swdp.c index eba7cab5..457b35fa 100644 --- a/src/target/adiv5_swdp.c +++ b/src/target/adiv5_swdp.c @@ -39,6 +39,7 @@ int adiv5_swdp_scan(void) target_list_free(); ADIv5_DP_t *dp = (void*)calloc(1, sizeof(*dp)); + dp->dp_jd_index = JTAG_MAX_DEVS; /* Tag for BMP_REMOTE */ if (!dp) { /* calloc failed: heap exhaustion */ DEBUG_WARN("calloc: failed in %s\n", __func__); return -1; diff --git a/src/target/jtag_devs.h b/src/target/jtag_devs.h index 47d17d0b..8c2c0b5a 100644 --- a/src/target/jtag_devs.h +++ b/src/target/jtag_devs.h @@ -22,7 +22,7 @@ typedef const struct jtag_dev_descr_s { const uint32_t idcode; const uint32_t idmask; const char * const descr; - void (*const handler)(jtag_dev_t *dev); + void (*const handler)(uint8_t jd_index, uint32_t j_idcode); } jtag_dev_descr_t; extern jtag_dev_descr_t dev_descr[]; diff --git a/src/target/jtag_scan.c b/src/target/jtag_scan.c index 69114d4a..90843f5e 100644 --- a/src/target/jtag_scan.c +++ b/src/target/jtag_scan.c @@ -188,15 +188,16 @@ int jtag_scan(const uint8_t *irlens) jtag_devs[i].jd_descr = dev_descr[j].descr; /* Call handler to initialise/probe device further */ if(dev_descr[j].handler) - dev_descr[j].handler(&jtag_devs[i]); + dev_descr[j].handler(i, dev_descr[j].idcode); break; } return jtag_dev_count; } -void jtag_dev_write_ir(jtag_proc_t *jp, jtag_dev_t *d, uint32_t ir) +void jtag_dev_write_ir(jtag_proc_t *jp, uint8_t jd_index, uint32_t ir) { + jtag_dev_t *d = &jtag_devs[jd_index]; if(ir == d->current_ir) return; for(int i = 0; i < jtag_dev_count; i++) jtag_devs[i].current_ir = -1; @@ -209,8 +210,9 @@ void jtag_dev_write_ir(jtag_proc_t *jp, jtag_dev_t *d, uint32_t ir) jtagtap_return_idle(); } -void jtag_dev_shift_dr(jtag_proc_t *jp, jtag_dev_t *d, uint8_t *dout, const uint8_t *din, int ticks) +void jtag_dev_shift_dr(jtag_proc_t *jp, uint8_t jd_index, uint8_t *dout, const uint8_t *din, int ticks) { + jtag_dev_t *d = &jtag_devs[jd_index]; jtagtap_shift_dr(); jp->jtagtap_tdi_seq(0, ones, d->dr_prescan); if(dout) diff --git a/src/target/jtag_scan.h b/src/target/jtag_scan.h index 30ced851..80896687 100644 --- a/src/target/jtag_scan.h +++ b/src/target/jtag_scan.h @@ -43,8 +43,8 @@ typedef struct jtag_dev_s { extern struct jtag_dev_s jtag_devs[JTAG_MAX_DEVS+1]; extern int jtag_dev_count; -void jtag_dev_write_ir(jtag_proc_t *jp, jtag_dev_t *dev, uint32_t ir); -void jtag_dev_shift_dr(jtag_proc_t *jp, jtag_dev_t *dev, uint8_t *dout, const uint8_t *din, int ticks); +void jtag_dev_write_ir(jtag_proc_t *jp, uint8_t jd_index, uint32_t ir); +void jtag_dev_shift_dr(jtag_proc_t *jp, uint8_t jd_index, uint8_t *dout, const uint8_t *din, int ticks); #endif From 8b929c12c9ea21b489c566be6cb94b1be36954ce Mon Sep 17 00:00:00 2001 From: Uwe Bonnes Date: Fri, 9 Oct 2020 17:42:11 +0200 Subject: [PATCH 17/28] hosted/jtag: Transfer jtag_devs to firmware. --- src/include/platform_support.h | 1 - src/platforms/hosted/bmp_remote.c | 31 +++++++++++++++++++++++++++---- src/platforms/hosted/bmp_remote.h | 1 + src/platforms/hosted/platform.c | 6 ++++++ src/remote.c | 27 ++++++++++++++++++++++++++- src/remote.h | 16 +++++++++++++++- src/target/adiv5.h | 2 ++ src/target/jtag_scan.c | 15 +++++++++++++++ src/target/jtag_scan.h | 2 +- 9 files changed, 93 insertions(+), 8 deletions(-) diff --git a/src/include/platform_support.h b/src/include/platform_support.h index 88f49263..968440a5 100644 --- a/src/include/platform_support.h +++ b/src/include/platform_support.h @@ -45,6 +45,5 @@ bool platform_srst_get_val(void); bool platform_target_get_power(void); void platform_target_set_power(bool power); void platform_request_boot(void); - #endif diff --git a/src/platforms/hosted/bmp_remote.c b/src/platforms/hosted/bmp_remote.c index 47abab8f..e6d4ead0 100644 --- a/src/platforms/hosted/bmp_remote.c +++ b/src/platforms/hosted/bmp_remote.c @@ -336,8 +336,7 @@ static void remote_ap_mem_write_sized( void remote_adiv5_dp_defaults(ADIv5_DP_t *dp) { uint8_t construct[REMOTE_MAX_MSG_SIZE]; - int s = snprintf((char *)construct, REMOTE_MAX_MSG_SIZE, "%s", - REMOTE_HL_CHECK_STR); + int s = snprintf((char *)construct, REMOTE_MAX_MSG_SIZE, REMOTE_HL_CHECK_STR); platform_buffer_write(construct, s); s = platform_buffer_read(construct, REMOTE_MAX_MSG_SIZE); if ((!s) || (construct[0] == REMOTE_RESP_ERR)) { @@ -346,8 +345,15 @@ void remote_adiv5_dp_defaults(ADIv5_DP_t *dp) return; } if (dp->dp_jd_index < JTAG_MAX_DEVS) { - DEBUG_WARN("Falling back to ll as high level JTAG is not yet possible!\n"); - return; + s = snprintf((char *)construct, REMOTE_MAX_MSG_SIZE, REMOTE_HL_JTAG_DEV_STR, + dp->dp_jd_index); + platform_buffer_write(construct, s); + s = platform_buffer_read(construct, REMOTE_MAX_MSG_SIZE); + if ((!s) || (construct[0] != REMOTE_RESP_OK)) { + DEBUG_WARN( + "Please update BMP firmware to allow high level jtag commands!\n"); + return; + } } dp->low_access = remote_adiv5_low_access; dp->dp_read = remote_adiv5_dp_read; @@ -356,3 +362,20 @@ void remote_adiv5_dp_defaults(ADIv5_DP_t *dp) dp->mem_read = remote_ap_mem_read; dp->mem_write_sized = remote_ap_mem_write_sized; } + +void remote_add_jtag_dev(int i, const jtag_dev_t *jtag_dev) +{ + uint8_t construct[REMOTE_MAX_MSG_SIZE]; + int s = snprintf((char *)construct, REMOTE_MAX_MSG_SIZE, + REMOTE_JTAG_ADD_DEV_STR, + i, + jtag_dev->dr_prescan, + jtag_dev->dr_postscan, + jtag_dev->ir_len, + jtag_dev->ir_prescan, + jtag_dev->ir_postscan, + jtag_dev->current_ir); + platform_buffer_write(construct, s); + s = platform_buffer_read(construct, REMOTE_MAX_MSG_SIZE); + /* No check for error here. Done in remote_adiv5_dp_defaults!*/ +} diff --git a/src/platforms/hosted/bmp_remote.h b/src/platforms/hosted/bmp_remote.h index ea21b7b6..f7c7dc80 100644 --- a/src/platforms/hosted/bmp_remote.h +++ b/src/platforms/hosted/bmp_remote.h @@ -39,5 +39,6 @@ void remote_srst_set_val(bool assert); bool remote_srst_get_val(void); const char *platform_target_voltage(void); void remote_adiv5_dp_defaults(ADIv5_DP_t *dp); +void remote_add_jtag_dev(int i, const jtag_dev_t *jtag_dev); #define __BMP_REMOTE_H_ #endif diff --git a/src/platforms/hosted/platform.c b/src/platforms/hosted/platform.c index dd46589d..f1f88b8a 100644 --- a/src/platforms/hosted/platform.c +++ b/src/platforms/hosted/platform.c @@ -392,6 +392,12 @@ int platform_swdptap_init(void) return -1; } +void platform_add_jtag_dev(int i, const jtag_dev_t *jtag_dev) +{ + if (info.bmp_type == BMP_TYPE_BMP) + remote_add_jtag_dev(i, jtag_dev); +} + int platform_jtag_scan(const uint8_t *lrlens) { switch (info.bmp_type) { diff --git a/src/remote.c b/src/remote.c index 87e86205..aa828013 100644 --- a/src/remote.c +++ b/src/remote.c @@ -189,7 +189,7 @@ void remotePacketProcessJTAG(uint8_t i, char *packet) uint64_t DO; uint8_t ticks; uint64_t DI; - + jtag_dev_t jtag_dev; switch (packet[1]) { case REMOTE_INIT: /* JS = initialise ============================= */ remote_dp.dp_read = fw_adiv5_jtagdp_read; @@ -241,6 +241,23 @@ void remotePacketProcessJTAG(uint8_t i, char *packet) } break; + case REMOTE_ADD_JTAG_DEV: /* JJ = fill firmware jtag_devs */ + if (i < 22) { + _respond(REMOTE_RESP_ERR,REMOTE_ERROR_WRONGLEN); + } else { + memset(&jtag_dev, 0, sizeof(jtag_dev)); + uint8_t index = remotehston(2, &packet[ 2]); + jtag_dev.dr_prescan = remotehston(2, &packet[ 4]); + jtag_dev.dr_postscan = remotehston(2, &packet[ 6]); + jtag_dev.ir_len = remotehston(2, &packet[ 8]); + jtag_dev.ir_prescan = remotehston(2, &packet[10]); + jtag_dev.ir_postscan = remotehston(2, &packet[12]); + jtag_dev.current_ir = remotehston(8, &packet[14]); + jtag_add_device(index, &jtag_dev); + _respond(REMOTE_RESP_OK, 0); + } + break; + default: _respond(REMOTE_RESP_ERR,REMOTE_ERROR_UNRECOGNISED); break; @@ -312,6 +329,14 @@ void remotePacketProcessHL(uint8_t i, char *packet) case REMOTE_HL_CHECK: /* HC = Check availability of HL commands*/ _respond(REMOTE_RESP_OK, 0); break; + case REMOTE_HL_JTAG_DEV: /* HJ for jtag device to use */ + if (i < 4) { + _respond(REMOTE_RESP_ERR,REMOTE_ERROR_WRONGLEN); + } else { + remote_dp.dp_jd_index = remotehston(2, &packet[2]); + _respond(REMOTE_RESP_OK, 0); + } + break; case REMOTE_DP_READ: /* Hd = Read from DP register */ packet += 2; uint16_t addr16 = remotehston(4, packet); diff --git a/src/remote.h b/src/remote.h index caf56c51..64a29b07 100644 --- a/src/remote.h +++ b/src/remote.h @@ -76,6 +76,7 @@ #define REMOTE_VOLTAGE 'V' #define REMOTE_SRST_SET 'Z' #define REMOTE_SRST_GET 'z' +#define REMOTE_ADD_JTAG_DEV 'J' /* Protocol response options */ #define REMOTE_RESP_OK 'K' @@ -85,6 +86,7 @@ /* High level protocol elements */ #define REMOTE_HL_CHECK 'C' +#define REMOTE_HL_JTAG_DEV 'J' #define REMOTE_HL_PACKET 'H' #define REMOTE_DP_READ 'd' #define REMOTE_LOW_ACCESS 'L' @@ -137,13 +139,25 @@ #define REMOTE_JTAG_NEXT (char []){ REMOTE_SOM, REMOTE_JTAG_PACKET, REMOTE_NEXT, \ '%','c','%','c',REMOTE_EOM, 0 } - /* HL protocol elements */ #define HEX '%', '0', '2', 'x' #define HEX_U32(x) '%', '0', '8', 'x' #define CHR(x) '%', 'c' +#define REMOTE_JTAG_ADD_DEV_STR (char []){ REMOTE_SOM, REMOTE_JTAG_PACKET,\ + REMOTE_ADD_JTAG_DEV, \ + '%','0','2','x', /* index */ \ + '%','0','2','x', /* dr_prescan */ \ + '%','0','2','x', /* dr_postscan */ \ + '%','0','2','x', /* ir_len */ \ + '%','0','2','x', /* ir_prescan */ \ + '%','0','2','x', /* ir_postscan */ \ + HEX_U32(current_ir), /* current_ir */ \ + REMOTE_EOM, 0} + #define REMOTE_HL_CHECK_STR (char []){ REMOTE_SOM, REMOTE_HL_PACKET, REMOTE_HL_CHECK, REMOTE_EOM, 0 } +#define REMOTE_HL_JTAG_DEV_STR (char []){ REMOTE_SOM, REMOTE_HL_PACKET, \ + REMOTE_HL_JTAG_DEV, '%', '0', '2', 'x', REMOTE_EOM, 0 } #define REMOTE_MEM_READ_STR (char []){ REMOTE_SOM, REMOTE_HL_PACKET, REMOTE_MEM_READ, \ HEX_U32(address), HEX_U32(count), REMOTE_EOM, 0 } #define REMOTE_DP_READ_STR (char []){ REMOTE_SOM, REMOTE_HL_PACKET, REMOTE_DP_READ, \ diff --git a/src/target/adiv5.h b/src/target/adiv5.h index ee296d31..3af8c9bc 100644 --- a/src/target/adiv5.h +++ b/src/target/adiv5.h @@ -260,8 +260,10 @@ void adiv5_dp_write(ADIv5_DP_t *dp, uint16_t addr, uint32_t value); void adiv5_dp_init(ADIv5_DP_t *dp); void platform_adiv5_dp_defaults(ADIv5_DP_t *dp); ADIv5_AP_t *adiv5_new_ap(ADIv5_DP_t *dp, uint8_t apsel); +void remote_jtag_dev(const jtag_dev_t *jtag_dev); void adiv5_ap_ref(ADIv5_AP_t *ap); void adiv5_ap_unref(ADIv5_AP_t *ap); +void platform_add_jtag_dev(const int dev_index, const jtag_dev_t *jtag_dev); void adiv5_jtag_dp_handler(uint8_t jd_index, uint32_t j_idcode); int platform_jtag_dp_init(ADIv5_DP_t *dp); diff --git a/src/target/jtag_scan.c b/src/target/jtag_scan.c index 90843f5e..d8927f73 100644 --- a/src/target/jtag_scan.c +++ b/src/target/jtag_scan.c @@ -36,6 +36,16 @@ int jtag_dev_count; /* bucket of ones for don't care TDI */ static const uint8_t ones[] = "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"; +#if PC_HOSTED == 0 +void jtag_add_device(const int dev_index, const jtag_dev_t *jtag_dev) +{ + if (dev_index == 0) + memset(&jtag_devs, 0, sizeof(jtag_devs)); + memcpy(&jtag_devs[dev_index], jtag_dev, sizeof(jtag_dev_t)); + jtag_dev_count = dev_index + 1; +} +#endif + /* Scan JTAG chain for devices, store IR length and IDCODE (if present). * Reset TAP state machine. * Select Shift-IR state. @@ -177,6 +187,11 @@ int jtag_scan(const uint8_t *irlens) DEBUG_INFO("Return to Run-Test/Idle\n"); jtag_proc.jtagtap_next(1, 1); jtagtap_return_idle(); +#if PC_HOSTED == 1 + /*Transfer needed device information to firmware jtag_devs*/ + for(i = 0; i < jtag_dev_count; i++) + platform_add_jtag_dev(i, &jtag_devs[i]); +#endif /* Check for known devices and handle accordingly */ for(i = 0; i < jtag_dev_count; i++) diff --git a/src/target/jtag_scan.h b/src/target/jtag_scan.h index 80896687..cc6d361a 100644 --- a/src/target/jtag_scan.h +++ b/src/target/jtag_scan.h @@ -45,6 +45,6 @@ extern int jtag_dev_count; void jtag_dev_write_ir(jtag_proc_t *jp, uint8_t jd_index, uint32_t ir); void jtag_dev_shift_dr(jtag_proc_t *jp, uint8_t jd_index, uint8_t *dout, const uint8_t *din, int ticks); - +void jtag_add_device(const int dev_index, const jtag_dev_t *jtag_dev); #endif From 5bc743d22119e52019dca8a3e01a5efe699b85ea Mon Sep 17 00:00:00 2001 From: Uwe Bonnes Date: Thu, 15 Oct 2020 00:29:02 +0200 Subject: [PATCH 18/28] samd: Propagate security after setting security by chip reset. --- src/target/samd.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/target/samd.c b/src/target/samd.c index 8345e0b7..525a43b7 100644 --- a/src/target/samd.c +++ b/src/target/samd.c @@ -847,8 +847,9 @@ static bool samd_cmd_ssb(target *t, int argc, const char **argv) if (target_check_error(t)) return -1; - tc_printf(t, "Set the security bit! " - "You will need to issue 'monitor erase_mass' to clear this.\n"); + tc_printf(t, "Security bit set! " + "Scan again, attach and issue 'monitor erase_mass' to reset.\n"); + target_reset(t); return true; } From 0ffb4f7b1865ca93790cdb58d270faa62ab85360 Mon Sep 17 00:00:00 2001 From: Uwe Bonnes Date: Wed, 14 Oct 2020 23:48:41 +0200 Subject: [PATCH 19/28] cortexm: Fix protected SAM detection - Only run cortex_prepare() if reading cidr fails - With Atmel DSU detected, run cortexm_probe() --- src/target/adiv5.c | 32 +++++++++++++------------------- 1 file changed, 13 insertions(+), 19 deletions(-) diff --git a/src/target/adiv5.c b/src/target/adiv5.c index 49023eba..05777882 100644 --- a/src/target/adiv5.c +++ b/src/target/adiv5.c @@ -409,6 +409,15 @@ static bool adiv5_component_probe(ADIv5_AP_t *ap, uint32_t addr, int recursion, if (addr == 0) /* No rom table on this AP */ return false; uint32_t cidr = adiv5_ap_read_id(ap, addr + CIDR0_OFFSET); + if ((cidr & ~CID_CLASS_MASK) != CID_PREAMBLE) { + /* Maybe caused by a not halted CortexM */ + if (!ap->apsel && ((ap->idr & 0xf) == ARM_AP_TYPE_AHB)) { + if (!cortexm_prepare(ap)) + return false; /* Halting failed! */ + /* CPU now halted, read cidr again. */ + cidr = adiv5_ap_read_id(ap, addr + CIDR0_OFFSET); + } + } bool res = false; #if defined(ENABLE_DEBUG) char indent[recursion + 1]; @@ -454,6 +463,10 @@ static bool adiv5_component_probe(ADIv5_AP_t *ap, uint32_t addr, int recursion, if (recursion == 0) { ap->ap_designer = designer; ap->ap_partno = partno; + if ((ap->ap_designer == AP_DESIGNER_ATMEL) && (ap->ap_partno == 0xcd0)) { + cortexm_probe(ap); + return true; + } } for (int i = 0; i < 960; i++) { adiv5_dp_error(ap->dp); @@ -598,25 +611,6 @@ ADIv5_AP_t *adiv5_new_ap(ADIv5_DP_t *dp, uint8_t apsel) DEBUG_INFO("AP %3d: IDR=%08"PRIx32" CFG=%08"PRIx32" BASE=%08" PRIx32 " CSW=%08"PRIx32"\n", apsel, ap->idr, cfg, ap->base, ap->csw); #endif - if (!apsel && ((ap->idr & 0xf) == ARM_AP_TYPE_AHB)) { - /* Test for protected Atmel devices. Access outside DSU fails. - * For protected device, continue with Rom Table anyways. - */ - adiv5_dp_error(ap->dp); - adiv5_mem_read32(ap, CORTEXM_DHCSR); - if ( adiv5_dp_error(ap->dp) & ADIV5_DP_CTRLSTAT_STICKYERR) { - uint32_t err = adiv5_dp_error(ap->dp); - if (err & ADIV5_DP_CTRLSTAT_STICKYERR) { - DEBUG_WARN("...\nHit error on DHCSR read. Suspect protected Atmel " - "part, skipping to PIDR check.\n"); - } - } else { - if (!cortexm_prepare(ap)) { - free(ap); - return NULL; - } - } - } adiv5_ap_ref(ap); return ap; } From 9cd3193a89ef075cc3f24963503a2118d5fa0e4b Mon Sep 17 00:00:00 2001 From: Uwe Bonnes Date: Sat, 17 Oct 2020 12:45:08 +0200 Subject: [PATCH 20/28] bmp_remote.c: Fix bug introduced with 8b929c12c9e. --- src/platforms/hosted/bmp_remote.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/platforms/hosted/bmp_remote.c b/src/platforms/hosted/bmp_remote.c index e6d4ead0..e42ac54b 100644 --- a/src/platforms/hosted/bmp_remote.c +++ b/src/platforms/hosted/bmp_remote.c @@ -336,7 +336,8 @@ static void remote_ap_mem_write_sized( void remote_adiv5_dp_defaults(ADIv5_DP_t *dp) { uint8_t construct[REMOTE_MAX_MSG_SIZE]; - int s = snprintf((char *)construct, REMOTE_MAX_MSG_SIZE, REMOTE_HL_CHECK_STR); + int s = snprintf((char *)construct, REMOTE_MAX_MSG_SIZE, "%s", + REMOTE_HL_CHECK_STR); platform_buffer_write(construct, s); s = platform_buffer_read(construct, REMOTE_MAX_MSG_SIZE); if ((!s) || (construct[0] == REMOTE_RESP_ERR)) { From 77c4f9d7028ecd5a6e70ab3edc3d32df6d7e38ca Mon Sep 17 00:00:00 2001 From: Uwe Bonnes Date: Thu, 8 Oct 2020 13:33:16 +0200 Subject: [PATCH 21/28] stlink: Rework README.md - Document flashing BMP Firmware and reverting to ST firmware - Consistant nameing --- src/platforms/stlink/README.md | 87 ++++++++++++++++++++-------------- 1 file changed, 51 insertions(+), 36 deletions(-) diff --git a/src/platforms/stlink/README.md b/src/platforms/stlink/README.md index 7ca359a2..87324bb2 100644 --- a/src/platforms/stlink/README.md +++ b/src/platforms/stlink/README.md @@ -1,41 +1,63 @@ -# Blackmagic for ST -Link Adapters +# Blackmagic for STLINK Adapters -For ST-LINK V3 and ST-LINKV 2/1, as found on all Nucleo and recent Discovery -boards, use the pc-stlinkv2 branch, running on the PC and with original, -recent ST firmware. +STLINK-V3, ST-LINK/V2-1 and /V2 with original, recent ST firmware can can use the hosted branch, running the GDB server on PC. -Only if you have a ST-LINK V22 with STM32F103C8 versus the STM32F103CB on V2/1 -and you want to rewire and use the UART, consider reflashing the the Stlink -firmware. +Running the BMP firmware on ST-LINK/V2 and ST-LINK/V2-1 provides: +- built-in gdb server on the dongle +- VCP on ST-LINK/V2. Access to VCP lines needs additional wires to the STM32F103C8! +- VCP on ST-LINK/V2 clones ([Baite](https://www.mikrocontroller.net/attachment/356780/st-linkV2-mini_LRG.jpg)), accessible on the bare PCB. +- no mass storage device (MSD). A MSD may collide with company policies. -On ST-LINK V2, the original ST Bootloader can also be used with +For all commands below, unplug all other BMP/ST-LINK beside the target(*1) -- Compile firmware with "make PROBE_HOST=stlink ST_BOOTLOADER=1" +## Upload BMP Firmware: -- Upload firmware with stlink-tool from [stlink-tool](https://github.com/jeanthom/stlink-tool.git). - Before upload, replug the stlink to enter the bootloader. +- Keep the original ST Bootloader. -- After each stlink replug, call "stlink-tool" without arguments - to enter BMP or on Linux use some udev rule like +- Compile firmware with `make PROBE_HOST=stlink ST_BOOTLOADER=1` + +- Upload firmware with stlink-tool from [stlink-tool](https://github.com/UweBonnes/stlink-tool/tree/stlinkv21)(*3). + +- For ST-LINK/V2, as on older disco boards, un- and replug USB to enter the bootloader. + +- Upload BMP firmware with `stlink-tool blackmagic.bin` + +- For ST-LINK/V2, after each stlink replug, call either `blackmacic -t` or `stlink-tool` without arguments or on Linux use some udev rule like `> cat /etc/udev/rules.d/98-stlink.rules` `SUBSYSTEM=="usb", ATTRS{idVendor}=="0483", ATTRS{idProduct}=="3748", ACTION=="add", RUN+="/stlink-tool"` -- To enter Bootloader again either replug or use "dfu-util -e". - With more than one DFU device connected, you need to specify - the needed device + to enter the BMP firmware + +## Reverting to original ST Firmware with running BMP firmware: + +- Get STLINK upgrade [firmware](https://www.st.com/content/st_com/en/products/development-tools/software-development-tools/stm32-software-development-tools/stm32-programmers/stsw-link007.html) and unzip. Change to "stsw-link007/AllPlatforms/" in the unzipped directory. + +- To enter Bootloader again use `dfu-util -e`, or with ST-LINK/V2 un- and replug. + +- For ST-LINK/V2(Standalone) run `java -jar STLinkUpgrade.jar -jtag_swim -force_prog` + +- For ST-LINK/V2(embedded) run `java -jar STLinkUpgrade.jar -jtag -force_prog` + +- For ST-LINK/V21 run `java -jar STLinkUpgrade.jar -msvcp -force_prog` + +- For STLINK-V3 run `java -jar STLinkUpgrade.jar -d8_d32_msc_br -force_prog` (*2) + +
(*1) Command arguments are available to specify some specific of several devices. Look at the help for blackmagic, stlink-tool and dfu-util if really needed. For STLinkUpgrade.jar, no documentation is known, but `strings ./st/stlinkupgrade/app/a.class` may give a clue.< +
(*2) Loading firmware V37 and higher to STLINK-V3 with original bootloader will inhibit further debugging the F723 on the ST-LINK itself. There are patched bootloaders out there that do not set RDP2. +
(*3) Pull request to original author pending. ## Versions -### [Standalone ST-LINKV2](https://www.st.com/content/st_com/en/products/development-tools/hardware-development-tools/development-tool-hardware-for-mcus/debug-hardware-for-mcus/debug-hardware-for-stm32-mcus/st-link-v2.html) +### [Standalone ST-LINK/V2](https://www.st.com/content/st_com/en/products/development-tools/hardware-development-tools/development-tool-hardware-for-mcus/debug-hardware-for-mcus/debug-hardware-for-stm32-mcus/st-link-v2.html) Accessible connectors for JTAG/SWD (20-pin) and SWIM. -ST-LINKV2/ISOL). -### ST-LINKV2 clones aka "baite" +ST-LINK/V2/ISOL). +### ST-LINK/V2 clones aka "baite" JTAG/SWD/SWIM are on a 10-pin connector. CPU SWD pins are accessible on the board. ### SWIM-only ST-LINK adapters on STM8 Discovery boards -JTAG and target SWIM pins are accessible on connector (footprints). They are handled in the swlink branch. +JTAG and target SWIM pins are accessible on connector (footprints). They are handled in the swlink platform. ### SWIM-only ST-LINK adapters on STM8 Nucleo-Stm8 boards As only a SWIM connector is accessible, they are not usefull as BMP target. ### [SWD only ST-LINK adapter](https://www.st.com/content/ccc/resource/technical/document/technical_note/group0/30/c8/1d/0f/15/62/46/ef/DM00290229/files/DM00290229.pdf/jcr:content/translations/en.DM00290229.pdf) (Stm32 Nucleo Boards, recent Discovery boards) @@ -46,12 +68,12 @@ As only a SWIM connector is accessible, they are not usefull as BMP target. Newer variants have transistor for USB reenumeration Newer variants may switch onboard target power. Newer Variants may have level shifters for some signals to onboard target. -#### ST-Link/V1 -CDCACM USART pins are not accessible. MCO output is used for LED. -#### ST-Link/V2 and ST-Link/V2-A +#### ST-LINK/V1 +CDCACM USART pins are not accessible. MCO output is used for LED. Use the swlink platform! +#### ST-LINK/V2 and ST-LINK/V2-A CDCACM USART pins are not accessible. MCO is connected to on board target. -#### ST-Link/V2-1 and ST-Link/V2-B -### [STLINK-V3SET](https://www.st.com/content/st_com/en/products/development-tools/hardware-development-tools/development-tool-hardware-for-mcus/debug-hardware-for-mcus/debug-hardware-for-stm32-mcus/stlink-v3set.html) +#### ST-LINK/V2-1 and ST-LINK/V2-B +#### [STLINK-V3SET](https://www.st.com/content/st_com/en/products/development-tools/hardware-development-tools/development-tool-hardware-for-mcus/debug-hardware-for-mcus/debug-hardware-for-stm32-mcus/stlink-v3set.html) ## Wiring on Discovery and Nucleo Boards @@ -74,20 +96,13 @@ the 2 jumper shortening the 4-pin connector like this: ## BMP version detection and handling All ST-LINK variants -PC13/14 open -> Standalone ST-LINKV2 or baite, some STM32 Disco w/o accessible +PC13/14 open -> Standalone ST-LINK/V2 or baite, some STM32 Disco w/o accessible UART RX/TX PC13 low -> SWIM internal connection -PC13/PC14 both low -> ST-LinkV2 on some F4_Diso boards. +PC13/PC14 both low -> ST-LINK/V2 on some F4_Diso boards. -## Reflashing BMP back to ST-LINK V2 original firmware - -If you built the firmware to use ST-Link v2's bootloader (with `ST_BOOTLOADER=1`), you should be able to reflash back to original firmware using the [STLinkUpgrade utility](https://www.st.com/en/development-tools/stsw-link007.html). Do not check the "Change type" checkbox unless you know what you are doing, as it will change the USB VID:PID and change how it operates. - -Replug ST-LINK before flashing if the utility doesn't detect it. -##ST-LINK V2.1 Force Bootloader entry +## ST-LINK V2.1 force Bootloader entry On ST-LINK V2/2-1 boards with the original bootloader, you can force -bootloader entry with asserting NRST of the STM32F103CB of the USB -powered board. Serveral attempts may be needed. -https://www.carminenoviello.com/2016/02/26/restore-st-link-interface-bad-update-2-26-15-firmware/ +bootloader entry with asserting [NRST](https://www.carminenoviello.com/2016/02/26/restore-st-link-interface-bad-update-2-26-15-firmware/) of the STM32F103CB of the USB powered board. Serveral attempts may be needed. From 3270138ec24ae408c6c9b584a389e4ef8e9b0ddf Mon Sep 17 00:00:00 2001 From: Uwe Bonnes Date: Sat, 17 Oct 2020 14:10:37 +0200 Subject: [PATCH 22/28] Revert 69e577c9243ce027b628e96881ce2416213fef43 What was thought to be a typo is apsel = 0xff for a dp access. --- src/remote.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/remote.h b/src/remote.h index 64a29b07..3cfd1b0a 100644 --- a/src/remote.h +++ b/src/remote.h @@ -161,7 +161,7 @@ #define REMOTE_MEM_READ_STR (char []){ REMOTE_SOM, REMOTE_HL_PACKET, REMOTE_MEM_READ, \ HEX_U32(address), HEX_U32(count), REMOTE_EOM, 0 } #define REMOTE_DP_READ_STR (char []){ REMOTE_SOM, REMOTE_HL_PACKET, REMOTE_DP_READ, \ - '%', '0', '4', 'x', REMOTE_EOM, 0 } + 'f', 'f', '%', '0', '4', 'x', REMOTE_EOM, 0 } #define REMOTE_LOW_ACCESS_STR (char []){ REMOTE_SOM, REMOTE_HL_PACKET, REMOTE_LOW_ACCESS, \ '%','0', '2', 'x', '%', '0', '4', 'x', HEX_U32(csw), REMOTE_EOM, 0 } #define REMOTE_AP_READ_STR (char []){ REMOTE_SOM, REMOTE_HL_PACKET, REMOTE_AP_READ, \ From cdd07544d5df183520d23ef41420ae02c78aac2e Mon Sep 17 00:00:00 2001 From: Uwe Bonnes Date: Sat, 17 Oct 2020 16:24:19 +0200 Subject: [PATCH 23/28] Cortexm: Allow pure debug on devices not yet handled for flashing - Recognize STM32L552 and MIMXRT10XX - Fix another PIDR - Fix bad debug print string. --- src/platforms/hosted/dap.c | 2 +- src/target/adiv5.c | 2 +- src/target/cortexm.c | 10 ++++++++++ 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/src/platforms/hosted/dap.c b/src/platforms/hosted/dap.c index 03844d11..73bf3c0a 100644 --- a/src/platforms/hosted/dap.c +++ b/src/platforms/hosted/dap.c @@ -397,7 +397,7 @@ unsigned int dap_read_block(ADIv5_AP_t *ap, void *dest, uint32_t src, dbg_dap_cmd(buf, 1023, 5 + 1); unsigned int transferred = buf[0] + (buf[1] << 8); if (buf[2] >= DAP_TRANSFER_FAULT) { - DEBUG_WARN("dap_read_block @ %08 "PRIx32 " fault -> line reset\n", src); + DEBUG_WARN("dap_read_block @ %08" PRIx32 " fault -> line reset\n", src); dap_line_reset(); } if (sz != transferred) { diff --git a/src/target/adiv5.c b/src/target/adiv5.c index 05777882..71fef15e 100644 --- a/src/target/adiv5.c +++ b/src/target/adiv5.c @@ -218,7 +218,7 @@ static const struct { {0x924, 0x13, 0, aa_nosupport, cidc_unknown, PIDR_PN_BIT_STRINGS("Cortex-M3 ETM", "(Embedded Trace)")}, {0x925, 0x13, 0, aa_nosupport, cidc_unknown, PIDR_PN_BIT_STRINGS("Cortex-M4 ETM", "(Embedded Trace)")}, {0x930, 0x00, 0, aa_nosupport, cidc_unknown, PIDR_PN_BIT_STRINGS("Cortex-R4 ETM", "(Embedded Trace)")}, - {0x932, 0x00, 0, aa_nosupport, cidc_unknown, PIDR_PN_BIT_STRINGS("CoreSight MTB-M0+", "(Simple Execution Trace)")}, + {0x932, 0x31, 0x0a31, aa_nosupport, cidc_unknown, PIDR_PN_BIT_STRINGS("CoreSight MTB-M0+", "(Simple Execution Trace)")}, {0x941, 0x00, 0, aa_nosupport, cidc_unknown, PIDR_PN_BIT_STRINGS("CoreSight TPIU-Lite", "(Trace Port Interface Unit)")}, {0x950, 0x00, 0, aa_nosupport, cidc_unknown, PIDR_PN_BIT_STRINGS("CoreSight Component", "(unidentified Cortex-A9 component)")}, {0x955, 0x00, 0, aa_nosupport, cidc_unknown, PIDR_PN_BIT_STRINGS("CoreSight Component", "(unidentified Cortex-A5 component)")}, diff --git a/src/target/cortexm.c b/src/target/cortexm.c index f2bf5259..274edf63 100644 --- a/src/target/cortexm.c +++ b/src/target/cortexm.c @@ -379,6 +379,10 @@ bool cortexm_probe(ADIv5_AP_t *ap) switch (ap->ap_designer) { case AP_DESIGNER_FREESCALE: PROBE(kinetis_probe); + if (ap->ap_partno == 0x88c) { + t->driver = "MIMXRT10xx(no flash)"; + target_halt_resume(t, 0); + } break; case AP_DESIGNER_STM: PROBE(stm32f1_probe); @@ -386,6 +390,10 @@ bool cortexm_probe(ADIv5_AP_t *ap) PROBE(stm32h7_probe); PROBE(stm32l0_probe); PROBE(stm32l4_probe); + if (ap->ap_partno == 0x472) { + t->driver = "STM32L552(no flash)"; + target_halt_resume(t, 0); + } break; case AP_DESIGNER_CYPRESS: DEBUG_WARN("Unhandled Cypress device\n"); @@ -432,6 +440,8 @@ bool cortexm_probe(ADIv5_AP_t *ap) PROBE(lpc17xx_probe); } #undef PROBE + /* Restart the CortexM we stopped for Romtable scan. Allow pure debug.*/ + target_halt_resume(t, 0); return true; } From c161521c262d58c10cf42e3f2c80b84d65c4e039 Mon Sep 17 00:00:00 2001 From: Uwe Bonnes Date: Sun, 18 Oct 2020 12:32:11 +0200 Subject: [PATCH 24/28] cortexm: Designer ARM must be in the default path when probing. --- src/target/adiv5.c | 4 +++- src/target/cortexm.c | 29 +++++++++++++++++------------ 2 files changed, 20 insertions(+), 13 deletions(-) diff --git a/src/target/adiv5.c b/src/target/adiv5.c index 71fef15e..b6990c94 100644 --- a/src/target/adiv5.c +++ b/src/target/adiv5.c @@ -201,8 +201,10 @@ static const struct { {0x471, 0x00, 0, aa_nosupport, cidc_unknown, PIDR_PN_BIT_STRINGS("Cortex-M0 ROM", "(Cortex-M0 ROM)")}, {0x490, 0x00, 0, aa_nosupport, cidc_unknown, PIDR_PN_BIT_STRINGS("Cortex-A15 GIC", "(Generic Interrupt Controller)")}, {0x4c0, 0x00, 0, aa_nosupport, cidc_unknown, PIDR_PN_BIT_STRINGS("Cortex-M0+ ROM", "(Cortex-M0+ ROM)")}, + {0x4c3, 0x00, 0, aa_nosupport, cidc_unknown, PIDR_PN_BIT_STRINGS("Cortex-M3 ROM", "(Cortex-M3 ROM)")}, {0x4c4, 0x00, 0, aa_nosupport, cidc_unknown, PIDR_PN_BIT_STRINGS("Cortex-M4 ROM", "(Cortex-M4 ROM)")}, - {0x4c7, 0x00, 0, aa_nosupport, cidc_unknown, PIDR_PN_BIT_STRINGS("Cortex-M7 PPB", "(Private Peripheral Bus ROM Table)")}, + {0x4c7, 0x00, 0, aa_nosupport, cidc_unknown, PIDR_PN_BIT_STRINGS("Cortex-M7 PPB", "(Cortex-M7 Private Peripheral Bus ROM Table)")}, + {0x4c8, 0x00, 0, aa_nosupport, cidc_unknown, PIDR_PN_BIT_STRINGS("Cortex-M7 ROM", "(Cortex-M7 ROM)")}, {0x906, 0x14, 0, aa_nosupport, cidc_unknown, PIDR_PN_BIT_STRINGS("CoreSight CTI", "(Cross Trigger)")}, {0x907, 0x21, 0, aa_nosupport, cidc_unknown, PIDR_PN_BIT_STRINGS("CoreSight ETB", "(Trace Buffer)")}, {0x908, 0x12, 0, aa_nosupport, cidc_unknown, PIDR_PN_BIT_STRINGS("CoreSight CSTF", "(Trace Funnel)")}, diff --git a/src/target/cortexm.c b/src/target/cortexm.c index 274edf63..e5231412 100644 --- a/src/target/cortexm.c +++ b/src/target/cortexm.c @@ -409,12 +409,6 @@ bool cortexm_probe(ADIv5_AP_t *ap) PROBE(samd_probe); PROBE(samx5x_probe); break; - case AP_DESIGNER_ARM: - if (ap->ap_partno == 0x4c3) /* Care for STM32F1 clones */ - PROBE(stm32f1_probe); - PROBE(sam3x_probe); - PROBE(lpc11xx_probe); /* LPC24C11 */ - break; case AP_DESIGNER_ENERGY_MICRO: PROBE(efm32_probe); break; @@ -425,16 +419,27 @@ bool cortexm_probe(ADIv5_AP_t *ap) PROBE(lpc11xx_probe); /* LPC845 */ break; default: + if (ap->ap_designer != AP_DESIGNER_ARM) { + /* Report unexpected designers */ #if PC_HOSTED == 0 - gdb_outf("Please report Designer %3x and Partno %3x and the probed " - "device\n", ap->ap_designer, ap->ap_partno); + gdb_outf("Please report Designer %3x and Partno %3x and the " + "probed device\n", ap->ap_designer, ap->ap_partno); #else - DEBUG_WARN("Please report Designer %3x and Partno %3x and the probed " - "device\n", ap->ap_designer, ap->ap_partno); + DEBUG_WARN("Please report Designer %3x and Partno %3x and the " + "probed device\n", ap->ap_designer, ap->ap_partno); #endif - PROBE(lpc11xx_probe); /* Let's get feedback if LPC11 is also Specular*/ + } + if (ap->ap_partno == 0x4c3) /* Cortex-M3 ROM */ + PROBE(stm32f1_probe); /* Care for STM32F1 clones */ + else if (ap->ap_partno == 0x471) { /* Cortex-M0 ROM */ + PROBE(lpc11xx_probe); /* LPC24C11 */ + PROBE(lpc43xx_probe); + } + else if (ap->ap_partno == 0x4c4) /* Cortex-M4 ROM */ + PROBE(lpc43xx_probe); + /* Info on PIDR of these parts wanted! */ + PROBE(sam3x_probe); PROBE(lpc15xx_probe); - PROBE(lpc43xx_probe); PROBE(lmi_probe); PROBE(ke04_probe); PROBE(lpc17xx_probe); From f15b1d776377a5f759ffed6f447eb5afe5fb89a7 Mon Sep 17 00:00:00 2001 From: Uwe Bonnes Date: Sun, 18 Oct 2020 15:41:40 +0200 Subject: [PATCH 25/28] cl_utils: Clip opt_flash_start only when not set. --- src/platforms/hosted/cmsis_dap.c | 2 +- src/platforms/pc/cl_utils.c | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/platforms/hosted/cmsis_dap.c b/src/platforms/hosted/cmsis_dap.c index c955761a..6c58578e 100644 --- a/src/platforms/hosted/cmsis_dap.c +++ b/src/platforms/hosted/cmsis_dap.c @@ -51,7 +51,7 @@ static int report_size = 512 + 1; // TODO: read actual report size /* LPC845 Breakout Board Rev. 0 report invalid response with > 65 bytes */ int dap_init(bmp_info_t *info) { - printf("dap_init\n"); + DEBUG_INFO("dap_init\n"); if (hid_init()) return -1; int size = strlen(info->serial); diff --git a/src/platforms/pc/cl_utils.c b/src/platforms/pc/cl_utils.c index 60191f14..545e102c 100644 --- a/src/platforms/pc/cl_utils.c +++ b/src/platforms/pc/cl_utils.c @@ -158,6 +158,7 @@ void cl_init(BMP_CL_OPTIONS_t *opt, int argc, char **argv) int c; opt->opt_target_dev = 1; opt->opt_flash_size = 16 * 1024 *1024; + opt->opt_flash_start = 0xffffffff; while((c = getopt(argc, argv, "eEhHv:d:s:I:c:CnltVta:S:jpP:rR")) != -1) { switch(c) { case 'c': @@ -362,7 +363,7 @@ int cl_execute(BMP_CL_OPTIONS_t *opt) break; } } - if (opt->opt_flash_start < flash_start) + if (opt->opt_flash_start == 0xffffffff) opt->opt_flash_start = flash_start; if (opt->opt_mode == BMP_MODE_TEST) goto target_detach; From 0995fe1288660c3b0a3d4e09e48a1b6b0611848b Mon Sep 17 00:00:00 2001 From: Uwe Bonnes Date: Sun, 18 Oct 2020 15:11:46 +0200 Subject: [PATCH 26/28] cmsis-dap: Various fixes - decrease report size to 64, otherwise MIMRXT10x0-EVK crashed when reading larger memory block - dp_read_reg acts direct, fixing CortexM core register read. - length of data to write with read_block. --- src/platforms/hosted/cmsis_dap.c | 11 ++--------- src/platforms/hosted/dap.c | 2 +- 2 files changed, 3 insertions(+), 10 deletions(-) diff --git a/src/platforms/hosted/cmsis_dap.c b/src/platforms/hosted/cmsis_dap.c index 6c58578e..4d2bb0bd 100644 --- a/src/platforms/hosted/cmsis_dap.c +++ b/src/platforms/hosted/cmsis_dap.c @@ -47,7 +47,7 @@ uint8_t mode; /*- Variables ---------------------------------------------------------------*/ static hid_device *handle = NULL; static uint8_t hid_buffer[1024 + 1]; -static int report_size = 512 + 1; // TODO: read actual report size +static int report_size = 64 + 1; // TODO: read actual report size /* LPC845 Breakout Board Rev. 0 report invalid response with > 65 bytes */ int dap_init(bmp_info_t *info) { @@ -129,14 +129,7 @@ static uint32_t dap_dp_low_access(struct ADIv5_DP_s *dp, uint8_t RnW, static uint32_t dap_dp_read_reg(ADIv5_DP_t *dp, uint16_t addr) { - uint32_t res; - if (addr & ADIV5_APnDP) { - dap_dp_low_access(dp, ADIV5_LOW_READ, addr, 0); - res = dap_dp_low_access(dp, ADIV5_LOW_READ, - ADIV5_DP_RDBUFF, 0); - } else { - res = dap_dp_low_access(dp, ADIV5_LOW_READ, addr, 0); - } + uint32_t res = dap_dp_low_access(dp, ADIV5_LOW_READ, addr, 0); DEBUG_PROBE("dp_read %04x %08" PRIx32 "\n", addr, res); return res; } diff --git a/src/platforms/hosted/dap.c b/src/platforms/hosted/dap.c index 73bf3c0a..0f0efee8 100644 --- a/src/platforms/hosted/dap.c +++ b/src/platforms/hosted/dap.c @@ -394,7 +394,7 @@ unsigned int dap_read_block(ADIv5_AP_t *ap, void *dest, uint32_t src, buf[2] = sz & 0xff; buf[3] = (sz >> 8) & 0xff; buf[4] = SWD_AP_DRW | DAP_TRANSFER_RnW; - dbg_dap_cmd(buf, 1023, 5 + 1); + dbg_dap_cmd(buf, 1023, 5); unsigned int transferred = buf[0] + (buf[1] << 8); if (buf[2] >= DAP_TRANSFER_FAULT) { DEBUG_WARN("dap_read_block @ %08" PRIx32 " fault -> line reset\n", src); From 976c763747e9b5cedeef0d18d33a33b031ad4c95 Mon Sep 17 00:00:00 2001 From: Uwe Bonnes Date: Mon, 19 Oct 2020 10:08:22 +0200 Subject: [PATCH 27/28] jtag remote: Start fixing handling M0 (second jtag) for LPC4322 in high-level - LPC11: Only print none-null unknown idcodes. --- src/remote.c | 4 ++-- src/target/lpc11xx.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/remote.c b/src/remote.c index aa828013..3e0a70e1 100644 --- a/src/remote.c +++ b/src/remote.c @@ -333,7 +333,7 @@ void remotePacketProcessHL(uint8_t i, char *packet) if (i < 4) { _respond(REMOTE_RESP_ERR,REMOTE_ERROR_WRONGLEN); } else { - remote_dp.dp_jd_index = remotehston(2, &packet[2]); + remote_dp.dp_jd_index = remotehston(2, packet); _respond(REMOTE_RESP_OK, 0); } break; @@ -411,7 +411,7 @@ void remotePacketProcessHL(uint8_t i, char *packet) remote_ap.dp->fault = 0; break; } - _respond_buf(REMOTE_RESP_OK, src, len); + _respond(REMOTE_RESP_OK, 0); break; default: _respond(REMOTE_RESP_ERR,REMOTE_ERROR_UNRECOGNISED); diff --git a/src/target/lpc11xx.c b/src/target/lpc11xx.c index 5cad1e77..2b6d28b5 100644 --- a/src/target/lpc11xx.c +++ b/src/target/lpc11xx.c @@ -137,7 +137,7 @@ lpc11xx_probe(target *t) target_add_commands(t, lpc11xx_cmd_list, "LPC8N04"); return true; } - if ((t->t_designer != AP_DESIGNER_SPECULAR) && !idcode) { + if ((t->t_designer != AP_DESIGNER_SPECULAR) && idcode) { DEBUG_INFO("LPC11xx: Unknown IDCODE 0x%08" PRIx32 "\n", idcode); } idcode = target_mem_read32(t, LPC8XX_DEVICE_ID); From 59dc1b7eb4f3a0fda23d2c8624c3ecd26515fec8 Mon Sep 17 00:00:00 2001 From: Uwe Bonnes Date: Mon, 19 Oct 2020 16:02:16 +0200 Subject: [PATCH 28/28] cortex-m7: Give hint about buggy core revision. --- src/target/cortexm.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/target/cortexm.c b/src/target/cortexm.c index e5231412..09657353 100644 --- a/src/target/cortexm.c +++ b/src/target/cortexm.c @@ -319,6 +319,10 @@ bool cortexm_probe(ADIv5_AP_t *ap) case 0xc27: t->core = "M7"; + if ((((cpuid >> 20) & 0xf) == 0) && (((cpuid >> 0) & 0xf) < 2)) { + DEBUG_WARN("Silicon bug: Single stepping will enter pending " + "exception handler with this M7 core revision!\n"); + } break; case 0xc60: