Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix: ADIv5 DP init #1544

Merged
merged 2 commits into from
Jul 19, 2023
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
64 changes: 36 additions & 28 deletions src/target/adiv5.c
Original file line number Diff line number Diff line change
Expand Up @@ -773,6 +773,19 @@ static void adiv5_dp_clear_sticky_errors(adiv5_debug_port_s *dp)
adiv5_dp_error(dp);
}

/* Keep the TRY_CATCH funkiness contained to avoid clobbering and reduce the need for volatiles */
static uint32_t adiv5_dp_read_dpidr(adiv5_debug_port_s *const dp)
{
volatile uint32_t dpidr = 0;
volatile exception_s e;
TRY_CATCH (e, EXCEPTION_ALL) {
dpidr = adiv5_dp_read(dp, ADIV5_DP_DPIDR);
}
if (e.type)
return 0;
return dpidr;
}

void adiv5_dp_init(adiv5_debug_port_s *const dp, const uint32_t idcode)
{
/*
Expand All @@ -795,22 +808,18 @@ void adiv5_dp_init(adiv5_debug_port_s *const dp, const uint32_t idcode)
*
* for SWD-DP, we are guaranteed to be DP v1 or later.
*/
volatile uint32_t dpidr = 0;
volatile exception_s e;
TRY_CATCH (e, EXCEPTION_ALL) {
if (idcode != JTAG_IDCODE_ARM_DPv0)
dpidr = adiv5_dp_read(dp, ADIV5_DP_DPIDR);
}
if (e.type) {
DEBUG_ERROR("DP not responding!...\n");
free(dp);
return;
}
if (idcode != JTAG_IDCODE_ARM_DPv0) {
const uint32_t dpidr = adiv5_dp_read_dpidr(dp);
if (!dpidr) {
dragonmux marked this conversation as resolved.
Show resolved Hide resolved
DEBUG_ERROR("Failed to read DPIDR\n");
free(dp);
return;
}

dp->version = (dpidr & ADIV5_DP_DPIDR_VERSION_MASK) >> ADIV5_DP_DPIDR_VERSION_OFFSET;

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
* 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
Expand All @@ -822,16 +831,22 @@ void adiv5_dp_init(adiv5_debug_port_s *const dp, const uint32_t idcode)
(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;

/* Minimal Debug Port (MINDP) functions implemented */
dp->mindp = !!(dpidr & ADIV5_DP_DPIDR_MINDP);

/* Check for a valid DPIDR / designer */
if (dp->designer_code != 0) {
/*
* Check DPIDR validity
* Designer code 0 is not a valid JEP-106 code
* Version 0 is reserved for DPv0 which does not implement DPIDR
* Bit 0 of DPIDR is read as 1
*/
if (dp->designer_code != 0 && dp->version > 0 && (dpidr & 1U)) {
DEBUG_INFO("DP DPIDR 0x%08" PRIx32 " (v%x %srev%" PRId32 ") designer 0x%x partno 0x%x\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);
DEBUG_WARN("Invalid DPIDR %08" PRIx32 " assuming DPv0\n", dpidr);
dp->version = 0;
dp->designer_code = 0;
dp->partno = 0;
Expand Down Expand Up @@ -874,15 +889,8 @@ void adiv5_dp_init(adiv5_debug_port_s *const dp, const uint32_t idcode)
return;
}

volatile uint32_t ctrlstat = 0;
TRY_CATCH (e, EXCEPTION_TIMEOUT) {
ctrlstat = adiv5_dp_read(dp, ADIV5_DP_CTRLSTAT);
}
if (e.type) {
DEBUG_WARN("DP not responding! Trying abort sequence...\n");
adiv5_dp_abort(dp, ADIV5_DP_ABORT_DAPABORT);
ctrlstat = adiv5_dp_read(dp, ADIV5_DP_CTRLSTAT);
}
/* Read DP Control/Status */
uint32_t ctrlstat = adiv5_dp_read(dp, ADIV5_DP_CTRLSTAT);

platform_timeout_s timeout;
platform_timeout_set(&timeout, 201);
Expand All @@ -905,7 +913,7 @@ void adiv5_dp_init(adiv5_debug_port_s *const dp, const uint32_t idcode)
* correctly on STM32. CDBGRSTACK is never asserted, and we
* just wait forever. This scenario is described in B2.4.1
* so we have a timeout mechanism in addition to the sensing one. */
platform_timeout_set(&timeout, 200);
platform_timeout_set(&timeout, 200U);
/* Write request for debug reset */
adiv5_dp_write(dp, ADIV5_DP_CTRLSTAT, ctrlstat | ADIV5_DP_CTRLSTAT_CDBGRSTREQ);
/* Wait for acknowledge */
Expand Down Expand Up @@ -941,7 +949,7 @@ void adiv5_dp_init(adiv5_debug_port_s *const dp, const uint32_t idcode)
/* We have probably found all APs on this DP so no need to keep looking.
* Continue with rest of init function down below.
*/
if (++invalid_aps == 8)
if (++invalid_aps == 8U)
break;

continue;
Expand Down