*/
int cortex_a8_init_debug_access(target_t *target)
{
-#if 0
-# Unlocking the debug registers for modification
-mww 0x54011FB0 0xC5ACCE55 4
-
-# Clear Sticky Power Down status Bit to enable access to
-# the registers in the Core Power Domain
-mdw 0x54011314
-# Check that it is cleared
-mdw 0x54011314
-# Now we can read Core Debug Registers at offset 0x080
-mdw 0x54011080 4
-# We can also read RAM.
-mdw 0x80000000 32
-
-mdw 0x5401d030
-mdw 0x54011FB8
-
-# Set DBGEN line for hardware debug (OMAP35xx)
-mww 0x5401d030 0x00002000
-
-#Check AUTHSTATUS
-mdw 0x54011FB8
-
-# Instr enable
-mww 0x54011088 0x2000
-mdw 0x54011080 4
-#endif
- return 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;
+
+ int retval;
+ uint32_t dummy;
+
+ LOG_DEBUG(" ");
+
+ /* Unlocking the debug registers for modification */
+ /* The debugport might be uninitialised so try twice */
+ retval = mem_ap_write_atomic_u32(swjdp, armv7a->debug_base + CPUDBG_LOCKACCESS, 0xC5ACCE55);
+ if (retval != ERROR_OK)
+ mem_ap_write_atomic_u32(swjdp, armv7a->debug_base + CPUDBG_LOCKACCESS, 0xC5ACCE55);
+ /* Clear Sticky Power Down status Bit in PRSR to enable access to
+ the registers in the Core Power Domain */
+ retval = mem_ap_read_atomic_u32(swjdp, armv7a->debug_base + CPUDBG_PRSR, &dummy);
+ /* Enabling of instruction execution in debug mode is done in debug_entry code */
+
+ return retval;
}
int cortex_a8_exec_opcode(target_t *target, uint32_t opcode)
do
{
retval = mem_ap_read_atomic_u32(swjdp,
- OMAP3530_DEBUG_BASE + CPUDBG_DSCR, &dscr);
+ armv7a->debug_base + CPUDBG_DSCR, &dscr);
if (retval != ERROR_OK)
return retval;
- }
+ }
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);
+ mem_ap_write_u32(swjdp, armv7a->debug_base + CPUDBG_ITR, opcode);
do
{
retval = mem_ap_read_atomic_u32(swjdp,
- OMAP3530_DEBUG_BASE + CPUDBG_DSCR, &dscr);
+ armv7a->debug_base + CPUDBG_DSCR, &dscr);
if (retval != ERROR_OK)
return retval;
- }
+ }
while ((dscr & (1 << DSCR_INSTR_COMP)) == 0); /* Wait for InstrCompl bit to be set */
return retval;
/* Read DCCTX */
retval = mem_ap_read_atomic_u32(swjdp,
- OMAP3530_DEBUG_BASE + CPUDBG_DTRTX, value);
+ armv7a->debug_base + CPUDBG_DTRTX, value);
return retval;
}
swjdp_common_t *swjdp = &armv7a->swjdp_info;
retval = mem_ap_write_u32(swjdp,
- OMAP3530_DEBUG_BASE + CPUDBG_DTRRX, value);
+ armv7a->debug_base + CPUDBG_DTRRX, value);
/* Move DTRRX to r0 */
cortex_a8_exec_opcode(target, ARMV4_5_MRC(14, 0, 0, 0, 5, 0));
do
{
retval = mem_ap_read_atomic_u32(swjdp,
- OMAP3530_DEBUG_BASE + CPUDBG_DSCR, &dscr);
+ armv7a->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);
+ armv7a->debug_base + CPUDBG_DTRTX, value);
return retval;
}
/* Write to DCCRX */
retval = mem_ap_write_u32(swjdp,
- OMAP3530_DEBUG_BASE + CPUDBG_DTRRX, value);
+ armv7a->debug_base + CPUDBG_DTRRX, value);
if (Rd < 15)
{
return retval;
}
+/* Write to memory mapped registers directly with no cache or mmu handling */
+int cortex_a8_dap_write_memap_register_u32(target_t *target, uint32_t address, uint32_t value)
+{
+ 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_atomic_u32(swjdp, address, value);
+
+ return retval;
+}
+
/*
* Cortex-A8 Run control
*/
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);
+ armv7a->debug_base + CPUDBG_DSCR, &dscr);
if (retval != ERROR_OK)
{
dap_ap_select(swjdp, saved_apsel);
* and then wait for the core to be halted.
*/
retval = mem_ap_write_atomic_u32(swjdp,
- OMAP3530_DEBUG_BASE + CPUDBG_DRCR, 0x1);
+ armv7a->debug_base + CPUDBG_DRCR, 0x1);
/*
* enter halting debug mode
*/
- mem_ap_read_atomic_u32(swjdp, OMAP3530_DEBUG_BASE + CPUDBG_DSCR, &dscr);
+ mem_ap_read_atomic_u32(swjdp, armv7a->debug_base + CPUDBG_DSCR, &dscr);
retval = mem_ap_write_atomic_u32(swjdp,
- OMAP3530_DEBUG_BASE + CPUDBG_DSCR, dscr | (1 << DSCR_HALT_DBG_MODE));
+ armv7a->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);
+ armv7a->debug_base + CPUDBG_DSCR, &dscr);
} while ((dscr & (1 << DSCR_CORE_HALTED)) == 0);
target->debug_reason = DBG_REASON_DBGRQ;
#endif
/* Restart core and wait for it to be started */
- mem_ap_write_atomic_u32(swjdp, OMAP3530_DEBUG_BASE + CPUDBG_DRCR, 0x2);
+ mem_ap_write_atomic_u32(swjdp, armv7a->debug_base + CPUDBG_DRCR, 0x2);
do {
mem_ap_read_atomic_u32(swjdp,
- OMAP3530_DEBUG_BASE + CPUDBG_DSCR, &dscr);
+ armv7a->debug_base + CPUDBG_DSCR, &dscr);
} while ((dscr & (1 << DSCR_CORE_RESTARTED)) == 0);
target->debug_reason = DBG_REASON_NOTHALTED;
/* Enable the ITR execution once we are in debug mode */
mem_ap_read_atomic_u32(swjdp,
- OMAP3530_DEBUG_BASE + CPUDBG_DSCR, &dscr);
+ armv7a->debug_base + CPUDBG_DSCR, &dscr);
dscr |= (1 << DSCR_EXT_INT_EN);
retval = mem_ap_write_atomic_u32(swjdp,
- OMAP3530_DEBUG_BASE + CPUDBG_DSCR, dscr);
+ armv7a->debug_base + CPUDBG_DSCR, dscr);
/* Examine debug reason */
switch ((cortex_a8->cpudbg_dscr >> 2)&0xF)
brp_list[brp_i].used = 1;
brp_list[brp_i].value = (breakpoint->address & 0xFFFFFFFC);
brp_list[brp_i].control = control;
- target_write_u32(target, OMAP3530_DEBUG_BASE
+ cortex_a8_dap_write_memap_register_u32(target, armv7a->debug_base
+ CPUDBG_BVR_BASE + 4 * brp_list[brp_i].BRPn,
brp_list[brp_i].value);
- target_write_u32(target, OMAP3530_DEBUG_BASE
+ cortex_a8_dap_write_memap_register_u32(target, armv7a->debug_base
+ CPUDBG_BCR_BASE + 4 * brp_list[brp_i].BRPn,
brp_list[brp_i].control);
LOG_DEBUG("brp %i control 0x%0" PRIx32 " value 0x%0" PRIx32, brp_i,
brp_list[brp_i].used = 0;
brp_list[brp_i].value = 0;
brp_list[brp_i].control = 0;
- target_write_u32(target, OMAP3530_DEBUG_BASE
+ cortex_a8_dap_write_memap_register_u32(target, armv7a->debug_base
+ CPUDBG_BCR_BASE + 4 * brp_list[brp_i].BRPn,
brp_list[brp_i].control);
- target_write_u32(target, OMAP3530_DEBUG_BASE
+ cortex_a8_dap_write_memap_register_u32(target, armv7a->debug_base
+ CPUDBG_BVR_BASE + 4 * brp_list[brp_i].BRPn,
brp_list[brp_i].value);
}
LOG_DEBUG("TODO");
+ /* Here we shall insert a proper ROM Table scan */
+ armv7a->debug_base = OMAP3530_DEBUG_BASE;
+
/* We do one extra read to ensure DAP is configured,
* we call ahbap_debugport_init(swjdp) instead
*/
ahbap_debugport_init(swjdp);
- mem_ap_read_atomic_u32(swjdp, OMAP3530_DEBUG_BASE + CPUDBG_CPUID, &cpuid);
+ mem_ap_read_atomic_u32(swjdp, armv7a->debug_base + CPUDBG_CPUID, &cpuid);
if ((retval = mem_ap_read_atomic_u32(swjdp,
- OMAP3530_DEBUG_BASE + CPUDBG_CPUID, &cpuid)) != ERROR_OK)
+ armv7a->debug_base + CPUDBG_CPUID, &cpuid)) != ERROR_OK)
{
LOG_DEBUG("Examine failed");
return retval;
}
if ((retval = mem_ap_read_atomic_u32(swjdp,
- OMAP3530_DEBUG_BASE + CPUDBG_CTYPR, &ctypr)) != ERROR_OK)
+ armv7a->debug_base + CPUDBG_CTYPR, &ctypr)) != ERROR_OK)
{
LOG_DEBUG("Examine failed");
return retval;
}
if ((retval = mem_ap_read_atomic_u32(swjdp,
- OMAP3530_DEBUG_BASE + CPUDBG_TTYPR, &ttypr)) != ERROR_OK)
+ armv7a->debug_base + CPUDBG_TTYPR, &ttypr)) != ERROR_OK)
{
LOG_DEBUG("Examine failed");
return retval;
}
if ((retval = mem_ap_read_atomic_u32(swjdp,
- OMAP3530_DEBUG_BASE + CPUDBG_DIDR, &didr)) != ERROR_OK)
+ armv7a->debug_base + CPUDBG_DIDR, &didr)) != ERROR_OK)
{
LOG_DEBUG("Examine failed");
return retval;
LOG_DEBUG("Configured %i hw breakpoint pairs and %i hw watchpoint pairs",
cortex_a8->brp_num , cortex_a8->wrp_num);
+ /* Configure core debug access */
+ cortex_a8_init_debug_access(target);
+
target->type->examined = 1;
return retval;
}
+static int cortex_a8_handle_dbginit_command(struct command_context_s *cmd_ctx,
+ char *cmd, char **args, int argc)
+{
+ target_t *target = get_current_target(cmd_ctx);
+
+ cortex_a8_init_debug_access(target);
+
+ return ERROR_OK;
+}
+
+
int cortex_a8_register_commands(struct command_context_s *cmd_ctx)
{
command_t *cortex_a8_cmd;
cortex_a8_handle_cache_info_command, COMMAND_EXEC,
"display information about target caches");
+ register_command(cmd_ctx, cortex_a8_cmd, "dbginit",
+ cortex_a8_handle_dbginit_command, COMMAND_EXEC,
+ "Initialize core debug");
+
return retval;
}