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/interface.h"
29 #include "jtag/jtag.h"
30 #include "jtag/hla/hla_transport.h"
31 #include "jtag/hla/hla_interface.h"
32 #include "jtag/hla/hla_layout.h"
34 #include "algorithm.h"
36 #include "breakpoints.h"
37 #include "target_type.h"
40 #include "arm_semihosting.h"
41 #include "target_request.h"
43 #define savedDCRDR dbgbase /* FIXME: using target->dbgbase to preserve DCRDR */
45 #define ARMV7M_SCS_DCRSR DCB_DCRSR
46 #define ARMV7M_SCS_DCRDR DCB_DCRDR
48 static inline struct hl_interface_s
*target_to_adapter(struct target
*target
)
50 return target
->tap
->priv
;
53 static int adapter_load_core_reg_u32(struct target
*target
,
54 uint32_t regsel
, uint32_t *value
)
57 struct hl_interface_s
*adapter
= target_to_adapter(target
);
59 LOG_DEBUG("%s", __func__
);
61 /* NOTE: we "know" here that the register identifiers used
62 * in the v7m header match the Cortex-M3 Debug Core Register
63 * Selector values for R0..R15, xPSR, MSP, and PSP.
66 case ARMV7M_REGSEL_R0
... ARMV7M_REGSEL_PSP
:
67 /* read a normal core register */
68 retval
= adapter
->layout
->api
->read_reg(adapter
->handle
, regsel
, value
);
70 if (retval
!= ERROR_OK
) {
71 LOG_ERROR("JTAG failure %i", retval
);
72 return ERROR_JTAG_DEVICE_ERROR
;
74 LOG_DEBUG("load from core reg %" PRIu32
" value 0x%" PRIx32
"", regsel
, *value
);
77 case ARMV7M_REGSEL_FPSCR
:
78 /* Floating-point Status and Registers */
79 retval
= target_write_u32(target
, ARMV7M_SCS_DCRSR
, regsel
);
80 if (retval
!= ERROR_OK
)
82 retval
= target_read_u32(target
, ARMV7M_SCS_DCRDR
, value
);
83 if (retval
!= ERROR_OK
)
85 LOG_DEBUG("load from FPSCR value 0x%" PRIx32
, *value
);
88 case ARMV7M_REGSEL_S0
... ARMV7M_REGSEL_S31
:
89 /* Floating-point Status and Registers */
90 retval
= target_write_u32(target
, ARMV7M_SCS_DCRSR
, regsel
);
91 if (retval
!= ERROR_OK
)
93 retval
= target_read_u32(target
, ARMV7M_SCS_DCRDR
, value
);
94 if (retval
!= ERROR_OK
)
96 LOG_DEBUG("load from FPU reg S%d value 0x%" PRIx32
,
97 (int)(regsel
- ARMV7M_REGSEL_S0
), *value
);
100 case ARMV7M_REGSEL_PMSK_BPRI_FLTMSK_CTRL
:
101 retval
= adapter
->layout
->api
->read_reg(adapter
->handle
, ARMV7M_REGSEL_PMSK_BPRI_FLTMSK_CTRL
, value
);
102 if (retval
!= ERROR_OK
)
105 LOG_DEBUG("load from special reg PRIMASK/BASEPRI/FAULTMASK/CONTROL value 0x%" PRIx32
, *value
);
109 return ERROR_COMMAND_SYNTAX_ERROR
;
115 static int adapter_store_core_reg_u32(struct target
*target
,
116 uint32_t regsel
, uint32_t value
)
119 struct armv7m_common
*armv7m
= target_to_armv7m(target
);
120 struct hl_interface_s
*adapter
= target_to_adapter(target
);
122 LOG_DEBUG("%s", __func__
);
125 case ARMV7M_REGSEL_R0
... ARMV7M_REGSEL_PSP
:
126 retval
= adapter
->layout
->api
->write_reg(adapter
->handle
, regsel
, value
);
128 if (retval
!= ERROR_OK
) {
131 LOG_ERROR("JTAG failure");
132 r
= armv7m
->arm
.core_cache
->reg_list
+ regsel
; /* TODO: don't use regsel as register index */
134 return ERROR_JTAG_DEVICE_ERROR
;
136 LOG_DEBUG("write core reg %" PRIu32
" value 0x%" PRIx32
"", regsel
, value
);
139 case ARMV7M_REGSEL_FPSCR
:
140 /* Floating-point Status and Registers */
141 retval
= target_write_u32(target
, ARMV7M_SCS_DCRDR
, value
);
142 if (retval
!= ERROR_OK
)
144 retval
= target_write_u32(target
, ARMV7M_SCS_DCRSR
, ARMV7M_REGSEL_FPSCR
| DCRSR_WnR
);
145 if (retval
!= ERROR_OK
)
147 LOG_DEBUG("write FPSCR value 0x%" PRIx32
, value
);
150 case ARMV7M_REGSEL_S0
... ARMV7M_REGSEL_S31
:
151 /* Floating-point Status and Registers */
152 retval
= target_write_u32(target
, ARMV7M_SCS_DCRDR
, value
);
153 if (retval
!= ERROR_OK
)
155 retval
= target_write_u32(target
, ARMV7M_SCS_DCRSR
, regsel
| DCRSR_WnR
);
156 if (retval
!= ERROR_OK
)
158 LOG_DEBUG("write FPU reg S%d value 0x%" PRIx32
,
159 (int)(regsel
- ARMV7M_REGSEL_S0
), value
);
162 case ARMV7M_REGSEL_PMSK_BPRI_FLTMSK_CTRL
:
163 adapter
->layout
->api
->write_reg(adapter
->handle
, ARMV7M_REGSEL_PMSK_BPRI_FLTMSK_CTRL
, value
);
165 LOG_DEBUG("write special reg PRIMASK/BASEPRI/FAULTMASK/CONTROL value 0x%" PRIx32
, value
);
169 return ERROR_COMMAND_SYNTAX_ERROR
;
175 static int adapter_examine_debug_reason(struct target
*target
)
177 if ((target
->debug_reason
!= DBG_REASON_DBGRQ
)
178 && (target
->debug_reason
!= DBG_REASON_SINGLESTEP
)) {
179 target
->debug_reason
= DBG_REASON_BREAKPOINT
;
185 static int hl_dcc_read(struct hl_interface_s
*hl_if
, uint8_t *value
, uint8_t *ctrl
)
188 int retval
= hl_if
->layout
->api
->read_mem(hl_if
->handle
,
189 DCB_DCRDR
, 1, sizeof(dcrdr
), (uint8_t *)&dcrdr
);
190 if (retval
== ERROR_OK
) {
191 *ctrl
= (uint8_t)dcrdr
;
192 *value
= (uint8_t)(dcrdr
>> 8);
194 LOG_DEBUG("data 0x%x ctrl 0x%x", *value
, *ctrl
);
197 /* write ack back to software dcc register
198 * to signify we have read data */
199 /* atomically clear just the byte containing the busy bit */
200 static const uint8_t zero
;
201 retval
= hl_if
->layout
->api
->write_mem(hl_if
->handle
, DCB_DCRDR
, 1, 1, &zero
);
207 static int hl_target_request_data(struct target
*target
,
208 uint32_t size
, uint8_t *buffer
)
210 struct hl_interface_s
*hl_if
= target_to_adapter(target
);
215 for (i
= 0; i
< (size
* 4); i
++) {
216 int err
= hl_dcc_read(hl_if
, &data
, &ctrl
);
226 static int hl_handle_target_request(void *priv
)
228 struct target
*target
= priv
;
231 if (!target_was_examined(target
))
233 struct hl_interface_s
*hl_if
= target_to_adapter(target
);
235 if (!target
->dbg_msg_enabled
)
238 if (target
->state
== TARGET_RUNNING
) {
242 err
= hl_dcc_read(hl_if
, &data
, &ctrl
);
246 /* check if we have data */
247 if (ctrl
& (1 << 0)) {
250 /* we assume target is quick enough */
252 err
= hl_dcc_read(hl_if
, &data
, &ctrl
);
256 request
|= (data
<< 8);
257 err
= hl_dcc_read(hl_if
, &data
, &ctrl
);
261 request
|= (data
<< 16);
262 err
= hl_dcc_read(hl_if
, &data
, &ctrl
);
266 request
|= (data
<< 24);
267 target_request(target
, request
);
274 static int adapter_init_arch_info(struct target
*target
,
275 struct cortex_m_common
*cortex_m
,
276 struct jtag_tap
*tap
)
278 struct armv7m_common
*armv7m
;
280 LOG_DEBUG("%s", __func__
);
282 armv7m
= &cortex_m
->armv7m
;
283 armv7m_init_arch_info(target
, armv7m
);
285 armv7m
->load_core_reg_u32
= adapter_load_core_reg_u32
;
286 armv7m
->store_core_reg_u32
= adapter_store_core_reg_u32
;
288 armv7m
->examine_debug_reason
= adapter_examine_debug_reason
;
289 armv7m
->stlink
= true;
291 target_register_timer_callback(hl_handle_target_request
, 1,
292 TARGET_TIMER_TYPE_PERIODIC
, target
);
297 static int adapter_init_target(struct command_context
*cmd_ctx
,
298 struct target
*target
)
300 LOG_DEBUG("%s", __func__
);
302 armv7m_build_reg_cache(target
);
303 arm_semihosting_init(target
);
307 static int adapter_target_create(struct target
*target
,
310 LOG_DEBUG("%s", __func__
);
311 struct adiv5_private_config
*pc
= target
->private_config
;
312 if (pc
!= NULL
&& pc
->ap_num
> 0) {
313 LOG_ERROR("hla_target: invalid parameter -ap-num (> 0)");
314 return ERROR_COMMAND_SYNTAX_ERROR
;
317 struct cortex_m_common
*cortex_m
= calloc(1, sizeof(struct cortex_m_common
));
318 if (cortex_m
== NULL
) {
319 LOG_ERROR("No memory creating target");
323 adapter_init_arch_info(target
, cortex_m
, target
->tap
);
328 static int adapter_load_context(struct target
*target
)
330 struct armv7m_common
*armv7m
= target_to_armv7m(target
);
331 int num_regs
= armv7m
->arm
.core_cache
->num_regs
;
333 for (int i
= 0; i
< num_regs
; i
++) {
335 struct reg
*r
= &armv7m
->arm
.core_cache
->reg_list
[i
];
337 armv7m
->arm
.read_core_reg(target
, r
, i
, ARM_MODE_ANY
);
343 static int adapter_debug_entry(struct target
*target
)
345 struct hl_interface_s
*adapter
= target_to_adapter(target
);
346 struct armv7m_common
*armv7m
= target_to_armv7m(target
);
347 struct arm
*arm
= &armv7m
->arm
;
352 /* preserve the DCRDR across halts */
353 retval
= target_read_u32(target
, DCB_DCRDR
, &target
->savedDCRDR
);
354 if (retval
!= ERROR_OK
)
357 retval
= armv7m
->examine_debug_reason(target
);
358 if (retval
!= ERROR_OK
)
361 adapter_load_context(target
);
363 /* make sure we clear the vector catch bit */
364 adapter
->layout
->api
->write_debug_reg(adapter
->handle
, DCB_DEMCR
, TRCENA
);
367 xPSR
= buf_get_u32(r
->value
, 0, 32);
369 /* Are we in an exception handler */
371 armv7m
->exception_number
= (xPSR
& 0x1FF);
373 arm
->core_mode
= ARM_MODE_HANDLER
;
374 arm
->map
= armv7m_msp_reg_map
;
376 unsigned control
= buf_get_u32(arm
->core_cache
377 ->reg_list
[ARMV7M_CONTROL
].value
, 0, 3);
379 /* is this thread privileged? */
380 arm
->core_mode
= control
& 1
381 ? ARM_MODE_USER_THREAD
384 /* which stack is it using? */
386 arm
->map
= armv7m_psp_reg_map
;
388 arm
->map
= armv7m_msp_reg_map
;
390 armv7m
->exception_number
= 0;
393 LOG_DEBUG("entered debug state in core mode: %s at PC 0x%08" PRIx32
", target->state: %s",
394 arm_mode_name(arm
->core_mode
),
395 buf_get_u32(arm
->pc
->value
, 0, 32),
396 target_state_name(target
));
401 static int adapter_poll(struct target
*target
)
403 enum target_state state
;
404 struct hl_interface_s
*adapter
= target_to_adapter(target
);
405 struct armv7m_common
*armv7m
= target_to_armv7m(target
);
406 enum target_state prev_target_state
= target
->state
;
408 state
= adapter
->layout
->api
->state(adapter
->handle
);
410 if (state
== TARGET_UNKNOWN
) {
411 LOG_ERROR("jtag status contains invalid mode value - communication failure");
412 return ERROR_TARGET_FAILURE
;
415 if (prev_target_state
== state
)
418 if (prev_target_state
== TARGET_DEBUG_RUNNING
&& state
== TARGET_RUNNING
)
421 target
->state
= state
;
423 if (state
== TARGET_HALTED
) {
425 int retval
= adapter_debug_entry(target
);
426 if (retval
!= ERROR_OK
)
429 if (prev_target_state
== TARGET_DEBUG_RUNNING
) {
430 target_call_event_callbacks(target
, TARGET_EVENT_DEBUG_HALTED
);
432 if (arm_semihosting(target
, &retval
) != 0)
435 target_call_event_callbacks(target
, TARGET_EVENT_HALTED
);
438 LOG_DEBUG("halted: PC: 0x%08" PRIx32
, buf_get_u32(armv7m
->arm
.pc
->value
, 0, 32));
444 static int hl_assert_reset(struct target
*target
)
447 struct hl_interface_s
*adapter
= target_to_adapter(target
);
448 struct armv7m_common
*armv7m
= target_to_armv7m(target
);
449 bool use_srst_fallback
= true;
451 LOG_DEBUG("%s", __func__
);
453 enum reset_types jtag_reset_config
= jtag_get_reset_config();
455 bool srst_asserted
= false;
457 if ((jtag_reset_config
& RESET_HAS_SRST
) &&
458 (jtag_reset_config
& RESET_SRST_NO_GATING
)) {
459 res
= adapter_assert_reset();
460 srst_asserted
= true;
463 adapter
->layout
->api
->write_debug_reg(adapter
->handle
, DCB_DHCSR
, DBGKEY
|C_DEBUGEN
);
465 /* only set vector catch if halt is requested */
466 if (target
->reset_halt
)
467 adapter
->layout
->api
->write_debug_reg(adapter
->handle
, DCB_DEMCR
, TRCENA
|VC_CORERESET
);
469 adapter
->layout
->api
->write_debug_reg(adapter
->handle
, DCB_DEMCR
, TRCENA
);
471 if (jtag_reset_config
& RESET_HAS_SRST
) {
472 if (!srst_asserted
) {
473 res
= adapter_assert_reset();
475 if (res
== ERROR_COMMAND_NOTFOUND
)
476 LOG_ERROR("Hardware srst not supported, falling back to software reset");
477 else if (res
== ERROR_OK
) {
478 /* hardware srst supported */
479 use_srst_fallback
= false;
483 if (use_srst_fallback
) {
484 /* stlink v1 api does not support hardware srst, so we use a software reset fallback */
485 adapter
->layout
->api
->write_debug_reg(adapter
->handle
, NVIC_AIRCR
, AIRCR_VECTKEY
| AIRCR_SYSRESETREQ
);
488 res
= adapter
->layout
->api
->reset(adapter
->handle
);
493 /* registers are now invalid */
494 register_cache_invalidate(armv7m
->arm
.core_cache
);
496 if (target
->reset_halt
) {
497 target
->state
= TARGET_RESET
;
498 target
->debug_reason
= DBG_REASON_DBGRQ
;
500 target
->state
= TARGET_HALTED
;
506 static int hl_deassert_reset(struct target
*target
)
508 enum reset_types jtag_reset_config
= jtag_get_reset_config();
510 LOG_DEBUG("%s", __func__
);
512 if (jtag_reset_config
& RESET_HAS_SRST
)
513 adapter_deassert_reset();
515 target
->savedDCRDR
= 0; /* clear both DCC busy bits on initial resume */
517 return target
->reset_halt
? ERROR_OK
: target_resume(target
, 1, 0, 0, 0);
520 static int adapter_halt(struct target
*target
)
523 struct hl_interface_s
*adapter
= target_to_adapter(target
);
525 LOG_DEBUG("%s", __func__
);
527 if (target
->state
== TARGET_HALTED
) {
528 LOG_DEBUG("target was already halted");
532 if (target
->state
== TARGET_UNKNOWN
)
533 LOG_WARNING("target was in unknown state when halt was requested");
535 res
= adapter
->layout
->api
->halt(adapter
->handle
);
540 target
->debug_reason
= DBG_REASON_DBGRQ
;
545 static int adapter_resume(struct target
*target
, int current
,
546 target_addr_t address
, int handle_breakpoints
,
550 struct hl_interface_s
*adapter
= target_to_adapter(target
);
551 struct armv7m_common
*armv7m
= target_to_armv7m(target
);
553 struct breakpoint
*breakpoint
= NULL
;
556 LOG_DEBUG("%s %d " TARGET_ADDR_FMT
" %d %d", __func__
, current
,
557 address
, handle_breakpoints
, debug_execution
);
559 if (target
->state
!= TARGET_HALTED
) {
560 LOG_WARNING("target not halted");
561 return ERROR_TARGET_NOT_HALTED
;
564 if (!debug_execution
) {
565 target_free_all_working_areas(target
);
566 cortex_m_enable_breakpoints(target
);
567 cortex_m_enable_watchpoints(target
);
572 buf_set_u32(pc
->value
, 0, 32, address
);
577 if (!breakpoint_find(target
, buf_get_u32(pc
->value
, 0, 32))
578 && !debug_execution
) {
579 armv7m_maybe_skip_bkpt_inst(target
, NULL
);
582 resume_pc
= buf_get_u32(pc
->value
, 0, 32);
584 /* write any user vector flags */
585 res
= target_write_u32(target
, DCB_DEMCR
, TRCENA
| armv7m
->demcr
);
589 armv7m_restore_context(target
);
591 /* restore savedDCRDR */
592 res
= target_write_u32(target
, DCB_DCRDR
, target
->savedDCRDR
);
596 /* registers are now invalid */
597 register_cache_invalidate(armv7m
->arm
.core_cache
);
599 /* the front-end may request us not to handle breakpoints */
600 if (handle_breakpoints
) {
601 /* Single step past breakpoint at current address */
602 breakpoint
= breakpoint_find(target
, resume_pc
);
604 LOG_DEBUG("unset breakpoint at " TARGET_ADDR_FMT
" (ID: %" PRIu32
")",
606 breakpoint
->unique_id
);
607 cortex_m_unset_breakpoint(target
, breakpoint
);
609 res
= adapter
->layout
->api
->step(adapter
->handle
);
614 cortex_m_set_breakpoint(target
, breakpoint
);
618 res
= adapter
->layout
->api
->run(adapter
->handle
);
623 target
->debug_reason
= DBG_REASON_NOTHALTED
;
625 if (!debug_execution
) {
626 target
->state
= TARGET_RUNNING
;
627 target_call_event_callbacks(target
, TARGET_EVENT_RESUMED
);
629 target
->state
= TARGET_DEBUG_RUNNING
;
630 target_call_event_callbacks(target
, TARGET_EVENT_DEBUG_RESUMED
);
636 static int adapter_step(struct target
*target
, int current
,
637 target_addr_t address
, int handle_breakpoints
)
640 struct hl_interface_s
*adapter
= target_to_adapter(target
);
641 struct armv7m_common
*armv7m
= target_to_armv7m(target
);
642 struct breakpoint
*breakpoint
= NULL
;
643 struct reg
*pc
= armv7m
->arm
.pc
;
644 bool bkpt_inst_found
= false;
646 LOG_DEBUG("%s", __func__
);
648 if (target
->state
!= TARGET_HALTED
) {
649 LOG_WARNING("target not halted");
650 return ERROR_TARGET_NOT_HALTED
;
654 buf_set_u32(pc
->value
, 0, 32, address
);
659 uint32_t pc_value
= buf_get_u32(pc
->value
, 0, 32);
661 /* the front-end may request us not to handle breakpoints */
662 if (handle_breakpoints
) {
663 breakpoint
= breakpoint_find(target
, pc_value
);
665 cortex_m_unset_breakpoint(target
, breakpoint
);
668 armv7m_maybe_skip_bkpt_inst(target
, &bkpt_inst_found
);
670 target
->debug_reason
= DBG_REASON_SINGLESTEP
;
672 armv7m_restore_context(target
);
674 /* restore savedDCRDR */
675 res
= target_write_u32(target
, DCB_DCRDR
, target
->savedDCRDR
);
679 target_call_event_callbacks(target
, TARGET_EVENT_RESUMED
);
681 res
= adapter
->layout
->api
->step(adapter
->handle
);
686 /* registers are now invalid */
687 register_cache_invalidate(armv7m
->arm
.core_cache
);
690 cortex_m_set_breakpoint(target
, breakpoint
);
692 adapter_debug_entry(target
);
693 target_call_event_callbacks(target
, TARGET_EVENT_HALTED
);
695 LOG_INFO("halted: PC: 0x%08" PRIx32
, buf_get_u32(armv7m
->arm
.pc
->value
, 0, 32));
700 static int adapter_read_memory(struct target
*target
, target_addr_t address
,
701 uint32_t size
, uint32_t count
,
704 struct hl_interface_s
*adapter
= target_to_adapter(target
);
706 if (!count
|| !buffer
)
707 return ERROR_COMMAND_SYNTAX_ERROR
;
709 LOG_DEBUG("%s " TARGET_ADDR_FMT
" %" PRIu32
" %" PRIu32
,
710 __func__
, address
, size
, count
);
712 return adapter
->layout
->api
->read_mem(adapter
->handle
, address
, size
, count
, buffer
);
715 static int adapter_write_memory(struct target
*target
, target_addr_t address
,
716 uint32_t size
, uint32_t count
,
717 const uint8_t *buffer
)
719 struct hl_interface_s
*adapter
= target_to_adapter(target
);
721 if (!count
|| !buffer
)
722 return ERROR_COMMAND_SYNTAX_ERROR
;
724 LOG_DEBUG("%s " TARGET_ADDR_FMT
" %" PRIu32
" %" PRIu32
,
725 __func__
, address
, size
, count
);
727 return adapter
->layout
->api
->write_mem(adapter
->handle
, address
, size
, count
, buffer
);
730 static const struct command_registration adapter_command_handlers
[] = {
732 .chain
= arm_command_handlers
,
735 .chain
= armv7m_trace_command_handlers
,
737 COMMAND_REGISTRATION_DONE
740 struct target_type hla_target
= {
741 .name
= "hla_target",
742 .deprecated_name
= "stm32_stlink",
744 .init_target
= adapter_init_target
,
745 .deinit_target
= cortex_m_deinit_target
,
746 .target_create
= adapter_target_create
,
747 .target_jim_configure
= adiv5_jim_configure
,
748 .examine
= cortex_m_examine
,
749 .commands
= adapter_command_handlers
,
751 .poll
= adapter_poll
,
752 .arch_state
= armv7m_arch_state
,
754 .target_request_data
= hl_target_request_data
,
755 .assert_reset
= hl_assert_reset
,
756 .deassert_reset
= hl_deassert_reset
,
758 .halt
= adapter_halt
,
759 .resume
= adapter_resume
,
760 .step
= adapter_step
,
762 .get_gdb_arch
= arm_get_gdb_arch
,
763 .get_gdb_reg_list
= armv7m_get_gdb_reg_list
,
765 .read_memory
= adapter_read_memory
,
766 .write_memory
= adapter_write_memory
,
767 .checksum_memory
= armv7m_checksum_memory
,
768 .blank_check_memory
= armv7m_blank_check_memory
,
770 .run_algorithm
= armv7m_run_algorithm
,
771 .start_algorithm
= armv7m_start_algorithm
,
772 .wait_algorithm
= armv7m_wait_algorithm
,
774 .add_breakpoint
= cortex_m_add_breakpoint
,
775 .remove_breakpoint
= cortex_m_remove_breakpoint
,
776 .add_watchpoint
= cortex_m_add_watchpoint
,
777 .remove_watchpoint
= cortex_m_remove_watchpoint
,
778 .profiling
= cortex_m_profiling
,
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)