aboutsummaryrefslogtreecommitdiff
path: root/src/target/aarch64.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/target/aarch64.c')
-rw-r--r--src/target/aarch64.c91
1 files changed, 63 insertions, 28 deletions
diff --git a/src/target/aarch64.c b/src/target/aarch64.c
index 6a70b2d..ce7808e 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;
}
@@ -563,8 +589,8 @@ static int aarch64_halt(struct target *target)
return aarch64_halt_one(target, HALT_SYNC);
}
-static int aarch64_restore_one(struct target *target, int current,
- uint64_t *address, int handle_breakpoints, int debug_execution)
+static int aarch64_restore_one(struct target *target, bool current,
+ uint64_t *address, bool handle_breakpoints, bool debug_execution)
{
struct armv8_common *armv8 = target_to_armv8(target);
struct arm *arm = &armv8->arm;
@@ -576,7 +602,7 @@ static int aarch64_restore_one(struct target *target, int current,
if (!debug_execution)
target_free_all_working_areas(target);
- /* current = 1: continue on current pc, otherwise continue at <address> */
+ /* current = true: continue on current pc, otherwise continue at <address> */
resume_pc = buf_get_u64(arm->pc->value, 0, 64);
if (!current)
resume_pc = *address;
@@ -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;
@@ -728,7 +753,8 @@ static int aarch64_restart_one(struct target *target, enum restart_mode mode)
/*
* prepare all but the current target for restart
*/
-static int aarch64_prep_restart_smp(struct target *target, int handle_breakpoints, struct target **p_first)
+static int aarch64_prep_restart_smp(struct target *target,
+ bool handle_breakpoints, struct target **p_first)
{
int retval = ERROR_OK;
struct target_list *head;
@@ -747,7 +773,8 @@ static int aarch64_prep_restart_smp(struct target *target, int handle_breakpoint
continue;
/* resume at current address, not in step mode */
- retval = aarch64_restore_one(curr, 1, &address, handle_breakpoints, 0);
+ retval = aarch64_restore_one(curr, true, &address, handle_breakpoints,
+ false);
if (retval == ERROR_OK)
retval = aarch64_prepare_restart_one(curr);
if (retval != ERROR_OK) {
@@ -774,7 +801,7 @@ static int aarch64_step_restart_smp(struct target *target)
LOG_DEBUG("%s", target_name(target));
- retval = aarch64_prep_restart_smp(target, 0, &first);
+ retval = aarch64_prep_restart_smp(target, false, &first);
if (retval != ERROR_OK)
return retval;
@@ -839,8 +866,8 @@ static int aarch64_step_restart_smp(struct target *target)
return retval;
}
-static int aarch64_resume(struct target *target, int current,
- target_addr_t address, int handle_breakpoints, int debug_execution)
+static int aarch64_resume(struct target *target, bool current,
+ target_addr_t address, bool handle_breakpoints, bool debug_execution)
{
int retval = 0;
uint64_t addr = address;
@@ -1088,8 +1115,8 @@ static int aarch64_post_debug_entry(struct target *target)
/*
* single-step a target
*/
-static int aarch64_step(struct target *target, int current, target_addr_t address,
- int handle_breakpoints)
+static int aarch64_step(struct target *target, bool current, target_addr_t address,
+ bool handle_breakpoints)
{
struct armv8_common *armv8 = target_to_armv8(target);
struct aarch64_common *aarch64 = target_to_aarch64(target);
@@ -1122,7 +1149,7 @@ static int aarch64_step(struct target *target, int current, target_addr_t addres
if (retval != ERROR_OK)
return retval;
- if (target->smp && (current == 1)) {
+ if (target->smp && current) {
/*
* isolate current target so that it doesn't get resumed
* together with the others
@@ -1139,7 +1166,7 @@ static int aarch64_step(struct target *target, int current, target_addr_t addres
}
/* all other targets running, restore and restart the current target */
- retval = aarch64_restore_one(target, current, &address, 0, 0);
+ retval = aarch64_restore_one(target, current, &address, false, false);
if (retval == ERROR_OK)
retval = aarch64_restart_one(target, RESTART_LAZY);
@@ -2830,6 +2857,14 @@ static void aarch64_deinit_target(struct target *target)
struct aarch64_common *aarch64 = target_to_aarch64(target);
struct armv8_common *armv8 = &aarch64->armv8_common;
struct arm_dpm *dpm = &armv8->dpm;
+ uint64_t address;
+
+ if (target->state == TARGET_HALTED) {
+ // Restore the previous state of the target (gp registers, MMU, caches, etc)
+ int retval = aarch64_restore_one(target, true, &address, false, false);
+ if (retval != ERROR_OK)
+ LOG_TARGET_ERROR(target, "Failed to restore target state");
+ }
if (armv8->debug_ap)
dap_put_ap(armv8->debug_ap);
@@ -2883,9 +2918,9 @@ static int aarch64_jim_configure(struct target *target, struct jim_getopt_info *
pc = (struct aarch64_private_config *)target->private_config;
if (!pc) {
- pc = calloc(1, sizeof(struct aarch64_private_config));
- pc->adiv5_config.ap_num = DP_APSEL_INVALID;
- target->private_config = pc;
+ pc = calloc(1, sizeof(struct aarch64_private_config));
+ pc->adiv5_config.ap_num = DP_APSEL_INVALID;
+ target->private_config = pc;
}
/*
@@ -2915,7 +2950,7 @@ static int aarch64_jim_configure(struct target *target, struct jim_getopt_info *
switch (n->value) {
case CFG_CTI: {
- if (goi->isconfigure) {
+ if (goi->is_configure) {
Jim_Obj *o_cti;
struct arm_cti *cti;
e = jim_getopt_obj(goi, &o_cti);