feeb11f667c3b2d867967664aae8ba448ea949ed
[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 hl_dcc_read(hl_if, &data, &ctrl);
275 buffer[i] = data;
276 }
277
278 return ERROR_OK;
279 }
280
281 static int hl_handle_target_request(void *priv)
282 {
283 struct target *target = priv;
284 if (!target_was_examined(target))
285 return ERROR_OK;
286 struct hl_interface_s *hl_if = target_to_adapter(target);
287
288 if (!target->dbg_msg_enabled)
289 return ERROR_OK;
290
291 if (target->state == TARGET_RUNNING) {
292 uint8_t data;
293 uint8_t ctrl;
294
295 hl_dcc_read(hl_if, &data, &ctrl);
296
297 /* check if we have data */
298 if (ctrl & (1 << 0)) {
299 uint32_t request;
300
301 /* we assume target is quick enough */
302 request = data;
303 hl_dcc_read(hl_if, &data, &ctrl);
304 request |= (data << 8);
305 hl_dcc_read(hl_if, &data, &ctrl);
306 request |= (data << 16);
307 hl_dcc_read(hl_if, &data, &ctrl);
308 request |= (data << 24);
309 target_request(target, request);
310 }
311 }
312
313 return ERROR_OK;
314 }
315
316 static int adapter_init_arch_info(struct target *target,
317 struct cortex_m_common *cortex_m,
318 struct jtag_tap *tap)
319 {
320 struct armv7m_common *armv7m;
321
322 LOG_DEBUG("%s", __func__);
323
324 armv7m = &cortex_m->armv7m;
325 armv7m_init_arch_info(target, armv7m);
326
327 armv7m->load_core_reg_u32 = adapter_load_core_reg_u32;
328 armv7m->store_core_reg_u32 = adapter_store_core_reg_u32;
329
330 armv7m->examine_debug_reason = adapter_examine_debug_reason;
331 armv7m->stlink = true;
332
333 target_register_timer_callback(hl_handle_target_request, 1, 1, target);
334
335 return ERROR_OK;
336 }
337
338 static int adapter_init_target(struct command_context *cmd_ctx,
339 struct target *target)
340 {
341 LOG_DEBUG("%s", __func__);
342
343 armv7m_build_reg_cache(target);
344 arm_semihosting_init(target);
345 return ERROR_OK;
346 }
347
348 static int adapter_target_create(struct target *target,
349 Jim_Interp *interp)
350 {
351 LOG_DEBUG("%s", __func__);
352
353 struct cortex_m_common *cortex_m = calloc(1, sizeof(struct cortex_m_common));
354
355 if (!cortex_m)
356 return ERROR_COMMAND_SYNTAX_ERROR;
357
358 adapter_init_arch_info(target, cortex_m, target->tap);
359
360 return ERROR_OK;
361 }
362
363 static int adapter_load_context(struct target *target)
364 {
365 struct armv7m_common *armv7m = target_to_armv7m(target);
366 int num_regs = armv7m->arm.core_cache->num_regs;
367
368 for (int i = 0; i < num_regs; i++) {
369
370 struct reg *r = &armv7m->arm.core_cache->reg_list[i];
371 if (!r->valid)
372 armv7m->arm.read_core_reg(target, r, i, ARM_MODE_ANY);
373 }
374
375 return ERROR_OK;
376 }
377
378 static int adapter_debug_entry(struct target *target)
379 {
380 struct hl_interface_s *adapter = target_to_adapter(target);
381 struct armv7m_common *armv7m = target_to_armv7m(target);
382 struct arm *arm = &armv7m->arm;
383 struct reg *r;
384 uint32_t xPSR;
385 int retval;
386
387 /* preserve the DCRDR across halts */
388 retval = target_read_u32(target, DCB_DCRDR, &target->savedDCRDR);
389 if (retval != ERROR_OK)
390 return retval;
391
392 retval = armv7m->examine_debug_reason(target);
393 if (retval != ERROR_OK)
394 return retval;
395
396 adapter_load_context(target);
397
398 /* make sure we clear the vector catch bit */
399 adapter->layout->api->write_debug_reg(adapter->handle, DCB_DEMCR, TRCENA);
400
401 r = arm->cpsr;
402 xPSR = buf_get_u32(r->value, 0, 32);
403
404 /* Are we in an exception handler */
405 if (xPSR & 0x1FF) {
406 armv7m->exception_number = (xPSR & 0x1FF);
407
408 arm->core_mode = ARM_MODE_HANDLER;
409 arm->map = armv7m_msp_reg_map;
410 } else {
411 unsigned control = buf_get_u32(arm->core_cache
412 ->reg_list[ARMV7M_CONTROL].value, 0, 2);
413
414 /* is this thread privileged? */
415 arm->core_mode = control & 1
416 ? ARM_MODE_USER_THREAD
417 : ARM_MODE_THREAD;
418
419 /* which stack is it using? */
420 if (control & 2)
421 arm->map = armv7m_psp_reg_map;
422 else
423 arm->map = armv7m_msp_reg_map;
424
425 armv7m->exception_number = 0;
426 }
427
428 LOG_DEBUG("entered debug state in core mode: %s at PC 0x%08" PRIx32 ", target->state: %s",
429 arm_mode_name(arm->core_mode),
430 buf_get_u32(arm->pc->value, 0, 32),
431 target_state_name(target));
432
433 return retval;
434 }
435
436 static int adapter_poll(struct target *target)
437 {
438 enum target_state state;
439 struct hl_interface_s *adapter = target_to_adapter(target);
440 struct armv7m_common *armv7m = target_to_armv7m(target);
441 enum target_state prev_target_state = target->state;
442
443 state = adapter->layout->api->state(adapter->handle);
444
445 if (state == TARGET_UNKNOWN) {
446 LOG_ERROR("jtag status contains invalid mode value - communication failure");
447 return ERROR_TARGET_FAILURE;
448 }
449
450 if (prev_target_state == state)
451 return ERROR_OK;
452
453 target->state = state;
454
455 if (state == TARGET_HALTED) {
456
457 int retval = adapter_debug_entry(target);
458 if (retval != ERROR_OK)
459 return retval;
460
461 if (prev_target_state == TARGET_DEBUG_RUNNING) {
462 target_call_event_callbacks(target, TARGET_EVENT_DEBUG_HALTED);
463 } else {
464 if (arm_semihosting(target, &retval) != 0)
465 return retval;
466
467 target_call_event_callbacks(target, TARGET_EVENT_HALTED);
468 }
469
470 LOG_DEBUG("halted: PC: 0x%08" PRIx32, buf_get_u32(armv7m->arm.pc->value, 0, 32));
471 }
472
473 return ERROR_OK;
474 }
475
476 static int adapter_assert_reset(struct target *target)
477 {
478 int res = ERROR_OK;
479 struct hl_interface_s *adapter = target_to_adapter(target);
480 struct armv7m_common *armv7m = target_to_armv7m(target);
481 bool use_srst_fallback = true;
482
483 LOG_DEBUG("%s", __func__);
484
485 enum reset_types jtag_reset_config = jtag_get_reset_config();
486
487 bool srst_asserted = false;
488
489 if ((jtag_reset_config & RESET_HAS_SRST) &&
490 (jtag_reset_config & RESET_SRST_NO_GATING)) {
491 jtag_add_reset(0, 1);
492 res = adapter->layout->api->assert_srst(adapter->handle, 0);
493 srst_asserted = true;
494 }
495
496 adapter->layout->api->write_debug_reg(adapter->handle, DCB_DHCSR, DBGKEY|C_DEBUGEN);
497
498 /* only set vector catch if halt is requested */
499 if (target->reset_halt)
500 adapter->layout->api->write_debug_reg(adapter->handle, DCB_DEMCR, TRCENA|VC_CORERESET);
501 else
502 adapter->layout->api->write_debug_reg(adapter->handle, DCB_DEMCR, TRCENA);
503
504 if (jtag_reset_config & RESET_HAS_SRST) {
505 if (!srst_asserted) {
506 jtag_add_reset(0, 1);
507 res = adapter->layout->api->assert_srst(adapter->handle, 0);
508 }
509 if (res == ERROR_COMMAND_NOTFOUND)
510 LOG_ERROR("Hardware srst not supported, falling back to software reset");
511 else if (res == ERROR_OK) {
512 /* hardware srst supported */
513 use_srst_fallback = false;
514 }
515 }
516
517 if (use_srst_fallback) {
518 /* stlink v1 api does not support hardware srst, so we use a software reset fallback */
519 adapter->layout->api->write_debug_reg(adapter->handle, NVIC_AIRCR, AIRCR_VECTKEY | AIRCR_SYSRESETREQ);
520 }
521
522 res = adapter->layout->api->reset(adapter->handle);
523
524 if (res != ERROR_OK)
525 return res;
526
527 /* registers are now invalid */
528 register_cache_invalidate(armv7m->arm.core_cache);
529
530 if (target->reset_halt) {
531 target->state = TARGET_RESET;
532 target->debug_reason = DBG_REASON_DBGRQ;
533 } else {
534 target->state = TARGET_HALTED;
535 }
536
537 return ERROR_OK;
538 }
539
540 static int adapter_deassert_reset(struct target *target)
541 {
542 struct hl_interface_s *adapter = target_to_adapter(target);
543
544 enum reset_types jtag_reset_config = jtag_get_reset_config();
545
546 LOG_DEBUG("%s", __func__);
547
548 if (jtag_reset_config & RESET_HAS_SRST)
549 adapter->layout->api->assert_srst(adapter->handle, 1);
550
551 /* virtual deassert reset, we need it for the internal
552 * jtag state machine
553 */
554 jtag_add_reset(0, 0);
555
556 target->savedDCRDR = 0; /* clear both DCC busy bits on initial resume */
557
558 return target->reset_halt ? ERROR_OK : target_resume(target, 1, 0, 0, 0);
559 }
560
561 static int adapter_halt(struct target *target)
562 {
563 int res;
564 struct hl_interface_s *adapter = target_to_adapter(target);
565
566 LOG_DEBUG("%s", __func__);
567
568 if (target->state == TARGET_HALTED) {
569 LOG_DEBUG("target was already halted");
570 return ERROR_OK;
571 }
572
573 if (target->state == TARGET_UNKNOWN)
574 LOG_WARNING("target was in unknown state when halt was requested");
575
576 res = adapter->layout->api->halt(adapter->handle);
577
578 if (res != ERROR_OK)
579 return res;
580
581 target->debug_reason = DBG_REASON_DBGRQ;
582
583 return ERROR_OK;
584 }
585
586 static int adapter_resume(struct target *target, int current,
587 uint32_t address, int handle_breakpoints,
588 int debug_execution)
589 {
590 int res;
591 struct hl_interface_s *adapter = target_to_adapter(target);
592 struct armv7m_common *armv7m = target_to_armv7m(target);
593 uint32_t resume_pc;
594 struct breakpoint *breakpoint = NULL;
595 struct reg *pc;
596
597 LOG_DEBUG("%s %d 0x%08" PRIx32 " %d %d", __func__, current, address,
598 handle_breakpoints, debug_execution);
599
600 if (target->state != TARGET_HALTED) {
601 LOG_WARNING("target not halted");
602 return ERROR_TARGET_NOT_HALTED;
603 }
604
605 if (!debug_execution) {
606 target_free_all_working_areas(target);
607 cortex_m_enable_breakpoints(target);
608 cortex_m_enable_watchpoints(target);
609 }
610
611 pc = armv7m->arm.pc;
612 if (!current) {
613 buf_set_u32(pc->value, 0, 32, address);
614 pc->dirty = true;
615 pc->valid = true;
616 }
617
618 if (!breakpoint_find(target, buf_get_u32(pc->value, 0, 32))
619 && !debug_execution) {
620 armv7m_maybe_skip_bkpt_inst(target, NULL);
621 }
622
623 resume_pc = buf_get_u32(pc->value, 0, 32);
624
625 /* write any user vector flags */
626 res = target_write_u32(target, DCB_DEMCR, TRCENA | armv7m->demcr);
627 if (res != ERROR_OK)
628 return res;
629
630 armv7m_restore_context(target);
631
632 /* restore savedDCRDR */
633 res = target_write_u32(target, DCB_DCRDR, target->savedDCRDR);
634 if (res != ERROR_OK)
635 return res;
636
637 /* registers are now invalid */
638 register_cache_invalidate(armv7m->arm.core_cache);
639
640 /* the front-end may request us not to handle breakpoints */
641 if (handle_breakpoints) {
642 /* Single step past breakpoint at current address */
643 breakpoint = breakpoint_find(target, resume_pc);
644 if (breakpoint) {
645 LOG_DEBUG("unset breakpoint at 0x%8.8" PRIx32 " (ID: %" PRIu32 ")",
646 breakpoint->address,
647 breakpoint->unique_id);
648 cortex_m_unset_breakpoint(target, breakpoint);
649
650 res = adapter->layout->api->step(adapter->handle);
651
652 if (res != ERROR_OK)
653 return res;
654
655 cortex_m_set_breakpoint(target, breakpoint);
656 }
657 }
658
659 res = adapter->layout->api->run(adapter->handle);
660
661 if (res != ERROR_OK)
662 return res;
663
664 target->debug_reason = DBG_REASON_NOTHALTED;
665
666 if (!debug_execution) {
667 target->state = TARGET_RUNNING;
668 target_call_event_callbacks(target, TARGET_EVENT_RESUMED);
669 } else {
670 target->state = TARGET_DEBUG_RUNNING;
671 target_call_event_callbacks(target, TARGET_EVENT_DEBUG_RESUMED);
672 }
673
674 return ERROR_OK;
675 }
676
677 static int adapter_step(struct target *target, int current,
678 uint32_t address, int handle_breakpoints)
679 {
680 int res;
681 struct hl_interface_s *adapter = target_to_adapter(target);
682 struct armv7m_common *armv7m = target_to_armv7m(target);
683 struct breakpoint *breakpoint = NULL;
684 struct reg *pc = armv7m->arm.pc;
685 bool bkpt_inst_found = false;
686
687 LOG_DEBUG("%s", __func__);
688
689 if (target->state != TARGET_HALTED) {
690 LOG_WARNING("target not halted");
691 return ERROR_TARGET_NOT_HALTED;
692 }
693
694 if (!current) {
695 buf_set_u32(pc->value, 0, 32, address);
696 pc->dirty = true;
697 pc->valid = true;
698 }
699
700 uint32_t pc_value = buf_get_u32(pc->value, 0, 32);
701
702 /* the front-end may request us not to handle breakpoints */
703 if (handle_breakpoints) {
704 breakpoint = breakpoint_find(target, pc_value);
705 if (breakpoint)
706 cortex_m_unset_breakpoint(target, breakpoint);
707 }
708
709 armv7m_maybe_skip_bkpt_inst(target, &bkpt_inst_found);
710
711 target->debug_reason = DBG_REASON_SINGLESTEP;
712
713 armv7m_restore_context(target);
714
715 /* restore savedDCRDR */
716 res = target_write_u32(target, DCB_DCRDR, target->savedDCRDR);
717 if (res != ERROR_OK)
718 return res;
719
720 target_call_event_callbacks(target, TARGET_EVENT_RESUMED);
721
722 res = adapter->layout->api->step(adapter->handle);
723
724 if (res != ERROR_OK)
725 return res;
726
727 /* registers are now invalid */
728 register_cache_invalidate(armv7m->arm.core_cache);
729
730 if (breakpoint)
731 cortex_m_set_breakpoint(target, breakpoint);
732
733 adapter_debug_entry(target);
734 target_call_event_callbacks(target, TARGET_EVENT_HALTED);
735
736 LOG_INFO("halted: PC: 0x%08" PRIx32, buf_get_u32(armv7m->arm.pc->value, 0, 32));
737
738 return ERROR_OK;
739 }
740
741 static int adapter_read_memory(struct target *target, uint32_t address,
742 uint32_t size, uint32_t count,
743 uint8_t *buffer)
744 {
745 struct hl_interface_s *adapter = target_to_adapter(target);
746
747 if (!count || !buffer)
748 return ERROR_COMMAND_SYNTAX_ERROR;
749
750 LOG_DEBUG("%s 0x%08" PRIx32 " %" PRIu32 " %" PRIu32, __func__, address, size, count);
751
752 return adapter->layout->api->read_mem(adapter->handle, address, size, count, buffer);
753 }
754
755 static int adapter_write_memory(struct target *target, uint32_t address,
756 uint32_t size, uint32_t count,
757 const uint8_t *buffer)
758 {
759 struct hl_interface_s *adapter = target_to_adapter(target);
760
761 if (!count || !buffer)
762 return ERROR_COMMAND_SYNTAX_ERROR;
763
764 LOG_DEBUG("%s 0x%08" PRIx32 " %" PRIu32 " %" PRIu32, __func__, address, size, count);
765
766 return adapter->layout->api->write_mem(adapter->handle, address, size, count, buffer);
767 }
768
769 static const struct command_registration adapter_command_handlers[] = {
770 {
771 .chain = arm_command_handlers,
772 },
773 {
774 .chain = armv7m_trace_command_handlers,
775 },
776 COMMAND_REGISTRATION_DONE
777 };
778
779 struct target_type hla_target = {
780 .name = "hla_target",
781 .deprecated_name = "stm32_stlink",
782
783 .init_target = adapter_init_target,
784 .deinit_target = cortex_m_deinit_target,
785 .target_create = adapter_target_create,
786 .examine = cortex_m_examine,
787 .commands = adapter_command_handlers,
788
789 .poll = adapter_poll,
790 .arch_state = armv7m_arch_state,
791
792 .target_request_data = hl_target_request_data,
793 .assert_reset = adapter_assert_reset,
794 .deassert_reset = adapter_deassert_reset,
795
796 .halt = adapter_halt,
797 .resume = adapter_resume,
798 .step = adapter_step,
799
800 .get_gdb_reg_list = armv7m_get_gdb_reg_list,
801
802 .read_memory = adapter_read_memory,
803 .write_memory = adapter_write_memory,
804 .checksum_memory = armv7m_checksum_memory,
805 .blank_check_memory = armv7m_blank_check_memory,
806
807 .run_algorithm = armv7m_run_algorithm,
808 .start_algorithm = armv7m_start_algorithm,
809 .wait_algorithm = armv7m_wait_algorithm,
810
811 .add_breakpoint = cortex_m_add_breakpoint,
812 .remove_breakpoint = cortex_m_remove_breakpoint,
813 .add_watchpoint = cortex_m_add_watchpoint,
814 .remove_watchpoint = cortex_m_remove_watchpoint,
815 };

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)