target/armv7m: change FPv4_SP and FPv5_SP/DP identifiers to uppercase
[fw/openocd] / src / target / cortex_m.c
index ed9397aef0f6e0ff714d168fb91036f3b3411f5c..e7a2fadda744ce30d6c6207eb4fcb0091da695ff 100644 (file)
@@ -39,6 +39,7 @@
 #include "arm_opcodes.h"
 #include "arm_semihosting.h"
 #include <helper/time_support.h>
+#include <rtt/rtt.h>
 
 /* NOTE:  most of this should work fine for the Cortex-M1 and
  * Cortex-M0 cores too, although they're ARMv6-M not ARMv7-M.
@@ -56,8 +57,8 @@ static int cortex_m_store_core_reg_u32(struct target *target,
                uint32_t num, uint32_t value);
 static void cortex_m_dwt_free(struct target *target);
 
-static int cortexm_dap_read_coreregister_u32(struct target *target,
-       uint32_t *value, int regnum)
+static int cortex_m_load_core_reg_u32(struct target *target,
+               uint32_t regsel, uint32_t *value)
 {
        struct armv7m_common *armv7m = target_to_armv7m(target);
        int retval;
@@ -71,7 +72,7 @@ static int cortexm_dap_read_coreregister_u32(struct target *target,
                        return retval;
        }
 
-       retval = mem_ap_write_u32(armv7m->debug_ap, DCB_DCRSR, regnum);
+       retval = mem_ap_write_u32(armv7m->debug_ap, DCB_DCRSR, regsel);
        if (retval != ERROR_OK)
                return retval;
 
@@ -89,8 +90,8 @@ static int cortexm_dap_read_coreregister_u32(struct target *target,
        return retval;
 }
 
-static int cortexm_dap_write_coreregister_u32(struct target *target,
-       uint32_t value, int regnum)
+static int cortex_m_store_core_reg_u32(struct target *target,
+               uint32_t regsel, uint32_t value)
 {
        struct armv7m_common *armv7m = target_to_armv7m(target);
        int retval;
@@ -108,12 +109,12 @@ static int cortexm_dap_write_coreregister_u32(struct target *target,
        if (retval != ERROR_OK)
                return retval;
 
-       retval = mem_ap_write_atomic_u32(armv7m->debug_ap, DCB_DCRSR, regnum | DCRSR_WnR);
+       retval = mem_ap_write_atomic_u32(armv7m->debug_ap, DCB_DCRSR, regsel | DCRSR_WnR);
        if (retval != ERROR_OK)
                return retval;
 
        if (target->dbg_msg_enabled) {
-               /* restore DCB_DCRDR - this needs to be in a seperate
+               /* restore DCB_DCRDR - this needs to be in a separate
                 * transaction otherwise the emulated DCC channel breaks */
                if (retval == ERROR_OK)
                        retval = mem_ap_write_atomic_u32(armv7m->debug_ap, DCB_DCRDR, dcrdr);
@@ -129,7 +130,7 @@ static int cortex_m_write_debug_halt_mask(struct target *target,
        struct armv7m_common *armv7m = &cortex_m->armv7m;
 
        /* mask off status bits */
-       cortex_m->dcb_dhcsr &= ~((0xFFFF << 16) | mask_off);
+       cortex_m->dcb_dhcsr &= ~((0xFFFFul << 16) | mask_off);
        /* create new register mask */
        cortex_m->dcb_dhcsr |= DBGKEY | C_DEBUGEN | mask_on;
 
@@ -445,6 +446,14 @@ static int cortex_m_examine_exception_reason(struct target *target)
                        if (retval != ERROR_OK)
                                return retval;
                        break;
+               case 7: /* Secure Fault */
+                       retval = mem_ap_read_u32(armv7m->debug_ap, NVIC_SFSR, &except_sr);
+                       if (retval != ERROR_OK)
+                               return retval;
+                       retval = mem_ap_read_u32(armv7m->debug_ap, NVIC_SFAR, &except_ar);
+                       if (retval != ERROR_OK)
+                               return retval;
+                       break;
                case 11:        /* SVCall */
                        break;
                case 12:        /* Debug Monitor */
@@ -494,25 +503,31 @@ static int cortex_m_debug_entry(struct target *target)
        if (retval != ERROR_OK)
                return retval;
 
+       /* examine PE security state */
+       bool secure_state = false;
+       if (armv7m->arm.is_armv8m) {
+               uint32_t dscsr;
+
+               retval = mem_ap_read_u32(armv7m->debug_ap, DCB_DSCSR, &dscsr);
+               if (retval != ERROR_OK)
+                       return retval;
+
+               secure_state = (dscsr & DSCSR_CDS) == DSCSR_CDS;
+       }
+
        /* Examine target state and mode
         * First load register accessible through core debug port */
        int num_regs = arm->core_cache->num_regs;
 
        for (i = 0; i < num_regs; i++) {
                r = &armv7m->arm.core_cache->reg_list[i];
-               if (!r->valid)
+               if (r->exist && !r->valid)
                        arm->read_core_reg(target, r, i, ARM_MODE_ANY);
        }
 
        r = arm->cpsr;
        xPSR = buf_get_u32(r->value, 0, 32);
 
-       /* For IT instructions xPSR must be reloaded on resume and clear on debug exec */
-       if (xPSR & 0xf00) {
-               r->dirty = r->valid;
-               cortex_m_store_core_reg_u32(target, 16, xPSR & ~0xff);
-       }
-
        /* Are we in an exception handler */
        if (xPSR & 0x1FF) {
                armv7m->exception_number = (xPSR & 0x1FF);
@@ -521,7 +536,7 @@ static int cortex_m_debug_entry(struct target *target)
                arm->map = armv7m_msp_reg_map;
        } else {
                unsigned control = buf_get_u32(arm->core_cache
-                               ->reg_list[ARMV7M_CONTROL].value, 0, 2);
+                               ->reg_list[ARMV7M_CONTROL].value, 0, 3);
 
                /* is this thread privileged? */
                arm->core_mode = control & 1
@@ -540,9 +555,10 @@ static int cortex_m_debug_entry(struct target *target)
        if (armv7m->exception_number)
                cortex_m_examine_exception_reason(target);
 
-       LOG_DEBUG("entered debug state in core mode: %s at PC 0x%" PRIx32 ", target->state: %s",
+       LOG_DEBUG("entered debug state in core mode: %s at PC 0x%" PRIx32 ", cpu in %s state, target->state: %s",
                arm_mode_name(arm->core_mode),
                buf_get_u32(arm->pc->value, 0, 32),
+               secure_state ? "Secure" : "Non-Secure",
                target_state_name(target));
 
        if (armv7m->post_debug_entry) {
@@ -635,13 +651,9 @@ static int cortex_m_poll(struct target *target)
                }
        }
 
-       /* REVISIT when S_SLEEP is set, it's in a Sleep or DeepSleep state.
-        * How best to model low power modes?
-        */
-
        if (target->state == TARGET_UNKNOWN) {
-               /* check if processor is retiring instructions */
-               if (cortex_m->dcb_dhcsr & S_RETIRE_ST) {
+               /* check if processor is retiring instructions or sleeping */
+               if (cortex_m->dcb_dhcsr & S_RETIRE_ST || cortex_m->dcb_dhcsr & S_SLEEP) {
                        target->state = TARGET_RUNNING;
                        retval = ERROR_OK;
                }
@@ -710,11 +722,16 @@ static int cortex_m_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
+       /* on single cortex_m MCU soft_reset_halt should be avoided as same functionality
+        * can be obtained by using 'reset halt' and 'cortex_m reset_config vectreset'.
+        * As this reset only uses 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.");
+       LOG_DEBUG("soft_reset_halt is discouraged, please use 'reset halt' instead.");
+
+       /* Set C_DEBUGEN */
+       retval = cortex_m_write_debug_halt_mask(target, 0, C_STEP | C_MASKINTS);
+       if (retval != ERROR_OK)
+               return retval;
 
        /* Enter debug state on reset; restore DEMCR in endreset_event() */
        retval = mem_ap_write_u32(armv7m->debug_ap, DCB_DEMCR,
@@ -801,15 +818,19 @@ static int cortex_m_resume(struct target *target, int current,
                 * in parallel with disabled interrupts can cause local faults
                 * to not be taken.
                 *
-                * REVISIT this clearly breaks non-debug execution, since the
-                * PRIMASK register state isn't saved/restored...  workaround
-                * by never resuming app code after debug execution.
+                * This breaks non-debug (application) execution if not
+                * called from armv7m_start_algorithm() which saves registers.
                 */
                buf_set_u32(r->value, 0, 1, 1);
                r->dirty = true;
                r->valid = true;
 
-               /* Make sure we are in Thumb mode */
+               /* Make sure we are in Thumb mode, set xPSR.T bit */
+               /* armv7m_start_algorithm() initializes entire xPSR register.
+                * This duplicity handles the case when cortex_m_resume()
+                * is used with the debug_execution flag directly,
+                * not called through armv7m_start_algorithm().
+                */
                r = armv7m->arm.cpsr;
                buf_set_u32(r->value, 24, 1, 1);
                r->dirty = true;
@@ -914,7 +935,7 @@ static int cortex_m_step(struct target *target, int current,
         * a normal step, otherwise we have to manually step over the bkpt
         * instruction - as such simulate a step */
        if (bkpt_inst_found == false) {
-               if ((cortex_m->isrmasking_mode != CORTEX_M_ISRMASK_AUTO)) {
+               if (cortex_m->isrmasking_mode != CORTEX_M_ISRMASK_AUTO) {
                        /* Automatic ISR masking mode off: Just step over the next
                         * instruction, with interrupts on or off as appropriate. */
                        cortex_m_set_maskints_for_step(target);
@@ -946,7 +967,7 @@ static int cortex_m_step(struct target *target, int current,
                         * just step over the instruction with interrupts disabled.
                         *
                         * The documentation has no information about this, it was found by observation
-                        * on STM32F1 and STM32F2. Proper explanation welcome. STM32F0 dosen't seem to
+                        * on STM32F1 and STM32F2. Proper explanation welcome. STM32F0 doesn't seem to
                         * suffer from this problem.
                         *
                         * To add some confusion: pc_value has bit 0 always set, while the breakpoint
@@ -961,8 +982,7 @@ static int cortex_m_step(struct target *target, int current,
                                /* Re-enable interrupts if appropriate */
                                cortex_m_write_debug_halt_mask(target, C_HALT, 0);
                                cortex_m_set_maskints_for_halt(target);
-                       }
-                       else {
+                       } else {
 
                                /* Set a temporary break point */
                                if (breakpoint) {
@@ -1183,11 +1203,13 @@ static int cortex_m_assert_reset(struct target *target)
                if (retval3 != ERROR_OK)
                        LOG_DEBUG("Ignoring AP write error right after reset");
 
-               retval3 = dap_dp_init(armv7m->debug_ap->dap);
-               if (retval3 != ERROR_OK)
+               retval3 = dap_dp_init_or_reconnect(armv7m->debug_ap->dap);
+               if (retval3 != ERROR_OK) {
                        LOG_ERROR("DP initialisation failed");
-
-               else {
+                       /* The error return value must not be propagated in this case.
+                        * SYSRESETREQ or VECTRESET have been possibly triggered
+                        * so reset processing should continue */
+               } else {
                        /* I do not know why this is necessary, but it
                         * fixes strange effects (step/resume cause NMI
                         * after reset) on LM3S6918 -- Michael Schwingen
@@ -1230,7 +1252,8 @@ static int cortex_m_deassert_reset(struct target *target)
        if ((jtag_reset_config & RESET_HAS_SRST) &&
            !(jtag_reset_config & RESET_SRST_NO_GATING) &&
                target_was_examined(target)) {
-               int retval = dap_dp_init(armv7m->debug_ap->dap);
+
+               int retval = dap_dp_init_or_reconnect(armv7m->debug_ap->dap);
                if (retval != ERROR_OK) {
                        LOG_ERROR("DP initialisation failed");
                        return retval;
@@ -1388,7 +1411,7 @@ int cortex_m_remove_breakpoint(struct target *target, struct breakpoint *breakpo
        return cortex_m_unset_breakpoint(target, breakpoint);
 }
 
-int cortex_m_set_watchpoint(struct target *target, struct watchpoint *watchpoint)
+static int cortex_m_set_watchpoint(struct target *target, struct watchpoint *watchpoint)
 {
        int dwt_num = 0;
        struct cortex_m_common *cortex_m = target_to_cm(target);
@@ -1471,7 +1494,7 @@ int cortex_m_set_watchpoint(struct target *target, struct watchpoint *watchpoint
        return ERROR_OK;
 }
 
-int cortex_m_unset_watchpoint(struct target *target, struct watchpoint *watchpoint)
+static int cortex_m_unset_watchpoint(struct target *target, struct watchpoint *watchpoint)
 {
        struct cortex_m_common *cortex_m = target_to_cm(target);
        struct cortex_m_dwt_comparator *comparator;
@@ -1585,176 +1608,6 @@ void cortex_m_enable_watchpoints(struct target *target)
        }
 }
 
-static int cortex_m_load_core_reg_u32(struct target *target,
-               uint32_t num, uint32_t *value)
-{
-       int retval;
-
-       /* 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.
-        */
-       switch (num) {
-               case 0 ... 18:
-                       /* read a normal core register */
-                       retval = cortexm_dap_read_coreregister_u32(target, value, num);
-
-                       if (retval != ERROR_OK) {
-                               LOG_ERROR("JTAG failure %i", retval);
-                               return ERROR_JTAG_DEVICE_ERROR;
-                       }
-                       LOG_DEBUG("load from core reg %i  value 0x%" PRIx32 "", (int)num, *value);
-                       break;
-
-               case ARMV7M_FPSCR:
-                       /* Floating-point Status and Registers */
-                       retval = target_write_u32(target, DCB_DCRSR, 0x21);
-                       if (retval != ERROR_OK)
-                               return retval;
-                       retval = target_read_u32(target, DCB_DCRDR, value);
-                       if (retval != ERROR_OK)
-                               return retval;
-                       LOG_DEBUG("load from FPSCR  value 0x%" PRIx32, *value);
-                       break;
-
-               case ARMV7M_S0 ... ARMV7M_S31:
-                       /* Floating-point Status and Registers */
-                       retval = target_write_u32(target, DCB_DCRSR, num - ARMV7M_S0 + 0x40);
-                       if (retval != ERROR_OK)
-                               return retval;
-                       retval = target_read_u32(target, DCB_DCRDR, value);
-                       if (retval != ERROR_OK)
-                               return retval;
-                       LOG_DEBUG("load from FPU reg S%d  value 0x%" PRIx32,
-                                 (int)(num - ARMV7M_S0), *value);
-                       break;
-
-               case ARMV7M_PRIMASK:
-               case ARMV7M_BASEPRI:
-               case ARMV7M_FAULTMASK:
-               case ARMV7M_CONTROL:
-                       /* Cortex-M3 packages these four registers as bitfields
-                        * in one Debug Core register.  So say r0 and r2 docs;
-                        * it was removed from r1 docs, but still works.
-                        */
-                       cortexm_dap_read_coreregister_u32(target, value, 20);
-
-                       switch (num) {
-                               case ARMV7M_PRIMASK:
-                                       *value = buf_get_u32((uint8_t *)value, 0, 1);
-                                       break;
-
-                               case ARMV7M_BASEPRI:
-                                       *value = buf_get_u32((uint8_t *)value, 8, 8);
-                                       break;
-
-                               case ARMV7M_FAULTMASK:
-                                       *value = buf_get_u32((uint8_t *)value, 16, 1);
-                                       break;
-
-                               case ARMV7M_CONTROL:
-                                       *value = buf_get_u32((uint8_t *)value, 24, 2);
-                                       break;
-                       }
-
-                       LOG_DEBUG("load from special reg %i value 0x%" PRIx32 "", (int)num, *value);
-                       break;
-
-               default:
-                       return ERROR_COMMAND_SYNTAX_ERROR;
-       }
-
-       return ERROR_OK;
-}
-
-static int cortex_m_store_core_reg_u32(struct target *target,
-               uint32_t num, uint32_t value)
-{
-       int retval;
-       uint32_t reg;
-       struct armv7m_common *armv7m = target_to_armv7m(target);
-
-       /* 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.
-        */
-       switch (num) {
-               case 0 ... 18:
-                       retval = cortexm_dap_write_coreregister_u32(target, value, num);
-                       if (retval != ERROR_OK) {
-                               struct reg *r;
-
-                               LOG_ERROR("JTAG failure");
-                               r = armv7m->arm.core_cache->reg_list + num;
-                               r->dirty = r->valid;
-                               return ERROR_JTAG_DEVICE_ERROR;
-                       }
-                       LOG_DEBUG("write core reg %i value 0x%" PRIx32 "", (int)num, value);
-                       break;
-
-               case ARMV7M_FPSCR:
-                       /* Floating-point Status and Registers */
-                       retval = target_write_u32(target, DCB_DCRDR, value);
-                       if (retval != ERROR_OK)
-                               return retval;
-                       retval = target_write_u32(target, DCB_DCRSR, 0x21 | (1<<16));
-                       if (retval != ERROR_OK)
-                               return retval;
-                       LOG_DEBUG("write FPSCR value 0x%" PRIx32, value);
-                       break;
-
-               case ARMV7M_S0 ... ARMV7M_S31:
-                       /* Floating-point Status and Registers */
-                       retval = target_write_u32(target, DCB_DCRDR, value);
-                       if (retval != ERROR_OK)
-                               return retval;
-                       retval = target_write_u32(target, DCB_DCRSR, (num - ARMV7M_S0 + 0x40) | (1<<16));
-                       if (retval != ERROR_OK)
-                               return retval;
-                       LOG_DEBUG("write FPU reg S%d  value 0x%" PRIx32,
-                                 (int)(num - ARMV7M_S0), value);
-                       break;
-
-               case ARMV7M_PRIMASK:
-               case ARMV7M_BASEPRI:
-               case ARMV7M_FAULTMASK:
-               case ARMV7M_CONTROL:
-                       /* Cortex-M3 packages these four registers as bitfields
-                        * in one Debug Core register.  So say r0 and r2 docs;
-                        * it was removed from r1 docs, but still works.
-                        */
-                       cortexm_dap_read_coreregister_u32(target, &reg, 20);
-
-                       switch (num) {
-                               case ARMV7M_PRIMASK:
-                                       buf_set_u32((uint8_t *)&reg, 0, 1, value);
-                                       break;
-
-                               case ARMV7M_BASEPRI:
-                                       buf_set_u32((uint8_t *)&reg, 8, 8, value);
-                                       break;
-
-                               case ARMV7M_FAULTMASK:
-                                       buf_set_u32((uint8_t *)&reg, 16, 1, value);
-                                       break;
-
-                               case ARMV7M_CONTROL:
-                                       buf_set_u32((uint8_t *)&reg, 24, 2, value);
-                                       break;
-                       }
-
-                       cortexm_dap_write_coreregister_u32(target, reg, 20);
-
-                       LOG_DEBUG("write special reg %i value 0x%" PRIx32 " ", (int)num, value);
-                       break;
-
-               default:
-                       return ERROR_COMMAND_SYNTAX_ERROR;
-       }
-
-       return ERROR_OK;
-}
-
 static int cortex_m_read_memory(struct target *target, target_addr_t address,
        uint32_t size, uint32_t count, uint8_t *buffer)
 {
@@ -1810,28 +1663,23 @@ int cortex_m_profiling(struct target *target, uint32_t *samples,
        struct timeval timeout, now;
        struct armv7m_common *armv7m = target_to_armv7m(target);
        uint32_t reg_value;
-       bool use_pcsr = false;
-       int retval = ERROR_OK;
-       struct reg *reg;
-
-       gettimeofday(&timeout, NULL);
-       timeval_add_time(&timeout, seconds, 0);
+       int retval;
 
        retval = target_read_u32(target, DWT_PCSR, &reg_value);
        if (retval != ERROR_OK) {
                LOG_ERROR("Error while reading PCSR");
                return retval;
        }
-
-       if (reg_value != 0) {
-               use_pcsr = true;
-               LOG_INFO("Starting Cortex-M profiling. Sampling DWT_PCSR as fast as we can...");
-       } else {
-               LOG_INFO("Starting profiling. Halting and resuming the"
-                        " target as often as we can...");
-               reg = register_get_by_name(target->reg_cache, "pc", 1);
+       if (reg_value == 0) {
+               LOG_INFO("PCSR sampling not supported on this processor.");
+               return target_profiling_default(target, samples, max_num_samples, num_samples, seconds);
        }
 
+       gettimeofday(&timeout, NULL);
+       timeval_add_time(&timeout, seconds, 0);
+
+       LOG_INFO("Starting Cortex-M profiling. Sampling DWT_PCSR as fast as we can...");
+
        /* Make sure the target is running */
        target_poll(target);
        if (target->state == TARGET_HALTED)
@@ -1845,40 +1693,21 @@ int cortex_m_profiling(struct target *target, uint32_t *samples,
        uint32_t sample_count = 0;
 
        for (;;) {
-               if (use_pcsr) {
-                       if (armv7m && armv7m->debug_ap) {
-                               uint32_t read_count = max_num_samples - sample_count;
-                               if (read_count > 1024)
-                                       read_count = 1024;
-
-                               retval = mem_ap_read_buf_noincr(armv7m->debug_ap,
-                                                       (void *)&samples[sample_count],
-                                                       4, read_count, DWT_PCSR);
-                               sample_count += read_count;
-                       } else {
-                               target_read_u32(target, DWT_PCSR, &samples[sample_count++]);
-                       }
+               if (armv7m && armv7m->debug_ap) {
+                       uint32_t read_count = max_num_samples - sample_count;
+                       if (read_count > 1024)
+                               read_count = 1024;
+
+                       retval = mem_ap_read_buf_noincr(armv7m->debug_ap,
+                                               (void *)&samples[sample_count],
+                                               4, read_count, DWT_PCSR);
+                       sample_count += read_count;
                } else {
-                       target_poll(target);
-                       if (target->state == TARGET_HALTED) {
-                               reg_value = buf_get_u32(reg->value, 0, 32);
-                               /* current pc, addr = 0, do not handle breakpoints, not debugging */
-                               retval = target_resume(target, 1, 0, 0, 0);
-                               samples[sample_count++] = reg_value;
-                               target_poll(target);
-                               alive_sleep(10); /* sleep 10ms, i.e. <100 samples/second. */
-                       } else if (target->state == TARGET_RUNNING) {
-                               /* We want to quickly sample the PC. */
-                               retval = target_halt(target);
-                       } else {
-                               LOG_INFO("Target not halted or running");
-                               retval = ERROR_OK;
-                               break;
-                       }
+                       target_read_u32(target, DWT_PCSR, &samples[sample_count++]);
                }
 
                if (retval != ERROR_OK) {
-                       LOG_ERROR("Error while reading %s", use_pcsr ? "PCSR" : "target pc");
+                       LOG_ERROR("Error while reading PCSR");
                        return retval;
                }
 
@@ -1975,7 +1804,7 @@ static void cortex_m_dwt_addreg(struct target *t, struct reg *r, const struct dw
 {
        struct dwt_reg_state *state;
 
-       state = calloc(1, sizeof *state);
+       state = calloc(1, sizeof(*state));
        if (!state)
                return;
        state->addr = d->addr;
@@ -1988,7 +1817,7 @@ static void cortex_m_dwt_addreg(struct target *t, struct reg *r, const struct dw
        r->type = &dwt_reg_type;
 }
 
-void cortex_m_dwt_setup(struct cortex_m_common *cm, struct target *target)
+static void cortex_m_dwt_setup(struct cortex_m_common *cm, struct target *target)
 {
        uint32_t dwtcr;
        struct reg_cache *cache;
@@ -2016,7 +1845,7 @@ fail0:
                return;
        }
 
-       cache = calloc(1, sizeof *cache);
+       cache = calloc(1, sizeof(*cache));
        if (!cache) {
 fail1:
                free(cm->dwt_comparator_list);
@@ -2024,7 +1853,7 @@ fail1:
        }
        cache->name = "Cortex-M DWT registers";
        cache->num_regs = 2 + cm->dwt_num_comp * 3;
-       cache->reg_list = calloc(cache->num_regs, sizeof *cache->reg_list);
+       cache->reg_list = calloc(cache->num_regs, sizeof(*cache->reg_list));
        if (!cache->reg_list) {
                free(cache);
                goto fail1;
@@ -2093,6 +1922,15 @@ static void cortex_m_dwt_free(struct target *target)
 #define MVFR1_DEFAULT_M7_SP 0x11000011
 #define MVFR1_DEFAULT_M7_DP 0x12000011
 
+static int cortex_m_find_mem_ap(struct adiv5_dap *swjdp,
+               struct adiv5_ap **debug_ap)
+{
+       if (dap_find_ap(swjdp, AP_TYPE_AHB3_AP, debug_ap) == ERROR_OK)
+               return ERROR_OK;
+
+       return dap_find_ap(swjdp, AP_TYPE_AHB5_AP, debug_ap);
+}
+
 int cortex_m_examine(struct target *target)
 {
        int retval;
@@ -2107,7 +1945,7 @@ int cortex_m_examine(struct target *target)
        if (!armv7m->stlink) {
                if (cortex_m->apsel == DP_APSEL_INVALID) {
                        /* Search for the MEM-AP */
-                       retval = dap_find_ap(swjdp, AP_TYPE_AHB3_AP, &armv7m->debug_ap);
+                       retval = cortex_m_find_mem_ap(swjdp, &armv7m->debug_ap);
                        if (retval != ERROR_OK) {
                                LOG_ERROR("Could not find MEM-AP to control the core");
                                return retval;
@@ -2135,16 +1973,24 @@ int cortex_m_examine(struct target *target)
                /* Get CPU Type */
                i = (cpuid >> 4) & 0xf;
 
+               /* Check if it is an ARMv8-M core */
+               armv7m->arm.is_armv8m = true;
+
                switch (cpuid & ARM_CPUID_PARTNO_MASK) {
                        case CORTEX_M23_PARTNO:
                                i = 23;
                                break;
-
                        case CORTEX_M33_PARTNO:
                                i = 33;
                                break;
-
+                       case CORTEX_M35P_PARTNO:
+                               i = 35;
+                               break;
+                       case CORTEX_M55_PARTNO:
+                               i = 55;
+                               break;
                        default:
+                               armv7m->arm.is_armv8m = false;
                                break;
                }
 
@@ -2163,8 +2009,8 @@ int cortex_m_examine(struct target *target)
                }
                LOG_DEBUG("cpuid: 0x%8.8" PRIx32 "", cpuid);
 
-               /* VECTRESET is not supported on Cortex-M0, M0+ and M1 */
-               cortex_m->vectreset_supported = i > 1;
+               /* VECTRESET is supported only on ARMv7-M cores */
+               cortex_m->vectreset_supported = !armv7m->arm.is_armv8m && !armv7m->arm.is_armv6m;
 
                if (i == 4) {
                        target_read_u32(target, MVFR0, &mvfr0);
@@ -2173,19 +2019,19 @@ int cortex_m_examine(struct target *target)
                        /* test for floating point feature on Cortex-M4 */
                        if ((mvfr0 == MVFR0_DEFAULT_M4) && (mvfr1 == MVFR1_DEFAULT_M4)) {
                                LOG_DEBUG("Cortex-M%d floating point feature FPv4_SP found", i);
-                               armv7m->fp_feature = FPv4_SP;
+                               armv7m->fp_feature = FPV4_SP;
                        }
-               } else if (i == 7 || i == 33) {
+               } else if (i == 7 || i == 33 || i == 35 || i == 55) {
                        target_read_u32(target, MVFR0, &mvfr0);
                        target_read_u32(target, MVFR1, &mvfr1);
 
                        /* test for floating point features on Cortex-M7 */
                        if ((mvfr0 == MVFR0_DEFAULT_M7_SP) && (mvfr1 == MVFR1_DEFAULT_M7_SP)) {
                                LOG_DEBUG("Cortex-M%d floating point feature FPv5_SP found", i);
-                               armv7m->fp_feature = FPv5_SP;
+                               armv7m->fp_feature = FPV5_SP;
                        } else if ((mvfr0 == MVFR0_DEFAULT_M7_DP) && (mvfr1 == MVFR1_DEFAULT_M7_DP)) {
                                LOG_DEBUG("Cortex-M%d floating point feature FPv5_DP found", i);
-                               armv7m->fp_feature = FPv5_DP;
+                               armv7m->fp_feature = FPV5_DP;
                        }
                } else if (i == 0) {
                        /* Cortex-M0 does not support unaligned memory access */
@@ -2200,7 +2046,6 @@ int cortex_m_examine(struct target *target)
                        for (idx = ARMV7M_NUM_CORE_REGS_NOFP;
                             idx < armv7m->arm.core_cache->num_regs;
                             idx++) {
-                               free(armv7m->arm.core_cache->reg_list[idx].value);
                                free(armv7m->arm.core_cache->reg_list[idx].feature);
                                free(armv7m->arm.core_cache->reg_list[idx].reg_data_type);
                        }
@@ -2217,15 +2062,26 @@ int cortex_m_examine(struct target *target)
                                armv7m->debug_ap->tar_autoincr_block = (1 << 10);
                }
 
+               /* Enable debug requests */
+               retval = target_read_u32(target, DCB_DHCSR, &cortex_m->dcb_dhcsr);
+               if (retval != ERROR_OK)
+                       return retval;
+               if (!(cortex_m->dcb_dhcsr & C_DEBUGEN)) {
+                       uint32_t dhcsr = (cortex_m->dcb_dhcsr | C_DEBUGEN) & ~(C_HALT | C_STEP | C_MASKINTS);
+
+                       retval = target_write_u32(target, DCB_DHCSR, DBGKEY | (dhcsr & 0x0000FFFFUL));
+                       if (retval != ERROR_OK)
+                               return retval;
+                       cortex_m->dcb_dhcsr = dhcsr;
+               }
+
                /* Configure trace modules */
                retval = target_write_u32(target, DCB_DEMCR, TRCENA | armv7m->demcr);
                if (retval != ERROR_OK)
                        return retval;
 
-               if (armv7m->trace_config.config_type != TRACE_CONFIG_TYPE_DISABLED) {
-                       armv7m_trace_tpiu_config(target);
+               if (armv7m->trace_config.itm_deferred_config)
                        armv7m_trace_itm_config(target);
-               }
 
                /* NOTE: FPB and DWT are both optional. */
 
@@ -2447,6 +2303,11 @@ COMMAND_HANDLER(handle_cortex_m_vector_catch_command)
        if (retval != ERROR_OK)
                return retval;
 
+       if (!target_was_examined(target)) {
+               LOG_ERROR("Target not examined yet");
+               return ERROR_FAIL;
+       }
+
        retval = mem_ap_read_atomic_u32(armv7m->debug_ap, DCB_DEMCR, &demcr);
        if (retval != ERROR_OK)
                return retval;
@@ -2620,6 +2481,11 @@ static const struct command_registration cortex_m_command_handlers[] = {
        {
                .chain = armv7m_trace_command_handlers,
        },
+       /* START_DEPRECATED_TPIU */
+       {
+               .chain = arm_tpiu_deprecated_command_handlers,
+       },
+       /* END_DEPRECATED_TPIU */
        {
                .name = "cortex_m",
                .mode = COMMAND_EXEC,
@@ -2627,12 +2493,14 @@ static const struct command_registration cortex_m_command_handlers[] = {
                .usage = "",
                .chain = cortex_m_exec_command_handlers,
        },
+       {
+               .chain = rtt_target_command_handlers,
+       },
        COMMAND_REGISTRATION_DONE
 };
 
 struct target_type cortexm_target = {
        .name = "cortex_m",
-       .deprecated_name = "cortex_m3",
 
        .poll = cortex_m_poll,
        .arch_state = armv7m_arch_state,