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
This commit is contained in:
Rafael Silva 2022-07-29 19:44:10 +01:00 committed by Rachel Mant
parent ad65f4a7c7
commit f435bd2136
9 changed files with 143 additions and 94 deletions

View File

@ -180,12 +180,22 @@ int jlink_swdp_scan(bmp_info_t *info)
free(dp); free(dp);
return 0; 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->dp_read = jlink_adiv5_swdp_read;
dp->error = jlink_adiv5_swdp_error; dp->error = jlink_adiv5_swdp_error;
dp->low_access = jlink_adiv5_swdp_low_access; dp->low_access = jlink_adiv5_swdp_low_access;
dp->abort = jlink_adiv5_swdp_abort; dp->abort = jlink_adiv5_swdp_abort;
jlink_adiv5_swdp_error(dp); 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); adiv5_dp_init(dp);
return target_list?1:0; return target_list?1:0;
} }

View File

@ -1078,17 +1078,20 @@ int stlink_enter_debug_swd(bmp_info_t *info, ADIv5_DP_t *dp)
if (stlink_usb_error_check(data, true)) if (stlink_usb_error_check(data, true))
exit( -1); exit( -1);
dp->debug_port_id = stlink_read_coreid(); 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->dp_read = stlink_dp_read;
dp->error = stlink_dp_error; dp->error = stlink_dp_error;
dp->low_access = stlink_dp_low_access; dp->low_access = stlink_dp_low_access;
dp->abort = stlink_dp_abort; dp->abort = stlink_dp_abort;
stlink_dp_error(dp); 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); if (dp->version >= 2) {
dp->targetid = adiv5_dp_read(dp, ADIV5_DP_CTRLSTAT); /* 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_write(dp, ADIV5_DP_SELECT, 0);
DEBUG_INFO("TARGETID 0x%08" PRIx32 "\n", dp->targetid);
} }
return 0; return 0;
} }

View File

@ -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_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 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 halt_timeout;
platform_timeout_set(&halt_timeout, cortexm_wait_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) 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 10:7 - JEP-106 Continuation code
* Bits 6:0 - JEP-106 Identity code * Bits 6:0 - JEP-106 Identity code
* here we convert it to our internal representation, See JEP-106 code list * 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 * 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; 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 | dp->designer_code =
(designer & ADIV5_DP_DESIGNER_JEP106_CODE_MASK); (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;
/* Check DPIDR for a valid manufacturer and sensible PARTNO */ /* on JTAG IDCODE this is actually the version */
if (dp->designer_code == 0 || dp->partno == 0xff7fU) { dp->revision = (dp->debug_port_id & ADIV5_DP_DPIDR_REVISION_MASK) >> ADIV5_DP_DPIDR_REVISION_OFFSET;
DEBUG_WARN("Invalid DP DPIDR %08" PRIx32 "\n", dp->debug_port_id);
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); free(dp);
return; return;
} }
DEBUG_INFO("DPIDR 0x%08" PRIx32 " (v%d %srev%d) designer 0x%" PRIx32 " partno 0x%" PRIx32 "\n", dp->debug_port_id, DEBUG_INFO("DP ID 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->version, dp->mindp ? "MINDP " : "", dp->revision, dp->designer_code, dp->partno);
(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, if (dp->version >= 2 && dp->target_id != 0)
dp->partno); DEBUG_INFO("TARGETID 0x%08" PRIx32 "\n", dp->target_id);
if (dp->designer_code == JEP106_MANUFACTURER_RASPBERRY && dp->partno == 0x2) { if (dp->designer_code == JEP106_MANUFACTURER_RASPBERRY && dp->partno == 0x2) {
rp_rescue_setup(dp); rp_rescue_setup(dp);

View File

@ -41,7 +41,7 @@
#define ADIV5_DP_DPIDR ADIV5_DP_REG(0x0U) #define ADIV5_DP_DPIDR ADIV5_DP_REG(0x0U)
#define ADIV5_DP_ABORT ADIV5_DP_REG(0x0U) #define ADIV5_DP_ABORT ADIV5_DP_REG(0x0U)
#define ADIV5_DP_CTRLSTAT ADIV5_DP_REG(0x4U) #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_SELECT ADIV5_DP_REG(0x8U)
#define ADIV5_DP_RDBUFF ADIV5_DP_REG(0xCU) #define ADIV5_DP_RDBUFF ADIV5_DP_REG(0xCU)
#define ADIV5_DP_TARGETSEL 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_OFFSET 1U
#define ADIV5_DP_TARGETID_TDESIGNER_MASK (0x7ffU << ADIV5_DP_TARGETID_TDESIGNER_OFFSET) #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 10:7 - JEP-106 Continuation code */
/* Bits 6:0 - JEP-106 Identity code */ /* Bits 6:0 - JEP-106 Identity code */
#define ADIV5_DP_DESIGNER_JEP106_CONT_OFFSET 7U #define ADIV5_DP_DESIGNER_JEP106_CONT_OFFSET 7U
@ -146,6 +146,14 @@
#define ADIV5_ROM_ROMENTRY_PRESENT (1U << 0U) #define ADIV5_ROM_ROMENTRY_PRESENT (1U << 0U)
#define ADIV5_ROM_ROMENTRY_OFFSET (0xFFFFF000U) #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 */ /* Constants to make RnW parameters more clear in code */
#define ADIV5_LOW_WRITE 0 #define ADIV5_LOW_WRITE 0
#define ADIV5_LOW_READ 1 #define ADIV5_LOW_READ 1
@ -220,11 +228,7 @@ typedef struct ADIv5_DP_s {
int refcnt; int refcnt;
uint32_t debug_port_id; uint32_t debug_port_id;
uint32_t target_id; /* present on DPv2 or later */
uint16_t designer_code;
uint16_t partno;
uint32_t targetid; /* Contains IDCODE for DPv2 devices.*/
void (*seq_out)(uint32_t tms_states, size_t clock_cycles); void (*seq_out)(uint32_t tms_states, size_t clock_cycles);
void (*seq_out_parity)(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); 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 dp_jd_index;
uint8_t fault; 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; } ADIv5_DP_t;
struct ADIv5_AP_s { struct ADIv5_AP_s {

View File

@ -48,11 +48,7 @@ void adiv5_jtag_dp_handler(uint8_t jd_index)
} }
dp->dp_jd_index = jd_index; dp->dp_jd_index = jd_index;
/* From the ADI spec : /* JTAG routine passes IDCODE to port ID and version = 0 */
* The architecture does not require that the TAP IDCODE
* register value and the DPIDR (ADIv5) value are the same
* should read DPIDR here
*/
dp->debug_port_id = jtag_devs[jd_index].jd_idcode; dp->debug_port_id = jtag_devs[jd_index].jd_idcode;
if ((PC_HOSTED == 0 ) || (!platform_jtag_dp_init(dp))) { if ((PC_HOSTED == 0 ) || (!platform_jtag_dp_init(dp))) {
dp->dp_read = fw_adiv5_jtagdp_read; dp->dp_read = fw_adiv5_jtagdp_read;

View File

@ -93,8 +93,6 @@ int adiv5_swdp_scan(uint32_t targetid)
* 0x1a Arm CoreSight SW-DP activation sequence * 0x1a Arm CoreSight SW-DP activation sequence
* 20 bits start of reset another reset sequence*/ * 20 bits start of reset another reset sequence*/
initial_dp->seq_out(0x1a0, 12); initial_dp->seq_out(0x1a0, 12);
uint32_t dpidr = 0;
volatile uint32_t target_id = 0;
bool scan_multidrop = true; bool scan_multidrop = true;
if (!targetid || !initial_dp->dp_low_write) { if (!targetid || !initial_dp->dp_low_write) {
/* No targetID given on the command line or probe can not /* 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); dp_line_reset(initial_dp);
TRY_CATCH (e, EXCEPTION_ALL) { 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) { if (e.type || initial_dp->fault) {
scan_multidrop = false; scan_multidrop = false;
@ -114,24 +112,27 @@ int adiv5_swdp_scan(uint32_t targetid)
initial_dp->fault = 0; initial_dp->fault = 0;
TRY_CATCH (e, EXCEPTION_ALL) { 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) { if (e.type || initial_dp->fault) {
DEBUG_WARN("No usable DP found\n"); DEBUG_WARN("No usable DP found\n");
return -1; 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; scan_multidrop = true;
/* Read TargetID. Can be done with device in WFI, sleep or reset!*/ /* Read TargetID. Can be done with device in WFI, sleep or reset!*/
adiv5_dp_write(initial_dp, ADIV5_DP_SELECT, 2); adiv5_dp_write(initial_dp, ADIV5_DP_SELECT, 2); /* TARGETID is on bank 2 */
target_id = adiv5_dp_read(initial_dp, ADIV5_DP_CTRLSTAT); initial_dp->target_id = adiv5_dp_read(initial_dp, ADIV5_DP_TARGETID);
adiv5_dp_write(initial_dp, ADIV5_DP_SELECT, 0); adiv5_dp_write(initial_dp, ADIV5_DP_SELECT, 0);
DEBUG_INFO("TARGETID %08" PRIx32 "\n", target_id);
const uint16_t tdesigner = const uint16_t tdesigner =
(target_id & ADIV5_DP_TARGETID_TDESIGNER_MASK) >> ADIV5_DP_TARGETID_TDESIGNER_OFFSET; (initial_dp->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; 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 */ /* convert it to our internal representation, See JEP-106 code list */
const uint16_t designer_code = (tdesigner & ADIV5_DP_DESIGNER_JEP106_CONT_MASK) << 1U | const uint16_t designer_code = (tdesigner & ADIV5_DP_DESIGNER_JEP106_CONT_MASK) << 1U |
(tdesigner & ADIV5_DP_DESIGNER_JEP106_CODE_MASK); (tdesigner & ADIV5_DP_DESIGNER_JEP106_CODE_MASK);
@ -150,23 +151,25 @@ int adiv5_swdp_scan(uint32_t targetid)
scan_multidrop = false; scan_multidrop = false;
} }
} else { } else {
target_id = targetid; initial_dp->target_id = targetid;
} }
const volatile size_t nr_dps = (scan_multidrop) ? 16U : 1U; const volatile size_t nr_dps = (scan_multidrop) ? 16U : 1U;
volatile uint32_t dp_targetid; volatile uint32_t dp_targetid;
volatile uint32_t dp_debug_port_id;
for (volatile size_t i = 0; i < nr_dps; i++) { for (volatile size_t i = 0; i < nr_dps; i++) {
if (scan_multidrop) { if (scan_multidrop) {
dp_line_reset(initial_dp); 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); initial_dp->dp_low_write(initial_dp, ADIV5_DP_TARGETSEL, dp_targetid);
TRY_CATCH (e, EXCEPTION_ALL) { 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) { if (e.type || initial_dp->fault) {
continue; continue;
} }
} else { } 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)); ADIv5_DP_t *dp = calloc(1, sizeof(*dp));
if (!dp) { /* calloc failed: heap exhaustion */ if (!dp) { /* calloc failed: heap exhaustion */
@ -174,8 +177,9 @@ int adiv5_swdp_scan(uint32_t targetid)
continue; continue;
} }
memcpy(dp, initial_dp, sizeof(ADIv5_DP_t)); memcpy(dp, initial_dp, sizeof(ADIv5_DP_t));
dp->debug_port_id = dpidr; dp->version = (dp_debug_port_id & ADIV5_DP_DPIDR_VERSION_MASK) >> ADIV5_DP_DPIDR_VERSION_OFFSET;
dp->targetid = dp_targetid; dp->debug_port_id = dp_debug_port_id;
dp->target_id = dp_targetid;
adiv5_dp_init(dp); adiv5_dp_init(dp);
} }
return target_list ? 1U : 0U; 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) 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) { if (dp->version >= 2 && dp->dp_low_write) {
/* On protocoll error target gets deselected. /* On protocol error target gets deselected.
* With DP Change, another target needs selection. * With DP Change, another target needs selection.
* => Reselect with right target! */ * => Reselect with right target! */
dp_line_reset(dp); 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); dp->dp_read(dp, ADIV5_DP_DPIDR);
/* Exception here is unexpected, so do not catch */ /* Exception here is unexpected, so do not catch */
} }

View File

@ -283,8 +283,19 @@ bool cortexm_probe(ADIv5_AP_t *ap)
} }
adiv5_ap_ref(ap); adiv5_ap_ref(ap);
t->designer_code = ap->designer_code; if (ap->dp->version >= 2 && ap->dp->target_id != 0) {
t->part_id = ap->ap_partno; /* 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)); struct cortexm_priv *priv = calloc(1, sizeof(*priv));
if (!priv) { /* calloc failed: heap exhaustion */ if (!priv) { /* calloc failed: heap exhaustion */
DEBUG_WARN("calloc: failed in %s\n", __func__); DEBUG_WARN("calloc: failed in %s\n", __func__);
@ -401,10 +412,10 @@ bool cortexm_probe(ADIv5_AP_t *ap)
} while (0) } while (0)
#endif #endif
switch (ap->designer_code) { switch (t->designer_code) {
case JEP106_MANUFACTURER_FREESCALE: case JEP106_MANUFACTURER_FREESCALE:
PROBE(kinetis_probe); PROBE(kinetis_probe);
if (ap->ap_partno == 0x88c) { if (t->part_id == 0x88c) {
t->driver = "MIMXRT10xx(no flash)"; t->driver = "MIMXRT10xx(no flash)";
target_halt_resume(t, 0); target_halt_resume(t, 0);
} }
@ -444,36 +455,21 @@ bool cortexm_probe(ADIv5_AP_t *ap)
case JEP106_MANUFACTURER_SPECULAR: case JEP106_MANUFACTURER_SPECULAR:
PROBE(lpc11xx_probe); /* LPC845 */ PROBE(lpc11xx_probe); /* LPC845 */
break; break;
default: case JEP106_MANUFACTURER_RASPBERRY:
if (ap->designer_code != JEP106_MANUFACTURER_ARM) { PROBE(rp_probe);
/* Report unexpected designers */ break;
#if PC_HOSTED == 0 case JEP106_MANUFACTURER_ARM:
gdb_outf("Please report probed device with Designer code 0x%3x and Partno 0x%3x\n", ap->designer_code, if (t->part_id == 0x4c0) { /* Cortex-M0+ ROM */
ap->ap_partno); PROBE(lpc11xx_probe); /* LPC8 */
#else } else if (t->part_id == 0x4c3) { /* Cortex-M3 ROM */
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 */
PROBE(lmi_probe); PROBE(lmi_probe);
PROBE(ch32f1_probe); PROBE(ch32f1_probe);
PROBE(stm32f1_probe); /* Care for other STM32F1 clones (?) */ PROBE(stm32f1_probe); /* Care for other STM32F1 clones (?) */
PROBE(lpc15xx_probe); /* Thanks to JojoS for testing */ PROBE(lpc15xx_probe); /* Thanks to JojoS for testing */
PROBE(lpc11xx_probe); /* LPC1343 */ } else if (t->part_id == 0x471) { /* Cortex-M0 ROM */
} else if (ap->ap_partno == 0x471) { /* Cortex-M0 ROM */ PROBE(lpc11xx_probe); /* LPC24C11 */
PROBE(lpc11xx_probe); /* LPC24C11 */
PROBE(lpc43xx_probe); PROBE(lpc43xx_probe);
} else if (ap->ap_partno == 0x4c4) { /* Cortex-M4 ROM */ } else if (t->part_id == 0x4c4) { /* Cortex-M4 ROM */
PROBE(lmi_probe); PROBE(lmi_probe);
/* The LPC546xx and LPC43xx parts present with the same AP ROM Part /* The LPC546xx and LPC43xx parts present with the same AP ROM Part
Number, so we need to probe both. Unfortunately, when probing for 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 probe for the LPC546xx first, which experimentally doesn't harm
LPC43xx detection. */ LPC43xx detection. */
PROBE(lpc546xx_probe); PROBE(lpc546xx_probe);
PROBE(lpc43xx_probe); PROBE(lpc43xx_probe);
PROBE(kinetis_probe); /* Older K-series */ PROBE(kinetis_probe); /* Older K-series */
} else if (ap->ap_partno == 0x4cb) { /* Cortex-M23 ROM */ } else if (t->part_id == 0x4cb) { /* Cortex-M23 ROM */
PROBE(gd32f1_probe); /* GD32E23x uses GD32F1 peripherals */ 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 */
} }
/* 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(sam3x_probe);
PROBE(ke04_probe); PROBE(ke04_probe);
PROBE(lpc17xx_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 #undef PROBE
return true; return true;
} }

View File

@ -511,14 +511,14 @@ bool stm32l4_probe(target *t)
{ {
ADIv5_AP_t *ap = cortexm_ap(t); ADIv5_AP_t *ap = cortexm_ap(t);
uint32_t device_id; uint32_t device_id;
if (ap->dp->targetid > 1) { /* STM32L552 has invalid TARGETID 1 */ if (ap->dp->version >= 2 && ap->dp->target_id > 1) { /* STM32L552 has invalid TARGETID 1 */
/* todo: cleanup, this does not look correct, nothing in TARGETID register has offset 16 */ /* FIXME: this does not look correct, nothing in TARGETID register has offset 16 */
device_id = (ap->dp->targetid >> 16) & 0xfff; device_id = (ap->dp->target_id >> 16U) & 0xfffU;
} else { } else {
uint32_t idcode_reg = STM32L4_DBGMCU_IDCODE_PHYS; 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; 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); DEBUG_INFO("Idcode %08" PRIx32 "\n", device_id);
} }

View File

@ -117,9 +117,6 @@ struct target_s {
/* target-defined options */ /* target-defined options */
unsigned target_options; unsigned target_options;
uint16_t designer_code;
uint16_t part_id;
void *target_storage; void *target_storage;
union { union {
bool unsafe_enabled; bool unsafe_enabled;
@ -144,6 +141,13 @@ struct target_s {
void *priv; void *priv;
void (*priv_free)(void *); 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); void target_print_progress(platform_timeout *timeout);