static int arm11_dpm_instr_read_data_r0(struct arm_dpm *dpm, uint32_t opcode, uint32_t *data) { return arm11_run_instr_data_from_core_via_r0(dpm_to_arm11(dpm), opcode, data); }
/** * Save processor state. This is called after a HALT instruction * succeeds, and on other occasions the processor enters debug mode * (breakpoint, watchpoint, etc). Caller has updated arm11->dscr. */ static int arm11_debug_entry(struct arm11_common *arm11) { int retval; arm11->arm.target->state = TARGET_HALTED; arm_dpm_report_dscr(arm11->arm.dpm, arm11->dscr); /* REVISIT entire cache should already be invalid !!! */ register_cache_invalidate(arm11->arm.core_cache); /* See e.g. ARM1136 TRM, "14.8.4 Entering Debug state" */ /* maybe save wDTR (pending DCC write to debug SW, e.g. libdcc) */ arm11->is_wdtr_saved = !!(arm11->dscr & DSCR_DTR_TX_FULL); if (arm11->is_wdtr_saved) { arm11_add_debug_SCAN_N(arm11, 0x05, ARM11_TAP_DEFAULT); arm11_add_IR(arm11, ARM11_INTEST, ARM11_TAP_DEFAULT); struct scan_field chain5_fields[3]; arm11_setup_field(arm11, 32, NULL, &arm11->saved_wdtr, chain5_fields + 0); arm11_setup_field(arm11, 1, NULL, NULL, chain5_fields + 1); arm11_setup_field(arm11, 1, NULL, NULL, chain5_fields + 2); arm11_add_dr_scan_vc(arm11->arm.target->tap, ARRAY_SIZE(chain5_fields), chain5_fields, TAP_DRPAUSE); } /* DSCR: set the Execute ARM instruction enable bit. * * ARM1176 spec says this is needed only for wDTR/rDTR's "ITR mode", * but not to issue ITRs(?). The ARMv7 arch spec says it's required * for executing instructions via ITR. */ CHECK_RETVAL(arm11_write_DSCR(arm11, DSCR_ITR_EN | arm11->dscr)); /* From the spec: Before executing any instruction in debug state you have to drain the write buffer. This ensures that no imprecise Data Aborts can return at a later point:*/ /** \todo TODO: Test drain write buffer. */ #if 0 while (1) { /* MRC p14,0,R0,c5,c10,0 */ // arm11_run_instr_no_data1(arm11, /*0xee150e1a*/0xe320f000); /* mcr 15, 0, r0, cr7, cr10, {4} */ arm11_run_instr_no_data1(arm11, 0xee070f9a); uint32_t dscr = arm11_read_DSCR(arm11); LOG_DEBUG("DRAIN, DSCR %08x", dscr); if (dscr & ARM11_DSCR_STICKY_IMPRECISE_DATA_ABORT) { arm11_run_instr_no_data1(arm11, 0xe320f000); dscr = arm11_read_DSCR(arm11); LOG_DEBUG("DRAIN, DSCR %08x (DONE)", dscr); break; } } #endif /* Save registers. * * NOTE: ARM1136 TRM suggests saving just R0 here now, then * CPSR and PC after the rDTR stuff. We do it all at once. */ retval = arm_dpm_read_current_registers(&arm11->dpm); if (retval != ERROR_OK) LOG_ERROR("DPM REG READ -- fail"); retval = arm11_run_instr_data_prepare(arm11); if (retval != ERROR_OK) return retval; /* maybe save rDTR (pending DCC read from debug SW, e.g. libdcc) */ arm11->is_rdtr_saved = !!(arm11->dscr & DSCR_DTR_RX_FULL); if (arm11->is_rdtr_saved) { /* MRC p14,0,R0,c0,c5,0 (move rDTR -> r0 (-> wDTR -> local var)) */ retval = arm11_run_instr_data_from_core_via_r0(arm11, 0xEE100E15, &arm11->saved_rdtr); if (retval != ERROR_OK) return retval; } /* REVISIT Now that we've saved core state, there's may also * be MMU and cache state to care about ... */ if (arm11->simulate_reset_on_next_halt) { arm11->simulate_reset_on_next_halt = false; LOG_DEBUG("Reset c1 Control Register"); /* Write 0 (reset value) to Control register 0 to disable MMU/Cache etc. */ /* MCR p15,0,R0,c1,c0,0 */ retval = arm11_run_instr_data_to_core_via_r0(arm11, 0xee010f10, 0); if (retval != ERROR_OK) return retval; } if (arm11->arm.target->debug_reason == DBG_REASON_WATCHPOINT) { uint32_t wfar; /* MRC p15, 0, <Rd>, c6, c0, 1 ; Read WFAR */ retval = arm11_run_instr_data_from_core_via_r0(arm11, ARMV4_5_MRC(15, 0, 0, 6, 0, 1), &wfar); if (retval != ERROR_OK) return retval; arm_dpm_report_wfar(arm11->arm.dpm, wfar); } retval = arm11_run_instr_data_finish(arm11); if (retval != ERROR_OK) return retval; return ERROR_OK; }