armv7m: use generic arm read/write_core_reg
[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 * This program is free software; you can redistribute it and/or modify *
9 * it under the terms of the GNU General Public License as published by *
10 * the Free Software Foundation; either version 2 of the License, or *
11 * (at your option) any later version. *
12 * *
13 * This program is distributed in the hope that it will be useful, *
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
16 * GNU General Public License for more details. *
17 * *
18 * You should have received a copy of the GNU General Public License *
19 * along with this program; if not, write to the *
20 * Free Software Foundation, Inc., *
21 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
22 ***************************************************************************/
23
24 #ifdef HAVE_CONFIG_H
25 #include "config.h"
26 #endif
27
28 #include "jtag/jtag.h"
29 #include "jtag/hla/hla_transport.h"
30 #include "jtag/hla/hla_interface.h"
31 #include "jtag/hla/hla_layout.h"
32 #include "register.h"
33 #include "algorithm.h"
34 #include "target.h"
35 #include "breakpoints.h"
36 #include "target_type.h"
37 #include "armv7m.h"
38 #include "cortex_m.h"
39 #include "arm_semihosting.h"
40
41 #define ARMV7M_SCS_DCRSR 0xe000edf4
42 #define ARMV7M_SCS_DCRDR 0xe000edf8
43
44 static inline struct hl_interface_s *target_to_adapter(struct target *target)
45 {
46 return target->tap->priv;
47 }
48
49 static int adapter_load_core_reg_u32(struct target *target,
50 uint32_t num, uint32_t *value)
51 {
52 int retval;
53 struct hl_interface_s *adapter = target_to_adapter(target);
54
55 LOG_DEBUG("%s", __func__);
56
57 /* NOTE: we "know" here that the register identifiers used
58 * in the v7m header match the Cortex-M3 Debug Core Register
59 * Selector values for R0..R15, xPSR, MSP, and PSP.
60 */
61 switch (num) {
62 case 0 ... 18:
63 /* read a normal core register */
64 retval = adapter->layout->api->read_reg(adapter->fd, num, value);
65
66 if (retval != ERROR_OK) {
67 LOG_ERROR("JTAG failure %i", retval);
68 return ERROR_JTAG_DEVICE_ERROR;
69 }
70 LOG_DEBUG("load from core reg %i value 0x%" PRIx32 "", (int)num, *value);
71 break;
72
73 case ARMV7M_FPSID:
74 case ARMV7M_FPEXC:
75 *value = 0;
76 break;
77
78 case ARMV7M_FPSCR:
79 /* Floating-point Status and Registers */
80 retval = target_write_u32(target, ARMV7M_SCS_DCRSR, 33);
81 if (retval != ERROR_OK)
82 return retval;
83 retval = target_read_u32(target, ARMV7M_SCS_DCRDR, value);
84 if (retval != ERROR_OK)
85 return retval;
86 LOG_DEBUG("load from core reg %i value 0x%" PRIx32 "", (int)num, *value);
87 break;
88
89 case ARMV7M_S0 ... ARMV7M_S31:
90 /* Floating-point Status and Registers */
91 retval = target_write_u32(target, ARMV7M_SCS_DCRSR, num-ARMV7M_S0+64);
92 if (retval != ERROR_OK)
93 return retval;
94 retval = target_read_u32(target, ARMV7M_SCS_DCRDR, value);
95 if (retval != ERROR_OK)
96 return retval;
97 LOG_DEBUG("load from core reg %i value 0x%" PRIx32 "", (int)num, *value);
98 break;
99
100 case ARMV7M_D0 ... ARMV7M_D15:
101 value = 0;
102 break;
103
104 case ARMV7M_PRIMASK:
105 case ARMV7M_BASEPRI:
106 case ARMV7M_FAULTMASK:
107 case ARMV7M_CONTROL:
108 /* Cortex-M3 packages these four registers as bitfields
109 * in one Debug Core register. So say r0 and r2 docs;
110 * it was removed from r1 docs, but still works.
111 */
112 retval = adapter->layout->api->read_reg(adapter->fd, 20, value);
113 if (retval != ERROR_OK)
114 return retval;
115
116 switch (num) {
117 case ARMV7M_PRIMASK:
118 *value = buf_get_u32((uint8_t *) value, 0, 1);
119 break;
120
121 case ARMV7M_BASEPRI:
122 *value = buf_get_u32((uint8_t *) value, 8, 8);
123 break;
124
125 case ARMV7M_FAULTMASK:
126 *value = buf_get_u32((uint8_t *) value, 16, 1);
127 break;
128
129 case ARMV7M_CONTROL:
130 *value = buf_get_u32((uint8_t *) value, 24, 2);
131 break;
132 }
133
134 LOG_DEBUG("load from special reg %i value 0x%" PRIx32 "",
135 (int)num, *value);
136 break;
137
138 default:
139 return ERROR_COMMAND_SYNTAX_ERROR;
140 }
141
142 return ERROR_OK;
143 }
144
145 static int adapter_store_core_reg_u32(struct target *target,
146 uint32_t num, uint32_t value)
147 {
148 int retval;
149 uint32_t reg;
150 struct armv7m_common *armv7m = target_to_armv7m(target);
151 struct hl_interface_s *adapter = target_to_adapter(target);
152
153 LOG_DEBUG("%s", __func__);
154
155 #ifdef ARMV7_GDB_HACKS
156 /* If the LR register is being modified, make sure it will put us
157 * in "thumb" mode, or an INVSTATE exception will occur. This is a
158 * hack to deal with the fact that gdb will sometimes "forge"
159 * return addresses, and doesn't set the LSB correctly (i.e., when
160 * printing expressions containing function calls, it sets LR = 0.)
161 * Valid exception return codes have bit 0 set too.
162 */
163 if (num == ARMV7M_R14)
164 value |= 0x01;
165 #endif
166
167 /* NOTE: we "know" here that the register identifiers used
168 * in the v7m header match the Cortex-M3 Debug Core Register
169 * Selector values for R0..R15, xPSR, MSP, and PSP.
170 */
171 switch (num) {
172 case 0 ... 18:
173 retval = adapter->layout->api->write_reg(adapter->fd, num, value);
174
175 if (retval != ERROR_OK) {
176 struct reg *r;
177
178 LOG_ERROR("JTAG failure");
179 r = armv7m->arm.core_cache->reg_list + num;
180 r->dirty = r->valid;
181 return ERROR_JTAG_DEVICE_ERROR;
182 }
183 LOG_DEBUG("write core reg %i value 0x%" PRIx32 "", (int)num, value);
184 break;
185
186 case ARMV7M_FPSID:
187 case ARMV7M_FPEXC:
188 break;
189
190 case ARMV7M_FPSCR:
191 /* Floating-point Status and Registers */
192 retval = target_write_u32(target, ARMV7M_SCS_DCRDR, value);
193 if (retval != ERROR_OK)
194 return retval;
195 retval = target_write_u32(target, ARMV7M_SCS_DCRSR, 33 | (1<<16));
196 if (retval != ERROR_OK)
197 return retval;
198 LOG_DEBUG("write core reg %i value 0x%" PRIx32 "", (int)num, value);
199 break;
200
201 case ARMV7M_S0 ... ARMV7M_S31:
202 /* Floating-point Status and Registers */
203 retval = target_write_u32(target, ARMV7M_SCS_DCRDR, value);
204 if (retval != ERROR_OK)
205 return retval;
206 retval = target_write_u32(target, ARMV7M_SCS_DCRSR, (num-ARMV7M_S0+64) | (1<<16));
207 if (retval != ERROR_OK)
208 return retval;
209 LOG_DEBUG("write core reg %i value 0x%" PRIx32 "", (int)num, value);
210 break;
211
212 case ARMV7M_D0 ... ARMV7M_D15:
213 break;
214
215 case ARMV7M_PRIMASK:
216 case ARMV7M_BASEPRI:
217 case ARMV7M_FAULTMASK:
218 case ARMV7M_CONTROL:
219 /* Cortex-M3 packages these four registers as bitfields
220 * in one Debug Core register. So say r0 and r2 docs;
221 * it was removed from r1 docs, but still works.
222 */
223
224 adapter->layout->api->read_reg(adapter->fd, 20, &reg);
225
226 switch (num) {
227 case ARMV7M_PRIMASK:
228 buf_set_u32((uint8_t *) &reg, 0, 1, value);
229 break;
230
231 case ARMV7M_BASEPRI:
232 buf_set_u32((uint8_t *) &reg, 8, 8, value);
233 break;
234
235 case ARMV7M_FAULTMASK:
236 buf_set_u32((uint8_t *) &reg, 16, 1, value);
237 break;
238
239 case ARMV7M_CONTROL:
240 buf_set_u32((uint8_t *) &reg, 24, 2, value);
241 break;
242 }
243
244 adapter->layout->api->write_reg(adapter->fd, 20, reg);
245
246 LOG_DEBUG("write special reg %i value 0x%" PRIx32 " ", (int)num, value);
247 break;
248
249 default:
250 return ERROR_COMMAND_SYNTAX_ERROR;
251 }
252
253 return ERROR_OK;
254 }
255
256 static int adapter_examine_debug_reason(struct target *target)
257 {
258 if ((target->debug_reason != DBG_REASON_DBGRQ)
259 && (target->debug_reason != DBG_REASON_SINGLESTEP)) {
260 target->debug_reason = DBG_REASON_BREAKPOINT;
261 }
262
263 return ERROR_OK;
264 }
265
266 static int adapter_init_arch_info(struct target *target,
267 struct cortex_m3_common *cortex_m3,
268 struct jtag_tap *tap)
269 {
270 struct armv7m_common *armv7m;
271
272 LOG_DEBUG("%s", __func__);
273
274 armv7m = &cortex_m3->armv7m;
275 armv7m_init_arch_info(target, armv7m);
276
277 armv7m->load_core_reg_u32 = adapter_load_core_reg_u32;
278 armv7m->store_core_reg_u32 = adapter_store_core_reg_u32;
279
280 armv7m->examine_debug_reason = adapter_examine_debug_reason;
281 armv7m->stlink = true;
282
283 return ERROR_OK;
284 }
285
286 static int adapter_init_target(struct command_context *cmd_ctx,
287 struct target *target)
288 {
289 LOG_DEBUG("%s", __func__);
290
291 armv7m_build_reg_cache(target);
292
293 return ERROR_OK;
294 }
295
296 static int adapter_target_create(struct target *target,
297 Jim_Interp *interp)
298 {
299 LOG_DEBUG("%s", __func__);
300
301 struct cortex_m3_common *cortex_m3 = calloc(1, sizeof(struct cortex_m3_common));
302
303 if (!cortex_m3)
304 return ERROR_COMMAND_SYNTAX_ERROR;
305
306 adapter_init_arch_info(target, cortex_m3, target->tap);
307
308 return ERROR_OK;
309 }
310
311 static int adapter_load_context(struct target *target)
312 {
313 struct armv7m_common *armv7m = target_to_armv7m(target);
314 int num_regs = armv7m->arm.core_cache->num_regs;
315
316 for (int i = 0; i < num_regs; i++) {
317
318 struct reg *r = &armv7m->arm.core_cache->reg_list[i];
319 if (!r->valid)
320 armv7m->arm.read_core_reg(target, r, i, ARM_MODE_ANY);
321 }
322
323 return ERROR_OK;
324 }
325
326 static int adapter_debug_entry(struct target *target)
327 {
328 struct hl_interface_s *adapter = target_to_adapter(target);
329 struct armv7m_common *armv7m = target_to_armv7m(target);
330 struct arm *arm = &armv7m->arm;
331 struct reg *r;
332 uint32_t xPSR;
333 int retval;
334
335 retval = armv7m->examine_debug_reason(target);
336 if (retval != ERROR_OK)
337 return retval;
338
339 adapter_load_context(target);
340
341 /* make sure we clear the vector catch bit */
342 adapter->layout->api->write_debug_reg(adapter->fd, DCB_DEMCR, TRCENA);
343
344 r = arm->core_cache->reg_list + ARMV7M_xPSR;
345 xPSR = buf_get_u32(r->value, 0, 32);
346
347 /* Are we in an exception handler */
348 if (xPSR & 0x1FF) {
349 armv7m->exception_number = (xPSR & 0x1FF);
350
351 arm->core_mode = ARM_MODE_HANDLER;
352 arm->map = armv7m_msp_reg_map;
353 } else {
354 unsigned control = buf_get_u32(arm->core_cache
355 ->reg_list[ARMV7M_CONTROL].value, 0, 2);
356
357 /* is this thread privileged? */
358 arm->core_mode = control & 1
359 ? ARM_MODE_USER_THREAD
360 : ARM_MODE_THREAD;
361
362 /* which stack is it using? */
363 if (control & 2)
364 arm->map = armv7m_psp_reg_map;
365 else
366 arm->map = armv7m_msp_reg_map;
367
368 armv7m->exception_number = 0;
369 }
370
371 LOG_DEBUG("entered debug state in core mode: %s at PC 0x%08" PRIx32 ", target->state: %s",
372 arm_mode_name(arm->core_mode),
373 *(uint32_t *)(arm->pc->value),
374 target_state_name(target));
375
376 return retval;
377 }
378
379 static int adapter_poll(struct target *target)
380 {
381 enum target_state state;
382 struct hl_interface_s *adapter = target_to_adapter(target);
383 struct armv7m_common *armv7m = target_to_armv7m(target);
384
385 state = adapter->layout->api->state(adapter->fd);
386
387 if (state == TARGET_UNKNOWN) {
388 LOG_ERROR("jtag status contains invalid mode value - communication failure");
389 return ERROR_TARGET_FAILURE;
390 }
391
392 if (target->state == state)
393 return ERROR_OK;
394
395 if (state == TARGET_HALTED) {
396 target->state = state;
397
398 int retval = adapter_debug_entry(target);
399 if (retval != ERROR_OK)
400 return retval;
401
402 if (arm_semihosting(target, &retval) != 0)
403 return retval;
404
405 target_call_event_callbacks(target, TARGET_EVENT_HALTED);
406 LOG_DEBUG("halted: PC: 0x%08x", buf_get_u32(armv7m->arm.pc->value, 0, 32));
407 }
408
409 return ERROR_OK;
410 }
411
412 static int adapter_assert_reset(struct target *target)
413 {
414 int res = ERROR_OK;
415 struct hl_interface_s *adapter = target_to_adapter(target);
416 struct armv7m_common *armv7m = target_to_armv7m(target);
417 bool use_srst_fallback = true;
418
419 LOG_DEBUG("%s", __func__);
420
421 enum reset_types jtag_reset_config = jtag_get_reset_config();
422
423 bool srst_asserted = false;
424
425 if (jtag_reset_config & RESET_SRST_NO_GATING) {
426 jtag_add_reset(0, 1);
427 res = adapter->layout->api->assert_srst(adapter->fd, 0);
428 srst_asserted = true;
429 }
430
431 adapter->layout->api->write_debug_reg(adapter->fd, DCB_DHCSR, DBGKEY|C_DEBUGEN);
432
433 /* only set vector catch if halt is requested */
434 if (target->reset_halt)
435 adapter->layout->api->write_debug_reg(adapter->fd, DCB_DEMCR, TRCENA|VC_CORERESET);
436 else
437 adapter->layout->api->write_debug_reg(adapter->fd, DCB_DEMCR, TRCENA);
438
439 if (jtag_reset_config & RESET_HAS_SRST) {
440 if (!srst_asserted) {
441 jtag_add_reset(0, 1);
442 res = adapter->layout->api->assert_srst(adapter->fd, 0);
443 }
444 if (res == ERROR_COMMAND_NOTFOUND)
445 LOG_ERROR("Hardware srst not supported, falling back to software reset");
446 else if (res == ERROR_OK) {
447 /* hardware srst supported */
448 use_srst_fallback = false;
449 }
450 }
451
452 if (use_srst_fallback) {
453 /* stlink v1 api does not support hardware srst, so we use a software reset fallback */
454 adapter->layout->api->write_debug_reg(adapter->fd, NVIC_AIRCR, AIRCR_VECTKEY | AIRCR_SYSRESETREQ);
455 }
456
457 res = adapter->layout->api->reset(adapter->fd);
458
459 if (res != ERROR_OK)
460 return res;
461
462 /* registers are now invalid */
463 register_cache_invalidate(armv7m->arm.core_cache);
464
465 if (target->reset_halt) {
466 target->state = TARGET_RESET;
467 target->debug_reason = DBG_REASON_DBGRQ;
468 } else {
469 target->state = TARGET_HALTED;
470 }
471
472 return ERROR_OK;
473 }
474
475 static int adapter_deassert_reset(struct target *target)
476 {
477 int res;
478 struct hl_interface_s *adapter = target_to_adapter(target);
479
480 enum reset_types jtag_reset_config = jtag_get_reset_config();
481
482 LOG_DEBUG("%s", __func__);
483
484 if (jtag_reset_config & RESET_HAS_SRST)
485 adapter->layout->api->assert_srst(adapter->fd, 1);
486
487 /* virtual deassert reset, we need it for the internal
488 * jtag state machine
489 */
490 jtag_add_reset(0, 0);
491
492 if (!target->reset_halt) {
493 res = target_resume(target, 1, 0, 0, 0);
494
495 if (res != ERROR_OK)
496 return res;
497 }
498
499 return ERROR_OK;
500 }
501
502 static int adapter_soft_reset_halt(struct target *target)
503 {
504 LOG_DEBUG("%s", __func__);
505 return ERROR_OK;
506 }
507
508 static int adapter_halt(struct target *target)
509 {
510 int res;
511 struct hl_interface_s *adapter = target_to_adapter(target);
512
513 LOG_DEBUG("%s", __func__);
514
515 if (target->state == TARGET_HALTED) {
516 LOG_DEBUG("target was already halted");
517 return ERROR_OK;
518 }
519
520 if (target->state == TARGET_UNKNOWN)
521 LOG_WARNING("target was in unknown state when halt was requested");
522
523 res = adapter->layout->api->halt(adapter->fd);
524
525 if (res != ERROR_OK)
526 return res;
527
528 target->debug_reason = DBG_REASON_DBGRQ;
529
530 return ERROR_OK;
531 }
532
533 static int adapter_resume(struct target *target, int current,
534 uint32_t address, int handle_breakpoints,
535 int debug_execution)
536 {
537 int res;
538 struct hl_interface_s *adapter = target_to_adapter(target);
539 struct armv7m_common *armv7m = target_to_armv7m(target);
540 uint32_t resume_pc;
541 struct breakpoint *breakpoint = NULL;
542 struct reg *pc;
543
544 LOG_DEBUG("%s %d 0x%08x %d %d", __func__, current, address,
545 handle_breakpoints, debug_execution);
546
547 if (target->state != TARGET_HALTED) {
548 LOG_WARNING("target not halted");
549 return ERROR_TARGET_NOT_HALTED;
550 }
551
552 if (!debug_execution) {
553 target_free_all_working_areas(target);
554 cortex_m3_enable_breakpoints(target);
555 cortex_m3_enable_watchpoints(target);
556 }
557
558 pc = armv7m->arm.pc;
559 if (!current) {
560 buf_set_u32(pc->value, 0, 32, address);
561 pc->dirty = true;
562 pc->valid = true;
563 }
564
565 if (!breakpoint_find(target, buf_get_u32(pc->value, 0, 32))
566 && !debug_execution) {
567 armv7m_maybe_skip_bkpt_inst(target, NULL);
568 }
569
570 resume_pc = buf_get_u32(pc->value, 0, 32);
571
572 /* write any user vector flags */
573 res = target_write_u32(target, DCB_DEMCR, TRCENA | armv7m->demcr);
574 if (res != ERROR_OK)
575 return res;
576
577 armv7m_restore_context(target);
578
579 /* registers are now invalid */
580 register_cache_invalidate(armv7m->arm.core_cache);
581
582 /* the front-end may request us not to handle breakpoints */
583 if (handle_breakpoints) {
584 /* Single step past breakpoint at current address */
585 breakpoint = breakpoint_find(target, resume_pc);
586 if (breakpoint) {
587 LOG_DEBUG("unset breakpoint at 0x%8.8" PRIx32 " (ID: %d)",
588 breakpoint->address,
589 breakpoint->unique_id);
590 cortex_m3_unset_breakpoint(target, breakpoint);
591
592 res = adapter->layout->api->step(adapter->fd);
593
594 if (res != ERROR_OK)
595 return res;
596
597 cortex_m3_set_breakpoint(target, breakpoint);
598 }
599 }
600
601 res = adapter->layout->api->run(adapter->fd);
602
603 if (res != ERROR_OK)
604 return res;
605
606 target->state = TARGET_RUNNING;
607 target->debug_reason = DBG_REASON_NOTHALTED;
608
609 target_call_event_callbacks(target, TARGET_EVENT_RESUMED);
610
611 return ERROR_OK;
612 }
613
614 static int adapter_step(struct target *target, int current,
615 uint32_t address, int handle_breakpoints)
616 {
617 int res;
618 struct hl_interface_s *adapter = target_to_adapter(target);
619 struct armv7m_common *armv7m = target_to_armv7m(target);
620 struct breakpoint *breakpoint = NULL;
621 struct reg *pc = armv7m->arm.pc;
622 bool bkpt_inst_found = false;
623
624 LOG_DEBUG("%s", __func__);
625
626 if (target->state != TARGET_HALTED) {
627 LOG_WARNING("target not halted");
628 return ERROR_TARGET_NOT_HALTED;
629 }
630
631 if (!current) {
632 buf_set_u32(pc->value, 0, 32, address);
633 pc->dirty = true;
634 pc->valid = true;
635 }
636
637 uint32_t pc_value = buf_get_u32(pc->value, 0, 32);
638
639 /* the front-end may request us not to handle breakpoints */
640 if (handle_breakpoints) {
641 breakpoint = breakpoint_find(target, pc_value);
642 if (breakpoint)
643 cortex_m3_unset_breakpoint(target, breakpoint);
644 }
645
646 armv7m_maybe_skip_bkpt_inst(target, &bkpt_inst_found);
647
648 target->debug_reason = DBG_REASON_SINGLESTEP;
649
650 armv7m_restore_context(target);
651
652 target_call_event_callbacks(target, TARGET_EVENT_RESUMED);
653
654 res = adapter->layout->api->step(adapter->fd);
655
656 if (res != ERROR_OK)
657 return res;
658
659 /* registers are now invalid */
660 register_cache_invalidate(armv7m->arm.core_cache);
661
662 if (breakpoint)
663 cortex_m3_set_breakpoint(target, breakpoint);
664
665 adapter_debug_entry(target);
666 target_call_event_callbacks(target, TARGET_EVENT_HALTED);
667
668 LOG_INFO("halted: PC: 0x%08x", buf_get_u32(armv7m->arm.pc->value, 0, 32));
669
670 return ERROR_OK;
671 }
672
673 static int adapter_read_memory(struct target *target, uint32_t address,
674 uint32_t size, uint32_t count,
675 uint8_t *buffer)
676 {
677 struct hl_interface_s *adapter = target_to_adapter(target);
678 int res;
679 uint32_t buffer_threshold = (adapter->param.max_buffer / 4);
680 uint32_t addr_increment = 4;
681 uint32_t c;
682
683 if (!count || !buffer)
684 return ERROR_COMMAND_SYNTAX_ERROR;
685
686 LOG_DEBUG("%s 0x%08x %d %d", __func__, address, size, count);
687
688 /* prepare byte count, buffer threshold
689 * and address increment for none 32bit access
690 */
691 if (size != 4) {
692 count *= size;
693 buffer_threshold = (adapter->param.max_buffer / 4) / 2;
694 addr_increment = 1;
695 }
696
697 while (count) {
698 if (count > buffer_threshold)
699 c = buffer_threshold;
700 else
701 c = count;
702
703 if (size != 4)
704 res = adapter->layout->api->read_mem8(adapter->fd,
705 address, c, buffer);
706 else
707 res = adapter->layout->api->read_mem32(adapter->fd,
708 address, c, buffer);
709
710 if (res != ERROR_OK)
711 return res;
712
713 address += (c * addr_increment);
714 buffer += (c * addr_increment);
715 count -= c;
716 }
717
718 return ERROR_OK;
719 }
720
721 static int adapter_write_memory(struct target *target, uint32_t address,
722 uint32_t size, uint32_t count,
723 const uint8_t *buffer)
724 {
725 struct hl_interface_s *adapter = target_to_adapter(target);
726 int res;
727 uint32_t buffer_threshold = (adapter->param.max_buffer / 4);
728 uint32_t addr_increment = 4;
729 uint32_t c;
730
731 if (!count || !buffer)
732 return ERROR_COMMAND_SYNTAX_ERROR;
733
734 LOG_DEBUG("%s 0x%08x %d %d", __func__, address, size, count);
735
736 /* prepare byte count, buffer threshold
737 * and address increment for none 32bit access
738 */
739 if (size != 4) {
740 count *= size;
741 buffer_threshold = (adapter->param.max_buffer / 4) / 2;
742 addr_increment = 1;
743 }
744
745 while (count) {
746 if (count > buffer_threshold)
747 c = buffer_threshold;
748 else
749 c = count;
750
751 if (size != 4)
752 res = adapter->layout->api->write_mem8(adapter->fd,
753 address, c, buffer);
754 else
755 res = adapter->layout->api->write_mem32(adapter->fd,
756 address, c, buffer);
757
758 if (res != ERROR_OK)
759 return res;
760
761 address += (c * addr_increment);
762 buffer += (c * addr_increment);
763 count -= c;
764 }
765
766 return ERROR_OK;
767 }
768
769 static int adapter_bulk_write_memory(struct target *target,
770 uint32_t address, uint32_t count,
771 const uint8_t *buffer)
772 {
773 return adapter_write_memory(target, address, 4, count, buffer);
774 }
775
776 static const struct command_registration adapter_command_handlers[] = {
777 {
778 .chain = arm_command_handlers,
779 },
780 COMMAND_REGISTRATION_DONE
781 };
782
783 struct target_type hla_target = {
784 .name = "hla_target",
785 .deprecated_name = "stm32_stlink",
786
787 .init_target = adapter_init_target,
788 .target_create = adapter_target_create,
789 .examine = cortex_m3_examine,
790 .commands = adapter_command_handlers,
791
792 .poll = adapter_poll,
793 .arch_state = armv7m_arch_state,
794
795 .assert_reset = adapter_assert_reset,
796 .deassert_reset = adapter_deassert_reset,
797 .soft_reset_halt = adapter_soft_reset_halt,
798
799 .halt = adapter_halt,
800 .resume = adapter_resume,
801 .step = adapter_step,
802
803 .get_gdb_reg_list = armv7m_get_gdb_reg_list,
804
805 .read_memory = adapter_read_memory,
806 .write_memory = adapter_write_memory,
807 .bulk_write_memory = adapter_bulk_write_memory,
808 .checksum_memory = armv7m_checksum_memory,
809 .blank_check_memory = armv7m_blank_check_memory,
810
811 .run_algorithm = armv7m_run_algorithm,
812 .start_algorithm = armv7m_start_algorithm,
813 .wait_algorithm = armv7m_wait_algorithm,
814
815 .add_breakpoint = cortex_m3_add_breakpoint,
816 .remove_breakpoint = cortex_m3_remove_breakpoint,
817 .add_watchpoint = cortex_m3_add_watchpoint,
818 .remove_watchpoint = cortex_m3_remove_watchpoint,
819 };

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)