aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTim Newsome <tim@sifive.com>2022-02-15 10:27:16 -0800
committerGitHub <noreply@github.com>2022-02-15 10:27:16 -0800
commit435a6522366ba9ebc8104c190045483918b27ff8 (patch)
tree3828021591ac759f5219d01a1c787e934ade04a9
parent3473953724ca1c4e41581c473acf491a00c3f876 (diff)
parent8274cc58c1a1b44ac23fd542f136d9265c6c3252 (diff)
downloadriscv-openocd-435a6522366ba9ebc8104c190045483918b27ff8.zip
riscv-openocd-435a6522366ba9ebc8104c190045483918b27ff8.tar.gz
riscv-openocd-435a6522366ba9ebc8104c190045483918b27ff8.tar.bz2
Merge pull request #678 from riscv/invalidate-progbuf-cache
fix progbuf cache: invalidate it when needed
-rw-r--r--src/target/riscv/riscv-013.c20
-rw-r--r--src/target/riscv/riscv.c23
-rw-r--r--src/target/riscv/riscv.h1
3 files changed, 39 insertions, 5 deletions
diff --git a/src/target/riscv/riscv-013.c b/src/target/riscv/riscv-013.c
index ec6821d..62866dc 100644
--- a/src/target/riscv/riscv-013.c
+++ b/src/target/riscv/riscv-013.c
@@ -52,6 +52,7 @@ 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);
+static int riscv013_invalidate_cached_debug_buffer(struct target *target);
static int riscv013_execute_debug_buffer(struct target *target);
static void riscv013_fill_dmi_write_u64(struct target *target, char *buf, int a, uint64_t d);
static void riscv013_fill_dmi_read_u64(struct target *target, char *buf, int a);
@@ -1248,6 +1249,7 @@ static int scratch_write64(struct target *target, scratch_mem_t *scratch,
case SPACE_DMI_PROGBUF:
dmi_write(target, DM_PROGBUF0 + scratch->debug_address, value);
dmi_write(target, DM_PROGBUF1 + scratch->debug_address, value >> 32);
+ riscv013_invalidate_cached_debug_buffer(target);
break;
case SPACE_DMI_RAM:
{
@@ -1566,6 +1568,9 @@ static int examine(struct target *target)
dmi_write(target, DM_DMCONTROL, 0);
dmi_write(target, DM_DMCONTROL, DM_DMCONTROL_DMACTIVE);
dm->was_reset = true;
+
+ /* The DM gets reset, so forget any cached progbuf entries. */
+ riscv013_invalidate_cached_debug_buffer(target);
}
dmi_write(target, DM_DMCONTROL, DM_DMCONTROL_HARTSELLO |
@@ -2278,6 +2283,7 @@ static int init_target(struct command_context *cmd_ctx,
generic_info->read_debug_buffer = &riscv013_read_debug_buffer;
generic_info->write_debug_buffer = &riscv013_write_debug_buffer;
generic_info->execute_debug_buffer = &riscv013_execute_debug_buffer;
+ generic_info->invalidate_cached_debug_buffer = &riscv013_invalidate_cached_debug_buffer;
generic_info->fill_dmi_write_u64 = &riscv013_fill_dmi_write_u64;
generic_info->fill_dmi_read_u64 = &riscv013_fill_dmi_read_u64;
generic_info->fill_dmi_nop_u64 = &riscv013_fill_dmi_nop_u64;
@@ -2368,7 +2374,7 @@ static int assert_reset(struct target *target)
/* The DM might have gotten reset if OpenOCD called us in some reset that
* involves SRST being toggled. So clear our cache which may be out of
* date. */
- memset(dm->progbuf_cache, 0, sizeof(dm->progbuf_cache));
+ riscv013_invalidate_cached_debug_buffer(target);
return ERROR_OK;
}
@@ -4337,6 +4343,18 @@ riscv_insn_t riscv013_read_debug_buffer(struct target *target, unsigned index)
return value;
}
+int riscv013_invalidate_cached_debug_buffer(struct target *target)
+{
+ dm013_info_t *dm = get_dm(target);
+ if (!dm)
+ return ERROR_FAIL;
+
+ LOG_TARGET_DEBUG(target, "Invalidating progbuf cache");
+ for (unsigned int i = 0; i < 15; i++)
+ dm->progbuf_cache[i] = 0;
+ return ERROR_OK;
+}
+
int riscv013_execute_debug_buffer(struct target *target)
{
uint32_t run_program = 0;
diff --git a/src/target/riscv/riscv.c b/src/target/riscv/riscv.c
index 5a6fc00..8828694 100644
--- a/src/target/riscv/riscv.c
+++ b/src/target/riscv/riscv.c
@@ -2795,11 +2795,26 @@ COMMAND_HANDLER(riscv_dmi_write)
COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], value);
if (r->dmi_write) {
- return r->dmi_write(target, address, value);
- } else {
- LOG_ERROR("dmi_write is not implemented for this target.");
- return ERROR_FAIL;
+ /* Perform the DMI write */
+ int retval = r->dmi_write(target, address, value);
+
+ /* Invalidate our cached progbuf copy:
+ - if the user tinkered directly with a progbuf register
+ - if debug module was reset, in which case progbuf registers
+ may not retain their value.
+ */
+ bool progbufTouched = (address >= DM_PROGBUF0 && address <= DM_PROGBUF15);
+ bool dmDeactivated = (address == DM_DMCONTROL && (value & DM_DMCONTROL_DMACTIVE) == 0);
+ if (progbufTouched || dmDeactivated) {
+ if (r->invalidate_cached_debug_buffer)
+ r->invalidate_cached_debug_buffer(target);
+ }
+
+ return retval;
}
+
+ LOG_ERROR("dmi_write is not implemented for this target.");
+ return ERROR_FAIL;
}
COMMAND_HANDLER(riscv_test_sba_config_reg)
diff --git a/src/target/riscv/riscv.h b/src/target/riscv/riscv.h
index 531c896..f1104e3 100644
--- a/src/target/riscv/riscv.h
+++ b/src/target/riscv/riscv.h
@@ -161,6 +161,7 @@ typedef struct {
riscv_insn_t d);
riscv_insn_t (*read_debug_buffer)(struct target *target, unsigned index);
int (*execute_debug_buffer)(struct target *target);
+ int (*invalidate_cached_debug_buffer)(struct target *target);
int (*dmi_write_u64_bits)(struct target *target);
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);