Skip to content

Commit a18fb6b

Browse files
committed
target/riscv: active dm before get nextdm
when Debug Module is inactive, accesses to the nextdm may fail. Specifically, nextdm might not return correct data.
1 parent 8d5f2fe commit a18fb6b

File tree

1 file changed

+41
-19
lines changed

1 file changed

+41
-19
lines changed

src/target/riscv/riscv-013.c

Lines changed: 41 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -534,16 +534,50 @@ static int dm_write(struct target *target, uint32_t address, uint32_t value)
534534
return dmi_write(target, riscv013_get_dmi_address(target, address), value);
535535
}
536536

537-
static bool check_dbgbase_exists(struct target *target)
537+
static int wait_for_dm_activation(struct target *target, uint32_t dm_base_addr)
538+
{
539+
uint32_t dmcontrol = 0;
540+
const time_t start = time(NULL);
541+
542+
LOG_TARGET_DEBUG(target, "Waiting for the DM to become active.");
543+
do {
544+
if (dmi_read(target, &dmcontrol, DM_DMCONTROL + dm_base_addr) != ERROR_OK)
545+
return ERROR_FAIL;
546+
547+
if (time(NULL) - start > riscv_get_command_timeout_sec()) {
548+
LOG_TARGET_ERROR(target, "Debug Module (at address dbgbase=0x%" PRIx32 ") did not become active in %d s. "
549+
"Increase the timeout with 'riscv set_command_timeout_sec'.",
550+
dm_base_addr, riscv_get_command_timeout_sec());
551+
return ERROR_TIMEOUT_REACHED;
552+
}
553+
} while (!get_field32(dmcontrol, DM_DMCONTROL_DMACTIVE));
554+
LOG_TARGET_DEBUG(target, "DM has become active.");
555+
return ERROR_OK;
556+
}
557+
558+
static int check_dbgbase_exists(struct target *target)
538559
{
539560
uint32_t next_dm = 0;
540561
unsigned int count = 1;
562+
uint32_t dmcontrol = 0;
541563

542564
LOG_TARGET_DEBUG(target, "Searching for DM with DMI base address (dbgbase) = 0x%x", target->dbgbase);
543565
while (1) {
544566
uint32_t current_dm = next_dm;
545567
if (current_dm == target->dbgbase)
546-
return true;
568+
return ERROR_OK;
569+
570+
if (dmi_read(target, &dmcontrol, DM_DMCONTROL + current_dm) != ERROR_OK)
571+
break;
572+
if (!get_field32(dmcontrol, DM_DMCONTROL_DMACTIVE)) {
573+
LOG_TARGET_DEBUG(target, "Activating the DM with DMI base address (dbgbase) = 0x%x", current_dm);
574+
if (dmi_write(target, DM_DMCONTROL + current_dm, DM_DMCONTROL_DMACTIVE) != ERROR_OK)
575+
break;
576+
577+
if (wait_for_dm_activation(target, current_dm) != ERROR_OK)
578+
break;
579+
}
580+
547581
if (dmi_read(target, &next_dm, DM_NEXTDM + current_dm) != ERROR_OK)
548582
break;
549583
LOG_TARGET_DEBUG(target, "dm @ 0x%x --> nextdm=0x%x", current_dm, next_dm);
@@ -558,7 +592,7 @@ static bool check_dbgbase_exists(struct target *target)
558592
break;
559593
}
560594
}
561-
return false;
595+
return ERROR_FAIL;
562596
}
563597

564598
static int dmstatus_read(struct target *target, uint32_t *dmstatus,
@@ -1852,21 +1886,9 @@ static int reset_dm(struct target *target)
18521886
if (result != ERROR_OK)
18531887
return result;
18541888

1855-
const time_t start = time(NULL);
1856-
LOG_TARGET_DEBUG(target, "Waiting for the DM to acknowledge reset.");
1857-
do {
1858-
result = dm_read(target, &dmcontrol, DM_DMCONTROL);
1859-
if (result != ERROR_OK)
1860-
return result;
1861-
1862-
if (time(NULL) - start > riscv_get_command_timeout_sec()) {
1863-
LOG_TARGET_ERROR(target, "DM didn't acknowledge reset in %d s. "
1864-
"Increase the timeout with 'riscv set_command_timeout_sec'.",
1865-
riscv_get_command_timeout_sec());
1866-
return ERROR_TIMEOUT_REACHED;
1867-
}
1868-
} while (get_field32(dmcontrol, DM_DMCONTROL_DMACTIVE));
1869-
LOG_TARGET_DEBUG(target, "DM reset initiated.");
1889+
result = wait_for_dm_activation(target, dm->base);
1890+
if (result != ERROR_OK)
1891+
return result;
18701892
}
18711893

18721894
LOG_TARGET_DEBUG(target, "Activating the DM.");
@@ -2043,7 +2065,7 @@ static int examine(struct target *target)
20432065
info->abits, RISCV013_DTMCS_ABITS_MIN);
20442066
}
20452067

2046-
if (!check_dbgbase_exists(target)) {
2068+
if (check_dbgbase_exists(target) != ERROR_OK) {
20472069
LOG_TARGET_ERROR(target, "Could not find debug module with DMI base address (dbgbase) = 0x%x", target->dbgbase);
20482070
return ERROR_FAIL;
20492071
}

0 commit comments

Comments
 (0)