hla: Add Simulated DCC register for target communicaton
[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->core_cache->reg_list + ARMV7M_xPSR;
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_soft_reset_halt(struct target *target)
590 {
591 LOG_DEBUG("%s", __func__);
592 return ERROR_OK;
593 }
594
595 static int adapter_halt(struct target *target)
596 {
597 int res;
598 struct hl_interface_s *adapter = target_to_adapter(target);
599
600 LOG_DEBUG("%s", __func__);
601
602 if (target->state == TARGET_HALTED) {
603 LOG_DEBUG("target was already halted");
604 return ERROR_OK;
605 }
606
607 if (target->state == TARGET_UNKNOWN)
608 LOG_WARNING("target was in unknown state when halt was requested");
609
610 res = adapter->layout->api->halt(adapter->fd);
611
612 if (res != ERROR_OK)
613 return res;
614
615 target->debug_reason = DBG_REASON_DBGRQ;
616
617 return ERROR_OK;
618 }
619
620 static int adapter_resume(struct target *target, int current,
621 uint32_t address, int handle_breakpoints,
622 int debug_execution)
623 {
624 int res;
625 struct hl_interface_s *adapter = target_to_adapter(target);
626 struct armv7m_common *armv7m = target_to_armv7m(target);
627 uint32_t resume_pc;
628 struct breakpoint *breakpoint = NULL;
629 struct reg *pc;
630
631 LOG_DEBUG("%s %d 0x%08x %d %d", __func__, current, address,
632 handle_breakpoints, debug_execution);
633
634 if (target->state != TARGET_HALTED) {
635 LOG_WARNING("target not halted");
636 return ERROR_TARGET_NOT_HALTED;
637 }
638
639 if (!debug_execution) {
640 target_free_all_working_areas(target);
641 cortex_m3_enable_breakpoints(target);
642 cortex_m3_enable_watchpoints(target);
643 }
644
645 pc = armv7m->arm.pc;
646 if (!current) {
647 buf_set_u32(pc->value, 0, 32, address);
648 pc->dirty = true;
649 pc->valid = true;
650 }
651
652 if (!breakpoint_find(target, buf_get_u32(pc->value, 0, 32))
653 && !debug_execution) {
654 armv7m_maybe_skip_bkpt_inst(target, NULL);
655 }
656
657 resume_pc = buf_get_u32(pc->value, 0, 32);
658
659 /* write any user vector flags */
660 res = target_write_u32(target, DCB_DEMCR, TRCENA | armv7m->demcr);
661 if (res != ERROR_OK)
662 return res;
663
664 armv7m_restore_context(target);
665
666 /* restore savedDCRDR */
667 res = target_write_u32(target, DCB_DCRDR, target->savedDCRDR);
668 if (res != ERROR_OK)
669 return res;
670
671 /* registers are now invalid */
672 register_cache_invalidate(armv7m->arm.core_cache);
673
674 /* the front-end may request us not to handle breakpoints */
675 if (handle_breakpoints) {
676 /* Single step past breakpoint at current address */
677 breakpoint = breakpoint_find(target, resume_pc);
678 if (breakpoint) {
679 LOG_DEBUG("unset breakpoint at 0x%8.8" PRIx32 " (ID: %d)",
680 breakpoint->address,
681 breakpoint->unique_id);
682 cortex_m3_unset_breakpoint(target, breakpoint);
683
684 res = adapter->layout->api->step(adapter->fd);
685
686 if (res != ERROR_OK)
687 return res;
688
689 cortex_m3_set_breakpoint(target, breakpoint);
690 }
691 }
692
693 res = adapter->layout->api->run(adapter->fd);
694
695 if (res != ERROR_OK)
696 return res;
697
698 target->debug_reason = DBG_REASON_NOTHALTED;
699
700 if (!debug_execution) {
701 target->state = TARGET_RUNNING;
702 target_call_event_callbacks(target, TARGET_EVENT_RESUMED);
703 } else {
704 target->state = TARGET_DEBUG_RUNNING;
705 target_call_event_callbacks(target, TARGET_EVENT_DEBUG_RESUMED);
706 }
707
708 return ERROR_OK;
709 }
710
711 static int adapter_step(struct target *target, int current,
712 uint32_t address, int handle_breakpoints)
713 {
714 int res;
715 struct hl_interface_s *adapter = target_to_adapter(target);
716 struct armv7m_common *armv7m = target_to_armv7m(target);
717 struct breakpoint *breakpoint = NULL;
718 struct reg *pc = armv7m->arm.pc;
719 bool bkpt_inst_found = false;
720
721 LOG_DEBUG("%s", __func__);
722
723 if (target->state != TARGET_HALTED) {
724 LOG_WARNING("target not halted");
725 return ERROR_TARGET_NOT_HALTED;
726 }
727
728 if (!current) {
729 buf_set_u32(pc->value, 0, 32, address);
730 pc->dirty = true;
731 pc->valid = true;
732 }
733
734 uint32_t pc_value = buf_get_u32(pc->value, 0, 32);
735
736 /* the front-end may request us not to handle breakpoints */
737 if (handle_breakpoints) {
738 breakpoint = breakpoint_find(target, pc_value);
739 if (breakpoint)
740 cortex_m3_unset_breakpoint(target, breakpoint);
741 }
742
743 armv7m_maybe_skip_bkpt_inst(target, &bkpt_inst_found);
744
745 target->debug_reason = DBG_REASON_SINGLESTEP;
746
747 armv7m_restore_context(target);
748
749 /* restore savedDCRDR */
750 res = target_write_u32(target, DCB_DCRDR, target->savedDCRDR);
751 if (res != ERROR_OK)
752 return res;
753
754 target_call_event_callbacks(target, TARGET_EVENT_RESUMED);
755
756 res = adapter->layout->api->step(adapter->fd);
757
758 if (res != ERROR_OK)
759 return res;
760
761 /* registers are now invalid */
762 register_cache_invalidate(armv7m->arm.core_cache);
763
764 if (breakpoint)
765 cortex_m3_set_breakpoint(target, breakpoint);
766
767 adapter_debug_entry(target);
768 target_call_event_callbacks(target, TARGET_EVENT_HALTED);
769
770 LOG_INFO("halted: PC: 0x%08x", buf_get_u32(armv7m->arm.pc->value, 0, 32));
771
772 return ERROR_OK;
773 }
774
775 static int adapter_read_memory(struct target *target, uint32_t address,
776 uint32_t size, uint32_t count,
777 uint8_t *buffer)
778 {
779 struct hl_interface_s *adapter = target_to_adapter(target);
780 int res;
781 uint32_t buffer_threshold = (adapter->param.max_buffer / 4);
782 uint32_t addr_increment = 4;
783 uint32_t c;
784
785 if (!count || !buffer)
786 return ERROR_COMMAND_SYNTAX_ERROR;
787
788 LOG_DEBUG("%s 0x%08x %d %d", __func__, address, size, count);
789
790 /* prepare byte count, buffer threshold
791 * and address increment for none 32bit access
792 */
793 if (size != 4) {
794 count *= size;
795 buffer_threshold = (adapter->param.max_buffer / 4) / 2;
796 addr_increment = 1;
797 }
798
799 while (count) {
800 if (count > buffer_threshold)
801 c = buffer_threshold;
802 else
803 c = count;
804
805 if (size != 4)
806 res = adapter->layout->api->read_mem8(adapter->fd,
807 address, c, buffer);
808 else
809 res = adapter->layout->api->read_mem32(adapter->fd,
810 address, c, buffer);
811
812 if (res != ERROR_OK)
813 return res;
814
815 address += (c * addr_increment);
816 buffer += (c * addr_increment);
817 count -= c;
818 }
819
820 return ERROR_OK;
821 }
822
823 static int adapter_write_memory(struct target *target, uint32_t address,
824 uint32_t size, uint32_t count,
825 const uint8_t *buffer)
826 {
827 struct hl_interface_s *adapter = target_to_adapter(target);
828 int res;
829 uint32_t buffer_threshold = (adapter->param.max_buffer / 4);
830 uint32_t addr_increment = 4;
831 uint32_t c;
832
833 if (!count || !buffer)
834 return ERROR_COMMAND_SYNTAX_ERROR;
835
836 LOG_DEBUG("%s 0x%08x %d %d", __func__, address, size, count);
837
838 /* prepare byte count, buffer threshold
839 * and address increment for none 32bit access
840 */
841 if (size != 4) {
842 count *= size;
843 buffer_threshold = (adapter->param.max_buffer / 4) / 2;
844 addr_increment = 1;
845 }
846
847 while (count) {
848 if (count > buffer_threshold)
849 c = buffer_threshold;
850 else
851 c = count;
852
853 if (size != 4)
854 res = adapter->layout->api->write_mem8(adapter->fd,
855 address, c, buffer);
856 else
857 res = adapter->layout->api->write_mem32(adapter->fd,
858 address, c, buffer);
859
860 if (res != ERROR_OK)
861 return res;
862
863 address += (c * addr_increment);
864 buffer += (c * addr_increment);
865 count -= c;
866 }
867
868 return ERROR_OK;
869 }
870
871 static const struct command_registration adapter_command_handlers[] = {
872 {
873 .chain = arm_command_handlers,
874 },
875 COMMAND_REGISTRATION_DONE
876 };
877
878 struct target_type hla_target = {
879 .name = "hla_target",
880 .deprecated_name = "stm32_stlink",
881
882 .init_target = adapter_init_target,
883 .target_create = adapter_target_create,
884 .examine = cortex_m3_examine,
885 .commands = adapter_command_handlers,
886
887 .poll = adapter_poll,
888 .arch_state = armv7m_arch_state,
889
890 .target_request_data = hl_target_request_data,
891 .assert_reset = adapter_assert_reset,
892 .deassert_reset = adapter_deassert_reset,
893 .soft_reset_halt = adapter_soft_reset_halt,
894
895 .halt = adapter_halt,
896 .resume = adapter_resume,
897 .step = adapter_step,
898
899 .get_gdb_reg_list = armv7m_get_gdb_reg_list,
900
901 .read_memory = adapter_read_memory,
902 .write_memory = adapter_write_memory,
903 .checksum_memory = armv7m_checksum_memory,
904 .blank_check_memory = armv7m_blank_check_memory,
905
906 .run_algorithm = armv7m_run_algorithm,
907 .start_algorithm = armv7m_start_algorithm,
908 .wait_algorithm = armv7m_wait_algorithm,
909
910 .add_breakpoint = cortex_m3_add_breakpoint,
911 .remove_breakpoint = cortex_m3_remove_breakpoint,
912 .add_watchpoint = cortex_m3_add_watchpoint,
913 .remove_watchpoint = cortex_m3_remove_watchpoint,
914 };

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)