078ac647942ec4aad870f8e7bf0df3155d90cefb
[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 #ifdef ARMV7_GDB_HACKS
161 /* If the LR register is being modified, make sure it will put us
162 * in "thumb" mode, or an INVSTATE exception will occur. This is a
163 * hack to deal with the fact that gdb will sometimes "forge"
164 * return addresses, and doesn't set the LSB correctly (i.e., when
165 * printing expressions containing function calls, it sets LR = 0.)
166 * Valid exception return codes have bit 0 set too.
167 */
168 if (num == ARMV7M_R14)
169 value |= 0x01;
170 #endif
171
172 /* NOTE: we "know" here that the register identifiers used
173 * in the v7m header match the Cortex-M3 Debug Core Register
174 * Selector values for R0..R15, xPSR, MSP, and PSP.
175 */
176 switch (num) {
177 case 0 ... 18:
178 retval = adapter->layout->api->write_reg(adapter->fd, num, value);
179
180 if (retval != ERROR_OK) {
181 struct reg *r;
182
183 LOG_ERROR("JTAG failure");
184 r = armv7m->arm.core_cache->reg_list + num;
185 r->dirty = r->valid;
186 return ERROR_JTAG_DEVICE_ERROR;
187 }
188 LOG_DEBUG("write core reg %i value 0x%" PRIx32 "", (int)num, value);
189 break;
190
191 case ARMV7M_FPSID:
192 case ARMV7M_FPEXC:
193 break;
194
195 case ARMV7M_FPSCR:
196 /* Floating-point Status and Registers */
197 retval = target_write_u32(target, ARMV7M_SCS_DCRDR, value);
198 if (retval != ERROR_OK)
199 return retval;
200 retval = target_write_u32(target, ARMV7M_SCS_DCRSR, 33 | (1<<16));
201 if (retval != ERROR_OK)
202 return retval;
203 LOG_DEBUG("write core reg %i value 0x%" PRIx32 "", (int)num, value);
204 break;
205
206 case ARMV7M_S0 ... ARMV7M_S31:
207 /* Floating-point Status and Registers */
208 retval = target_write_u32(target, ARMV7M_SCS_DCRDR, value);
209 if (retval != ERROR_OK)
210 return retval;
211 retval = target_write_u32(target, ARMV7M_SCS_DCRSR, (num-ARMV7M_S0+64) | (1<<16));
212 if (retval != ERROR_OK)
213 return retval;
214 LOG_DEBUG("write core reg %i value 0x%" PRIx32 "", (int)num, value);
215 break;
216
217 case ARMV7M_D0 ... ARMV7M_D15:
218 break;
219
220 case ARMV7M_PRIMASK:
221 case ARMV7M_BASEPRI:
222 case ARMV7M_FAULTMASK:
223 case ARMV7M_CONTROL:
224 /* Cortex-M3 packages these four registers as bitfields
225 * in one Debug Core register. So say r0 and r2 docs;
226 * it was removed from r1 docs, but still works.
227 */
228
229 adapter->layout->api->read_reg(adapter->fd, 20, &reg);
230
231 switch (num) {
232 case ARMV7M_PRIMASK:
233 buf_set_u32((uint8_t *) &reg, 0, 1, value);
234 break;
235
236 case ARMV7M_BASEPRI:
237 buf_set_u32((uint8_t *) &reg, 8, 8, value);
238 break;
239
240 case ARMV7M_FAULTMASK:
241 buf_set_u32((uint8_t *) &reg, 16, 1, value);
242 break;
243
244 case ARMV7M_CONTROL:
245 buf_set_u32((uint8_t *) &reg, 24, 2, value);
246 break;
247 }
248
249 adapter->layout->api->write_reg(adapter->fd, 20, reg);
250
251 LOG_DEBUG("write special reg %i value 0x%" PRIx32 " ", (int)num, value);
252 break;
253
254 default:
255 return ERROR_COMMAND_SYNTAX_ERROR;
256 }
257
258 return ERROR_OK;
259 }
260
261 static int adapter_examine_debug_reason(struct target *target)
262 {
263 if ((target->debug_reason != DBG_REASON_DBGRQ)
264 && (target->debug_reason != DBG_REASON_SINGLESTEP)) {
265 target->debug_reason = DBG_REASON_BREAKPOINT;
266 }
267
268 return ERROR_OK;
269 }
270
271 static int hl_dcc_read(struct hl_interface_s *hl_if, uint8_t *value, uint8_t *ctrl)
272 {
273 uint16_t dcrdr;
274 int retval = hl_if->layout->api->read_mem8(hl_if->fd,
275 DCB_DCRDR, sizeof(dcrdr), (uint8_t *)&dcrdr);
276 if (retval == ERROR_OK) {
277 *ctrl = (uint8_t)dcrdr;
278 *value = (uint8_t)(dcrdr >> 8);
279
280 LOG_DEBUG("data 0x%x ctrl 0x%x", *value, *ctrl);
281
282 if (dcrdr & 1) {
283 /* write ack back to software dcc register
284 * to signify we have read data */
285 /* atomically clear just the byte containing the busy bit */
286 static const uint8_t zero;
287 retval = hl_if->layout->api->write_mem8(
288 hl_if->fd, DCB_DCRDR, 1, &zero);
289 }
290 }
291 return retval;
292 }
293
294 static int hl_target_request_data(struct target *target,
295 uint32_t size, uint8_t *buffer)
296 {
297 struct hl_interface_s *hl_if = target_to_adapter(target);
298 uint8_t data;
299 uint8_t ctrl;
300 uint32_t i;
301
302 for (i = 0; i < (size * 4); i++) {
303 hl_dcc_read(hl_if, &data, &ctrl);
304 buffer[i] = data;
305 }
306
307 return ERROR_OK;
308 }
309
310 static int hl_handle_target_request(void *priv)
311 {
312 struct target *target = priv;
313 if (!target_was_examined(target))
314 return ERROR_OK;
315 struct hl_interface_s *hl_if = target_to_adapter(target);
316
317 if (!target->dbg_msg_enabled)
318 return ERROR_OK;
319
320 if (target->state == TARGET_RUNNING) {
321 uint8_t data;
322 uint8_t ctrl;
323
324 hl_dcc_read(hl_if, &data, &ctrl);
325
326 /* check if we have data */
327 if (ctrl & (1 << 0)) {
328 uint32_t request;
329
330 /* we assume target is quick enough */
331 request = data;
332 hl_dcc_read(hl_if, &data, &ctrl);
333 request |= (data << 8);
334 hl_dcc_read(hl_if, &data, &ctrl);
335 request |= (data << 16);
336 hl_dcc_read(hl_if, &data, &ctrl);
337 request |= (data << 24);
338 target_request(target, request);
339 }
340 }
341
342 return ERROR_OK;
343 }
344
345 static int adapter_init_arch_info(struct target *target,
346 struct cortex_m3_common *cortex_m3,
347 struct jtag_tap *tap)
348 {
349 struct armv7m_common *armv7m;
350
351 LOG_DEBUG("%s", __func__);
352
353 armv7m = &cortex_m3->armv7m;
354 armv7m_init_arch_info(target, armv7m);
355
356 armv7m->load_core_reg_u32 = adapter_load_core_reg_u32;
357 armv7m->store_core_reg_u32 = adapter_store_core_reg_u32;
358
359 armv7m->examine_debug_reason = adapter_examine_debug_reason;
360 armv7m->stlink = true;
361
362 target_register_timer_callback(hl_handle_target_request, 1, 1, target);
363
364 return ERROR_OK;
365 }
366
367 static int adapter_init_target(struct command_context *cmd_ctx,
368 struct target *target)
369 {
370 LOG_DEBUG("%s", __func__);
371
372 armv7m_build_reg_cache(target);
373
374 return ERROR_OK;
375 }
376
377 static int adapter_target_create(struct target *target,
378 Jim_Interp *interp)
379 {
380 LOG_DEBUG("%s", __func__);
381
382 struct cortex_m3_common *cortex_m3 = calloc(1, sizeof(struct cortex_m3_common));
383
384 if (!cortex_m3)
385 return ERROR_COMMAND_SYNTAX_ERROR;
386
387 adapter_init_arch_info(target, cortex_m3, target->tap);
388
389 return ERROR_OK;
390 }
391
392 static int adapter_load_context(struct target *target)
393 {
394 struct armv7m_common *armv7m = target_to_armv7m(target);
395 int num_regs = armv7m->arm.core_cache->num_regs;
396
397 for (int i = 0; i < num_regs; i++) {
398
399 struct reg *r = &armv7m->arm.core_cache->reg_list[i];
400 if (!r->valid)
401 armv7m->arm.read_core_reg(target, r, i, ARM_MODE_ANY);
402 }
403
404 return ERROR_OK;
405 }
406
407 static int adapter_debug_entry(struct target *target)
408 {
409 struct hl_interface_s *adapter = target_to_adapter(target);
410 struct armv7m_common *armv7m = target_to_armv7m(target);
411 struct arm *arm = &armv7m->arm;
412 struct reg *r;
413 uint32_t xPSR;
414 int retval;
415
416 /* preserve the DCRDR across halts */
417 retval = target_read_u32(target, DCB_DCRDR, &target->savedDCRDR);
418 if (retval != ERROR_OK)
419 return retval;
420
421 retval = armv7m->examine_debug_reason(target);
422 if (retval != ERROR_OK)
423 return retval;
424
425 adapter_load_context(target);
426
427 /* make sure we clear the vector catch bit */
428 adapter->layout->api->write_debug_reg(adapter->fd, DCB_DEMCR, TRCENA);
429
430 r = arm->cpsr;
431 xPSR = buf_get_u32(r->value, 0, 32);
432
433 /* Are we in an exception handler */
434 if (xPSR & 0x1FF) {
435 armv7m->exception_number = (xPSR & 0x1FF);
436
437 arm->core_mode = ARM_MODE_HANDLER;
438 arm->map = armv7m_msp_reg_map;
439 } else {
440 unsigned control = buf_get_u32(arm->core_cache
441 ->reg_list[ARMV7M_CONTROL].value, 0, 2);
442
443 /* is this thread privileged? */
444 arm->core_mode = control & 1
445 ? ARM_MODE_USER_THREAD
446 : ARM_MODE_THREAD;
447
448 /* which stack is it using? */
449 if (control & 2)
450 arm->map = armv7m_psp_reg_map;
451 else
452 arm->map = armv7m_msp_reg_map;
453
454 armv7m->exception_number = 0;
455 }
456
457 LOG_DEBUG("entered debug state in core mode: %s at PC 0x%08" PRIx32 ", target->state: %s",
458 arm_mode_name(arm->core_mode),
459 *(uint32_t *)(arm->pc->value),
460 target_state_name(target));
461
462 return retval;
463 }
464
465 static int adapter_poll(struct target *target)
466 {
467 enum target_state state;
468 struct hl_interface_s *adapter = target_to_adapter(target);
469 struct armv7m_common *armv7m = target_to_armv7m(target);
470 enum target_state prev_target_state = target->state;
471
472 state = adapter->layout->api->state(adapter->fd);
473
474 if (state == TARGET_UNKNOWN) {
475 LOG_ERROR("jtag status contains invalid mode value - communication failure");
476 return ERROR_TARGET_FAILURE;
477 }
478
479 if (target->state == state)
480 return ERROR_OK;
481
482 if (state == TARGET_HALTED) {
483 target->state = state;
484
485 int retval = adapter_debug_entry(target);
486 if (retval != ERROR_OK)
487 return retval;
488
489 if (prev_target_state == TARGET_DEBUG_RUNNING) {
490 target_call_event_callbacks(target, TARGET_EVENT_DEBUG_HALTED);
491 } else {
492 if (arm_semihosting(target, &retval) != 0)
493 return retval;
494
495 target_call_event_callbacks(target, TARGET_EVENT_HALTED);
496 }
497
498 LOG_DEBUG("halted: PC: 0x%08x", buf_get_u32(armv7m->arm.pc->value, 0, 32));
499 }
500
501 return ERROR_OK;
502 }
503
504 static int adapter_assert_reset(struct target *target)
505 {
506 int res = ERROR_OK;
507 struct hl_interface_s *adapter = target_to_adapter(target);
508 struct armv7m_common *armv7m = target_to_armv7m(target);
509 bool use_srst_fallback = true;
510
511 LOG_DEBUG("%s", __func__);
512
513 enum reset_types jtag_reset_config = jtag_get_reset_config();
514
515 bool srst_asserted = false;
516
517 if ((jtag_reset_config & RESET_HAS_SRST) &&
518 (jtag_reset_config & RESET_SRST_NO_GATING)) {
519 jtag_add_reset(0, 1);
520 res = adapter->layout->api->assert_srst(adapter->fd, 0);
521 srst_asserted = true;
522 }
523
524 adapter->layout->api->write_debug_reg(adapter->fd, DCB_DHCSR, DBGKEY|C_DEBUGEN);
525
526 /* only set vector catch if halt is requested */
527 if (target->reset_halt)
528 adapter->layout->api->write_debug_reg(adapter->fd, DCB_DEMCR, TRCENA|VC_CORERESET);
529 else
530 adapter->layout->api->write_debug_reg(adapter->fd, DCB_DEMCR, TRCENA);
531
532 if (jtag_reset_config & RESET_HAS_SRST) {
533 if (!srst_asserted) {
534 jtag_add_reset(0, 1);
535 res = adapter->layout->api->assert_srst(adapter->fd, 0);
536 }
537 if (res == ERROR_COMMAND_NOTFOUND)
538 LOG_ERROR("Hardware srst not supported, falling back to software reset");
539 else if (res == ERROR_OK) {
540 /* hardware srst supported */
541 use_srst_fallback = false;
542 }
543 }
544
545 if (use_srst_fallback) {
546 /* stlink v1 api does not support hardware srst, so we use a software reset fallback */
547 adapter->layout->api->write_debug_reg(adapter->fd, NVIC_AIRCR, AIRCR_VECTKEY | AIRCR_SYSRESETREQ);
548 }
549
550 res = adapter->layout->api->reset(adapter->fd);
551
552 if (res != ERROR_OK)
553 return res;
554
555 /* registers are now invalid */
556 register_cache_invalidate(armv7m->arm.core_cache);
557
558 if (target->reset_halt) {
559 target->state = TARGET_RESET;
560 target->debug_reason = DBG_REASON_DBGRQ;
561 } else {
562 target->state = TARGET_HALTED;
563 }
564
565 return ERROR_OK;
566 }
567
568 static int adapter_deassert_reset(struct target *target)
569 {
570 struct hl_interface_s *adapter = target_to_adapter(target);
571
572 enum reset_types jtag_reset_config = jtag_get_reset_config();
573
574 LOG_DEBUG("%s", __func__);
575
576 if (jtag_reset_config & RESET_HAS_SRST)
577 adapter->layout->api->assert_srst(adapter->fd, 1);
578
579 /* virtual deassert reset, we need it for the internal
580 * jtag state machine
581 */
582 jtag_add_reset(0, 0);
583
584 target->savedDCRDR = 0; /* clear both DCC busy bits on initial resume */
585
586 return target->reset_halt ? ERROR_OK : target_resume(target, 1, 0, 0, 0);
587 }
588
589 static int adapter_halt(struct target *target)
590 {
591 int res;
592 struct hl_interface_s *adapter = target_to_adapter(target);
593
594 LOG_DEBUG("%s", __func__);
595
596 if (target->state == TARGET_HALTED) {
597 LOG_DEBUG("target was already halted");
598 return ERROR_OK;
599 }
600
601 if (target->state == TARGET_UNKNOWN)
602 LOG_WARNING("target was in unknown state when halt was requested");
603
604 res = adapter->layout->api->halt(adapter->fd);
605
606 if (res != ERROR_OK)
607 return res;
608
609 target->debug_reason = DBG_REASON_DBGRQ;
610
611 return ERROR_OK;
612 }
613
614 static int adapter_resume(struct target *target, int current,
615 uint32_t address, int handle_breakpoints,
616 int debug_execution)
617 {
618 int res;
619 struct hl_interface_s *adapter = target_to_adapter(target);
620 struct armv7m_common *armv7m = target_to_armv7m(target);
621 uint32_t resume_pc;
622 struct breakpoint *breakpoint = NULL;
623 struct reg *pc;
624
625 LOG_DEBUG("%s %d 0x%08x %d %d", __func__, current, address,
626 handle_breakpoints, debug_execution);
627
628 if (target->state != TARGET_HALTED) {
629 LOG_WARNING("target not halted");
630 return ERROR_TARGET_NOT_HALTED;
631 }
632
633 if (!debug_execution) {
634 target_free_all_working_areas(target);
635 cortex_m3_enable_breakpoints(target);
636 cortex_m3_enable_watchpoints(target);
637 }
638
639 pc = armv7m->arm.pc;
640 if (!current) {
641 buf_set_u32(pc->value, 0, 32, address);
642 pc->dirty = true;
643 pc->valid = true;
644 }
645
646 if (!breakpoint_find(target, buf_get_u32(pc->value, 0, 32))
647 && !debug_execution) {
648 armv7m_maybe_skip_bkpt_inst(target, NULL);
649 }
650
651 resume_pc = buf_get_u32(pc->value, 0, 32);
652
653 /* write any user vector flags */
654 res = target_write_u32(target, DCB_DEMCR, TRCENA | armv7m->demcr);
655 if (res != ERROR_OK)
656 return res;
657
658 armv7m_restore_context(target);
659
660 /* restore savedDCRDR */
661 res = target_write_u32(target, DCB_DCRDR, target->savedDCRDR);
662 if (res != ERROR_OK)
663 return res;
664
665 /* registers are now invalid */
666 register_cache_invalidate(armv7m->arm.core_cache);
667
668 /* the front-end may request us not to handle breakpoints */
669 if (handle_breakpoints) {
670 /* Single step past breakpoint at current address */
671 breakpoint = breakpoint_find(target, resume_pc);
672 if (breakpoint) {
673 LOG_DEBUG("unset breakpoint at 0x%8.8" PRIx32 " (ID: %d)",
674 breakpoint->address,
675 breakpoint->unique_id);
676 cortex_m3_unset_breakpoint(target, breakpoint);
677
678 res = adapter->layout->api->step(adapter->fd);
679
680 if (res != ERROR_OK)
681 return res;
682
683 cortex_m3_set_breakpoint(target, breakpoint);
684 }
685 }
686
687 res = adapter->layout->api->run(adapter->fd);
688
689 if (res != ERROR_OK)
690 return res;
691
692 target->debug_reason = DBG_REASON_NOTHALTED;
693
694 if (!debug_execution) {
695 target->state = TARGET_RUNNING;
696 target_call_event_callbacks(target, TARGET_EVENT_RESUMED);
697 } else {
698 target->state = TARGET_DEBUG_RUNNING;
699 target_call_event_callbacks(target, TARGET_EVENT_DEBUG_RESUMED);
700 }
701
702 return ERROR_OK;
703 }
704
705 static int adapter_step(struct target *target, int current,
706 uint32_t address, int handle_breakpoints)
707 {
708 int res;
709 struct hl_interface_s *adapter = target_to_adapter(target);
710 struct armv7m_common *armv7m = target_to_armv7m(target);
711 struct breakpoint *breakpoint = NULL;
712 struct reg *pc = armv7m->arm.pc;
713 bool bkpt_inst_found = false;
714
715 LOG_DEBUG("%s", __func__);
716
717 if (target->state != TARGET_HALTED) {
718 LOG_WARNING("target not halted");
719 return ERROR_TARGET_NOT_HALTED;
720 }
721
722 if (!current) {
723 buf_set_u32(pc->value, 0, 32, address);
724 pc->dirty = true;
725 pc->valid = true;
726 }
727
728 uint32_t pc_value = buf_get_u32(pc->value, 0, 32);
729
730 /* the front-end may request us not to handle breakpoints */
731 if (handle_breakpoints) {
732 breakpoint = breakpoint_find(target, pc_value);
733 if (breakpoint)
734 cortex_m3_unset_breakpoint(target, breakpoint);
735 }
736
737 armv7m_maybe_skip_bkpt_inst(target, &bkpt_inst_found);
738
739 target->debug_reason = DBG_REASON_SINGLESTEP;
740
741 armv7m_restore_context(target);
742
743 /* restore savedDCRDR */
744 res = target_write_u32(target, DCB_DCRDR, target->savedDCRDR);
745 if (res != ERROR_OK)
746 return res;
747
748 target_call_event_callbacks(target, TARGET_EVENT_RESUMED);
749
750 res = adapter->layout->api->step(adapter->fd);
751
752 if (res != ERROR_OK)
753 return res;
754
755 /* registers are now invalid */
756 register_cache_invalidate(armv7m->arm.core_cache);
757
758 if (breakpoint)
759 cortex_m3_set_breakpoint(target, breakpoint);
760
761 adapter_debug_entry(target);
762 target_call_event_callbacks(target, TARGET_EVENT_HALTED);
763
764 LOG_INFO("halted: PC: 0x%08x", buf_get_u32(armv7m->arm.pc->value, 0, 32));
765
766 return ERROR_OK;
767 }
768
769 static int adapter_read_memory(struct target *target, uint32_t address,
770 uint32_t size, uint32_t count,
771 uint8_t *buffer)
772 {
773 struct hl_interface_s *adapter = target_to_adapter(target);
774 int res;
775 uint32_t buffer_threshold = (adapter->param.max_buffer / 4);
776 uint32_t addr_increment = 4;
777 uint32_t c;
778
779 if (!count || !buffer)
780 return ERROR_COMMAND_SYNTAX_ERROR;
781
782 LOG_DEBUG("%s 0x%08x %d %d", __func__, address, size, count);
783
784 /* prepare byte count, buffer threshold
785 * and address increment for none 32bit access
786 */
787 if (size != 4) {
788 count *= size;
789 buffer_threshold = (adapter->param.max_buffer / 4) / 2;
790 addr_increment = 1;
791 }
792
793 while (count) {
794 if (count > buffer_threshold)
795 c = buffer_threshold;
796 else
797 c = count;
798
799 if (size != 4)
800 res = adapter->layout->api->read_mem8(adapter->fd,
801 address, c, buffer);
802 else
803 res = adapter->layout->api->read_mem32(adapter->fd,
804 address, c, buffer);
805
806 if (res != ERROR_OK)
807 return res;
808
809 address += (c * addr_increment);
810 buffer += (c * addr_increment);
811 count -= c;
812 }
813
814 return ERROR_OK;
815 }
816
817 static int adapter_write_memory(struct target *target, uint32_t address,
818 uint32_t size, uint32_t count,
819 const uint8_t *buffer)
820 {
821 struct hl_interface_s *adapter = target_to_adapter(target);
822 int res;
823 uint32_t buffer_threshold = (adapter->param.max_buffer / 4);
824 uint32_t addr_increment = 4;
825 uint32_t c;
826
827 if (!count || !buffer)
828 return ERROR_COMMAND_SYNTAX_ERROR;
829
830 LOG_DEBUG("%s 0x%08x %d %d", __func__, address, size, count);
831
832 /* prepare byte count, buffer threshold
833 * and address increment for none 32bit access
834 */
835 if (size != 4) {
836 count *= size;
837 buffer_threshold = (adapter->param.max_buffer / 4) / 2;
838 addr_increment = 1;
839 }
840
841 while (count) {
842 if (count > buffer_threshold)
843 c = buffer_threshold;
844 else
845 c = count;
846
847 if (size != 4)
848 res = adapter->layout->api->write_mem8(adapter->fd,
849 address, c, buffer);
850 else
851 res = adapter->layout->api->write_mem32(adapter->fd,
852 address, c, buffer);
853
854 if (res != ERROR_OK)
855 return res;
856
857 address += (c * addr_increment);
858 buffer += (c * addr_increment);
859 count -= c;
860 }
861
862 return ERROR_OK;
863 }
864
865 static const struct command_registration adapter_command_handlers[] = {
866 {
867 .chain = arm_command_handlers,
868 },
869 COMMAND_REGISTRATION_DONE
870 };
871
872 struct target_type hla_target = {
873 .name = "hla_target",
874 .deprecated_name = "stm32_stlink",
875
876 .init_target = adapter_init_target,
877 .target_create = adapter_target_create,
878 .examine = cortex_m3_examine,
879 .commands = adapter_command_handlers,
880
881 .poll = adapter_poll,
882 .arch_state = armv7m_arch_state,
883
884 .target_request_data = hl_target_request_data,
885 .assert_reset = adapter_assert_reset,
886 .deassert_reset = adapter_deassert_reset,
887
888 .halt = adapter_halt,
889 .resume = adapter_resume,
890 .step = adapter_step,
891
892 .get_gdb_reg_list = armv7m_get_gdb_reg_list,
893
894 .read_memory = adapter_read_memory,
895 .write_memory = adapter_write_memory,
896 .checksum_memory = armv7m_checksum_memory,
897 .blank_check_memory = armv7m_blank_check_memory,
898
899 .run_algorithm = armv7m_run_algorithm,
900 .start_algorithm = armv7m_start_algorithm,
901 .wait_algorithm = armv7m_wait_algorithm,
902
903 .add_breakpoint = cortex_m3_add_breakpoint,
904 .remove_breakpoint = cortex_m3_remove_breakpoint,
905 .add_watchpoint = cortex_m3_add_watchpoint,
906 .remove_watchpoint = cortex_m3_remove_watchpoint,
907 };

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)