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

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)