cortex_m: Call mem_ap_read/write directly
[openocd.git] / src / target / cortex_m.c
index 4d9daf5ca09e48de924fda94476f4b207655107d..ea8a086027e42edb498a3f3bdc093b889197f5af 100644 (file)
@@ -21,7 +21,7 @@
  *   You should have received a copy of the GNU General Public License     *
  *   along with this program; if not, write to the                         *
  *   Free Software Foundation, Inc.,                                       *
- *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
+ *   51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.           *
  *                                                                         *
  *                                                                         *
  *   Cortex-M3(tm) TRM, ARM DDI 0337E (r1p1) and 0337G (r2p0)              *
@@ -61,7 +61,7 @@
 
 /* forward declarations */
 static int cortex_m3_store_core_reg_u32(struct target *target,
-       enum armv7m_regtype type, uint32_t num, uint32_t value);
+               uint32_t num, uint32_t value);
 
 static int cortexm3_dap_read_coreregister_u32(struct adiv5_dap *swjdp,
        uint32_t *value, int regnum)
@@ -298,7 +298,7 @@ static int cortex_m3_endreset_event(struct target *target)
        if (retval != ERROR_OK)
                return retval;
 
-       register_cache_invalidate(cortex_m3->armv7m.core_cache);
+       register_cache_invalidate(armv7m->arm.core_cache);
 
        /* make sure we have latest dhcsr flags */
        retval = mem_ap_read_atomic_u32(swjdp, DCB_DHCSR, &cortex_m3->dcb_dhcsr);
@@ -421,48 +421,36 @@ static int cortex_m3_debug_entry(struct target *target)
                return retval;
 
        /* Examine target state and mode
-        * First load register acessible through core debug port*/
-       int num_regs = armv7m->core_cache->num_regs;
+        * First load register accessible through core debug port */
+       int num_regs = arm->core_cache->num_regs;
 
        for (i = 0; i < num_regs; i++) {
-               if (!armv7m->core_cache->reg_list[i].valid)
-                       armv7m->read_core_reg(target, i);
+               r = &armv7m->arm.core_cache->reg_list[i];
+               if (!r->valid)
+                       arm->read_core_reg(target, r, i, ARM_MODE_ANY);
        }
 
-       r = armv7m->core_cache->reg_list + ARMV7M_xPSR;
+       r = arm->cpsr;
        xPSR = buf_get_u32(r->value, 0, 32);
 
-#ifdef ARMV7_GDB_HACKS
-       /* FIXME this breaks on scan chains with more than one Cortex-M3.
-        * Instead, each CM3 should have its own dummy value...
-        */
-       /* copy real xpsr reg for gdb, setting thumb bit */
-       buf_set_u32(armv7m_gdb_dummy_cpsr_value, 0, 32, xPSR);
-       buf_set_u32(armv7m_gdb_dummy_cpsr_value, 5, 1, 1);
-       armv7m_gdb_dummy_cpsr_reg.valid = r->valid;
-       armv7m_gdb_dummy_cpsr_reg.dirty = r->dirty;
-#endif
-
        /* For IT instructions xPSR must be reloaded on resume and clear on debug exec */
        if (xPSR & 0xf00) {
                r->dirty = r->valid;
-               cortex_m3_store_core_reg_u32(target, ARMV7M_REGISTER_CORE_GP, 16, xPSR & ~0xff);
+               cortex_m3_store_core_reg_u32(target, 16, xPSR & ~0xff);
        }
 
        /* Are we in an exception handler */
        if (xPSR & 0x1FF) {
-               armv7m->core_mode = ARMV7M_MODE_HANDLER;
                armv7m->exception_number = (xPSR & 0x1FF);
 
                arm->core_mode = ARM_MODE_HANDLER;
                arm->map = armv7m_msp_reg_map;
        } else {
-               unsigned control = buf_get_u32(armv7m->core_cache
+               unsigned control = buf_get_u32(arm->core_cache
                                ->reg_list[ARMV7M_CONTROL].value, 0, 2);
 
                /* is this thread privileged? */
-               armv7m->core_mode = control & 1;
-               arm->core_mode = armv7m->core_mode
+               arm->core_mode = control & 1
                        ? ARM_MODE_USER_THREAD
                        : ARM_MODE_THREAD;
 
@@ -479,7 +467,7 @@ static int cortex_m3_debug_entry(struct target *target)
                cortex_m3_examine_exception_reason(target);
 
        LOG_DEBUG("entered debug state in core mode: %s at PC 0x%" PRIx32 ", target->state: %s",
-               armv7m_mode_strings[armv7m->core_mode],
+               arm_mode_name(arm->core_mode),
                *(uint32_t *)(arm->pc->value),
                target_state_name(target));
 
@@ -633,6 +621,12 @@ static int cortex_m3_soft_reset_halt(struct target *target)
        uint32_t dcb_dhcsr = 0;
        int retval, timeout = 0;
 
+       /* soft_reset_halt is deprecated on cortex_m as the same functionality
+        * can be obtained by using 'reset halt' and 'cortex_m reset_config vectreset'
+        * As this reset only used VC_CORERESET it would only ever reset the cortex_m
+        * core, not the peripherals */
+       LOG_WARNING("soft_reset_halt is deprecated, please use 'reset halt' instead.");
+
        /* Enter debug state on reset; restore DEMCR in endreset_event() */
        retval = mem_ap_write_u32(swjdp, DCB_DEMCR,
                        TRCENA | VC_HARDERR | VC_BUSERR | VC_CORERESET);
@@ -647,7 +641,7 @@ static int cortex_m3_soft_reset_halt(struct target *target)
        target->state = TARGET_RESET;
 
        /* registers are now invalid */
-       register_cache_invalidate(cortex_m3->armv7m.core_cache);
+       register_cache_invalidate(cortex_m3->armv7m.arm.core_cache);
 
        while (timeout < 100) {
                retval = mem_ap_read_atomic_u32(swjdp, DCB_DHCSR, &dcb_dhcsr);
@@ -677,7 +671,7 @@ static int cortex_m3_soft_reset_halt(struct target *target)
        return ERROR_OK;
 }
 
-static void cortex_m3_enable_breakpoints(struct target *target)
+void cortex_m3_enable_breakpoints(struct target *target)
 {
        struct breakpoint *breakpoint = target->breakpoints;
 
@@ -709,7 +703,7 @@ static int cortex_m3_resume(struct target *target, int current,
        }
 
        if (debug_execution) {
-               r = armv7m->core_cache->reg_list + ARMV7M_PRIMASK;
+               r = armv7m->arm.core_cache->reg_list + ARMV7M_PRIMASK;
 
                /* Disable interrupts */
                /* We disable interrupts in the PRIMASK register instead of
@@ -727,7 +721,7 @@ static int cortex_m3_resume(struct target *target, int current,
                r->valid = true;
 
                /* Make sure we are in Thumb mode */
-               r = armv7m->core_cache->reg_list + ARMV7M_xPSR;
+               r = armv7m->arm.cpsr;
                buf_set_u32(r->value, 24, 1, 1);
                r->dirty = true;
                r->valid = true;
@@ -773,7 +767,7 @@ static int cortex_m3_resume(struct target *target, int current,
        target->debug_reason = DBG_REASON_NOTHALTED;
 
        /* registers are now invalid */
-       register_cache_invalidate(armv7m->core_cache);
+       register_cache_invalidate(armv7m->arm.core_cache);
 
        if (!debug_execution) {
                target->state = TARGET_RUNNING;
@@ -936,7 +930,7 @@ static int cortex_m3_step(struct target *target, int current,
                return retval;
 
        /* registers are now invalid */
-       register_cache_invalidate(cortex_m3->armv7m.core_cache);
+       register_cache_invalidate(armv7m->arm.core_cache);
 
        if (breakpoint)
                cortex_m3_set_breakpoint(target, breakpoint);
@@ -979,7 +973,7 @@ static int cortex_m3_assert_reset(struct target *target)
                /* allow scripts to override the reset event */
 
                target_handle_event(target, TARGET_EVENT_RESET_ASSERT);
-               register_cache_invalidate(cortex_m3->armv7m.core_cache);
+               register_cache_invalidate(cortex_m3->armv7m.arm.core_cache);
                target->state = TARGET_RESET;
 
                return ERROR_OK;
@@ -990,7 +984,8 @@ static int cortex_m3_assert_reset(struct target *target)
 
        bool srst_asserted = false;
 
-       if (jtag_reset_config & RESET_SRST_NO_GATING) {
+       if ((jtag_reset_config & RESET_HAS_SRST) &&
+           (jtag_reset_config & RESET_SRST_NO_GATING)) {
                adapter_assert_reset();
                srst_asserted = true;
        }
@@ -1061,11 +1056,11 @@ static int cortex_m3_assert_reset(struct target *target)
                if (retval != ERROR_OK)
                        return retval;
 
-               LOG_DEBUG("Using Cortex-M3 %s", (reset_config == CORTEX_M3_RESET_SYSRESETREQ)
+               LOG_DEBUG("Using Cortex-M %s", (reset_config == CORTEX_M3_RESET_SYSRESETREQ)
                        ? "SYSRESETREQ" : "VECTRESET");
 
                if (reset_config == CORTEX_M3_RESET_VECTRESET) {
-                       LOG_WARNING("Only resetting the Cortex-M3 core, use a reset-init event "
+                       LOG_WARNING("Only resetting the Cortex-M core, use a reset-init event "
                                "handler to reset any peripherals or configure hardware srst support.");
                }
 
@@ -1084,7 +1079,7 @@ static int cortex_m3_assert_reset(struct target *target)
        target->state = TARGET_RESET;
        jtag_add_sleep(50000);
 
-       register_cache_invalidate(cortex_m3->armv7m.core_cache);
+       register_cache_invalidate(cortex_m3->armv7m.arm.core_cache);
 
        if (target->reset_halt) {
                retval = target_halt(target);
@@ -1226,17 +1221,8 @@ int cortex_m3_add_breakpoint(struct target *target, struct breakpoint *breakpoin
 {
        struct cortex_m3_common *cortex_m3 = target_to_cm3(target);
 
-       if (cortex_m3->auto_bp_type) {
+       if (cortex_m3->auto_bp_type)
                breakpoint->type = BKPT_TYPE_BY_ADDR(breakpoint->address);
-#ifdef ARMV7_GDB_HACKS
-               if (breakpoint->length != 2) {
-                       /* XXX Hack: Replace all breakpoints with length != 2 with
-                        * a hardware breakpoint. */
-                       breakpoint->type = BKPT_HARD;
-                       breakpoint->length = 2;
-               }
-#endif
-       }
 
        if (breakpoint->type != BKPT_TYPE_BY_ADDR(breakpoint->address)) {
                if (breakpoint->type == BKPT_HARD) {
@@ -1466,7 +1452,7 @@ void cortex_m3_enable_watchpoints(struct target *target)
 }
 
 static int cortex_m3_load_core_reg_u32(struct target *target,
-       enum armv7m_regtype type, uint32_t num, uint32_t *value)
+               uint32_t num, uint32_t *value)
 {
        int retval;
        struct armv7m_common *armv7m = target_to_armv7m(target);
@@ -1527,25 +1513,13 @@ static int cortex_m3_load_core_reg_u32(struct target *target,
 }
 
 static int cortex_m3_store_core_reg_u32(struct target *target,
-       enum armv7m_regtype type, uint32_t num, uint32_t value)
+               uint32_t num, uint32_t value)
 {
        int retval;
        uint32_t reg;
        struct armv7m_common *armv7m = target_to_armv7m(target);
        struct adiv5_dap *swjdp = armv7m->arm.dap;
 
-#ifdef ARMV7_GDB_HACKS
-       /* If the LR register is being modified, make sure it will put us
-        * in "thumb" mode, or an INVSTATE exception will occur. This is a
-        * hack to deal with the fact that gdb will sometimes "forge"
-        * return addresses, and doesn't set the LSB correctly (i.e., when
-        * printing expressions containing function calls, it sets LR = 0.)
-        * Valid exception return codes have bit 0 set too.
-        */
-       if (num == ARMV7M_R14)
-               value |= 0x01;
-#endif
-
        /* NOTE:  we "know" here that the register identifiers used
         * in the v7m header match the Cortex-M3 Debug Core Register
         * Selector values for R0..R15, xPSR, MSP, and PSP.
@@ -1557,7 +1531,7 @@ static int cortex_m3_store_core_reg_u32(struct target *target,
                                struct reg *r;
 
                                LOG_ERROR("JTAG failure");
-                               r = armv7m->core_cache->reg_list + num;
+                               r = armv7m->arm.core_cache->reg_list + num;
                                r->dirty = r->valid;
                                return ERROR_JTAG_DEVICE_ERROR;
                        }
@@ -1609,7 +1583,6 @@ static int cortex_m3_read_memory(struct target *target, uint32_t address,
 {
        struct armv7m_common *armv7m = target_to_armv7m(target);
        struct adiv5_dap *swjdp = armv7m->arm.dap;
-       int retval = ERROR_COMMAND_SYNTAX_ERROR;
 
        if (armv7m->arm.is_armv6m) {
                /* armv6m does not handle unaligned memory access */
@@ -1617,22 +1590,7 @@ static int cortex_m3_read_memory(struct target *target, uint32_t address,
                        return ERROR_TARGET_UNALIGNED_ACCESS;
        }
 
-       /* cortex_m3 handles unaligned memory access */
-       if (count && buffer) {
-               switch (size) {
-                       case 4:
-                               retval = mem_ap_read_buf_u32(swjdp, buffer, 4 * count, address);
-                               break;
-                       case 2:
-                               retval = mem_ap_read_buf_u16(swjdp, buffer, 2 * count, address);
-                               break;
-                       case 1:
-                               retval = mem_ap_read_buf_u8(swjdp, buffer, count, address);
-                               break;
-               }
-       }
-
-       return retval;
+       return mem_ap_read(swjdp, buffer, size, count, address, true);
 }
 
 static int cortex_m3_write_memory(struct target *target, uint32_t address,
@@ -1640,7 +1598,6 @@ static int cortex_m3_write_memory(struct target *target, uint32_t address,
 {
        struct armv7m_common *armv7m = target_to_armv7m(target);
        struct adiv5_dap *swjdp = armv7m->arm.dap;
-       int retval = ERROR_COMMAND_SYNTAX_ERROR;
 
        if (armv7m->arm.is_armv6m) {
                /* armv6m does not handle unaligned memory access */
@@ -1648,27 +1605,7 @@ static int cortex_m3_write_memory(struct target *target, uint32_t address,
                        return ERROR_TARGET_UNALIGNED_ACCESS;
        }
 
-       if (count && buffer) {
-               switch (size) {
-                       case 4:
-                               retval = mem_ap_write_buf_u32(swjdp, buffer, 4 * count, address);
-                               break;
-                       case 2:
-                               retval = mem_ap_write_buf_u16(swjdp, buffer, 2 * count, address);
-                               break;
-                       case 1:
-                               retval = mem_ap_write_buf_u8(swjdp, buffer, count, address);
-                               break;
-               }
-       }
-
-       return retval;
-}
-
-static int cortex_m3_bulk_write_memory(struct target *target, uint32_t address,
-       uint32_t count, const uint8_t *buffer)
-{
-       return cortex_m3_write_memory(target, address, 4, count, buffer);
+       return mem_ap_write(swjdp, buffer, size, count, address, true);
 }
 
 static int cortex_m3_init_target(struct command_context *cmd_ctx,
@@ -1803,6 +1740,9 @@ fail1:
                for (j = 0; j < 3; j++, reg++)
                        cortex_m3_dwt_addreg(target, cache->reg_list + reg,
                                dwt_comp + 3 * i + j);
+
+               /* make sure we clear any watchpoints enabled on the target */
+               target_write_u32(target, comparator->dwt_comparator_address + 8, 0);
        }
 
        *register_get_last_cache_p(&target->reg_cache) = cache;
@@ -1894,6 +1834,9 @@ int cortex_m3_examine(struct target *target)
                        cortex_m3->fp_comparator_list[i].type =
                                (i < cortex_m3->fp_num_code) ? FPCR_CODE : FPCR_LITERAL;
                        cortex_m3->fp_comparator_list[i].fpcr_address = FP_COMP0 + 4 * i;
+
+                       /* make sure we clear any breakpoints enabled on the target */
+                       target_write_u32(target, cortex_m3->fp_comparator_list[i].fpcr_address, 0);
                }
                LOG_DEBUG("FPB fpcr 0x%" PRIx32 ", numcode %i, numlit %i",
                        fpcr,
@@ -1918,7 +1861,7 @@ static int cortex_m3_dcc_read(struct adiv5_dap *swjdp, uint8_t *value, uint8_t *
        uint16_t dcrdr;
        int retval;
 
-       mem_ap_read_buf_u16(swjdp, (uint8_t *)&dcrdr, 1, DCB_DCRDR);
+       mem_ap_read_buf_u16(swjdp, (uint8_t *)&dcrdr, 2, DCB_DCRDR);
        *ctrl = (uint8_t)dcrdr;
        *value = (uint8_t)(dcrdr >> 8);
 
@@ -1928,7 +1871,7 @@ static int cortex_m3_dcc_read(struct adiv5_dap *swjdp, uint8_t *value, uint8_t *
         * signify we have read data */
        if (dcrdr & (1 << 0)) {
                dcrdr = 0;
-               retval = mem_ap_write_buf_u16(swjdp, (uint8_t *)&dcrdr, 1, DCB_DCRDR);
+               retval = mem_ap_write_buf_u16(swjdp, (uint8_t *)&dcrdr, 2, DCB_DCRDR);
                if (retval != ERROR_OK)
                        return retval;
        }
@@ -2051,7 +1994,7 @@ static int cortex_m3_verify_pointer(struct command_context *cmd_ctx,
        struct cortex_m3_common *cm3)
 {
        if (cm3->common_magic != CORTEX_M3_COMMON_MAGIC) {
-               command_print(cmd_ctx, "target is not a Cortex-M3");
+               command_print(cmd_ctx, "target is not a Cortex-M");
                return ERROR_TARGET_INVALID;
        }
        return ERROR_OK;
@@ -2186,7 +2129,7 @@ COMMAND_HANDLER(handle_cortex_m3_mask_interrupts_command)
        }
 
        n = Jim_Nvp_value2name_simple(nvp_maskisr_modes, cortex_m3->isrmasking_mode);
-       command_print(CMD_CTX, "cortex_m3 interrupt mask %s", n->name);
+       command_print(CMD_CTX, "cortex_m interrupt mask %s", n->name);
 
        return ERROR_OK;
 }
@@ -2223,7 +2166,7 @@ COMMAND_HANDLER(handle_cortex_m3_reset_config_command)
                        break;
        }
 
-       command_print(CMD_CTX, "cortex_m3 reset_config %s", reset_config);
+       command_print(CMD_CTX, "cortex_m reset_config %s", reset_config);
 
        return ERROR_OK;
 }
@@ -2233,7 +2176,7 @@ static const struct command_registration cortex_m3_exec_command_handlers[] = {
                .name = "maskisr",
                .handler = handle_cortex_m3_mask_interrupts_command,
                .mode = COMMAND_EXEC,
-               .help = "mask cortex_m3 interrupts",
+               .help = "mask cortex_m interrupts",
                .usage = "['auto'|'on'|'off']",
        },
        {
@@ -2257,9 +2200,9 @@ static const struct command_registration cortex_m3_command_handlers[] = {
                .chain = armv7m_command_handlers,
        },
        {
-               .name = "cortex_m3",
+               .name = "cortex_m",
                .mode = COMMAND_EXEC,
-               .help = "Cortex-M3 command group",
+               .help = "Cortex-M command group",
                .usage = "",
                .chain = cortex_m3_exec_command_handlers,
        },
@@ -2267,7 +2210,8 @@ static const struct command_registration cortex_m3_command_handlers[] = {
 };
 
 struct target_type cortexm3_target = {
-       .name = "cortex_m3",
+       .name = "cortex_m",
+       .deprecated_name = "cortex_m3",
 
        .poll = cortex_m3_poll,
        .arch_state = armv7m_arch_state,
@@ -2286,7 +2230,6 @@ struct target_type cortexm3_target = {
 
        .read_memory = cortex_m3_read_memory,
        .write_memory = cortex_m3_write_memory,
-       .bulk_write_memory = cortex_m3_bulk_write_memory,
        .checksum_memory = armv7m_checksum_memory,
        .blank_check_memory = armv7m_blank_check_memory,
 

Linking to existing account procedure

If you already have an account and want to add another login method you MUST first sign in with your existing account and then change URL to read https://review.openocd.org/login/?link to get to this page again but this time it'll work for linking. Thank you.

SSH host keys fingerprints

1024 SHA256:YKx8b7u5ZWdcbp7/4AeXNaqElP49m6QrwfXaqQGJAOk gerrit-code-review@openocd.zylin.com (DSA)
384 SHA256:jHIbSQa4REvwCFG4cq5LBlBLxmxSqelQPem/EXIrxjk gerrit-code-review@openocd.org (ECDSA)
521 SHA256:UAOPYkU9Fjtcao0Ul/Rrlnj/OsQvt+pgdYSZ4jOYdgs gerrit-code-review@openocd.org (ECDSA)
256 SHA256:A13M5QlnozFOvTllybRZH6vm7iSt0XLxbA48yfc2yfY gerrit-code-review@openocd.org (ECDSA)
256 SHA256:spYMBqEYoAOtK7yZBrcwE8ZpYt6b68Cfh9yEVetvbXg gerrit-code-review@openocd.org (ED25519)
+--[ED25519 256]--+
|=..              |
|+o..   .         |
|*.o   . .        |
|+B . . .         |
|Bo. = o S        |
|Oo.+ + =         |
|oB=.* = . o      |
| =+=.+   + E     |
|. .=o   . o      |
+----[SHA256]-----+
2048 SHA256:0Onrb7/PHjpo6iVZ7xQX2riKN83FJ3KGU0TvI0TaFG4 gerrit-code-review@openocd.zylin.com (RSA)