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

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)