stm32: determine all cpu types and use common examine
[openocd.git] / src / target / stm32_stlink.c
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
24 #ifdef HAVE_CONFIG_H
25 #include "config.h"
26 #endif
27
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"
40
41 static inline struct stlink_interface_s *target_to_stlink(struct target *target)
42 {
43 return target->tap->priv;
44 }
45
46 static int stm32_stlink_load_core_reg_u32(struct target *target,
47 enum armv7m_regtype type,
48 uint32_t num, uint32_t *value)
49 {
50 int retval;
51 struct stlink_interface_s *stlink_if = target_to_stlink(target);
52
53 LOG_DEBUG("%s", __func__);
54
55 /* NOTE: we "know" here that the register identifiers used
56 * in the v7m header match the Cortex-M3 Debug Core Register
57 * Selector values for R0..R15, xPSR, MSP, and PSP.
58 */
59 switch (num) {
60 case 0 ... 18:
61 /* read a normal core register */
62 retval = stlink_if->layout->api->read_reg(stlink_if->fd, num, value);
63
64 if (retval != ERROR_OK) {
65 LOG_ERROR("JTAG failure %i", retval);
66 return ERROR_JTAG_DEVICE_ERROR;
67 }
68 LOG_DEBUG("load from core reg %i value 0x%" PRIx32 "",
69 (int)num, *value);
70 break;
71
72 case ARMV7M_PRIMASK:
73 case ARMV7M_BASEPRI:
74 case ARMV7M_FAULTMASK:
75 case ARMV7M_CONTROL:
76 /* Cortex-M3 packages these four registers as bitfields
77 * in one Debug Core register. So say r0 and r2 docs;
78 * it was removed from r1 docs, but still works.
79 */
80 retval = stlink_if->layout->api->read_reg(stlink_if->fd, 20, value);
81
82 switch (num) {
83 case ARMV7M_PRIMASK:
84 *value = buf_get_u32((uint8_t *) value, 0, 1);
85 break;
86
87 case ARMV7M_BASEPRI:
88 *value = buf_get_u32((uint8_t *) value, 8, 8);
89 break;
90
91 case ARMV7M_FAULTMASK:
92 *value = buf_get_u32((uint8_t *) value, 16, 1);
93 break;
94
95 case ARMV7M_CONTROL:
96 *value = buf_get_u32((uint8_t *) value, 24, 2);
97 break;
98 }
99
100 LOG_DEBUG("load from special reg %i value 0x%" PRIx32 "",
101 (int)num, *value);
102 break;
103
104 default:
105 return ERROR_COMMAND_SYNTAX_ERROR;
106 }
107
108 return ERROR_OK;
109 }
110
111 static int stm32_stlink_store_core_reg_u32(struct target *target,
112 enum armv7m_regtype type,
113 uint32_t num, uint32_t value)
114 {
115 int retval;
116 uint32_t reg;
117 struct armv7m_common *armv7m = target_to_armv7m(target);
118 struct stlink_interface_s *stlink_if = target_to_stlink(target);
119
120 LOG_DEBUG("%s", __func__);
121
122 #ifdef ARMV7_GDB_HACKS
123 /* If the LR register is being modified, make sure it will put us
124 * in "thumb" mode, or an INVSTATE exception will occur. This is a
125 * hack to deal with the fact that gdb will sometimes "forge"
126 * return addresses, and doesn't set the LSB correctly (i.e., when
127 * printing expressions containing function calls, it sets LR = 0.)
128 * Valid exception return codes have bit 0 set too.
129 */
130 if (num == ARMV7M_R14)
131 value |= 0x01;
132 #endif
133
134 /* NOTE: we "know" here that the register identifiers used
135 * in the v7m header match the Cortex-M3 Debug Core Register
136 * Selector values for R0..R15, xPSR, MSP, and PSP.
137 */
138 switch (num) {
139 case 0 ... 18:
140 retval = stlink_if->layout->api->write_reg(stlink_if->fd, num, value);
141
142 if (retval != ERROR_OK) {
143 struct reg *r;
144
145 LOG_ERROR("JTAG failure");
146 r = armv7m->core_cache->reg_list + num;
147 r->dirty = r->valid;
148 return ERROR_JTAG_DEVICE_ERROR;
149 }
150 LOG_DEBUG("write core reg %i value 0x%" PRIx32 "", (int)num, value);
151 break;
152
153 case ARMV7M_PRIMASK:
154 case ARMV7M_BASEPRI:
155 case ARMV7M_FAULTMASK:
156 case ARMV7M_CONTROL:
157 /* Cortex-M3 packages these four registers as bitfields
158 * in one Debug Core register. So say r0 and r2 docs;
159 * it was removed from r1 docs, but still works.
160 */
161
162 stlink_if->layout->api->read_reg(stlink_if->fd, 20, &reg);
163
164 switch (num) {
165 case ARMV7M_PRIMASK:
166 buf_set_u32((uint8_t *) &reg, 0, 1, value);
167 break;
168
169 case ARMV7M_BASEPRI:
170 buf_set_u32((uint8_t *) &reg, 8, 8, value);
171 break;
172
173 case ARMV7M_FAULTMASK:
174 buf_set_u32((uint8_t *) &reg, 16, 1, value);
175 break;
176
177 case ARMV7M_CONTROL:
178 buf_set_u32((uint8_t *) &reg, 24, 2, value);
179 break;
180 }
181
182 stlink_if->layout->api->write_reg(stlink_if->fd, 20, reg);
183
184 LOG_DEBUG("write special reg %i value 0x%" PRIx32 " ", (int)num, value);
185 break;
186
187 default:
188 return ERROR_COMMAND_SYNTAX_ERROR;
189 }
190
191 return ERROR_OK;
192 }
193
194 static int stm32_stlink_examine_debug_reason(struct target *target)
195 {
196 if ((target->debug_reason != DBG_REASON_DBGRQ)
197 && (target->debug_reason != DBG_REASON_SINGLESTEP)) {
198 target->debug_reason = DBG_REASON_BREAKPOINT;
199 }
200
201 return ERROR_OK;
202 }
203
204 static int stm32_stlink_init_arch_info(struct target *target,
205 struct cortex_m3_common *cortex_m3,
206 struct jtag_tap *tap)
207 {
208 struct armv7m_common *armv7m;
209
210 LOG_DEBUG("%s", __func__);
211
212 armv7m = &cortex_m3->armv7m;
213 armv7m_init_arch_info(target, armv7m);
214
215 armv7m->load_core_reg_u32 = stm32_stlink_load_core_reg_u32;
216 armv7m->store_core_reg_u32 = stm32_stlink_store_core_reg_u32;
217
218 armv7m->examine_debug_reason = stm32_stlink_examine_debug_reason;
219
220 return ERROR_OK;
221 }
222
223 static int stm32_stlink_init_target(struct command_context *cmd_ctx,
224 struct target *target)
225 {
226 LOG_DEBUG("%s", __func__);
227
228 armv7m_build_reg_cache(target);
229
230 return ERROR_OK;
231 }
232
233 static int stm32_stlink_target_create(struct target *target,
234 Jim_Interp *interp)
235 {
236 LOG_DEBUG("%s", __func__);
237
238 struct cortex_m3_common *cortex_m3 = calloc(1, sizeof(struct cortex_m3_common));
239
240 if (!cortex_m3)
241 return ERROR_COMMAND_SYNTAX_ERROR;
242
243 stm32_stlink_init_arch_info(target, cortex_m3, target->tap);
244
245 return ERROR_OK;
246 }
247
248 static int stm32_stlink_load_context(struct target *target)
249 {
250 struct armv7m_common *armv7m = target_to_armv7m(target);
251 int num_regs = armv7m->core_cache->num_regs;
252
253 for (int i = 0; i < num_regs; i++) {
254 if (!armv7m->core_cache->reg_list[i].valid)
255 armv7m->read_core_reg(target, i);
256 }
257
258 return ERROR_OK;
259 }
260
261 static int stlink_debug_entry(struct target *target)
262 {
263 struct armv7m_common *armv7m = target_to_armv7m(target);
264 struct arm *arm = &armv7m->arm;
265 struct reg *r;
266 uint32_t xPSR;
267 int retval;
268
269 retval = armv7m->examine_debug_reason(target);
270 if (retval != ERROR_OK)
271 return retval;
272
273 stm32_stlink_load_context(target);
274
275 r = armv7m->core_cache->reg_list + ARMV7M_xPSR;
276 xPSR = buf_get_u32(r->value, 0, 32);
277
278 /* Are we in an exception handler */
279 if (xPSR & 0x1FF) {
280 armv7m->core_mode = ARMV7M_MODE_HANDLER;
281 armv7m->exception_number = (xPSR & 0x1FF);
282
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
289 /* is this thread privileged? */
290 armv7m->core_mode = control & 1;
291 arm->core_mode = armv7m->core_mode
292 ? ARM_MODE_USER_THREAD
293 : ARM_MODE_THREAD;
294
295 /* which stack is it using? */
296 if (control & 2)
297 arm->map = armv7m_psp_reg_map;
298 else
299 arm->map = armv7m_msp_reg_map;
300
301 armv7m->exception_number = 0;
302 }
303
304 LOG_DEBUG("entered debug state in core mode: %s at PC 0x%" PRIx32 ", target->state: %s",
305 armv7m_mode_strings[armv7m->core_mode],
306 *(uint32_t *)(arm->pc->value),
307 target_state_name(target));
308
309 return retval;
310 }
311
312 static int stm32_stlink_poll(struct target *target)
313 {
314 enum target_state state;
315 struct stlink_interface_s *stlink_if = target_to_stlink(target);
316 struct armv7m_common *armv7m = target_to_armv7m(target);
317
318 state = stlink_if->layout->api->state(stlink_if->fd);
319
320 if (state == TARGET_UNKNOWN) {
321 LOG_ERROR("jtag status contains invalid mode value - communication failure");
322 return ERROR_TARGET_FAILURE;
323 }
324
325 if (target->state == state)
326 return ERROR_OK;
327
328 if (state == TARGET_HALTED) {
329 target->state = state;
330
331 int retval = stlink_debug_entry(target);
332 if (retval != ERROR_OK)
333 return retval;
334
335 if (arm_semihosting(target, &retval) != 0)
336 return retval;
337
338 target_call_event_callbacks(target, TARGET_EVENT_HALTED);
339 LOG_DEBUG("halted: PC: 0x%x", buf_get_u32(armv7m->arm.pc->value, 0, 32));
340 }
341
342 return ERROR_OK;
343 }
344
345 static int stm32_stlink_assert_reset(struct target *target)
346 {
347 int res;
348 struct stlink_interface_s *stlink_if = target_to_stlink(target);
349 struct armv7m_common *armv7m = target_to_armv7m(target);
350
351 LOG_DEBUG("%s", __func__);
352
353 res = stlink_if->layout->api->reset(stlink_if->fd);
354
355 if (res != ERROR_OK)
356 return res;
357
358 /* virtual assert reset, we need it for the internal
359 * jtag state machine
360 */
361 jtag_add_reset(1, 1);
362
363 /* registers are now invalid */
364 register_cache_invalidate(armv7m->core_cache);
365
366 if (target->reset_halt) {
367 target->state = TARGET_RESET;
368 target->debug_reason = DBG_REASON_DBGRQ;
369 } else {
370 target->state = TARGET_HALTED;
371 }
372
373 return ERROR_OK;
374 }
375
376 static int stm32_stlink_deassert_reset(struct target *target)
377 {
378 int res;
379
380 LOG_DEBUG("%s", __func__);
381
382 /* virtual deassert reset, we need it for the internal
383 * jtag state machine
384 */
385 jtag_add_reset(0, 0);
386
387 if (!target->reset_halt) {
388 res = target_resume(target, 1, 0, 0, 0);
389
390 if (res != ERROR_OK)
391 return res;
392 }
393
394 return ERROR_OK;
395 }
396
397 static int stm32_stlink_soft_reset_halt(struct target *target)
398 {
399 LOG_DEBUG("%s", __func__);
400 return ERROR_OK;
401 }
402
403 static int stm32_stlink_halt(struct target *target)
404 {
405 int res;
406 struct stlink_interface_s *stlink_if = target_to_stlink(target);
407
408 LOG_DEBUG("%s", __func__);
409
410 if (target->state == TARGET_HALTED) {
411 LOG_DEBUG("target was already halted");
412 return ERROR_OK;
413 }
414
415 if (target->state == TARGET_UNKNOWN)
416 LOG_WARNING("target was in unknown state when halt was requested");
417
418 res = stlink_if->layout->api->halt(stlink_if->fd);
419
420 if (res != ERROR_OK)
421 return res;
422
423 target->debug_reason = DBG_REASON_DBGRQ;
424
425 return ERROR_OK;
426 }
427
428 static int stm32_stlink_resume(struct target *target, int current,
429 uint32_t address, int handle_breakpoints,
430 int debug_execution)
431 {
432 int res;
433 struct stlink_interface_s *stlink_if = target_to_stlink(target);
434 struct armv7m_common *armv7m = target_to_armv7m(target);
435 uint32_t resume_pc;
436 struct breakpoint *breakpoint = NULL;
437 struct reg *pc;
438
439 LOG_DEBUG("%s %d %x %d %d", __func__, current, address,
440 handle_breakpoints, debug_execution);
441
442 if (target->state != TARGET_HALTED) {
443 LOG_WARNING("target not halted");
444 return ERROR_TARGET_NOT_HALTED;
445 }
446
447 pc = armv7m->arm.pc;
448 if (!current) {
449 buf_set_u32(pc->value, 0, 32, address);
450 pc->dirty = true;
451 pc->valid = true;
452 }
453
454 if (!breakpoint_find(target, buf_get_u32(pc->value, 0, 32))
455 && !debug_execution) {
456 armv7m_maybe_skip_bkpt_inst(target, NULL);
457 }
458
459 resume_pc = buf_get_u32(pc->value, 0, 32);
460
461 armv7m_restore_context(target);
462
463 /* registers are now invalid */
464 register_cache_invalidate(armv7m->core_cache);
465
466 /* the front-end may request us not to handle breakpoints */
467 if (handle_breakpoints) {
468 /* Single step past breakpoint at current address */
469 breakpoint = breakpoint_find(target, resume_pc);
470 if (breakpoint) {
471 LOG_DEBUG("unset breakpoint at 0x%8.8" PRIx32 " (ID: %d)",
472 breakpoint->address,
473 breakpoint->unique_id);
474 cortex_m3_unset_breakpoint(target, breakpoint);
475
476 res = stlink_if->layout->api->step(stlink_if->fd);
477
478 if (res != ERROR_OK)
479 return res;
480
481 cortex_m3_set_breakpoint(target, breakpoint);
482 }
483 }
484
485 res = stlink_if->layout->api->run(stlink_if->fd);
486
487 if (res != ERROR_OK)
488 return res;
489
490 target->state = TARGET_RUNNING;
491
492 target_call_event_callbacks(target, TARGET_EVENT_RESUMED);
493
494 return ERROR_OK;
495 }
496
497 static int stm32_stlink_step(struct target *target, int current,
498 uint32_t address, int handle_breakpoints)
499 {
500 int res;
501 struct stlink_interface_s *stlink_if = target_to_stlink(target);
502 struct armv7m_common *armv7m = target_to_armv7m(target);
503 struct breakpoint *breakpoint = NULL;
504 struct reg *pc = armv7m->arm.pc;
505 bool bkpt_inst_found = false;
506
507 LOG_DEBUG("%s", __func__);
508
509 if (target->state != TARGET_HALTED) {
510 LOG_WARNING("target not halted");
511 return ERROR_TARGET_NOT_HALTED;
512 }
513
514 if (!current) {
515 buf_set_u32(pc->value, 0, 32, address);
516 pc->dirty = true;
517 pc->valid = true;
518 }
519
520 uint32_t pc_value = buf_get_u32(pc->value, 0, 32);
521
522 /* the front-end may request us not to handle breakpoints */
523 if (handle_breakpoints) {
524 breakpoint = breakpoint_find(target, pc_value);
525 if (breakpoint)
526 cortex_m3_unset_breakpoint(target, breakpoint);
527 }
528
529 armv7m_maybe_skip_bkpt_inst(target, &bkpt_inst_found);
530
531 target->debug_reason = DBG_REASON_SINGLESTEP;
532
533 armv7m_restore_context(target);
534
535 target_call_event_callbacks(target, TARGET_EVENT_RESUMED);
536
537 res = stlink_if->layout->api->step(stlink_if->fd);
538
539 if (res != ERROR_OK)
540 return res;
541
542 /* registers are now invalid */
543 register_cache_invalidate(armv7m->core_cache);
544
545 if (breakpoint)
546 cortex_m3_set_breakpoint(target, breakpoint);
547
548 stlink_debug_entry(target);
549 target_call_event_callbacks(target, TARGET_EVENT_HALTED);
550
551 LOG_INFO("halted: PC: 0x%x", buf_get_u32(armv7m->arm.pc->value, 0, 32));
552
553 return ERROR_OK;
554 }
555
556 static int stm32_stlink_read_memory(struct target *target, uint32_t address,
557 uint32_t size, uint32_t count,
558 uint8_t *buffer)
559 {
560 int res;
561 uint32_t buffer_threshold = 128;
562 uint32_t addr_increment = 4;
563 uint8_t *dst = buffer;
564 uint32_t c;
565 struct stlink_interface_s *stlink_if = target_to_stlink(target);
566
567 if (!count || !buffer)
568 return ERROR_COMMAND_SYNTAX_ERROR;
569
570 LOG_DEBUG("%s %x %d %d", __func__, address, size, count);
571
572 /* prepare byte count, buffer threshold
573 * and address increment for none 32bit access
574 */
575 if (size != 4) {
576 count *= size;
577 buffer_threshold = 64;
578 addr_increment = 1;
579 }
580
581 while (count) {
582 if (count > buffer_threshold)
583 c = buffer_threshold;
584 else
585 c = count;
586
587 if (size != 4)
588 res = stlink_if->layout->api->read_mem8(stlink_if->fd,
589 address, c, dst);
590 else
591 res = stlink_if->layout->api->read_mem32(stlink_if->fd,
592 address, c, (uint32_t *)dst);
593
594 if (res != ERROR_OK)
595 return res;
596
597 address += (c * addr_increment);
598 dst += (c * addr_increment);
599 count -= c;
600 }
601
602 return ERROR_OK;
603 }
604
605 static int stm32_stlink_write_memory(struct target *target, uint32_t address,
606 uint32_t size, uint32_t count,
607 const uint8_t *buffer)
608 {
609 int res;
610 uint32_t buffer_threshold = 128;
611 uint32_t addr_increment = 4;
612 const uint8_t *dst = buffer;
613 uint32_t c;
614 struct stlink_interface_s *stlink_if = target_to_stlink(target);
615
616 if (!count || !buffer)
617 return ERROR_COMMAND_SYNTAX_ERROR;
618
619 LOG_DEBUG("%s %x %d %d", __func__, address, size, count);
620
621 /* prepare byte count, buffer threshold
622 * and address increment for none 32bit access
623 */
624 if (size != 4) {
625 count *= size;
626 buffer_threshold = 64;
627 addr_increment = 1;
628 }
629
630 while (count) {
631 if (count > buffer_threshold)
632 c = buffer_threshold;
633 else
634 c = count;
635
636 if (size != 4)
637 res = stlink_if->layout->api->write_mem8(stlink_if->fd,
638 address, c, dst);
639 else
640 res = stlink_if->layout->api->write_mem32(stlink_if->fd,
641 address, c, (uint32_t *)dst);
642
643 if (res != ERROR_OK)
644 return res;
645
646 address += (c * addr_increment);
647 dst += (c * addr_increment);
648 count -= c;
649 }
650
651 return ERROR_OK;
652 }
653
654 static int stm32_stlink_bulk_write_memory(struct target *target,
655 uint32_t address, uint32_t count,
656 const uint8_t *buffer)
657 {
658 return stm32_stlink_write_memory(target, address, 4, count, buffer);
659 }
660
661 struct target_type stm32_stlink_target = {
662 .name = "stm32_stlink",
663
664 .init_target = stm32_stlink_init_target,
665 .target_create = stm32_stlink_target_create,
666 .examine = cortex_m3_examine,
667
668 .poll = stm32_stlink_poll,
669 .arch_state = armv7m_arch_state,
670
671 .assert_reset = stm32_stlink_assert_reset,
672 .deassert_reset = stm32_stlink_deassert_reset,
673 .soft_reset_halt = stm32_stlink_soft_reset_halt,
674
675 .halt = stm32_stlink_halt,
676 .resume = stm32_stlink_resume,
677 .step = stm32_stlink_step,
678
679 .get_gdb_reg_list = armv7m_get_gdb_reg_list,
680
681 .read_memory = stm32_stlink_read_memory,
682 .write_memory = stm32_stlink_write_memory,
683 .bulk_write_memory = stm32_stlink_bulk_write_memory,
684 .checksum_memory = armv7m_checksum_memory,
685 .blank_check_memory = armv7m_blank_check_memory,
686
687 .run_algorithm = armv7m_run_algorithm,
688 .start_algorithm = armv7m_start_algorithm,
689 .wait_algorithm = armv7m_wait_algorithm,
690
691 .add_breakpoint = cortex_m3_add_breakpoint,
692 .remove_breakpoint = cortex_m3_remove_breakpoint,
693 .add_watchpoint = cortex_m3_add_watchpoint,
694 .remove_watchpoint = cortex_m3_remove_watchpoint,
695 };

Linking to existing account procedure

If you already have an account and want to add another login method you MUST first sign in with your existing account and then change URL to read https://review.openocd.org/login/?link to get to this page again but this time it'll work for linking. Thank you.

SSH host keys fingerprints

1024 SHA256:YKx8b7u5ZWdcbp7/4AeXNaqElP49m6QrwfXaqQGJAOk gerrit-code-review@openocd.zylin.com (DSA)
384 SHA256:jHIbSQa4REvwCFG4cq5LBlBLxmxSqelQPem/EXIrxjk gerrit-code-review@openocd.org (ECDSA)
521 SHA256:UAOPYkU9Fjtcao0Ul/Rrlnj/OsQvt+pgdYSZ4jOYdgs gerrit-code-review@openocd.org (ECDSA)
256 SHA256:A13M5QlnozFOvTllybRZH6vm7iSt0XLxbA48yfc2yfY gerrit-code-review@openocd.org (ECDSA)
256 SHA256:spYMBqEYoAOtK7yZBrcwE8ZpYt6b68Cfh9yEVetvbXg gerrit-code-review@openocd.org (ED25519)
+--[ED25519 256]--+
|=..              |
|+o..   .         |
|*.o   . .        |
|+B . . .         |
|Bo. = o S        |
|Oo.+ + =         |
|oB=.* = . o      |
| =+=.+   + E     |
|. .=o   . o      |
+----[SHA256]-----+
2048 SHA256:0Onrb7/PHjpo6iVZ7xQX2riKN83FJ3KGU0TvI0TaFG4 gerrit-code-review@openocd.zylin.com (RSA)