armv7m: remove gdb register hacks
[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, write to the *
22 * Free Software Foundation, Inc., *
23 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
24 ***************************************************************************/
25
26 #ifdef HAVE_CONFIG_H
27 #include "config.h"
28 #endif
29
30 #include "jtag/jtag.h"
31 #include "jtag/hla/hla_transport.h"
32 #include "jtag/hla/hla_interface.h"
33 #include "jtag/hla/hla_layout.h"
34 #include "register.h"
35 #include "algorithm.h"
36 #include "target.h"
37 #include "breakpoints.h"
38 #include "target_type.h"
39 #include "armv7m.h"
40 #include "cortex_m.h"
41 #include "arm_semihosting.h"
42 #include "target_request.h"
43
44 #define savedDCRDR dbgbase /* FIXME: using target->dbgbase to preserve DCRDR */
45
46 #define ARMV7M_SCS_DCRSR DCB_DCRSR
47 #define ARMV7M_SCS_DCRDR DCB_DCRDR
48
49 static inline struct hl_interface_s *target_to_adapter(struct target *target)
50 {
51 return target->tap->priv;
52 }
53
54 static int adapter_load_core_reg_u32(struct target *target,
55 uint32_t num, uint32_t *value)
56 {
57 int retval;
58 struct hl_interface_s *adapter = target_to_adapter(target);
59
60 LOG_DEBUG("%s", __func__);
61
62 /* NOTE: we "know" here that the register identifiers used
63 * in the v7m header match the Cortex-M3 Debug Core Register
64 * Selector values for R0..R15, xPSR, MSP, and PSP.
65 */
66 switch (num) {
67 case 0 ... 18:
68 /* read a normal core register */
69 retval = adapter->layout->api->read_reg(adapter->fd, num, value);
70
71 if (retval != ERROR_OK) {
72 LOG_ERROR("JTAG failure %i", retval);
73 return ERROR_JTAG_DEVICE_ERROR;
74 }
75 LOG_DEBUG("load from core reg %i value 0x%" PRIx32 "", (int)num, *value);
76 break;
77
78 case ARMV7M_FPSID:
79 case ARMV7M_FPEXC:
80 *value = 0;
81 break;
82
83 case ARMV7M_FPSCR:
84 /* Floating-point Status and Registers */
85 retval = target_write_u32(target, ARMV7M_SCS_DCRSR, 33);
86 if (retval != ERROR_OK)
87 return retval;
88 retval = target_read_u32(target, ARMV7M_SCS_DCRDR, value);
89 if (retval != ERROR_OK)
90 return retval;
91 LOG_DEBUG("load from core reg %i value 0x%" PRIx32 "", (int)num, *value);
92 break;
93
94 case ARMV7M_S0 ... ARMV7M_S31:
95 /* Floating-point Status and Registers */
96 retval = target_write_u32(target, ARMV7M_SCS_DCRSR, num-ARMV7M_S0+64);
97 if (retval != ERROR_OK)
98 return retval;
99 retval = target_read_u32(target, ARMV7M_SCS_DCRDR, value);
100 if (retval != ERROR_OK)
101 return retval;
102 LOG_DEBUG("load from core reg %i value 0x%" PRIx32 "", (int)num, *value);
103 break;
104
105 case ARMV7M_D0 ... ARMV7M_D15:
106 value = 0;
107 break;
108
109 case ARMV7M_PRIMASK:
110 case ARMV7M_BASEPRI:
111 case ARMV7M_FAULTMASK:
112 case ARMV7M_CONTROL:
113 /* Cortex-M3 packages these four registers as bitfields
114 * in one Debug Core register. So say r0 and r2 docs;
115 * it was removed from r1 docs, but still works.
116 */
117 retval = adapter->layout->api->read_reg(adapter->fd, 20, value);
118 if (retval != ERROR_OK)
119 return retval;
120
121 switch (num) {
122 case ARMV7M_PRIMASK:
123 *value = buf_get_u32((uint8_t *) value, 0, 1);
124 break;
125
126 case ARMV7M_BASEPRI:
127 *value = buf_get_u32((uint8_t *) value, 8, 8);
128 break;
129
130 case ARMV7M_FAULTMASK:
131 *value = buf_get_u32((uint8_t *) value, 16, 1);
132 break;
133
134 case ARMV7M_CONTROL:
135 *value = buf_get_u32((uint8_t *) value, 24, 2);
136 break;
137 }
138
139 LOG_DEBUG("load from special reg %i value 0x%" PRIx32 "",
140 (int)num, *value);
141 break;
142
143 default:
144 return ERROR_COMMAND_SYNTAX_ERROR;
145 }
146
147 return ERROR_OK;
148 }
149
150 static int adapter_store_core_reg_u32(struct target *target,
151 uint32_t num, uint32_t value)
152 {
153 int retval;
154 uint32_t reg;
155 struct armv7m_common *armv7m = target_to_armv7m(target);
156 struct hl_interface_s *adapter = target_to_adapter(target);
157
158 LOG_DEBUG("%s", __func__);
159
160 /* NOTE: we "know" here that the register identifiers used
161 * in the v7m header match the Cortex-M3 Debug Core Register
162 * Selector values for R0..R15, xPSR, MSP, and PSP.
163 */
164 switch (num) {
165 case 0 ... 18:
166 retval = adapter->layout->api->write_reg(adapter->fd, num, value);
167
168 if (retval != ERROR_OK) {
169 struct reg *r;
170
171 LOG_ERROR("JTAG failure");
172 r = armv7m->arm.core_cache->reg_list + num;
173 r->dirty = r->valid;
174 return ERROR_JTAG_DEVICE_ERROR;
175 }
176 LOG_DEBUG("write core reg %i value 0x%" PRIx32 "", (int)num, value);
177 break;
178
179 case ARMV7M_FPSID:
180 case ARMV7M_FPEXC:
181 break;
182
183 case ARMV7M_FPSCR:
184 /* Floating-point Status and Registers */
185 retval = target_write_u32(target, ARMV7M_SCS_DCRDR, value);
186 if (retval != ERROR_OK)
187 return retval;
188 retval = target_write_u32(target, ARMV7M_SCS_DCRSR, 33 | (1<<16));
189 if (retval != ERROR_OK)
190 return retval;
191 LOG_DEBUG("write core reg %i value 0x%" PRIx32 "", (int)num, value);
192 break;
193
194 case ARMV7M_S0 ... ARMV7M_S31:
195 /* Floating-point Status and Registers */
196 retval = target_write_u32(target, ARMV7M_SCS_DCRDR, value);
197 if (retval != ERROR_OK)
198 return retval;
199 retval = target_write_u32(target, ARMV7M_SCS_DCRSR, (num-ARMV7M_S0+64) | (1<<16));
200 if (retval != ERROR_OK)
201 return retval;
202 LOG_DEBUG("write core reg %i value 0x%" PRIx32 "", (int)num, value);
203 break;
204
205 case ARMV7M_D0 ... ARMV7M_D15:
206 break;
207
208 case ARMV7M_PRIMASK:
209 case ARMV7M_BASEPRI:
210 case ARMV7M_FAULTMASK:
211 case ARMV7M_CONTROL:
212 /* Cortex-M3 packages these four registers as bitfields
213 * in one Debug Core register. So say r0 and r2 docs;
214 * it was removed from r1 docs, but still works.
215 */
216
217 adapter->layout->api->read_reg(adapter->fd, 20, &reg);
218
219 switch (num) {
220 case ARMV7M_PRIMASK:
221 buf_set_u32((uint8_t *) &reg, 0, 1, value);
222 break;
223
224 case ARMV7M_BASEPRI:
225 buf_set_u32((uint8_t *) &reg, 8, 8, value);
226 break;
227
228 case ARMV7M_FAULTMASK:
229 buf_set_u32((uint8_t *) &reg, 16, 1, value);
230 break;
231
232 case ARMV7M_CONTROL:
233 buf_set_u32((uint8_t *) &reg, 24, 2, value);
234 break;
235 }
236
237 adapter->layout->api->write_reg(adapter->fd, 20, reg);
238
239 LOG_DEBUG("write special reg %i value 0x%" PRIx32 " ", (int)num, value);
240 break;
241
242 default:
243 return ERROR_COMMAND_SYNTAX_ERROR;
244 }
245
246 return ERROR_OK;
247 }
248
249 static int adapter_examine_debug_reason(struct target *target)
250 {
251 if ((target->debug_reason != DBG_REASON_DBGRQ)
252 && (target->debug_reason != DBG_REASON_SINGLESTEP)) {
253 target->debug_reason = DBG_REASON_BREAKPOINT;
254 }
255
256 return ERROR_OK;
257 }
258
259 static int hl_dcc_read(struct hl_interface_s *hl_if, uint8_t *value, uint8_t *ctrl)
260 {
261 uint16_t dcrdr;
262 int retval = hl_if->layout->api->read_mem8(hl_if->fd,
263 DCB_DCRDR, sizeof(dcrdr), (uint8_t *)&dcrdr);
264 if (retval == ERROR_OK) {
265 *ctrl = (uint8_t)dcrdr;
266 *value = (uint8_t)(dcrdr >> 8);
267
268 LOG_DEBUG("data 0x%x ctrl 0x%x", *value, *ctrl);
269
270 if (dcrdr & 1) {
271 /* write ack back to software dcc register
272 * to signify we have read data */
273 /* atomically clear just the byte containing the busy bit */
274 static const uint8_t zero;
275 retval = hl_if->layout->api->write_mem8(
276 hl_if->fd, DCB_DCRDR, 1, &zero);
277 }
278 }
279 return retval;
280 }
281
282 static int hl_target_request_data(struct target *target,
283 uint32_t size, uint8_t *buffer)
284 {
285 struct hl_interface_s *hl_if = target_to_adapter(target);
286 uint8_t data;
287 uint8_t ctrl;
288 uint32_t i;
289
290 for (i = 0; i < (size * 4); i++) {
291 hl_dcc_read(hl_if, &data, &ctrl);
292 buffer[i] = data;
293 }
294
295 return ERROR_OK;
296 }
297
298 static int hl_handle_target_request(void *priv)
299 {
300 struct target *target = priv;
301 if (!target_was_examined(target))
302 return ERROR_OK;
303 struct hl_interface_s *hl_if = target_to_adapter(target);
304
305 if (!target->dbg_msg_enabled)
306 return ERROR_OK;
307
308 if (target->state == TARGET_RUNNING) {
309 uint8_t data;
310 uint8_t ctrl;
311
312 hl_dcc_read(hl_if, &data, &ctrl);
313
314 /* check if we have data */
315 if (ctrl & (1 << 0)) {
316 uint32_t request;
317
318 /* we assume target is quick enough */
319 request = data;
320 hl_dcc_read(hl_if, &data, &ctrl);
321 request |= (data << 8);
322 hl_dcc_read(hl_if, &data, &ctrl);
323 request |= (data << 16);
324 hl_dcc_read(hl_if, &data, &ctrl);
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_m3_common *cortex_m3,
335 struct jtag_tap *tap)
336 {
337 struct armv7m_common *armv7m;
338
339 LOG_DEBUG("%s", __func__);
340
341 armv7m = &cortex_m3->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, 1, 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
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
370 struct cortex_m3_common *cortex_m3 = calloc(1, sizeof(struct cortex_m3_common));
371
372 if (!cortex_m3)
373 return ERROR_COMMAND_SYNTAX_ERROR;
374
375 adapter_init_arch_info(target, cortex_m3, target->tap);
376
377 return ERROR_OK;
378 }
379
380 static int adapter_load_context(struct target *target)
381 {
382 struct armv7m_common *armv7m = target_to_armv7m(target);
383 int num_regs = armv7m->arm.core_cache->num_regs;
384
385 for (int i = 0; i < num_regs; i++) {
386
387 struct reg *r = &armv7m->arm.core_cache->reg_list[i];
388 if (!r->valid)
389 armv7m->arm.read_core_reg(target, r, i, ARM_MODE_ANY);
390 }
391
392 return ERROR_OK;
393 }
394
395 static int adapter_debug_entry(struct target *target)
396 {
397 struct hl_interface_s *adapter = target_to_adapter(target);
398 struct armv7m_common *armv7m = target_to_armv7m(target);
399 struct arm *arm = &armv7m->arm;
400 struct reg *r;
401 uint32_t xPSR;
402 int retval;
403
404 /* preserve the DCRDR across halts */
405 retval = target_read_u32(target, DCB_DCRDR, &target->savedDCRDR);
406 if (retval != ERROR_OK)
407 return retval;
408
409 retval = armv7m->examine_debug_reason(target);
410 if (retval != ERROR_OK)
411 return retval;
412
413 adapter_load_context(target);
414
415 /* make sure we clear the vector catch bit */
416 adapter->layout->api->write_debug_reg(adapter->fd, DCB_DEMCR, TRCENA);
417
418 r = arm->cpsr;
419 xPSR = buf_get_u32(r->value, 0, 32);
420
421 /* Are we in an exception handler */
422 if (xPSR & 0x1FF) {
423 armv7m->exception_number = (xPSR & 0x1FF);
424
425 arm->core_mode = ARM_MODE_HANDLER;
426 arm->map = armv7m_msp_reg_map;
427 } else {
428 unsigned control = buf_get_u32(arm->core_cache
429 ->reg_list[ARMV7M_CONTROL].value, 0, 2);
430
431 /* is this thread privileged? */
432 arm->core_mode = control & 1
433 ? ARM_MODE_USER_THREAD
434 : ARM_MODE_THREAD;
435
436 /* which stack is it using? */
437 if (control & 2)
438 arm->map = armv7m_psp_reg_map;
439 else
440 arm->map = armv7m_msp_reg_map;
441
442 armv7m->exception_number = 0;
443 }
444
445 LOG_DEBUG("entered debug state in core mode: %s at PC 0x%08" PRIx32 ", target->state: %s",
446 arm_mode_name(arm->core_mode),
447 *(uint32_t *)(arm->pc->value),
448 target_state_name(target));
449
450 return retval;
451 }
452
453 static int adapter_poll(struct target *target)
454 {
455 enum target_state state;
456 struct hl_interface_s *adapter = target_to_adapter(target);
457 struct armv7m_common *armv7m = target_to_armv7m(target);
458 enum target_state prev_target_state = target->state;
459
460 state = adapter->layout->api->state(adapter->fd);
461
462 if (state == TARGET_UNKNOWN) {
463 LOG_ERROR("jtag status contains invalid mode value - communication failure");
464 return ERROR_TARGET_FAILURE;
465 }
466
467 if (target->state == state)
468 return ERROR_OK;
469
470 if (state == TARGET_HALTED) {
471 target->state = state;
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%08x", 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->fd, 0);
509 srst_asserted = true;
510 }
511
512 adapter->layout->api->write_debug_reg(adapter->fd, 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->fd, DCB_DEMCR, TRCENA|VC_CORERESET);
517 else
518 adapter->layout->api->write_debug_reg(adapter->fd, 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->fd, 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->fd, NVIC_AIRCR, AIRCR_VECTKEY | AIRCR_SYSRESETREQ);
536 }
537
538 res = adapter->layout->api->reset(adapter->fd);
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->fd, 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->fd);
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 uint32_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 0x%08x %d %d", __func__, current, address,
614 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_m3_enable_breakpoints(target);
624 cortex_m3_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 0x%8.8" PRIx32 " (ID: %d)",
662 breakpoint->address,
663 breakpoint->unique_id);
664 cortex_m3_unset_breakpoint(target, breakpoint);
665
666 res = adapter->layout->api->step(adapter->fd);
667
668 if (res != ERROR_OK)
669 return res;
670
671 cortex_m3_set_breakpoint(target, breakpoint);
672 }
673 }
674
675 res = adapter->layout->api->run(adapter->fd);
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 uint32_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_m3_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->fd);
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_m3_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%08x", 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, uint32_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 int res;
763 uint32_t buffer_threshold = (adapter->param.max_buffer / 4);
764 uint32_t addr_increment = 4;
765 uint32_t c;
766
767 if (!count || !buffer)
768 return ERROR_COMMAND_SYNTAX_ERROR;
769
770 LOG_DEBUG("%s 0x%08x %d %d", __func__, address, size, count);
771
772 /* prepare byte count, buffer threshold
773 * and address increment for none 32bit access
774 */
775 if (size != 4) {
776 count *= size;
777 buffer_threshold = (adapter->param.max_buffer / 4) / 2;
778 addr_increment = 1;
779 }
780
781 while (count) {
782 if (count > buffer_threshold)
783 c = buffer_threshold;
784 else
785 c = count;
786
787 if (size != 4)
788 res = adapter->layout->api->read_mem8(adapter->fd,
789 address, c, buffer);
790 else
791 res = adapter->layout->api->read_mem32(adapter->fd,
792 address, c, buffer);
793
794 if (res != ERROR_OK)
795 return res;
796
797 address += (c * addr_increment);
798 buffer += (c * addr_increment);
799 count -= c;
800 }
801
802 return ERROR_OK;
803 }
804
805 static int adapter_write_memory(struct target *target, uint32_t address,
806 uint32_t size, uint32_t count,
807 const uint8_t *buffer)
808 {
809 struct hl_interface_s *adapter = target_to_adapter(target);
810 int res;
811 uint32_t buffer_threshold = (adapter->param.max_buffer / 4);
812 uint32_t addr_increment = 4;
813 uint32_t c;
814
815 if (!count || !buffer)
816 return ERROR_COMMAND_SYNTAX_ERROR;
817
818 LOG_DEBUG("%s 0x%08x %d %d", __func__, address, size, count);
819
820 /* prepare byte count, buffer threshold
821 * and address increment for none 32bit access
822 */
823 if (size != 4) {
824 count *= size;
825 buffer_threshold = (adapter->param.max_buffer / 4) / 2;
826 addr_increment = 1;
827 }
828
829 while (count) {
830 if (count > buffer_threshold)
831 c = buffer_threshold;
832 else
833 c = count;
834
835 if (size != 4)
836 res = adapter->layout->api->write_mem8(adapter->fd,
837 address, c, buffer);
838 else
839 res = adapter->layout->api->write_mem32(adapter->fd,
840 address, c, buffer);
841
842 if (res != ERROR_OK)
843 return res;
844
845 address += (c * addr_increment);
846 buffer += (c * addr_increment);
847 count -= c;
848 }
849
850 return ERROR_OK;
851 }
852
853 static const struct command_registration adapter_command_handlers[] = {
854 {
855 .chain = arm_command_handlers,
856 },
857 COMMAND_REGISTRATION_DONE
858 };
859
860 struct target_type hla_target = {
861 .name = "hla_target",
862 .deprecated_name = "stm32_stlink",
863
864 .init_target = adapter_init_target,
865 .target_create = adapter_target_create,
866 .examine = cortex_m3_examine,
867 .commands = adapter_command_handlers,
868
869 .poll = adapter_poll,
870 .arch_state = armv7m_arch_state,
871
872 .target_request_data = hl_target_request_data,
873 .assert_reset = adapter_assert_reset,
874 .deassert_reset = adapter_deassert_reset,
875
876 .halt = adapter_halt,
877 .resume = adapter_resume,
878 .step = adapter_step,
879
880 .get_gdb_reg_list = armv7m_get_gdb_reg_list,
881
882 .read_memory = adapter_read_memory,
883 .write_memory = adapter_write_memory,
884 .checksum_memory = armv7m_checksum_memory,
885 .blank_check_memory = armv7m_blank_check_memory,
886
887 .run_algorithm = armv7m_run_algorithm,
888 .start_algorithm = armv7m_start_algorithm,
889 .wait_algorithm = armv7m_wait_algorithm,
890
891 .add_breakpoint = cortex_m3_add_breakpoint,
892 .remove_breakpoint = cortex_m3_remove_breakpoint,
893 .add_watchpoint = cortex_m3_add_watchpoint,
894 .remove_watchpoint = cortex_m3_remove_watchpoint,
895 };

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)