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:
parent
c04b98435a
commit
ce6477886f
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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 */
|
||||
}
|
||||
|
|
|
@ -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__);
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue