Merge pull request #678 from riscv/invalidate-progbuf-cache
fix progbuf cache: invalidate it when needed
This commit is contained in:
commit
435a652236
|
@ -52,6 +52,7 @@ static int riscv013_write_debug_buffer(struct target *target, unsigned index,
|
||||||
riscv_insn_t d);
|
riscv_insn_t d);
|
||||||
static riscv_insn_t riscv013_read_debug_buffer(struct target *target, unsigned
|
static riscv_insn_t riscv013_read_debug_buffer(struct target *target, unsigned
|
||||||
index);
|
index);
|
||||||
|
static int riscv013_invalidate_cached_debug_buffer(struct target *target);
|
||||||
static int riscv013_execute_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_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);
|
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:
|
case SPACE_DMI_PROGBUF:
|
||||||
dmi_write(target, DM_PROGBUF0 + scratch->debug_address, value);
|
dmi_write(target, DM_PROGBUF0 + scratch->debug_address, value);
|
||||||
dmi_write(target, DM_PROGBUF1 + scratch->debug_address, value >> 32);
|
dmi_write(target, DM_PROGBUF1 + scratch->debug_address, value >> 32);
|
||||||
|
riscv013_invalidate_cached_debug_buffer(target);
|
||||||
break;
|
break;
|
||||||
case SPACE_DMI_RAM:
|
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, 0);
|
||||||
dmi_write(target, DM_DMCONTROL, DM_DMCONTROL_DMACTIVE);
|
dmi_write(target, DM_DMCONTROL, DM_DMCONTROL_DMACTIVE);
|
||||||
dm->was_reset = true;
|
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 |
|
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->read_debug_buffer = &riscv013_read_debug_buffer;
|
||||||
generic_info->write_debug_buffer = &riscv013_write_debug_buffer;
|
generic_info->write_debug_buffer = &riscv013_write_debug_buffer;
|
||||||
generic_info->execute_debug_buffer = &riscv013_execute_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_write_u64 = &riscv013_fill_dmi_write_u64;
|
||||||
generic_info->fill_dmi_read_u64 = &riscv013_fill_dmi_read_u64;
|
generic_info->fill_dmi_read_u64 = &riscv013_fill_dmi_read_u64;
|
||||||
generic_info->fill_dmi_nop_u64 = &riscv013_fill_dmi_nop_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
|
/* 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
|
* involves SRST being toggled. So clear our cache which may be out of
|
||||||
* date. */
|
* date. */
|
||||||
memset(dm->progbuf_cache, 0, sizeof(dm->progbuf_cache));
|
riscv013_invalidate_cached_debug_buffer(target);
|
||||||
|
|
||||||
return ERROR_OK;
|
return ERROR_OK;
|
||||||
}
|
}
|
||||||
|
@ -4337,6 +4343,18 @@ riscv_insn_t riscv013_read_debug_buffer(struct target *target, unsigned index)
|
||||||
return value;
|
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)
|
int riscv013_execute_debug_buffer(struct target *target)
|
||||||
{
|
{
|
||||||
uint32_t run_program = 0;
|
uint32_t run_program = 0;
|
||||||
|
|
|
@ -2795,11 +2795,26 @@ COMMAND_HANDLER(riscv_dmi_write)
|
||||||
COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], value);
|
COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], value);
|
||||||
|
|
||||||
if (r->dmi_write) {
|
if (r->dmi_write) {
|
||||||
return r->dmi_write(target, address, value);
|
/* Perform the DMI write */
|
||||||
} else {
|
int retval = r->dmi_write(target, address, value);
|
||||||
LOG_ERROR("dmi_write is not implemented for this target.");
|
|
||||||
return ERROR_FAIL;
|
/* 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)
|
COMMAND_HANDLER(riscv_test_sba_config_reg)
|
||||||
|
|
|
@ -161,6 +161,7 @@ typedef struct {
|
||||||
riscv_insn_t d);
|
riscv_insn_t d);
|
||||||
riscv_insn_t (*read_debug_buffer)(struct target *target, unsigned index);
|
riscv_insn_t (*read_debug_buffer)(struct target *target, unsigned index);
|
||||||
int (*execute_debug_buffer)(struct target *target);
|
int (*execute_debug_buffer)(struct target *target);
|
||||||
|
int (*invalidate_cached_debug_buffer)(struct target *target);
|
||||||
int (*dmi_write_u64_bits)(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_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_read_u64)(struct target *target, char *buf, int a);
|
||||||
|
|
Loading…
Reference in New Issue