73b7ca3d0e8a005a4be1a28607f0cea5f3c38c7d
[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->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->core_cache->num_regs;
315
316 for (int i = 0; i < num_regs; i++) {
317 if (!armv7m->core_cache->reg_list[i].valid)
318 armv7m->read_core_reg(target, i);
319 }
320
321 return ERROR_OK;
322 }
323
324 static int adapter_debug_entry(struct target *target)
325 {
326 struct hl_interface_s *adapter = target_to_adapter(target);
327 struct armv7m_common *armv7m = target_to_armv7m(target);
328 struct arm *arm = &armv7m->arm;
329 struct reg *r;
330 uint32_t xPSR;
331 int retval;
332
333 retval = armv7m->examine_debug_reason(target);
334 if (retval != ERROR_OK)
335 return retval;
336
337 adapter_load_context(target);
338
339 /* make sure we clear the vector catch bit */
340 adapter->layout->api->write_debug_reg(adapter->fd, DCB_DEMCR, TRCENA);
341
342 r = armv7m->core_cache->reg_list + ARMV7M_xPSR;
343 xPSR = buf_get_u32(r->value, 0, 32);
344
345 /* Are we in an exception handler */
346 if (xPSR & 0x1FF) {
347 armv7m->exception_number = (xPSR & 0x1FF);
348
349 arm->core_mode = ARM_MODE_HANDLER;
350 arm->map = armv7m_msp_reg_map;
351 } else {
352 unsigned control = buf_get_u32(arm->core_cache
353 ->reg_list[ARMV7M_CONTROL].value, 0, 2);
354
355 /* is this thread privileged? */
356 arm->core_mode = control & 1
357 ? ARM_MODE_USER_THREAD
358 : ARM_MODE_THREAD;
359
360 /* which stack is it using? */
361 if (control & 2)
362 arm->map = armv7m_psp_reg_map;
363 else
364 arm->map = armv7m_msp_reg_map;
365
366 armv7m->exception_number = 0;
367 }
368
369 LOG_DEBUG("entered debug state in core mode: %s at PC 0x%08" PRIx32 ", target->state: %s",
370 arm_mode_name(arm->core_mode),
371 *(uint32_t *)(arm->pc->value),
372 target_state_name(target));
373
374 return retval;
375 }
376
377 static int adapter_poll(struct target *target)
378 {
379 enum target_state state;
380 struct hl_interface_s *adapter = target_to_adapter(target);
381 struct armv7m_common *armv7m = target_to_armv7m(target);
382
383 state = adapter->layout->api->state(adapter->fd);
384
385 if (state == TARGET_UNKNOWN) {
386 LOG_ERROR("jtag status contains invalid mode value - communication failure");
387 return ERROR_TARGET_FAILURE;
388 }
389
390 if (target->state == state)
391 return ERROR_OK;
392
393 if (state == TARGET_HALTED) {
394 target->state = state;
395
396 int retval = adapter_debug_entry(target);
397 if (retval != ERROR_OK)
398 return retval;
399
400 if (arm_semihosting(target, &retval) != 0)
401 return retval;
402
403 target_call_event_callbacks(target, TARGET_EVENT_HALTED);
404 LOG_DEBUG("halted: PC: 0x%08x", buf_get_u32(armv7m->arm.pc->value, 0, 32));
405 }
406
407 return ERROR_OK;
408 }
409
410 static int adapter_assert_reset(struct target *target)
411 {
412 int res = ERROR_OK;
413 struct hl_interface_s *adapter = target_to_adapter(target);
414 struct armv7m_common *armv7m = target_to_armv7m(target);
415 bool use_srst_fallback = true;
416
417 LOG_DEBUG("%s", __func__);
418
419 enum reset_types jtag_reset_config = jtag_get_reset_config();
420
421 bool srst_asserted = false;
422
423 if (jtag_reset_config & RESET_SRST_NO_GATING) {
424 jtag_add_reset(0, 1);
425 res = adapter->layout->api->assert_srst(adapter->fd, 0);
426 srst_asserted = true;
427 }
428
429 adapter->layout->api->write_debug_reg(adapter->fd, DCB_DHCSR, DBGKEY|C_DEBUGEN);
430
431 /* only set vector catch if halt is requested */
432 if (target->reset_halt)
433 adapter->layout->api->write_debug_reg(adapter->fd, DCB_DEMCR, TRCENA|VC_CORERESET);
434 else
435 adapter->layout->api->write_debug_reg(adapter->fd, DCB_DEMCR, TRCENA);
436
437 if (jtag_reset_config & RESET_HAS_SRST) {
438 if (!srst_asserted) {
439 jtag_add_reset(0, 1);
440 res = adapter->layout->api->assert_srst(adapter->fd, 0);
441 }
442 if (res == ERROR_COMMAND_NOTFOUND)
443 LOG_ERROR("Hardware srst not supported, falling back to software reset");
444 else if (res == ERROR_OK) {
445 /* hardware srst supported */
446 use_srst_fallback = false;
447 }
448 }
449
450 if (use_srst_fallback) {
451 /* stlink v1 api does not support hardware srst, so we use a software reset fallback */
452 adapter->layout->api->write_debug_reg(adapter->fd, NVIC_AIRCR, AIRCR_VECTKEY | AIRCR_SYSRESETREQ);
453 }
454
455 res = adapter->layout->api->reset(adapter->fd);
456
457 if (res != ERROR_OK)
458 return res;
459
460 /* registers are now invalid */
461 register_cache_invalidate(armv7m->core_cache);
462
463 if (target->reset_halt) {
464 target->state = TARGET_RESET;
465 target->debug_reason = DBG_REASON_DBGRQ;
466 } else {
467 target->state = TARGET_HALTED;
468 }
469
470 return ERROR_OK;
471 }
472
473 static int adapter_deassert_reset(struct target *target)
474 {
475 int res;
476 struct hl_interface_s *adapter = target_to_adapter(target);
477
478 enum reset_types jtag_reset_config = jtag_get_reset_config();
479
480 LOG_DEBUG("%s", __func__);
481
482 if (jtag_reset_config & RESET_HAS_SRST)
483 adapter->layout->api->assert_srst(adapter->fd, 1);
484
485 /* virtual deassert reset, we need it for the internal
486 * jtag state machine
487 */
488 jtag_add_reset(0, 0);
489
490 if (!target->reset_halt) {
491 res = target_resume(target, 1, 0, 0, 0);
492
493 if (res != ERROR_OK)
494 return res;
495 }
496
497 return ERROR_OK;
498 }
499
500 static int adapter_soft_reset_halt(struct target *target)
501 {
502 LOG_DEBUG("%s", __func__);
503 return ERROR_OK;
504 }
505
506 static int adapter_halt(struct target *target)
507 {
508 int res;
509 struct hl_interface_s *adapter = target_to_adapter(target);
510
511 LOG_DEBUG("%s", __func__);
512
513 if (target->state == TARGET_HALTED) {
514 LOG_DEBUG("target was already halted");
515 return ERROR_OK;
516 }
517
518 if (target->state == TARGET_UNKNOWN)
519 LOG_WARNING("target was in unknown state when halt was requested");
520
521 res = adapter->layout->api->halt(adapter->fd);
522
523 if (res != ERROR_OK)
524 return res;
525
526 target->debug_reason = DBG_REASON_DBGRQ;
527
528 return ERROR_OK;
529 }
530
531 static int adapter_resume(struct target *target, int current,
532 uint32_t address, int handle_breakpoints,
533 int debug_execution)
534 {
535 int res;
536 struct hl_interface_s *adapter = target_to_adapter(target);
537 struct armv7m_common *armv7m = target_to_armv7m(target);
538 uint32_t resume_pc;
539 struct breakpoint *breakpoint = NULL;
540 struct reg *pc;
541
542 LOG_DEBUG("%s %d 0x%08x %d %d", __func__, current, address,
543 handle_breakpoints, debug_execution);
544
545 if (target->state != TARGET_HALTED) {
546 LOG_WARNING("target not halted");
547 return ERROR_TARGET_NOT_HALTED;
548 }
549
550 if (!debug_execution) {
551 target_free_all_working_areas(target);
552 cortex_m3_enable_breakpoints(target);
553 cortex_m3_enable_watchpoints(target);
554 }
555
556 pc = armv7m->arm.pc;
557 if (!current) {
558 buf_set_u32(pc->value, 0, 32, address);
559 pc->dirty = true;
560 pc->valid = true;
561 }
562
563 if (!breakpoint_find(target, buf_get_u32(pc->value, 0, 32))
564 && !debug_execution) {
565 armv7m_maybe_skip_bkpt_inst(target, NULL);
566 }
567
568 resume_pc = buf_get_u32(pc->value, 0, 32);
569
570 /* write any user vector flags */
571 res = target_write_u32(target, DCB_DEMCR, TRCENA | armv7m->demcr);
572 if (res != ERROR_OK)
573 return res;
574
575 armv7m_restore_context(target);
576
577 /* registers are now invalid */
578 register_cache_invalidate(armv7m->core_cache);
579
580 /* the front-end may request us not to handle breakpoints */
581 if (handle_breakpoints) {
582 /* Single step past breakpoint at current address */
583 breakpoint = breakpoint_find(target, resume_pc);
584 if (breakpoint) {
585 LOG_DEBUG("unset breakpoint at 0x%8.8" PRIx32 " (ID: %d)",
586 breakpoint->address,
587 breakpoint->unique_id);
588 cortex_m3_unset_breakpoint(target, breakpoint);
589
590 res = adapter->layout->api->step(adapter->fd);
591
592 if (res != ERROR_OK)
593 return res;
594
595 cortex_m3_set_breakpoint(target, breakpoint);
596 }
597 }
598
599 res = adapter->layout->api->run(adapter->fd);
600
601 if (res != ERROR_OK)
602 return res;
603
604 target->state = TARGET_RUNNING;
605 target->debug_reason = DBG_REASON_NOTHALTED;
606
607 target_call_event_callbacks(target, TARGET_EVENT_RESUMED);
608
609 return ERROR_OK;
610 }
611
612 static int adapter_step(struct target *target, int current,
613 uint32_t address, int handle_breakpoints)
614 {
615 int res;
616 struct hl_interface_s *adapter = target_to_adapter(target);
617 struct armv7m_common *armv7m = target_to_armv7m(target);
618 struct breakpoint *breakpoint = NULL;
619 struct reg *pc = armv7m->arm.pc;
620 bool bkpt_inst_found = false;
621
622 LOG_DEBUG("%s", __func__);
623
624 if (target->state != TARGET_HALTED) {
625 LOG_WARNING("target not halted");
626 return ERROR_TARGET_NOT_HALTED;
627 }
628
629 if (!current) {
630 buf_set_u32(pc->value, 0, 32, address);
631 pc->dirty = true;
632 pc->valid = true;
633 }
634
635 uint32_t pc_value = buf_get_u32(pc->value, 0, 32);
636
637 /* the front-end may request us not to handle breakpoints */
638 if (handle_breakpoints) {
639 breakpoint = breakpoint_find(target, pc_value);
640 if (breakpoint)
641 cortex_m3_unset_breakpoint(target, breakpoint);
642 }
643
644 armv7m_maybe_skip_bkpt_inst(target, &bkpt_inst_found);
645
646 target->debug_reason = DBG_REASON_SINGLESTEP;
647
648 armv7m_restore_context(target);
649
650 target_call_event_callbacks(target, TARGET_EVENT_RESUMED);
651
652 res = adapter->layout->api->step(adapter->fd);
653
654 if (res != ERROR_OK)
655 return res;
656
657 /* registers are now invalid */
658 register_cache_invalidate(armv7m->core_cache);
659
660 if (breakpoint)
661 cortex_m3_set_breakpoint(target, breakpoint);
662
663 adapter_debug_entry(target);
664 target_call_event_callbacks(target, TARGET_EVENT_HALTED);
665
666 LOG_INFO("halted: PC: 0x%08x", buf_get_u32(armv7m->arm.pc->value, 0, 32));
667
668 return ERROR_OK;
669 }
670
671 static int adapter_read_memory(struct target *target, uint32_t address,
672 uint32_t size, uint32_t count,
673 uint8_t *buffer)
674 {
675 struct hl_interface_s *adapter = target_to_adapter(target);
676 int res;
677 uint32_t buffer_threshold = (adapter->param.max_buffer / 4);
678 uint32_t addr_increment = 4;
679 uint32_t c;
680
681 if (!count || !buffer)
682 return ERROR_COMMAND_SYNTAX_ERROR;
683
684 LOG_DEBUG("%s 0x%08x %d %d", __func__, address, size, count);
685
686 /* prepare byte count, buffer threshold
687 * and address increment for none 32bit access
688 */
689 if (size != 4) {
690 count *= size;
691 buffer_threshold = (adapter->param.max_buffer / 4) / 2;
692 addr_increment = 1;
693 }
694
695 while (count) {
696 if (count > buffer_threshold)
697 c = buffer_threshold;
698 else
699 c = count;
700
701 if (size != 4)
702 res = adapter->layout->api->read_mem8(adapter->fd,
703 address, c, buffer);
704 else
705 res = adapter->layout->api->read_mem32(adapter->fd,
706 address, c, buffer);
707
708 if (res != ERROR_OK)
709 return res;
710
711 address += (c * addr_increment);
712 buffer += (c * addr_increment);
713 count -= c;
714 }
715
716 return ERROR_OK;
717 }
718
719 static int adapter_write_memory(struct target *target, uint32_t address,
720 uint32_t size, uint32_t count,
721 const uint8_t *buffer)
722 {
723 struct hl_interface_s *adapter = target_to_adapter(target);
724 int res;
725 uint32_t buffer_threshold = (adapter->param.max_buffer / 4);
726 uint32_t addr_increment = 4;
727 uint32_t c;
728
729 if (!count || !buffer)
730 return ERROR_COMMAND_SYNTAX_ERROR;
731
732 LOG_DEBUG("%s 0x%08x %d %d", __func__, address, size, count);
733
734 /* prepare byte count, buffer threshold
735 * and address increment for none 32bit access
736 */
737 if (size != 4) {
738 count *= size;
739 buffer_threshold = (adapter->param.max_buffer / 4) / 2;
740 addr_increment = 1;
741 }
742
743 while (count) {
744 if (count > buffer_threshold)
745 c = buffer_threshold;
746 else
747 c = count;
748
749 if (size != 4)
750 res = adapter->layout->api->write_mem8(adapter->fd,
751 address, c, buffer);
752 else
753 res = adapter->layout->api->write_mem32(adapter->fd,
754 address, c, buffer);
755
756 if (res != ERROR_OK)
757 return res;
758
759 address += (c * addr_increment);
760 buffer += (c * addr_increment);
761 count -= c;
762 }
763
764 return ERROR_OK;
765 }
766
767 static int adapter_bulk_write_memory(struct target *target,
768 uint32_t address, uint32_t count,
769 const uint8_t *buffer)
770 {
771 return adapter_write_memory(target, address, 4, count, buffer);
772 }
773
774 static const struct command_registration adapter_command_handlers[] = {
775 {
776 .chain = arm_command_handlers,
777 },
778 COMMAND_REGISTRATION_DONE
779 };
780
781 struct target_type hla_target = {
782 .name = "hla_target",
783 .deprecated_name = "stm32_stlink",
784
785 .init_target = adapter_init_target,
786 .target_create = adapter_target_create,
787 .examine = cortex_m3_examine,
788 .commands = adapter_command_handlers,
789
790 .poll = adapter_poll,
791 .arch_state = armv7m_arch_state,
792
793 .assert_reset = adapter_assert_reset,
794 .deassert_reset = adapter_deassert_reset,
795 .soft_reset_halt = adapter_soft_reset_halt,
796
797 .halt = adapter_halt,
798 .resume = adapter_resume,
799 .step = adapter_step,
800
801 .get_gdb_reg_list = armv7m_get_gdb_reg_list,
802
803 .read_memory = adapter_read_memory,
804 .write_memory = adapter_write_memory,
805 .bulk_write_memory = adapter_bulk_write_memory,
806 .checksum_memory = armv7m_checksum_memory,
807 .blank_check_memory = armv7m_blank_check_memory,
808
809 .run_algorithm = armv7m_run_algorithm,
810 .start_algorithm = armv7m_start_algorithm,
811 .wait_algorithm = armv7m_wait_algorithm,
812
813 .add_breakpoint = cortex_m3_add_breakpoint,
814 .remove_breakpoint = cortex_m3_remove_breakpoint,
815 .add_watchpoint = cortex_m3_add_watchpoint,
816 .remove_watchpoint = cortex_m3_remove_watchpoint,
817 };

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)