Use only one hart to run algorithm. (#396)
* Clear cmderr by writing all ones. This should have been part of #389. Change-Id: Ie40e95fdd904af65c53d1f5de7c8464b27038ec0 * Don't update reg cache in register_write_direct(). This function explicitly bypasses any caches. Change-Id: Ie3c9a1163e870f80c0ed75b74495079c527663e9 * Use only one hart to run algorithm. Fixes a bug with `-rtos hwthread` where all harts would run when running a flash/CRC algorithm, which would probably ruin flashing, and was unexpectedly changing registers on other harts for the CRC algorithm. Change-Id: Ia2f600624f4c8d4cab319861fef2c14722f08b53debug-log-reg-failure
parent
cd7eea6d76
commit
5173ddf75e
|
@ -828,8 +828,7 @@ static int execute_abstract_command(struct target *target, uint32_t command)
|
||||||
if (info->cmderr != 0 || result != ERROR_OK) {
|
if (info->cmderr != 0 || result != ERROR_OK) {
|
||||||
LOG_DEBUG("command 0x%x failed; abstractcs=0x%x", command, abstractcs);
|
LOG_DEBUG("command 0x%x failed; abstractcs=0x%x", command, abstractcs);
|
||||||
/* Clear the error. */
|
/* Clear the error. */
|
||||||
dmi_write(target, DMI_ABSTRACTCS, set_field(0, DMI_ABSTRACTCS_CMDERR,
|
dmi_write(target, DMI_ABSTRACTCS, DMI_ABSTRACTCS_CMDERR);
|
||||||
info->cmderr));
|
|
||||||
return ERROR_FAIL;
|
return ERROR_FAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1267,10 +1266,6 @@ static int register_write_direct(struct target *target, unsigned number,
|
||||||
|
|
||||||
int result = register_write_abstract(target, number, value,
|
int result = register_write_abstract(target, number, value,
|
||||||
register_size(target, number));
|
register_size(target, number));
|
||||||
if (result == ERROR_OK && target->reg_cache) {
|
|
||||||
struct reg *reg = &target->reg_cache->reg_list[number];
|
|
||||||
buf_set_u64(reg->value, 0, reg->size, value);
|
|
||||||
}
|
|
||||||
if (result == ERROR_OK || info->progbufsize + r->impebreak < 2 ||
|
if (result == ERROR_OK || info->progbufsize + r->impebreak < 2 ||
|
||||||
!riscv_is_halted(target))
|
!riscv_is_halted(target))
|
||||||
return result;
|
return result;
|
||||||
|
|
|
@ -1251,16 +1251,21 @@ static int resume_finish(struct target *target)
|
||||||
return target_call_event_callbacks(target, TARGET_EVENT_RESUMED);
|
return target_call_event_callbacks(target, TARGET_EVENT_RESUMED);
|
||||||
}
|
}
|
||||||
|
|
||||||
int riscv_resume(
|
/**
|
||||||
|
* @par single_hart When true, only resume a single hart even if SMP is
|
||||||
|
* configured. This is used to run algorithms on just one hart.
|
||||||
|
*/
|
||||||
|
int riscv_resume_internal(
|
||||||
struct target *target,
|
struct target *target,
|
||||||
int current,
|
int current,
|
||||||
target_addr_t address,
|
target_addr_t address,
|
||||||
int handle_breakpoints,
|
int handle_breakpoints,
|
||||||
int debug_execution
|
int debug_execution,
|
||||||
){
|
bool single_hart)
|
||||||
|
{
|
||||||
LOG_DEBUG("handle_breakpoints=%d", handle_breakpoints);
|
LOG_DEBUG("handle_breakpoints=%d", handle_breakpoints);
|
||||||
int result = ERROR_OK;
|
int result = ERROR_OK;
|
||||||
if (target->smp) {
|
if (target->smp && !single_hart) {
|
||||||
for (struct target_list *tlist = target->head; tlist; tlist = tlist->next) {
|
for (struct target_list *tlist = target->head; tlist; tlist = tlist->next) {
|
||||||
struct target *t = tlist->target;
|
struct target *t = tlist->target;
|
||||||
if (resume_prep(t, current, address, handle_breakpoints,
|
if (resume_prep(t, current, address, handle_breakpoints,
|
||||||
|
@ -1298,6 +1303,13 @@ int riscv_resume(
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int riscv_resume(struct target *target, int current, target_addr_t address,
|
||||||
|
int handle_breakpoints, int debug_execution)
|
||||||
|
{
|
||||||
|
return riscv_resume_internal(target, current, address, handle_breakpoints,
|
||||||
|
debug_execution, false);
|
||||||
|
}
|
||||||
|
|
||||||
static int riscv_select_current_hart(struct target *target)
|
static int riscv_select_current_hart(struct target *target)
|
||||||
{
|
{
|
||||||
RISCV_INFO(r);
|
RISCV_INFO(r);
|
||||||
|
@ -1420,6 +1432,7 @@ static int riscv_run_algorithm(struct target *target, int num_mem_params,
|
||||||
if (!reg_pc || reg_pc->type->get(reg_pc) != ERROR_OK)
|
if (!reg_pc || reg_pc->type->get(reg_pc) != ERROR_OK)
|
||||||
return ERROR_FAIL;
|
return ERROR_FAIL;
|
||||||
uint64_t saved_pc = buf_get_u64(reg_pc->value, 0, reg_pc->size);
|
uint64_t saved_pc = buf_get_u64(reg_pc->value, 0, reg_pc->size);
|
||||||
|
LOG_DEBUG("saved_pc=0x%" PRIx64, saved_pc);
|
||||||
|
|
||||||
uint64_t saved_regs[32];
|
uint64_t saved_regs[32];
|
||||||
for (int i = 0; i < num_reg_params; i++) {
|
for (int i = 0; i < num_reg_params; i++) {
|
||||||
|
@ -1474,7 +1487,7 @@ static int riscv_run_algorithm(struct target *target, int num_mem_params,
|
||||||
|
|
||||||
/* Run algorithm */
|
/* Run algorithm */
|
||||||
LOG_DEBUG("resume at 0x%" TARGET_PRIxADDR, entry_point);
|
LOG_DEBUG("resume at 0x%" TARGET_PRIxADDR, entry_point);
|
||||||
if (riscv_resume(target, 0, entry_point, 0, 0) != ERROR_OK)
|
if (riscv_resume_internal(target, 0, entry_point, 0, 0, true) != ERROR_OK)
|
||||||
return ERROR_FAIL;
|
return ERROR_FAIL;
|
||||||
|
|
||||||
int64_t start = timeval_ms();
|
int64_t start = timeval_ms();
|
||||||
|
|
Loading…
Reference in New Issue