1 /***************************************************************************
2 * Copyright (C) 2011 by Mathias Kuester *
3 * Mathias Kuester <kesmtp@freenet.de> *
5 * Copyright (C) 2011 by Spencer Oliver *
6 * spen@spen-soft.co.uk *
8 * revised: 4/25/13 by brent@mbari.org [DCC target request support] *
10 * This program is free software; you can redistribute it and/or modify *
11 * it under the terms of the GNU General Public License as published by *
12 * the Free Software Foundation; either version 2 of the License, or *
13 * (at your option) any later version. *
15 * This program is distributed in the hope that it will be useful, *
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
18 * GNU General Public License for more details. *
20 * You should have received a copy of the GNU General Public License *
21 * along with this program. If not, see <http://www.gnu.org/licenses/>. *
22 ***************************************************************************/
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"
33 #include "algorithm.h"
35 #include "breakpoints.h"
36 #include "target_type.h"
39 #include "arm_semihosting.h"
40 #include "target_request.h"
42 #define savedDCRDR dbgbase /* FIXME: using target->dbgbase to preserve DCRDR */
44 #define ARMV7M_SCS_DCRSR DCB_DCRSR
45 #define ARMV7M_SCS_DCRDR DCB_DCRDR
47 static inline struct hl_interface_s
*target_to_adapter(struct target
*target
)
49 return target
->tap
->priv
;
52 static int adapter_load_core_reg_u32(struct target
*target
,
53 uint32_t num
, uint32_t *value
)
56 struct hl_interface_s
*adapter
= target_to_adapter(target
);
58 LOG_DEBUG("%s", __func__
);
60 /* NOTE: we "know" here that the register identifiers used
61 * in the v7m header match the Cortex-M3 Debug Core Register
62 * Selector values for R0..R15, xPSR, MSP, and PSP.
66 /* read a normal core register */
67 retval
= adapter
->layout
->api
->read_reg(adapter
->handle
, num
, value
);
69 if (retval
!= ERROR_OK
) {
70 LOG_ERROR("JTAG failure %i", retval
);
71 return ERROR_JTAG_DEVICE_ERROR
;
73 LOG_DEBUG("load from core reg %i value 0x%" PRIx32
"", (int)num
, *value
);
77 /* Floating-point Status and Registers */
78 retval
= target_write_u32(target
, ARMV7M_SCS_DCRSR
, 33);
79 if (retval
!= ERROR_OK
)
81 retval
= target_read_u32(target
, ARMV7M_SCS_DCRDR
, value
);
82 if (retval
!= ERROR_OK
)
84 LOG_DEBUG("load from FPSCR value 0x%" PRIx32
, *value
);
87 case ARMV7M_S0
... ARMV7M_S31
:
88 /* Floating-point Status and Registers */
89 retval
= target_write_u32(target
, ARMV7M_SCS_DCRSR
, num
-ARMV7M_S0
+64);
90 if (retval
!= ERROR_OK
)
92 retval
= target_read_u32(target
, ARMV7M_SCS_DCRDR
, value
);
93 if (retval
!= ERROR_OK
)
95 LOG_DEBUG("load from FPU reg S%d value 0x%" PRIx32
,
96 (int)(num
- ARMV7M_S0
), *value
);
101 case ARMV7M_FAULTMASK
:
103 /* Cortex-M3 packages these four registers as bitfields
104 * in one Debug Core register. So say r0 and r2 docs;
105 * it was removed from r1 docs, but still works.
107 retval
= adapter
->layout
->api
->read_reg(adapter
->handle
, 20, value
);
108 if (retval
!= ERROR_OK
)
113 *value
= buf_get_u32((uint8_t *) value
, 0, 1);
117 *value
= buf_get_u32((uint8_t *) value
, 8, 8);
120 case ARMV7M_FAULTMASK
:
121 *value
= buf_get_u32((uint8_t *) value
, 16, 1);
125 *value
= buf_get_u32((uint8_t *) value
, 24, 2);
129 LOG_DEBUG("load from special reg %i value 0x%" PRIx32
"",
134 return ERROR_COMMAND_SYNTAX_ERROR
;
140 static int adapter_store_core_reg_u32(struct target
*target
,
141 uint32_t num
, uint32_t value
)
145 struct armv7m_common
*armv7m
= target_to_armv7m(target
);
146 struct hl_interface_s
*adapter
= target_to_adapter(target
);
148 LOG_DEBUG("%s", __func__
);
150 /* NOTE: we "know" here that the register identifiers used
151 * in the v7m header match the Cortex-M3 Debug Core Register
152 * Selector values for R0..R15, xPSR, MSP, and PSP.
156 retval
= adapter
->layout
->api
->write_reg(adapter
->handle
, num
, value
);
158 if (retval
!= ERROR_OK
) {
161 LOG_ERROR("JTAG failure");
162 r
= armv7m
->arm
.core_cache
->reg_list
+ num
;
164 return ERROR_JTAG_DEVICE_ERROR
;
166 LOG_DEBUG("write core reg %i value 0x%" PRIx32
"", (int)num
, value
);
170 /* Floating-point Status and Registers */
171 retval
= target_write_u32(target
, ARMV7M_SCS_DCRDR
, value
);
172 if (retval
!= ERROR_OK
)
174 retval
= target_write_u32(target
, ARMV7M_SCS_DCRSR
, 33 | (1<<16));
175 if (retval
!= ERROR_OK
)
177 LOG_DEBUG("write FPSCR value 0x%" PRIx32
, value
);
180 case ARMV7M_S0
... ARMV7M_S31
:
181 /* Floating-point Status and Registers */
182 retval
= target_write_u32(target
, ARMV7M_SCS_DCRDR
, value
);
183 if (retval
!= ERROR_OK
)
185 retval
= target_write_u32(target
, ARMV7M_SCS_DCRSR
, (num
-ARMV7M_S0
+64) | (1<<16));
186 if (retval
!= ERROR_OK
)
188 LOG_DEBUG("write FPU reg S%d value 0x%" PRIx32
,
189 (int)(num
- ARMV7M_S0
), value
);
194 case ARMV7M_FAULTMASK
:
196 /* Cortex-M3 packages these four registers as bitfields
197 * in one Debug Core register. So say r0 and r2 docs;
198 * it was removed from r1 docs, but still works.
201 adapter
->layout
->api
->read_reg(adapter
->handle
, 20, ®
);
205 buf_set_u32((uint8_t *) ®
, 0, 1, value
);
209 buf_set_u32((uint8_t *) ®
, 8, 8, value
);
212 case ARMV7M_FAULTMASK
:
213 buf_set_u32((uint8_t *) ®
, 16, 1, value
);
217 buf_set_u32((uint8_t *) ®
, 24, 2, value
);
221 adapter
->layout
->api
->write_reg(adapter
->handle
, 20, reg
);
223 LOG_DEBUG("write special reg %i value 0x%" PRIx32
" ", (int)num
, value
);
227 return ERROR_COMMAND_SYNTAX_ERROR
;
233 static int adapter_examine_debug_reason(struct target
*target
)
235 if ((target
->debug_reason
!= DBG_REASON_DBGRQ
)
236 && (target
->debug_reason
!= DBG_REASON_SINGLESTEP
)) {
237 target
->debug_reason
= DBG_REASON_BREAKPOINT
;
243 static int hl_dcc_read(struct hl_interface_s
*hl_if
, uint8_t *value
, uint8_t *ctrl
)
246 int retval
= hl_if
->layout
->api
->read_mem(hl_if
->handle
,
247 DCB_DCRDR
, 1, sizeof(dcrdr
), (uint8_t *)&dcrdr
);
248 if (retval
== ERROR_OK
) {
249 *ctrl
= (uint8_t)dcrdr
;
250 *value
= (uint8_t)(dcrdr
>> 8);
252 LOG_DEBUG("data 0x%x ctrl 0x%x", *value
, *ctrl
);
255 /* write ack back to software dcc register
256 * to signify we have read data */
257 /* atomically clear just the byte containing the busy bit */
258 static const uint8_t zero
;
259 retval
= hl_if
->layout
->api
->write_mem(hl_if
->handle
, DCB_DCRDR
, 1, 1, &zero
);
265 static int hl_target_request_data(struct target
*target
,
266 uint32_t size
, uint8_t *buffer
)
268 struct hl_interface_s
*hl_if
= target_to_adapter(target
);
273 for (i
= 0; i
< (size
* 4); i
++) {
274 hl_dcc_read(hl_if
, &data
, &ctrl
);
281 static int hl_handle_target_request(void *priv
)
283 struct target
*target
= priv
;
284 if (!target_was_examined(target
))
286 struct hl_interface_s
*hl_if
= target_to_adapter(target
);
288 if (!target
->dbg_msg_enabled
)
291 if (target
->state
== TARGET_RUNNING
) {
295 hl_dcc_read(hl_if
, &data
, &ctrl
);
297 /* check if we have data */
298 if (ctrl
& (1 << 0)) {
301 /* we assume target is quick enough */
303 hl_dcc_read(hl_if
, &data
, &ctrl
);
304 request
|= (data
<< 8);
305 hl_dcc_read(hl_if
, &data
, &ctrl
);
306 request
|= (data
<< 16);
307 hl_dcc_read(hl_if
, &data
, &ctrl
);
308 request
|= (data
<< 24);
309 target_request(target
, request
);
316 static int adapter_init_arch_info(struct target
*target
,
317 struct cortex_m_common
*cortex_m
,
318 struct jtag_tap
*tap
)
320 struct armv7m_common
*armv7m
;
322 LOG_DEBUG("%s", __func__
);
324 armv7m
= &cortex_m
->armv7m
;
325 armv7m_init_arch_info(target
, armv7m
);
327 armv7m
->load_core_reg_u32
= adapter_load_core_reg_u32
;
328 armv7m
->store_core_reg_u32
= adapter_store_core_reg_u32
;
330 armv7m
->examine_debug_reason
= adapter_examine_debug_reason
;
331 armv7m
->stlink
= true;
333 target_register_timer_callback(hl_handle_target_request
, 1, 1, target
);
338 static int adapter_init_target(struct command_context
*cmd_ctx
,
339 struct target
*target
)
341 LOG_DEBUG("%s", __func__
);
343 armv7m_build_reg_cache(target
);
344 arm_semihosting_init(target
);
348 static int adapter_target_create(struct target
*target
,
351 LOG_DEBUG("%s", __func__
);
353 struct cortex_m_common
*cortex_m
= calloc(1, sizeof(struct cortex_m_common
));
356 return ERROR_COMMAND_SYNTAX_ERROR
;
358 adapter_init_arch_info(target
, cortex_m
, target
->tap
);
363 static int adapter_load_context(struct target
*target
)
365 struct armv7m_common
*armv7m
= target_to_armv7m(target
);
366 int num_regs
= armv7m
->arm
.core_cache
->num_regs
;
368 for (int i
= 0; i
< num_regs
; i
++) {
370 struct reg
*r
= &armv7m
->arm
.core_cache
->reg_list
[i
];
372 armv7m
->arm
.read_core_reg(target
, r
, i
, ARM_MODE_ANY
);
378 static int adapter_debug_entry(struct target
*target
)
380 struct hl_interface_s
*adapter
= target_to_adapter(target
);
381 struct armv7m_common
*armv7m
= target_to_armv7m(target
);
382 struct arm
*arm
= &armv7m
->arm
;
387 /* preserve the DCRDR across halts */
388 retval
= target_read_u32(target
, DCB_DCRDR
, &target
->savedDCRDR
);
389 if (retval
!= ERROR_OK
)
392 retval
= armv7m
->examine_debug_reason(target
);
393 if (retval
!= ERROR_OK
)
396 adapter_load_context(target
);
398 /* make sure we clear the vector catch bit */
399 adapter
->layout
->api
->write_debug_reg(adapter
->handle
, DCB_DEMCR
, TRCENA
);
402 xPSR
= buf_get_u32(r
->value
, 0, 32);
404 /* Are we in an exception handler */
406 armv7m
->exception_number
= (xPSR
& 0x1FF);
408 arm
->core_mode
= ARM_MODE_HANDLER
;
409 arm
->map
= armv7m_msp_reg_map
;
411 unsigned control
= buf_get_u32(arm
->core_cache
412 ->reg_list
[ARMV7M_CONTROL
].value
, 0, 2);
414 /* is this thread privileged? */
415 arm
->core_mode
= control
& 1
416 ? ARM_MODE_USER_THREAD
419 /* which stack is it using? */
421 arm
->map
= armv7m_psp_reg_map
;
423 arm
->map
= armv7m_msp_reg_map
;
425 armv7m
->exception_number
= 0;
428 LOG_DEBUG("entered debug state in core mode: %s at PC 0x%08" PRIx32
", target->state: %s",
429 arm_mode_name(arm
->core_mode
),
430 buf_get_u32(arm
->pc
->value
, 0, 32),
431 target_state_name(target
));
436 static int adapter_poll(struct target
*target
)
438 enum target_state state
;
439 struct hl_interface_s
*adapter
= target_to_adapter(target
);
440 struct armv7m_common
*armv7m
= target_to_armv7m(target
);
441 enum target_state prev_target_state
= target
->state
;
443 state
= adapter
->layout
->api
->state(adapter
->handle
);
445 if (state
== TARGET_UNKNOWN
) {
446 LOG_ERROR("jtag status contains invalid mode value - communication failure");
447 return ERROR_TARGET_FAILURE
;
450 if (prev_target_state
== state
)
453 target
->state
= state
;
455 if (state
== TARGET_HALTED
) {
457 int retval
= adapter_debug_entry(target
);
458 if (retval
!= ERROR_OK
)
461 if (prev_target_state
== TARGET_DEBUG_RUNNING
) {
462 target_call_event_callbacks(target
, TARGET_EVENT_DEBUG_HALTED
);
464 if (arm_semihosting(target
, &retval
) != 0)
467 target_call_event_callbacks(target
, TARGET_EVENT_HALTED
);
470 LOG_DEBUG("halted: PC: 0x%08" PRIx32
, buf_get_u32(armv7m
->arm
.pc
->value
, 0, 32));
476 static int adapter_assert_reset(struct target
*target
)
479 struct hl_interface_s
*adapter
= target_to_adapter(target
);
480 struct armv7m_common
*armv7m
= target_to_armv7m(target
);
481 bool use_srst_fallback
= true;
483 LOG_DEBUG("%s", __func__
);
485 enum reset_types jtag_reset_config
= jtag_get_reset_config();
487 bool srst_asserted
= false;
489 if ((jtag_reset_config
& RESET_HAS_SRST
) &&
490 (jtag_reset_config
& RESET_SRST_NO_GATING
)) {
491 jtag_add_reset(0, 1);
492 res
= adapter
->layout
->api
->assert_srst(adapter
->handle
, 0);
493 srst_asserted
= true;
496 adapter
->layout
->api
->write_debug_reg(adapter
->handle
, DCB_DHCSR
, DBGKEY
|C_DEBUGEN
);
498 /* only set vector catch if halt is requested */
499 if (target
->reset_halt
)
500 adapter
->layout
->api
->write_debug_reg(adapter
->handle
, DCB_DEMCR
, TRCENA
|VC_CORERESET
);
502 adapter
->layout
->api
->write_debug_reg(adapter
->handle
, DCB_DEMCR
, TRCENA
);
504 if (jtag_reset_config
& RESET_HAS_SRST
) {
505 if (!srst_asserted
) {
506 jtag_add_reset(0, 1);
507 res
= adapter
->layout
->api
->assert_srst(adapter
->handle
, 0);
509 if (res
== ERROR_COMMAND_NOTFOUND
)
510 LOG_ERROR("Hardware srst not supported, falling back to software reset");
511 else if (res
== ERROR_OK
) {
512 /* hardware srst supported */
513 use_srst_fallback
= false;
517 if (use_srst_fallback
) {
518 /* stlink v1 api does not support hardware srst, so we use a software reset fallback */
519 adapter
->layout
->api
->write_debug_reg(adapter
->handle
, NVIC_AIRCR
, AIRCR_VECTKEY
| AIRCR_SYSRESETREQ
);
522 res
= adapter
->layout
->api
->reset(adapter
->handle
);
527 /* registers are now invalid */
528 register_cache_invalidate(armv7m
->arm
.core_cache
);
530 if (target
->reset_halt
) {
531 target
->state
= TARGET_RESET
;
532 target
->debug_reason
= DBG_REASON_DBGRQ
;
534 target
->state
= TARGET_HALTED
;
540 static int adapter_deassert_reset(struct target
*target
)
542 struct hl_interface_s
*adapter
= target_to_adapter(target
);
544 enum reset_types jtag_reset_config
= jtag_get_reset_config();
546 LOG_DEBUG("%s", __func__
);
548 if (jtag_reset_config
& RESET_HAS_SRST
)
549 adapter
->layout
->api
->assert_srst(adapter
->handle
, 1);
551 /* virtual deassert reset, we need it for the internal
554 jtag_add_reset(0, 0);
556 target
->savedDCRDR
= 0; /* clear both DCC busy bits on initial resume */
558 return target
->reset_halt
? ERROR_OK
: target_resume(target
, 1, 0, 0, 0);
561 static int adapter_halt(struct target
*target
)
564 struct hl_interface_s
*adapter
= target_to_adapter(target
);
566 LOG_DEBUG("%s", __func__
);
568 if (target
->state
== TARGET_HALTED
) {
569 LOG_DEBUG("target was already halted");
573 if (target
->state
== TARGET_UNKNOWN
)
574 LOG_WARNING("target was in unknown state when halt was requested");
576 res
= adapter
->layout
->api
->halt(adapter
->handle
);
581 target
->debug_reason
= DBG_REASON_DBGRQ
;
586 static int adapter_resume(struct target
*target
, int current
,
587 target_addr_t address
, int handle_breakpoints
,
591 struct hl_interface_s
*adapter
= target_to_adapter(target
);
592 struct armv7m_common
*armv7m
= target_to_armv7m(target
);
594 struct breakpoint
*breakpoint
= NULL
;
597 LOG_DEBUG("%s %d " TARGET_ADDR_FMT
" %d %d", __func__
, current
,
598 address
, handle_breakpoints
, debug_execution
);
600 if (target
->state
!= TARGET_HALTED
) {
601 LOG_WARNING("target not halted");
602 return ERROR_TARGET_NOT_HALTED
;
605 if (!debug_execution
) {
606 target_free_all_working_areas(target
);
607 cortex_m_enable_breakpoints(target
);
608 cortex_m_enable_watchpoints(target
);
613 buf_set_u32(pc
->value
, 0, 32, address
);
618 if (!breakpoint_find(target
, buf_get_u32(pc
->value
, 0, 32))
619 && !debug_execution
) {
620 armv7m_maybe_skip_bkpt_inst(target
, NULL
);
623 resume_pc
= buf_get_u32(pc
->value
, 0, 32);
625 /* write any user vector flags */
626 res
= target_write_u32(target
, DCB_DEMCR
, TRCENA
| armv7m
->demcr
);
630 armv7m_restore_context(target
);
632 /* restore savedDCRDR */
633 res
= target_write_u32(target
, DCB_DCRDR
, target
->savedDCRDR
);
637 /* registers are now invalid */
638 register_cache_invalidate(armv7m
->arm
.core_cache
);
640 /* the front-end may request us not to handle breakpoints */
641 if (handle_breakpoints
) {
642 /* Single step past breakpoint at current address */
643 breakpoint
= breakpoint_find(target
, resume_pc
);
645 LOG_DEBUG("unset breakpoint at " TARGET_ADDR_FMT
" (ID: %" PRIu32
")",
647 breakpoint
->unique_id
);
648 cortex_m_unset_breakpoint(target
, breakpoint
);
650 res
= adapter
->layout
->api
->step(adapter
->handle
);
655 cortex_m_set_breakpoint(target
, breakpoint
);
659 res
= adapter
->layout
->api
->run(adapter
->handle
);
664 target
->debug_reason
= DBG_REASON_NOTHALTED
;
666 if (!debug_execution
) {
667 target
->state
= TARGET_RUNNING
;
668 target_call_event_callbacks(target
, TARGET_EVENT_RESUMED
);
670 target
->state
= TARGET_DEBUG_RUNNING
;
671 target_call_event_callbacks(target
, TARGET_EVENT_DEBUG_RESUMED
);
677 static int adapter_step(struct target
*target
, int current
,
678 target_addr_t address
, int handle_breakpoints
)
681 struct hl_interface_s
*adapter
= target_to_adapter(target
);
682 struct armv7m_common
*armv7m
= target_to_armv7m(target
);
683 struct breakpoint
*breakpoint
= NULL
;
684 struct reg
*pc
= armv7m
->arm
.pc
;
685 bool bkpt_inst_found
= false;
687 LOG_DEBUG("%s", __func__
);
689 if (target
->state
!= TARGET_HALTED
) {
690 LOG_WARNING("target not halted");
691 return ERROR_TARGET_NOT_HALTED
;
695 buf_set_u32(pc
->value
, 0, 32, address
);
700 uint32_t pc_value
= buf_get_u32(pc
->value
, 0, 32);
702 /* the front-end may request us not to handle breakpoints */
703 if (handle_breakpoints
) {
704 breakpoint
= breakpoint_find(target
, pc_value
);
706 cortex_m_unset_breakpoint(target
, breakpoint
);
709 armv7m_maybe_skip_bkpt_inst(target
, &bkpt_inst_found
);
711 target
->debug_reason
= DBG_REASON_SINGLESTEP
;
713 armv7m_restore_context(target
);
715 /* restore savedDCRDR */
716 res
= target_write_u32(target
, DCB_DCRDR
, target
->savedDCRDR
);
720 target_call_event_callbacks(target
, TARGET_EVENT_RESUMED
);
722 res
= adapter
->layout
->api
->step(adapter
->handle
);
727 /* registers are now invalid */
728 register_cache_invalidate(armv7m
->arm
.core_cache
);
731 cortex_m_set_breakpoint(target
, breakpoint
);
733 adapter_debug_entry(target
);
734 target_call_event_callbacks(target
, TARGET_EVENT_HALTED
);
736 LOG_INFO("halted: PC: 0x%08" PRIx32
, buf_get_u32(armv7m
->arm
.pc
->value
, 0, 32));
741 static int adapter_read_memory(struct target
*target
, target_addr_t address
,
742 uint32_t size
, uint32_t count
,
745 struct hl_interface_s
*adapter
= target_to_adapter(target
);
747 if (!count
|| !buffer
)
748 return ERROR_COMMAND_SYNTAX_ERROR
;
750 LOG_DEBUG("%s " TARGET_ADDR_FMT
" %" PRIu32
" %" PRIu32
,
751 __func__
, address
, size
, count
);
753 return adapter
->layout
->api
->read_mem(adapter
->handle
, address
, size
, count
, buffer
);
756 static int adapter_write_memory(struct target
*target
, target_addr_t address
,
757 uint32_t size
, uint32_t count
,
758 const uint8_t *buffer
)
760 struct hl_interface_s
*adapter
= target_to_adapter(target
);
762 if (!count
|| !buffer
)
763 return ERROR_COMMAND_SYNTAX_ERROR
;
765 LOG_DEBUG("%s " TARGET_ADDR_FMT
" %" PRIu32
" %" PRIu32
,
766 __func__
, address
, size
, count
);
768 return adapter
->layout
->api
->write_mem(adapter
->handle
, address
, size
, count
, buffer
);
771 static const struct command_registration adapter_command_handlers
[] = {
773 .chain
= arm_command_handlers
,
776 .chain
= armv7m_trace_command_handlers
,
778 COMMAND_REGISTRATION_DONE
781 struct target_type hla_target
= {
782 .name
= "hla_target",
783 .deprecated_name
= "stm32_stlink",
785 .init_target
= adapter_init_target
,
786 .deinit_target
= cortex_m_deinit_target
,
787 .target_create
= adapter_target_create
,
788 .examine
= cortex_m_examine
,
789 .commands
= adapter_command_handlers
,
791 .poll
= adapter_poll
,
792 .arch_state
= armv7m_arch_state
,
794 .target_request_data
= hl_target_request_data
,
795 .assert_reset
= adapter_assert_reset
,
796 .deassert_reset
= adapter_deassert_reset
,
798 .halt
= adapter_halt
,
799 .resume
= adapter_resume
,
800 .step
= adapter_step
,
802 .get_gdb_reg_list
= armv7m_get_gdb_reg_list
,
804 .read_memory
= adapter_read_memory
,
805 .write_memory
= adapter_write_memory
,
806 .checksum_memory
= armv7m_checksum_memory
,
807 .blank_check_memory
= armv7m_blank_check_memory
,
809 .run_algorithm
= armv7m_run_algorithm
,
810 .start_algorithm
= armv7m_start_algorithm
,
811 .wait_algorithm
= armv7m_wait_algorithm
,
813 .add_breakpoint
= cortex_m_add_breakpoint
,
814 .remove_breakpoint
= cortex_m_remove_breakpoint
,
815 .add_watchpoint
= cortex_m_add_watchpoint
,
816 .remove_watchpoint
= cortex_m_remove_watchpoint
,
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)