target/adi: unify DPIDR TARGETID handling in adiv5_dp_init

this makes the assumption that DPs will be v1 or higher, for SWD-DP scans this is
guaranteed, but on JTAG-SCANS it may not be true, DPv0 does not have DPIDR
implemented and reads are UNPREDICTABLE

Signed-off-by: Rafael Silva <perigoso@riseup.net>
This commit is contained in:
Rafael Silva 2022-08-06 02:17:47 +01:00 committed by Rachel Mant
parent c04b98435a
commit ce6477886f
8 changed files with 157 additions and 134 deletions

View File

@ -130,17 +130,6 @@ int jlink_swdp_scan(bmp_info_t *info)
return 0;
}
volatile struct exception e;
TRY_CATCH (e, EXCEPTION_ALL) {
dp->debug_port_id = jlink_adiv5_swdp_low_access(dp, ADIV5_LOW_READ, ADIV5_DP_DPIDR, 0);
}
if (e.type) {
DEBUG_WARN("DP not responding for DPIDR! Reset stuck low?\n");
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;
@ -148,14 +137,8 @@ int jlink_swdp_scan(bmp_info_t *info)
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 ? 1U : 0U;
}

View File

@ -673,15 +673,15 @@ static int stlink_enter_debug_jtag(bmp_info_t *info)
return stlink_usb_error_check(data, true);
}
static uint32_t stlink_read_coreid(void)
{
uint8_t cmd[16] = {STLINK_DEBUG_COMMAND, STLINK_DEBUG_APIV2_READ_IDCODES};
uint8_t data[12];
send_recv(info.usb_link, cmd, 16, data, 12);
uint32_t id = data[4] | data[5] << 8 | data[6] << 16 | data[7] << 24;
DEBUG_INFO("Read Core ID: 0x%08" PRIx32 "\n", id);
return id;
}
// static uint32_t stlink_read_coreid(void)
// {
// uint8_t cmd[16] = {STLINK_DEBUG_COMMAND, STLINK_DEBUG_APIV2_READ_IDCODES};
// uint8_t data[12];
// send_recv(info.usb_link, cmd, 16, data, 12);
// uint32_t id = data[4] | data[5] << 8 | data[6] << 16 | data[7] << 24;
// DEBUG_INFO("Read Core ID: 0x%08" PRIx32 "\n", id);
// return id;
// }
static int stlink_read_idcodes(bmp_info_t *info, uint32_t *idcodes)
{
@ -1070,15 +1070,16 @@ void stlink_adiv5_dp_defaults(ADIv5_DP_t *dp)
int stlink_enter_debug_swd(bmp_info_t *info, ADIv5_DP_t *dp)
{
stlink_leave_state(info);
uint8_t cmd[16] = {STLINK_DEBUG_COMMAND,
STLINK_DEBUG_APIV2_ENTER,
STLINK_DEBUG_ENTER_SWD_NO_RESET};
uint8_t data[2];
stlink_send_recv_retry(cmd, 16, data, 2);
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;
@ -1087,12 +1088,6 @@ int stlink_enter_debug_swd(bmp_info_t *info, ADIv5_DP_t *dp)
stlink_dp_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);
}
return 0;
}

View File

@ -474,8 +474,8 @@ static void adiv5_component_probe(ADIv5_AP_t *ap, uint32_t addr, const size_t re
/* CIDR preamble sanity check */
if ((cidr & ~CID_CLASS_MASK) != CID_PREAMBLE) {
DEBUG_WARN("%s%" PRIu32 " 0x%08" PRIx32 ": 0x%08" PRIx32 " <- does not match preamble (0x%08" PRIx32 ")\n", indent + 1,
num_entry, addr, cidr, CID_PREAMBLE);
DEBUG_WARN("%s%" PRIu32 " 0x%08" PRIx32 ": 0x%08" PRIx32 " <- does not match preamble (0x%08" PRIx32 ")\n",
indent + 1, num_entry, addr, cidr, CID_PREAMBLE);
return;
}
@ -586,8 +586,8 @@ static void adiv5_component_probe(ADIv5_AP_t *ap, uint32_t addr, const size_t re
arm_component_lut[i].arch_id != arch_id)
continue;
DEBUG_INFO("%s%" PRIu32 " 0x%" PRIx32 ": %s - %s %s (PIDR = 0x%08" PRIx32 "%08" PRIx32
" DEVTYPE = 0x%02x ARCHID = 0x%04x)\n",
DEBUG_INFO("%s%" PRIu32 " 0x%" PRIx32 ": %s - %s %s (PIDR = 0x%08" PRIx32 "%08" PRIx32 " DEVTYPE = 0x%02x "
"ARCHID = 0x%04x)\n",
indent + 1, num_entry, addr, cidc_debug_strings[cid_class], arm_component_lut[i].type,
arm_component_lut[i].full, (uint32_t)(pidr >> 32U), (uint32_t)pidr, dev_type, arch_id);
@ -612,8 +612,9 @@ static void adiv5_component_probe(ADIv5_AP_t *ap, uint32_t addr, const size_t re
break;
}
if (arm_component_lut[i].arch == aa_end) {
DEBUG_WARN("%s%" PRIu32 " 0x%" PRIx32 ": %s - Unknown (PIDR = 0x%08" PRIx32 "%08" PRIx32
" DEVTYPE = 0x%02x ARCHID = 0x%04x)\n",
DEBUG_WARN("%s%" PRIu32 " 0x%" PRIx32 ": %s - Unknown (PIDR = 0x%08" PRIx32 "%08" PRIx32 " DEVTYPE = "
"0x%02x ARCHID = "
"0x%04x)\n",
indent, num_entry, addr, cidc_debug_strings[cid_class], (uint32_t)(pidr >> 32U), (uint32_t)pidr,
dev_type, arch_id);
}
@ -682,44 +683,82 @@ 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/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
* Assume DP v1 or later.
* this may not be true for JTAG-DP
* in such cases (DPv0) DPIDR is not implemented
* and reads are UNPREDICTABLE.
*
* for SWD-DP, we are guaranteed to be DP v1 or later.
*/
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);
/* 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;
volatile uint32_t dpidr;
volatile struct exception e;
TRY_CATCH (e, EXCEPTION_ALL) {
dpidr = adiv5_dp_read(dp, ADIV5_DP_DPIDR);
}
/* Check for a valid designer */
if (dp->designer_code == 0) {
DEBUG_WARN("Invalid DP ID %08" PRIx32 "\n", dp->debug_port_id);
if (e.type) {
DEBUG_WARN("DP not responding!...\n");
free(dp);
return;
}
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);
dp->version = (dpidr & ADIV5_DP_DPIDR_VERSION_MASK) >> ADIV5_DP_DPIDR_VERSION_OFFSET;
if (dp->version > 0 && (dpidr & 1U)) {
/*
* the code in the DPIDR 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 = (dpidr & 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 = (dpidr & ADIV5_DP_DPIDR_PARTNO_MASK) >> ADIV5_DP_DPIDR_PARTNO_OFFSET;
if (dp->version >= 2 && dp->target_id != 0)
DEBUG_INFO("TARGETID 0x%08" PRIx32 "\n", dp->target_id);
dp->mindp = !!(dpidr & ADIV5_DP_DPIDR_MINDP);
/* Check for a valid DPIDR / designer */
if (dp->designer_code != 0) {
DEBUG_INFO("DP DPIDR 0x%08" PRIx32 " (v%d %srev%d) designer 0x%" PRIx32 " partno 0x%" PRIx32 "\n", dpidr,
dp->version, dp->mindp ? "MINDP " : "",
(dpidr & ADIV5_DP_DPIDR_REVISION_MASK) >> ADIV5_DP_DPIDR_REVISION_OFFSET, dp->designer_code,
dp->partno);
} else {
DEBUG_WARN("Invalid DPIDR %08" PRIx32 " assuming DP version 0\n", dpidr);
dp->version = 0;
}
}
if (dp->version == 0) {
/* DP v0 */
DEBUG_WARN("DPv0 detected, no designer code available\n", dpidr);
dp->designer_code = 0;
dp->partno = 0;
dp->mindp = 0;
}
if (dp->version >= 2) {
adiv5_dp_write(dp, ADIV5_DP_SELECT, 2); /* TARGETID is on bank 2 */
const uint32_t targetid = adiv5_dp_read(dp, ADIV5_DP_TARGETID);
adiv5_dp_write(dp, ADIV5_DP_SELECT, 0);
/* Use TARGETID register to identify target */
const uint16_t tdesigner = (targetid & ADIV5_DP_TARGETID_TDESIGNER_MASK) >> ADIV5_DP_TARGETID_TDESIGNER_OFFSET;
/* convert it to our internal representation, See JEP-106 code list */
dp->target_designer_code =
(tdesigner & ADIV5_DP_DESIGNER_JEP106_CONT_MASK) << 1U | (tdesigner & ADIV5_DP_DESIGNER_JEP106_CODE_MASK);
dp->target_partno = (targetid & ADIV5_DP_TARGETID_TPARTNO_MASK) >> ADIV5_DP_TARGETID_TPARTNO_OFFSET;
DEBUG_INFO("TARGETID 0x%08" PRIx32 " designer 0x%" PRIx32 " partno 0x%" PRIx32 "\n", targetid,
dp->target_designer_code, dp->target_partno);
dp->targetsel = dp->instance << ADIV5_DP_TARGETSEL_TINSTANCE_OFFSET |
(targetid & (ADIV5_DP_TARGETID_TDESIGNER_MASK | ADIV5_DP_TARGETID_TPARTNO_MASK)) | 1U;
}
if (dp->designer_code == JEP106_MANUFACTURER_RASPBERRY && dp->partno == 0x2) {
rp_rescue_setup(dp);
@ -744,7 +783,6 @@ void adiv5_dp_init(ADIv5_DP_t *dp)
#endif
volatile uint32_t ctrlstat = 0;
volatile struct exception e;
TRY_CATCH (e, EXCEPTION_TIMEOUT) {
ctrlstat = adiv5_dp_read(dp, ADIV5_DP_CTRLSTAT);
}

View File

@ -235,9 +235,6 @@ typedef struct ADIv5_AP_s ADIv5_AP_t;
typedef struct ADIv5_DP_s {
int refcnt;
uint32_t debug_port_id;
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);
uint32_t (*seq_in)(size_t clock_cycles);
@ -267,14 +264,21 @@ typedef struct ADIv5_DP_s {
uint8_t dp_jd_index;
uint8_t fault;
/* targetsel DPv2 */
uint8_t instance;
uint32_t targetsel;
uint8_t version;
uint8_t revision;
bool mindp;
/* DP designer (not implementer!) and partno */
uint16_t designer_code;
uint16_t partno;
/* TARGETID designer and partno, present on DPv2 */
uint16_t target_designer_code;
uint16_t target_partno;
} ADIv5_DP_t;
struct ADIv5_AP_s {

View File

@ -48,14 +48,14 @@ void adiv5_jtag_dp_handler(uint8_t jd_index)
}
dp->dp_jd_index = jd_index;
/* 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;
dp->error = adiv5_jtagdp_error;
dp->low_access = fw_adiv5_jtagdp_low_access;
dp->abort = adiv5_jtagdp_abort;
}
adiv5_dp_init(dp);
}

View File

@ -70,7 +70,9 @@ bool firmware_dp_low_write(ADIv5_DP_t *dp, uint16_t addr, const uint32_t data)
int adiv5_swdp_scan(uint32_t targetid)
{
volatile struct exception e;
target_list_free();
ADIv5_DP_t idp = {
.dp_low_write = firmware_dp_low_write,
.error = firmware_swdp_error,
@ -79,8 +81,10 @@ int adiv5_swdp_scan(uint32_t targetid)
.abort = firmware_swdp_abort,
};
ADIv5_DP_t *initial_dp = &idp;
if (swdptap_init(initial_dp))
return -1;
/* DORMANT-> SWD sequence*/
initial_dp->seq_out(0xFFFFFFFF, 32);
initial_dp->seq_out(0xFFFFFFFF, 32);
@ -93,26 +97,33 @@ 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);
bool scan_multidrop = true;
if (!targetid || !initial_dp->dp_low_write) {
/* No targetID given on the command line or probe can not
* handle multi-drop. Try to read ID */
volatile uint32_t dp_targetid = targetid;
if (!dp_targetid) {
/* No targetID given on the command line Try to read ID */
scan_multidrop = false;
dp_line_reset(initial_dp);
volatile uint32_t dp_dpidr;
TRY_CATCH (e, EXCEPTION_ALL) {
initial_dp->debug_port_id = initial_dp->dp_read(initial_dp, ADIV5_DP_DPIDR);
dp_dpidr = initial_dp->dp_read(initial_dp, ADIV5_DP_DPIDR);
}
if (e.type || initial_dp->fault) {
scan_multidrop = false;
DEBUG_WARN("Trying old JTAG to SWD sequence\n");
initial_dp->seq_out(0xFFFFFFFF, 32);
initial_dp->seq_out(0xFFFFFFFF, 32);
initial_dp->seq_out(0xE79E, 16); /* 0b0111100111100111 */
dp_line_reset(initial_dp);
initial_dp->fault = 0;
TRY_CATCH (e, EXCEPTION_ALL) {
initial_dp->debug_port_id = initial_dp->dp_read(initial_dp, ADIV5_DP_DPIDR);
dp_dpidr = initial_dp->dp_read(initial_dp, ADIV5_DP_DPIDR);
}
if (e.type || initial_dp->fault) {
DEBUG_WARN("No usable DP found\n");
@ -120,68 +131,64 @@ int adiv5_swdp_scan(uint32_t targetid)
}
}
initial_dp->version =
(initial_dp->debug_port_id & ADIV5_DP_DPIDR_VERSION_MASK) >> ADIV5_DP_DPIDR_VERSION_OFFSET;
if (initial_dp->version >= 2) {
const uint8_t dp_version = (dp_dpidr & ADIV5_DP_DPIDR_VERSION_MASK) >> ADIV5_DP_DPIDR_VERSION_OFFSET;
if (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); /* TARGETID is on bank 2 */
initial_dp->target_id = adiv5_dp_read(initial_dp, ADIV5_DP_TARGETID);
dp_targetid = adiv5_dp_read(initial_dp, ADIV5_DP_TARGETID);
adiv5_dp_write(initial_dp, ADIV5_DP_SELECT, 0);
const uint16_t tdesigner =
(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;
(dp_targetid & ADIV5_DP_TARGETID_TDESIGNER_MASK) >> ADIV5_DP_TARGETID_TDESIGNER_OFFSET;
const uint16_t tpartno = (dp_targetid & 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);
if (designer_code == JEP106_MANUFACTURER_RASPBERRY && tpartno == 0x2) {
if (designer_code == JEP106_MANUFACTURER_RASPBERRY && tpartno == 0x1002) {
/* RP2040 */
/* Release evt. handing RESCUE DP reset*/
adiv5_dp_write(initial_dp, ADIV5_DP_CTRLSTAT, 0);
}
if (!initial_dp->dp_low_write) {
DEBUG_WARN("CMSIS_DAP < V1.2 can not handle multi-drop!\n");
/* E.g. CMSIS_DAP < V1.2 can not handle multi-drop!*/
scan_multidrop = false;
}
} else {
scan_multidrop = false;
}
} else {
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 (!initial_dp->dp_low_write) {
DEBUG_WARN("CMSIS_DAP < V1.2 can not handle multi-drop!\n");
/* E.g. CMSIS_DAP < V1.2 can not handle multi-drop!*/
scan_multidrop = false;
}
DEBUG_WARN("scan_multidrop: %s\n", scan_multidrop ? "true" : "false");
const volatile size_t max_dp = (scan_multidrop) ? 16U : 1U;
for (volatile size_t i = 0; i < max_dp; i++) {
if (scan_multidrop) {
dp_line_reset(initial_dp);
dp_targetid =
initial_dp->dp_low_write(initial_dp, ADIV5_DP_TARGETSEL,
(i << ADIV5_DP_TARGETSEL_TINSTANCE_OFFSET) |
(initial_dp->target_id & (ADIV5_DP_TARGETSEL_TPARTNO_MASK | ADIV5_DP_TARGETSEL_TDESIGNER_MASK | 1U));
initial_dp->dp_low_write(initial_dp, ADIV5_DP_TARGETSEL, dp_targetid);
(dp_targetid & (ADIV5_DP_TARGETSEL_TPARTNO_MASK | ADIV5_DP_TARGETSEL_TDESIGNER_MASK | 1U)));
TRY_CATCH (e, EXCEPTION_ALL) {
dp_debug_port_id = initial_dp->dp_read(initial_dp, ADIV5_DP_DPIDR);
initial_dp->dp_read(initial_dp, ADIV5_DP_DPIDR);
}
if (e.type || initial_dp->fault) {
if (e.type || initial_dp->fault)
continue;
}
} else {
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 */
DEBUG_WARN("calloc: failed in %s\n", __func__);
continue;
}
memcpy(dp, initial_dp, sizeof(ADIv5_DP_t));
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;
dp->instance = i;
adiv5_dp_init(dp);
}
return target_list ? 1U : 0U;
@ -192,9 +199,8 @@ uint32_t firmware_swdp_read(ADIv5_DP_t *dp, uint16_t addr)
if (addr & ADIV5_APnDP) {
adiv5_dp_low_access(dp, ADIV5_LOW_READ, addr, 0);
return adiv5_dp_low_access(dp, ADIV5_LOW_READ, ADIV5_DP_RDBUFF, 0);
} else {
} else
return firmware_swdp_low_access(dp, ADIV5_LOW_READ, addr, 0);
}
}
uint32_t firmware_swdp_error(ADIv5_DP_t *dp)
@ -204,7 +210,7 @@ uint32_t firmware_swdp_error(ADIv5_DP_t *dp)
* With DP Change, another target needs selection.
* => Reselect with right target! */
dp_line_reset(dp);
dp->dp_low_write(dp, ADIV5_DP_TARGETSEL, dp->target_id);
dp->dp_low_write(dp, ADIV5_DP_TARGETSEL, dp->targetsel);
dp->dp_read(dp, ADIV5_DP_DPIDR);
/* Exception here is unexpected, so do not catch */
}

View File

@ -278,24 +278,20 @@ bool cortexm_probe(ADIv5_AP_t *ap)
target *t;
t = target_new();
if (!t) {
if (!t)
return false;
}
adiv5_ap_ref(ap);
if (ap->dp->version >= 2 && ap->dp->target_id != 0) {
if (ap->dp->version >= 2 && ap->dp->target_designer_code != 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;
t->designer_code = ap->dp->target_designer_code;
t->part_id = ap->dp->target_partno;
} 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__);

View File

@ -511,12 +511,13 @@ bool stm32l4_probe(target *t)
{
ADIv5_AP_t *ap = cortexm_ap(t);
uint32_t device_id;
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;
if (ap->dp->version >= 2 && ap->dp->target_partno > 1) { /* STM32L552 has invalid TARGETID 1 */
/* FIXME: ids likely no longer match and need fixing */
device_id = ap->dp->target_partno;
} else {
uint32_t idcode_reg = STM32L4_DBGMCU_IDCODE_PHYS;
if (ap->dp->debug_port_id == 0x0be12477U)
/* FIXME: we probaly want to check if this is a C-M33 via cpuid */
if (ap->dp->partno == 0xbe)
idcode_reg = STM32L5_DBGMCU_IDCODE_PHYS;
device_id = target_mem_read32(t, idcode_reg) & 0xfffU;
DEBUG_INFO("Idcode %08" PRIx32 "\n", device_id);