cortex_m: suggest using hardware srst if VECTRESET used
[openocd.git] / src / target / cortex_m.c
index 488899cbe9430ac814db859efb9219bc2d0d38d5..74505a85e1b669168640eaae4cf0ec7fa1f8b9c3 100644 (file)
@@ -31,6 +31,7 @@
 #include "config.h"
 #endif
 
+#include "jtag/interface.h"
 #include "breakpoints.h"
 #include "cortex_m.h"
 #include "target_request.h"
@@ -148,7 +149,7 @@ static int cortex_m3_write_debug_halt_mask(struct target *target,
        uint32_t mask_on, uint32_t mask_off)
 {
        struct cortex_m3_common *cortex_m3 = target_to_cm3(target);
-       struct adiv5_dap *swjdp = &cortex_m3->armv7m.dap;
+       struct adiv5_dap *swjdp = cortex_m3->armv7m.arm.dap;
 
        /* mask off status bits */
        cortex_m3->dcb_dhcsr &= ~((0xFFFF << 16) | mask_off);
@@ -161,7 +162,7 @@ static int cortex_m3_write_debug_halt_mask(struct target *target,
 static int cortex_m3_clear_halt(struct target *target)
 {
        struct cortex_m3_common *cortex_m3 = target_to_cm3(target);
-       struct adiv5_dap *swjdp = &cortex_m3->armv7m.dap;
+       struct adiv5_dap *swjdp = cortex_m3->armv7m.arm.dap;
        int retval;
 
        /* clear step if any */
@@ -184,7 +185,7 @@ static int cortex_m3_clear_halt(struct target *target)
 static int cortex_m3_single_step_core(struct target *target)
 {
        struct cortex_m3_common *cortex_m3 = target_to_cm3(target);
-       struct adiv5_dap *swjdp = &cortex_m3->armv7m.dap;
+       struct adiv5_dap *swjdp = cortex_m3->armv7m.arm.dap;
        uint32_t dhcsr_save;
        int retval;
 
@@ -221,7 +222,7 @@ static int cortex_m3_endreset_event(struct target *target)
        uint32_t dcb_demcr;
        struct cortex_m3_common *cortex_m3 = target_to_cm3(target);
        struct armv7m_common *armv7m = &cortex_m3->armv7m;
-       struct adiv5_dap *swjdp = &cortex_m3->armv7m.dap;
+       struct adiv5_dap *swjdp = cortex_m3->armv7m.arm.dap;
        struct cortex_m3_fp_comparator *fp_list = cortex_m3->fp_comparator_list;
        struct cortex_m3_dwt_comparator *dwt_list = cortex_m3->dwt_comparator_list;
 
@@ -333,7 +334,7 @@ static int cortex_m3_examine_exception_reason(struct target *target)
 {
        uint32_t shcsr = 0, except_sr = 0, cfsr = -1, except_ar = -1;
        struct armv7m_common *armv7m = target_to_armv7m(target);
-       struct adiv5_dap *swjdp = &armv7m->dap;
+       struct adiv5_dap *swjdp = armv7m->arm.dap;
        int retval;
 
        retval = mem_ap_read_u32(swjdp, NVIC_SHCSR, &shcsr);
@@ -405,7 +406,7 @@ static int cortex_m3_debug_entry(struct target *target)
        struct cortex_m3_common *cortex_m3 = target_to_cm3(target);
        struct armv7m_common *armv7m = &cortex_m3->armv7m;
        struct arm *arm = &armv7m->arm;
-       struct adiv5_dap *swjdp = &armv7m->dap;
+       struct adiv5_dap *swjdp = armv7m->arm.dap;
        struct reg *r;
 
        LOG_DEBUG(" ");
@@ -497,7 +498,7 @@ static int cortex_m3_poll(struct target *target)
        int retval = ERROR_OK;
        enum target_state prev_target_state = target->state;
        struct cortex_m3_common *cortex_m3 = target_to_cm3(target);
-       struct adiv5_dap *swjdp = &cortex_m3->armv7m.dap;
+       struct adiv5_dap *swjdp = cortex_m3->armv7m.arm.dap;
 
        /* Read from Debug Halting Control and Status Register */
        retval = mem_ap_read_atomic_u32(swjdp, DCB_DHCSR, &cortex_m3->dcb_dhcsr);
@@ -628,7 +629,7 @@ static int cortex_m3_halt(struct target *target)
 static int cortex_m3_soft_reset_halt(struct target *target)
 {
        struct cortex_m3_common *cortex_m3 = target_to_cm3(target);
-       struct adiv5_dap *swjdp = &cortex_m3->armv7m.dap;
+       struct adiv5_dap *swjdp = cortex_m3->armv7m.arm.dap;
        uint32_t dcb_dhcsr = 0;
        int retval, timeout = 0;
 
@@ -793,7 +794,7 @@ static int cortex_m3_step(struct target *target, int current,
 {
        struct cortex_m3_common *cortex_m3 = target_to_cm3(target);
        struct armv7m_common *armv7m = &cortex_m3->armv7m;
-       struct adiv5_dap *swjdp = &armv7m->dap;
+       struct adiv5_dap *swjdp = armv7m->arm.dap;
        struct breakpoint *breakpoint = NULL;
        struct reg *pc = armv7m->arm.pc;
        bool bkpt_inst_found = false;
@@ -933,7 +934,7 @@ static int cortex_m3_step(struct target *target, int current,
 static int cortex_m3_assert_reset(struct target *target)
 {
        struct cortex_m3_common *cortex_m3 = target_to_cm3(target);
-       struct adiv5_dap *swjdp = &cortex_m3->armv7m.dap;
+       struct adiv5_dap *swjdp = cortex_m3->armv7m.arm.dap;
        enum cortex_m3_soft_reset_config reset_config = cortex_m3->soft_reset_config;
 
        LOG_DEBUG("target->state: %s",
@@ -951,6 +952,16 @@ static int cortex_m3_assert_reset(struct target *target)
                return ERROR_OK;
        }
 
+       /* some cores support connecting while srst is asserted
+        * use that mode is it has been configured */
+
+       bool srst_asserted = false;
+
+       if (jtag_reset_config & RESET_SRST_NO_GATING) {
+               adapter_assert_reset();
+               srst_asserted = true;
+       }
+
        /* Enable debug requests */
        int retval;
        retval = mem_ap_read_atomic_u32(swjdp, DCB_DHCSR, &cortex_m3->dcb_dhcsr);
@@ -995,10 +1006,8 @@ static int cortex_m3_assert_reset(struct target *target)
 
        if (jtag_reset_config & RESET_HAS_SRST) {
                /* default to asserting srst */
-               if (jtag_reset_config & RESET_SRST_PULLS_TRST)
-                       jtag_add_reset(1, 1);
-               else
-                       jtag_add_reset(0, 1);
+               if (!srst_asserted)
+                       adapter_assert_reset();
        } else {
                /* Use a standard Cortex-M3 software reset mechanism.
                 * We default to using VECRESET as it is supported on all current cores.
@@ -1016,7 +1025,7 @@ static int cortex_m3_assert_reset(struct target *target)
 
                if (reset_config == CORTEX_M3_RESET_VECTRESET) {
                        LOG_WARNING("Only resetting the Cortex-M3 core, use a reset-init event "
-                               "handler to reset any peripherals");
+                               "handler to reset any peripherals or configure hardware srst support.");
                }
 
                {
@@ -1051,7 +1060,7 @@ static int cortex_m3_deassert_reset(struct target *target)
                target_state_name(target));
 
        /* deassert reset lines */
-       jtag_add_reset(0, 0);
+       adapter_deassert_reset();
 
        return ERROR_OK;
 }
@@ -1420,7 +1429,7 @@ static int cortex_m3_load_core_reg_u32(struct target *target,
 {
        int retval;
        struct armv7m_common *armv7m = target_to_armv7m(target);
-       struct adiv5_dap *swjdp = &armv7m->dap;
+       struct adiv5_dap *swjdp = armv7m->arm.dap;
 
        /* NOTE:  we "know" here that the register identifiers used
         * in the v7m header match the Cortex-M3 Debug Core Register
@@ -1482,7 +1491,7 @@ static int cortex_m3_store_core_reg_u32(struct target *target,
        int retval;
        uint32_t reg;
        struct armv7m_common *armv7m = target_to_armv7m(target);
-       struct adiv5_dap *swjdp = &armv7m->dap;
+       struct adiv5_dap *swjdp = armv7m->arm.dap;
 
 #ifdef ARMV7_GDB_HACKS
        /* If the LR register is being modified, make sure it will put us
@@ -1558,9 +1567,15 @@ static int cortex_m3_read_memory(struct target *target, uint32_t address,
        uint32_t size, uint32_t count, uint8_t *buffer)
 {
        struct armv7m_common *armv7m = target_to_armv7m(target);
-       struct adiv5_dap *swjdp = &armv7m->dap;
+       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 */
+               if (((size == 4) && (address & 0x3u)) || ((size == 2) && (address & 0x1u)))
+                       return ERROR_TARGET_UNALIGNED_ACCESS;
+       }
+
        /* cortex_m3 handles unaligned memory access */
        if (count && buffer) {
                switch (size) {
@@ -1583,9 +1598,15 @@ static int cortex_m3_write_memory(struct target *target, uint32_t address,
        uint32_t size, uint32_t count, const uint8_t *buffer)
 {
        struct armv7m_common *armv7m = target_to_armv7m(target);
-       struct adiv5_dap *swjdp = &armv7m->dap;
+       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 */
+               if (((size == 4) && (address & 0x3u)) || ((size == 2) && (address & 0x1u)))
+                       return ERROR_TARGET_UNALIGNED_ACCESS;
+       }
+
        if (count && buffer) {
                switch (size) {
                        case 4:
@@ -1768,12 +1789,16 @@ int cortex_m3_examine(struct target *target)
        uint32_t cpuid, fpcr, mvfr0, mvfr1;
        int i;
        struct cortex_m3_common *cortex_m3 = target_to_cm3(target);
-       struct adiv5_dap *swjdp = &cortex_m3->armv7m.dap;
+       struct adiv5_dap *swjdp = cortex_m3->armv7m.arm.dap;
        struct armv7m_common *armv7m = target_to_armv7m(target);
 
-       retval = ahbap_debugport_init(swjdp);
-       if (retval != ERROR_OK)
-               return retval;
+       /* stlink shares the examine handler but does not support
+        * all its calls */
+       if (!armv7m->stlink) {
+               retval = ahbap_debugport_init(swjdp);
+               if (retval != ERROR_OK)
+                       return retval;
+       }
 
        if (!target_was_examined(target)) {
                target_set_examined(target);
@@ -1799,6 +1824,14 @@ int cortex_m3_examine(struct target *target)
                                LOG_DEBUG("Cortex-M%d floating point feature FPv4_SP found", i);
                                armv7m->fp_feature = FPv4_SP;
                        }
+               } else if (i == 0) {
+                       /* Cortex-M0 does not support unaligned memory access */
+                       armv7m->arm.is_armv6m = true;
+               }
+
+               if (i == 4 || i == 3) {
+                       /* Cortex-M3/M4 has 4096 bytes autoincrement range */
+                       armv7m->dap.tar_autoincr_block = (1 << 12);
                }
 
                /* NOTE: FPB and DWT are both optional. */
@@ -1866,7 +1899,7 @@ static int cortex_m3_target_request_data(struct target *target,
        uint32_t size, uint8_t *buffer)
 {
        struct armv7m_common *armv7m = target_to_armv7m(target);
-       struct adiv5_dap *swjdp = &armv7m->dap;
+       struct adiv5_dap *swjdp = armv7m->arm.dap;
        uint8_t data;
        uint8_t ctrl;
        uint32_t i;
@@ -1885,7 +1918,7 @@ static int cortex_m3_handle_target_request(void *priv)
        if (!target_was_examined(target))
                return ERROR_OK;
        struct armv7m_common *armv7m = target_to_armv7m(target);
-       struct adiv5_dap *swjdp = &armv7m->dap;
+       struct adiv5_dap *swjdp = armv7m->arm.dap;
 
        if (!target->dbg_msg_enabled)
                return ERROR_OK;
@@ -1936,8 +1969,11 @@ static int cortex_m3_init_arch_info(struct target *target,
        /* Leave (only) generic DAP stuff for debugport_init(); */
        armv7m->dap.jtag_info = &cortex_m3->jtag_info;
        armv7m->dap.memaccess_tck = 8;
-       /* Cortex-M3 has 4096 bytes autoincrement range */
-       armv7m->dap.tar_autoincr_block = (1 << 12);
+
+       /* Cortex-M3/M4 has 4096 bytes autoincrement range
+        * but set a safe default to 1024 to support Cortex-M0
+        * this will be changed in cortex_m3_examine if a M3/M4 is detected */
+       armv7m->dap.tar_autoincr_block = (1 << 10);
 
        /* register arch-specific functions */
        armv7m->examine_debug_reason = cortex_m3_examine_debug_reason;
@@ -2005,7 +2041,7 @@ COMMAND_HANDLER(handle_cortex_m3_vector_catch_command)
        struct target *target = get_current_target(CMD_CTX);
        struct cortex_m3_common *cortex_m3 = target_to_cm3(target);
        struct armv7m_common *armv7m = &cortex_m3->armv7m;
-       struct adiv5_dap *swjdp = &armv7m->dap;
+       struct adiv5_dap *swjdp = armv7m->arm.dap;
        uint32_t demcr = 0;
        int retval;
 

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)