You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

801 lines
21 KiB

  1. /***************************************************************************
  2. * Copyright (C) 2011 by Mathias Kuester *
  3. * Mathias Kuester <kesmtp@freenet.de> *
  4. * *
  5. * Copyright (C) 2011 by Spencer Oliver *
  6. * spen@spen-soft.co.uk *
  7. * *
  8. * This program is free software; you can redistribute it and/or modify *
  9. * it under the terms of the GNU General Public License as published by *
  10. * the Free Software Foundation; either version 2 of the License, or *
  11. * (at your option) any later version. *
  12. * *
  13. * This program is distributed in the hope that it will be useful, *
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of *
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
  16. * GNU General Public License for more details. *
  17. * *
  18. * You should have received a copy of the GNU General Public License *
  19. * along with this program; if not, write to the *
  20. * Free Software Foundation, Inc., *
  21. * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
  22. ***************************************************************************/
  23. #ifdef HAVE_CONFIG_H
  24. #include "config.h"
  25. #endif
  26. #include "jtag/jtag.h"
  27. #include "jtag/stlink/stlink_transport.h"
  28. #include "jtag/stlink/stlink_interface.h"
  29. #include "jtag/stlink/stlink_layout.h"
  30. #include "register.h"
  31. #include "algorithm.h"
  32. #include "target.h"
  33. #include "breakpoints.h"
  34. #include "target_type.h"
  35. #include "armv7m.h"
  36. #include "cortex_m.h"
  37. #include "arm_semihosting.h"
  38. #define ARMV7M_SCS_DCRSR 0xe000edf4
  39. #define ARMV7M_SCS_DCRDR 0xe000edf8
  40. static inline struct stlink_interface_s *target_to_stlink(struct target *target)
  41. {
  42. return target->tap->priv;
  43. }
  44. static int stm32_stlink_load_core_reg_u32(struct target *target,
  45. enum armv7m_regtype type,
  46. uint32_t num, uint32_t *value)
  47. {
  48. int retval;
  49. struct stlink_interface_s *stlink_if = target_to_stlink(target);
  50. LOG_DEBUG("%s", __func__);
  51. /* NOTE: we "know" here that the register identifiers used
  52. * in the v7m header match the Cortex-M3 Debug Core Register
  53. * Selector values for R0..R15, xPSR, MSP, and PSP.
  54. */
  55. switch (num) {
  56. case 0 ... 18:
  57. /* read a normal core register */
  58. retval = stlink_if->layout->api->read_reg(stlink_if->fd, num, value);
  59. if (retval != ERROR_OK) {
  60. LOG_ERROR("JTAG failure %i", retval);
  61. return ERROR_JTAG_DEVICE_ERROR;
  62. }
  63. LOG_DEBUG("load from core reg %i value 0x%" PRIx32 "", (int)num, *value);
  64. break;
  65. case ARMV7M_FPSID:
  66. case ARMV7M_FPEXC:
  67. *value = 0;
  68. break;
  69. case ARMV7M_FPSCR:
  70. /* Floating-point Status and Registers */
  71. retval = target_write_u32(target, ARMV7M_SCS_DCRSR, 33);
  72. if (retval != ERROR_OK)
  73. return retval;
  74. retval = target_read_u32(target, ARMV7M_SCS_DCRDR, value);
  75. if (retval != ERROR_OK)
  76. return retval;
  77. LOG_DEBUG("load from core reg %i value 0x%" PRIx32 "", (int)num, *value);
  78. break;
  79. case ARMV7M_S0 ... ARMV7M_S31:
  80. /* Floating-point Status and Registers */
  81. retval = target_write_u32(target, ARMV7M_SCS_DCRSR, num-ARMV7M_S0+64);
  82. if (retval != ERROR_OK)
  83. return retval;
  84. retval = target_read_u32(target, ARMV7M_SCS_DCRDR, value);
  85. if (retval != ERROR_OK)
  86. return retval;
  87. LOG_DEBUG("load from core reg %i value 0x%" PRIx32 "", (int)num, *value);
  88. break;
  89. case ARMV7M_D0 ... ARMV7M_D15:
  90. value = 0;
  91. break;
  92. case ARMV7M_PRIMASK:
  93. case ARMV7M_BASEPRI:
  94. case ARMV7M_FAULTMASK:
  95. case ARMV7M_CONTROL:
  96. /* Cortex-M3 packages these four registers as bitfields
  97. * in one Debug Core register. So say r0 and r2 docs;
  98. * it was removed from r1 docs, but still works.
  99. */
  100. retval = stlink_if->layout->api->read_reg(stlink_if->fd, 20, value);
  101. if (retval != ERROR_OK)
  102. return retval;
  103. switch (num) {
  104. case ARMV7M_PRIMASK:
  105. *value = buf_get_u32((uint8_t *) value, 0, 1);
  106. break;
  107. case ARMV7M_BASEPRI:
  108. *value = buf_get_u32((uint8_t *) value, 8, 8);
  109. break;
  110. case ARMV7M_FAULTMASK:
  111. *value = buf_get_u32((uint8_t *) value, 16, 1);
  112. break;
  113. case ARMV7M_CONTROL:
  114. *value = buf_get_u32((uint8_t *) value, 24, 2);
  115. break;
  116. }
  117. LOG_DEBUG("load from special reg %i value 0x%" PRIx32 "",
  118. (int)num, *value);
  119. break;
  120. default:
  121. return ERROR_COMMAND_SYNTAX_ERROR;
  122. }
  123. return ERROR_OK;
  124. }
  125. static int stm32_stlink_store_core_reg_u32(struct target *target,
  126. enum armv7m_regtype type,
  127. uint32_t num, uint32_t value)
  128. {
  129. int retval;
  130. uint32_t reg;
  131. struct armv7m_common *armv7m = target_to_armv7m(target);
  132. struct stlink_interface_s *stlink_if = target_to_stlink(target);
  133. LOG_DEBUG("%s", __func__);
  134. #ifdef ARMV7_GDB_HACKS
  135. /* If the LR register is being modified, make sure it will put us
  136. * in "thumb" mode, or an INVSTATE exception will occur. This is a
  137. * hack to deal with the fact that gdb will sometimes "forge"
  138. * return addresses, and doesn't set the LSB correctly (i.e., when
  139. * printing expressions containing function calls, it sets LR = 0.)
  140. * Valid exception return codes have bit 0 set too.
  141. */
  142. if (num == ARMV7M_R14)
  143. value |= 0x01;
  144. #endif
  145. /* NOTE: we "know" here that the register identifiers used
  146. * in the v7m header match the Cortex-M3 Debug Core Register
  147. * Selector values for R0..R15, xPSR, MSP, and PSP.
  148. */
  149. switch (num) {
  150. case 0 ... 18:
  151. retval = stlink_if->layout->api->write_reg(stlink_if->fd, num, value);
  152. if (retval != ERROR_OK) {
  153. struct reg *r;
  154. LOG_ERROR("JTAG failure");
  155. r = armv7m->core_cache->reg_list + num;
  156. r->dirty = r->valid;
  157. return ERROR_JTAG_DEVICE_ERROR;
  158. }
  159. LOG_DEBUG("write core reg %i value 0x%" PRIx32 "", (int)num, value);
  160. break;
  161. case ARMV7M_FPSID:
  162. case ARMV7M_FPEXC:
  163. break;
  164. case ARMV7M_FPSCR:
  165. /* Floating-point Status and Registers */
  166. retval = target_write_u32(target, ARMV7M_SCS_DCRDR, value);
  167. if (retval != ERROR_OK)
  168. return retval;
  169. retval = target_write_u32(target, ARMV7M_SCS_DCRSR, 33 | (1<<16));
  170. if (retval != ERROR_OK)
  171. return retval;
  172. LOG_DEBUG("write core reg %i value 0x%" PRIx32 "", (int)num, value);
  173. break;
  174. case ARMV7M_S0 ... ARMV7M_S31:
  175. /* Floating-point Status and Registers */
  176. retval = target_write_u32(target, ARMV7M_SCS_DCRDR, value);
  177. if (retval != ERROR_OK)
  178. return retval;
  179. retval = target_write_u32(target, ARMV7M_SCS_DCRSR, (num-ARMV7M_S0+64) | (1<<16));
  180. if (retval != ERROR_OK)
  181. return retval;
  182. LOG_DEBUG("write core reg %i value 0x%" PRIx32 "", (int)num, value);
  183. break;
  184. case ARMV7M_D0 ... ARMV7M_D15:
  185. break;
  186. case ARMV7M_PRIMASK:
  187. case ARMV7M_BASEPRI:
  188. case ARMV7M_FAULTMASK:
  189. case ARMV7M_CONTROL:
  190. /* Cortex-M3 packages these four registers as bitfields
  191. * in one Debug Core register. So say r0 and r2 docs;
  192. * it was removed from r1 docs, but still works.
  193. */
  194. stlink_if->layout->api->read_reg(stlink_if->fd, 20, &reg);
  195. switch (num) {
  196. case ARMV7M_PRIMASK:
  197. buf_set_u32((uint8_t *) &reg, 0, 1, value);
  198. break;
  199. case ARMV7M_BASEPRI:
  200. buf_set_u32((uint8_t *) &reg, 8, 8, value);
  201. break;
  202. case ARMV7M_FAULTMASK:
  203. buf_set_u32((uint8_t *) &reg, 16, 1, value);
  204. break;
  205. case ARMV7M_CONTROL:
  206. buf_set_u32((uint8_t *) &reg, 24, 2, value);
  207. break;
  208. }
  209. stlink_if->layout->api->write_reg(stlink_if->fd, 20, reg);
  210. LOG_DEBUG("write special reg %i value 0x%" PRIx32 " ", (int)num, value);
  211. break;
  212. default:
  213. return ERROR_COMMAND_SYNTAX_ERROR;
  214. }
  215. return ERROR_OK;
  216. }
  217. static int stm32_stlink_examine_debug_reason(struct target *target)
  218. {
  219. if ((target->debug_reason != DBG_REASON_DBGRQ)
  220. && (target->debug_reason != DBG_REASON_SINGLESTEP)) {
  221. target->debug_reason = DBG_REASON_BREAKPOINT;
  222. }
  223. return ERROR_OK;
  224. }
  225. static int stm32_stlink_init_arch_info(struct target *target,
  226. struct cortex_m3_common *cortex_m3,
  227. struct jtag_tap *tap)
  228. {
  229. struct armv7m_common *armv7m;
  230. LOG_DEBUG("%s", __func__);
  231. armv7m = &cortex_m3->armv7m;
  232. armv7m_init_arch_info(target, armv7m);
  233. armv7m->load_core_reg_u32 = stm32_stlink_load_core_reg_u32;
  234. armv7m->store_core_reg_u32 = stm32_stlink_store_core_reg_u32;
  235. armv7m->examine_debug_reason = stm32_stlink_examine_debug_reason;
  236. armv7m->stlink = true;
  237. return ERROR_OK;
  238. }
  239. static int stm32_stlink_init_target(struct command_context *cmd_ctx,
  240. struct target *target)
  241. {
  242. LOG_DEBUG("%s", __func__);
  243. armv7m_build_reg_cache(target);
  244. return ERROR_OK;
  245. }
  246. static int stm32_stlink_target_create(struct target *target,
  247. Jim_Interp *interp)
  248. {
  249. LOG_DEBUG("%s", __func__);
  250. struct cortex_m3_common *cortex_m3 = calloc(1, sizeof(struct cortex_m3_common));
  251. if (!cortex_m3)
  252. return ERROR_COMMAND_SYNTAX_ERROR;
  253. stm32_stlink_init_arch_info(target, cortex_m3, target->tap);
  254. return ERROR_OK;
  255. }
  256. static int stm32_stlink_load_context(struct target *target)
  257. {
  258. struct armv7m_common *armv7m = target_to_armv7m(target);
  259. int num_regs = armv7m->core_cache->num_regs;
  260. for (int i = 0; i < num_regs; i++) {
  261. if (!armv7m->core_cache->reg_list[i].valid)
  262. armv7m->read_core_reg(target, i);
  263. }
  264. return ERROR_OK;
  265. }
  266. static int stlink_debug_entry(struct target *target)
  267. {
  268. struct armv7m_common *armv7m = target_to_armv7m(target);
  269. struct arm *arm = &armv7m->arm;
  270. struct reg *r;
  271. uint32_t xPSR;
  272. int retval;
  273. retval = armv7m->examine_debug_reason(target);
  274. if (retval != ERROR_OK)
  275. return retval;
  276. stm32_stlink_load_context(target);
  277. r = armv7m->core_cache->reg_list + ARMV7M_xPSR;
  278. xPSR = buf_get_u32(r->value, 0, 32);
  279. /* Are we in an exception handler */
  280. if (xPSR & 0x1FF) {
  281. armv7m->core_mode = ARMV7M_MODE_HANDLER;
  282. armv7m->exception_number = (xPSR & 0x1FF);
  283. arm->core_mode = ARM_MODE_HANDLER;
  284. arm->map = armv7m_msp_reg_map;
  285. } else {
  286. unsigned control = buf_get_u32(armv7m->core_cache
  287. ->reg_list[ARMV7M_CONTROL].value, 0, 2);
  288. /* is this thread privileged? */
  289. armv7m->core_mode = control & 1;
  290. arm->core_mode = armv7m->core_mode
  291. ? ARM_MODE_USER_THREAD
  292. : ARM_MODE_THREAD;
  293. /* which stack is it using? */
  294. if (control & 2)
  295. arm->map = armv7m_psp_reg_map;
  296. else
  297. arm->map = armv7m_msp_reg_map;
  298. armv7m->exception_number = 0;
  299. }
  300. LOG_DEBUG("entered debug state in core mode: %s at PC 0x%08" PRIx32 ", target->state: %s",
  301. armv7m_mode_strings[armv7m->core_mode],
  302. *(uint32_t *)(arm->pc->value),
  303. target_state_name(target));
  304. return retval;
  305. }
  306. static int stm32_stlink_poll(struct target *target)
  307. {
  308. enum target_state state;
  309. struct stlink_interface_s *stlink_if = target_to_stlink(target);
  310. struct armv7m_common *armv7m = target_to_armv7m(target);
  311. state = stlink_if->layout->api->state(stlink_if->fd);
  312. if (state == TARGET_UNKNOWN) {
  313. LOG_ERROR("jtag status contains invalid mode value - communication failure");
  314. return ERROR_TARGET_FAILURE;
  315. }
  316. if (target->state == state)
  317. return ERROR_OK;
  318. if (state == TARGET_HALTED) {
  319. target->state = state;
  320. int retval = stlink_debug_entry(target);
  321. if (retval != ERROR_OK)
  322. return retval;
  323. if (arm_semihosting(target, &retval) != 0)
  324. return retval;
  325. target_call_event_callbacks(target, TARGET_EVENT_HALTED);
  326. LOG_DEBUG("halted: PC: 0x%08x", buf_get_u32(armv7m->arm.pc->value, 0, 32));
  327. }
  328. return ERROR_OK;
  329. }
  330. static int stm32_stlink_assert_reset(struct target *target)
  331. {
  332. int res = ERROR_OK;
  333. struct stlink_interface_s *stlink_if = target_to_stlink(target);
  334. struct armv7m_common *armv7m = target_to_armv7m(target);
  335. bool use_srst_fallback = true;
  336. LOG_DEBUG("%s", __func__);
  337. enum reset_types jtag_reset_config = jtag_get_reset_config();
  338. bool srst_asserted = false;
  339. if (jtag_reset_config & RESET_SRST_NO_GATING) {
  340. jtag_add_reset(0, 1);
  341. res = stlink_if->layout->api->assert_srst(stlink_if->fd, 0);
  342. srst_asserted = true;
  343. }
  344. stlink_if->layout->api->write_debug_reg(stlink_if->fd, DCB_DHCSR, DBGKEY|C_DEBUGEN);
  345. stlink_if->layout->api->write_debug_reg(stlink_if->fd, DCB_DEMCR, VC_CORERESET);
  346. if (jtag_reset_config & RESET_HAS_SRST) {
  347. if (!srst_asserted) {
  348. jtag_add_reset(0, 1);
  349. res = stlink_if->layout->api->assert_srst(stlink_if->fd, 0);
  350. }
  351. if (res == ERROR_COMMAND_NOTFOUND)
  352. LOG_ERROR("Hardware srst not supported, falling back to software reset");
  353. else if (res == ERROR_OK) {
  354. /* hardware srst supported */
  355. use_srst_fallback = false;
  356. }
  357. }
  358. if (use_srst_fallback) {
  359. /* stlink v1 api does not support hardware srst, so we use a software reset fallback */
  360. stlink_if->layout->api->write_debug_reg(stlink_if->fd, NVIC_AIRCR, AIRCR_VECTKEY | AIRCR_SYSRESETREQ);
  361. }
  362. res = stlink_if->layout->api->reset(stlink_if->fd);
  363. if (res != ERROR_OK)
  364. return res;
  365. /* registers are now invalid */
  366. register_cache_invalidate(armv7m->core_cache);
  367. if (target->reset_halt) {
  368. target->state = TARGET_RESET;
  369. target->debug_reason = DBG_REASON_DBGRQ;
  370. } else {
  371. target->state = TARGET_HALTED;
  372. }
  373. return ERROR_OK;
  374. }
  375. static int stm32_stlink_deassert_reset(struct target *target)
  376. {
  377. int res;
  378. struct stlink_interface_s *stlink_if = target_to_stlink(target);
  379. enum reset_types jtag_reset_config = jtag_get_reset_config();
  380. LOG_DEBUG("%s", __func__);
  381. if (jtag_reset_config & RESET_HAS_SRST)
  382. stlink_if->layout->api->assert_srst(stlink_if->fd, 1);
  383. /* virtual deassert reset, we need it for the internal
  384. * jtag state machine
  385. */
  386. jtag_add_reset(0, 0);
  387. if (!target->reset_halt) {
  388. res = target_resume(target, 1, 0, 0, 0);
  389. if (res != ERROR_OK)
  390. return res;
  391. }
  392. return ERROR_OK;
  393. }
  394. static int stm32_stlink_soft_reset_halt(struct target *target)
  395. {
  396. LOG_DEBUG("%s", __func__);
  397. return ERROR_OK;
  398. }
  399. static int stm32_stlink_halt(struct target *target)
  400. {
  401. int res;
  402. struct stlink_interface_s *stlink_if = target_to_stlink(target);
  403. LOG_DEBUG("%s", __func__);
  404. if (target->state == TARGET_HALTED) {
  405. LOG_DEBUG("target was already halted");
  406. return ERROR_OK;
  407. }
  408. if (target->state == TARGET_UNKNOWN)
  409. LOG_WARNING("target was in unknown state when halt was requested");
  410. res = stlink_if->layout->api->halt(stlink_if->fd);
  411. if (res != ERROR_OK)
  412. return res;
  413. target->debug_reason = DBG_REASON_DBGRQ;
  414. return ERROR_OK;
  415. }
  416. static int stm32_stlink_resume(struct target *target, int current,
  417. uint32_t address, int handle_breakpoints,
  418. int debug_execution)
  419. {
  420. int res;
  421. struct stlink_interface_s *stlink_if = target_to_stlink(target);
  422. struct armv7m_common *armv7m = target_to_armv7m(target);
  423. uint32_t resume_pc;
  424. struct breakpoint *breakpoint = NULL;
  425. struct reg *pc;
  426. LOG_DEBUG("%s %d 0x%08x %d %d", __func__, current, address,
  427. handle_breakpoints, debug_execution);
  428. if (target->state != TARGET_HALTED) {
  429. LOG_WARNING("target not halted");
  430. return ERROR_TARGET_NOT_HALTED;
  431. }
  432. pc = armv7m->arm.pc;
  433. if (!current) {
  434. buf_set_u32(pc->value, 0, 32, address);
  435. pc->dirty = true;
  436. pc->valid = true;
  437. }
  438. if (!breakpoint_find(target, buf_get_u32(pc->value, 0, 32))
  439. && !debug_execution) {
  440. armv7m_maybe_skip_bkpt_inst(target, NULL);
  441. }
  442. resume_pc = buf_get_u32(pc->value, 0, 32);
  443. armv7m_restore_context(target);
  444. /* registers are now invalid */
  445. register_cache_invalidate(armv7m->core_cache);
  446. /* the front-end may request us not to handle breakpoints */
  447. if (handle_breakpoints) {
  448. /* Single step past breakpoint at current address */
  449. breakpoint = breakpoint_find(target, resume_pc);
  450. if (breakpoint) {
  451. LOG_DEBUG("unset breakpoint at 0x%8.8" PRIx32 " (ID: %d)",
  452. breakpoint->address,
  453. breakpoint->unique_id);
  454. cortex_m3_unset_breakpoint(target, breakpoint);
  455. res = stlink_if->layout->api->step(stlink_if->fd);
  456. if (res != ERROR_OK)
  457. return res;
  458. cortex_m3_set_breakpoint(target, breakpoint);
  459. }
  460. }
  461. res = stlink_if->layout->api->run(stlink_if->fd);
  462. if (res != ERROR_OK)
  463. return res;
  464. target->state = TARGET_RUNNING;
  465. target->debug_reason = DBG_REASON_NOTHALTED;
  466. target_call_event_callbacks(target, TARGET_EVENT_RESUMED);
  467. return ERROR_OK;
  468. }
  469. static int stm32_stlink_step(struct target *target, int current,
  470. uint32_t address, int handle_breakpoints)
  471. {
  472. int res;
  473. struct stlink_interface_s *stlink_if = target_to_stlink(target);
  474. struct armv7m_common *armv7m = target_to_armv7m(target);
  475. struct breakpoint *breakpoint = NULL;
  476. struct reg *pc = armv7m->arm.pc;
  477. bool bkpt_inst_found = false;
  478. LOG_DEBUG("%s", __func__);
  479. if (target->state != TARGET_HALTED) {
  480. LOG_WARNING("target not halted");
  481. return ERROR_TARGET_NOT_HALTED;
  482. }
  483. if (!current) {
  484. buf_set_u32(pc->value, 0, 32, address);
  485. pc->dirty = true;
  486. pc->valid = true;
  487. }
  488. uint32_t pc_value = buf_get_u32(pc->value, 0, 32);
  489. /* the front-end may request us not to handle breakpoints */
  490. if (handle_breakpoints) {
  491. breakpoint = breakpoint_find(target, pc_value);
  492. if (breakpoint)
  493. cortex_m3_unset_breakpoint(target, breakpoint);
  494. }
  495. armv7m_maybe_skip_bkpt_inst(target, &bkpt_inst_found);
  496. target->debug_reason = DBG_REASON_SINGLESTEP;
  497. armv7m_restore_context(target);
  498. target_call_event_callbacks(target, TARGET_EVENT_RESUMED);
  499. res = stlink_if->layout->api->step(stlink_if->fd);
  500. if (res != ERROR_OK)
  501. return res;
  502. /* registers are now invalid */
  503. register_cache_invalidate(armv7m->core_cache);
  504. if (breakpoint)
  505. cortex_m3_set_breakpoint(target, breakpoint);
  506. stlink_debug_entry(target);
  507. target_call_event_callbacks(target, TARGET_EVENT_HALTED);
  508. LOG_INFO("halted: PC: 0x%08x", buf_get_u32(armv7m->arm.pc->value, 0, 32));
  509. return ERROR_OK;
  510. }
  511. static int stm32_stlink_read_memory(struct target *target, uint32_t address,
  512. uint32_t size, uint32_t count,
  513. uint8_t *buffer)
  514. {
  515. int res;
  516. uint32_t buffer_threshold = 128;
  517. uint32_t addr_increment = 4;
  518. uint32_t c;
  519. struct stlink_interface_s *stlink_if = target_to_stlink(target);
  520. if (!count || !buffer)
  521. return ERROR_COMMAND_SYNTAX_ERROR;
  522. LOG_DEBUG("%s 0x%08x %d %d", __func__, address, size, count);
  523. /* prepare byte count, buffer threshold
  524. * and address increment for none 32bit access
  525. */
  526. if (size != 4) {
  527. count *= size;
  528. buffer_threshold = 64;
  529. addr_increment = 1;
  530. }
  531. while (count) {
  532. if (count > buffer_threshold)
  533. c = buffer_threshold;
  534. else
  535. c = count;
  536. if (size != 4)
  537. res = stlink_if->layout->api->read_mem8(stlink_if->fd,
  538. address, c, buffer);
  539. else
  540. res = stlink_if->layout->api->read_mem32(stlink_if->fd,
  541. address, c, buffer);
  542. if (res != ERROR_OK)
  543. return res;
  544. address += (c * addr_increment);
  545. buffer += (c * addr_increment);
  546. count -= c;
  547. }
  548. return ERROR_OK;
  549. }
  550. static int stm32_stlink_write_memory(struct target *target, uint32_t address,
  551. uint32_t size, uint32_t count,
  552. const uint8_t *buffer)
  553. {
  554. int res;
  555. uint32_t buffer_threshold = 128;
  556. uint32_t addr_increment = 4;
  557. uint32_t c;
  558. struct stlink_interface_s *stlink_if = target_to_stlink(target);
  559. if (!count || !buffer)
  560. return ERROR_COMMAND_SYNTAX_ERROR;
  561. LOG_DEBUG("%s 0x%08x %d %d", __func__, address, size, count);
  562. /* prepare byte count, buffer threshold
  563. * and address increment for none 32bit access
  564. */
  565. if (size != 4) {
  566. count *= size;
  567. buffer_threshold = 64;
  568. addr_increment = 1;
  569. }
  570. while (count) {
  571. if (count > buffer_threshold)
  572. c = buffer_threshold;
  573. else
  574. c = count;
  575. if (size != 4)
  576. res = stlink_if->layout->api->write_mem8(stlink_if->fd,
  577. address, c, buffer);
  578. else
  579. res = stlink_if->layout->api->write_mem32(stlink_if->fd,
  580. address, c, buffer);
  581. if (res != ERROR_OK)
  582. return res;
  583. address += (c * addr_increment);
  584. buffer += (c * addr_increment);
  585. count -= c;
  586. }
  587. return ERROR_OK;
  588. }
  589. static int stm32_stlink_bulk_write_memory(struct target *target,
  590. uint32_t address, uint32_t count,
  591. const uint8_t *buffer)
  592. {
  593. return stm32_stlink_write_memory(target, address, 4, count, buffer);
  594. }
  595. static const struct command_registration stm32_stlink_command_handlers[] = {
  596. {
  597. .chain = arm_command_handlers,
  598. },
  599. COMMAND_REGISTRATION_DONE
  600. };
  601. struct target_type stm32_stlink_target = {
  602. .name = "stm32_stlink",
  603. .init_target = stm32_stlink_init_target,
  604. .target_create = stm32_stlink_target_create,
  605. .examine = cortex_m3_examine,
  606. .commands = stm32_stlink_command_handlers,
  607. .poll = stm32_stlink_poll,
  608. .arch_state = armv7m_arch_state,
  609. .assert_reset = stm32_stlink_assert_reset,
  610. .deassert_reset = stm32_stlink_deassert_reset,
  611. .soft_reset_halt = stm32_stlink_soft_reset_halt,
  612. .halt = stm32_stlink_halt,
  613. .resume = stm32_stlink_resume,
  614. .step = stm32_stlink_step,
  615. .get_gdb_reg_list = armv7m_get_gdb_reg_list,
  616. .read_memory = stm32_stlink_read_memory,
  617. .write_memory = stm32_stlink_write_memory,
  618. .bulk_write_memory = stm32_stlink_bulk_write_memory,
  619. .checksum_memory = armv7m_checksum_memory,
  620. .blank_check_memory = armv7m_blank_check_memory,
  621. .run_algorithm = armv7m_run_algorithm,
  622. .start_algorithm = armv7m_start_algorithm,
  623. .wait_algorithm = armv7m_wait_algorithm,
  624. .add_breakpoint = cortex_m3_add_breakpoint,
  625. .remove_breakpoint = cortex_m3_remove_breakpoint,
  626. .add_watchpoint = cortex_m3_add_watchpoint,
  627. .remove_watchpoint = cortex_m3_remove_watchpoint,
  628. };