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

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)