hla_target: fix adapter_poll() to preserve TARGET_DEBUG_RUNNING state
[openocd.git] / src / target / hla_target.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 * revised: 4/25/13 by brent@mbari.org [DCC target request support] *
9 * *
10 * This program is free software; you can redistribute it and/or modify *
11 * it under the terms of the GNU General Public License as published by *
12 * the Free Software Foundation; either version 2 of the License, or *
13 * (at your option) any later version. *
14 * *
15 * This program is distributed in the hope that it will be useful, *
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
18 * GNU General Public License for more details. *
19 * *
20 * You should have received a copy of the GNU General Public License *
21 * along with this program. If not, see <http://www.gnu.org/licenses/>. *
22 ***************************************************************************/
23
24 #ifdef HAVE_CONFIG_H
25 #include "config.h"
26 #endif
27
28 #include "jtag/jtag.h"
29 #include "jtag/hla/hla_transport.h"
30 #include "jtag/hla/hla_interface.h"
31 #include "jtag/hla/hla_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 #include "target_request.h"
41
42 #define savedDCRDR dbgbase /* FIXME: using target->dbgbase to preserve DCRDR */
43
44 #define ARMV7M_SCS_DCRSR DCB_DCRSR
45 #define ARMV7M_SCS_DCRDR DCB_DCRDR
46
47 static inline struct hl_interface_s *target_to_adapter(struct target *target)
48 {
49 return target->tap->priv;
50 }
51
52 static int adapter_load_core_reg_u32(struct target *target,
53 uint32_t num, uint32_t *value)
54 {
55 int retval;
56 struct hl_interface_s *adapter = target_to_adapter(target);
57
58 LOG_DEBUG("%s", __func__);
59
60 /* NOTE: we "know" here that the register identifiers used
61 * in the v7m header match the Cortex-M3 Debug Core Register
62 * Selector values for R0..R15, xPSR, MSP, and PSP.
63 */
64 switch (num) {
65 case 0 ... 18:
66 /* read a normal core register */
67 retval = adapter->layout->api->read_reg(adapter->handle, num, value);
68
69 if (retval != ERROR_OK) {
70 LOG_ERROR("JTAG failure %i", retval);
71 return ERROR_JTAG_DEVICE_ERROR;
72 }
73 LOG_DEBUG("load from core reg %i value 0x%" PRIx32 "", (int)num, *value);
74 break;
75
76 case ARMV7M_FPSCR:
77 /* Floating-point Status and Registers */
78 retval = target_write_u32(target, ARMV7M_SCS_DCRSR, 33);
79 if (retval != ERROR_OK)
80 return retval;
81 retval = target_read_u32(target, ARMV7M_SCS_DCRDR, value);
82 if (retval != ERROR_OK)
83 return retval;
84 LOG_DEBUG("load from FPSCR value 0x%" PRIx32, *value);
85 break;
86
87 case ARMV7M_S0 ... ARMV7M_S31:
88 /* Floating-point Status and Registers */
89 retval = target_write_u32(target, ARMV7M_SCS_DCRSR, num-ARMV7M_S0+64);
90 if (retval != ERROR_OK)
91 return retval;
92 retval = target_read_u32(target, ARMV7M_SCS_DCRDR, value);
93 if (retval != ERROR_OK)
94 return retval;
95 LOG_DEBUG("load from FPU reg S%d value 0x%" PRIx32,
96 (int)(num - ARMV7M_S0), *value);
97 break;
98
99 case ARMV7M_PRIMASK:
100 case ARMV7M_BASEPRI:
101 case ARMV7M_FAULTMASK:
102 case ARMV7M_CONTROL:
103 /* Cortex-M3 packages these four registers as bitfields
104 * in one Debug Core register. So say r0 and r2 docs;
105 * it was removed from r1 docs, but still works.
106 */
107 retval = adapter->layout->api->read_reg(adapter->handle, 20, value);
108 if (retval != ERROR_OK)
109 return retval;
110
111 switch (num) {
112 case ARMV7M_PRIMASK:
113 *value = buf_get_u32((uint8_t *) value, 0, 1);
114 break;
115
116 case ARMV7M_BASEPRI:
117 *value = buf_get_u32((uint8_t *) value, 8, 8);
118 break;
119
120 case ARMV7M_FAULTMASK:
121 *value = buf_get_u32((uint8_t *) value, 16, 1);
122 break;
123
124 case ARMV7M_CONTROL:
125 *value = buf_get_u32((uint8_t *) value, 24, 2);
126 break;
127 }
128
129 LOG_DEBUG("load from special reg %i value 0x%" PRIx32 "",
130 (int)num, *value);
131 break;
132
133 default:
134 return ERROR_COMMAND_SYNTAX_ERROR;
135 }
136
137 return ERROR_OK;
138 }
139
140 static int adapter_store_core_reg_u32(struct target *target,
141 uint32_t num, uint32_t value)
142 {
143 int retval;
144 uint32_t reg;
145 struct armv7m_common *armv7m = target_to_armv7m(target);
146 struct hl_interface_s *adapter = target_to_adapter(target);
147
148 LOG_DEBUG("%s", __func__);
149
150 /* NOTE: we "know" here that the register identifiers used
151 * in the v7m header match the Cortex-M3 Debug Core Register
152 * Selector values for R0..R15, xPSR, MSP, and PSP.
153 */
154 switch (num) {
155 case 0 ... 18:
156 retval = adapter->layout->api->write_reg(adapter->handle, num, value);
157
158 if (retval != ERROR_OK) {
159 struct reg *r;
160
161 LOG_ERROR("JTAG failure");
162 r = armv7m->arm.core_cache->reg_list + num;
163 r->dirty = r->valid;
164 return ERROR_JTAG_DEVICE_ERROR;
165 }
166 LOG_DEBUG("write core reg %i value 0x%" PRIx32 "", (int)num, value);
167 break;
168
169 case ARMV7M_FPSCR:
170 /* Floating-point Status and Registers */
171 retval = target_write_u32(target, ARMV7M_SCS_DCRDR, value);
172 if (retval != ERROR_OK)
173 return retval;
174 retval = target_write_u32(target, ARMV7M_SCS_DCRSR, 33 | (1<<16));
175 if (retval != ERROR_OK)
176 return retval;
177 LOG_DEBUG("write FPSCR value 0x%" PRIx32, value);
178 break;
179
180 case ARMV7M_S0 ... ARMV7M_S31:
181 /* Floating-point Status and Registers */
182 retval = target_write_u32(target, ARMV7M_SCS_DCRDR, value);
183 if (retval != ERROR_OK)
184 return retval;
185 retval = target_write_u32(target, ARMV7M_SCS_DCRSR, (num-ARMV7M_S0+64) | (1<<16));
186 if (retval != ERROR_OK)
187 return retval;
188 LOG_DEBUG("write FPU reg S%d value 0x%" PRIx32,
189 (int)(num - ARMV7M_S0), value);
190 break;
191
192 case ARMV7M_PRIMASK:
193 case ARMV7M_BASEPRI:
194 case ARMV7M_FAULTMASK:
195 case ARMV7M_CONTROL:
196 /* Cortex-M3 packages these four registers as bitfields
197 * in one Debug Core register. So say r0 and r2 docs;
198 * it was removed from r1 docs, but still works.
199 */
200
201 adapter->layout->api->read_reg(adapter->handle, 20, &reg);
202
203 switch (num) {
204 case ARMV7M_PRIMASK:
205 buf_set_u32((uint8_t *) &reg, 0, 1, value);
206 break;
207
208 case ARMV7M_BASEPRI:
209 buf_set_u32((uint8_t *) &reg, 8, 8, value);
210 break;
211
212 case ARMV7M_FAULTMASK:
213 buf_set_u32((uint8_t *) &reg, 16, 1, value);
214 break;
215
216 case ARMV7M_CONTROL:
217 buf_set_u32((uint8_t *) &reg, 24, 2, value);
218 break;
219 }
220
221 adapter->layout->api->write_reg(adapter->handle, 20, reg);
222
223 LOG_DEBUG("write special reg %i value 0x%" PRIx32 " ", (int)num, value);
224 break;
225
226 default:
227 return ERROR_COMMAND_SYNTAX_ERROR;
228 }
229
230 return ERROR_OK;
231 }
232
233 static int adapter_examine_debug_reason(struct target *target)
234 {
235 if ((target->debug_reason != DBG_REASON_DBGRQ)
236 && (target->debug_reason != DBG_REASON_SINGLESTEP)) {
237 target->debug_reason = DBG_REASON_BREAKPOINT;
238 }
239
240 return ERROR_OK;
241 }
242
243 static int hl_dcc_read(struct hl_interface_s *hl_if, uint8_t *value, uint8_t *ctrl)
244 {
245 uint16_t dcrdr;
246 int retval = hl_if->layout->api->read_mem(hl_if->handle,
247 DCB_DCRDR, 1, sizeof(dcrdr), (uint8_t *)&dcrdr);
248 if (retval == ERROR_OK) {
249 *ctrl = (uint8_t)dcrdr;
250 *value = (uint8_t)(dcrdr >> 8);
251
252 LOG_DEBUG("data 0x%x ctrl 0x%x", *value, *ctrl);
253
254 if (dcrdr & 1) {
255 /* write ack back to software dcc register
256 * to signify we have read data */
257 /* atomically clear just the byte containing the busy bit */
258 static const uint8_t zero;
259 retval = hl_if->layout->api->write_mem(hl_if->handle, DCB_DCRDR, 1, 1, &zero);
260 }
261 }
262 return retval;
263 }
264
265 static int hl_target_request_data(struct target *target,
266 uint32_t size, uint8_t *buffer)
267 {
268 struct hl_interface_s *hl_if = target_to_adapter(target);
269 uint8_t data;
270 uint8_t ctrl;
271 uint32_t i;
272
273 for (i = 0; i < (size * 4); i++) {
274 int err = hl_dcc_read(hl_if, &data, &ctrl);
275 if (err != ERROR_OK)
276 return err;
277
278 buffer[i] = data;
279 }
280
281 return ERROR_OK;
282 }
283
284 static int hl_handle_target_request(void *priv)
285 {
286 struct target *target = priv;
287 int err;
288
289 if (!target_was_examined(target))
290 return ERROR_OK;
291 struct hl_interface_s *hl_if = target_to_adapter(target);
292
293 if (!target->dbg_msg_enabled)
294 return ERROR_OK;
295
296 if (target->state == TARGET_RUNNING) {
297 uint8_t data;
298 uint8_t ctrl;
299
300 err = hl_dcc_read(hl_if, &data, &ctrl);
301 if (err != ERROR_OK)
302 return err;
303
304 /* check if we have data */
305 if (ctrl & (1 << 0)) {
306 uint32_t request;
307
308 /* we assume target is quick enough */
309 request = data;
310 err = hl_dcc_read(hl_if, &data, &ctrl);
311 if (err != ERROR_OK)
312 return err;
313
314 request |= (data << 8);
315 err = hl_dcc_read(hl_if, &data, &ctrl);
316 if (err != ERROR_OK)
317 return err;
318
319 request |= (data << 16);
320 err = hl_dcc_read(hl_if, &data, &ctrl);
321 if (err != ERROR_OK)
322 return err;
323
324 request |= (data << 24);
325 target_request(target, request);
326 }
327 }
328
329 return ERROR_OK;
330 }
331
332 static int adapter_init_arch_info(struct target *target,
333 struct cortex_m_common *cortex_m,
334 struct jtag_tap *tap)
335 {
336 struct armv7m_common *armv7m;
337
338 LOG_DEBUG("%s", __func__);
339
340 armv7m = &cortex_m->armv7m;
341 armv7m_init_arch_info(target, armv7m);
342
343 armv7m->load_core_reg_u32 = adapter_load_core_reg_u32;
344 armv7m->store_core_reg_u32 = adapter_store_core_reg_u32;
345
346 armv7m->examine_debug_reason = adapter_examine_debug_reason;
347 armv7m->stlink = true;
348
349 target_register_timer_callback(hl_handle_target_request, 1, 1, target);
350
351 return ERROR_OK;
352 }
353
354 static int adapter_init_target(struct command_context *cmd_ctx,
355 struct target *target)
356 {
357 LOG_DEBUG("%s", __func__);
358
359 armv7m_build_reg_cache(target);
360 arm_semihosting_init(target);
361 return ERROR_OK;
362 }
363
364 static int adapter_target_create(struct target *target,
365 Jim_Interp *interp)
366 {
367 LOG_DEBUG("%s", __func__);
368 struct adiv5_private_config *pc = target->private_config;
369 struct cortex_m_common *cortex_m = calloc(1, sizeof(struct cortex_m_common));
370 if (!cortex_m)
371 return ERROR_COMMAND_SYNTAX_ERROR;
372
373 if (pc != NULL && pc->ap_num > 0) {
374 LOG_ERROR("hla_target: invalid parameter -ap-num (> 0)");
375 return ERROR_FAIL;
376 }
377
378 adapter_init_arch_info(target, cortex_m, target->tap);
379
380 return ERROR_OK;
381 }
382
383 static int adapter_load_context(struct target *target)
384 {
385 struct armv7m_common *armv7m = target_to_armv7m(target);
386 int num_regs = armv7m->arm.core_cache->num_regs;
387
388 for (int i = 0; i < num_regs; i++) {
389
390 struct reg *r = &armv7m->arm.core_cache->reg_list[i];
391 if (!r->valid)
392 armv7m->arm.read_core_reg(target, r, i, ARM_MODE_ANY);
393 }
394
395 return ERROR_OK;
396 }
397
398 static int adapter_debug_entry(struct target *target)
399 {
400 struct hl_interface_s *adapter = target_to_adapter(target);
401 struct armv7m_common *armv7m = target_to_armv7m(target);
402 struct arm *arm = &armv7m->arm;
403 struct reg *r;
404 uint32_t xPSR;
405 int retval;
406
407 /* preserve the DCRDR across halts */
408 retval = target_read_u32(target, DCB_DCRDR, &target->savedDCRDR);
409 if (retval != ERROR_OK)
410 return retval;
411
412 retval = armv7m->examine_debug_reason(target);
413 if (retval != ERROR_OK)
414 return retval;
415
416 adapter_load_context(target);
417
418 /* make sure we clear the vector catch bit */
419 adapter->layout->api->write_debug_reg(adapter->handle, DCB_DEMCR, TRCENA);
420
421 r = arm->cpsr;
422 xPSR = buf_get_u32(r->value, 0, 32);
423
424 /* Are we in an exception handler */
425 if (xPSR & 0x1FF) {
426 armv7m->exception_number = (xPSR & 0x1FF);
427
428 arm->core_mode = ARM_MODE_HANDLER;
429 arm->map = armv7m_msp_reg_map;
430 } else {
431 unsigned control = buf_get_u32(arm->core_cache
432 ->reg_list[ARMV7M_CONTROL].value, 0, 2);
433
434 /* is this thread privileged? */
435 arm->core_mode = control & 1
436 ? ARM_MODE_USER_THREAD
437 : ARM_MODE_THREAD;
438
439 /* which stack is it using? */
440 if (control & 2)
441 arm->map = armv7m_psp_reg_map;
442 else
443 arm->map = armv7m_msp_reg_map;
444
445 armv7m->exception_number = 0;
446 }
447
448 LOG_DEBUG("entered debug state in core mode: %s at PC 0x%08" PRIx32 ", target->state: %s",
449 arm_mode_name(arm->core_mode),
450 buf_get_u32(arm->pc->value, 0, 32),
451 target_state_name(target));
452
453 return retval;
454 }
455
456 static int adapter_poll(struct target *target)
457 {
458 enum target_state state;
459 struct hl_interface_s *adapter = target_to_adapter(target);
460 struct armv7m_common *armv7m = target_to_armv7m(target);
461 enum target_state prev_target_state = target->state;
462
463 state = adapter->layout->api->state(adapter->handle);
464
465 if (state == TARGET_UNKNOWN) {
466 LOG_ERROR("jtag status contains invalid mode value - communication failure");
467 return ERROR_TARGET_FAILURE;
468 }
469
470 if (prev_target_state == state)
471 return ERROR_OK;
472
473 if (prev_target_state == TARGET_DEBUG_RUNNING && state == TARGET_RUNNING)
474 return ERROR_OK;
475
476 target->state = state;
477
478 if (state == TARGET_HALTED) {
479
480 int retval = adapter_debug_entry(target);
481 if (retval != ERROR_OK)
482 return retval;
483
484 if (prev_target_state == TARGET_DEBUG_RUNNING) {
485 target_call_event_callbacks(target, TARGET_EVENT_DEBUG_HALTED);
486 } else {
487 if (arm_semihosting(target, &retval) != 0)
488 return retval;
489
490 target_call_event_callbacks(target, TARGET_EVENT_HALTED);
491 }
492
493 LOG_DEBUG("halted: PC: 0x%08" PRIx32, buf_get_u32(armv7m->arm.pc->value, 0, 32));
494 }
495
496 return ERROR_OK;
497 }
498
499 static int adapter_assert_reset(struct target *target)
500 {
501 int res = ERROR_OK;
502 struct hl_interface_s *adapter = target_to_adapter(target);
503 struct armv7m_common *armv7m = target_to_armv7m(target);
504 bool use_srst_fallback = true;
505
506 LOG_DEBUG("%s", __func__);
507
508 enum reset_types jtag_reset_config = jtag_get_reset_config();
509
510 bool srst_asserted = false;
511
512 if ((jtag_reset_config & RESET_HAS_SRST) &&
513 (jtag_reset_config & RESET_SRST_NO_GATING)) {
514 jtag_add_reset(0, 1);
515 res = adapter->layout->api->assert_srst(adapter->handle, 0);
516 srst_asserted = true;
517 }
518
519 adapter->layout->api->write_debug_reg(adapter->handle, DCB_DHCSR, DBGKEY|C_DEBUGEN);
520
521 /* only set vector catch if halt is requested */
522 if (target->reset_halt)
523 adapter->layout->api->write_debug_reg(adapter->handle, DCB_DEMCR, TRCENA|VC_CORERESET);
524 else
525 adapter->layout->api->write_debug_reg(adapter->handle, DCB_DEMCR, TRCENA);
526
527 if (jtag_reset_config & RESET_HAS_SRST) {
528 if (!srst_asserted) {
529 jtag_add_reset(0, 1);
530 res = adapter->layout->api->assert_srst(adapter->handle, 0);
531 }
532 if (res == ERROR_COMMAND_NOTFOUND)
533 LOG_ERROR("Hardware srst not supported, falling back to software reset");
534 else if (res == ERROR_OK) {
535 /* hardware srst supported */
536 use_srst_fallback = false;
537 }
538 }
539
540 if (use_srst_fallback) {
541 /* stlink v1 api does not support hardware srst, so we use a software reset fallback */
542 adapter->layout->api->write_debug_reg(adapter->handle, NVIC_AIRCR, AIRCR_VECTKEY | AIRCR_SYSRESETREQ);
543 }
544
545 res = adapter->layout->api->reset(adapter->handle);
546
547 if (res != ERROR_OK)
548 return res;
549
550 /* registers are now invalid */
551 register_cache_invalidate(armv7m->arm.core_cache);
552
553 if (target->reset_halt) {
554 target->state = TARGET_RESET;
555 target->debug_reason = DBG_REASON_DBGRQ;
556 } else {
557 target->state = TARGET_HALTED;
558 }
559
560 return ERROR_OK;
561 }
562
563 static int adapter_deassert_reset(struct target *target)
564 {
565 struct hl_interface_s *adapter = target_to_adapter(target);
566
567 enum reset_types jtag_reset_config = jtag_get_reset_config();
568
569 LOG_DEBUG("%s", __func__);
570
571 if (jtag_reset_config & RESET_HAS_SRST)
572 adapter->layout->api->assert_srst(adapter->handle, 1);
573
574 /* virtual deassert reset, we need it for the internal
575 * jtag state machine
576 */
577 jtag_add_reset(0, 0);
578
579 target->savedDCRDR = 0; /* clear both DCC busy bits on initial resume */
580
581 return target->reset_halt ? ERROR_OK : target_resume(target, 1, 0, 0, 0);
582 }
583
584 static int adapter_halt(struct target *target)
585 {
586 int res;
587 struct hl_interface_s *adapter = target_to_adapter(target);
588
589 LOG_DEBUG("%s", __func__);
590
591 if (target->state == TARGET_HALTED) {
592 LOG_DEBUG("target was already halted");
593 return ERROR_OK;
594 }
595
596 if (target->state == TARGET_UNKNOWN)
597 LOG_WARNING("target was in unknown state when halt was requested");
598
599 res = adapter->layout->api->halt(adapter->handle);
600
601 if (res != ERROR_OK)
602 return res;
603
604 target->debug_reason = DBG_REASON_DBGRQ;
605
606 return ERROR_OK;
607 }
608
609 static int adapter_resume(struct target *target, int current,
610 target_addr_t address, int handle_breakpoints,
611 int debug_execution)
612 {
613 int res;
614 struct hl_interface_s *adapter = target_to_adapter(target);
615 struct armv7m_common *armv7m = target_to_armv7m(target);
616 uint32_t resume_pc;
617 struct breakpoint *breakpoint = NULL;
618 struct reg *pc;
619
620 LOG_DEBUG("%s %d " TARGET_ADDR_FMT " %d %d", __func__, current,
621 address, handle_breakpoints, debug_execution);
622
623 if (target->state != TARGET_HALTED) {
624 LOG_WARNING("target not halted");
625 return ERROR_TARGET_NOT_HALTED;
626 }
627
628 if (!debug_execution) {
629 target_free_all_working_areas(target);
630 cortex_m_enable_breakpoints(target);
631 cortex_m_enable_watchpoints(target);
632 }
633
634 pc = armv7m->arm.pc;
635 if (!current) {
636 buf_set_u32(pc->value, 0, 32, address);
637 pc->dirty = true;
638 pc->valid = true;
639 }
640
641 if (!breakpoint_find(target, buf_get_u32(pc->value, 0, 32))
642 && !debug_execution) {
643 armv7m_maybe_skip_bkpt_inst(target, NULL);
644 }
645
646 resume_pc = buf_get_u32(pc->value, 0, 32);
647
648 /* write any user vector flags */
649 res = target_write_u32(target, DCB_DEMCR, TRCENA | armv7m->demcr);
650 if (res != ERROR_OK)
651 return res;
652
653 armv7m_restore_context(target);
654
655 /* restore savedDCRDR */
656 res = target_write_u32(target, DCB_DCRDR, target->savedDCRDR);
657 if (res != ERROR_OK)
658 return res;
659
660 /* registers are now invalid */
661 register_cache_invalidate(armv7m->arm.core_cache);
662
663 /* the front-end may request us not to handle breakpoints */
664 if (handle_breakpoints) {
665 /* Single step past breakpoint at current address */
666 breakpoint = breakpoint_find(target, resume_pc);
667 if (breakpoint) {
668 LOG_DEBUG("unset breakpoint at " TARGET_ADDR_FMT " (ID: %" PRIu32 ")",
669 breakpoint->address,
670 breakpoint->unique_id);
671 cortex_m_unset_breakpoint(target, breakpoint);
672
673 res = adapter->layout->api->step(adapter->handle);
674
675 if (res != ERROR_OK)
676 return res;
677
678 cortex_m_set_breakpoint(target, breakpoint);
679 }
680 }
681
682 res = adapter->layout->api->run(adapter->handle);
683
684 if (res != ERROR_OK)
685 return res;
686
687 target->debug_reason = DBG_REASON_NOTHALTED;
688
689 if (!debug_execution) {
690 target->state = TARGET_RUNNING;
691 target_call_event_callbacks(target, TARGET_EVENT_RESUMED);
692 } else {
693 target->state = TARGET_DEBUG_RUNNING;
694 target_call_event_callbacks(target, TARGET_EVENT_DEBUG_RESUMED);
695 }
696
697 return ERROR_OK;
698 }
699
700 static int adapter_step(struct target *target, int current,
701 target_addr_t address, int handle_breakpoints)
702 {
703 int res;
704 struct hl_interface_s *adapter = target_to_adapter(target);
705 struct armv7m_common *armv7m = target_to_armv7m(target);
706 struct breakpoint *breakpoint = NULL;
707 struct reg *pc = armv7m->arm.pc;
708 bool bkpt_inst_found = false;
709
710 LOG_DEBUG("%s", __func__);
711
712 if (target->state != TARGET_HALTED) {
713 LOG_WARNING("target not halted");
714 return ERROR_TARGET_NOT_HALTED;
715 }
716
717 if (!current) {
718 buf_set_u32(pc->value, 0, 32, address);
719 pc->dirty = true;
720 pc->valid = true;
721 }
722
723 uint32_t pc_value = buf_get_u32(pc->value, 0, 32);
724
725 /* the front-end may request us not to handle breakpoints */
726 if (handle_breakpoints) {
727 breakpoint = breakpoint_find(target, pc_value);
728 if (breakpoint)
729 cortex_m_unset_breakpoint(target, breakpoint);
730 }
731
732 armv7m_maybe_skip_bkpt_inst(target, &bkpt_inst_found);
733
734 target->debug_reason = DBG_REASON_SINGLESTEP;
735
736 armv7m_restore_context(target);
737
738 /* restore savedDCRDR */
739 res = target_write_u32(target, DCB_DCRDR, target->savedDCRDR);
740 if (res != ERROR_OK)
741 return res;
742
743 target_call_event_callbacks(target, TARGET_EVENT_RESUMED);
744
745 res = adapter->layout->api->step(adapter->handle);
746
747 if (res != ERROR_OK)
748 return res;
749
750 /* registers are now invalid */
751 register_cache_invalidate(armv7m->arm.core_cache);
752
753 if (breakpoint)
754 cortex_m_set_breakpoint(target, breakpoint);
755
756 adapter_debug_entry(target);
757 target_call_event_callbacks(target, TARGET_EVENT_HALTED);
758
759 LOG_INFO("halted: PC: 0x%08" PRIx32, buf_get_u32(armv7m->arm.pc->value, 0, 32));
760
761 return ERROR_OK;
762 }
763
764 static int adapter_read_memory(struct target *target, target_addr_t address,
765 uint32_t size, uint32_t count,
766 uint8_t *buffer)
767 {
768 struct hl_interface_s *adapter = target_to_adapter(target);
769
770 if (!count || !buffer)
771 return ERROR_COMMAND_SYNTAX_ERROR;
772
773 LOG_DEBUG("%s " TARGET_ADDR_FMT " %" PRIu32 " %" PRIu32,
774 __func__, address, size, count);
775
776 return adapter->layout->api->read_mem(adapter->handle, address, size, count, buffer);
777 }
778
779 static int adapter_write_memory(struct target *target, target_addr_t address,
780 uint32_t size, uint32_t count,
781 const uint8_t *buffer)
782 {
783 struct hl_interface_s *adapter = target_to_adapter(target);
784
785 if (!count || !buffer)
786 return ERROR_COMMAND_SYNTAX_ERROR;
787
788 LOG_DEBUG("%s " TARGET_ADDR_FMT " %" PRIu32 " %" PRIu32,
789 __func__, address, size, count);
790
791 return adapter->layout->api->write_mem(adapter->handle, address, size, count, buffer);
792 }
793
794 static const struct command_registration adapter_command_handlers[] = {
795 {
796 .chain = arm_command_handlers,
797 },
798 {
799 .chain = armv7m_trace_command_handlers,
800 },
801 COMMAND_REGISTRATION_DONE
802 };
803
804 struct target_type hla_target = {
805 .name = "hla_target",
806 .deprecated_name = "stm32_stlink",
807
808 .init_target = adapter_init_target,
809 .deinit_target = cortex_m_deinit_target,
810 .target_create = adapter_target_create,
811 .target_jim_configure = adiv5_jim_configure,
812 .examine = cortex_m_examine,
813 .commands = adapter_command_handlers,
814
815 .poll = adapter_poll,
816 .arch_state = armv7m_arch_state,
817
818 .target_request_data = hl_target_request_data,
819 .assert_reset = adapter_assert_reset,
820 .deassert_reset = adapter_deassert_reset,
821
822 .halt = adapter_halt,
823 .resume = adapter_resume,
824 .step = adapter_step,
825
826 .get_gdb_arch = arm_get_gdb_arch,
827 .get_gdb_reg_list = armv7m_get_gdb_reg_list,
828
829 .read_memory = adapter_read_memory,
830 .write_memory = adapter_write_memory,
831 .checksum_memory = armv7m_checksum_memory,
832 .blank_check_memory = armv7m_blank_check_memory,
833
834 .run_algorithm = armv7m_run_algorithm,
835 .start_algorithm = armv7m_start_algorithm,
836 .wait_algorithm = armv7m_wait_algorithm,
837
838 .add_breakpoint = cortex_m_add_breakpoint,
839 .remove_breakpoint = cortex_m_remove_breakpoint,
840 .add_watchpoint = cortex_m_add_watchpoint,
841 .remove_watchpoint = cortex_m_remove_watchpoint,
842 .profiling = cortex_m_profiling,
843 };

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)