From f435bd21368654500ad67aa8ba64a66b6bf4f4db Mon Sep 17 00:00:00 2001 From: Rafael Silva Date: Fri, 29 Jul 2022 19:44:10 +0100 Subject: [PATCH] target/adi: rework handling of TARGETID add missing fetching of targetid in jlink probes clarify how targetid is being read handle idcode as debug_port_id use targetid when available to identify device in probe routine --- src/platforms/hosted/jlink_adiv5_swdp.c | 10 +++ src/platforms/hosted/stlinkv2.c | 11 ++-- src/target/adiv5.c | 40 ++++++++---- src/target/adiv5.h | 27 ++++++--- src/target/adiv5_jtagdp.c | 6 +- src/target/adiv5_swdp.c | 42 +++++++------ src/target/cortexm.c | 81 +++++++++++++------------ src/target/stm32l4.c | 10 +-- src/target/target_internal.h | 10 ++- 9 files changed, 143 insertions(+), 94 deletions(-) diff --git a/src/platforms/hosted/jlink_adiv5_swdp.c b/src/platforms/hosted/jlink_adiv5_swdp.c index c20746c..6844989 100644 --- a/src/platforms/hosted/jlink_adiv5_swdp.c +++ b/src/platforms/hosted/jlink_adiv5_swdp.c @@ -180,12 +180,22 @@ int jlink_swdp_scan(bmp_info_t *info) free(dp); return 0; } + dp->version = (dp->debug_port_id & ADIV5_DP_DPIDR_VERSION_MASK) >> ADIV5_DP_DPIDR_VERSION_OFFSET; + dp->dp_read = jlink_adiv5_swdp_read; dp->error = jlink_adiv5_swdp_error; dp->low_access = jlink_adiv5_swdp_low_access; dp->abort = jlink_adiv5_swdp_abort; jlink_adiv5_swdp_error(dp); + + if (dp->version >= 2) { + /* READ TARGETID, only available on DPv2 or later */ + adiv5_dp_write(dp, ADIV5_DP_SELECT, 2); /* TARGETID is on bank 2 */ + dp->target_id = adiv5_dp_read(dp, ADIV5_DP_TARGETID); + adiv5_dp_write(dp, ADIV5_DP_SELECT, 0); + } + adiv5_dp_init(dp); return target_list?1:0; } diff --git a/src/platforms/hosted/stlinkv2.c b/src/platforms/hosted/stlinkv2.c index d13f1d9..c268b91 100644 --- a/src/platforms/hosted/stlinkv2.c +++ b/src/platforms/hosted/stlinkv2.c @@ -1078,17 +1078,20 @@ int stlink_enter_debug_swd(bmp_info_t *info, ADIv5_DP_t *dp) if (stlink_usb_error_check(data, true)) exit( -1); dp->debug_port_id = stlink_read_coreid(); + dp->version = (dp->debug_port_id & ADIV5_DP_DPIDR_VERSION_MASK) >> ADIV5_DP_DPIDR_VERSION_OFFSET; + dp->dp_read = stlink_dp_read; dp->error = stlink_dp_error; dp->low_access = stlink_dp_low_access; dp->abort = stlink_dp_abort; stlink_dp_error(dp); - if ((dp->debug_port_id & ADIV5_DP_DPIDR_VERSION_MASK) == ADIV5_DP_DPIDR_VERSION_DPv2) { - adiv5_dp_write(dp, ADIV5_DP_SELECT, 2); - dp->targetid = adiv5_dp_read(dp, ADIV5_DP_CTRLSTAT); + + if (dp->version >= 2) { + /* READ TARGETID, only available on DPv2 or later */ + adiv5_dp_write(dp, ADIV5_DP_SELECT, 2); /* TARGETID is on bank 2 */ + dp->target_id = adiv5_dp_read(dp, ADIV5_DP_TARGETID); adiv5_dp_write(dp, ADIV5_DP_SELECT, 0); - DEBUG_INFO("TARGETID 0x%08" PRIx32 "\n", dp->targetid); } return 0; } diff --git a/src/target/adiv5.c b/src/target/adiv5.c index de66055..b5f070b 100644 --- a/src/target/adiv5.c +++ b/src/target/adiv5.c @@ -332,7 +332,7 @@ static uint32_t cortexm_initial_halt(ADIv5_AP_t *ap) const uint32_t dhcsr_ctl = CORTEXM_DHCSR_DBGKEY | CORTEXM_DHCSR_C_DEBUGEN | CORTEXM_DHCSR_C_HALT; const uint32_t dhcsr_valid = CORTEXM_DHCSR_S_HALT | CORTEXM_DHCSR_C_DEBUGEN; - const bool use_low_access = !(ap->dp->debug_port_id & ADIV5_DP_DPIDR_MINDP); + const bool use_low_access = !ap->dp->mindp; platform_timeout halt_timeout; platform_timeout_set(&halt_timeout, cortexm_wait_timeout); @@ -682,30 +682,44 @@ static void rp_rescue_setup(ADIv5_DP_t *dp) void adiv5_dp_init(ADIv5_DP_t *dp) { + /* designer code is in the same format in IDCODE and DPIDR */ + /* common handling */ /* - * the code in the DPIDR is in the form + * the code in the DPIDR/IDCODE is in the form * Bits 10:7 - JEP-106 Continuation code * Bits 6:0 - JEP-106 Identity code * here we convert it to our internal representation, See JEP-106 code list * note, this is the code of the designer not the implementer, we expect it to be ARM */ const uint16_t designer = (dp->debug_port_id & ADIV5_DP_DPIDR_DESIGNER_MASK) >> ADIV5_DP_DPIDR_DESIGNER_OFFSET; - dp->designer_code = (designer & ADIV5_DP_DESIGNER_JEP106_CONT_MASK) << 1U | - (designer & ADIV5_DP_DESIGNER_JEP106_CODE_MASK); - dp->partno = (dp->debug_port_id & ADIV5_DP_DPIDR_PARTNO_MASK) >> ADIV5_DP_DPIDR_PARTNO_OFFSET; + dp->designer_code = + (designer & ADIV5_DP_DESIGNER_JEP106_CONT_MASK) << 1U | (designer & ADIV5_DP_DESIGNER_JEP106_CODE_MASK); - /* Check DPIDR for a valid manufacturer and sensible PARTNO */ - if (dp->designer_code == 0 || dp->partno == 0xff7fU) { - DEBUG_WARN("Invalid DP DPIDR %08" PRIx32 "\n", dp->debug_port_id); + /* on JTAG IDCODE this is actually the version */ + dp->revision = (dp->debug_port_id & ADIV5_DP_DPIDR_REVISION_MASK) >> ADIV5_DP_DPIDR_REVISION_OFFSET; + + if (dp->version > 0) { + /* debug_port_id is valid DPIDR */ + dp->partno = (dp->debug_port_id & ADIV5_DP_DPIDR_PARTNO_MASK) >> ADIV5_DP_DPIDR_PARTNO_OFFSET; + dp->mindp = !!(dp->debug_port_id & ADIV5_DP_DPIDR_MINDP); + } else { + /* called from JTAG scan, debug_port_id is JTAG TAP IDCODE */ + dp->partno = (dp->debug_port_id & JTAG_IDCODE_PARTNO_MASK) >> JTAG_IDCODE_PARTNO_OFFSET; + dp->mindp = false; + } + + /* Check for a valid designer */ + if (dp->designer_code == 0) { + DEBUG_WARN("Invalid DP ID %08" PRIx32 "\n", dp->debug_port_id); free(dp); return; } - DEBUG_INFO("DPIDR 0x%08" PRIx32 " (v%d %srev%d) designer 0x%" PRIx32 " partno 0x%" PRIx32 "\n", dp->debug_port_id, - (uint8_t)((dp->debug_port_id & ADIV5_DP_DPIDR_VERSION_MASK) >> ADIV5_DP_DPIDR_VERSION_OFFSET), - (dp->debug_port_id & ADIV5_DP_DPIDR_MINDP) ? "MINDP " : "", - (uint8_t)((dp->debug_port_id & ADIV5_DP_DPIDR_REVISION_MASK) >> ADIV5_DP_DPIDR_REVISION_OFFSET), dp->designer_code, - dp->partno); + DEBUG_INFO("DP ID 0x%08" PRIx32 " (v%d %srev%d) designer 0x%" PRIx32 " partno 0x%" PRIx32 "\n", dp->debug_port_id, + dp->version, dp->mindp ? "MINDP " : "", dp->revision, dp->designer_code, dp->partno); + + if (dp->version >= 2 && dp->target_id != 0) + DEBUG_INFO("TARGETID 0x%08" PRIx32 "\n", dp->target_id); if (dp->designer_code == JEP106_MANUFACTURER_RASPBERRY && dp->partno == 0x2) { rp_rescue_setup(dp); diff --git a/src/target/adiv5.h b/src/target/adiv5.h index 50828bd..170d1fb 100644 --- a/src/target/adiv5.h +++ b/src/target/adiv5.h @@ -41,7 +41,7 @@ #define ADIV5_DP_DPIDR ADIV5_DP_REG(0x0U) #define ADIV5_DP_ABORT ADIV5_DP_REG(0x0U) #define ADIV5_DP_CTRLSTAT ADIV5_DP_REG(0x4U) -#define ADIV5_DP_TARGETID (ADIV5_DP_BANK2 | ADIV5_DP_REG(0x4U)) +#define ADIV5_DP_TARGETID ADIV5_DP_REG(0x4U) /* ADIV5_DP_BANK2 */ #define ADIV5_DP_SELECT ADIV5_DP_REG(0x8U) #define ADIV5_DP_RDBUFF ADIV5_DP_REG(0xCU) #define ADIV5_DP_TARGETSEL ADIV5_DP_REG(0xCU) @@ -68,7 +68,7 @@ #define ADIV5_DP_TARGETID_TDESIGNER_OFFSET 1U #define ADIV5_DP_TARGETID_TDESIGNER_MASK (0x7ffU << ADIV5_DP_TARGETID_TDESIGNER_OFFSET) -/* DP DPIDR/TARGETID DESIGNER */ +/* DP DPIDR/TARGETID/IDCODE DESIGNER */ /* Bits 10:7 - JEP-106 Continuation code */ /* Bits 6:0 - JEP-106 Identity code */ #define ADIV5_DP_DESIGNER_JEP106_CONT_OFFSET 7U @@ -146,6 +146,14 @@ #define ADIV5_ROM_ROMENTRY_PRESENT (1U << 0U) #define ADIV5_ROM_ROMENTRY_OFFSET (0xFFFFF000U) +/* JTAG TAP IDCODE */ +#define JTAG_IDCODE_VERSION_OFFSET 28U +#define JTAG_IDCODE_VERSION_MASK (0xfU << JTAG_IDCODE_VERSION_OFFSET) +#define JTAG_IDCODE_PARTNO_OFFSET 12U +#define JTAG_IDCODE_PARTNO_MASK (0xffffU << JTAG_IDCODE_PARTNO_OFFSET) +#define JTAG_IDCODE_DESIGNER_OFFSET 1U +#define JTAG_IDCODE_DESIGNER_MASK (0x7ffU << JTAG_IDCODE_DESIGNER_OFFSET) + /* Constants to make RnW parameters more clear in code */ #define ADIV5_LOW_WRITE 0 #define ADIV5_LOW_READ 1 @@ -220,11 +228,7 @@ typedef struct ADIv5_DP_s { int refcnt; uint32_t debug_port_id; - - uint16_t designer_code; - uint16_t partno; - - uint32_t targetid; /* Contains IDCODE for DPv2 devices.*/ + uint32_t target_id; /* present on DPv2 or later */ void (*seq_out)(uint32_t tms_states, size_t clock_cycles); void (*seq_out_parity)(uint32_t tms_states, size_t clock_cycles); @@ -254,6 +258,15 @@ typedef struct ADIv5_DP_s { void (*mem_write_sized)(ADIv5_AP_t *ap, uint32_t dest, const void *src, size_t len, enum align align); uint8_t dp_jd_index; uint8_t fault; + + uint8_t version; + + uint8_t revision; + bool mindp; + + /* DP designer (not implementer!) and partno */ + uint16_t designer_code; + uint16_t partno; } ADIv5_DP_t; struct ADIv5_AP_s { diff --git a/src/target/adiv5_jtagdp.c b/src/target/adiv5_jtagdp.c index ce5e9e5..66e2976 100644 --- a/src/target/adiv5_jtagdp.c +++ b/src/target/adiv5_jtagdp.c @@ -48,11 +48,7 @@ void adiv5_jtag_dp_handler(uint8_t jd_index) } dp->dp_jd_index = jd_index; - /* From the ADI spec : - * The architecture does not require that the TAP IDCODE - * register value and the DPIDR (ADIv5) value are the same - * should read DPIDR here - */ + /* JTAG routine passes IDCODE to port ID and version = 0 */ dp->debug_port_id = jtag_devs[jd_index].jd_idcode; if ((PC_HOSTED == 0 ) || (!platform_jtag_dp_init(dp))) { dp->dp_read = fw_adiv5_jtagdp_read; diff --git a/src/target/adiv5_swdp.c b/src/target/adiv5_swdp.c index 2718553..58f3038 100644 --- a/src/target/adiv5_swdp.c +++ b/src/target/adiv5_swdp.c @@ -93,8 +93,6 @@ int adiv5_swdp_scan(uint32_t targetid) * 0x1a Arm CoreSight SW-DP activation sequence * 20 bits start of reset another reset sequence*/ initial_dp->seq_out(0x1a0, 12); - uint32_t dpidr = 0; - volatile uint32_t target_id = 0; bool scan_multidrop = true; if (!targetid || !initial_dp->dp_low_write) { /* No targetID given on the command line or probe can not @@ -102,7 +100,7 @@ int adiv5_swdp_scan(uint32_t targetid) dp_line_reset(initial_dp); TRY_CATCH (e, EXCEPTION_ALL) { - dpidr = initial_dp->dp_read(initial_dp, ADIV5_DP_DPIDR); + initial_dp->debug_port_id = initial_dp->dp_read(initial_dp, ADIV5_DP_DPIDR); } if (e.type || initial_dp->fault) { scan_multidrop = false; @@ -114,24 +112,27 @@ int adiv5_swdp_scan(uint32_t targetid) initial_dp->fault = 0; TRY_CATCH (e, EXCEPTION_ALL) { - dpidr = initial_dp->dp_read(initial_dp, ADIV5_DP_DPIDR); + initial_dp->debug_port_id = initial_dp->dp_read(initial_dp, ADIV5_DP_DPIDR); } if (e.type || initial_dp->fault) { DEBUG_WARN("No usable DP found\n"); return -1; } } - if ((dpidr & ADIV5_DP_DPIDR_VERSION_MASK) == ADIV5_DP_DPIDR_VERSION_DPv2) { + + initial_dp->version = + (initial_dp->debug_port_id & ADIV5_DP_DPIDR_VERSION_MASK) >> ADIV5_DP_DPIDR_VERSION_OFFSET; + if (initial_dp->version >= 2) { scan_multidrop = true; /* Read TargetID. Can be done with device in WFI, sleep or reset!*/ - adiv5_dp_write(initial_dp, ADIV5_DP_SELECT, 2); - target_id = adiv5_dp_read(initial_dp, ADIV5_DP_CTRLSTAT); + adiv5_dp_write(initial_dp, ADIV5_DP_SELECT, 2); /* TARGETID is on bank 2 */ + initial_dp->target_id = adiv5_dp_read(initial_dp, ADIV5_DP_TARGETID); adiv5_dp_write(initial_dp, ADIV5_DP_SELECT, 0); - DEBUG_INFO("TARGETID %08" PRIx32 "\n", target_id); const uint16_t tdesigner = - (target_id & ADIV5_DP_TARGETID_TDESIGNER_MASK) >> ADIV5_DP_TARGETID_TDESIGNER_OFFSET; - const uint16_t tpartno = (target_id & ADIV5_DP_TARGETID_TPARTNO_MASK) >> ADIV5_DP_TARGETID_TPARTNO_OFFSET; + (initial_dp->target_id & ADIV5_DP_TARGETID_TDESIGNER_MASK) >> ADIV5_DP_TARGETID_TDESIGNER_OFFSET; + const uint16_t tpartno = + (initial_dp->target_id & ADIV5_DP_TARGETID_TPARTNO_MASK) >> ADIV5_DP_TARGETID_TPARTNO_OFFSET; /* convert it to our internal representation, See JEP-106 code list */ const uint16_t designer_code = (tdesigner & ADIV5_DP_DESIGNER_JEP106_CONT_MASK) << 1U | (tdesigner & ADIV5_DP_DESIGNER_JEP106_CODE_MASK); @@ -150,23 +151,25 @@ int adiv5_swdp_scan(uint32_t targetid) scan_multidrop = false; } } else { - target_id = targetid; + initial_dp->target_id = targetid; } const volatile size_t nr_dps = (scan_multidrop) ? 16U : 1U; volatile uint32_t dp_targetid; + volatile uint32_t dp_debug_port_id; for (volatile size_t i = 0; i < nr_dps; i++) { if (scan_multidrop) { dp_line_reset(initial_dp); - dp_targetid = (i << 28U) | (target_id & 0x0fffffffU); + dp_targetid = (i << 28U) | (initial_dp->target_id & 0x0fffffffU); initial_dp->dp_low_write(initial_dp, ADIV5_DP_TARGETSEL, dp_targetid); TRY_CATCH (e, EXCEPTION_ALL) { - dpidr = initial_dp->dp_read(initial_dp, ADIV5_DP_DPIDR); + dp_debug_port_id = initial_dp->dp_read(initial_dp, ADIV5_DP_DPIDR); } if (e.type || initial_dp->fault) { continue; } } else { - dp_targetid = target_id; + dp_debug_port_id = initial_dp->debug_port_id; + dp_targetid = initial_dp->target_id; } ADIv5_DP_t *dp = calloc(1, sizeof(*dp)); if (!dp) { /* calloc failed: heap exhaustion */ @@ -174,8 +177,9 @@ int adiv5_swdp_scan(uint32_t targetid) continue; } memcpy(dp, initial_dp, sizeof(ADIv5_DP_t)); - dp->debug_port_id = dpidr; - dp->targetid = dp_targetid; + dp->version = (dp_debug_port_id & ADIV5_DP_DPIDR_VERSION_MASK) >> ADIV5_DP_DPIDR_VERSION_OFFSET; + dp->debug_port_id = dp_debug_port_id; + dp->target_id = dp_targetid; adiv5_dp_init(dp); } return target_list ? 1U : 0U; @@ -193,12 +197,12 @@ uint32_t firmware_swdp_read(ADIv5_DP_t *dp, uint16_t addr) uint32_t firmware_swdp_error(ADIv5_DP_t *dp) { - if ((dp->fault && (dp->debug_port_id & ADIV5_DP_DPIDR_VERSION_MASK) == ADIV5_DP_DPIDR_VERSION_DPv2) && dp->dp_low_write) { - /* On protocoll error target gets deselected. + if (dp->version >= 2 && dp->dp_low_write) { + /* On protocol error target gets deselected. * With DP Change, another target needs selection. * => Reselect with right target! */ dp_line_reset(dp); - dp->dp_low_write(dp, ADIV5_DP_TARGETSEL, dp->targetid); + dp->dp_low_write(dp, ADIV5_DP_TARGETSEL, dp->target_id); dp->dp_read(dp, ADIV5_DP_DPIDR); /* Exception here is unexpected, so do not catch */ } diff --git a/src/target/cortexm.c b/src/target/cortexm.c index bc7df91..6919a4c 100644 --- a/src/target/cortexm.c +++ b/src/target/cortexm.c @@ -283,8 +283,19 @@ bool cortexm_probe(ADIv5_AP_t *ap) } adiv5_ap_ref(ap); - t->designer_code = ap->designer_code; - t->part_id = ap->ap_partno; + if (ap->dp->version >= 2 && ap->dp->target_id != 0) { + /* Use TARGETID register to identify target */ + const uint16_t tdesigner = + (ap->dp->target_id & ADIV5_DP_TARGETID_TDESIGNER_MASK) >> ADIV5_DP_TARGETID_TDESIGNER_OFFSET; + /* convert it to our internal representation, See JEP-106 code list */ + t->designer_code = + (tdesigner & ADIV5_DP_DESIGNER_JEP106_CONT_MASK) << 1U | (tdesigner & ADIV5_DP_DESIGNER_JEP106_CODE_MASK); + t->part_id = (ap->dp->target_id & ADIV5_DP_TARGETID_TPARTNO_MASK) >> ADIV5_DP_TARGETID_TPARTNO_OFFSET; + } else { + /* Use AP DESIGNER and AP PARTNO to identify target */ + t->designer_code = ap->designer_code; + t->part_id = ap->partno; + } struct cortexm_priv *priv = calloc(1, sizeof(*priv)); if (!priv) { /* calloc failed: heap exhaustion */ DEBUG_WARN("calloc: failed in %s\n", __func__); @@ -401,10 +412,10 @@ bool cortexm_probe(ADIv5_AP_t *ap) } while (0) #endif - switch (ap->designer_code) { + switch (t->designer_code) { case JEP106_MANUFACTURER_FREESCALE: PROBE(kinetis_probe); - if (ap->ap_partno == 0x88c) { + if (t->part_id == 0x88c) { t->driver = "MIMXRT10xx(no flash)"; target_halt_resume(t, 0); } @@ -444,36 +455,21 @@ bool cortexm_probe(ADIv5_AP_t *ap) case JEP106_MANUFACTURER_SPECULAR: PROBE(lpc11xx_probe); /* LPC845 */ break; - default: - if (ap->designer_code != JEP106_MANUFACTURER_ARM) { - /* Report unexpected designers */ -#if PC_HOSTED == 0 - gdb_outf("Please report probed device with Designer code 0x%3x and Partno 0x%3x\n", ap->designer_code, - ap->ap_partno); -#else - DEBUG_WARN("Please report probed device with Designer code 0x%3x and Partno 0x%3x\n", ap->designer_code, - ap->ap_partno); -#endif - } - if (ap->ap_partno == 0x4c0) { /* Cortex-M0+ ROM */ - const uint16_t tdesigner = - (ap->dp->targetid & ADIV5_DP_TARGETID_TDESIGNER_MASK) >> ADIV5_DP_TARGETID_TDESIGNER_OFFSET; - /* convert it to our internal representation, See JEP-106 code list */ - const uint16_t designer_code = (tdesigner & ADIV5_DP_DESIGNER_JEP106_CONT_MASK) << 1U | - (tdesigner & ADIV5_DP_DESIGNER_JEP106_CODE_MASK); - if (designer_code == JEP106_MANUFACTURER_RASPBERRY) - PROBE(rp_probe); - PROBE(lpc11xx_probe); /* LPC8 */ - } else if (ap->ap_partno == 0x4c3) { /* Cortex-M3 ROM */ + case JEP106_MANUFACTURER_RASPBERRY: + PROBE(rp_probe); + break; + case JEP106_MANUFACTURER_ARM: + if (t->part_id == 0x4c0) { /* Cortex-M0+ ROM */ + PROBE(lpc11xx_probe); /* LPC8 */ + } else if (t->part_id == 0x4c3) { /* Cortex-M3 ROM */ PROBE(lmi_probe); PROBE(ch32f1_probe); - PROBE(stm32f1_probe); /* Care for other STM32F1 clones (?) */ - PROBE(lpc15xx_probe); /* Thanks to JojoS for testing */ - PROBE(lpc11xx_probe); /* LPC1343 */ - } else if (ap->ap_partno == 0x471) { /* Cortex-M0 ROM */ - PROBE(lpc11xx_probe); /* LPC24C11 */ + PROBE(stm32f1_probe); /* Care for other STM32F1 clones (?) */ + PROBE(lpc15xx_probe); /* Thanks to JojoS for testing */ + } else if (t->part_id == 0x471) { /* Cortex-M0 ROM */ + PROBE(lpc11xx_probe); /* LPC24C11 */ PROBE(lpc43xx_probe); - } else if (ap->ap_partno == 0x4c4) { /* Cortex-M4 ROM */ + } else if (t->part_id == 0x4c4) { /* Cortex-M4 ROM */ PROBE(lmi_probe); /* The LPC546xx and LPC43xx parts present with the same AP ROM Part Number, so we need to probe both. Unfortunately, when probing for @@ -483,19 +479,28 @@ bool cortexm_probe(ADIv5_AP_t *ap) probe for the LPC546xx first, which experimentally doesn't harm LPC43xx detection. */ PROBE(lpc546xx_probe); - PROBE(lpc43xx_probe); - PROBE(kinetis_probe); /* Older K-series */ - } else if (ap->ap_partno == 0x4cb) { /* Cortex-M23 ROM */ - PROBE(gd32f1_probe); /* GD32E23x uses GD32F1 peripherals */ - } else if (ap->ap_partno == 0x4c0) { /* Cortex-M0+ ROM */ - PROBE(lpc11xx_probe); /* some of the LPC8xx series, like LPC802 */ + PROBE(kinetis_probe); /* Older K-series */ + } else if (t->part_id == 0x4cb) { /* Cortex-M23 ROM */ + PROBE(gd32f1_probe); /* GD32E23x uses GD32F1 peripherals */ } - /* Info on PIDR of these parts wanted! */ + break; + case ASCII_CODE_FLAG: + /* + * these devices enumerate an AP with an empty ascii code, + * and have no available designer code elsewhere + */ PROBE(sam3x_probe); PROBE(ke04_probe); PROBE(lpc17xx_probe); + PROBE(lpc11xx_probe); /* LPC1343 */ + break; } +#if PC_HOSTED == 0 + gdb_outf("Please report unknown device with Designer %x Part ID %x\n", ap->designer_code, ap->partno); +#else + DEBUG_WARN("Please report unknown device with Designer %x Part ID %x\n", ap->designer_code, ap->partno); +#endif #undef PROBE return true; } diff --git a/src/target/stm32l4.c b/src/target/stm32l4.c index b59bdc2..338f08b 100644 --- a/src/target/stm32l4.c +++ b/src/target/stm32l4.c @@ -511,14 +511,14 @@ bool stm32l4_probe(target *t) { ADIv5_AP_t *ap = cortexm_ap(t); uint32_t device_id; - if (ap->dp->targetid > 1) { /* STM32L552 has invalid TARGETID 1 */ - /* todo: cleanup, this does not look correct, nothing in TARGETID register has offset 16 */ - device_id = (ap->dp->targetid >> 16) & 0xfff; + if (ap->dp->version >= 2 && ap->dp->target_id > 1) { /* STM32L552 has invalid TARGETID 1 */ + /* FIXME: this does not look correct, nothing in TARGETID register has offset 16 */ + device_id = (ap->dp->target_id >> 16U) & 0xfffU; } else { uint32_t idcode_reg = STM32L4_DBGMCU_IDCODE_PHYS; - if (ap->dp->debug_port_id == 0x0Be12477) + if (ap->dp->debug_port_id == 0x0be12477U) idcode_reg = STM32L5_DBGMCU_IDCODE_PHYS; - device_id = target_mem_read32(t, idcode_reg) & 0xfff; + device_id = target_mem_read32(t, idcode_reg) & 0xfffU; DEBUG_INFO("Idcode %08" PRIx32 "\n", device_id); } diff --git a/src/target/target_internal.h b/src/target/target_internal.h index 5fe6514..2871278 100644 --- a/src/target/target_internal.h +++ b/src/target/target_internal.h @@ -117,9 +117,6 @@ struct target_s { /* target-defined options */ unsigned target_options; - uint16_t designer_code; - uint16_t part_id; - void *target_storage; union { bool unsafe_enabled; @@ -144,6 +141,13 @@ struct target_s { void *priv; void (*priv_free)(void *); + + /* Target designer and id / partno */ + uint16_t designer_code; + /* targetid partno if available (>= DPv2) + * fallback to ap partno + */ + uint16_t part_id; }; void target_print_progress(platform_timeout *timeout);