- /* write R0 to DCC */
- retval = aarch64_exec_opcode(
- a8->armv8_common.arm.target,
- ARMV8_MSR_GP(SYSTEM_DBG_DBGDTR_EL0, 0), /* msr dbgdtr_el0, x0 */
- &dscr);
- if (retval != ERROR_OK)
- return retval;
-
- return aarch64_read_dcc_64(&a8->armv8_common, data, &dscr);
-}
-
-static int aarch64_bpwp_enable(struct arm_dpm *dpm, unsigned index_t,
- uint32_t addr, uint32_t control)
-{
- struct aarch64_common *a8 = dpm_to_a8(dpm);
- uint32_t vr = a8->armv8_common.debug_base;
- uint32_t cr = a8->armv8_common.debug_base;
- int retval;
-
- switch (index_t) {
- case 0 ... 15: /* breakpoints */
- vr += CPUV8_DBG_BVR_BASE;
- cr += CPUV8_DBG_BCR_BASE;
- break;
- case 16 ... 31: /* watchpoints */
- vr += CPUV8_DBG_WVR_BASE;
- cr += CPUV8_DBG_WCR_BASE;
- index_t -= 16;
- break;
- default:
- return ERROR_FAIL;
- }
- vr += 16 * index_t;
- cr += 16 * index_t;
-
- LOG_DEBUG("A8: bpwp enable, vr %08x cr %08x",
- (unsigned) vr, (unsigned) cr);
-
- retval = aarch64_dap_write_memap_register_u32(dpm->arm->target,
- vr, addr);
- if (retval != ERROR_OK)
- return retval;
- retval = aarch64_dap_write_memap_register_u32(dpm->arm->target,
- cr, control);
- return retval;
-}
-
-static int aarch64_bpwp_disable(struct arm_dpm *dpm, unsigned index_t)
-{
- struct aarch64_common *a = dpm_to_a8(dpm);
- uint32_t cr;
-
- switch (index_t) {
- case 0 ... 15:
- cr = a->armv8_common.debug_base + CPUV8_DBG_BCR_BASE;
- break;
- case 16 ... 31:
- cr = a->armv8_common.debug_base + CPUV8_DBG_WCR_BASE;
- index_t -= 16;
- break;
- default:
- return ERROR_FAIL;
- }
- cr += 16 * index_t;
-
- LOG_DEBUG("A: bpwp disable, cr %08x", (unsigned) cr);
-
- /* clear control register */
- return aarch64_dap_write_memap_register_u32(dpm->arm->target, cr, 0);
-
-}
-
-static int aarch64_dpm_setup(struct aarch64_common *a8, uint32_t debug)
-{
- struct arm_dpm *dpm = &a8->armv8_common.dpm;
- int retval;
-
- dpm->arm = &a8->armv8_common.arm;
- dpm->didr = debug;
-
- dpm->prepare = aarch64_dpm_prepare;
- dpm->finish = aarch64_dpm_finish;
-
- dpm->instr_execute = aarch64_instr_execute;
- dpm->instr_write_data_dcc = aarch64_instr_write_data_dcc;
- dpm->instr_write_data_dcc_64 = aarch64_instr_write_data_dcc_64;
- dpm->instr_write_data_r0 = aarch64_instr_write_data_r0;
- dpm->instr_write_data_r0_64 = aarch64_instr_write_data_r0_64;
- dpm->instr_cpsr_sync = aarch64_instr_cpsr_sync;
-
- dpm->instr_read_data_dcc = aarch64_instr_read_data_dcc;
- dpm->instr_read_data_dcc_64 = aarch64_instr_read_data_dcc_64;
- dpm->instr_read_data_r0 = aarch64_instr_read_data_r0;
- dpm->instr_read_data_r0_64 = aarch64_instr_read_data_r0_64;
-
- dpm->arm_reg_current = armv8_reg_current;
-
- dpm->bpwp_enable = aarch64_bpwp_enable;
- dpm->bpwp_disable = aarch64_bpwp_disable;
-
- retval = armv8_dpm_setup(dpm);
- if (retval == ERROR_OK)
- retval = armv8_dpm_initialize(dpm);
-
- return retval;
-}
-static struct target *get_aarch64(struct target *target, int32_t coreid)
-{
- struct target_list *head;
- struct target *curr;
-
- head = target->head;
- while (head != (struct target_list *)NULL) {
- curr = head->target;
- if ((curr->coreid == coreid) && (curr->state == TARGET_HALTED))
- return curr;
- head = head->next;
- }
- return target;
-}
-static int aarch64_halt(struct target *target);
-
-static int aarch64_halt_smp(struct target *target)
-{
- int retval = 0;
- struct target_list *head;
- struct target *curr;
- head = target->head;
- while (head != (struct target_list *)NULL) {
- curr = head->target;
- if ((curr != target) && (curr->state != TARGET_HALTED))
- retval += aarch64_halt(curr);
- head = head->next;
- }
- return retval;
-}
-
-static int update_halt_gdb(struct target *target)
-{
- int retval = 0;
- if (target->gdb_service && target->gdb_service->core[0] == -1) {
- target->gdb_service->target = target;
- target->gdb_service->core[0] = target->coreid;
- retval += aarch64_halt_smp(target);
- }
- return retval;
-}
-
-/*
- * Cortex-A8 Run control
- */
-
-static int aarch64_poll(struct target *target)
-{
- int retval = ERROR_OK;
- uint32_t dscr;
- struct aarch64_common *aarch64 = target_to_aarch64(target);
- struct armv8_common *armv8 = &aarch64->armv8_common;
- enum target_state prev_target_state = target->state;
- /* toggle to another core is done by gdb as follow */
- /* maint packet J core_id */
- /* continue */
- /* the next polling trigger an halt event sent to gdb */
- if ((target->state == TARGET_HALTED) && (target->smp) &&
- (target->gdb_service) &&
- (target->gdb_service->target == NULL)) {
- target->gdb_service->target =
- get_aarch64(target, target->gdb_service->core[1]);
- target_call_event_callbacks(target, TARGET_EVENT_HALTED);
- return retval;
- }
- retval = mem_ap_read_atomic_u32(armv8->debug_ap,
- armv8->debug_base + CPUV8_DBG_DSCR, &dscr);
- if (retval != ERROR_OK)
- return retval;
- aarch64->cpudbg_dscr = dscr;
-
- if (DSCR_RUN_MODE(dscr) == (DSCR_CORE_HALTED | DSCR_CORE_RESTARTED)) {
- if (prev_target_state != TARGET_HALTED) {
- /* We have a halting debug event */
- LOG_DEBUG("Target halted");
- target->state = TARGET_HALTED;
- if ((prev_target_state == TARGET_RUNNING)
- || (prev_target_state == TARGET_UNKNOWN)
- || (prev_target_state == TARGET_RESET)) {
- retval = aarch64_debug_entry(target);
- if (retval != ERROR_OK)
- return retval;
- if (target->smp) {
- retval = update_halt_gdb(target);
- if (retval != ERROR_OK)
- return retval;
- }
- target_call_event_callbacks(target,
- TARGET_EVENT_HALTED);
- }
- if (prev_target_state == TARGET_DEBUG_RUNNING) {
- LOG_DEBUG(" ");
-
- retval = aarch64_debug_entry(target);
- if (retval != ERROR_OK)
- return retval;
- if (target->smp) {
- retval = update_halt_gdb(target);
- if (retval != ERROR_OK)
- return retval;
- }
-
- target_call_event_callbacks(target,
- TARGET_EVENT_DEBUG_HALTED);
- }
- }
- } else if (DSCR_RUN_MODE(dscr) == DSCR_CORE_RESTARTED)
- target->state = TARGET_RUNNING;
- else {
- LOG_DEBUG("Unknown target state dscr = 0x%08" PRIx32, dscr);
- target->state = TARGET_UNKNOWN;
- }
-
- return retval;
-}
-
-static int aarch64_halt(struct target *target)
-{
- int retval = ERROR_OK;
- uint32_t dscr;
- struct armv8_common *armv8 = target_to_armv8(target);
-
- /* enable CTI*/
- retval = mem_ap_write_atomic_u32(armv8->debug_ap,
- armv8->cti_base + CTI_CTR, 1);
- if (retval != ERROR_OK)
- return retval;
-
- retval = mem_ap_write_atomic_u32(armv8->debug_ap,
- armv8->cti_base + CTI_GATE, 3);
- if (retval != ERROR_OK)
- return retval;
-
- retval = mem_ap_write_atomic_u32(armv8->debug_ap,
- armv8->cti_base + CTI_OUTEN0, 1);
- if (retval != ERROR_OK)
- return retval;
-
- retval = mem_ap_write_atomic_u32(armv8->debug_ap,
- armv8->cti_base + CTI_OUTEN1, 2);
- if (retval != ERROR_OK)
- return retval;
-
- /*
- * 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)
- return retval;
-
- retval = mem_ap_write_atomic_u32(armv8->debug_ap,
- armv8->debug_base + CPUV8_DBG_DSCR, dscr | DSCR_HDE);
- if (retval != ERROR_OK)
- return retval;
-
- retval = mem_ap_write_atomic_u32(armv8->debug_ap,
- armv8->cti_base + CTI_APPPULSE, 1);
- if (retval != ERROR_OK)
- return retval;
-
- retval = mem_ap_write_atomic_u32(armv8->debug_ap,
- armv8->cti_base + CTI_INACK, 1);
- if (retval != ERROR_OK)
- return retval;
-
-
- long long then = timeval_ms();
- for (;; ) {
- retval = mem_ap_read_atomic_u32(armv8->debug_ap,
- armv8->debug_base + CPUV8_DBG_DSCR, &dscr);
- if (retval != ERROR_OK)
- return retval;
- if ((dscr & DSCRV8_HALT_MASK) != 0)
- break;
- if (timeval_ms() > then + 1000) {
- LOG_ERROR("Timeout waiting for halt");
- return ERROR_FAIL;
- }
- }
-
- target->debug_reason = DBG_REASON_DBGRQ;
-
- return ERROR_OK;
-}
-
-static int aarch64_internal_restore(struct target *target, int current,