.deassert_reset = NULL,
.soft_reset_halt = NULL,
-// .get_gdb_reg_list = armv4_5_get_gdb_reg_list,
.get_gdb_reg_list = armv4_5_get_gdb_reg_list,
.read_memory = cortex_a8_read_memory,
swjdp_common_t *swjdp = &armv7a->swjdp_info;
LOG_DEBUG("exec opcode 0x%08" PRIx32, opcode);
+ do
+ {
+ retvalue = mem_ap_read_atomic_u32(swjdp,
+ OMAP3530_DEBUG_BASE + CPUDBG_DSCR, &dscr);
+ }
+ while ((dscr & (1 << DSCR_INSTR_COMP)) == 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 */
+ while ((dscr & (1 << DSCR_INSTR_COMP)) == 0); /* Wait for InstrCompl bit to be set */
return retvalue;
}
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 */
/* 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));
+ cortex_a8_exec_opcode(target, ARMV4_5_MCR(CP, op1, 0, CRn, CRm, op2));
return retval;
}
{
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;
- swjdp->trans_mode = TRANS_MODE_COMPOSITE;
-
if (reg > 16)
return retval;
cortex_a8_exec_opcode(target, ARMV4_5_MCR(14, 0, 0, 0, 5, 0));
}
- /* Read DCCTX */
+ /* Read DTRRTX */
+ do
+ {
+ retval = mem_ap_read_atomic_u32(swjdp,
+ OMAP3530_DEBUG_BASE + CPUDBG_DSCR, &dscr);
+ }
+ while ((dscr & (1 << DSCR_DTR_TX_FULL)) == 0); /* Wait for DTRRXfull */
+
retval = mem_ap_read_atomic_u32(swjdp,
OMAP3530_DEBUG_BASE + CPUDBG_DTRTX, value);
-// retval = mem_ap_read_u32(swjdp, OMAP3530_DEBUG_BASE + CPUDBG_DTRTX, value);
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;
uint8_t saved_apsel = dap_ap_get_select(swjdp);
dap_ap_select(swjdp, swjdp_debugap);
- /* Perhaps we should do a read-modify-write here */
+ /*
+ * 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);
+ /*
+ * enter halting debug mode
+ */
+ mem_ap_read_atomic_u32(swjdp, OMAP3530_DEBUG_BASE + CPUDBG_DSCR, &dscr);
+ retval = mem_ap_write_atomic_u32(swjdp,
+ OMAP3530_DEBUG_BASE + CPUDBG_DSCR, dscr | (1 << DSCR_HALT_DBG_MODE));
+
+ if (retval != ERROR_OK)
+ goto out;
+
+ do {
+ mem_ap_read_atomic_u32(swjdp,
+ OMAP3530_DEBUG_BASE + CPUDBG_DSCR, &dscr);
+ } while ((dscr & (1 << DSCR_CORE_HALTED)) == 0);
+
target->debug_reason = DBG_REASON_DBGRQ;
- dap_ap_select(swjdp, saved_apsel);
+out:
+ dap_ap_select(swjdp, saved_apsel);
return retval;
}
/* 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;
+ uint32_t resume_pc, dscr;
uint8_t saved_apsel = dap_ap_get_select(swjdp);
dap_ap_select(swjdp, swjdp_debugap);
/* Make sure that the Armv7 gdb thumb fixups does not
* kill the return address
*/
- if (!(cortex_a8->cpudbg_dscr & (1 << 5)))
+ if (armv7a->core_state == ARMV7A_STATE_ARM)
{
resume_pc &= 0xFFFFFFFC;
}
+ /* When the return address is loaded into PC
+ * bit 0 must be 1 to stay in Thumb state
+ */
+ if (armv7a->core_state == ARMV7A_STATE_THUMB)
+ {
+ resume_pc |= 0x1;
+ }
LOG_DEBUG("resume pc = 0x%08" PRIx32, resume_pc);
buf_set_u32(ARMV7A_CORE_REG_MODE(armv4_5->core_cache,
armv4_5->core_mode, 15).value,
}
#endif
- /* Restart core */
- /* Perhaps we should do a read-modify-write here */
+ /* Restart core and wait for it to be started */
mem_ap_write_atomic_u32(swjdp, OMAP3530_DEBUG_BASE + CPUDBG_DRCR, 0x2);
+ do {
+ mem_ap_read_atomic_u32(swjdp,
+ OMAP3530_DEBUG_BASE + CPUDBG_DSCR, &dscr);
+ } while ((dscr & (1 << DSCR_CORE_RESTARTED)) == 0);
+
target->debug_reason = DBG_REASON_NOTHALTED;
target->state = TARGET_RUNNING;
int cortex_a8_debug_entry(target_t *target)
{
int i;
- uint32_t regfile[16], pc, cpsr;
+ uint32_t regfile[16], pc, cpsr, dscr;
int retval = ERROR_OK;
working_area_t *regfile_working_area = NULL;
LOG_DEBUG("dscr = 0x%08" PRIx32, cortex_a8->cpudbg_dscr);
+ /* Enable the ITR execution once we are in debug mode */
+ mem_ap_read_atomic_u32(swjdp,
+ OMAP3530_DEBUG_BASE + CPUDBG_DSCR, &dscr);
+ dscr |= (1 << DSCR_EXT_INT_EN);
+ retval = mem_ap_write_atomic_u32(swjdp,
+ OMAP3530_DEBUG_BASE + CPUDBG_DSCR, dscr);
+
/* Examine debug reason */
switch ((cortex_a8->cpudbg_dscr >> 2)&0xF)
{
}
/* Examine target state and mode */
- dap_ap_select(swjdp, swjdp_memoryap);
if (cortex_a8->fast_reg_read)
target_alloc_working_area(target, 64, ®file_working_area);
}
else
{
+ dap_ap_select(swjdp, swjdp_memoryap);
cortex_a8_read_regs_through_mem(target,
regfile_working_area->address, regfile);
dap_ap_select(swjdp, swjdp_memoryap);
dap_ap_select(swjdp, swjdp_debugap);
LOG_DEBUG("cpsr: %8.8" PRIx32, cpsr);
- armv4_5->core_mode = cpsr & 0x3F;
+ armv4_5->core_mode = cpsr & 0x1F;
+ armv7a->core_state = (cpsr & 0x20)?ARMV7A_STATE_THUMB:ARMV7A_STATE_ARM;
for (i = 0; i <= ARM_PC; i++)
{
ARMV7A_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 16).dirty = 0;
/* Fixup PC Resume Address */
- /* TODO Her we should use arch->core_state */
- if (cortex_a8->cpudbg_dscr & (1 << 5))
+ if (armv7a->core_state == ARMV7A_STATE_THUMB)
{
// T bit set for Thumb or ThumbEE state
regfile[ARM_PC] -= 4;
/* 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;
breakpoint_t *breakpoint = NULL;
breakpoint_t stepbreakpoint;
/* Setup single step breakpoint */
stepbreakpoint.address = address;
- stepbreakpoint.length = (cortex_a8->cpudbg_dscr & (1 << 5)) ? 2 : 4;
+ stepbreakpoint.length = (armv7a->core_state == ARMV7A_STATE_THUMB) ? 2 : 4;
stepbreakpoint.type = BKPT_HARD;
stepbreakpoint.set = 0;
exit(-1);
}
+ /* The Cache handling will NOT work with MMU active, the wrong addresses will be invalidated */
+ /* invalidate I-Cache */
+ if (armv7a->armv4_5_mmu.armv4_5_cache.i_cache_enabled)
+ {
+ /* Invalidate ICache single entry with MVA, repeat this for all cache
+ lines in the address range, Cortex-A8 has fixed 64 byte line length */
+ /* Invalidate Cache single entry with MVA to PoU */
+ for (uint32_t cacheline=address; cacheline<address+size*count; cacheline+=64)
+ armv7a->write_cp15(target, 0, 1, 7, 5, cacheline); /* I-Cache to PoU */
+ }
+ /* invalidate D-Cache */
+ if (armv7a->armv4_5_mmu.armv4_5_cache.d_u_cache_enabled)
+ {
+ /* Invalidate Cache single entry with MVA to PoC */
+ for (uint32_t cacheline=address; cacheline<address+size*count; cacheline+=64)
+ armv7a->write_cp15(target, 0, 1, 7, 6, cacheline); /* U/D cache to PoC */
+ }
+
return retval;
}