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

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)