Skip to content

Commit 579c41b

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 579c41b

File tree

1 file changed

+31
-4
lines changed

1 file changed

+31
-4
lines changed

src/target/riscv/riscv-013.c

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -534,16 +534,43 @@ 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 check_dbgbase_exists(struct target *target)
538538
{
539539
uint32_t next_dm = 0;
540540
unsigned int count = 1;
541+
uint32_t dmcontrol = 0;
541542

542543
LOG_TARGET_DEBUG(target, "Searching for DM with DMI base address (dbgbase) = 0x%x", target->dbgbase);
543544
while (1) {
544545
uint32_t current_dm = next_dm;
545546
if (current_dm == target->dbgbase)
546-
return true;
547+
return ERROR_OK;
548+
549+
if (dmi_read(target, &dmcontrol, DM_DMCONTROL + current_dm) != ERROR_OK)
550+
break;
551+
if (!get_field32(dmcontrol, DM_DMCONTROL_DMACTIVE)) {
552+
LOG_TARGET_DEBUG(target, "Activating the DM with DMI base address (dbgbase) = 0x%x", current_dm);
553+
if (dmi_write(target, DM_DMCONTROL + current_dm, DM_DMCONTROL_DMACTIVE) != ERROR_OK)
554+
break;
555+
556+
const time_t start = time(NULL);
557+
LOG_TARGET_DEBUG(target, "Waiting for the DM to become active.");
558+
do {
559+
if (dmi_read(target, &dmcontrol, DM_DMCONTROL + current_dm) != ERROR_OK)
560+
return ERROR_FAIL;
561+
562+
if (time(NULL) - start > riscv_get_command_timeout_sec()) {
563+
LOG_TARGET_ERROR(target, "Debug Module did not become active in %d s. "
564+
"Increase the timeout with 'riscv set_command_timeout_sec'.",
565+
riscv_get_command_timeout_sec());
566+
return ERROR_TIMEOUT_REACHED;
567+
}
568+
569+
570+
} while (!get_field32(dmcontrol, DM_DMCONTROL_DMACTIVE));
571+
LOG_TARGET_DEBUG(target, "DM is active.");
572+
}
573+
547574
if (dmi_read(target, &next_dm, DM_NEXTDM + current_dm) != ERROR_OK)
548575
break;
549576
LOG_TARGET_DEBUG(target, "dm @ 0x%x --> nextdm=0x%x", current_dm, next_dm);
@@ -558,7 +585,7 @@ static bool check_dbgbase_exists(struct target *target)
558585
break;
559586
}
560587
}
561-
return false;
588+
return ERROR_FAIL;
562589
}
563590

564591
static int dmstatus_read(struct target *target, uint32_t *dmstatus,
@@ -2043,7 +2070,7 @@ static int examine(struct target *target)
20432070
info->abits, RISCV013_DTMCS_ABITS_MIN);
20442071
}
20452072

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

0 commit comments

Comments
 (0)