aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/target/riscv/program.c3
-rw-r--r--src/target/riscv/riscv-011.c5
-rw-r--r--src/target/riscv/riscv-013.c76
-rw-r--r--src/target/riscv/riscv.c32
-rw-r--r--src/target/riscv/riscv.h15
5 files changed, 77 insertions, 54 deletions
diff --git a/src/target/riscv/program.c b/src/target/riscv/program.c
index 76f63b8..a7a2e85 100644
--- a/src/target/riscv/program.c
+++ b/src/target/riscv/program.c
@@ -55,7 +55,6 @@ int riscv_program_exec(struct riscv_program *p, struct target *t)
LOG_ERROR("Unable to write ebreak");
for (size_t i = 0; i < riscv_debug_buffer_size(p->target); ++i)
LOG_ERROR("ram[%02x]: DASM(0x%08lx) [0x%08lx]", (int)i, (long)p->debug_buffer[i], (long)p->debug_buffer[i]);
- abort();
return ERROR_FAIL;
}
@@ -152,7 +151,7 @@ int riscv_program_insert(struct riscv_program *p, riscv_insn_t i)
LOG_ERROR("Unable to insert instruction:");
LOG_ERROR(" instruction_count=%d", (int)p->instruction_count);
LOG_ERROR(" buffer size =%d", (int)riscv_debug_buffer_size(p->target));
- abort();
+ return ERROR_FAIL;
}
p->debug_buffer[p->instruction_count] = i;
diff --git a/src/target/riscv/riscv-011.c b/src/target/riscv/riscv-011.c
index 9490f7a..18e31c7 100644
--- a/src/target/riscv/riscv-011.c
+++ b/src/target/riscv/riscv-011.c
@@ -1329,12 +1329,11 @@ static riscv_reg_t get_register(struct target *target, int hartid, int regid)
return value;
}
-static void set_register(struct target *target, int hartid, int regid,
+static int set_register(struct target *target, int hartid, int regid,
uint64_t value)
{
assert(hartid == 0);
- /* TODO: propagate errors */
- register_write(target, regid, value);
+ return register_write(target, regid, value);
}
static int halt(struct target *target)
diff --git a/src/target/riscv/riscv-013.c b/src/target/riscv/riscv-013.c
index 25a875b..6251765 100644
--- a/src/target/riscv/riscv-013.c
+++ b/src/target/riscv/riscv-013.c
@@ -31,22 +31,22 @@
#define DMI_PROGBUF1 (DMI_PROGBUF0 + 1)
static void riscv013_on_step_or_resume(struct target *target, bool step);
-static void riscv013_step_or_resume_current_hart(struct target *target, bool step);
+static int riscv013_step_or_resume_current_hart(struct target *target, bool step);
static void riscv013_clear_abstract_error(struct target *target);
/* Implementations of the functions in riscv_info_t. */
static riscv_reg_t riscv013_get_register(struct target *target, int hartid, int regid);
-static void riscv013_set_register(struct target *target, int hartid, int regid, uint64_t value);
+static int riscv013_set_register(struct target *target, int hartid, int regid, uint64_t value);
static void riscv013_select_current_hart(struct target *target);
-static void riscv013_halt_current_hart(struct target *target);
-static void riscv013_resume_current_hart(struct target *target);
-static void riscv013_step_current_hart(struct target *target);
+static int riscv013_halt_current_hart(struct target *target);
+static int riscv013_resume_current_hart(struct target *target);
+static int riscv013_step_current_hart(struct target *target);
static void riscv013_on_halt(struct target *target);
static void riscv013_on_step(struct target *target);
static void riscv013_on_resume(struct target *target);
static bool riscv013_is_halted(struct target *target);
static enum riscv_halt_reason riscv013_halt_reason(struct target *target);
-static void riscv013_write_debug_buffer(struct target *target, unsigned index,
+static int riscv013_write_debug_buffer(struct target *target, unsigned index,
riscv_insn_t d);
static riscv_insn_t riscv013_read_debug_buffer(struct target *target, unsigned
index);
@@ -418,7 +418,7 @@ static uint64_t dmi_read(struct target *target, uint16_t address)
if (status != DMI_STATUS_SUCCESS) {
LOG_ERROR("Failed read from 0x%x; status=%d", address, status);
- abort();
+ return ~0ULL;
}
/* This second loop ensures that we got the read
@@ -441,13 +441,13 @@ static uint64_t dmi_read(struct target *target, uint16_t address)
if (status != DMI_STATUS_SUCCESS) {
LOG_ERROR("Failed read (NOP) from 0x%x; value=0x%" PRIx64 ", status=%d",
address, value, status);
- abort();
+ return ~0ULL;
}
return value;
}
-static void dmi_write(struct target *target, uint16_t address, uint64_t value)
+static int dmi_write(struct target *target, uint16_t address, uint64_t value)
{
select_dmi(target);
dmi_status_t status = DMI_STATUS_BUSY;
@@ -470,7 +470,7 @@ static void dmi_write(struct target *target, uint16_t address, uint64_t value)
if (status != DMI_STATUS_SUCCESS) {
LOG_ERROR("Failed write to 0x%x;, status=%d",
address, status);
- abort();
+ return ERROR_FAIL;
}
/* The second loop isn't strictly necessary, but would ensure that the
@@ -490,8 +490,10 @@ static void dmi_write(struct target *target, uint16_t address, uint64_t value)
}
if (status != DMI_STATUS_SUCCESS) {
LOG_ERROR("failed to write (NOP) 0x%" PRIx64 " to 0x%x; status=%d", value, address, status);
- abort();
+ return ERROR_FAIL;
}
+
+ return ERROR_OK;
}
static void increase_ac_busy_delay(struct target *target)
@@ -964,7 +966,7 @@ static int register_write_direct(struct target *target, unsigned number,
riscv_program_csrw(&program, S0, number);
} else {
LOG_ERROR("Unsupported register (enum gdb_regno)(%d)", number);
- abort();
+ return ERROR_FAIL;
}
}
@@ -1024,7 +1026,7 @@ static int register_read_direct(struct target *target, uint64_t *value, uint32_t
riscv_program_csrr(&program, S0, number);
} else {
LOG_ERROR("Unsupported register (enum gdb_regno)(%d)", number);
- abort();
+ return ERROR_FAIL;
}
/* Execute program. */
@@ -1885,7 +1887,7 @@ static riscv_reg_t riscv013_get_register(struct target *target, int hid, int rid
return out;
}
-static void riscv013_set_register(struct target *target, int hid, int rid, uint64_t value)
+static int riscv013_set_register(struct target *target, int hid, int rid, uint64_t value)
{
LOG_DEBUG("writing 0x%" PRIx64 " to register %s on hart %d", value,
gdb_regno_name(rid), hid);
@@ -1893,22 +1895,28 @@ static void riscv013_set_register(struct target *target, int hid, int rid, uint6
riscv_set_current_hartid(target, hid);
if (rid <= GDB_REGNO_XPR31) {
- register_write_direct(target, rid, value);
+ return register_write_direct(target, rid, value);
} else if (rid == GDB_REGNO_PC) {
LOG_DEBUG("writing PC to DPC: 0x%016" PRIx64, value);
register_write_direct(target, GDB_REGNO_DPC, value);
uint64_t actual_value;
register_read_direct(target, &actual_value, GDB_REGNO_DPC);
LOG_DEBUG(" actual DPC written: 0x%016" PRIx64, actual_value);
- assert(value == actual_value);
+ if (value != actual_value) {
+ LOG_ERROR("Written PC (0x%" PRIx64 ") does not match read back "
+ "value (0x%" PRIx64 ")", value, actual_value);
+ return ERROR_FAIL;
+ }
} else if (rid == GDB_REGNO_PRIV) {
uint64_t dcsr;
register_read_direct(target, &dcsr, GDB_REGNO_DCSR);
dcsr = set_field(dcsr, CSR_DCSR_PRV, value);
- register_write_direct(target, GDB_REGNO_DCSR, dcsr);
+ return register_write_direct(target, GDB_REGNO_DCSR, dcsr);
} else {
- register_write_direct(target, rid, value);
+ return register_write_direct(target, rid, value);
}
+
+ return ERROR_OK;
}
static void riscv013_select_current_hart(struct target *target)
@@ -1920,11 +1928,12 @@ static void riscv013_select_current_hart(struct target *target)
dmi_write(target, DMI_DMCONTROL, dmcontrol);
}
-static void riscv013_halt_current_hart(struct target *target)
+static int riscv013_halt_current_hart(struct target *target)
{
RISCV_INFO(r);
LOG_DEBUG("halting hart %d", r->current_hartid);
- assert(!riscv_is_halted(target));
+ if (riscv_is_halted(target))
+ LOG_ERROR("Hart %d is already halted!", r->current_hartid);
/* Issue the halt command, and then wait for the current hart to halt. */
uint32_t dmcontrol = dmi_read(target, DMI_DMCONTROL);
@@ -1941,19 +1950,21 @@ static void riscv013_halt_current_hart(struct target *target)
LOG_ERROR("unable to halt hart %d", r->current_hartid);
LOG_ERROR(" dmcontrol=0x%08x", dmcontrol);
LOG_ERROR(" dmstatus =0x%08x", dmstatus);
- abort();
+ return ERROR_FAIL;
}
dmcontrol = set_field(dmcontrol, DMI_DMCONTROL_HALTREQ, 0);
dmi_write(target, DMI_DMCONTROL, dmcontrol);
+
+ return ERROR_OK;
}
-static void riscv013_resume_current_hart(struct target *target)
+static int riscv013_resume_current_hart(struct target *target)
{
return riscv013_step_or_resume_current_hart(target, false);
}
-static void riscv013_step_current_hart(struct target *target)
+static int riscv013_step_current_hart(struct target *target)
{
return riscv013_step_or_resume_current_hart(target, true);
}
@@ -1998,10 +2009,10 @@ static enum riscv_halt_reason riscv013_halt_reason(struct target *target)
LOG_ERROR("Unknown DCSR cause field: %x", (int)get_field(dcsr, CSR_DCSR_CAUSE));
LOG_ERROR(" dcsr=0x%016lx", (long)dcsr);
- abort();
+ return RISCV_HALT_UNKNOWN;
}
-void riscv013_write_debug_buffer(struct target *target, unsigned index, riscv_insn_t data)
+int riscv013_write_debug_buffer(struct target *target, unsigned index, riscv_insn_t data)
{
return dmi_write(target, DMI_PROGBUF0 + index, data);
}
@@ -2070,17 +2081,20 @@ static void riscv013_on_step_or_resume(struct target *target, bool step)
riscv_set_register(target, GDB_REGNO_DCSR, dcsr);
}
-static void riscv013_step_or_resume_current_hart(struct target *target, bool step)
+static int riscv013_step_or_resume_current_hart(struct target *target, bool step)
{
RISCV_INFO(r);
LOG_DEBUG("resuming hart %d (for step?=%d)", r->current_hartid, step);
- assert(riscv_is_halted(target));
+ if (!riscv_is_halted(target)) {
+ LOG_ERROR("Hart %d is not halted!", r->current_hartid);
+ return ERROR_FAIL;
+ }
struct riscv_program program;
riscv_program_init(&program, target);
riscv_program_fence_i(&program);
if (riscv_program_exec(&program, target) != ERROR_OK)
- abort();
+ return ERROR_FAIL;
/* Issue the resume command, and then wait for the current hart to resume. */
uint32_t dmcontrol = dmi_read(target, DMI_DMCONTROL);
@@ -2097,7 +2111,7 @@ static void riscv013_step_or_resume_current_hart(struct target *target, bool ste
dmcontrol = set_field(dmcontrol, DMI_DMCONTROL_RESUMEREQ, 0);
dmi_write(target, DMI_DMCONTROL, dmcontrol);
- return;
+ return ERROR_OK;
}
uint32_t dmstatus = dmi_read(target, DMI_DMSTATUS);
@@ -2109,10 +2123,10 @@ static void riscv013_step_or_resume_current_hart(struct target *target, bool ste
if (step) {
LOG_ERROR(" was stepping, halting");
riscv013_halt_current_hart(target);
- return;
+ return ERROR_OK;
}
- abort();
+ return ERROR_FAIL;
}
void riscv013_clear_abstract_error(struct target *target)
diff --git a/src/target/riscv/riscv.c b/src/target/riscv/riscv.c
index cda16f3..009bc3a 100644
--- a/src/target/riscv/riscv.c
+++ b/src/target/riscv/riscv.c
@@ -1011,6 +1011,9 @@ int riscv_openocd_poll(struct target *target)
case RISCV_HALT_SINGLESTEP:
target->debug_reason = DBG_REASON_SINGLESTEP;
break;
+ case RISCV_HALT_UNKNOWN:
+ target->debug_reason = DBG_REASON_UNDEFINED;
+ break;
}
if (riscv_rtos_enabled(target)) {
@@ -1361,8 +1364,7 @@ int riscv_halt_one_hart(struct target *target, int hartid)
return ERROR_OK;
}
- r->halt_current_hart(target);
- return ERROR_OK;
+ return r->halt_current_hart(target);
}
int riscv_resume_all_harts(struct target *target)
@@ -1389,8 +1391,7 @@ int riscv_resume_one_hart(struct target *target, int hartid)
}
r->on_resume(target);
- r->resume_current_hart(target);
- return ERROR_OK;
+ return r->resume_current_hart(target);
}
int riscv_step_rtos_hart(struct target *target)
@@ -1407,13 +1408,20 @@ int riscv_step_rtos_hart(struct target *target)
riscv_set_current_hartid(target, hartid);
LOG_DEBUG("stepping hart %d", hartid);
- assert(riscv_is_halted(target));
+ if (!riscv_is_halted(target)) {
+ LOG_ERROR("Hart isn't halted before single step!");
+ return ERROR_FAIL;
+ }
riscv_invalidate_register_cache(target);
r->on_step(target);
- r->step_current_hart(target);
+ if (r->step_current_hart(target) != ERROR_OK)
+ return ERROR_FAIL;
riscv_invalidate_register_cache(target);
r->on_halt(target);
- assert(riscv_is_halted(target));
+ if (!riscv_is_halted(target)) {
+ LOG_ERROR("Hart was not halted after single step!");
+ return ERROR_FAIL;
+ }
return ERROR_OK;
}
@@ -1523,13 +1531,12 @@ bool riscv_has_register(struct target *target, int hartid, int regid)
return 1;
}
-void riscv_set_register(struct target *target, enum gdb_regno r, riscv_reg_t v)
+int riscv_set_register(struct target *target, enum gdb_regno r, riscv_reg_t v)
{
- /* TODO: propagate errors */
return riscv_set_register_on_hart(target, riscv_current_hartid(target), r, v);
}
-void riscv_set_register_on_hart(struct target *target, int hartid,
+int riscv_set_register_on_hart(struct target *target, int hartid,
enum gdb_regno regid, uint64_t value)
{
RISCV_INFO(r);
@@ -1562,7 +1569,10 @@ enum riscv_halt_reason riscv_halt_reason(struct target *target, int hartid)
{
RISCV_INFO(r);
riscv_set_current_hartid(target, hartid);
- assert(riscv_is_halted(target));
+ if (!riscv_is_halted(target)) {
+ LOG_ERROR("Hart is not halted!");
+ return RISCV_HALT_UNKNOWN;
+ }
return r->halt_reason(target);
}
diff --git a/src/target/riscv/riscv.h b/src/target/riscv/riscv.h
index 71c68a2..dc3c6f5 100644
--- a/src/target/riscv/riscv.h
+++ b/src/target/riscv/riscv.h
@@ -30,6 +30,7 @@ enum riscv_halt_reason {
RISCV_HALT_INTERRUPT,
RISCV_HALT_BREAKPOINT,
RISCV_HALT_SINGLESTEP,
+ RISCV_HALT_UNKNOWN
};
typedef struct {
@@ -88,18 +89,18 @@ typedef struct {
/* Helper functions that target the various RISC-V debug spec
* implementations. */
riscv_reg_t (*get_register)(struct target *, int hartid, int regid);
- void (*set_register)(struct target *, int hartid, int regid,
+ int (*set_register)(struct target *, int hartid, int regid,
uint64_t value);
void (*select_current_hart)(struct target *);
bool (*is_halted)(struct target *target);
- void (*halt_current_hart)(struct target *);
- void (*resume_current_hart)(struct target *target);
- void (*step_current_hart)(struct target *target);
+ int (*halt_current_hart)(struct target *);
+ int (*resume_current_hart)(struct target *target);
+ int (*step_current_hart)(struct target *target);
void (*on_halt)(struct target *target);
void (*on_resume)(struct target *target);
void (*on_step)(struct target *target);
enum riscv_halt_reason (*halt_reason)(struct target *target);
- void (*write_debug_buffer)(struct target *target, unsigned index,
+ int (*write_debug_buffer)(struct target *target, unsigned index,
riscv_insn_t d);
riscv_insn_t (*read_debug_buffer)(struct target *target, unsigned index);
int (*execute_debug_buffer)(struct target *target);
@@ -202,8 +203,8 @@ bool riscv_has_register(struct target *target, int hartid, int regid);
/* Returns the value of the given register on the given hart. 32-bit registers
* are zero extended to 64 bits. */
-void riscv_set_register(struct target *target, enum gdb_regno i, riscv_reg_t v);
-void riscv_set_register_on_hart(struct target *target, int hid, enum gdb_regno rid, uint64_t v);
+int riscv_set_register(struct target *target, enum gdb_regno i, riscv_reg_t v);
+int riscv_set_register_on_hart(struct target *target, int hid, enum gdb_regno rid, uint64_t v);
riscv_reg_t riscv_get_register(struct target *target, enum gdb_regno i);
riscv_reg_t riscv_get_register_on_hart(struct target *target, int hid, enum gdb_regno rid);