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

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)