X-Git-Url: https://review.openocd.org/gitweb?p=openocd.git;a=blobdiff_plain;f=src%2Ftarget%2Fcortex_m.c;h=9a1f2b16fee1adb2caaad68de9989b00ad41a77f;hp=ce3ab09c01928b90434af3057573992e21442348;hb=8105c46ba5d219345cc554fd958a65f4e26ae9ce;hpb=5b768b0d39e629b71b5d729fb6a6919cda342630 diff --git a/src/target/cortex_m.c b/src/target/cortex_m.c index ce3ab09c01..9a1f2b16fe 100644 --- a/src/target/cortex_m.c +++ b/src/target/cortex_m.c @@ -716,6 +716,11 @@ static int cortex_m_soft_reset_halt(struct target *target) * core, not the peripherals */ LOG_WARNING("soft_reset_halt is deprecated, 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, TRCENA | VC_HARDERR | VC_BUSERR | VC_CORERESET); @@ -914,7 +919,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); @@ -1198,7 +1203,7 @@ static int cortex_m_assert_reset(struct target *target) } target->state = TARGET_RESET; - jtag_add_sleep(50000); + jtag_sleep(50000); register_cache_invalidate(cortex_m->armv7m.arm.core_cache); @@ -1391,18 +1396,8 @@ int cortex_m_remove_breakpoint(struct target *target, struct breakpoint *breakpo int cortex_m_set_watchpoint(struct target *target, struct watchpoint *watchpoint) { int dwt_num = 0; - uint32_t mask, temp; struct cortex_m_common *cortex_m = target_to_cm(target); - /* watchpoint params were validated earlier */ - mask = 0; - temp = watchpoint->length; - while (temp) { - temp >>= 1; - mask++; - } - mask--; - /* REVISIT Don't fully trust these "not used" records ... users * may set up breakpoints by hand, e.g. dual-address data value * watchpoint using comparator #1; comparator #0 matching cycle @@ -1425,11 +1420,22 @@ int cortex_m_set_watchpoint(struct target *target, struct watchpoint *watchpoint target_write_u32(target, comparator->dwt_comparator_address + 0, comparator->comp); - comparator->mask = mask; - target_write_u32(target, comparator->dwt_comparator_address + 4, - comparator->mask); + if ((cortex_m->dwt_devarch & 0x1FFFFF) != DWT_DEVARCH_ARMV8M) { + uint32_t mask = 0, temp; - switch (watchpoint->rw) { + /* watchpoint params were validated earlier */ + temp = watchpoint->length; + while (temp) { + temp >>= 1; + mask++; + } + mask--; + + comparator->mask = mask; + target_write_u32(target, comparator->dwt_comparator_address + 4, + comparator->mask); + + switch (watchpoint->rw) { case WPT_READ: comparator->function = 5; break; @@ -1439,7 +1445,26 @@ int cortex_m_set_watchpoint(struct target *target, struct watchpoint *watchpoint case WPT_ACCESS: comparator->function = 7; break; + } + } else { + uint32_t data_size = watchpoint->length >> 1; + comparator->mask = (watchpoint->length >> 1) | 1; + + switch (watchpoint->rw) { + case WPT_ACCESS: + comparator->function = 4; + break; + case WPT_WRITE: + comparator->function = 5; + break; + case WPT_READ: + comparator->function = 6; + break; + } + comparator->function = comparator->function | (1 << 4) | + (data_size << 10); } + target_write_u32(target, comparator->dwt_comparator_address + 8, comparator->function); @@ -1982,6 +2007,9 @@ void cortex_m_dwt_setup(struct cortex_m_common *cm, struct target *target) return; } + target_read_u32(target, DWT_DEVARCH, &cm->dwt_devarch); + LOG_DEBUG("DWT_DEVARCH: 0x%" PRIx32, cm->dwt_devarch); + cm->dwt_num_comp = (dwtcr >> 28) & 0xF; cm->dwt_comp_available = cm->dwt_num_comp; cm->dwt_comparator_list = calloc(cm->dwt_num_comp, @@ -2070,6 +2098,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; @@ -2084,7 +2121,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_AHB_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; @@ -2112,6 +2149,20 @@ int cortex_m_examine(struct target *target) /* Get CPU Type */ i = (cpuid >> 4) & 0xf; + switch (cpuid & ARM_CPUID_PARTNO_MASK) { + case CORTEX_M23_PARTNO: + i = 23; + break; + + case CORTEX_M33_PARTNO: + i = 33; + break; + + default: + break; + } + + LOG_DEBUG("Cortex-M%d r%" PRId8 "p%" PRId8 " processor detected", i, (uint8_t)((cpuid >> 20) & 0xf), (uint8_t)((cpuid >> 0) & 0xf)); cortex_m->maskints_erratum = false; @@ -2138,7 +2189,7 @@ int cortex_m_examine(struct target *target) LOG_DEBUG("Cortex-M%d floating point feature FPv4_SP found", i); armv7m->fp_feature = FPv4_SP; } - } else if (i == 7) { + } else if (i == 7 || i == 33) { target_read_u32(target, MVFR0, &mvfr0); target_read_u32(target, MVFR1, &mvfr1);