aboutsummaryrefslogtreecommitdiff
path: root/src/target
diff options
context:
space:
mode:
authorMatthias Welwarsky <matthias.welwarsky@sysgo.com>2017-02-27 17:10:19 +0100
committerMatthias Welwarsky <matthias@welwarsky.de>2018-01-16 09:05:41 +0000
commitb3d29cb5441ee5d38e8f7b561a58f03eb269dbe4 (patch)
tree2b0d763407ddac3be85ff4b7596e315b1fcb3eb3 /src/target
parentf7836bbc75586666d639edd1cf39a871c434d980 (diff)
downloadriscv-openocd-b3d29cb5441ee5d38e8f7b561a58f03eb269dbe4.zip
riscv-openocd-b3d29cb5441ee5d38e8f7b561a58f03eb269dbe4.tar.gz
riscv-openocd-b3d29cb5441ee5d38e8f7b561a58f03eb269dbe4.tar.bz2
aarch64: add 'maskisr' command
Allow to configure ISR masking during single-step and add handling for stepping over WFI with ISR masked. Change-Id: I7918be7bcda6a1d9badac44fc36c59b52f662fef Signed-off-by: Matthias Welwarsky <matthias.welwarsky@sysgo.com> Reviewed-on: http://openocd.zylin.com/4023 Tested-by: jenkins Reviewed-by: Matthias Welwarsky <matthias@welwarsky.de>
Diffstat (limited to 'src/target')
-rw-r--r--src/target/aarch64.c60
-rw-r--r--src/target/aarch64.h7
2 files changed, 59 insertions, 8 deletions
diff --git a/src/target/aarch64.c b/src/target/aarch64.c
index b18a12a..f1ce914 100644
--- a/src/target/aarch64.c
+++ b/src/target/aarch64.c
@@ -1049,6 +1049,7 @@ static int aarch64_step(struct target *target, int current, target_addr_t addres
int handle_breakpoints)
{
struct armv8_common *armv8 = target_to_armv8(target);
+ struct aarch64_common *aarch64 = target_to_aarch64(target);
int saved_retval = ERROR_OK;
int retval;
uint32_t edecr;
@@ -1069,7 +1070,7 @@ static int aarch64_step(struct target *target, int current, target_addr_t addres
armv8->debug_base + CPUV8_DBG_EDECR, (edecr|0x4));
}
/* disable interrupts while stepping */
- if (retval == ERROR_OK)
+ if (retval == ERROR_OK && aarch64->isrmasking_mode == AARCH64_ISRMASK_ON)
retval = aarch64_set_dscr_bits(target, 0x3 << 22, 0x3 << 22);
/* bail out if stepping setup has failed */
if (retval != ERROR_OK)
@@ -1113,7 +1114,7 @@ static int aarch64_step(struct target *target, int current, target_addr_t addres
if (retval != ERROR_OK || stepped)
break;
- if (timeval_ms() > then + 1000) {
+ if (timeval_ms() > then + 100) {
LOG_ERROR("timeout waiting for target %s halt after step",
target_name(target));
retval = ERROR_TARGET_TIMEOUT;
@@ -1121,8 +1122,14 @@ static int aarch64_step(struct target *target, int current, target_addr_t addres
}
}
+ /*
+ * At least on one SoC (Renesas R8A7795) stepping over a WFI instruction
+ * causes a timeout. The core takes the step but doesn't complete it and so
+ * debug state is never entered. However, you can manually halt the core
+ * as an external debug even is also a WFI wakeup event.
+ */
if (retval == ERROR_TARGET_TIMEOUT)
- saved_retval = retval;
+ saved_retval = aarch64_halt_one(target, HALT_SYNC);
/* restore EDECR */
retval = mem_ap_write_atomic_u32(armv8->debug_ap,
@@ -1131,9 +1138,11 @@ static int aarch64_step(struct target *target, int current, target_addr_t addres
return retval;
/* restore interrupts */
- retval = aarch64_set_dscr_bits(target, 0x3 << 22, 0);
- if (retval != ERROR_OK)
- return ERROR_OK;
+ if (aarch64->isrmasking_mode == AARCH64_ISRMASK_ON) {
+ retval = aarch64_set_dscr_bits(target, 0x3 << 22, 0);
+ if (retval != ERROR_OK)
+ return ERROR_OK;
+ }
if (saved_retval != ERROR_OK)
return saved_retval;
@@ -2303,9 +2312,9 @@ static int aarch64_examine_first(struct target *target)
LOG_DEBUG("Configured %i hw breakpoints", aarch64->brp_num);
- target->state = TARGET_RUNNING;
+ target->state = TARGET_UNKNOWN;
target->debug_reason = DBG_REASON_NOTHALTED;
-
+ aarch64->isrmasking_mode = AARCH64_ISRMASK_ON;
target_set_examined(target);
return ERROR_OK;
}
@@ -2443,6 +2452,34 @@ COMMAND_HANDLER(aarch64_handle_smp_on_command)
return ERROR_OK;
}
+COMMAND_HANDLER(aarch64_mask_interrupts_command)
+{
+ struct target *target = get_current_target(CMD_CTX);
+ struct aarch64_common *aarch64 = target_to_aarch64(target);
+
+ static const Jim_Nvp nvp_maskisr_modes[] = {
+ { .name = "off", .value = AARCH64_ISRMASK_OFF },
+ { .name = "on", .value = AARCH64_ISRMASK_ON },
+ { .name = NULL, .value = -1 },
+ };
+ const Jim_Nvp *n;
+
+ if (CMD_ARGC > 0) {
+ n = Jim_Nvp_name2value_simple(nvp_maskisr_modes, CMD_ARGV[0]);
+ if (n->name == NULL) {
+ LOG_ERROR("Unknown parameter: %s - should be off or on", CMD_ARGV[0]);
+ return ERROR_COMMAND_SYNTAX_ERROR;
+ }
+
+ aarch64->isrmasking_mode = n->value;
+ }
+
+ n = Jim_Nvp_value2name_simple(nvp_maskisr_modes, aarch64->isrmasking_mode);
+ command_print(CMD_CTX, "aarch64 interrupt mask %s", n->name);
+
+ return ERROR_OK;
+}
+
static const struct command_registration aarch64_exec_command_handlers[] = {
{
.name = "cache_info",
@@ -2471,6 +2508,13 @@ static const struct command_registration aarch64_exec_command_handlers[] = {
.help = "Restart smp handling",
.usage = "",
},
+ {
+ .name = "maskisr",
+ .handler = aarch64_mask_interrupts_command,
+ .mode = COMMAND_ANY,
+ .help = "mask aarch64 interrupts during single-step",
+ .usage = "['on'|'off']",
+ },
COMMAND_REGISTRATION_DONE
};
diff --git a/src/target/aarch64.h b/src/target/aarch64.h
index c9ec02d..d7886a3 100644
--- a/src/target/aarch64.h
+++ b/src/target/aarch64.h
@@ -36,6 +36,11 @@
#define AARCH64_PADDRDBG_CPU_SHIFT 13
+enum aarch64_isrmasking_mode {
+ AARCH64_ISRMASK_OFF,
+ AARCH64_ISRMASK_ON,
+};
+
struct aarch64_brp {
int used;
int type;
@@ -58,6 +63,8 @@ struct aarch64_common {
struct aarch64_brp *brp_list;
struct armv8_common armv8_common;
+
+ enum aarch64_isrmasking_mode isrmasking_mode;
};
static inline struct aarch64_common *