Skip to content

Commit

Permalink
aarch64: Invalidate caches on reset
Browse files Browse the repository at this point in the history
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 <[email protected]>
Reviewed-on: https://review.openocd.org/c/openocd/+/8425
Reviewed-by: Antonio Borneo <[email protected]>
Tested-by: jenkins
  • Loading branch information
pcc authored and borneoa committed Sep 21, 2024
1 parent fd7b66c commit b14f63e
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 12 deletions.
49 changes: 37 additions & 12 deletions src/target/aarch64.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
*/
Expand All @@ -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;

Expand Down Expand Up @@ -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;

Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -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;
Expand Down
2 changes: 2 additions & 0 deletions src/target/armv8.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down

0 comments on commit b14f63e

Please sign in to comment.