fix progbuf cache: invalidate it when needed

This commit relates to progbuf cache,
implemented in https://github.com/riscv/riscv-openocd/pull/381

Make sure the cache gets invalidated when the progbuf
contents change via other means. I've identified two
such cases where the invalidation is required:

1) When the user manually tinkers with the progbuf registers
   (TCL command "riscv dmi_write")

2) When program buffer is used as a scratch memory
   (scratch_write64())

Change-Id: Ie7ffb0fccda63297de894ab919d09082ea21cfae
Signed-off-by: Jan Matyas <matyas@codasip.com>
This commit is contained in:
Jan Matyas 2022-02-11 08:16:10 +01:00
parent bdce7319b7
commit feb83b78b7
3 changed files with 30 additions and 4 deletions

View File

@ -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:
{
@ -2278,6 +2280,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;
@ -4337,6 +4340,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;

View File

@ -2795,11 +2795,21 @@ 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);
/* If the user tinkered with progbuf registers, we need to
drop our cached copy of the progbuf */
if (address >= DM_PROGBUF0 && address <= DM_PROGBUF15) {
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)

View File

@ -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);