This is an automated email from Gerrit.

"Peter Collingbourne <p...@google.com>" just uploaded a new patch set to 
Gerrit, which you can find at https://review.openocd.org/c/openocd/+/8425

-- gerrit

commit ab23ab4e6d92d2f35fa357c035bce51d63bcc598
Author: Peter Collingbourne <p...@google.com>
Date:   Thu Aug 1 15:48:25 2024 -0700

    aarch64: Invalidate caches on reset
    
    When a target is reset we must invalidate register caches in order
    to avoid showing stale register values or writing them back to
    registers. Use EDPRSR.SR to detect a previous reset, and EDPRSR.R to
    detect a current reset state.
    
    Change-Id: Ia1e97d7154cf7789d392274eee475733086a835b
    Signed-off-by: Peter Collingbourne <p...@google.com>

diff --git a/src/target/aarch64.c b/src/target/aarch64.c
index 6a70b2ddf8..182ff44af0 100644
--- a/src/target/aarch64.c
+++ b/src/target/aarch64.c
@@ -193,6 +193,20 @@ static int aarch64_mmu_modify(struct target *target, int 
enable)
        return retval;
 }
 
+static int aarch64_read_prsr(struct target *target, uint32_t *prsr)
+{
+       struct armv8_common *armv8 = target_to_armv8(target);
+       int retval;
+
+       retval = mem_ap_read_atomic_u32(armv8->debug_ap,
+                       armv8->debug_base + CPUV8_DBG_PRSR, prsr);
+       if (retval != ERROR_OK)
+               return retval;
+
+       armv8->sticky_reset |= *prsr & PRSR_SR;
+       return ERROR_OK;
+}
+
 /*
  * Basic debug access, very low level assumes state is saved
  */
@@ -213,8 +227,7 @@ static int aarch64_init_debug_access(struct target *target)
 
        /* Clear Sticky Power Down status Bit in PRSR to enable access to
           the registers in the Core Power Domain */
-       retval = mem_ap_read_atomic_u32(armv8->debug_ap,
-                       armv8->debug_base + CPUV8_DBG_PRSR, &dummy);
+       retval = aarch64_read_prsr(target, &dummy);
        if (retval != ERROR_OK)
                return retval;
 
@@ -281,12 +294,10 @@ static int aarch64_set_dscr_bits(struct target *target, 
unsigned long bit_mask,
 static int aarch64_check_state_one(struct target *target,
                uint32_t mask, uint32_t val, int *p_result, uint32_t *p_prsr)
 {
-       struct armv8_common *armv8 = target_to_armv8(target);
        uint32_t prsr;
        int retval;
 
-       retval = mem_ap_read_atomic_u32(armv8->debug_ap,
-                       armv8->debug_base + CPUV8_DBG_PRSR, &prsr);
+       retval = aarch64_read_prsr(target, &prsr);
        if (retval != ERROR_OK)
                return retval;
 
@@ -506,16 +517,28 @@ static int update_halt_gdb(struct target *target, enum 
target_debug_reason debug
 
 static int aarch64_poll(struct target *target)
 {
+       struct armv8_common *armv8 = target_to_armv8(target);
        enum target_state prev_target_state;
        int retval = ERROR_OK;
-       int halted;
+       uint32_t prsr;
 
-       retval = aarch64_check_state_one(target,
-                               PRSR_HALT, PRSR_HALT, &halted, NULL);
+       retval = aarch64_read_prsr(target, &prsr);
        if (retval != ERROR_OK)
                return retval;
 
-       if (halted) {
+       if (armv8->sticky_reset) {
+               armv8->sticky_reset = false;
+               if (target->state != TARGET_RESET) {
+                       target->state = TARGET_RESET;
+                       LOG_TARGET_INFO(target, "external reset detected");
+                       if (armv8->arm.core_cache) {
+                               
register_cache_invalidate(armv8->arm.core_cache);
+                               
register_cache_invalidate(armv8->arm.core_cache->next);
+                       }
+               }
+       }
+
+       if (prsr & PRSR_HALT) {
                prev_target_state = target->state;
                if (prev_target_state != TARGET_HALTED) {
                        enum target_debug_reason debug_reason = 
target->debug_reason;
@@ -546,8 +569,11 @@ static int aarch64_poll(struct target *target)
                                break;
                        }
                }
-       } else
+       } else if (prsr & PRSR_RESET) {
+               target->state = TARGET_RESET;
+       } else {
                target->state = TARGET_RUNNING;
+       }
 
        return retval;
 }
@@ -663,8 +689,7 @@ static int aarch64_prepare_restart_one(struct target 
*target)
 
        if (retval == ERROR_OK) {
                /* clear sticky bits in PRSR, SDR is now 0 */
-               retval = mem_ap_read_atomic_u32(armv8->debug_ap,
-                               armv8->debug_base + CPUV8_DBG_PRSR, &tmp);
+               retval = aarch64_read_prsr(target, &tmp);
        }
 
        return retval;
diff --git a/src/target/armv8.h b/src/target/armv8.h
index f5aa211097..156b5f8bbd 100644
--- a/src/target/armv8.h
+++ b/src/target/armv8.h
@@ -213,6 +213,8 @@ struct armv8_common {
        /* True if OpenOCD provides pointer auth related info to GDB */
        bool enable_pauth;
 
+       bool sticky_reset;
+
        /* last run-control command issued to this target (resume, halt, step) 
*/
        enum run_control_op last_run_control_op;
 

-- 

Reply via email to