X-Git-Url: https://review.openocd.org/gitweb?p=openocd.git;a=blobdiff_plain;f=src%2Ftarget%2Fcortex_m.c;h=11dbf24f28eb871fffd7ed05ebfb6875a37acd53;hp=012a1a6855088562a3e3ccd4f6b0c69f1930683f;hb=02df0abb547a71e34f7b5bee8ffbc4ded44572de;hpb=d0e763ac7ef6aa17b17bd00ccdfbccfb4eacda69 diff --git a/src/target/cortex_m.c b/src/target/cortex_m.c index 012a1a6855..11dbf24f28 100644 --- a/src/target/cortex_m.c +++ b/src/target/cortex_m.c @@ -242,7 +242,7 @@ static int cortex_m_endreset_event(struct target *target) if (retval != ERROR_OK) return retval; if (!(cortex_m->dcb_dhcsr & C_DEBUGEN)) { - retval = mem_ap_write_u32(armv7m->debug_ap, DCB_DHCSR, DBGKEY | C_DEBUGEN); + retval = cortex_m_write_debug_halt_mask(target, 0, C_HALT | C_STEP | C_MASKINTS); if (retval != ERROR_OK) return retval; } @@ -682,7 +682,7 @@ void cortex_m_enable_breakpoints(struct target *target) } static int cortex_m_resume(struct target *target, int current, - uint32_t address, int handle_breakpoints, int debug_execution) + target_addr_t address, int handle_breakpoints, int debug_execution) { struct armv7m_common *armv7m = target_to_armv7m(target); struct breakpoint *breakpoint = NULL; @@ -750,7 +750,7 @@ static int cortex_m_resume(struct target *target, int current, /* Single step past breakpoint at current address */ breakpoint = breakpoint_find(target, resume_pc); if (breakpoint) { - LOG_DEBUG("unset breakpoint at 0x%8.8" PRIx32 " (ID: %" PRIu32 ")", + LOG_DEBUG("unset breakpoint at " TARGET_ADDR_FMT " (ID: %" PRIu32 ")", breakpoint->address, breakpoint->unique_id); cortex_m_unset_breakpoint(target, breakpoint); @@ -782,7 +782,7 @@ static int cortex_m_resume(struct target *target, int current, /* int irqstepcount = 0; */ static int cortex_m_step(struct target *target, int current, - uint32_t address, int handle_breakpoints) + target_addr_t address, int handle_breakpoints) { struct cortex_m_common *cortex_m = target_to_cm(target); struct armv7m_common *armv7m = &cortex_m->armv7m; @@ -981,6 +981,18 @@ static int cortex_m_assert_reset(struct target *target) bool srst_asserted = false; + if (!target_was_examined(target)) { + if (jtag_reset_config & RESET_HAS_SRST) { + adapter_assert_reset(); + if (target->reset_halt) + LOG_ERROR("Target not examined, will not halt after reset!"); + return ERROR_OK; + } else { + LOG_ERROR("Target not examined, reset NOT asserted!"); + return ERROR_FAIL; + } + } + if ((jtag_reset_config & RESET_HAS_SRST) && (jtag_reset_config & RESET_SRST_NO_GATING)) { adapter_assert_reset(); @@ -993,12 +1005,12 @@ static int cortex_m_assert_reset(struct target *target) /* Store important errors instead of failing and proceed to reset assert */ if (retval != ERROR_OK || !(cortex_m->dcb_dhcsr & C_DEBUGEN)) - retval = mem_ap_write_u32(armv7m->debug_ap, DCB_DHCSR, DBGKEY | C_DEBUGEN); + retval = cortex_m_write_debug_halt_mask(target, 0, C_HALT | C_STEP | C_MASKINTS); /* If the processor is sleeping in a WFI or WFE instruction, the * C_HALT bit must be asserted to regain control */ if (retval == ERROR_OK && (cortex_m->dcb_dhcsr & S_SLEEP)) - retval = mem_ap_write_u32(armv7m->debug_ap, DCB_DHCSR, DBGKEY | C_HALT | C_DEBUGEN); + retval = cortex_m_write_debug_halt_mask(target, C_HALT, 0); mem_ap_write_u32(armv7m->debug_ap, DCB_DCRDR, 0); /* Ignore less important errors */ @@ -1006,8 +1018,7 @@ static int cortex_m_assert_reset(struct target *target) if (!target->reset_halt) { /* Set/Clear C_MASKINTS in a separate operation */ if (cortex_m->dcb_dhcsr & C_MASKINTS) - mem_ap_write_atomic_u32(armv7m->debug_ap, DCB_DHCSR, - DBGKEY | C_DEBUGEN | C_HALT); + cortex_m_write_debug_halt_mask(target, 0, C_MASKINTS); /* clear any debug flags before resuming */ cortex_m_clear_halt(target); @@ -1101,7 +1112,8 @@ static int cortex_m_deassert_reset(struct target *target) enum reset_types jtag_reset_config = jtag_get_reset_config(); if ((jtag_reset_config & RESET_HAS_SRST) && - !(jtag_reset_config & RESET_SRST_NO_GATING)) { + !(jtag_reset_config & RESET_SRST_NO_GATING) && + target_was_examined(target)) { int retval = dap_dp_init(armv7m->debug_ap->dap); if (retval != ERROR_OK) { LOG_ERROR("DP initialisation failed"); @@ -1185,7 +1197,7 @@ int cortex_m_set_breakpoint(struct target *target, struct breakpoint *breakpoint breakpoint->set = true; } - LOG_DEBUG("BPID: %" PRIu32 ", Type: %d, Address: 0x%08" PRIx32 " Length: %d (set=%d)", + LOG_DEBUG("BPID: %" PRIu32 ", Type: %d, Address: " TARGET_ADDR_FMT " Length: %d (set=%d)", breakpoint->unique_id, (int)(breakpoint->type), breakpoint->address, @@ -1206,7 +1218,7 @@ int cortex_m_unset_breakpoint(struct target *target, struct breakpoint *breakpoi return ERROR_OK; } - LOG_DEBUG("BPID: %" PRIu32 ", Type: %d, Address: 0x%08" PRIx32 " Length: %d (set=%d)", + LOG_DEBUG("BPID: %" PRIu32 ", Type: %d, Address: " TARGET_ADDR_FMT " Length: %d (set=%d)", breakpoint->unique_id, (int)(breakpoint->type), breakpoint->address, @@ -1651,7 +1663,7 @@ static int cortex_m_store_core_reg_u32(struct target *target, return ERROR_OK; } -static int cortex_m_read_memory(struct target *target, uint32_t address, +static int cortex_m_read_memory(struct target *target, target_addr_t address, uint32_t size, uint32_t count, uint8_t *buffer) { struct armv7m_common *armv7m = target_to_armv7m(target); @@ -1665,7 +1677,7 @@ static int cortex_m_read_memory(struct target *target, uint32_t address, return mem_ap_read_buf(armv7m->debug_ap, buffer, size, count, address); } -static int cortex_m_write_memory(struct target *target, uint32_t address, +static int cortex_m_write_memory(struct target *target, target_addr_t address, uint32_t size, uint32_t count, const uint8_t *buffer) { struct armv7m_common *armv7m = target_to_armv7m(target); @@ -1683,6 +1695,7 @@ static int cortex_m_init_target(struct command_context *cmd_ctx, struct target *target) { armv7m_build_reg_cache(target); + arm_semihosting_init(target); return ERROR_OK; } @@ -1695,6 +1708,7 @@ void cortex_m_deinit_target(struct target *target) cortex_m_dwt_free(target); armv7m_free_reg_cache(target); + free(target->private_config); free(cortex_m); } @@ -1875,6 +1889,11 @@ static void cortex_m_dwt_free(struct target *target) #define MVFR0_DEFAULT_M4 0x10110021 #define MVFR1_DEFAULT_M4 0x11000011 +#define MVFR0_DEFAULT_M7_SP 0x10110021 +#define MVFR0_DEFAULT_M7_DP 0x10110221 +#define MVFR1_DEFAULT_M7_SP 0x11000011 +#define MVFR1_DEFAULT_M7_DP 0x12000011 + int cortex_m_examine(struct target *target) { int retval; @@ -1893,11 +1912,15 @@ int cortex_m_examine(struct target *target) return retval; } - /* Search for the MEM-AP */ - retval = dap_find_ap(swjdp, AP_TYPE_AHB_AP, &armv7m->debug_ap); - if (retval != ERROR_OK) { - LOG_ERROR("Could not find MEM-AP to control the core"); - return retval; + if (cortex_m->apsel < 0) { + /* Search for the MEM-AP */ + retval = dap_find_ap(swjdp, AP_TYPE_AHB_AP, &armv7m->debug_ap); + if (retval != ERROR_OK) { + LOG_ERROR("Could not find MEM-AP to control the core"); + return retval; + } + } else { + armv7m->debug_ap = dap_ap(swjdp, cortex_m->apsel); } /* Leave (only) generic DAP stuff for debugport_init(); */ @@ -1930,21 +1953,33 @@ int cortex_m_examine(struct target *target) } LOG_DEBUG("cpuid: 0x%8.8" PRIx32 "", cpuid); - /* test for floating point feature on Cortex-M4 */ if (i == 4) { target_read_u32(target, MVFR0, &mvfr0); target_read_u32(target, MVFR1, &mvfr1); + /* 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; } + } else if (i == 7) { + 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; + } 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; + } } else if (i == 0) { /* Cortex-M0 does not support unaligned memory access */ armv7m->arm.is_armv6m = true; } - if (armv7m->fp_feature != FPv4_SP && + if (armv7m->fp_feature == FP_NONE && armv7m->arm.core_cache->num_regs > ARMV7M_NUM_CORE_REGS_NOFP) { /* free unavailable FPU registers */ size_t idx; @@ -1959,9 +1994,14 @@ int cortex_m_examine(struct target *target) armv7m->arm.core_cache->num_regs = ARMV7M_NUM_CORE_REGS_NOFP; } - if ((i == 4 || i == 3) && !armv7m->stlink) { - /* Cortex-M3/M4 has 4096 bytes autoincrement range */ - armv7m->debug_ap->tar_autoincr_block = (1 << 12); + if (!armv7m->stlink) { + if (i == 3 || i == 4) + /* Cortex-M3/M4 have 4096 bytes autoincrement range, + * s. ARM IHI 0031C: MEM-AP 7.2.2 */ + armv7m->debug_ap->tar_autoincr_block = (1 << 12); + else if (i == 7) + /* Cortex-M7 has only 1024 bytes autoincrement range */ + armv7m->debug_ap->tar_autoincr_block = (1 << 10); } /* Configure trace modules */ @@ -2144,6 +2184,13 @@ static int cortex_m_target_create(struct target *target, Jim_Interp *interp) cortex_m->common_magic = CORTEX_M_COMMON_MAGIC; cortex_m_init_arch_info(target, cortex_m, target->tap); + if (target->private_config != NULL) { + struct adiv5_private_config *pc = + (struct adiv5_private_config *)target->private_config; + cortex_m->apsel = pc->ap_num; + } else + cortex_m->apsel = -1; + return ERROR_OK; } @@ -2405,6 +2452,7 @@ struct target_type cortexm_target = { .commands = cortex_m_command_handlers, .target_create = cortex_m_target_create, + .target_jim_configure = adiv5_jim_configure, .init_target = cortex_m_init_target, .examine = cortex_m_examine, .deinit_target = cortex_m_deinit_target,