case ARMV8_64_EL3T:
instr = ARMV8_MSR_GP(SYSTEM_SCTLR_EL3, 0);
break;
+
+ case ARM_MODE_SVC:
+ case ARM_MODE_ABT:
+ case ARM_MODE_FIQ:
+ case ARM_MODE_IRQ:
+ instr = ARMV4_5_MCR(15, 0, 0, 1, 0, 0);
+ break;
+
default:
- LOG_DEBUG("unknown cpu state 0x%x" PRIx32, armv8->arm.core_state);
+ LOG_DEBUG("unknown cpu state 0x%" PRIx32, armv8->arm.core_mode);
break;
}
int retval;
uint32_t dummy;
- LOG_DEBUG(" ");
+ LOG_DEBUG("%s", target_name(target));
retval = mem_ap_write_atomic_u32(armv8->debug_ap,
armv8->debug_base + CPUV8_DBG_OSLAR, 0);
if (curr == target)
continue;
+ if (!target_was_examined(curr))
+ continue;
+
retval = aarch64_check_state_one(curr,
PRSR_SDR, PRSR_SDR, &resumed, &prsr);
if (retval != ERROR_OK || (!resumed && (prsr & PRSR_HALT))) {
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;
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)
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;
}
}
+ /*
+ * 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,
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;
int retval = ERROR_OK;
uint64_t debug, ttypr;
uint32_t cpuid;
- uint32_t tmp0, tmp1;
+ uint32_t tmp0, tmp1, tmp2, tmp3;
debug = ttypr = cpuid = 0;
retval = dap_dp_init(swjdp);
} else
armv8->debug_base = target->dbgbase;
- uint32_t prsr;
- int64_t then = timeval_ms();
- do {
- retval = mem_ap_read_atomic_u32(armv8->debug_ap,
- armv8->debug_base + CPUV8_DBG_PRSR, &prsr);
- if (retval == ERROR_OK) {
- retval = mem_ap_write_atomic_u32(armv8->debug_ap,
- armv8->debug_base + CPUV8_DBG_PRCR, PRCR_COREPURQ|PRCR_CORENPDRQ);
- if (retval != ERROR_OK) {
- LOG_DEBUG("write to PRCR failed");
- break;
- }
- }
-
- if (timeval_ms() > then + 1000) {
- retval = ERROR_TARGET_TIMEOUT;
- break;
- }
-
- } while ((prsr & PRSR_PU) == 0);
-
- if (retval != ERROR_OK) {
- LOG_ERROR("target %s: failed to set power state of the core.", target_name(target));
- return retval;
- }
-
retval = mem_ap_write_atomic_u32(armv8->debug_ap,
armv8->debug_base + CPUV8_DBG_OSLAR, 0);
if (retval != ERROR_OK) {
return retval;
}
- retval = mem_ap_read_atomic_u32(armv8->debug_ap,
+ retval = mem_ap_read_u32(armv8->debug_ap,
armv8->debug_base + CPUV8_DBG_MAINID0, &cpuid);
if (retval != ERROR_OK) {
LOG_DEBUG("Examine %s failed", "CPUID");
return retval;
}
- retval = mem_ap_read_atomic_u32(armv8->debug_ap,
+ retval = mem_ap_read_u32(armv8->debug_ap,
armv8->debug_base + CPUV8_DBG_MEMFEATURE0, &tmp0);
- retval += mem_ap_read_atomic_u32(armv8->debug_ap,
+ retval += mem_ap_read_u32(armv8->debug_ap,
armv8->debug_base + CPUV8_DBG_MEMFEATURE0 + 4, &tmp1);
if (retval != ERROR_OK) {
LOG_DEBUG("Examine %s failed", "Memory Model Type");
return retval;
}
- ttypr |= tmp1;
- ttypr = (ttypr << 32) | tmp0;
-
- retval = mem_ap_read_atomic_u32(armv8->debug_ap,
- armv8->debug_base + CPUV8_DBG_DBGFEATURE0, &tmp0);
- retval += mem_ap_read_atomic_u32(armv8->debug_ap,
- armv8->debug_base + CPUV8_DBG_DBGFEATURE0 + 4, &tmp1);
+ retval = mem_ap_read_u32(armv8->debug_ap,
+ armv8->debug_base + CPUV8_DBG_DBGFEATURE0, &tmp2);
+ retval += mem_ap_read_u32(armv8->debug_ap,
+ armv8->debug_base + CPUV8_DBG_DBGFEATURE0 + 4, &tmp3);
if (retval != ERROR_OK) {
LOG_DEBUG("Examine %s failed", "ID_AA64DFR0_EL1");
return retval;
}
- debug |= tmp1;
- debug = (debug << 32) | tmp0;
+
+ retval = dap_run(armv8->debug_ap->dap);
+ if (retval != ERROR_OK) {
+ LOG_ERROR("%s: examination failed\n", target_name(target));
+ return retval;
+ }
+
+ ttypr |= tmp1;
+ ttypr = (ttypr << 32) | tmp0;
+ debug |= tmp3;
+ debug = (debug << 32) | tmp2;
LOG_DEBUG("cpuid = 0x%08" PRIx32, cpuid);
LOG_DEBUG("ttypr = 0x%08" PRIx64, ttypr);
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;
}
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",
.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
};