+ retvalue = mem_ap_read_atomic_u32(swjdp,
+ OMAP3530_DEBUG_BASE + CPUDBG_DSCR, &dscr);
+ }
+ while ((dscr & (1 << 24)) == 0); /* Wait for InstrCompl bit to be set */
+
+ mem_ap_write_u32(swjdp, OMAP3530_DEBUG_BASE + CPUDBG_ITR, opcode);
+
+ do
+ {
+ retvalue = mem_ap_read_atomic_u32(swjdp,
+ OMAP3530_DEBUG_BASE + CPUDBG_DSCR, &dscr);
+ }
+ while ((dscr & (1 << 24)) == 0); /* Wait for InstrCompl bit to be set */
+
+ return retvalue;
+}
+
+/**************************************************************************
+Read core register with very few exec_opcode, fast but needs work_area.
+This can cause problems with MMU active.
+**************************************************************************/
+int cortex_a8_read_regs_through_mem(target_t *target, uint32_t address,
+ uint32_t * regfile)
+{
+ int retval = ERROR_OK;
+ /* get pointers to arch-specific information */
+ armv4_5_common_t *armv4_5 = target->arch_info;
+ armv7a_common_t *armv7a = armv4_5->arch_info;
+ swjdp_common_t *swjdp = &armv7a->swjdp_info;
+
+ cortex_a8_dap_read_coreregister_u32(target, regfile, 0);
+ cortex_a8_dap_write_coreregister_u32(target, address, 0);
+ cortex_a8_exec_opcode(target, ARMV4_5_STMIA(0, 0xFFFE, 0, 0));
+ dap_ap_select(swjdp, swjdp_memoryap);
+ mem_ap_read_buf_u32(swjdp, (uint8_t *)(®file[1]), 4*15, address);
+ dap_ap_select(swjdp, swjdp_debugap);
+
+ return retval;
+}
+
+int cortex_a8_read_cp(target_t *target, uint32_t *value, uint8_t CP,
+ uint8_t op1, uint8_t CRn, uint8_t CRm, uint8_t op2)
+{
+ int retval;
+ /* get pointers to arch-specific information */
+ armv4_5_common_t *armv4_5 = target->arch_info;
+ armv7a_common_t *armv7a = armv4_5->arch_info;
+ swjdp_common_t *swjdp = &armv7a->swjdp_info;
+
+ cortex_a8_exec_opcode(target, ARMV4_5_MRC(CP, op1, 0, CRn, CRm, op2));
+ /* Move R0 to DTRTX */
+ cortex_a8_exec_opcode(target, ARMV4_5_MCR(14, 0, 0, 0, 5, 0));
+
+ /* Read DCCTX */
+ retval = mem_ap_read_atomic_u32(swjdp,
+ OMAP3530_DEBUG_BASE + CPUDBG_DTRTX, value);
+
+ return retval;
+}
+
+int cortex_a8_write_cp(target_t *target, uint32_t value,
+ uint8_t CP, uint8_t op1, uint8_t CRn, uint8_t CRm, uint8_t op2)
+/* TODO Fix this */
+{
+ int retval;
+ /* get pointers to arch-specific information */
+ armv4_5_common_t *armv4_5 = target->arch_info;
+ armv7a_common_t *armv7a = armv4_5->arch_info;
+ swjdp_common_t *swjdp = &armv7a->swjdp_info;
+
+ retval = mem_ap_write_u32(swjdp,
+ OMAP3530_DEBUG_BASE + CPUDBG_DTRRX, value);
+ /* Move DTRRX to r0 */
+ cortex_a8_exec_opcode(target, ARMV4_5_MRC(14, 0, 0, 0, 5, 0));
+
+ cortex_a8_exec_opcode(target, ARMV4_5_MCR(CP, 0, 0, 0, 5, 0));
+ return retval;
+}
+
+int cortex_a8_read_cp15(target_t *target, uint32_t op1, uint32_t op2,
+ uint32_t CRn, uint32_t CRm, uint32_t *value)
+{
+ return cortex_a8_read_cp(target, value, 15, op1, CRn, CRm, op2);
+}
+
+int cortex_a8_write_cp15(target_t *target, uint32_t op1, uint32_t op2,
+ uint32_t CRn, uint32_t CRm, uint32_t value)
+{
+ return cortex_a8_write_cp(target, value, 15, op1, CRn, CRm, op2);
+}
+
+int cortex_a8_dap_read_coreregister_u32(target_t *target,
+ uint32_t *value, int regnum)
+{
+ int retval = ERROR_OK;
+ uint8_t reg = regnum&0xFF;
+ uint32_t dscr;
+
+ /* get pointers to arch-specific information */
+ armv4_5_common_t *armv4_5 = target->arch_info;
+ armv7a_common_t *armv7a = armv4_5->arch_info;
+ swjdp_common_t *swjdp = &armv7a->swjdp_info;
+
+ if (reg > 16)
+ return retval;
+
+ if (reg < 15)
+ {
+ /* Rn to DCCTX, MCR p14, 0, Rd, c0, c5, 0, 0xEE000E15 */
+ cortex_a8_exec_opcode(target, ARMV4_5_MCR(14, 0, reg, 0, 5, 0));
+ }
+ else if (reg == 15)
+ {
+ cortex_a8_exec_opcode(target, 0xE1A0000F);
+ cortex_a8_exec_opcode(target, ARMV4_5_MCR(14, 0, 0, 0, 5, 0));
+ }
+ else if (reg == 16)
+ {
+ cortex_a8_exec_opcode(target, ARMV4_5_MRS(0, 0));
+ cortex_a8_exec_opcode(target, ARMV4_5_MCR(14, 0, 0, 0, 5, 0));
+ }
+
+ /* Read DTRRTX */
+ do
+ {
+ retval = mem_ap_read_atomic_u32(swjdp,
+ OMAP3530_DEBUG_BASE + CPUDBG_DSCR, &dscr);
+ }
+ while ((dscr & (1 << 29)) == 0); /* Wait for DTRRXfull */
+
+ retval = mem_ap_read_atomic_u32(swjdp,
+ OMAP3530_DEBUG_BASE + CPUDBG_DTRTX, value);
+
+ return retval;
+}
+
+int cortex_a8_dap_write_coreregister_u32(target_t *target, uint32_t value, int regnum)
+{
+ int retval = ERROR_OK;
+ uint8_t Rd = regnum&0xFF;
+
+ /* get pointers to arch-specific information */
+ armv4_5_common_t *armv4_5 = target->arch_info;
+ armv7a_common_t *armv7a = armv4_5->arch_info;
+ swjdp_common_t *swjdp = &armv7a->swjdp_info;
+
+ if (Rd > 16)
+ return retval;
+
+ /* Write to DCCRX */
+ retval = mem_ap_write_u32(swjdp,
+ OMAP3530_DEBUG_BASE + CPUDBG_DTRRX, value);
+
+ if (Rd < 15)
+ {
+ /* DCCRX to Rd, MCR p14, 0, Rd, c0, c5, 0, 0xEE000E15 */
+ cortex_a8_exec_opcode(target, ARMV4_5_MRC(14, 0, Rd, 0, 5, 0));
+ }
+ else if (Rd == 15)
+ {
+ cortex_a8_exec_opcode(target, ARMV4_5_MRC(14, 0, 0, 0, 5, 0));
+ cortex_a8_exec_opcode(target, 0xE1A0F000);
+ }
+ else if (Rd == 16)
+ {
+ cortex_a8_exec_opcode(target, ARMV4_5_MRC(14, 0, 0, 0, 5, 0));
+ cortex_a8_exec_opcode(target, ARMV4_5_MSR_GP(0, 0xF, 0));
+ /* Execute a PrefetchFlush instruction through the ITR. */
+ cortex_a8_exec_opcode(target, ARMV4_5_MCR(15, 0, 0, 7, 5, 4));
+ }
+
+ return retval;
+}
+
+/*
+ * Cortex-A8 Run control
+ */
+
+int cortex_a8_poll(target_t *target)
+{
+ int retval = ERROR_OK;
+ uint32_t dscr;
+ /* get pointers to arch-specific information */
+ armv4_5_common_t *armv4_5 = target->arch_info;
+ armv7a_common_t *armv7a = armv4_5->arch_info;
+ cortex_a8_common_t *cortex_a8 = armv7a->arch_info;
+ swjdp_common_t *swjdp = &armv7a->swjdp_info;
+
+
+ enum target_state prev_target_state = target->state;
+
+ uint8_t saved_apsel = dap_ap_get_select(swjdp);
+ dap_ap_select(swjdp, swjdp_debugap);
+ retval = mem_ap_read_atomic_u32(swjdp,
+ OMAP3530_DEBUG_BASE + CPUDBG_DSCR, &dscr);
+ if (retval != ERROR_OK)
+ {
+ dap_ap_select(swjdp, saved_apsel);
+ return retval;
+ }
+ cortex_a8->cpudbg_dscr = dscr;
+
+ if ((dscr & 0x3) == 0x3)
+ {
+ 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_RESET))
+ {
+ retval = cortex_a8_debug_entry(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 = cortex_a8_debug_entry(target);
+ if (retval != ERROR_OK)
+ return retval;
+
+ target_call_event_callbacks(target,
+ TARGET_EVENT_DEBUG_HALTED);
+ }
+ }
+ }
+ else if ((dscr & 0x3) == 0x2)
+ {
+ target->state = TARGET_RUNNING;
+ }
+ else
+ {
+ LOG_DEBUG("Unknown target state dscr = 0x%08" PRIx32, dscr);
+ target->state = TARGET_UNKNOWN;
+ }
+
+ dap_ap_select(swjdp, saved_apsel);
+
+ return retval;
+}
+
+int cortex_a8_halt(target_t *target)
+{
+ int retval = ERROR_OK;
+ uint32_t dscr;
+
+ /* get pointers to arch-specific information */
+ armv4_5_common_t *armv4_5 = target->arch_info;
+ armv7a_common_t *armv7a = armv4_5->arch_info;
+ swjdp_common_t *swjdp = &armv7a->swjdp_info;
+
+ uint8_t saved_apsel = dap_ap_get_select(swjdp);
+ dap_ap_select(swjdp, swjdp_debugap);
+
+ /*
+ * Tell the core to be halted by writing DRCR with 0x1
+ * and then wait for the core to be halted.
+ */
+ retval = mem_ap_write_atomic_u32(swjdp,
+ OMAP3530_DEBUG_BASE + CPUDBG_DRCR, 0x1);
+
+ if (retval != ERROR_OK)
+ goto out;
+
+ do {
+ mem_ap_read_atomic_u32(swjdp,
+ OMAP3530_DEBUG_BASE + CPUDBG_DSCR, &dscr);
+ } while ((dscr & (1 << 0)) == 0);
+
+ target->debug_reason = DBG_REASON_DBGRQ;
+
+out:
+ dap_ap_select(swjdp, saved_apsel);
+ return retval;
+}
+
+int cortex_a8_resume(struct target_s *target, int current,
+ uint32_t address, int handle_breakpoints, int debug_execution)
+{
+ /* get pointers to arch-specific information */
+ armv4_5_common_t *armv4_5 = target->arch_info;
+ armv7a_common_t *armv7a = armv4_5->arch_info;
+ cortex_a8_common_t *cortex_a8 = armv7a->arch_info;
+ swjdp_common_t *swjdp = &armv7a->swjdp_info;
+
+// breakpoint_t *breakpoint = NULL;
+ uint32_t resume_pc, dscr;
+
+ uint8_t saved_apsel = dap_ap_get_select(swjdp);
+ dap_ap_select(swjdp, swjdp_debugap);
+
+ if (!debug_execution)
+ {
+ target_free_all_working_areas(target);
+// cortex_m3_enable_breakpoints(target);
+// cortex_m3_enable_watchpoints(target);