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