ARM11 command handling fixes
[fw/openocd] / src / target / cortex_a8.c
index ae97f87ed180ab1a1605375147bf59c8eac6bddf..f6f13cfc9b742ab84bd6c376631bfe7a8e7995f7 100644 (file)
@@ -120,34 +120,27 @@ target_type_t cortexa8_target =
  */
 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)
@@ -163,21 +156,21 @@ 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;
@@ -221,7 +214,7 @@ int cortex_a8_read_cp(target_t *target, uint32_t *value, uint8_t CP,
 
        /* Read DCCTX */
        retval = mem_ap_read_atomic_u32(swjdp,
-                       OMAP3530_DEBUG_BASE + CPUDBG_DTRTX, value);
+                       armv7a->debug_base + CPUDBG_DTRTX, value);
 
        return retval;
 }
@@ -236,7 +229,7 @@ int cortex_a8_write_cp(target_t *target, uint32_t value,
        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));
 
@@ -291,12 +284,12 @@ int cortex_a8_dap_read_coreregister_u32(target_t *target,
        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;
 }
@@ -316,7 +309,7 @@ int cortex_a8_dap_write_coreregister_u32(target_t *target, uint32_t value, int r
 
        /* Write to DCCRX */
        retval = mem_ap_write_u32(swjdp,
-                       OMAP3530_DEBUG_BASE + CPUDBG_DTRRX, value);
+                       armv7a->debug_base + CPUDBG_DTRRX, value);
 
        if (Rd < 15)
        {
@@ -339,6 +332,21 @@ int cortex_a8_dap_write_coreregister_u32(target_t *target, uint32_t value, int r
        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
  */
@@ -359,7 +367,7 @@ int cortex_a8_poll(target_t *target)
        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);
@@ -430,21 +438,21 @@ int cortex_a8_halt(target_t *target)
         * 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;
@@ -545,11 +553,11 @@ int cortex_a8_resume(struct target_s *target, int current,
 
 #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;
@@ -596,10 +604,10 @@ int cortex_a8_debug_entry(target_t *target)
 
        /* 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)
@@ -1029,10 +1037,10 @@ int cortex_a8_set_breakpoint(struct target_s *target,
                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,
@@ -1095,10 +1103,10 @@ int cortex_a8_unset_breakpoint(struct target_s *target, breakpoint_t *breakpoint
                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);
        }
@@ -1367,34 +1375,37 @@ int cortex_a8_examine(struct target_s *target)
 
        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;
@@ -1438,6 +1449,9 @@ int cortex_a8_examine(struct target_s *target)
        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;
@@ -1556,6 +1570,17 @@ static int cortex_a8_handle_cache_info_command(struct command_context_s *cmd_ctx
 }
 
 
+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;
@@ -1572,5 +1597,9 @@ int cortex_a8_register_commands(struct command_context_s *cmd_ctx)
                        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;
 }