From f7dbcc3fab3d5b52710f235ae3ead3135cf9c2e6 Mon Sep 17 00:00:00 2001 From: Matthias Welwarsky Date: Thu, 6 Oct 2016 16:37:25 +0200 Subject: [PATCH] aarch64: consolidate sticky error handling Move clearing of DSCR "Sticky Error" condition to the exception handling function. Clear once on entering debug state. Change-Id: Iec1d09d6f2d9cdd7e92953da5ea19f3e399ca12c Signed-off-by: Matthias Welwarsky --- src/target/aarch64.c | 25 +++---------------------- src/target/armv8_dpm.c | 13 ++++--------- 2 files changed, 7 insertions(+), 31 deletions(-) diff --git a/src/target/aarch64.c b/src/target/aarch64.c index 110f8dca0..b716122fa 100644 --- a/src/target/aarch64.c +++ b/src/target/aarch64.c @@ -538,7 +538,9 @@ static int aarch64_internal_restart(struct target *target, bool slave_pe) return retval; if ((dscr & DSCR_ITE) == 0) - LOG_ERROR("DSCR InstrCompl must be set before leaving debug!"); + LOG_ERROR("DSCR.ITE must be set before leaving debug!"); + if ((dscr & DSCR_ERR) != 0) + LOG_ERROR("DSCR.ERR must be cleared before leaving debug!"); /* make sure to acknowledge the halt event before resuming */ retval = mem_ap_write_atomic_u32(armv8->debug_ap, @@ -709,10 +711,6 @@ static int aarch64_post_debug_entry(struct target *target) struct armv8_common *armv8 = &aarch64->armv8_common; int retval; - /* clear sticky errors */ - mem_ap_write_atomic_u32(armv8->debug_ap, - armv8->debug_base + CPUV8_DBG_DRCR, DRCR_CSE); - switch (armv8->arm.core_mode) { case ARMV8_64_EL0T: armv8_dpm_modeswitch(&armv8->dpm, ARMV8_64_EL1H); @@ -1389,13 +1387,6 @@ static int aarch64_write_apb_ap_memory(struct target *target, reg = armv8_reg_current(arm, 0); reg->dirty = true; - /* clear any abort */ - retval = mem_ap_write_atomic_u32(armv8->debug_ap, - armv8->debug_base + CPUV8_DBG_DRCR, DRCR_CSE); - if (retval != ERROR_OK) - return retval; - - /* This algorithm comes from DDI0487A.g, chapter J9.1 */ /* The algorithm only copies 32 bit words, so the buffer @@ -1486,8 +1477,6 @@ static int aarch64_write_apb_ap_memory(struct target *target, if (dscr & (DSCR_ERR | DSCR_SYS_ERROR_PEND)) { /* Abort occurred - clear it and exit */ LOG_ERROR("abort occurred - dscr = 0x%08" PRIx32, dscr); - mem_ap_write_atomic_u32(armv8->debug_ap, - armv8->debug_base + CPUV8_DBG_DRCR, 1<<2); armv8_dpm_handle_exception(dpm); goto error_free_buff_w; } @@ -1547,12 +1536,6 @@ static int aarch64_read_apb_ap_memory(struct target *target, reg = armv8_reg_current(arm, 0); reg->dirty = true; - /* clear any abort */ - retval = mem_ap_write_atomic_u32(armv8->debug_ap, - armv8->debug_base + CPUV8_DBG_DRCR, DRCR_CSE); - if (retval != ERROR_OK) - goto error_free_buff_r; - /* Read DSCR */ retval = mem_ap_read_atomic_u32(armv8->debug_ap, armv8->debug_base + CPUV8_DBG_DSCR, &dscr); @@ -1652,8 +1635,6 @@ static int aarch64_read_apb_ap_memory(struct target *target, if (dscr & (DSCR_ERR | DSCR_SYS_ERROR_PEND)) { /* Abort occurred - clear it and exit */ LOG_ERROR("abort occurred - dscr = 0x%08" PRIx32, dscr); - mem_ap_write_atomic_u32(armv8->debug_ap, - armv8->debug_base + CPUV8_DBG_DRCR, DRCR_CSE); armv8_dpm_handle_exception(dpm); goto error_free_buff_r; } diff --git a/src/target/armv8_dpm.c b/src/target/armv8_dpm.c index 8caa8b60c..ef53452f1 100644 --- a/src/target/armv8_dpm.c +++ b/src/target/armv8_dpm.c @@ -202,12 +202,6 @@ static int dpmv8_dpm_prepare(struct arm_dpm *dpm) armv8->debug_base + CPUV8_DBG_DTRRX, &dscr); if (retval != ERROR_OK) return retval; - - /* Clear sticky error */ - retval = mem_ap_write_u32(armv8->debug_ap, - armv8->debug_base + CPUV8_DBG_DRCR, DRCR_CSE); - if (retval != ERROR_OK) - return retval; } return retval; @@ -276,9 +270,6 @@ static int dpmv8_exec_opcode(struct arm_dpm *dpm, if (dscr & DSCR_ERR) { LOG_ERROR("Opcode 0x%08"PRIx32", DSCR.ERR=1, DSCR.EL=%i", opcode, dpm->last_el); - /* clear the sticky error condition */ - mem_ap_write_atomic_u32(armv8->debug_ap, - armv8->debug_base + CPUV8_DBG_DRCR, DRCR_CSE); armv8_dpm_handle_exception(dpm); retval = ERROR_FAIL; } @@ -1353,6 +1344,10 @@ void armv8_dpm_handle_exception(struct arm_dpm *dpm) return; } + /* Clear sticky error */ + mem_ap_write_u32(armv8->debug_ap, + armv8->debug_base + CPUV8_DBG_DRCR, DRCR_CSE); + armv8->read_reg_u64(armv8, ARMV8_xPSR, &dlr); dspsr = dlr; armv8->read_reg_u64(armv8, ARMV8_PC, &dlr);