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"
44 #define SAVED_DCRDR 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 regsel
, uint32_t *value
)
57 struct hl_interface_s
*adapter
= target_to_adapter(target
);
58 return adapter
->layout
->api
->read_reg(adapter
->handle
, regsel
, value
);
61 static int adapter_store_core_reg_u32(struct target
*target
,
62 uint32_t regsel
, uint32_t value
)
64 struct hl_interface_s
*adapter
= target_to_adapter(target
);
65 return adapter
->layout
->api
->write_reg(adapter
->handle
, regsel
, value
);
68 static int adapter_examine_debug_reason(struct target
*target
)
70 if ((target
->debug_reason
!= DBG_REASON_DBGRQ
)
71 && (target
->debug_reason
!= DBG_REASON_SINGLESTEP
)) {
72 target
->debug_reason
= DBG_REASON_BREAKPOINT
;
78 static int hl_dcc_read(struct hl_interface_s
*hl_if
, uint8_t *value
, uint8_t *ctrl
)
81 int retval
= hl_if
->layout
->api
->read_mem(hl_if
->handle
,
82 DCB_DCRDR
, 1, sizeof(dcrdr
), (uint8_t *)&dcrdr
);
83 if (retval
== ERROR_OK
) {
84 *ctrl
= (uint8_t)dcrdr
;
85 *value
= (uint8_t)(dcrdr
>> 8);
87 LOG_DEBUG("data 0x%x ctrl 0x%x", *value
, *ctrl
);
90 /* write ack back to software dcc register
91 * to signify we have read data */
92 /* atomically clear just the byte containing the busy bit */
93 static const uint8_t zero
;
94 retval
= hl_if
->layout
->api
->write_mem(hl_if
->handle
, DCB_DCRDR
, 1, 1, &zero
);
100 static int hl_target_request_data(struct target
*target
,
101 uint32_t size
, uint8_t *buffer
)
103 struct hl_interface_s
*hl_if
= target_to_adapter(target
);
108 for (i
= 0; i
< (size
* 4); i
++) {
109 int err
= hl_dcc_read(hl_if
, &data
, &ctrl
);
119 static int hl_handle_target_request(void *priv
)
121 struct target
*target
= priv
;
124 if (!target_was_examined(target
))
126 struct hl_interface_s
*hl_if
= target_to_adapter(target
);
128 if (!target
->dbg_msg_enabled
)
131 if (target
->state
== TARGET_RUNNING
) {
135 err
= hl_dcc_read(hl_if
, &data
, &ctrl
);
139 /* check if we have data */
140 if (ctrl
& (1 << 0)) {
143 /* we assume target is quick enough */
145 err
= hl_dcc_read(hl_if
, &data
, &ctrl
);
149 request
|= (data
<< 8);
150 err
= hl_dcc_read(hl_if
, &data
, &ctrl
);
154 request
|= (data
<< 16);
155 err
= hl_dcc_read(hl_if
, &data
, &ctrl
);
159 request
|= (data
<< 24);
160 target_request(target
, request
);
167 static int adapter_init_arch_info(struct target
*target
,
168 struct cortex_m_common
*cortex_m
,
169 struct jtag_tap
*tap
)
171 struct armv7m_common
*armv7m
;
173 LOG_DEBUG("%s", __func__
);
175 armv7m
= &cortex_m
->armv7m
;
176 armv7m_init_arch_info(target
, armv7m
);
178 armv7m
->load_core_reg_u32
= adapter_load_core_reg_u32
;
179 armv7m
->store_core_reg_u32
= adapter_store_core_reg_u32
;
181 armv7m
->examine_debug_reason
= adapter_examine_debug_reason
;
182 armv7m
->is_hla_target
= true;
184 target_register_timer_callback(hl_handle_target_request
, 1,
185 TARGET_TIMER_TYPE_PERIODIC
, target
);
190 static int adapter_init_target(struct command_context
*cmd_ctx
,
191 struct target
*target
)
193 LOG_DEBUG("%s", __func__
);
195 armv7m_build_reg_cache(target
);
196 arm_semihosting_init(target
);
200 static int adapter_target_create(struct target
*target
,
203 LOG_DEBUG("%s", __func__
);
204 struct adiv5_private_config
*pc
= target
->private_config
;
205 if (pc
!= NULL
&& pc
->ap_num
> 0) {
206 LOG_ERROR("hla_target: invalid parameter -ap-num (> 0)");
207 return ERROR_COMMAND_SYNTAX_ERROR
;
210 struct cortex_m_common
*cortex_m
= calloc(1, sizeof(struct cortex_m_common
));
211 if (cortex_m
== NULL
) {
212 LOG_ERROR("No memory creating target");
216 adapter_init_arch_info(target
, cortex_m
, target
->tap
);
221 static int adapter_load_context(struct target
*target
)
223 struct armv7m_common
*armv7m
= target_to_armv7m(target
);
224 int num_regs
= armv7m
->arm
.core_cache
->num_regs
;
226 for (int i
= 0; i
< num_regs
; i
++) {
228 struct reg
*r
= &armv7m
->arm
.core_cache
->reg_list
[i
];
229 if (r
->exist
&& !r
->valid
)
230 armv7m
->arm
.read_core_reg(target
, r
, i
, ARM_MODE_ANY
);
236 static int adapter_debug_entry(struct target
*target
)
238 struct hl_interface_s
*adapter
= target_to_adapter(target
);
239 struct armv7m_common
*armv7m
= target_to_armv7m(target
);
240 struct arm
*arm
= &armv7m
->arm
;
245 /* preserve the DCRDR across halts */
246 retval
= target_read_u32(target
, DCB_DCRDR
, &target
->SAVED_DCRDR
);
247 if (retval
!= ERROR_OK
)
250 retval
= armv7m
->examine_debug_reason(target
);
251 if (retval
!= ERROR_OK
)
254 adapter_load_context(target
);
256 /* make sure we clear the vector catch bit */
257 adapter
->layout
->api
->write_debug_reg(adapter
->handle
, DCB_DEMCR
, TRCENA
);
260 xPSR
= buf_get_u32(r
->value
, 0, 32);
262 /* Are we in an exception handler */
264 armv7m
->exception_number
= (xPSR
& 0x1FF);
266 arm
->core_mode
= ARM_MODE_HANDLER
;
267 arm
->map
= armv7m_msp_reg_map
;
269 unsigned control
= buf_get_u32(arm
->core_cache
270 ->reg_list
[ARMV7M_CONTROL
].value
, 0, 3);
272 /* is this thread privileged? */
273 arm
->core_mode
= control
& 1
274 ? ARM_MODE_USER_THREAD
277 /* which stack is it using? */
279 arm
->map
= armv7m_psp_reg_map
;
281 arm
->map
= armv7m_msp_reg_map
;
283 armv7m
->exception_number
= 0;
286 LOG_DEBUG("entered debug state in core mode: %s at PC 0x%08" PRIx32
", target->state: %s",
287 arm_mode_name(arm
->core_mode
),
288 buf_get_u32(arm
->pc
->value
, 0, 32),
289 target_state_name(target
));
294 static int adapter_poll(struct target
*target
)
296 enum target_state state
;
297 struct hl_interface_s
*adapter
= target_to_adapter(target
);
298 struct armv7m_common
*armv7m
= target_to_armv7m(target
);
299 enum target_state prev_target_state
= target
->state
;
301 state
= adapter
->layout
->api
->state(adapter
->handle
);
303 if (state
== TARGET_UNKNOWN
) {
304 LOG_ERROR("jtag status contains invalid mode value - communication failure");
305 return ERROR_TARGET_FAILURE
;
308 if (prev_target_state
== state
)
311 if (prev_target_state
== TARGET_DEBUG_RUNNING
&& state
== TARGET_RUNNING
)
314 target
->state
= state
;
316 if (state
== TARGET_HALTED
) {
318 int retval
= adapter_debug_entry(target
);
319 if (retval
!= ERROR_OK
)
322 if (prev_target_state
== TARGET_DEBUG_RUNNING
) {
323 target_call_event_callbacks(target
, TARGET_EVENT_DEBUG_HALTED
);
325 if (arm_semihosting(target
, &retval
) != 0)
328 target_call_event_callbacks(target
, TARGET_EVENT_HALTED
);
331 LOG_DEBUG("halted: PC: 0x%08" PRIx32
, buf_get_u32(armv7m
->arm
.pc
->value
, 0, 32));
337 static int hl_assert_reset(struct target
*target
)
340 struct hl_interface_s
*adapter
= target_to_adapter(target
);
341 struct armv7m_common
*armv7m
= target_to_armv7m(target
);
342 bool use_srst_fallback
= true;
344 LOG_DEBUG("%s", __func__
);
346 enum reset_types jtag_reset_config
= jtag_get_reset_config();
348 bool srst_asserted
= false;
350 if ((jtag_reset_config
& RESET_HAS_SRST
) &&
351 (jtag_reset_config
& RESET_SRST_NO_GATING
)) {
352 res
= adapter_assert_reset();
353 srst_asserted
= true;
356 adapter
->layout
->api
->write_debug_reg(adapter
->handle
, DCB_DHCSR
, DBGKEY
|C_DEBUGEN
);
358 /* only set vector catch if halt is requested */
359 if (target
->reset_halt
)
360 adapter
->layout
->api
->write_debug_reg(adapter
->handle
, DCB_DEMCR
, TRCENA
|VC_CORERESET
);
362 adapter
->layout
->api
->write_debug_reg(adapter
->handle
, DCB_DEMCR
, TRCENA
);
364 if (jtag_reset_config
& RESET_HAS_SRST
) {
365 if (!srst_asserted
) {
366 res
= adapter_assert_reset();
368 if (res
== ERROR_COMMAND_NOTFOUND
)
369 LOG_ERROR("Hardware srst not supported, falling back to software reset");
370 else if (res
== ERROR_OK
) {
371 /* hardware srst supported */
372 use_srst_fallback
= false;
376 if (use_srst_fallback
) {
377 /* stlink v1 api does not support hardware srst, so we use a software reset fallback */
378 adapter
->layout
->api
->write_debug_reg(adapter
->handle
, NVIC_AIRCR
, AIRCR_VECTKEY
| AIRCR_SYSRESETREQ
);
381 res
= adapter
->layout
->api
->reset(adapter
->handle
);
386 /* registers are now invalid */
387 register_cache_invalidate(armv7m
->arm
.core_cache
);
389 if (target
->reset_halt
) {
390 target
->state
= TARGET_RESET
;
391 target
->debug_reason
= DBG_REASON_DBGRQ
;
393 target
->state
= TARGET_HALTED
;
399 static int hl_deassert_reset(struct target
*target
)
401 enum reset_types jtag_reset_config
= jtag_get_reset_config();
403 LOG_DEBUG("%s", __func__
);
405 if (jtag_reset_config
& RESET_HAS_SRST
)
406 adapter_deassert_reset();
408 target
->SAVED_DCRDR
= 0; /* clear both DCC busy bits on initial resume */
410 return target
->reset_halt
? ERROR_OK
: target_resume(target
, 1, 0, 0, 0);
413 static int adapter_halt(struct target
*target
)
416 struct hl_interface_s
*adapter
= target_to_adapter(target
);
418 LOG_DEBUG("%s", __func__
);
420 if (target
->state
== TARGET_HALTED
) {
421 LOG_DEBUG("target was already halted");
425 if (target
->state
== TARGET_UNKNOWN
)
426 LOG_WARNING("target was in unknown state when halt was requested");
428 res
= adapter
->layout
->api
->halt(adapter
->handle
);
433 target
->debug_reason
= DBG_REASON_DBGRQ
;
438 static int adapter_resume(struct target
*target
, int current
,
439 target_addr_t address
, int handle_breakpoints
,
443 struct hl_interface_s
*adapter
= target_to_adapter(target
);
444 struct armv7m_common
*armv7m
= target_to_armv7m(target
);
446 struct breakpoint
*breakpoint
= NULL
;
449 LOG_DEBUG("%s %d " TARGET_ADDR_FMT
" %d %d", __func__
, current
,
450 address
, handle_breakpoints
, debug_execution
);
452 if (target
->state
!= TARGET_HALTED
) {
453 LOG_WARNING("target not halted");
454 return ERROR_TARGET_NOT_HALTED
;
457 if (!debug_execution
) {
458 target_free_all_working_areas(target
);
459 cortex_m_enable_breakpoints(target
);
460 cortex_m_enable_watchpoints(target
);
465 buf_set_u32(pc
->value
, 0, 32, address
);
470 if (!breakpoint_find(target
, buf_get_u32(pc
->value
, 0, 32))
471 && !debug_execution
) {
472 armv7m_maybe_skip_bkpt_inst(target
, NULL
);
475 resume_pc
= buf_get_u32(pc
->value
, 0, 32);
477 /* write any user vector flags */
478 res
= target_write_u32(target
, DCB_DEMCR
, TRCENA
| armv7m
->demcr
);
482 armv7m_restore_context(target
);
484 /* restore SAVED_DCRDR */
485 res
= target_write_u32(target
, DCB_DCRDR
, target
->SAVED_DCRDR
);
489 /* registers are now invalid */
490 register_cache_invalidate(armv7m
->arm
.core_cache
);
492 /* the front-end may request us not to handle breakpoints */
493 if (handle_breakpoints
) {
494 /* Single step past breakpoint at current address */
495 breakpoint
= breakpoint_find(target
, resume_pc
);
497 LOG_DEBUG("unset breakpoint at " TARGET_ADDR_FMT
" (ID: %" PRIu32
")",
499 breakpoint
->unique_id
);
500 cortex_m_unset_breakpoint(target
, breakpoint
);
502 res
= adapter
->layout
->api
->step(adapter
->handle
);
507 cortex_m_set_breakpoint(target
, breakpoint
);
511 res
= adapter
->layout
->api
->run(adapter
->handle
);
516 target
->debug_reason
= DBG_REASON_NOTHALTED
;
518 if (!debug_execution
) {
519 target
->state
= TARGET_RUNNING
;
520 target_call_event_callbacks(target
, TARGET_EVENT_RESUMED
);
522 target
->state
= TARGET_DEBUG_RUNNING
;
523 target_call_event_callbacks(target
, TARGET_EVENT_DEBUG_RESUMED
);
529 static int adapter_step(struct target
*target
, int current
,
530 target_addr_t address
, int handle_breakpoints
)
533 struct hl_interface_s
*adapter
= target_to_adapter(target
);
534 struct armv7m_common
*armv7m
= target_to_armv7m(target
);
535 struct breakpoint
*breakpoint
= NULL
;
536 struct reg
*pc
= armv7m
->arm
.pc
;
537 bool bkpt_inst_found
= false;
539 LOG_DEBUG("%s", __func__
);
541 if (target
->state
!= TARGET_HALTED
) {
542 LOG_WARNING("target not halted");
543 return ERROR_TARGET_NOT_HALTED
;
547 buf_set_u32(pc
->value
, 0, 32, address
);
552 uint32_t pc_value
= buf_get_u32(pc
->value
, 0, 32);
554 /* the front-end may request us not to handle breakpoints */
555 if (handle_breakpoints
) {
556 breakpoint
= breakpoint_find(target
, pc_value
);
558 cortex_m_unset_breakpoint(target
, breakpoint
);
561 armv7m_maybe_skip_bkpt_inst(target
, &bkpt_inst_found
);
563 target
->debug_reason
= DBG_REASON_SINGLESTEP
;
565 armv7m_restore_context(target
);
567 /* restore SAVED_DCRDR */
568 res
= target_write_u32(target
, DCB_DCRDR
, target
->SAVED_DCRDR
);
572 target_call_event_callbacks(target
, TARGET_EVENT_RESUMED
);
574 res
= adapter
->layout
->api
->step(adapter
->handle
);
579 /* registers are now invalid */
580 register_cache_invalidate(armv7m
->arm
.core_cache
);
583 cortex_m_set_breakpoint(target
, breakpoint
);
585 adapter_debug_entry(target
);
586 target_call_event_callbacks(target
, TARGET_EVENT_HALTED
);
588 LOG_INFO("halted: PC: 0x%08" PRIx32
, buf_get_u32(armv7m
->arm
.pc
->value
, 0, 32));
593 static int adapter_read_memory(struct target
*target
, target_addr_t address
,
594 uint32_t size
, uint32_t count
,
597 struct hl_interface_s
*adapter
= target_to_adapter(target
);
599 if (!count
|| !buffer
)
600 return ERROR_COMMAND_SYNTAX_ERROR
;
602 LOG_DEBUG("%s " TARGET_ADDR_FMT
" %" PRIu32
" %" PRIu32
,
603 __func__
, address
, size
, count
);
605 return adapter
->layout
->api
->read_mem(adapter
->handle
, address
, size
, count
, buffer
);
608 static int adapter_write_memory(struct target
*target
, target_addr_t address
,
609 uint32_t size
, uint32_t count
,
610 const uint8_t *buffer
)
612 struct hl_interface_s
*adapter
= target_to_adapter(target
);
614 if (!count
|| !buffer
)
615 return ERROR_COMMAND_SYNTAX_ERROR
;
617 LOG_DEBUG("%s " TARGET_ADDR_FMT
" %" PRIu32
" %" PRIu32
,
618 __func__
, address
, size
, count
);
620 return adapter
->layout
->api
->write_mem(adapter
->handle
, address
, size
, count
, buffer
);
623 static const struct command_registration adapter_command_handlers
[] = {
625 .chain
= arm_command_handlers
,
628 .chain
= armv7m_trace_command_handlers
,
631 .chain
= rtt_target_command_handlers
,
633 /* START_DEPRECATED_TPIU */
635 .chain
= arm_tpiu_deprecated_command_handlers
,
637 /* END_DEPRECATED_TPIU */
638 COMMAND_REGISTRATION_DONE
641 struct target_type hla_target
= {
642 .name
= "hla_target",
644 .init_target
= adapter_init_target
,
645 .deinit_target
= cortex_m_deinit_target
,
646 .target_create
= adapter_target_create
,
647 .target_jim_configure
= adiv5_jim_configure
,
648 .examine
= cortex_m_examine
,
649 .commands
= adapter_command_handlers
,
651 .poll
= adapter_poll
,
652 .arch_state
= armv7m_arch_state
,
654 .target_request_data
= hl_target_request_data
,
655 .assert_reset
= hl_assert_reset
,
656 .deassert_reset
= hl_deassert_reset
,
658 .halt
= adapter_halt
,
659 .resume
= adapter_resume
,
660 .step
= adapter_step
,
662 .get_gdb_arch
= arm_get_gdb_arch
,
663 .get_gdb_reg_list
= armv7m_get_gdb_reg_list
,
665 .read_memory
= adapter_read_memory
,
666 .write_memory
= adapter_write_memory
,
667 .checksum_memory
= armv7m_checksum_memory
,
668 .blank_check_memory
= armv7m_blank_check_memory
,
670 .run_algorithm
= armv7m_run_algorithm
,
671 .start_algorithm
= armv7m_start_algorithm
,
672 .wait_algorithm
= armv7m_wait_algorithm
,
674 .add_breakpoint
= cortex_m_add_breakpoint
,
675 .remove_breakpoint
= cortex_m_remove_breakpoint
,
676 .add_watchpoint
= cortex_m_add_watchpoint
,
677 .remove_watchpoint
= cortex_m_remove_watchpoint
,
678 .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)