stlink: fix alignment build warning
[openocd/jflash.git] / src / target / stm32_stlink.c
blob7bec73f5827a3ceafcf4d6de109c9a6bd35666a1
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 ***************************************************************************/
24 #ifdef HAVE_CONFIG_H
25 #include "config.h"
26 #endif
28 #include "jtag/jtag.h"
29 #include "jtag/stlink/stlink_transport.h"
30 #include "jtag/stlink/stlink_interface.h"
31 #include "jtag/stlink/stlink_layout.h"
32 #include "register.h"
33 #include "algorithm.h"
34 #include "target.h"
35 #include "breakpoints.h"
36 #include "target_type.h"
37 #include "armv7m.h"
38 #include "cortex_m.h"
39 #include "arm_semihosting.h"
41 #define ARMV7M_SCS_DCRSR 0xe000edf4
42 #define ARMV7M_SCS_DCRDR 0xe000edf8
44 static inline struct stlink_interface_s *target_to_stlink(struct target *target)
46 return target->tap->priv;
49 static int stm32_stlink_load_core_reg_u32(struct target *target,
50 enum armv7m_regtype type,
51 uint32_t num, uint32_t *value)
53 int retval;
54 struct stlink_interface_s *stlink_if = target_to_stlink(target);
56 LOG_DEBUG("%s", __func__);
58 /* NOTE: we "know" here that the register identifiers used
59 * in the v7m header match the Cortex-M3 Debug Core Register
60 * Selector values for R0..R15, xPSR, MSP, and PSP.
62 switch (num) {
63 case 0 ... 18:
64 /* read a normal core register */
65 retval = stlink_if->layout->api->read_reg(stlink_if->fd, num, value);
67 if (retval != ERROR_OK) {
68 LOG_ERROR("JTAG failure %i", retval);
69 return ERROR_JTAG_DEVICE_ERROR;
71 LOG_DEBUG("load from core reg %i value 0x%" PRIx32 "", (int)num, *value);
72 break;
74 case 33:
75 case 64 ... 96:
76 /* Floating-point Status and Registers */
77 retval = target_write_u32(target, ARMV7M_SCS_DCRSR, num);
78 if (retval != ERROR_OK)
79 return retval;
80 retval = target_read_u32(target, ARMV7M_SCS_DCRDR, value);
81 if (retval != ERROR_OK)
82 return retval;
83 LOG_DEBUG("load from core reg %i value 0x%" PRIx32 "", (int)num, *value);
84 break;
86 case ARMV7M_PRIMASK:
87 case ARMV7M_BASEPRI:
88 case ARMV7M_FAULTMASK:
89 case ARMV7M_CONTROL:
90 /* Cortex-M3 packages these four registers as bitfields
91 * in one Debug Core register. So say r0 and r2 docs;
92 * it was removed from r1 docs, but still works.
94 retval = stlink_if->layout->api->read_reg(stlink_if->fd, 20, value);
96 switch (num) {
97 case ARMV7M_PRIMASK:
98 *value = buf_get_u32((uint8_t *) value, 0, 1);
99 break;
101 case ARMV7M_BASEPRI:
102 *value = buf_get_u32((uint8_t *) value, 8, 8);
103 break;
105 case ARMV7M_FAULTMASK:
106 *value = buf_get_u32((uint8_t *) value, 16, 1);
107 break;
109 case ARMV7M_CONTROL:
110 *value = buf_get_u32((uint8_t *) value, 24, 2);
111 break;
114 LOG_DEBUG("load from special reg %i value 0x%" PRIx32 "",
115 (int)num, *value);
116 break;
118 default:
119 return ERROR_COMMAND_SYNTAX_ERROR;
122 return ERROR_OK;
125 static int stm32_stlink_store_core_reg_u32(struct target *target,
126 enum armv7m_regtype type,
127 uint32_t num, uint32_t value)
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);
134 LOG_DEBUG("%s", __func__);
136 #ifdef ARMV7_GDB_HACKS
137 /* If the LR register is being modified, make sure it will put us
138 * in "thumb" mode, or an INVSTATE exception will occur. This is a
139 * hack to deal with the fact that gdb will sometimes "forge"
140 * return addresses, and doesn't set the LSB correctly (i.e., when
141 * printing expressions containing function calls, it sets LR = 0.)
142 * Valid exception return codes have bit 0 set too.
144 if (num == ARMV7M_R14)
145 value |= 0x01;
146 #endif
148 /* NOTE: we "know" here that the register identifiers used
149 * in the v7m header match the Cortex-M3 Debug Core Register
150 * Selector values for R0..R15, xPSR, MSP, and PSP.
152 switch (num) {
153 case 0 ... 18:
154 retval = stlink_if->layout->api->write_reg(stlink_if->fd, num, value);
156 if (retval != ERROR_OK) {
157 struct reg *r;
159 LOG_ERROR("JTAG failure");
160 r = armv7m->core_cache->reg_list + num;
161 r->dirty = r->valid;
162 return ERROR_JTAG_DEVICE_ERROR;
164 LOG_DEBUG("write core reg %i value 0x%" PRIx32 "", (int)num, value);
165 break;
167 case 33:
168 case 64 ... 96:
169 /* Floating-point Status and Registers */
170 retval = target_write_u32(target, ARMV7M_SCS_DCRDR, value);
171 if (retval != ERROR_OK)
172 return retval;
173 retval = target_write_u32(target, ARMV7M_SCS_DCRSR, num | (1<<16));
174 if (retval != ERROR_OK)
175 return retval;
176 LOG_DEBUG("write core reg %i value 0x%" PRIx32 "", (int)num, value);
177 break;
179 case ARMV7M_PRIMASK:
180 case ARMV7M_BASEPRI:
181 case ARMV7M_FAULTMASK:
182 case ARMV7M_CONTROL:
183 /* Cortex-M3 packages these four registers as bitfields
184 * in one Debug Core register. So say r0 and r2 docs;
185 * it was removed from r1 docs, but still works.
188 stlink_if->layout->api->read_reg(stlink_if->fd, 20, &reg);
190 switch (num) {
191 case ARMV7M_PRIMASK:
192 buf_set_u32((uint8_t *) &reg, 0, 1, value);
193 break;
195 case ARMV7M_BASEPRI:
196 buf_set_u32((uint8_t *) &reg, 8, 8, value);
197 break;
199 case ARMV7M_FAULTMASK:
200 buf_set_u32((uint8_t *) &reg, 16, 1, value);
201 break;
203 case ARMV7M_CONTROL:
204 buf_set_u32((uint8_t *) &reg, 24, 2, value);
205 break;
208 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;
213 default:
214 return ERROR_COMMAND_SYNTAX_ERROR;
217 return ERROR_OK;
220 static int stm32_stlink_examine_debug_reason(struct target *target)
222 if ((target->debug_reason != DBG_REASON_DBGRQ)
223 && (target->debug_reason != DBG_REASON_SINGLESTEP)) {
224 target->debug_reason = DBG_REASON_BREAKPOINT;
227 return ERROR_OK;
230 static int stm32_stlink_init_arch_info(struct target *target,
231 struct cortex_m3_common *cortex_m3,
232 struct jtag_tap *tap)
234 struct armv7m_common *armv7m;
236 LOG_DEBUG("%s", __func__);
238 armv7m = &cortex_m3->armv7m;
239 armv7m_init_arch_info(target, armv7m);
241 armv7m->load_core_reg_u32 = stm32_stlink_load_core_reg_u32;
242 armv7m->store_core_reg_u32 = stm32_stlink_store_core_reg_u32;
244 armv7m->examine_debug_reason = stm32_stlink_examine_debug_reason;
246 return ERROR_OK;
249 static int stm32_stlink_init_target(struct command_context *cmd_ctx,
250 struct target *target)
252 LOG_DEBUG("%s", __func__);
254 armv7m_build_reg_cache(target);
256 return ERROR_OK;
259 static int stm32_stlink_target_create(struct target *target,
260 Jim_Interp *interp)
262 LOG_DEBUG("%s", __func__);
264 struct cortex_m3_common *cortex_m3 = calloc(1, sizeof(struct cortex_m3_common));
266 if (!cortex_m3)
267 return ERROR_COMMAND_SYNTAX_ERROR;
269 stm32_stlink_init_arch_info(target, cortex_m3, target->tap);
271 return ERROR_OK;
274 static int stm32_stlink_load_context(struct target *target)
276 struct armv7m_common *armv7m = target_to_armv7m(target);
277 int num_regs = armv7m->core_cache->num_regs;
279 for (int i = 0; i < num_regs; i++) {
280 if (!armv7m->core_cache->reg_list[i].valid)
281 armv7m->read_core_reg(target, i);
284 return ERROR_OK;
287 static int stlink_debug_entry(struct target *target)
289 struct armv7m_common *armv7m = target_to_armv7m(target);
290 struct arm *arm = &armv7m->arm;
291 struct reg *r;
292 uint32_t xPSR;
293 int retval;
295 retval = armv7m->examine_debug_reason(target);
296 if (retval != ERROR_OK)
297 return retval;
299 stm32_stlink_load_context(target);
301 r = armv7m->core_cache->reg_list + ARMV7M_xPSR;
302 xPSR = buf_get_u32(r->value, 0, 32);
304 /* Are we in an exception handler */
305 if (xPSR & 0x1FF) {
306 armv7m->core_mode = ARMV7M_MODE_HANDLER;
307 armv7m->exception_number = (xPSR & 0x1FF);
309 arm->core_mode = ARM_MODE_HANDLER;
310 arm->map = armv7m_msp_reg_map;
311 } else {
312 unsigned control = buf_get_u32(armv7m->core_cache
313 ->reg_list[ARMV7M_CONTROL].value, 0, 2);
315 /* is this thread privileged? */
316 armv7m->core_mode = control & 1;
317 arm->core_mode = armv7m->core_mode
318 ? ARM_MODE_USER_THREAD
319 : ARM_MODE_THREAD;
321 /* which stack is it using? */
322 if (control & 2)
323 arm->map = armv7m_psp_reg_map;
324 else
325 arm->map = armv7m_msp_reg_map;
327 armv7m->exception_number = 0;
330 LOG_DEBUG("entered debug state in core mode: %s at PC 0x%" PRIx32 ", target->state: %s",
331 armv7m_mode_strings[armv7m->core_mode],
332 *(uint32_t *)(arm->pc->value),
333 target_state_name(target));
335 return retval;
338 static int stm32_stlink_poll(struct target *target)
340 enum target_state state;
341 struct stlink_interface_s *stlink_if = target_to_stlink(target);
342 struct armv7m_common *armv7m = target_to_armv7m(target);
344 state = stlink_if->layout->api->state(stlink_if->fd);
346 if (state == TARGET_UNKNOWN) {
347 LOG_ERROR("jtag status contains invalid mode value - communication failure");
348 return ERROR_TARGET_FAILURE;
351 if (target->state == state)
352 return ERROR_OK;
354 if (state == TARGET_HALTED) {
355 target->state = state;
357 int retval = stlink_debug_entry(target);
358 if (retval != ERROR_OK)
359 return retval;
361 if (arm_semihosting(target, &retval) != 0)
362 return retval;
364 target_call_event_callbacks(target, TARGET_EVENT_HALTED);
365 LOG_DEBUG("halted: PC: 0x%x", buf_get_u32(armv7m->arm.pc->value, 0, 32));
368 return ERROR_OK;
371 static int stm32_stlink_assert_reset(struct target *target)
373 int res;
374 struct stlink_interface_s *stlink_if = target_to_stlink(target);
375 struct armv7m_common *armv7m = target_to_armv7m(target);
377 LOG_DEBUG("%s", __func__);
379 res = stlink_if->layout->api->reset(stlink_if->fd);
381 if (res != ERROR_OK)
382 return res;
384 /* virtual assert reset, we need it for the internal
385 * jtag state machine
387 jtag_add_reset(1, 1);
389 /* registers are now invalid */
390 register_cache_invalidate(armv7m->core_cache);
392 if (target->reset_halt) {
393 target->state = TARGET_RESET;
394 target->debug_reason = DBG_REASON_DBGRQ;
395 } else {
396 target->state = TARGET_HALTED;
399 return ERROR_OK;
402 static int stm32_stlink_deassert_reset(struct target *target)
404 int res;
406 LOG_DEBUG("%s", __func__);
408 /* virtual deassert reset, we need it for the internal
409 * jtag state machine
411 jtag_add_reset(0, 0);
413 if (!target->reset_halt) {
414 res = target_resume(target, 1, 0, 0, 0);
416 if (res != ERROR_OK)
417 return res;
420 return ERROR_OK;
423 static int stm32_stlink_soft_reset_halt(struct target *target)
425 LOG_DEBUG("%s", __func__);
426 return ERROR_OK;
429 static int stm32_stlink_halt(struct target *target)
431 int res;
432 struct stlink_interface_s *stlink_if = target_to_stlink(target);
434 LOG_DEBUG("%s", __func__);
436 if (target->state == TARGET_HALTED) {
437 LOG_DEBUG("target was already halted");
438 return ERROR_OK;
441 if (target->state == TARGET_UNKNOWN)
442 LOG_WARNING("target was in unknown state when halt was requested");
444 res = stlink_if->layout->api->halt(stlink_if->fd);
446 if (res != ERROR_OK)
447 return res;
449 target->debug_reason = DBG_REASON_DBGRQ;
451 return ERROR_OK;
454 static int stm32_stlink_resume(struct target *target, int current,
455 uint32_t address, int handle_breakpoints,
456 int debug_execution)
458 int res;
459 struct stlink_interface_s *stlink_if = target_to_stlink(target);
460 struct armv7m_common *armv7m = target_to_armv7m(target);
461 uint32_t resume_pc;
462 struct breakpoint *breakpoint = NULL;
463 struct reg *pc;
465 LOG_DEBUG("%s %d %x %d %d", __func__, current, address,
466 handle_breakpoints, debug_execution);
468 if (target->state != TARGET_HALTED) {
469 LOG_WARNING("target not halted");
470 return ERROR_TARGET_NOT_HALTED;
473 pc = armv7m->arm.pc;
474 if (!current) {
475 buf_set_u32(pc->value, 0, 32, address);
476 pc->dirty = true;
477 pc->valid = true;
480 if (!breakpoint_find(target, buf_get_u32(pc->value, 0, 32))
481 && !debug_execution) {
482 armv7m_maybe_skip_bkpt_inst(target, NULL);
485 resume_pc = buf_get_u32(pc->value, 0, 32);
487 armv7m_restore_context(target);
489 /* registers are now invalid */
490 register_cache_invalidate(armv7m->core_cache);
492 /* the front-end may request us not to handle breakpoints */
493 if (handle_breakpoints) {
494 /* Single step past breakpoint at current address */
495 breakpoint = breakpoint_find(target, resume_pc);
496 if (breakpoint) {
497 LOG_DEBUG("unset breakpoint at 0x%8.8" PRIx32 " (ID: %d)",
498 breakpoint->address,
499 breakpoint->unique_id);
500 cortex_m3_unset_breakpoint(target, breakpoint);
502 res = stlink_if->layout->api->step(stlink_if->fd);
504 if (res != ERROR_OK)
505 return res;
507 cortex_m3_set_breakpoint(target, breakpoint);
511 res = stlink_if->layout->api->run(stlink_if->fd);
513 if (res != ERROR_OK)
514 return res;
516 target->state = TARGET_RUNNING;
518 target_call_event_callbacks(target, TARGET_EVENT_RESUMED);
520 return ERROR_OK;
523 static int stm32_stlink_step(struct target *target, int current,
524 uint32_t address, int handle_breakpoints)
526 int res;
527 struct stlink_interface_s *stlink_if = target_to_stlink(target);
528 struct armv7m_common *armv7m = target_to_armv7m(target);
529 struct breakpoint *breakpoint = NULL;
530 struct reg *pc = armv7m->arm.pc;
531 bool bkpt_inst_found = false;
533 LOG_DEBUG("%s", __func__);
535 if (target->state != TARGET_HALTED) {
536 LOG_WARNING("target not halted");
537 return ERROR_TARGET_NOT_HALTED;
540 if (!current) {
541 buf_set_u32(pc->value, 0, 32, address);
542 pc->dirty = true;
543 pc->valid = true;
546 uint32_t pc_value = buf_get_u32(pc->value, 0, 32);
548 /* the front-end may request us not to handle breakpoints */
549 if (handle_breakpoints) {
550 breakpoint = breakpoint_find(target, pc_value);
551 if (breakpoint)
552 cortex_m3_unset_breakpoint(target, breakpoint);
555 armv7m_maybe_skip_bkpt_inst(target, &bkpt_inst_found);
557 target->debug_reason = DBG_REASON_SINGLESTEP;
559 armv7m_restore_context(target);
561 target_call_event_callbacks(target, TARGET_EVENT_RESUMED);
563 res = stlink_if->layout->api->step(stlink_if->fd);
565 if (res != ERROR_OK)
566 return res;
568 /* registers are now invalid */
569 register_cache_invalidate(armv7m->core_cache);
571 if (breakpoint)
572 cortex_m3_set_breakpoint(target, breakpoint);
574 stlink_debug_entry(target);
575 target_call_event_callbacks(target, TARGET_EVENT_HALTED);
577 LOG_INFO("halted: PC: 0x%x", buf_get_u32(armv7m->arm.pc->value, 0, 32));
579 return ERROR_OK;
582 static int stm32_stlink_read_memory(struct target *target, uint32_t address,
583 uint32_t size, uint32_t count,
584 uint8_t *buffer)
586 int res;
587 uint32_t buffer_threshold = 128;
588 uint32_t addr_increment = 4;
589 uint32_t c;
590 struct stlink_interface_s *stlink_if = target_to_stlink(target);
592 if (!count || !buffer)
593 return ERROR_COMMAND_SYNTAX_ERROR;
595 LOG_DEBUG("%s %x %d %d", __func__, address, size, count);
597 /* prepare byte count, buffer threshold
598 * and address increment for none 32bit access
600 if (size != 4) {
601 count *= size;
602 buffer_threshold = 64;
603 addr_increment = 1;
606 while (count) {
607 if (count > buffer_threshold)
608 c = buffer_threshold;
609 else
610 c = count;
612 if (size != 4)
613 res = stlink_if->layout->api->read_mem8(stlink_if->fd,
614 address, c, buffer);
615 else
616 res = stlink_if->layout->api->read_mem32(stlink_if->fd,
617 address, c, buffer);
619 if (res != ERROR_OK)
620 return res;
622 address += (c * addr_increment);
623 buffer += (c * addr_increment);
624 count -= c;
627 return ERROR_OK;
630 static int stm32_stlink_write_memory(struct target *target, uint32_t address,
631 uint32_t size, uint32_t count,
632 const uint8_t *buffer)
634 int res;
635 uint32_t buffer_threshold = 128;
636 uint32_t addr_increment = 4;
637 uint32_t c;
638 struct stlink_interface_s *stlink_if = target_to_stlink(target);
640 if (!count || !buffer)
641 return ERROR_COMMAND_SYNTAX_ERROR;
643 LOG_DEBUG("%s %x %d %d", __func__, address, size, count);
645 /* prepare byte count, buffer threshold
646 * and address increment for none 32bit access
648 if (size != 4) {
649 count *= size;
650 buffer_threshold = 64;
651 addr_increment = 1;
654 while (count) {
655 if (count > buffer_threshold)
656 c = buffer_threshold;
657 else
658 c = count;
660 if (size != 4)
661 res = stlink_if->layout->api->write_mem8(stlink_if->fd,
662 address, c, buffer);
663 else
664 res = stlink_if->layout->api->write_mem32(stlink_if->fd,
665 address, c, buffer);
667 if (res != ERROR_OK)
668 return res;
670 address += (c * addr_increment);
671 buffer += (c * addr_increment);
672 count -= c;
675 return ERROR_OK;
678 static int stm32_stlink_bulk_write_memory(struct target *target,
679 uint32_t address, uint32_t count,
680 const uint8_t *buffer)
682 return stm32_stlink_write_memory(target, address, 4, count, buffer);
685 struct target_type stm32_stlink_target = {
686 .name = "stm32_stlink",
688 .init_target = stm32_stlink_init_target,
689 .target_create = stm32_stlink_target_create,
690 .examine = cortex_m3_examine,
692 .poll = stm32_stlink_poll,
693 .arch_state = armv7m_arch_state,
695 .assert_reset = stm32_stlink_assert_reset,
696 .deassert_reset = stm32_stlink_deassert_reset,
697 .soft_reset_halt = stm32_stlink_soft_reset_halt,
699 .halt = stm32_stlink_halt,
700 .resume = stm32_stlink_resume,
701 .step = stm32_stlink_step,
703 .get_gdb_reg_list = armv7m_get_gdb_reg_list,
705 .read_memory = stm32_stlink_read_memory,
706 .write_memory = stm32_stlink_write_memory,
707 .bulk_write_memory = stm32_stlink_bulk_write_memory,
708 .checksum_memory = armv7m_checksum_memory,
709 .blank_check_memory = armv7m_blank_check_memory,
711 .run_algorithm = armv7m_run_algorithm,
712 .start_algorithm = armv7m_start_algorithm,
713 .wait_algorithm = armv7m_wait_algorithm,
715 .add_breakpoint = cortex_m3_add_breakpoint,
716 .remove_breakpoint = cortex_m3_remove_breakpoint,
717 .add_watchpoint = cortex_m3_add_watchpoint,
718 .remove_watchpoint = cortex_m3_remove_watchpoint,