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, write to the *
22 * Free Software Foundation, Inc., *
23 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
24 ***************************************************************************/
30 #include "jtag/jtag.h"
31 #include "jtag/hla/hla_transport.h"
32 #include "jtag/hla/hla_interface.h"
33 #include "jtag/hla/hla_layout.h"
35 #include "algorithm.h"
37 #include "breakpoints.h"
38 #include "target_type.h"
41 #include "arm_semihosting.h"
42 #include "target_request.h"
44 #define savedDCRDR dbgbase /* FIXME: using target->dbgbase to preserve DCRDR */
46 #define ARMV7M_SCS_DCRSR DCB_DCRSR
47 #define ARMV7M_SCS_DCRDR DCB_DCRDR
49 static inline struct hl_interface_s
*target_to_adapter(struct target
*target
)
51 return target
->tap
->priv
;
54 static int adapter_load_core_reg_u32(struct target
*target
,
55 uint32_t num
, uint32_t *value
)
58 struct hl_interface_s
*adapter
= target_to_adapter(target
);
60 LOG_DEBUG("%s", __func__
);
62 /* NOTE: we "know" here that the register identifiers used
63 * in the v7m header match the Cortex-M3 Debug Core Register
64 * Selector values for R0..R15, xPSR, MSP, and PSP.
68 /* read a normal core register */
69 retval
= adapter
->layout
->api
->read_reg(adapter
->fd
, num
, value
);
71 if (retval
!= ERROR_OK
) {
72 LOG_ERROR("JTAG failure %i", retval
);
73 return ERROR_JTAG_DEVICE_ERROR
;
75 LOG_DEBUG("load from core reg %i value 0x%" PRIx32
"", (int)num
, *value
);
84 /* Floating-point Status and Registers */
85 retval
= target_write_u32(target
, ARMV7M_SCS_DCRSR
, 33);
86 if (retval
!= ERROR_OK
)
88 retval
= target_read_u32(target
, ARMV7M_SCS_DCRDR
, value
);
89 if (retval
!= ERROR_OK
)
91 LOG_DEBUG("load from core reg %i value 0x%" PRIx32
"", (int)num
, *value
);
94 case ARMV7M_S0
... ARMV7M_S31
:
95 /* Floating-point Status and Registers */
96 retval
= target_write_u32(target
, ARMV7M_SCS_DCRSR
, num
-ARMV7M_S0
+64);
97 if (retval
!= ERROR_OK
)
99 retval
= target_read_u32(target
, ARMV7M_SCS_DCRDR
, value
);
100 if (retval
!= ERROR_OK
)
102 LOG_DEBUG("load from core reg %i value 0x%" PRIx32
"", (int)num
, *value
);
105 case ARMV7M_D0
... ARMV7M_D15
:
111 case ARMV7M_FAULTMASK
:
113 /* Cortex-M3 packages these four registers as bitfields
114 * in one Debug Core register. So say r0 and r2 docs;
115 * it was removed from r1 docs, but still works.
117 retval
= adapter
->layout
->api
->read_reg(adapter
->fd
, 20, value
);
118 if (retval
!= ERROR_OK
)
123 *value
= buf_get_u32((uint8_t *) value
, 0, 1);
127 *value
= buf_get_u32((uint8_t *) value
, 8, 8);
130 case ARMV7M_FAULTMASK
:
131 *value
= buf_get_u32((uint8_t *) value
, 16, 1);
135 *value
= buf_get_u32((uint8_t *) value
, 24, 2);
139 LOG_DEBUG("load from special reg %i value 0x%" PRIx32
"",
144 return ERROR_COMMAND_SYNTAX_ERROR
;
150 static int adapter_store_core_reg_u32(struct target
*target
,
151 uint32_t num
, uint32_t value
)
155 struct armv7m_common
*armv7m
= target_to_armv7m(target
);
156 struct hl_interface_s
*adapter
= target_to_adapter(target
);
158 LOG_DEBUG("%s", __func__
);
160 /* NOTE: we "know" here that the register identifiers used
161 * in the v7m header match the Cortex-M3 Debug Core Register
162 * Selector values for R0..R15, xPSR, MSP, and PSP.
166 retval
= adapter
->layout
->api
->write_reg(adapter
->fd
, num
, value
);
168 if (retval
!= ERROR_OK
) {
171 LOG_ERROR("JTAG failure");
172 r
= armv7m
->arm
.core_cache
->reg_list
+ num
;
174 return ERROR_JTAG_DEVICE_ERROR
;
176 LOG_DEBUG("write core reg %i value 0x%" PRIx32
"", (int)num
, value
);
184 /* Floating-point Status and Registers */
185 retval
= target_write_u32(target
, ARMV7M_SCS_DCRDR
, value
);
186 if (retval
!= ERROR_OK
)
188 retval
= target_write_u32(target
, ARMV7M_SCS_DCRSR
, 33 | (1<<16));
189 if (retval
!= ERROR_OK
)
191 LOG_DEBUG("write core reg %i value 0x%" PRIx32
"", (int)num
, value
);
194 case ARMV7M_S0
... ARMV7M_S31
:
195 /* Floating-point Status and Registers */
196 retval
= target_write_u32(target
, ARMV7M_SCS_DCRDR
, value
);
197 if (retval
!= ERROR_OK
)
199 retval
= target_write_u32(target
, ARMV7M_SCS_DCRSR
, (num
-ARMV7M_S0
+64) | (1<<16));
200 if (retval
!= ERROR_OK
)
202 LOG_DEBUG("write core reg %i value 0x%" PRIx32
"", (int)num
, value
);
205 case ARMV7M_D0
... ARMV7M_D15
:
210 case ARMV7M_FAULTMASK
:
212 /* Cortex-M3 packages these four registers as bitfields
213 * in one Debug Core register. So say r0 and r2 docs;
214 * it was removed from r1 docs, but still works.
217 adapter
->layout
->api
->read_reg(adapter
->fd
, 20, ®
);
221 buf_set_u32((uint8_t *) ®
, 0, 1, value
);
225 buf_set_u32((uint8_t *) ®
, 8, 8, value
);
228 case ARMV7M_FAULTMASK
:
229 buf_set_u32((uint8_t *) ®
, 16, 1, value
);
233 buf_set_u32((uint8_t *) ®
, 24, 2, value
);
237 adapter
->layout
->api
->write_reg(adapter
->fd
, 20, reg
);
239 LOG_DEBUG("write special reg %i value 0x%" PRIx32
" ", (int)num
, value
);
243 return ERROR_COMMAND_SYNTAX_ERROR
;
249 static int adapter_examine_debug_reason(struct target
*target
)
251 if ((target
->debug_reason
!= DBG_REASON_DBGRQ
)
252 && (target
->debug_reason
!= DBG_REASON_SINGLESTEP
)) {
253 target
->debug_reason
= DBG_REASON_BREAKPOINT
;
259 static int hl_dcc_read(struct hl_interface_s
*hl_if
, uint8_t *value
, uint8_t *ctrl
)
262 int retval
= hl_if
->layout
->api
->read_mem(hl_if
->fd
,
263 DCB_DCRDR
, 1, sizeof(dcrdr
), (uint8_t *)&dcrdr
);
264 if (retval
== ERROR_OK
) {
265 *ctrl
= (uint8_t)dcrdr
;
266 *value
= (uint8_t)(dcrdr
>> 8);
268 LOG_DEBUG("data 0x%x ctrl 0x%x", *value
, *ctrl
);
271 /* write ack back to software dcc register
272 * to signify we have read data */
273 /* atomically clear just the byte containing the busy bit */
274 static const uint8_t zero
;
275 retval
= hl_if
->layout
->api
->write_mem(hl_if
->fd
, DCB_DCRDR
, 1, 1, &zero
);
281 static int hl_target_request_data(struct target
*target
,
282 uint32_t size
, uint8_t *buffer
)
284 struct hl_interface_s
*hl_if
= target_to_adapter(target
);
289 for (i
= 0; i
< (size
* 4); i
++) {
290 hl_dcc_read(hl_if
, &data
, &ctrl
);
297 static int hl_handle_target_request(void *priv
)
299 struct target
*target
= priv
;
300 if (!target_was_examined(target
))
302 struct hl_interface_s
*hl_if
= target_to_adapter(target
);
304 if (!target
->dbg_msg_enabled
)
307 if (target
->state
== TARGET_RUNNING
) {
311 hl_dcc_read(hl_if
, &data
, &ctrl
);
313 /* check if we have data */
314 if (ctrl
& (1 << 0)) {
317 /* we assume target is quick enough */
319 hl_dcc_read(hl_if
, &data
, &ctrl
);
320 request
|= (data
<< 8);
321 hl_dcc_read(hl_if
, &data
, &ctrl
);
322 request
|= (data
<< 16);
323 hl_dcc_read(hl_if
, &data
, &ctrl
);
324 request
|= (data
<< 24);
325 target_request(target
, request
);
332 static int adapter_init_arch_info(struct target
*target
,
333 struct cortex_m_common
*cortex_m
,
334 struct jtag_tap
*tap
)
336 struct armv7m_common
*armv7m
;
338 LOG_DEBUG("%s", __func__
);
340 armv7m
= &cortex_m
->armv7m
;
341 armv7m_init_arch_info(target
, armv7m
);
343 armv7m
->load_core_reg_u32
= adapter_load_core_reg_u32
;
344 armv7m
->store_core_reg_u32
= adapter_store_core_reg_u32
;
346 armv7m
->examine_debug_reason
= adapter_examine_debug_reason
;
347 armv7m
->stlink
= true;
349 target_register_timer_callback(hl_handle_target_request
, 1, 1, target
);
354 static int adapter_init_target(struct command_context
*cmd_ctx
,
355 struct target
*target
)
357 LOG_DEBUG("%s", __func__
);
359 armv7m_build_reg_cache(target
);
364 static int adapter_target_create(struct target
*target
,
367 LOG_DEBUG("%s", __func__
);
369 struct cortex_m_common
*cortex_m
= calloc(1, sizeof(struct cortex_m_common
));
372 return ERROR_COMMAND_SYNTAX_ERROR
;
374 adapter_init_arch_info(target
, cortex_m
, target
->tap
);
379 static int adapter_load_context(struct target
*target
)
381 struct armv7m_common
*armv7m
= target_to_armv7m(target
);
382 int num_regs
= armv7m
->arm
.core_cache
->num_regs
;
384 for (int i
= 0; i
< num_regs
; i
++) {
386 struct reg
*r
= &armv7m
->arm
.core_cache
->reg_list
[i
];
388 armv7m
->arm
.read_core_reg(target
, r
, i
, ARM_MODE_ANY
);
394 static int adapter_debug_entry(struct target
*target
)
396 struct hl_interface_s
*adapter
= target_to_adapter(target
);
397 struct armv7m_common
*armv7m
= target_to_armv7m(target
);
398 struct arm
*arm
= &armv7m
->arm
;
403 /* preserve the DCRDR across halts */
404 retval
= target_read_u32(target
, DCB_DCRDR
, &target
->savedDCRDR
);
405 if (retval
!= ERROR_OK
)
408 retval
= armv7m
->examine_debug_reason(target
);
409 if (retval
!= ERROR_OK
)
412 adapter_load_context(target
);
414 /* make sure we clear the vector catch bit */
415 adapter
->layout
->api
->write_debug_reg(adapter
->fd
, DCB_DEMCR
, TRCENA
);
418 xPSR
= buf_get_u32(r
->value
, 0, 32);
420 /* Are we in an exception handler */
422 armv7m
->exception_number
= (xPSR
& 0x1FF);
424 arm
->core_mode
= ARM_MODE_HANDLER
;
425 arm
->map
= armv7m_msp_reg_map
;
427 unsigned control
= buf_get_u32(arm
->core_cache
428 ->reg_list
[ARMV7M_CONTROL
].value
, 0, 2);
430 /* is this thread privileged? */
431 arm
->core_mode
= control
& 1
432 ? ARM_MODE_USER_THREAD
435 /* which stack is it using? */
437 arm
->map
= armv7m_psp_reg_map
;
439 arm
->map
= armv7m_msp_reg_map
;
441 armv7m
->exception_number
= 0;
444 LOG_DEBUG("entered debug state in core mode: %s at PC 0x%08" PRIx32
", target->state: %s",
445 arm_mode_name(arm
->core_mode
),
446 *(uint32_t *)(arm
->pc
->value
),
447 target_state_name(target
));
452 static int adapter_poll(struct target
*target
)
454 enum target_state state
;
455 struct hl_interface_s
*adapter
= target_to_adapter(target
);
456 struct armv7m_common
*armv7m
= target_to_armv7m(target
);
457 enum target_state prev_target_state
= target
->state
;
459 state
= adapter
->layout
->api
->state(adapter
->fd
);
461 if (state
== TARGET_UNKNOWN
) {
462 LOG_ERROR("jtag status contains invalid mode value - communication failure");
463 return ERROR_TARGET_FAILURE
;
466 if (target
->state
== state
)
469 if (state
== TARGET_HALTED
) {
470 target
->state
= state
;
472 int retval
= adapter_debug_entry(target
);
473 if (retval
!= ERROR_OK
)
476 if (prev_target_state
== TARGET_DEBUG_RUNNING
) {
477 target_call_event_callbacks(target
, TARGET_EVENT_DEBUG_HALTED
);
479 if (arm_semihosting(target
, &retval
) != 0)
482 target_call_event_callbacks(target
, TARGET_EVENT_HALTED
);
485 LOG_DEBUG("halted: PC: 0x%08x", buf_get_u32(armv7m
->arm
.pc
->value
, 0, 32));
491 static int adapter_assert_reset(struct target
*target
)
494 struct hl_interface_s
*adapter
= target_to_adapter(target
);
495 struct armv7m_common
*armv7m
= target_to_armv7m(target
);
496 bool use_srst_fallback
= true;
498 LOG_DEBUG("%s", __func__
);
500 enum reset_types jtag_reset_config
= jtag_get_reset_config();
502 bool srst_asserted
= false;
504 if ((jtag_reset_config
& RESET_HAS_SRST
) &&
505 (jtag_reset_config
& RESET_SRST_NO_GATING
)) {
506 jtag_add_reset(0, 1);
507 res
= adapter
->layout
->api
->assert_srst(adapter
->fd
, 0);
508 srst_asserted
= true;
511 adapter
->layout
->api
->write_debug_reg(adapter
->fd
, DCB_DHCSR
, DBGKEY
|C_DEBUGEN
);
513 /* only set vector catch if halt is requested */
514 if (target
->reset_halt
)
515 adapter
->layout
->api
->write_debug_reg(adapter
->fd
, DCB_DEMCR
, TRCENA
|VC_CORERESET
);
517 adapter
->layout
->api
->write_debug_reg(adapter
->fd
, DCB_DEMCR
, TRCENA
);
519 if (jtag_reset_config
& RESET_HAS_SRST
) {
520 if (!srst_asserted
) {
521 jtag_add_reset(0, 1);
522 res
= adapter
->layout
->api
->assert_srst(adapter
->fd
, 0);
524 if (res
== ERROR_COMMAND_NOTFOUND
)
525 LOG_ERROR("Hardware srst not supported, falling back to software reset");
526 else if (res
== ERROR_OK
) {
527 /* hardware srst supported */
528 use_srst_fallback
= false;
532 if (use_srst_fallback
) {
533 /* stlink v1 api does not support hardware srst, so we use a software reset fallback */
534 adapter
->layout
->api
->write_debug_reg(adapter
->fd
, NVIC_AIRCR
, AIRCR_VECTKEY
| AIRCR_SYSRESETREQ
);
537 res
= adapter
->layout
->api
->reset(adapter
->fd
);
542 /* registers are now invalid */
543 register_cache_invalidate(armv7m
->arm
.core_cache
);
545 if (target
->reset_halt
) {
546 target
->state
= TARGET_RESET
;
547 target
->debug_reason
= DBG_REASON_DBGRQ
;
549 target
->state
= TARGET_HALTED
;
555 static int adapter_deassert_reset(struct target
*target
)
557 struct hl_interface_s
*adapter
= target_to_adapter(target
);
559 enum reset_types jtag_reset_config
= jtag_get_reset_config();
561 LOG_DEBUG("%s", __func__
);
563 if (jtag_reset_config
& RESET_HAS_SRST
)
564 adapter
->layout
->api
->assert_srst(adapter
->fd
, 1);
566 /* virtual deassert reset, we need it for the internal
569 jtag_add_reset(0, 0);
571 target
->savedDCRDR
= 0; /* clear both DCC busy bits on initial resume */
573 return target
->reset_halt
? ERROR_OK
: target_resume(target
, 1, 0, 0, 0);
576 static int adapter_halt(struct target
*target
)
579 struct hl_interface_s
*adapter
= target_to_adapter(target
);
581 LOG_DEBUG("%s", __func__
);
583 if (target
->state
== TARGET_HALTED
) {
584 LOG_DEBUG("target was already halted");
588 if (target
->state
== TARGET_UNKNOWN
)
589 LOG_WARNING("target was in unknown state when halt was requested");
591 res
= adapter
->layout
->api
->halt(adapter
->fd
);
596 target
->debug_reason
= DBG_REASON_DBGRQ
;
601 static int adapter_resume(struct target
*target
, int current
,
602 uint32_t address
, int handle_breakpoints
,
606 struct hl_interface_s
*adapter
= target_to_adapter(target
);
607 struct armv7m_common
*armv7m
= target_to_armv7m(target
);
609 struct breakpoint
*breakpoint
= NULL
;
612 LOG_DEBUG("%s %d 0x%08x %d %d", __func__
, current
, address
,
613 handle_breakpoints
, debug_execution
);
615 if (target
->state
!= TARGET_HALTED
) {
616 LOG_WARNING("target not halted");
617 return ERROR_TARGET_NOT_HALTED
;
620 if (!debug_execution
) {
621 target_free_all_working_areas(target
);
622 cortex_m_enable_breakpoints(target
);
623 cortex_m_enable_watchpoints(target
);
628 buf_set_u32(pc
->value
, 0, 32, address
);
633 if (!breakpoint_find(target
, buf_get_u32(pc
->value
, 0, 32))
634 && !debug_execution
) {
635 armv7m_maybe_skip_bkpt_inst(target
, NULL
);
638 resume_pc
= buf_get_u32(pc
->value
, 0, 32);
640 /* write any user vector flags */
641 res
= target_write_u32(target
, DCB_DEMCR
, TRCENA
| armv7m
->demcr
);
645 armv7m_restore_context(target
);
647 /* restore savedDCRDR */
648 res
= target_write_u32(target
, DCB_DCRDR
, target
->savedDCRDR
);
652 /* registers are now invalid */
653 register_cache_invalidate(armv7m
->arm
.core_cache
);
655 /* the front-end may request us not to handle breakpoints */
656 if (handle_breakpoints
) {
657 /* Single step past breakpoint at current address */
658 breakpoint
= breakpoint_find(target
, resume_pc
);
660 LOG_DEBUG("unset breakpoint at 0x%8.8" PRIx32
" (ID: %d)",
662 breakpoint
->unique_id
);
663 cortex_m_unset_breakpoint(target
, breakpoint
);
665 res
= adapter
->layout
->api
->step(adapter
->fd
);
670 cortex_m_set_breakpoint(target
, breakpoint
);
674 res
= adapter
->layout
->api
->run(adapter
->fd
);
679 target
->debug_reason
= DBG_REASON_NOTHALTED
;
681 if (!debug_execution
) {
682 target
->state
= TARGET_RUNNING
;
683 target_call_event_callbacks(target
, TARGET_EVENT_RESUMED
);
685 target
->state
= TARGET_DEBUG_RUNNING
;
686 target_call_event_callbacks(target
, TARGET_EVENT_DEBUG_RESUMED
);
692 static int adapter_step(struct target
*target
, int current
,
693 uint32_t address
, int handle_breakpoints
)
696 struct hl_interface_s
*adapter
= target_to_adapter(target
);
697 struct armv7m_common
*armv7m
= target_to_armv7m(target
);
698 struct breakpoint
*breakpoint
= NULL
;
699 struct reg
*pc
= armv7m
->arm
.pc
;
700 bool bkpt_inst_found
= false;
702 LOG_DEBUG("%s", __func__
);
704 if (target
->state
!= TARGET_HALTED
) {
705 LOG_WARNING("target not halted");
706 return ERROR_TARGET_NOT_HALTED
;
710 buf_set_u32(pc
->value
, 0, 32, address
);
715 uint32_t pc_value
= buf_get_u32(pc
->value
, 0, 32);
717 /* the front-end may request us not to handle breakpoints */
718 if (handle_breakpoints
) {
719 breakpoint
= breakpoint_find(target
, pc_value
);
721 cortex_m_unset_breakpoint(target
, breakpoint
);
724 armv7m_maybe_skip_bkpt_inst(target
, &bkpt_inst_found
);
726 target
->debug_reason
= DBG_REASON_SINGLESTEP
;
728 armv7m_restore_context(target
);
730 /* restore savedDCRDR */
731 res
= target_write_u32(target
, DCB_DCRDR
, target
->savedDCRDR
);
735 target_call_event_callbacks(target
, TARGET_EVENT_RESUMED
);
737 res
= adapter
->layout
->api
->step(adapter
->fd
);
742 /* registers are now invalid */
743 register_cache_invalidate(armv7m
->arm
.core_cache
);
746 cortex_m_set_breakpoint(target
, breakpoint
);
748 adapter_debug_entry(target
);
749 target_call_event_callbacks(target
, TARGET_EVENT_HALTED
);
751 LOG_INFO("halted: PC: 0x%08x", buf_get_u32(armv7m
->arm
.pc
->value
, 0, 32));
756 static int adapter_read_memory(struct target
*target
, uint32_t address
,
757 uint32_t size
, uint32_t count
,
760 struct hl_interface_s
*adapter
= target_to_adapter(target
);
762 if (!count
|| !buffer
)
763 return ERROR_COMMAND_SYNTAX_ERROR
;
765 LOG_DEBUG("%s 0x%08x %d %d", __func__
, address
, size
, count
);
767 return adapter
->layout
->api
->read_mem(adapter
->fd
, address
, size
, count
, buffer
);
770 static int adapter_write_memory(struct target
*target
, uint32_t address
,
771 uint32_t size
, uint32_t count
,
772 const uint8_t *buffer
)
774 struct hl_interface_s
*adapter
= target_to_adapter(target
);
776 if (!count
|| !buffer
)
777 return ERROR_COMMAND_SYNTAX_ERROR
;
779 LOG_DEBUG("%s 0x%08x %d %d", __func__
, address
, size
, count
);
781 return adapter
->layout
->api
->write_mem(adapter
->fd
, address
, size
, count
, buffer
);
784 static const struct command_registration adapter_command_handlers
[] = {
786 .chain
= arm_command_handlers
,
788 COMMAND_REGISTRATION_DONE
791 struct target_type hla_target
= {
792 .name
= "hla_target",
793 .deprecated_name
= "stm32_stlink",
795 .init_target
= adapter_init_target
,
796 .target_create
= adapter_target_create
,
797 .examine
= cortex_m_examine
,
798 .commands
= adapter_command_handlers
,
800 .poll
= adapter_poll
,
801 .arch_state
= armv7m_arch_state
,
803 .target_request_data
= hl_target_request_data
,
804 .assert_reset
= adapter_assert_reset
,
805 .deassert_reset
= adapter_deassert_reset
,
807 .halt
= adapter_halt
,
808 .resume
= adapter_resume
,
809 .step
= adapter_step
,
811 .get_gdb_reg_list
= armv7m_get_gdb_reg_list
,
813 .read_memory
= adapter_read_memory
,
814 .write_memory
= adapter_write_memory
,
815 .checksum_memory
= armv7m_checksum_memory
,
816 .blank_check_memory
= armv7m_blank_check_memory
,
818 .run_algorithm
= armv7m_run_algorithm
,
819 .start_algorithm
= armv7m_start_algorithm
,
820 .wait_algorithm
= armv7m_wait_algorithm
,
822 .add_breakpoint
= cortex_m_add_breakpoint
,
823 .remove_breakpoint
= cortex_m_remove_breakpoint
,
824 .add_watchpoint
= cortex_m_add_watchpoint
,
825 .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)