From 9bb2807706f44ecbafc501f1b5b0f05670853e58 Mon Sep 17 00:00:00 2001 From: Uwe Bonnes Date: Wed, 30 Sep 2020 16:40:47 +0200 Subject: [PATCH 1/6] 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 2/6] 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 3/6] 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 4/6] 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 5/6] 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 6/6] 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);