X-Git-Url: https://review.openocd.org/gitweb?a=blobdiff_plain;f=src%2Ftarget%2Fstm32_stlink.c;h=1c755084749e150cc597264c926981e4b49c570c;hb=6d76fc13282311c6bb40a6d5f594ad955346ff5c;hp=baa6b7488cea60ee11b23044bb6749d037270f8b;hpb=033d1053ae42b913ff7100221628c0376e596d71;p=openocd.git diff --git a/src/target/stm32_stlink.c b/src/target/stm32_stlink.c index baa6b7488c..1c75508474 100644 --- a/src/target/stm32_stlink.c +++ b/src/target/stm32_stlink.c @@ -2,6 +2,9 @@ * Copyright (C) 2011 by Mathias Kuester * * Mathias Kuester * * * + * Copyright (C) 2011 by Spencer Oliver * + * spen@spen-soft.co.uk * + * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * @@ -17,11 +20,13 @@ * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ + #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "jtag/jtag.h" +#include "jtag/stlink/stlink_transport.h" #include "jtag/stlink/stlink_interface.h" #include "jtag/stlink/stlink_layout.h" #include "register.h" @@ -31,6 +36,10 @@ #include "target_type.h" #include "armv7m.h" #include "cortex_m.h" +#include "arm_semihosting.h" + +#define ARMV7M_SCS_DCRSR 0xe000edf4 +#define ARMV7M_SCS_DCRDR 0xe000edf8 static inline struct stlink_interface_s *target_to_stlink(struct target *target) { @@ -38,8 +47,8 @@ static inline struct stlink_interface_s *target_to_stlink(struct target *target) } static int stm32_stlink_load_core_reg_u32(struct target *target, - enum armv7m_regtype type, - uint32_t num, uint32_t *value) + enum armv7m_regtype type, + uint32_t num, uint32_t *value) { int retval; struct stlink_interface_s *stlink_if = target_to_stlink(target); @@ -53,15 +62,44 @@ static int stm32_stlink_load_core_reg_u32(struct target *target, switch (num) { case 0 ... 18: /* read a normal core register */ - retval = - stlink_if->layout->api->read_reg(stlink_if->fd, num, value); + retval = stlink_if->layout->api->read_reg(stlink_if->fd, num, value); 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); + LOG_DEBUG("load from core reg %i value 0x%" PRIx32 "", (int)num, *value); + break; + + case ARMV7M_FPSID: + case ARMV7M_FPEXC: + *value = 0; + break; + + case ARMV7M_FPSCR: + /* Floating-point Status and Registers */ + retval = target_write_u32(target, ARMV7M_SCS_DCRSR, 33); + if (retval != ERROR_OK) + return retval; + retval = target_read_u32(target, ARMV7M_SCS_DCRDR, value); + if (retval != ERROR_OK) + return retval; + LOG_DEBUG("load from core reg %i value 0x%" PRIx32 "", (int)num, *value); + break; + + case ARMV7M_S0 ... ARMV7M_S31: + /* Floating-point Status and Registers */ + retval = target_write_u32(target, ARMV7M_SCS_DCRSR, num-ARMV7M_S0+64); + if (retval != ERROR_OK) + return retval; + retval = target_read_u32(target, ARMV7M_SCS_DCRDR, value); + if (retval != ERROR_OK) + return retval; + LOG_DEBUG("load from core reg %i value 0x%" PRIx32 "", (int)num, *value); + break; + + case ARMV7M_D0 ... ARMV7M_D15: + value = 0; break; case ARMV7M_PRIMASK: @@ -72,8 +110,9 @@ static int stm32_stlink_load_core_reg_u32(struct target *target, * in one Debug Core register. So say r0 and r2 docs; * it was removed from r1 docs, but still works. */ - retval = - stlink_if->layout->api->read_reg(stlink_if->fd, 20, value); + retval = stlink_if->layout->api->read_reg(stlink_if->fd, 20, value); + if (retval != ERROR_OK) + return retval; switch (num) { case ARMV7M_PRIMASK: @@ -98,15 +137,15 @@ static int stm32_stlink_load_core_reg_u32(struct target *target, break; default: - return ERROR_INVALID_ARGUMENTS; + return ERROR_COMMAND_SYNTAX_ERROR; } return ERROR_OK; } static int stm32_stlink_store_core_reg_u32(struct target *target, - enum armv7m_regtype type, - uint32_t num, uint32_t value) + enum armv7m_regtype type, + uint32_t num, uint32_t value) { int retval; uint32_t reg; @@ -133,9 +172,7 @@ static int stm32_stlink_store_core_reg_u32(struct target *target, */ switch (num) { case 0 ... 18: - retval = - stlink_if->layout->api->write_reg(stlink_if->fd, num, - value); + retval = stlink_if->layout->api->write_reg(stlink_if->fd, num, value); if (retval != ERROR_OK) { struct reg *r; @@ -145,8 +182,36 @@ static int stm32_stlink_store_core_reg_u32(struct target *target, r->dirty = r->valid; return ERROR_JTAG_DEVICE_ERROR; } - LOG_DEBUG("write core reg %i value 0x%" PRIx32 "", (int)num, - value); + LOG_DEBUG("write core reg %i value 0x%" PRIx32 "", (int)num, value); + break; + + case ARMV7M_FPSID: + case ARMV7M_FPEXC: + break; + + case ARMV7M_FPSCR: + /* Floating-point Status and Registers */ + retval = target_write_u32(target, ARMV7M_SCS_DCRDR, value); + if (retval != ERROR_OK) + return retval; + retval = target_write_u32(target, ARMV7M_SCS_DCRSR, 33 | (1<<16)); + if (retval != ERROR_OK) + return retval; + LOG_DEBUG("write core reg %i value 0x%" PRIx32 "", (int)num, value); + break; + + case ARMV7M_S0 ... ARMV7M_S31: + /* Floating-point Status and Registers */ + retval = target_write_u32(target, ARMV7M_SCS_DCRDR, value); + if (retval != ERROR_OK) + return retval; + retval = target_write_u32(target, ARMV7M_SCS_DCRSR, (num-ARMV7M_S0+64) | (1<<16)); + if (retval != ERROR_OK) + return retval; + LOG_DEBUG("write core reg %i value 0x%" PRIx32 "", (int)num, value); + break; + + case ARMV7M_D0 ... ARMV7M_D15: break; case ARMV7M_PRIMASK: @@ -157,7 +222,8 @@ static int stm32_stlink_store_core_reg_u32(struct target *target, * in one Debug Core register. So say r0 and r2 docs; * it was removed from r1 docs, but still works. */ - /* cortexm3_dap_read_coreregister_u32(swjdp, ®, 20); */ + + stlink_if->layout->api->read_reg(stlink_if->fd, 20, ®); switch (num) { case ARMV7M_PRIMASK: @@ -177,14 +243,23 @@ static int stm32_stlink_store_core_reg_u32(struct target *target, break; } - /* cortexm3_dap_write_coreregister_u32(swjdp, reg, 20); */ + stlink_if->layout->api->write_reg(stlink_if->fd, 20, reg); - LOG_DEBUG("write special reg %i value 0x%" PRIx32 " ", (int)num, - value); + LOG_DEBUG("write special reg %i value 0x%" PRIx32 " ", (int)num, value); break; default: - return ERROR_INVALID_ARGUMENTS; + return ERROR_COMMAND_SYNTAX_ERROR; + } + + return ERROR_OK; +} + +static int stm32_stlink_examine_debug_reason(struct target *target) +{ + if ((target->debug_reason != DBG_REASON_DBGRQ) + && (target->debug_reason != DBG_REASON_SINGLESTEP)) { + target->debug_reason = DBG_REASON_BREAKPOINT; } return ERROR_OK; @@ -204,6 +279,9 @@ static int stm32_stlink_init_arch_info(struct target *target, armv7m->load_core_reg_u32 = stm32_stlink_load_core_reg_u32; armv7m->store_core_reg_u32 = stm32_stlink_store_core_reg_u32; + armv7m->examine_debug_reason = stm32_stlink_examine_debug_reason; + armv7m->stlink = true; + return ERROR_OK; } @@ -218,94 +296,86 @@ static int stm32_stlink_init_target(struct command_context *cmd_ctx, } static int stm32_stlink_target_create(struct target *target, - Jim_Interp *interp) + Jim_Interp *interp) { LOG_DEBUG("%s", __func__); struct cortex_m3_common *cortex_m3 = calloc(1, sizeof(struct cortex_m3_common)); if (!cortex_m3) - return ERROR_INVALID_ARGUMENTS; + return ERROR_COMMAND_SYNTAX_ERROR; stm32_stlink_init_arch_info(target, cortex_m3, target->tap); return ERROR_OK; } -static int stm32_stlink_poll(struct target *target); - -static int stm32_stlink_examine(struct target *target) +static int stm32_stlink_load_context(struct target *target) { - int retval, i; - uint32_t cpuid, fpcr; - struct cortex_m3_common *cortex_m3 = target_to_cm3(target); - - LOG_DEBUG("%s", __func__); - - if (target->tap->hasidcode == false) { - LOG_ERROR("no IDCODE present on device"); + struct armv7m_common *armv7m = target_to_armv7m(target); + int num_regs = armv7m->core_cache->num_regs; - return ERROR_INVALID_ARGUMENTS; + for (int i = 0; i < num_regs; i++) { + if (!armv7m->core_cache->reg_list[i].valid) + armv7m->read_core_reg(target, i); } - if (!target_was_examined(target)) { - target_set_examined(target); + return ERROR_OK; +} - stm32_stlink_poll(target); +static int stlink_debug_entry(struct target *target) +{ + struct stlink_interface_s *stlink_if = target_to_stlink(target); + struct armv7m_common *armv7m = target_to_armv7m(target); + struct arm *arm = &armv7m->arm; + struct reg *r; + uint32_t xPSR; + int retval; - LOG_INFO("IDCODE %x", target->tap->idcode); + retval = armv7m->examine_debug_reason(target); + if (retval != ERROR_OK) + return retval; - /* Read from Device Identification Registers */ - retval = target_read_u32(target, CPUID, &cpuid); - if (retval != ERROR_OK) - return retval; + stm32_stlink_load_context(target); - if (((cpuid >> 4) & 0xc3f) == 0xc23) - LOG_DEBUG("Cortex-M3 r%" PRId8 "p%" PRId8 " processor detected", - (uint8_t)((cpuid >> 20) & 0xf), (uint8_t)((cpuid >> 0) & 0xf)); - LOG_DEBUG("cpuid: 0x%8.8" PRIx32 "", cpuid); - - /* Setup FPB */ - target_read_u32(target, FP_CTRL, &fpcr); - cortex_m3->auto_bp_type = 1; - cortex_m3->fp_num_code = ((fpcr >> 8) & 0x70) | - ((fpcr >> 4) & 0xF); /* bits [14:12] and [7:4] */ - cortex_m3->fp_num_lit = (fpcr >> 8) & 0xF; - cortex_m3->fp_code_available = cortex_m3->fp_num_code; - cortex_m3->fp_comparator_list = calloc(cortex_m3->fp_num_code + - cortex_m3->fp_num_lit, sizeof(struct cortex_m3_fp_comparator)); - cortex_m3->fpb_enabled = fpcr & 1; - for (i = 0; i < cortex_m3->fp_num_code + cortex_m3->fp_num_lit; i++) { - cortex_m3->fp_comparator_list[i].type = - (i < cortex_m3->fp_num_code) ? FPCR_CODE : FPCR_LITERAL; - cortex_m3->fp_comparator_list[i].fpcr_address = FP_COMP0 + 4 * i; - } - LOG_DEBUG("FPB fpcr 0x%" PRIx32 ", numcode %i, numlit %i", fpcr, - cortex_m3->fp_num_code, cortex_m3->fp_num_lit); + /* make sure we clear the vector catch bit */ + stlink_if->layout->api->write_debug_reg(stlink_if->fd, DCB_DEMCR, 0); - /* Setup DWT */ - cortex_m3_dwt_setup(cortex_m3, target); + r = armv7m->core_cache->reg_list + ARMV7M_xPSR; + xPSR = buf_get_u32(r->value, 0, 32); - /* These hardware breakpoints only work for code in flash! */ - LOG_INFO("%s: hardware has %d breakpoints, %d watchpoints", - target_name(target), - cortex_m3->fp_num_code, - cortex_m3->dwt_num_comp); - } + /* Are we in an exception handler */ + if (xPSR & 0x1FF) { + armv7m->core_mode = ARMV7M_MODE_HANDLER; + armv7m->exception_number = (xPSR & 0x1FF); - return ERROR_OK; -} + arm->core_mode = ARM_MODE_HANDLER; + arm->map = armv7m_msp_reg_map; + } else { + unsigned control = buf_get_u32(armv7m->core_cache + ->reg_list[ARMV7M_CONTROL].value, 0, 2); -static int stm32_stlink_load_context(struct target *target) -{ - struct armv7m_common *armv7m = target_to_armv7m(target); + /* is this thread privileged? */ + armv7m->core_mode = control & 1; + arm->core_mode = armv7m->core_mode + ? ARM_MODE_USER_THREAD + : ARM_MODE_THREAD; - for (unsigned i = 0; i < 23; i++) { - if (!armv7m->core_cache->reg_list[i].valid) - armv7m->read_core_reg(target, i); + /* which stack is it using? */ + if (control & 2) + arm->map = armv7m_psp_reg_map; + else + arm->map = armv7m_msp_reg_map; + + armv7m->exception_number = 0; } - return ERROR_OK; + LOG_DEBUG("entered debug state in core mode: %s at PC 0x%08" PRIx32 ", target->state: %s", + armv7m_mode_strings[armv7m->core_mode], + *(uint32_t *)(arm->pc->value), + target_state_name(target)); + + return retval; } static int stm32_stlink_poll(struct target *target) @@ -317,8 +387,7 @@ static int stm32_stlink_poll(struct target *target) state = stlink_if->layout->api->state(stlink_if->fd); if (state == TARGET_UNKNOWN) { - LOG_ERROR - ("jtag status contains invalid mode value - communication failure"); + LOG_ERROR("jtag status contains invalid mode value - communication failure"); return ERROR_TARGET_FAILURE; } @@ -326,47 +395,81 @@ static int stm32_stlink_poll(struct target *target) return ERROR_OK; if (state == TARGET_HALTED) { - target_call_event_callbacks(target, TARGET_EVENT_DEBUG_HALTED); target->state = state; - stm32_stlink_load_context(target); + int retval = stlink_debug_entry(target); + if (retval != ERROR_OK) + return retval; - LOG_INFO("halted: PC: 0x%x", buf_get_u32(armv7m->arm.pc->value, 0, 32)); - } + if (arm_semihosting(target, &retval) != 0) + return retval; - return ERROR_OK; -} + target_call_event_callbacks(target, TARGET_EVENT_HALTED); + LOG_DEBUG("halted: PC: 0x%08x", buf_get_u32(armv7m->arm.pc->value, 0, 32)); + } -static int stm32_stlink_arch_state(struct target *target) -{ - LOG_DEBUG("%s", __func__); return ERROR_OK; } static int stm32_stlink_assert_reset(struct target *target) { - int res; + int res = ERROR_OK; struct stlink_interface_s *stlink_if = target_to_stlink(target); struct armv7m_common *armv7m = target_to_armv7m(target); + bool use_srst_fallback = true; LOG_DEBUG("%s", __func__); + enum reset_types jtag_reset_config = jtag_get_reset_config(); + + bool srst_asserted = false; + + if (jtag_reset_config & RESET_SRST_NO_GATING) { + jtag_add_reset(0, 1); + res = stlink_if->layout->api->assert_srst(stlink_if->fd, 0); + srst_asserted = true; + } + + stlink_if->layout->api->write_debug_reg(stlink_if->fd, DCB_DHCSR, DBGKEY|C_DEBUGEN); + + /* only set vector catch if halt is requested */ + if (target->reset_halt) + stlink_if->layout->api->write_debug_reg(stlink_if->fd, DCB_DEMCR, VC_CORERESET); + else + stlink_if->layout->api->write_debug_reg(stlink_if->fd, DCB_DEMCR, 0); + + if (jtag_reset_config & RESET_HAS_SRST) { + if (!srst_asserted) { + jtag_add_reset(0, 1); + res = stlink_if->layout->api->assert_srst(stlink_if->fd, 0); + } + if (res == ERROR_COMMAND_NOTFOUND) + LOG_ERROR("Hardware srst not supported, falling back to software reset"); + else if (res == ERROR_OK) { + /* hardware srst supported */ + use_srst_fallback = false; + } + } + + if (use_srst_fallback) { + /* stlink v1 api does not support hardware srst, so we use a software reset fallback */ + stlink_if->layout->api->write_debug_reg(stlink_if->fd, NVIC_AIRCR, AIRCR_VECTKEY | AIRCR_SYSRESETREQ); + } + res = stlink_if->layout->api->reset(stlink_if->fd); if (res != ERROR_OK) return res; - /* virtual assert reset, we need it for the internal - * jtag state machine - */ - jtag_add_reset(1, 1); - /* registers are now invalid */ register_cache_invalidate(armv7m->core_cache); - stm32_stlink_load_context(target); - - target->state = TARGET_HALTED; + if (target->reset_halt) { + target->state = TARGET_RESET; + target->debug_reason = DBG_REASON_DBGRQ; + } else { + target->state = TARGET_HALTED; + } return ERROR_OK; } @@ -374,9 +477,15 @@ static int stm32_stlink_assert_reset(struct target *target) static int stm32_stlink_deassert_reset(struct target *target) { int res; + struct stlink_interface_s *stlink_if = target_to_stlink(target); + + enum reset_types jtag_reset_config = jtag_get_reset_config(); LOG_DEBUG("%s", __func__); + if (jtag_reset_config & RESET_HAS_SRST) + stlink_if->layout->api->assert_srst(stlink_if->fd, 1); + /* virtual deassert reset, we need it for the internal * jtag state machine */ @@ -410,10 +519,8 @@ static int stm32_stlink_halt(struct target *target) return ERROR_OK; } - if (target->state == TARGET_UNKNOWN) { - LOG_WARNING - ("target was in unknown state when halt was requested"); - } + if (target->state == TARGET_UNKNOWN) + LOG_WARNING("target was in unknown state when halt was requested"); res = stlink_if->layout->api->halt(stlink_if->fd); @@ -426,8 +533,8 @@ static int stm32_stlink_halt(struct target *target) } static int stm32_stlink_resume(struct target *target, int current, - uint32_t address, int handle_breakpoints, - int debug_execution) + uint32_t address, int handle_breakpoints, + int debug_execution) { int res; struct stlink_interface_s *stlink_if = target_to_stlink(target); @@ -436,8 +543,8 @@ static int stm32_stlink_resume(struct target *target, int current, struct breakpoint *breakpoint = NULL; struct reg *pc; - LOG_DEBUG("%s %d %x %d %d", __func__, current, address, - handle_breakpoints, debug_execution); + LOG_DEBUG("%s %d 0x%08x %d %d", __func__, current, address, + handle_breakpoints, debug_execution); if (target->state != TARGET_HALTED) { LOG_WARNING("target not halted"); @@ -469,8 +576,8 @@ static int stm32_stlink_resume(struct target *target, int current, breakpoint = breakpoint_find(target, resume_pc); if (breakpoint) { LOG_DEBUG("unset breakpoint at 0x%8.8" PRIx32 " (ID: %d)", - breakpoint->address, - breakpoint->unique_id); + breakpoint->address, + breakpoint->unique_id); cortex_m3_unset_breakpoint(target, breakpoint); res = stlink_if->layout->api->step(stlink_if->fd); @@ -488,14 +595,15 @@ static int stm32_stlink_resume(struct target *target, int current, return res; target->state = TARGET_RUNNING; + target->debug_reason = DBG_REASON_NOTHALTED; - target_call_event_callbacks(target, TARGET_EVENT_DEBUG_RESUMED); + target_call_event_callbacks(target, TARGET_EVENT_RESUMED); return ERROR_OK; } static int stm32_stlink_step(struct target *target, int current, - uint32_t address, int handle_breakpoints) + uint32_t address, int handle_breakpoints) { int res; struct stlink_interface_s *stlink_if = target_to_stlink(target); @@ -511,7 +619,6 @@ static int stm32_stlink_step(struct target *target, int current, return ERROR_TARGET_NOT_HALTED; } - pc = armv7m->arm.pc; if (!current) { buf_set_u32(pc->value, 0, 32, address); pc->dirty = true; @@ -546,46 +653,56 @@ static int stm32_stlink_step(struct target *target, int current, if (breakpoint) cortex_m3_set_breakpoint(target, breakpoint); - target->debug_reason = DBG_REASON_SINGLESTEP; + stlink_debug_entry(target); target_call_event_callbacks(target, TARGET_EVENT_HALTED); - stm32_stlink_load_context(target); - - LOG_INFO("halted: PC: 0x%x", buf_get_u32(armv7m->arm.pc->value, 0, 32)); + LOG_INFO("halted: PC: 0x%08x", buf_get_u32(armv7m->arm.pc->value, 0, 32)); return ERROR_OK; } static int stm32_stlink_read_memory(struct target *target, uint32_t address, - uint32_t size, uint32_t count, - uint8_t *buffer) + uint32_t size, uint32_t count, + uint8_t *buffer) { int res; - uint32_t *dst = (uint32_t *) buffer; + uint32_t buffer_threshold = 128; + uint32_t addr_increment = 4; uint32_t c; struct stlink_interface_s *stlink_if = target_to_stlink(target); if (!count || !buffer) - return ERROR_INVALID_ARGUMENTS; + return ERROR_COMMAND_SYNTAX_ERROR; + + LOG_DEBUG("%s 0x%08x %d %d", __func__, address, size, count); + + /* prepare byte count, buffer threshold + * and address increment for none 32bit access + */ if (size != 4) { - LOG_DEBUG("%s %x %d %d", __func__, address, size, count); - return ERROR_INVALID_ARGUMENTS; + count *= size; + buffer_threshold = 64; + addr_increment = 1; } while (count) { - if (count > 128) - c = 128; + if (count > buffer_threshold) + c = buffer_threshold; else c = count; - res = - stlink_if->layout->api->read_mem32(stlink_if->fd, address, - c, dst); + if (size != 4) + res = stlink_if->layout->api->read_mem8(stlink_if->fd, + address, c, buffer); + else + res = stlink_if->layout->api->read_mem32(stlink_if->fd, + address, c, buffer); if (res != ERROR_OK) return res; - dst += c; - address += (c * 4); + + address += (c * addr_increment); + buffer += (c * addr_increment); count -= c; } @@ -593,35 +710,47 @@ static int stm32_stlink_read_memory(struct target *target, uint32_t address, } static int stm32_stlink_write_memory(struct target *target, uint32_t address, - uint32_t size, uint32_t count, - const uint8_t *buffer) + uint32_t size, uint32_t count, + const uint8_t *buffer) { int res; - uint32_t *dst = (uint32_t *) buffer; + uint32_t buffer_threshold = 128; + uint32_t addr_increment = 4; uint32_t c; struct stlink_interface_s *stlink_if = target_to_stlink(target); if (!count || !buffer) - return ERROR_INVALID_ARGUMENTS; + return ERROR_COMMAND_SYNTAX_ERROR; + + LOG_DEBUG("%s 0x%08x %d %d", __func__, address, size, count); + + /* prepare byte count, buffer threshold + * and address increment for none 32bit access + */ if (size != 4) { - LOG_DEBUG("%s %x %d %d", __func__, address, size, count); - return ERROR_INVALID_ARGUMENTS; + count *= size; + buffer_threshold = 64; + addr_increment = 1; } while (count) { - if (count > 128) - c = 128; + if (count > buffer_threshold) + c = buffer_threshold; else c = count; - res = - stlink_if->layout->api->write_mem32(stlink_if->fd, address, - c, dst); + if (size != 4) + res = stlink_if->layout->api->write_mem8(stlink_if->fd, + address, c, buffer); + else + res = stlink_if->layout->api->write_mem32(stlink_if->fd, + address, c, buffer); if (res != ERROR_OK) return res; - dst += c; - address += (c * 4); + + address += (c * addr_increment); + buffer += (c * addr_increment); count -= c; } @@ -629,21 +758,29 @@ static int stm32_stlink_write_memory(struct target *target, uint32_t address, } static int stm32_stlink_bulk_write_memory(struct target *target, - uint32_t address, uint32_t count, - const uint8_t *buffer) + uint32_t address, uint32_t count, + const uint8_t *buffer) { return stm32_stlink_write_memory(target, address, 4, count, buffer); } +static const struct command_registration stm32_stlink_command_handlers[] = { + { + .chain = arm_command_handlers, + }, + COMMAND_REGISTRATION_DONE +}; + struct target_type stm32_stlink_target = { .name = "stm32_stlink", .init_target = stm32_stlink_init_target, .target_create = stm32_stlink_target_create, - .examine = stm32_stlink_examine, + .examine = cortex_m3_examine, + .commands = stm32_stlink_command_handlers, .poll = stm32_stlink_poll, - .arch_state = stm32_stlink_arch_state, + .arch_state = armv7m_arch_state, .assert_reset = stm32_stlink_assert_reset, .deassert_reset = stm32_stlink_deassert_reset, @@ -658,6 +795,8 @@ struct target_type stm32_stlink_target = { .read_memory = stm32_stlink_read_memory, .write_memory = stm32_stlink_write_memory, .bulk_write_memory = stm32_stlink_bulk_write_memory, + .checksum_memory = armv7m_checksum_memory, + .blank_check_memory = armv7m_blank_check_memory, .run_algorithm = armv7m_run_algorithm, .start_algorithm = armv7m_start_algorithm,