Skip to content

Commit a68695b

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 a68695b

File tree

1 file changed

+40
-21
lines changed

1 file changed

+40
-21
lines changed

src/target/riscv/riscv-013.c

Lines changed: 40 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -534,7 +534,33 @@ 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 activate_dm(struct target *target, uint32_t dm_base_addr)
538+
{
539+
uint32_t dmcontrol = 0;
540+
541+
LOG_TARGET_DEBUG(target, "Activating the DM with DMI base address (dbgbase) = 0x%x", dm_base_addr);
542+
if (dmi_write(target, DM_DMCONTROL + dm_base_addr, DM_DMCONTROL_DMACTIVE) != ERROR_OK)
543+
return ERROR_FAIL;
544+
545+
const time_t start = time(NULL);
546+
LOG_TARGET_DEBUG(target, "Waiting for the DM to become active.");
547+
while (1) {
548+
if (dmi_read(target, &dmcontrol, DM_DMCONTROL + dm_base_addr) != ERROR_OK)
549+
return ERROR_FAIL;
550+
if (get_field32(dmcontrol, DM_DMCONTROL_DMACTIVE))
551+
break;
552+
if (time(NULL) - start > riscv_get_command_timeout_sec()) {
553+
LOG_TARGET_ERROR(target, "Debug Module (at address dbgbase=0x%" PRIx32 ") did not become active in %d s. "
554+
"Increase the timeout with 'riscv set_command_timeout_sec'.",
555+
dm_base_addr, riscv_get_command_timeout_sec());
556+
return ERROR_TIMEOUT_REACHED;
557+
}
558+
}
559+
LOG_TARGET_DEBUG(target, "DM has become active.");
560+
return ERROR_OK;
561+
}
562+
563+
static int check_dbgbase_exists(struct target *target)
538564
{
539565
uint32_t next_dm = 0;
540566
unsigned int count = 1;
@@ -543,7 +569,14 @@ static bool check_dbgbase_exists(struct target *target)
543569
while (1) {
544570
uint32_t current_dm = next_dm;
545571
if (current_dm == target->dbgbase)
546-
return true;
572+
return ERROR_OK;
573+
574+
uint32_t dmcontrol = 0;
575+
if (dmi_read(target, &dmcontrol, DM_DMCONTROL + current_dm) != ERROR_OK)
576+
break;
577+
if (!get_field32(dmcontrol, DM_DMCONTROL_DMACTIVE) && activate_dm(target, current_dm) != ERROR_OK)
578+
break;
579+
547580
if (dmi_read(target, &next_dm, DM_NEXTDM + current_dm) != ERROR_OK)
548581
break;
549582
LOG_TARGET_DEBUG(target, "dm @ 0x%x --> nextdm=0x%x", current_dm, next_dm);
@@ -558,7 +591,7 @@ static bool check_dbgbase_exists(struct target *target)
558591
break;
559592
}
560593
}
561-
return false;
594+
return ERROR_FAIL;
562595
}
563596

564597
static int dmstatus_read(struct target *target, uint32_t *dmstatus,
@@ -1868,27 +1901,13 @@ static int reset_dm(struct target *target)
18681901
} while (get_field32(dmcontrol, DM_DMCONTROL_DMACTIVE));
18691902
LOG_TARGET_DEBUG(target, "DM reset initiated.");
18701903
}
1904+
/* TODO: Move the code above into `deactivate_dm()` function
1905+
* (a logical counterpart to activate_dm()). */
18711906

1872-
LOG_TARGET_DEBUG(target, "Activating the DM.");
1873-
result = dm_write(target, DM_DMCONTROL, DM_DMCONTROL_DMACTIVE);
1907+
result = activate_dm(target, dm->base);
18741908
if (result != ERROR_OK)
18751909
return result;
18761910

1877-
const time_t start = time(NULL);
1878-
LOG_TARGET_DEBUG(target, "Waiting for the DM to come out of reset.");
1879-
do {
1880-
result = dm_read(target, &dmcontrol, DM_DMCONTROL);
1881-
if (result != ERROR_OK)
1882-
return result;
1883-
1884-
if (time(NULL) - start > riscv_get_command_timeout_sec()) {
1885-
LOG_TARGET_ERROR(target, "Debug Module did not become active in %d s. "
1886-
"Increase the timeout with 'riscv set_command_timeout_sec'.",
1887-
riscv_get_command_timeout_sec());
1888-
return ERROR_TIMEOUT_REACHED;
1889-
}
1890-
} while (!get_field32(dmcontrol, DM_DMCONTROL_DMACTIVE));
1891-
18921911
LOG_TARGET_DEBUG(target, "DM successfully reset.");
18931912
dm->was_reset = true;
18941913
return ERROR_OK;
@@ -2043,7 +2062,7 @@ static int examine(struct target *target)
20432062
info->abits, RISCV013_DTMCS_ABITS_MIN);
20442063
}
20452064

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

0 commit comments

Comments
 (0)