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 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 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
->savedDCRDR
);
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
->savedDCRDR
= 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 savedDCRDR */
485 res
= target_write_u32(target
, DCB_DCRDR
, target
->savedDCRDR
);
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 savedDCRDR */
568 res
= target_write_u32(target
, DCB_DCRDR
, target
->savedDCRDR
);
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
,