From fc210e8689226a8eed9d1a9809e2748814a22a0e Mon Sep 17 00:00:00 2001 From: Tim Newsome Date: Thu, 17 Nov 2022 09:44:11 -0800 Subject: [PATCH 1/3] target/riscv: Ignore debug_execution in 0.11 resume It's only used to change what callback events are generated, and there are none anyway. (That's probably a bug, but since 0.11 is so rare I'm not going to worry about it.) Fixes #757. Change-Id: I5b5df3a9bec927fb0368304229533e2875a83f6b Signed-off-by: Tim Newsome --- src/target/riscv/riscv-011.c | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/src/target/riscv/riscv-011.c b/src/target/riscv/riscv-011.c index d999ab397..2c4a46e46 100644 --- a/src/target/riscv/riscv-011.c +++ b/src/target/riscv/riscv-011.c @@ -1195,16 +1195,6 @@ static int full_step(struct target *target, bool announce) return ERROR_OK; } -static int resume(struct target *target, int debug_execution, bool step) -{ - if (debug_execution) { - LOG_ERROR("TODO: debug_execution is true"); - return ERROR_FAIL; - } - - return execute_resume(target, step); -} - static uint64_t reg_cache_get(struct target *target, unsigned int number) { struct reg *r = &target->reg_cache->reg_list[number]; @@ -1935,7 +1925,7 @@ static int riscv011_resume(struct target *target, int current, jtag_add_ir_scan(target->tap, &select_dbus, TAP_IDLE); r->prepped = false; - return resume(target, debug_execution, false); + return execute_resume(target, false); } static int assert_reset(struct target *target) From e16d7a5611e6f36d218aed1edfc6f445999eb8ed Mon Sep 17 00:00:00 2001 From: Tim Newsome Date: Thu, 17 Nov 2022 09:47:01 -0800 Subject: [PATCH 2/3] target/riscv: Ignore maskmax when reading back tdata1 We don't correctly write it, so we shouldn't expect it to read back the same value. Fixes hardware breakpoints on mcontrol triggers. Change-Id: Ie5e445060ec9c8887af933fd8887e57308330f09 --- src/target/riscv/riscv.c | 33 ++++++++++++++++++--------------- 1 file changed, 18 insertions(+), 15 deletions(-) diff --git a/src/target/riscv/riscv.c b/src/target/riscv/riscv.c index 5cda3acc6..c4809a0e9 100644 --- a/src/target/riscv/riscv.c +++ b/src/target/riscv/riscv.c @@ -506,7 +506,8 @@ static int find_trigger(struct target *target, int type, bool chained, int *idx) return ERROR_FAIL; } -static int set_trigger(struct target *target, int idx, riscv_reg_t tdata1, riscv_reg_t tdata2) +static int set_trigger(struct target *target, int idx, riscv_reg_t tdata1, riscv_reg_t tdata2, + riscv_reg_t tdata1_ignore_mask) { riscv_reg_t tdata1_rb; if (riscv_set_register(target, GDB_REGNO_TSELECT, idx) != ERROR_OK) @@ -515,10 +516,11 @@ static int set_trigger(struct target *target, int idx, riscv_reg_t tdata1, riscv return ERROR_FAIL; if (riscv_get_register(target, &tdata1_rb, GDB_REGNO_TDATA1) != ERROR_OK) return ERROR_FAIL; - if (tdata1 != tdata1_rb) { + if ((tdata1 & ~tdata1_ignore_mask) != (tdata1_rb & ~tdata1_ignore_mask)) { LOG_DEBUG("Trigger doesn't support what we need; After writing 0x%" - PRIx64 " to tdata1 it contains 0x%" PRIx64, - tdata1, tdata1_rb); + PRIx64 " to tdata1 it contains 0x%" PRIx64 + "; tdata1_ignore_mask=0x%" PRIx64, + tdata1, tdata1_rb, tdata1_ignore_mask); riscv_set_register(target, GDB_REGNO_TDATA1, 0); return ERROR_TARGET_RESOURCE_NOT_AVAILABLE; } @@ -567,7 +569,7 @@ static int maybe_add_trigger_t1(struct target *target, struct trigger *trigger) tdata1 = set_field(tdata1, bpcontrol_bpaction, 0); /* cause bp exception */ tdata1 = set_field(tdata1, bpcontrol_bpmatch, 0); /* exact match */ tdata2 = trigger->address; - ret = set_trigger(target, idx, tdata1, tdata2); + ret = set_trigger(target, idx, tdata1, tdata2, 0); if (ret != ERROR_OK) return ret; r->trigger_unique_id[idx] = trigger->unique_id; @@ -604,7 +606,7 @@ static int maybe_add_trigger_t2(struct target *target, struct trigger *trigger) return ret; tdata1 = set_field(tdata1, CSR_MCONTROL_MATCH, CSR_MCONTROL_MATCH_NAPOT); tdata1 = set_field(tdata1, CSR_MCONTROL_CHAIN, CSR_MCONTROL_CHAIN_DISABLED); - ret = set_trigger(target, idx, tdata1, tdata2); + ret = set_trigger(target, idx, tdata1, tdata2, CSR_MCONTROL_MASKMAX(riscv_xlen(target))); if (ret != ERROR_OK) { if (ret == ERROR_TARGET_RESOURCE_NOT_AVAILABLE) goto MATCH_GE_LT; /* Fallback to chained MATCH using GT and LE */ @@ -620,7 +622,7 @@ MATCH_GE_LT: tdata1 = set_field(tdata1, CSR_MCONTROL_MATCH, CSR_MCONTROL_MATCH_GE); tdata1 = set_field(tdata1, CSR_MCONTROL_CHAIN, CSR_MCONTROL_CHAIN_ENABLED); tdata2 = trigger->address; - ret = set_trigger(target, idx, tdata1, tdata2); + ret = set_trigger(target, idx, tdata1, tdata2, 0); if (ret != ERROR_OK) { if (ret == ERROR_TARGET_RESOURCE_NOT_AVAILABLE) goto MATCH_EQUAL; /* Fallback to EQUAL MATCH */ @@ -629,9 +631,10 @@ MATCH_GE_LT: tdata1 = set_field(tdata1, CSR_MCONTROL_MATCH, CSR_MCONTROL_MATCH_LT); tdata1 = set_field(tdata1, CSR_MCONTROL_CHAIN, CSR_MCONTROL_CHAIN_DISABLED); tdata2 = trigger->address + trigger->length; - ret = set_trigger(target, idx + 1, tdata1, tdata2); + ret = set_trigger(target, idx + 1, tdata1, tdata2, 0); if (ret != ERROR_OK) { - set_trigger(target, idx, 0, 0); /* Undo the setting of the previous trigger*/ + /* Undo the setting of the previous trigger*/ + set_trigger(target, idx, 0, 0, CSR_MCONTROL_MASKMAX(riscv_xlen(target))); if (ret == ERROR_TARGET_RESOURCE_NOT_AVAILABLE) goto MATCH_EQUAL; /* Fallback to EQUAL MATCH */ return ret; @@ -651,7 +654,7 @@ MATCH_EQUAL: } tdata1 = set_field(tdata1, CSR_MCONTROL_CHAIN, CSR_MCONTROL_CHAIN_DISABLED); tdata2 = trigger->address; - ret = set_trigger(target, idx, tdata1, tdata2); + ret = set_trigger(target, idx, tdata1, tdata2, CSR_MCONTROL_MASKMAX(riscv_xlen(target))); if (ret != ERROR_OK) return ret; r->trigger_unique_id[idx] = trigger->unique_id; @@ -687,7 +690,7 @@ static int maybe_add_trigger_t6(struct target *target, struct trigger *trigger) return ret; tdata1 = set_field(tdata1, CSR_MCONTROL6_MATCH, CSR_MCONTROL6_MATCH_NAPOT); tdata1 = set_field(tdata1, CSR_MCONTROL6_CHAIN, CSR_MCONTROL6_CHAIN_DISABLED); - ret = set_trigger(target, idx, tdata1, tdata2); + ret = set_trigger(target, idx, tdata1, tdata2, 0); if (ret != ERROR_OK) { if (ret == ERROR_TARGET_RESOURCE_NOT_AVAILABLE) goto MATCH_GE_LT; /* Fallback to chained MATCH using GT and LE */ @@ -703,7 +706,7 @@ MATCH_GE_LT: tdata1 = set_field(tdata1, CSR_MCONTROL6_MATCH, CSR_MCONTROL6_MATCH_GE); tdata1 = set_field(tdata1, CSR_MCONTROL6_CHAIN, CSR_MCONTROL6_CHAIN_ENABLED); tdata2 = trigger->address; - ret = set_trigger(target, idx, tdata1, tdata2); + ret = set_trigger(target, idx, tdata1, tdata2, 0); if (ret != ERROR_OK) { if (ret == ERROR_TARGET_RESOURCE_NOT_AVAILABLE) goto MATCH_EQUAL; /* Fallback to EQUAL MATCH */ @@ -712,9 +715,9 @@ MATCH_GE_LT: tdata1 = set_field(tdata1, CSR_MCONTROL6_MATCH, CSR_MCONTROL6_MATCH_LT); tdata1 = set_field(tdata1, CSR_MCONTROL6_CHAIN, CSR_MCONTROL6_CHAIN_DISABLED); tdata2 = trigger->address + trigger->length; - ret = set_trigger(target, idx + 1, tdata1, tdata2); + ret = set_trigger(target, idx + 1, tdata1, tdata2, 0); if (ret != ERROR_OK) { - set_trigger(target, idx, 0, 0); /* Undo the setting of the previous trigger*/ + set_trigger(target, idx, 0, 0, 0); /* Undo the setting of the previous trigger*/ if (ret == ERROR_TARGET_RESOURCE_NOT_AVAILABLE) goto MATCH_EQUAL; /* Fallback to EQUAL MATCH */ return ret; @@ -732,7 +735,7 @@ MATCH_EQUAL: tdata1 = set_field(tdata1, CSR_MCONTROL6_SIZE, CSR_MCONTROL6_SIZE_8BIT); tdata1 = set_field(tdata1, CSR_MCONTROL6_CHAIN, CSR_MCONTROL6_CHAIN_DISABLED); tdata2 = trigger->address; - ret = set_trigger(target, idx, tdata1, tdata2); + ret = set_trigger(target, idx, tdata1, tdata2, 0); if (ret != ERROR_OK) return ret; r->trigger_unique_id[idx] = trigger->unique_id; From f1e20767bc9c78b994ecc18f1124e721b169013f Mon Sep 17 00:00:00 2001 From: Tim Newsome Date: Thu, 17 Nov 2022 11:27:18 -0800 Subject: [PATCH 3/3] target/riscv: 0.11, call handle_halt() after step This ensures that we populate the register cache and set target->state. Some RISC-V changes had upset the balance. Change-Id: I47fbf8ebd8fe39fa5b752212080f87e3b7e6e5e5 Signed-off-by: Tim Newsome --- src/target/riscv/riscv-011.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/target/riscv/riscv-011.c b/src/target/riscv/riscv-011.c index 2c4a46e46..e38d85410 100644 --- a/src/target/riscv/riscv-011.c +++ b/src/target/riscv/riscv-011.c @@ -67,6 +67,8 @@ * to the target. Afterwards use cache_get... to read results. */ +static int handle_halt(struct target *target, bool announce); + #define get_field(reg, mask) (((reg) & (mask)) / ((mask) & ~((mask) << 1))) #define set_field(reg, mask, val) (((reg) & ~(mask)) | (((val) * ((mask) & ~((mask) << 1))) & (mask))) @@ -1192,7 +1194,7 @@ static int full_step(struct target *target, bool announce) return ERROR_FAIL; } } - return ERROR_OK; + return handle_halt(target, announce); } static uint64_t reg_cache_get(struct target *target, unsigned int number)