Skip to content

Commit 9736c96

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 9736c96

File tree

1 file changed

+39
-21
lines changed

1 file changed

+39
-21
lines changed

src/target/riscv/riscv-013.c

Lines changed: 39 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -534,7 +534,32 @@ 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+
const time_t start = time(NULL);
541+
542+
LOG_TARGET_DEBUG(target, "Activating the DM with DMI base address (dbgbase) = 0x%x", dm_base_addr);
543+
if (dmi_write(target, DM_DMCONTROL + dm_base_addr, DM_DMCONTROL_DMACTIVE) != ERROR_OK)
544+
return ERROR_FAIL;
545+
546+
LOG_TARGET_DEBUG(target, "Waiting for the DM to become active.");
547+
do {
548+
if (dmi_read(target, &dmcontrol, DM_DMCONTROL + dm_base_addr) != ERROR_OK)
549+
return ERROR_FAIL;
550+
551+
if (time(NULL) - start > riscv_get_command_timeout_sec()) {
552+
LOG_TARGET_ERROR(target, "Debug Module (at address dbgbase=0x%" PRIx32 ") did not become active in %d s. "
553+
"Increase the timeout with 'riscv set_command_timeout_sec'.",
554+
dm_base_addr, riscv_get_command_timeout_sec());
555+
return ERROR_TIMEOUT_REACHED;
556+
}
557+
} while (!get_field32(dmcontrol, DM_DMCONTROL_DMACTIVE));
558+
LOG_TARGET_DEBUG(target, "DM has become active.");
559+
return ERROR_OK;
560+
}
561+
562+
static int check_dbgbase_exists(struct target *target)
538563
{
539564
uint32_t next_dm = 0;
540565
unsigned int count = 1;
@@ -543,7 +568,14 @@ static bool check_dbgbase_exists(struct target *target)
543568
while (1) {
544569
uint32_t current_dm = next_dm;
545570
if (current_dm == target->dbgbase)
546-
return true;
571+
return ERROR_OK;
572+
573+
uint32_t dmcontrol = 0;
574+
if (dmi_read(target, &dmcontrol, DM_DMCONTROL + current_dm) != ERROR_OK)
575+
break;
576+
if (!get_field32(dmcontrol, DM_DMCONTROL_DMACTIVE) && activate_dm(target, current_dm) != ERROR_OK)
577+
break;
578+
547579
if (dmi_read(target, &next_dm, DM_NEXTDM + current_dm) != ERROR_OK)
548580
break;
549581
LOG_TARGET_DEBUG(target, "dm @ 0x%x --> nextdm=0x%x", current_dm, next_dm);
@@ -558,7 +590,7 @@ static bool check_dbgbase_exists(struct target *target)
558590
break;
559591
}
560592
}
561-
return false;
593+
return ERROR_FAIL;
562594
}
563595

564596
static int dmstatus_read(struct target *target, uint32_t *dmstatus,
@@ -1868,27 +1900,13 @@ static int reset_dm(struct target *target)
18681900
} while (get_field32(dmcontrol, DM_DMCONTROL_DMACTIVE));
18691901
LOG_TARGET_DEBUG(target, "DM reset initiated.");
18701902
}
1903+
/* TODO: Move the code above into `deactivate_dm()` function
1904+
* (a logical counterpart to activate_dm()). */
18711905

1872-
LOG_TARGET_DEBUG(target, "Activating the DM.");
1873-
result = dm_write(target, DM_DMCONTROL, DM_DMCONTROL_DMACTIVE);
1906+
result = activate_dm(target, dm->base);
18741907
if (result != ERROR_OK)
18751908
return result;
18761909

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-
18921910
LOG_TARGET_DEBUG(target, "DM successfully reset.");
18931911
dm->was_reset = true;
18941912
return ERROR_OK;
@@ -2043,7 +2061,7 @@ static int examine(struct target *target)
20432061
info->abits, RISCV013_DTMCS_ABITS_MIN);
20442062
}
20452063

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

0 commit comments

Comments
 (0)