target: disable armv6m unaligned memory access
[fw/openocd] / src / target / cortex_m.c
index 488899cbe9430ac814db859efb9219bc2d0d38d5..e4374318aa1afb71a42a97f18cd60c8d356cde8f 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"
@@ -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.
@@ -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;
 }
@@ -1561,6 +1570,12 @@ static int cortex_m3_read_memory(struct target *target, uint32_t address,
        struct adiv5_dap *swjdp = &armv7m->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) {
@@ -1586,6 +1601,12 @@ static int cortex_m3_write_memory(struct target *target, uint32_t address,
        struct adiv5_dap *swjdp = &armv7m->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:
@@ -1771,9 +1792,13 @@ int cortex_m3_examine(struct target *target)
        struct adiv5_dap *swjdp = &cortex_m3->armv7m.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,9 @@ 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;
                }
 
                /* NOTE: FPB and DWT are both optional. */