From 8274cc58c1a1b44ac23fd542f136d9265c6c3252 Mon Sep 17 00:00:00 2001 From: Jan Matyas Date: Mon, 14 Feb 2022 14:10:17 +0100 Subject: [PATCH] fix progbuf cache: another two cases for invalidation Continuation of the previous patch. There are two more cases when progbuf cache in OpenOCD shall be invalidated: - When OpenOCD resets the debug module undergoes reset (dmactive=0), e.g. during target examination - When the user manually performs that very same operation (via riscv dmi_write) Change-Id: I53f8f08250eeedcbd55ab4361d5665370b063680 Signed-off-by: Jan Matyas --- src/target/riscv/riscv-013.c | 5 ++++- src/target/riscv/riscv.c | 11 ++++++++--- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/src/target/riscv/riscv-013.c b/src/target/riscv/riscv-013.c index 9ed2d2f53..62866dcfd 100644 --- a/src/target/riscv/riscv-013.c +++ b/src/target/riscv/riscv-013.c @@ -1568,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 | @@ -2371,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; } diff --git a/src/target/riscv/riscv.c b/src/target/riscv/riscv.c index 783d937f7..7be42ef5e 100644 --- a/src/target/riscv/riscv.c +++ b/src/target/riscv/riscv.c @@ -2798,9 +2798,14 @@ COMMAND_HANDLER(riscv_dmi_write) /* 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) { + /* 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); }