return retval;
}
+static int aarch64_set_dscr_bits(struct target *target, unsigned long bit_mask, unsigned long value)
+{
+ struct armv8_common *armv8 = target_to_armv8(target);
+ uint32_t dscr;
+
+ /* Read DSCR */
+ int retval = mem_ap_read_atomic_u32(armv8->debug_ap,
+ armv8->debug_base + CPUV8_DBG_DSCR, &dscr);
+ if (ERROR_OK != retval)
+ return retval;
+
+ /* clear bitfield */
+ dscr &= ~bit_mask;
+ /* put new value */
+ dscr |= value & bit_mask;
+
+ /* write new DSCR */
+ retval = mem_ap_write_atomic_u32(armv8->debug_ap,
+ armv8->debug_base + CPUV8_DBG_DSCR, dscr);
+ return retval;
+}
+
static struct target *get_aarch64(struct target *target, int32_t coreid)
{
struct target_list *head;
struct armv8_common *armv8 = target_to_armv8(curr);
/* open the gate for channel 0 to let HALT requests pass to the CTM */
- if (curr->smp)
+ if (curr->smp) {
retval = mem_ap_write_atomic_u32(armv8->debug_ap,
armv8->cti_base + CTI_GATE, CTI_CHNL(0));
+ if (retval == ERROR_OK)
+ retval = aarch64_set_dscr_bits(curr, DSCR_HDE, DSCR_HDE);
+ }
if (retval != ERROR_OK)
break;
if (DSCR_RUN_MODE(dscr) == 0x3) {
if (prev_target_state != TARGET_HALTED) {
/* We have a halting debug event */
- LOG_DEBUG("Target halted");
+ LOG_DEBUG("Target %s halted", target_name(target));
target->state = TARGET_HALTED;
if ((prev_target_state == TARGET_RUNNING)
|| (prev_target_state == TARGET_UNKNOWN)
/*
* add HDE in halting debug mode
*/
- retval = mem_ap_read_atomic_u32(armv8->debug_ap,
- armv8->debug_base + CPUV8_DBG_DSCR, &dscr);
- if (retval == ERROR_OK)
- retval = mem_ap_write_atomic_u32(armv8->debug_ap,
- armv8->debug_base + CPUV8_DBG_DSCR, dscr | DSCR_HDE);
+ retval = aarch64_set_dscr_bits(target, DSCR_HDE, DSCR_HDE);
if (retval != ERROR_OK)
return retval;
LOG_ERROR("How do I resume into Jazelle state??");
return ERROR_FAIL;
}
- LOG_DEBUG("resume pc = 0x%16" PRIx64, resume_pc);
+ LOG_DEBUG("resume pc = 0x%016" PRIx64, resume_pc);
buf_set_u64(arm->pc->value, 0, 64, resume_pc);
arm->pc->dirty = 1;
arm->pc->valid = 1;
- dpmv8_modeswitch(&armv8->dpm, ARM_MODE_ANY);
/* called it now before restoring context because it uses cpu
* register r0 for restoring system control register */
retval = aarch64_restore_system_control_reg(target);
- if (retval != ERROR_OK)
- return retval;
- retval = aarch64_restore_context(target, handle_breakpoints);
- if (retval != ERROR_OK)
- return retval;
- target->debug_reason = DBG_REASON_NOTHALTED;
- target->state = TARGET_RUNNING;
-
- /* registers are now invalid */
- register_cache_invalidate(arm->core_cache);
+ if (retval == ERROR_OK)
+ retval = aarch64_restore_context(target, handle_breakpoints);
return retval;
}
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,
/* registers are now invalid */
register_cache_invalidate(arm->core_cache);
+ register_cache_invalidate(arm->core_cache->next);
return ERROR_OK;
}
int retval = ERROR_OK;
struct aarch64_common *aarch64 = target_to_aarch64(target);
struct armv8_common *armv8 = target_to_armv8(target);
+ struct arm_dpm *dpm = &armv8->dpm;
+ enum arm_state core_state;
- LOG_DEBUG("dscr = 0x%08" PRIx32, aarch64->cpudbg_dscr);
+ LOG_DEBUG("%s dscr = 0x%08" PRIx32, target_name(target), aarch64->cpudbg_dscr);
- /* REVISIT see A8 TRM 12.11.4 steps 2..3 -- make sure that any
- * imprecise data aborts get discarded by issuing a Data
- * Synchronization Barrier: ARMV4_5_MCR(15, 0, 0, 7, 10, 4).
- */
+ dpm->dscr = aarch64->cpudbg_dscr;
+ core_state = armv8_dpm_get_core_state(dpm);
+ armv8_select_opcodes(armv8, core_state == ARM_STATE_AARCH64);
+ armv8_select_reg_access(armv8, core_state == ARM_STATE_AARCH64);
/* make sure to clear all sticky errors */
retval = mem_ap_write_atomic_u32(armv8->debug_ap,
armv8->debug_base + CPUV8_DBG_DRCR, DRCR_CSE);
+
+ /* discard async exceptions */
+ if (retval == ERROR_OK)
+ retval = dpm->instr_cpsr_sync(dpm);
+
if (retval != ERROR_OK)
return retval;
/* Examine debug reason */
- armv8_dpm_report_dscr(&armv8->dpm, aarch64->cpudbg_dscr);
+ armv8_dpm_report_dscr(dpm, aarch64->cpudbg_dscr);
/* save address of instruction that triggered the watchpoint? */
if (target->debug_reason == DBG_REASON_WATCHPOINT) {
retval = armv8_dpm_read_current_registers(&armv8->dpm);
- if (armv8->post_debug_entry) {
+ if (retval == ERROR_OK && armv8->post_debug_entry)
retval = armv8->post_debug_entry(target);
- if (retval != ERROR_OK)
- return retval;
- }
return retval;
}
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:
- dpmv8_modeswitch(&armv8->dpm, ARMV8_64_EL1T);
+ armv8_dpm_modeswitch(&armv8->dpm, ARMV8_64_EL1H);
/* fall through */
case ARMV8_64_EL1T:
case ARMV8_64_EL1H:
break;
}
- dpmv8_modeswitch(&armv8->dpm, ARM_MODE_ANY);
+ armv8_dpm_modeswitch(&armv8->dpm, ARM_MODE_ANY);
LOG_DEBUG("System_register: %8.8" PRIx32, aarch64->system_control_reg);
aarch64->system_control_reg_curr = aarch64->system_control_reg;
return ERROR_OK;
}
-static int aarch64_set_dscr_bits(struct target *target, unsigned long bit_mask, unsigned long value)
-{
- struct armv8_common *armv8 = target_to_armv8(target);
- uint32_t dscr;
-
- /* Read DSCR */
- int retval = mem_ap_read_atomic_u32(armv8->debug_ap,
- armv8->debug_base + CPUV8_DBG_DSCR, &dscr);
- if (ERROR_OK != retval)
- return retval;
-
- /* clear bitfield */
- dscr &= ~bit_mask;
- /* put new value */
- dscr |= value & bit_mask;
-
- /* write new DSCR */
- retval = mem_ap_write_atomic_u32(armv8->debug_ap,
- armv8->debug_base + CPUV8_DBG_DSCR, dscr);
- return retval;
-}
-
static int aarch64_step(struct target *target, int current, target_addr_t address,
int handle_breakpoints)
{
{
struct armv8_common *armv8 = target_to_armv8(target);
- LOG_DEBUG(" ");
+ LOG_DEBUG("%s", target_name(target));
if (armv8->pre_restore_context)
armv8->pre_restore_context(target);
return armv8_dpm_write_dirty_registers(&armv8->dpm, bpwp);
-
}
/*
uint32_t dscr;
uint8_t *tmp_buff = NULL;
- LOG_DEBUG("Writing APB-AP memory address 0x%" PRIx64 " size %" PRIu32 " count%" PRIu32,
+ LOG_DEBUG("Writing APB-AP memory address 0x%" PRIx64 " size %" PRIu32 " count %" PRIu32,
address, size, count);
+
if (target->state != TARGET_HALTED) {
LOG_WARNING("target not halted");
return ERROR_TARGET_NOT_HALTED;
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
/* Step 1.a+b - Write the address for read access into DBGDTRRX */
/* Step 1.c - Copy value from DTR to R0 using instruction mrc DBGDTRTXint, r0 */
dpm->instr_write_data_dcc(dpm,
- T32_FMTITR(ARMV4_5_MRC(14, 0, 0, 0, 5, 0)), address & ~0x3ULL);
+ ARMV4_5_MRC(14, 0, 0, 0, 5, 0), address & ~0x3ULL);
}
/* Step 1.d - Change DCC to memory mode */
armv8->debug_base + CPUV8_DBG_DSCR, &dscr);
if (retval != ERROR_OK)
goto error_free_buff_w;
+
+ dpm->dscr = dscr;
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;
}
uint8_t *u8buf_ptr;
uint32_t value;
- LOG_DEBUG("Reading APB-AP memory address 0x%" TARGET_PRIxADDR " size %" PRIu32 " count%" PRIu32,
+ LOG_DEBUG("Reading APB-AP memory address 0x%" TARGET_PRIxADDR " size %" PRIu32 " count %" PRIu32,
address, size, count);
+
if (target->state != TARGET_HALTED) {
LOG_WARNING("target not halted");
return ERROR_TARGET_NOT_HALTED;
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);
/* Step 1.a+b - Write the address for read access into DBGDTRRXint */
/* Step 1.c - Copy value from DTR to R0 using instruction mrc DBGDTRTXint, r0 */
retval += dpm->instr_write_data_dcc(dpm,
- T32_FMTITR(ARMV4_5_MRC(14, 0, 0, 0, 5, 0)), address & ~0x3ULL);
+ ARMV4_5_MRC(14, 0, 0, 0, 5, 0), address & ~0x3ULL);
/* Step 1.d - Dummy operation to ensure EDSCR.Txfull == 1 */
- retval += dpm->instr_execute(dpm, T32_FMTITR(ARMV4_5_MCR(14, 0, 0, 0, 5, 0)));
+ retval += dpm->instr_execute(dpm, ARMV4_5_MCR(14, 0, 0, 0, 5, 0));
/* Step 1.e - Change DCC to memory mode */
dscr = dscr | DSCR_MA;
retval += mem_ap_write_atomic_u32(armv8->debug_ap,
armv8->debug_base + CPUV8_DBG_DSCR, &dscr);
if (retval != ERROR_OK)
goto error_free_buff_r;
+
+ dpm->dscr = dscr;
+
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;
}
COMMAND_REGISTRATION_DONE
};
static const struct command_registration aarch64_command_handlers[] = {
- {
- .chain = arm_command_handlers,
- },
{
.chain = armv8_command_handlers,
},