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

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)