diff --git a/src/target/riscv/riscv-013.c b/src/target/riscv/riscv-013.c index 66d9602a1..c5a2420ba 100644 --- a/src/target/riscv/riscv-013.c +++ b/src/target/riscv/riscv-013.c @@ -63,7 +63,6 @@ static void riscv013_fill_dmi_write_u64(struct target *target, char *buf, int a, static void riscv013_fill_dmi_read_u64(struct target *target, char *buf, int a); static int riscv013_dmi_write_u64_bits(struct target *target); static void riscv013_fill_dmi_nop_u64(struct target *target, char *buf); -static void riscv013_reset_current_hart(struct target *target); /** * Since almost everything can be accomplish by scanning the dbus register, all @@ -904,7 +903,6 @@ static int init_target(struct command_context *cmd_ctx, generic_info->fill_dmi_read_u64 = &riscv013_fill_dmi_read_u64; generic_info->fill_dmi_nop_u64 = &riscv013_fill_dmi_nop_u64; generic_info->dmi_write_u64_bits = &riscv013_dmi_write_u64_bits; - generic_info->reset_current_hart = &riscv013_reset_current_hart; generic_info->version_specific = calloc(1, sizeof(riscv013_info_t)); if (!generic_info->version_specific) return ERROR_FAIL; @@ -1192,19 +1190,19 @@ static int assert_reset(struct target *target) assert(r->current_hartid == 0); select_dmi(target); - LOG_DEBUG("ASSERTING NDRESET"); - uint32_t control = dmi_read(target, DMI_DMCONTROL); - control = set_field(control, DMI_DMCONTROL_NDMRESET, 1); - if (target->reset_halt) { - LOG_DEBUG("TARGET RESET HALT SET, ensuring halt is set during reset."); - control = set_field(control, DMI_DMCONTROL_HALTREQ, 1); - } else { - LOG_DEBUG("TARGET RESET HALT NOT SET"); - control = set_field(control, DMI_DMCONTROL_HALTREQ, 0); - } + uint32_t control = 0; + control = set_field(control, DMI_DMCONTROL_HALTREQ, target->reset_halt ? 1 : 0); + control = set_field(control, DMI_DMCONTROL_HARTRESET, 1); + control = set_field(control, DMI_DMCONTROL_NDMRESET, 1); + control = set_field(control, DMI_DMCONTROL_HARTSEL, r->current_hartid); + control = set_field(control, DMI_DMCONTROL_DMACTIVE, 1); + + LOG_DEBUG("write 0x%x to dmcontrol", control); dmi_write(target, DMI_DMCONTROL, control); + target->state = TARGET_RESET; + return ERROR_OK; } @@ -1219,33 +1217,53 @@ static int deassert_reset(struct target *target) /*FIXME -- is there bookkeeping we need to do here*/ - uint32_t control = dmi_read(target, DMI_DMCONTROL); - // Clear the reset, but make sure haltreq is still set - if (target->reset_halt) { - control = set_field(control, DMI_DMCONTROL_HALTREQ, 1); - } - - control = set_field(control, DMI_DMCONTROL_NDMRESET, 0); + uint32_t control = 0; + control = set_field(control, DMI_DMCONTROL_HALTREQ, target->reset_halt ? 1 : 0); + control = set_field(control, DMI_DMCONTROL_HARTSEL, r->current_hartid); + control = set_field(control, DMI_DMCONTROL_DMACTIVE, 1); dmi_write(target, DMI_DMCONTROL, control); - uint32_t status; + uint32_t dmstatus; int dmi_busy_delay = info->dmi_busy_delay; + time_t start = time(NULL); + if (target->reset_halt) { - LOG_DEBUG("DEASSERTING RESET, waiting for hart to be halted."); + LOG_DEBUG("Waiting for hart to be halted."); do { - status = dmi_read(target, DMI_DMSTATUS); - } while (get_field(status, DMI_DMSTATUS_ALLHALTED) == 0); - } else { - LOG_DEBUG("DEASSERTING RESET, waiting for hart to be running."); - do { - status = dmi_read(target, DMI_DMSTATUS); - if (get_field(status, DMI_DMSTATUS_ANYHALTED) || - get_field(status, DMI_DMSTATUS_ANYUNAVAIL)) { - LOG_ERROR("Unexpected hart status during reset."); - abort(); + dmstatus = dmi_read(target, DMI_DMSTATUS); + if (time(NULL) - start > riscv_reset_timeout_sec) { + LOG_ERROR("Hart didn't halt coming out of reset in %ds; " + "dmstatus=0x%x; " + "Increase the timeout with riscv set_reset_timeout_sec.", + riscv_reset_timeout_sec, dmstatus); + return ERROR_FAIL; } - } while (get_field(status, DMI_DMSTATUS_ALLRUNNING) == 0); + target->state = TARGET_HALTED; + } while (get_field(dmstatus, DMI_DMSTATUS_ALLHALTED) == 0); + + control = set_field(control, DMI_DMCONTROL_HALTREQ, 0); + dmi_write(target, DMI_DMCONTROL, control); + + } else { + LOG_DEBUG("Waiting for hart to be running."); + do { + dmstatus = dmi_read(target, DMI_DMSTATUS); + if (get_field(dmstatus, DMI_DMSTATUS_ANYHALTED) || + get_field(dmstatus, DMI_DMSTATUS_ANYUNAVAIL)) { + LOG_ERROR("Unexpected hart status during reset. dmstatus=0x%x", + dmstatus); + return ERROR_FAIL; + } + if (time(NULL) - start > riscv_reset_timeout_sec) { + LOG_ERROR("Hart didn't run coming out of reset in %ds; " + "dmstatus=0x%x; " + "Increase the timeout with riscv set_reset_timeout_sec.", + riscv_reset_timeout_sec, dmstatus); + return ERROR_FAIL; + } + } while (get_field(dmstatus, DMI_DMSTATUS_ALLRUNNING) == 0); + target->state = TARGET_RUNNING; } info->dmi_busy_delay = dmi_busy_delay; return ERROR_OK; @@ -1880,37 +1898,6 @@ int riscv013_dmi_write_u64_bits(struct target *target) return info->abits + DTM_DMI_DATA_LENGTH + DTM_DMI_OP_LENGTH; } -void riscv013_reset_current_hart(struct target *target) -{ - select_dmi(target); - uint32_t control = dmi_read(target, DMI_DMCONTROL); - control = set_field(control, DMI_DMCONTROL_NDMRESET, 1); - control = set_field(control, DMI_DMCONTROL_HALTREQ, 1); - dmi_write(target, DMI_DMCONTROL, control); - - control = set_field(control, DMI_DMCONTROL_NDMRESET, 0); - dmi_write(target, DMI_DMCONTROL, control); - - time_t start = time(NULL); - - while (1) { - uint32_t dmstatus = dmi_read(target, DMI_DMSTATUS); - if (get_field(dmstatus, DMI_DMSTATUS_ALLHALTED)) { - break; - } - if (time(NULL) - start > riscv_reset_timeout_sec) { - LOG_ERROR("Hart didn't halt coming out of reset in %ds; " - "dmstatus=0x%x; " - "Increase the timeout with riscv set_reset_timeout_sec.", - riscv_reset_timeout_sec, dmstatus); - return; - } - } - - control = set_field(control, DMI_DMCONTROL_HALTREQ, 0); - dmi_write(target, DMI_DMCONTROL, control); -} - /* Helper Functions. */ static void riscv013_on_step_or_resume(struct target *target, bool step) { diff --git a/src/target/riscv/riscv.c b/src/target/riscv/riscv.c index a502da5a6..491996bf1 100644 --- a/src/target/riscv/riscv.c +++ b/src/target/riscv/riscv.c @@ -676,14 +676,13 @@ static int old_or_new_riscv_halt(struct target *target) return riscv_openocd_halt(target); } -static int oldriscv_assert_reset(struct target *target) +static int riscv_assert_reset(struct target *target) { - LOG_DEBUG("RISCV ASSERT RESET"); struct target_type *tt = get_target_type(target); return tt->assert_reset(target); } -static int oldriscv_deassert_reset(struct target *target) +static int riscv_deassert_reset(struct target *target) { LOG_DEBUG("RISCV DEASSERT RESET"); struct target_type *tt = get_target_type(target); @@ -691,24 +690,6 @@ static int oldriscv_deassert_reset(struct target *target) } -static int old_or_new_riscv_assert_reset(struct target *target) -{ - RISCV_INFO(r); - if (r->is_halted == NULL) - return oldriscv_assert_reset(target); - else - return riscv_openocd_assert_reset(target); -} - -static int old_or_new_riscv_deassert_reset(struct target *target) -{ - RISCV_INFO(r); - if (r->is_halted == NULL) - return oldriscv_deassert_reset(target); - else - return riscv_openocd_deassert_reset(target); -} - static int oldriscv_resume(struct target *target, int current, uint32_t address, int handle_breakpoints, int debug_execution) { @@ -1115,29 +1096,6 @@ int riscv_openocd_step( return out; } -int riscv_openocd_assert_reset(struct target *target) -{ - LOG_DEBUG("asserting reset for all harts"); - int out = riscv_reset_all_harts(target); - if (out != ERROR_OK) { - LOG_ERROR("unable to reset all harts"); - return out; - } - - return out; -} - -int riscv_openocd_deassert_reset(struct target *target) -{ - LOG_DEBUG("deasserting reset for all harts"); - if (target->reset_halt) - riscv_halt_all_harts(target); - else - riscv_resume_all_harts(target); - return ERROR_OK; -} - - /* Command Handlers */ COMMAND_HANDLER(riscv_set_command_timeout_sec) { @@ -1217,8 +1175,8 @@ struct target_type riscv_target = .resume = old_or_new_riscv_resume, .step = old_or_new_riscv_step, - .assert_reset = old_or_new_riscv_assert_reset, - .deassert_reset = old_or_new_riscv_deassert_reset, + .assert_reset = riscv_assert_reset, + .deassert_reset = riscv_deassert_reset, .read_memory = riscv_read_memory, .write_memory = riscv_write_memory, @@ -1315,33 +1273,6 @@ int riscv_resume_one_hart(struct target *target, int hartid) return ERROR_OK; } -int riscv_reset_all_harts(struct target *target) -{ - for (int i = 0; i < riscv_count_harts(target); ++i) { - if (!riscv_hart_enabled(target, i)) - continue; - - riscv_reset_one_hart(target, i); - } - - riscv_invalidate_register_cache(target); - return ERROR_OK; -} - -int riscv_reset_one_hart(struct target *target, int hartid) -{ - RISCV_INFO(r); - LOG_DEBUG("resetting hart %d", hartid); - riscv_halt_one_hart(target, hartid); - riscv_set_current_hartid(target, hartid); - r->reset_current_hart(target); - /* At this point the hart must be halted. On platforms that support - * "reset halt" exactly we expect the hart to have been halted before - * executing any instructions, while on older cores it'll just have - * halted quickly. */ - return ERROR_OK; -} - int riscv_step_rtos_hart(struct target *target) { RISCV_INFO(r); diff --git a/src/target/riscv/riscv.h b/src/target/riscv/riscv.h index 391b1a69e..d84e51ceb 100644 --- a/src/target/riscv/riscv.h +++ b/src/target/riscv/riscv.h @@ -103,7 +103,6 @@ typedef struct { void (*fill_dmi_write_u64)(struct target *target, char *buf, int a, uint64_t d); void (*fill_dmi_read_u64)(struct target *target, char *buf, int a); void (*fill_dmi_nop_u64)(struct target *target, char *buf); - void (*reset_current_hart)(struct target *target); } riscv_info_t; /* Wall-clock timeout for a command/access. Settable via RISC-V Target commands.*/ @@ -161,8 +160,6 @@ int riscv_halt_all_harts(struct target *target); int riscv_halt_one_hart(struct target *target, int hartid); int riscv_resume_all_harts(struct target *target); int riscv_resume_one_hart(struct target *target, int hartid); -int riscv_reset_all_harts(struct target *target); -int riscv_reset_one_hart(struct target *target, int hartid); /* Steps the hart that's currently selected in the RTOS, or if there is no RTOS * then the only hart. */