1 // SPDX-License-Identifier: GPL-2.0-or-later
3 /***************************************************************************
4 * Copyright (C) 2015 by David Ung *
6 ***************************************************************************/
12 #include "breakpoints.h"
14 #include "a64_disassembler.h"
16 #include "target_request.h"
17 #include "target_type.h"
18 #include "armv8_opcodes.h"
19 #include "armv8_cache.h"
20 #include "arm_coresight.h"
21 #include "arm_semihosting.h"
22 #include "jtag/interface.h"
24 #include <helper/nvp.h>
25 #include <helper/time_support.h>
37 struct aarch64_private_config
{
38 struct adiv5_private_config adiv5_config
;
42 static int aarch64_poll(struct target
*target
);
43 static int aarch64_debug_entry(struct target
*target
);
44 static int aarch64_restore_context(struct target
*target
, bool bpwp
);
45 static int aarch64_set_breakpoint(struct target
*target
,
46 struct breakpoint
*breakpoint
, uint8_t matchmode
);
47 static int aarch64_set_context_breakpoint(struct target
*target
,
48 struct breakpoint
*breakpoint
, uint8_t matchmode
);
49 static int aarch64_set_hybrid_breakpoint(struct target
*target
,
50 struct breakpoint
*breakpoint
);
51 static int aarch64_unset_breakpoint(struct target
*target
,
52 struct breakpoint
*breakpoint
);
53 static int aarch64_mmu(struct target
*target
, int *enabled
);
54 static int aarch64_virt2phys(struct target
*target
,
55 target_addr_t virt
, target_addr_t
*phys
);
56 static int aarch64_read_cpu_memory(struct target
*target
,
57 uint64_t address
, uint32_t size
, uint32_t count
, uint8_t *buffer
);
59 static int aarch64_restore_system_control_reg(struct target
*target
)
61 enum arm_mode target_mode
= ARM_MODE_ANY
;
62 int retval
= ERROR_OK
;
65 struct aarch64_common
*aarch64
= target_to_aarch64(target
);
66 struct armv8_common
*armv8
= target_to_armv8(target
);
68 if (aarch64
->system_control_reg
!= aarch64
->system_control_reg_curr
) {
69 aarch64
->system_control_reg_curr
= aarch64
->system_control_reg
;
70 /* LOG_INFO("cp15_control_reg: %8.8" PRIx32, cortex_v8->cp15_control_reg); */
72 switch (armv8
->arm
.core_mode
) {
74 target_mode
= ARMV8_64_EL1H
;
78 instr
= ARMV8_MSR_GP(SYSTEM_SCTLR_EL1
, 0);
82 instr
= ARMV8_MSR_GP(SYSTEM_SCTLR_EL2
, 0);
86 instr
= ARMV8_MSR_GP(SYSTEM_SCTLR_EL3
, 0);
97 instr
= ARMV4_5_MCR(15, 0, 0, 1, 0, 0);
101 LOG_ERROR("cannot read system control register in this mode: (%s : 0x%x)",
102 armv8_mode_name(armv8
->arm
.core_mode
), armv8
->arm
.core_mode
);
106 if (target_mode
!= ARM_MODE_ANY
)
107 armv8_dpm_modeswitch(&armv8
->dpm
, target_mode
);
109 retval
= armv8
->dpm
.instr_write_data_r0_64(&armv8
->dpm
, instr
, aarch64
->system_control_reg
);
110 if (retval
!= ERROR_OK
)
113 if (target_mode
!= ARM_MODE_ANY
)
114 armv8_dpm_modeswitch(&armv8
->dpm
, ARM_MODE_ANY
);
120 /* modify system_control_reg in order to enable or disable mmu for :
121 * - virt2phys address conversion
122 * - read or write memory in phys or virt address */
123 static int aarch64_mmu_modify(struct target
*target
, int enable
)
125 struct aarch64_common
*aarch64
= target_to_aarch64(target
);
126 struct armv8_common
*armv8
= &aarch64
->armv8_common
;
127 int retval
= ERROR_OK
;
128 enum arm_mode target_mode
= ARM_MODE_ANY
;
132 /* if mmu enabled at target stop and mmu not enable */
133 if (!(aarch64
->system_control_reg
& 0x1U
)) {
134 LOG_ERROR("trying to enable mmu on target stopped with mmu disable");
137 if (!(aarch64
->system_control_reg_curr
& 0x1U
))
138 aarch64
->system_control_reg_curr
|= 0x1U
;
140 if (aarch64
->system_control_reg_curr
& 0x4U
) {
141 /* data cache is active */
142 aarch64
->system_control_reg_curr
&= ~0x4U
;
143 /* flush data cache armv8 function to be called */
144 if (armv8
->armv8_mmu
.armv8_cache
.flush_all_data_cache
)
145 armv8
->armv8_mmu
.armv8_cache
.flush_all_data_cache(target
);
147 if ((aarch64
->system_control_reg_curr
& 0x1U
)) {
148 aarch64
->system_control_reg_curr
&= ~0x1U
;
152 switch (armv8
->arm
.core_mode
) {
154 target_mode
= ARMV8_64_EL1H
;
158 instr
= ARMV8_MSR_GP(SYSTEM_SCTLR_EL1
, 0);
162 instr
= ARMV8_MSR_GP(SYSTEM_SCTLR_EL2
, 0);
166 instr
= ARMV8_MSR_GP(SYSTEM_SCTLR_EL3
, 0);
177 instr
= ARMV4_5_MCR(15, 0, 0, 1, 0, 0);
181 LOG_DEBUG("unknown cpu state 0x%x", armv8
->arm
.core_mode
);
184 if (target_mode
!= ARM_MODE_ANY
)
185 armv8_dpm_modeswitch(&armv8
->dpm
, target_mode
);
187 retval
= armv8
->dpm
.instr_write_data_r0_64(&armv8
->dpm
, instr
,
188 aarch64
->system_control_reg_curr
);
190 if (target_mode
!= ARM_MODE_ANY
)
191 armv8_dpm_modeswitch(&armv8
->dpm
, ARM_MODE_ANY
);
197 * Basic debug access, very low level assumes state is saved
199 static int aarch64_init_debug_access(struct target
*target
)
201 struct armv8_common
*armv8
= target_to_armv8(target
);
205 LOG_DEBUG("%s", target_name(target
));
207 retval
= mem_ap_write_atomic_u32(armv8
->debug_ap
,
208 armv8
->debug_base
+ CPUV8_DBG_OSLAR
, 0);
209 if (retval
!= ERROR_OK
) {
210 LOG_DEBUG("Examine %s failed", "oslock");
214 /* Clear Sticky Power Down status Bit in PRSR to enable access to
215 the registers in the Core Power Domain */
216 retval
= mem_ap_read_atomic_u32(armv8
->debug_ap
,
217 armv8
->debug_base
+ CPUV8_DBG_PRSR
, &dummy
);
218 if (retval
!= ERROR_OK
)
222 * Static CTI configuration:
223 * Channel 0 -> trigger outputs HALT request to PE
224 * Channel 1 -> trigger outputs Resume request to PE
225 * Gate all channel trigger events from entering the CTM
229 retval
= arm_cti_enable(armv8
->cti
, true);
230 /* By default, gate all channel events to and from the CTM */
231 if (retval
== ERROR_OK
)
232 retval
= arm_cti_write_reg(armv8
->cti
, CTI_GATE
, 0);
233 /* output halt requests to PE on channel 0 event */
234 if (retval
== ERROR_OK
)
235 retval
= arm_cti_write_reg(armv8
->cti
, CTI_OUTEN0
, CTI_CHNL(0));
236 /* output restart requests to PE on channel 1 event */
237 if (retval
== ERROR_OK
)
238 retval
= arm_cti_write_reg(armv8
->cti
, CTI_OUTEN1
, CTI_CHNL(1));
239 if (retval
!= ERROR_OK
)
242 /* Resync breakpoint registers */
247 /* Write to memory mapped registers directly with no cache or mmu handling */
248 static int aarch64_dap_write_memap_register_u32(struct target
*target
,
249 target_addr_t address
,
253 struct armv8_common
*armv8
= target_to_armv8(target
);
255 retval
= mem_ap_write_atomic_u32(armv8
->debug_ap
, address
, value
);
260 static int aarch64_dpm_setup(struct aarch64_common
*a8
, uint64_t debug
)
262 struct arm_dpm
*dpm
= &a8
->armv8_common
.dpm
;
265 dpm
->arm
= &a8
->armv8_common
.arm
;
268 retval
= armv8_dpm_setup(dpm
);
269 if (retval
== ERROR_OK
)
270 retval
= armv8_dpm_initialize(dpm
);
275 static int aarch64_set_dscr_bits(struct target
*target
, unsigned long bit_mask
, unsigned long value
)
277 struct armv8_common
*armv8
= target_to_armv8(target
);
278 return armv8_set_dbgreg_bits(armv8
, CPUV8_DBG_DSCR
, bit_mask
, value
);
281 static int aarch64_check_state_one(struct target
*target
,
282 uint32_t mask
, uint32_t val
, int *p_result
, uint32_t *p_prsr
)
284 struct armv8_common
*armv8
= target_to_armv8(target
);
288 retval
= mem_ap_read_atomic_u32(armv8
->debug_ap
,
289 armv8
->debug_base
+ CPUV8_DBG_PRSR
, &prsr
);
290 if (retval
!= ERROR_OK
)
297 *p_result
= (prsr
& mask
) == (val
& mask
);
302 static int aarch64_wait_halt_one(struct target
*target
)
304 int retval
= ERROR_OK
;
307 int64_t then
= timeval_ms();
311 retval
= aarch64_check_state_one(target
, PRSR_HALT
, PRSR_HALT
, &halted
, &prsr
);
312 if (retval
!= ERROR_OK
|| halted
)
315 if (timeval_ms() > then
+ 1000) {
316 retval
= ERROR_TARGET_TIMEOUT
;
317 LOG_DEBUG("target %s timeout, prsr=0x%08"PRIx32
, target_name(target
), prsr
);
324 static int aarch64_prepare_halt_smp(struct target
*target
, bool exc_target
, struct target
**p_first
)
326 int retval
= ERROR_OK
;
327 struct target_list
*head
;
328 struct target
*first
= NULL
;
330 LOG_DEBUG("target %s exc %i", target_name(target
), exc_target
);
332 foreach_smp_target(head
, target
->smp_targets
) {
333 struct target
*curr
= head
->target
;
334 struct armv8_common
*armv8
= target_to_armv8(curr
);
336 if (exc_target
&& curr
== target
)
338 if (!target_was_examined(curr
))
340 if (curr
->state
!= TARGET_RUNNING
)
343 /* HACK: mark this target as prepared for halting */
344 curr
->debug_reason
= DBG_REASON_DBGRQ
;
346 /* open the gate for channel 0 to let HALT requests pass to the CTM */
347 retval
= arm_cti_ungate_channel(armv8
->cti
, 0);
348 if (retval
== ERROR_OK
)
349 retval
= aarch64_set_dscr_bits(curr
, DSCR_HDE
, DSCR_HDE
);
350 if (retval
!= ERROR_OK
)
353 LOG_DEBUG("target %s prepared", target_name(curr
));
360 if (exc_target
&& first
)
369 static int aarch64_halt_one(struct target
*target
, enum halt_mode mode
)
371 int retval
= ERROR_OK
;
372 struct armv8_common
*armv8
= target_to_armv8(target
);
374 LOG_DEBUG("%s", target_name(target
));
376 /* allow Halting Debug Mode */
377 retval
= aarch64_set_dscr_bits(target
, DSCR_HDE
, DSCR_HDE
);
378 if (retval
!= ERROR_OK
)
381 /* trigger an event on channel 0, this outputs a halt request to the PE */
382 retval
= arm_cti_pulse_channel(armv8
->cti
, 0);
383 if (retval
!= ERROR_OK
)
386 if (mode
== HALT_SYNC
) {
387 retval
= aarch64_wait_halt_one(target
);
388 if (retval
!= ERROR_OK
) {
389 if (retval
== ERROR_TARGET_TIMEOUT
)
390 LOG_ERROR("Timeout waiting for target %s halt", target_name(target
));
398 static int aarch64_halt_smp(struct target
*target
, bool exc_target
)
400 struct target
*next
= target
;
403 /* prepare halt on all PEs of the group */
404 retval
= aarch64_prepare_halt_smp(target
, exc_target
, &next
);
406 if (exc_target
&& next
== target
)
409 /* halt the target PE */
410 if (retval
== ERROR_OK
)
411 retval
= aarch64_halt_one(next
, HALT_LAZY
);
413 if (retval
!= ERROR_OK
)
416 /* wait for all PEs to halt */
417 int64_t then
= timeval_ms();
419 bool all_halted
= true;
420 struct target_list
*head
;
423 foreach_smp_target(head
, target
->smp_targets
) {
428 if (!target_was_examined(curr
))
431 retval
= aarch64_check_state_one(curr
, PRSR_HALT
, PRSR_HALT
, &halted
, NULL
);
432 if (retval
!= ERROR_OK
|| !halted
) {
441 if (timeval_ms() > then
+ 1000) {
442 retval
= ERROR_TARGET_TIMEOUT
;
447 * HACK: on Hi6220 there are 8 cores organized in 2 clusters
448 * and it looks like the CTI's are not connected by a common
449 * trigger matrix. It seems that we need to halt one core in each
450 * cluster explicitly. So if we find that a core has not halted
451 * yet, we trigger an explicit halt for the second cluster.
453 retval
= aarch64_halt_one(curr
, HALT_LAZY
);
454 if (retval
!= ERROR_OK
)
461 static int update_halt_gdb(struct target
*target
, enum target_debug_reason debug_reason
)
463 struct target
*gdb_target
= NULL
;
464 struct target_list
*head
;
467 if (debug_reason
== DBG_REASON_NOTHALTED
) {
468 LOG_DEBUG("Halting remaining targets in SMP group");
469 aarch64_halt_smp(target
, true);
472 /* poll all targets in the group, but skip the target that serves GDB */
473 foreach_smp_target(head
, target
->smp_targets
) {
475 /* skip calling context */
478 if (!target_was_examined(curr
))
480 /* skip targets that were already halted */
481 if (curr
->state
== TARGET_HALTED
)
483 /* remember the gdb_service->target */
484 if (curr
->gdb_service
)
485 gdb_target
= curr
->gdb_service
->target
;
487 if (curr
== gdb_target
)
490 /* avoid recursion in aarch64_poll() */
496 /* after all targets were updated, poll the gdb serving target */
497 if (gdb_target
&& gdb_target
!= target
)
498 aarch64_poll(gdb_target
);
504 * Aarch64 Run control
507 static int aarch64_poll(struct target
*target
)
509 enum target_state prev_target_state
;
510 int retval
= ERROR_OK
;
513 retval
= aarch64_check_state_one(target
,
514 PRSR_HALT
, PRSR_HALT
, &halted
, NULL
);
515 if (retval
!= ERROR_OK
)
519 prev_target_state
= target
->state
;
520 if (prev_target_state
!= TARGET_HALTED
) {
521 enum target_debug_reason debug_reason
= target
->debug_reason
;
523 /* We have a halting debug event */
524 target
->state
= TARGET_HALTED
;
525 LOG_DEBUG("Target %s halted", target_name(target
));
526 retval
= aarch64_debug_entry(target
);
527 if (retval
!= ERROR_OK
)
531 update_halt_gdb(target
, debug_reason
);
533 if (arm_semihosting(target
, &retval
) != 0)
536 switch (prev_target_state
) {
540 target_call_event_callbacks(target
, TARGET_EVENT_HALTED
);
542 case TARGET_DEBUG_RUNNING
:
543 target_call_event_callbacks(target
, TARGET_EVENT_DEBUG_HALTED
);
550 target
->state
= TARGET_RUNNING
;
555 static int aarch64_halt(struct target
*target
)
557 struct armv8_common
*armv8
= target_to_armv8(target
);
558 armv8
->last_run_control_op
= ARMV8_RUNCONTROL_HALT
;
561 return aarch64_halt_smp(target
, false);
563 return aarch64_halt_one(target
, HALT_SYNC
);
566 static int aarch64_restore_one(struct target
*target
, int current
,
567 uint64_t *address
, int handle_breakpoints
, int debug_execution
)
569 struct armv8_common
*armv8
= target_to_armv8(target
);
570 struct arm
*arm
= &armv8
->arm
;
574 LOG_DEBUG("%s", target_name(target
));
576 if (!debug_execution
)
577 target_free_all_working_areas(target
);
579 /* current = 1: continue on current pc, otherwise continue at <address> */
580 resume_pc
= buf_get_u64(arm
->pc
->value
, 0, 64);
582 resume_pc
= *address
;
584 *address
= resume_pc
;
586 /* Make sure that the Armv7 gdb thumb fixups does not
587 * kill the return address
589 switch (arm
->core_state
) {
591 resume_pc
&= 0xFFFFFFFC;
593 case ARM_STATE_AARCH64
:
594 resume_pc
&= 0xFFFFFFFFFFFFFFFCULL
;
596 case ARM_STATE_THUMB
:
597 case ARM_STATE_THUMB_EE
:
598 /* When the return address is loaded into PC
599 * bit 0 must be 1 to stay in Thumb state
603 case ARM_STATE_JAZELLE
:
604 LOG_ERROR("How do I resume into Jazelle state??");
607 LOG_DEBUG("resume pc = 0x%016" PRIx64
, resume_pc
);
608 buf_set_u64(arm
->pc
->value
, 0, 64, resume_pc
);
609 arm
->pc
->dirty
= true;
610 arm
->pc
->valid
= true;
612 /* called it now before restoring context because it uses cpu
613 * register r0 for restoring system control register */
614 retval
= aarch64_restore_system_control_reg(target
);
615 if (retval
== ERROR_OK
)
616 retval
= aarch64_restore_context(target
, handle_breakpoints
);
622 * prepare single target for restart
626 static int aarch64_prepare_restart_one(struct target
*target
)
628 struct armv8_common
*armv8
= target_to_armv8(target
);
633 LOG_DEBUG("%s", target_name(target
));
635 retval
= mem_ap_read_atomic_u32(armv8
->debug_ap
,
636 armv8
->debug_base
+ CPUV8_DBG_DSCR
, &dscr
);
637 if (retval
!= ERROR_OK
)
640 if ((dscr
& DSCR_ITE
) == 0)
641 LOG_ERROR("DSCR.ITE must be set before leaving debug!");
642 if ((dscr
& DSCR_ERR
) != 0)
643 LOG_ERROR("DSCR.ERR must be cleared before leaving debug!");
645 /* acknowledge a pending CTI halt event */
646 retval
= arm_cti_ack_events(armv8
->cti
, CTI_TRIG(HALT
));
648 * open the CTI gate for channel 1 so that the restart events
649 * get passed along to all PEs. Also close gate for channel 0
650 * to isolate the PE from halt events.
652 if (retval
== ERROR_OK
)
653 retval
= arm_cti_ungate_channel(armv8
->cti
, 1);
654 if (retval
== ERROR_OK
)
655 retval
= arm_cti_gate_channel(armv8
->cti
, 0);
657 /* make sure that DSCR.HDE is set */
658 if (retval
== ERROR_OK
) {
660 retval
= mem_ap_write_atomic_u32(armv8
->debug_ap
,
661 armv8
->debug_base
+ CPUV8_DBG_DSCR
, dscr
);
664 if (retval
== ERROR_OK
) {
665 /* clear sticky bits in PRSR, SDR is now 0 */
666 retval
= mem_ap_read_atomic_u32(armv8
->debug_ap
,
667 armv8
->debug_base
+ CPUV8_DBG_PRSR
, &tmp
);
673 static int aarch64_do_restart_one(struct target
*target
, enum restart_mode mode
)
675 struct armv8_common
*armv8
= target_to_armv8(target
);
678 LOG_DEBUG("%s", target_name(target
));
680 /* trigger an event on channel 1, generates a restart request to the PE */
681 retval
= arm_cti_pulse_channel(armv8
->cti
, 1);
682 if (retval
!= ERROR_OK
)
685 if (mode
== RESTART_SYNC
) {
686 int64_t then
= timeval_ms();
690 * if PRSR.SDR is set now, the target did restart, even
691 * if it's now already halted again (e.g. due to breakpoint)
693 retval
= aarch64_check_state_one(target
,
694 PRSR_SDR
, PRSR_SDR
, &resumed
, NULL
);
695 if (retval
!= ERROR_OK
|| resumed
)
698 if (timeval_ms() > then
+ 1000) {
699 LOG_ERROR("%s: Timeout waiting for resume"PRIx32
, target_name(target
));
700 retval
= ERROR_TARGET_TIMEOUT
;
706 if (retval
!= ERROR_OK
)
709 target
->debug_reason
= DBG_REASON_NOTHALTED
;
710 target
->state
= TARGET_RUNNING
;
715 static int aarch64_restart_one(struct target
*target
, enum restart_mode mode
)
719 LOG_DEBUG("%s", target_name(target
));
721 retval
= aarch64_prepare_restart_one(target
);
722 if (retval
== ERROR_OK
)
723 retval
= aarch64_do_restart_one(target
, mode
);
729 * prepare all but the current target for restart
731 static int aarch64_prep_restart_smp(struct target
*target
, int handle_breakpoints
, struct target
**p_first
)
733 int retval
= ERROR_OK
;
734 struct target_list
*head
;
735 struct target
*first
= NULL
;
738 foreach_smp_target(head
, target
->smp_targets
) {
739 struct target
*curr
= head
->target
;
741 /* skip calling target */
744 if (!target_was_examined(curr
))
746 if (curr
->state
!= TARGET_HALTED
)
749 /* resume at current address, not in step mode */
750 retval
= aarch64_restore_one(curr
, 1, &address
, handle_breakpoints
, 0);
751 if (retval
== ERROR_OK
)
752 retval
= aarch64_prepare_restart_one(curr
);
753 if (retval
!= ERROR_OK
) {
754 LOG_ERROR("failed to restore target %s", target_name(curr
));
757 /* remember the first valid target in the group */
769 static int aarch64_step_restart_smp(struct target
*target
)
771 int retval
= ERROR_OK
;
772 struct target_list
*head
;
773 struct target
*first
= NULL
;
775 LOG_DEBUG("%s", target_name(target
));
777 retval
= aarch64_prep_restart_smp(target
, 0, &first
);
778 if (retval
!= ERROR_OK
)
782 retval
= aarch64_do_restart_one(first
, RESTART_LAZY
);
783 if (retval
!= ERROR_OK
) {
784 LOG_DEBUG("error restarting target %s", target_name(first
));
788 int64_t then
= timeval_ms();
790 struct target
*curr
= target
;
791 bool all_resumed
= true;
793 foreach_smp_target(head
, target
->smp_targets
) {
802 if (!target_was_examined(curr
))
805 retval
= aarch64_check_state_one(curr
,
806 PRSR_SDR
, PRSR_SDR
, &resumed
, &prsr
);
807 if (retval
!= ERROR_OK
|| (!resumed
&& (prsr
& PRSR_HALT
))) {
812 if (curr
->state
!= TARGET_RUNNING
) {
813 curr
->state
= TARGET_RUNNING
;
814 curr
->debug_reason
= DBG_REASON_NOTHALTED
;
815 target_call_event_callbacks(curr
, TARGET_EVENT_RESUMED
);
822 if (timeval_ms() > then
+ 1000) {
823 LOG_ERROR("%s: timeout waiting for target resume", __func__
);
824 retval
= ERROR_TARGET_TIMEOUT
;
828 * HACK: on Hi6220 there are 8 cores organized in 2 clusters
829 * and it looks like the CTI's are not connected by a common
830 * trigger matrix. It seems that we need to halt one core in each
831 * cluster explicitly. So if we find that a core has not halted
832 * yet, we trigger an explicit resume for the second cluster.
834 retval
= aarch64_do_restart_one(curr
, RESTART_LAZY
);
835 if (retval
!= ERROR_OK
)
842 static int aarch64_resume(struct target
*target
, int current
,
843 target_addr_t address
, int handle_breakpoints
, int debug_execution
)
846 uint64_t addr
= address
;
848 struct armv8_common
*armv8
= target_to_armv8(target
);
849 armv8
->last_run_control_op
= ARMV8_RUNCONTROL_RESUME
;
851 if (target
->state
!= TARGET_HALTED
) {
852 LOG_TARGET_ERROR(target
, "not halted");
853 return ERROR_TARGET_NOT_HALTED
;
857 * If this target is part of a SMP group, prepare the others
858 * targets for resuming. This involves restoring the complete
859 * target register context and setting up CTI gates to accept
860 * resume events from the trigger matrix.
863 retval
= aarch64_prep_restart_smp(target
, handle_breakpoints
, NULL
);
864 if (retval
!= ERROR_OK
)
868 /* all targets prepared, restore and restart the current target */
869 retval
= aarch64_restore_one(target
, current
, &addr
, handle_breakpoints
,
871 if (retval
== ERROR_OK
)
872 retval
= aarch64_restart_one(target
, RESTART_SYNC
);
873 if (retval
!= ERROR_OK
)
877 int64_t then
= timeval_ms();
879 struct target
*curr
= target
;
880 struct target_list
*head
;
881 bool all_resumed
= true;
883 foreach_smp_target(head
, target
->smp_targets
) {
890 if (!target_was_examined(curr
))
893 retval
= aarch64_check_state_one(curr
,
894 PRSR_SDR
, PRSR_SDR
, &resumed
, &prsr
);
895 if (retval
!= ERROR_OK
|| (!resumed
&& (prsr
& PRSR_HALT
))) {
900 if (curr
->state
!= TARGET_RUNNING
) {
901 curr
->state
= TARGET_RUNNING
;
902 curr
->debug_reason
= DBG_REASON_NOTHALTED
;
903 target_call_event_callbacks(curr
, TARGET_EVENT_RESUMED
);
910 if (timeval_ms() > then
+ 1000) {
911 LOG_ERROR("%s: timeout waiting for target %s to resume", __func__
, target_name(curr
));
912 retval
= ERROR_TARGET_TIMEOUT
;
917 * HACK: on Hi6220 there are 8 cores organized in 2 clusters
918 * and it looks like the CTI's are not connected by a common
919 * trigger matrix. It seems that we need to halt one core in each
920 * cluster explicitly. So if we find that a core has not halted
921 * yet, we trigger an explicit resume for the second cluster.
923 retval
= aarch64_do_restart_one(curr
, RESTART_LAZY
);
924 if (retval
!= ERROR_OK
)
929 if (retval
!= ERROR_OK
)
932 target
->debug_reason
= DBG_REASON_NOTHALTED
;
934 if (!debug_execution
) {
935 target
->state
= TARGET_RUNNING
;
936 target_call_event_callbacks(target
, TARGET_EVENT_RESUMED
);
937 LOG_DEBUG("target resumed at 0x%" PRIx64
, addr
);
939 target
->state
= TARGET_DEBUG_RUNNING
;
940 target_call_event_callbacks(target
, TARGET_EVENT_DEBUG_RESUMED
);
941 LOG_DEBUG("target debug resumed at 0x%" PRIx64
, addr
);
947 static int aarch64_debug_entry(struct target
*target
)
949 int retval
= ERROR_OK
;
950 struct armv8_common
*armv8
= target_to_armv8(target
);
951 struct arm_dpm
*dpm
= &armv8
->dpm
;
952 enum arm_state core_state
;
955 /* make sure to clear all sticky errors */
956 retval
= mem_ap_write_atomic_u32(armv8
->debug_ap
,
957 armv8
->debug_base
+ CPUV8_DBG_DRCR
, DRCR_CSE
);
958 if (retval
== ERROR_OK
)
959 retval
= mem_ap_read_atomic_u32(armv8
->debug_ap
,
960 armv8
->debug_base
+ CPUV8_DBG_DSCR
, &dscr
);
961 if (retval
== ERROR_OK
)
962 retval
= arm_cti_ack_events(armv8
->cti
, CTI_TRIG(HALT
));
964 if (retval
!= ERROR_OK
)
967 LOG_DEBUG("%s dscr = 0x%08" PRIx32
, target_name(target
), dscr
);
970 core_state
= armv8_dpm_get_core_state(dpm
);
971 armv8_select_opcodes(armv8
, core_state
== ARM_STATE_AARCH64
);
972 armv8_select_reg_access(armv8
, core_state
== ARM_STATE_AARCH64
);
974 /* close the CTI gate for all events */
975 if (retval
== ERROR_OK
)
976 retval
= arm_cti_write_reg(armv8
->cti
, CTI_GATE
, 0);
977 /* discard async exceptions */
978 if (retval
== ERROR_OK
)
979 retval
= dpm
->instr_cpsr_sync(dpm
);
980 if (retval
!= ERROR_OK
)
983 /* Examine debug reason */
984 armv8_dpm_report_dscr(dpm
, dscr
);
986 /* save the memory address that triggered the watchpoint */
987 if (target
->debug_reason
== DBG_REASON_WATCHPOINT
) {
990 retval
= mem_ap_read_atomic_u32(armv8
->debug_ap
,
991 armv8
->debug_base
+ CPUV8_DBG_EDWAR0
, &tmp
);
992 if (retval
!= ERROR_OK
)
994 target_addr_t edwar
= tmp
;
996 /* EDWAR[63:32] has unknown content in aarch32 state */
997 if (core_state
== ARM_STATE_AARCH64
) {
998 retval
= mem_ap_read_atomic_u32(armv8
->debug_ap
,
999 armv8
->debug_base
+ CPUV8_DBG_EDWAR1
, &tmp
);
1000 if (retval
!= ERROR_OK
)
1002 edwar
|= ((target_addr_t
)tmp
) << 32;
1005 armv8
->dpm
.wp_addr
= edwar
;
1008 retval
= armv8_dpm_read_current_registers(&armv8
->dpm
);
1010 if (retval
== ERROR_OK
&& armv8
->post_debug_entry
)
1011 retval
= armv8
->post_debug_entry(target
);
1016 static int aarch64_post_debug_entry(struct target
*target
)
1018 struct aarch64_common
*aarch64
= target_to_aarch64(target
);
1019 struct armv8_common
*armv8
= &aarch64
->armv8_common
;
1021 enum arm_mode target_mode
= ARM_MODE_ANY
;
1024 switch (armv8
->arm
.core_mode
) {
1026 target_mode
= ARMV8_64_EL1H
;
1030 instr
= ARMV8_MRS(SYSTEM_SCTLR_EL1
, 0);
1034 instr
= ARMV8_MRS(SYSTEM_SCTLR_EL2
, 0);
1038 instr
= ARMV8_MRS(SYSTEM_SCTLR_EL3
, 0);
1049 instr
= ARMV4_5_MRC(15, 0, 0, 1, 0, 0);
1053 LOG_ERROR("cannot read system control register in this mode: (%s : 0x%x)",
1054 armv8_mode_name(armv8
->arm
.core_mode
), armv8
->arm
.core_mode
);
1058 if (target_mode
!= ARM_MODE_ANY
)
1059 armv8_dpm_modeswitch(&armv8
->dpm
, target_mode
);
1061 retval
= armv8
->dpm
.instr_read_data_r0_64(&armv8
->dpm
, instr
, &aarch64
->system_control_reg
);
1062 if (retval
!= ERROR_OK
)
1065 if (target_mode
!= ARM_MODE_ANY
)
1066 armv8_dpm_modeswitch(&armv8
->dpm
, ARM_MODE_ANY
);
1068 LOG_DEBUG("System_register: %8.8" PRIx64
, aarch64
->system_control_reg
);
1069 aarch64
->system_control_reg_curr
= aarch64
->system_control_reg
;
1071 if (armv8
->armv8_mmu
.armv8_cache
.info
== -1) {
1072 armv8_identify_cache(armv8
);
1073 armv8_read_mpidr(armv8
);
1075 if (armv8
->is_armv8r
) {
1076 armv8
->armv8_mmu
.mmu_enabled
= 0;
1078 armv8
->armv8_mmu
.mmu_enabled
=
1079 (aarch64
->system_control_reg
& 0x1U
) ? 1 : 0;
1081 armv8
->armv8_mmu
.armv8_cache
.d_u_cache_enabled
=
1082 (aarch64
->system_control_reg
& 0x4U
) ? 1 : 0;
1083 armv8
->armv8_mmu
.armv8_cache
.i_cache_enabled
=
1084 (aarch64
->system_control_reg
& 0x1000U
) ? 1 : 0;
1089 * single-step a target
1091 static int aarch64_step(struct target
*target
, int current
, target_addr_t address
,
1092 int handle_breakpoints
)
1094 struct armv8_common
*armv8
= target_to_armv8(target
);
1095 struct aarch64_common
*aarch64
= target_to_aarch64(target
);
1096 int saved_retval
= ERROR_OK
;
1101 armv8
->last_run_control_op
= ARMV8_RUNCONTROL_STEP
;
1103 if (target
->state
!= TARGET_HALTED
) {
1104 LOG_TARGET_ERROR(target
, "not halted");
1105 return ERROR_TARGET_NOT_HALTED
;
1108 retval
= mem_ap_read_atomic_u32(armv8
->debug_ap
,
1109 armv8
->debug_base
+ CPUV8_DBG_EDECR
, &edecr
);
1110 /* make sure EDECR.SS is not set when restoring the register */
1112 if (retval
== ERROR_OK
) {
1114 /* set EDECR.SS to enter hardware step mode */
1115 retval
= mem_ap_write_atomic_u32(armv8
->debug_ap
,
1116 armv8
->debug_base
+ CPUV8_DBG_EDECR
, (edecr
|0x4));
1118 /* disable interrupts while stepping */
1119 if (retval
== ERROR_OK
&& aarch64
->isrmasking_mode
== AARCH64_ISRMASK_ON
)
1120 retval
= aarch64_set_dscr_bits(target
, 0x3 << 22, 0x3 << 22);
1121 /* bail out if stepping setup has failed */
1122 if (retval
!= ERROR_OK
)
1125 if (target
->smp
&& (current
== 1)) {
1127 * isolate current target so that it doesn't get resumed
1128 * together with the others
1130 retval
= arm_cti_gate_channel(armv8
->cti
, 1);
1131 /* resume all other targets in the group */
1132 if (retval
== ERROR_OK
)
1133 retval
= aarch64_step_restart_smp(target
);
1134 if (retval
!= ERROR_OK
) {
1135 LOG_ERROR("Failed to restart non-stepping targets in SMP group");
1138 LOG_DEBUG("Restarted all non-stepping targets in SMP group");
1141 /* all other targets running, restore and restart the current target */
1142 retval
= aarch64_restore_one(target
, current
, &address
, 0, 0);
1143 if (retval
== ERROR_OK
)
1144 retval
= aarch64_restart_one(target
, RESTART_LAZY
);
1146 if (retval
!= ERROR_OK
)
1149 LOG_DEBUG("target step-resumed at 0x%" PRIx64
, address
);
1150 if (!handle_breakpoints
)
1151 target_call_event_callbacks(target
, TARGET_EVENT_RESUMED
);
1153 int64_t then
= timeval_ms();
1158 retval
= aarch64_check_state_one(target
,
1159 PRSR_SDR
|PRSR_HALT
, PRSR_SDR
|PRSR_HALT
, &stepped
, &prsr
);
1160 if (retval
!= ERROR_OK
|| stepped
)
1163 if (timeval_ms() > then
+ 100) {
1164 LOG_ERROR("timeout waiting for target %s halt after step",
1165 target_name(target
));
1166 retval
= ERROR_TARGET_TIMEOUT
;
1172 * At least on one SoC (Renesas R8A7795) stepping over a WFI instruction
1173 * causes a timeout. The core takes the step but doesn't complete it and so
1174 * debug state is never entered. However, you can manually halt the core
1175 * as an external debug even is also a WFI wakeup event.
1177 if (retval
== ERROR_TARGET_TIMEOUT
)
1178 saved_retval
= aarch64_halt_one(target
, HALT_SYNC
);
1180 poll_retval
= aarch64_poll(target
);
1183 retval
= mem_ap_write_atomic_u32(armv8
->debug_ap
,
1184 armv8
->debug_base
+ CPUV8_DBG_EDECR
, edecr
);
1185 if (retval
!= ERROR_OK
)
1188 /* restore interrupts */
1189 if (aarch64
->isrmasking_mode
== AARCH64_ISRMASK_ON
) {
1190 retval
= aarch64_set_dscr_bits(target
, 0x3 << 22, 0);
1191 if (retval
!= ERROR_OK
)
1195 if (saved_retval
!= ERROR_OK
)
1196 return saved_retval
;
1198 if (poll_retval
!= ERROR_OK
)
1204 static int aarch64_restore_context(struct target
*target
, bool bpwp
)
1206 struct armv8_common
*armv8
= target_to_armv8(target
);
1207 struct arm
*arm
= &armv8
->arm
;
1211 LOG_DEBUG("%s", target_name(target
));
1213 if (armv8
->pre_restore_context
)
1214 armv8
->pre_restore_context(target
);
1216 retval
= armv8_dpm_write_dirty_registers(&armv8
->dpm
, bpwp
);
1217 if (retval
== ERROR_OK
) {
1218 /* registers are now invalid */
1219 register_cache_invalidate(arm
->core_cache
);
1220 register_cache_invalidate(arm
->core_cache
->next
);
1227 * Cortex-A8 Breakpoint and watchpoint functions
1230 /* Setup hardware Breakpoint Register Pair */
1231 static int aarch64_set_breakpoint(struct target
*target
,
1232 struct breakpoint
*breakpoint
, uint8_t matchmode
)
1237 uint8_t byte_addr_select
= 0x0F;
1238 struct aarch64_common
*aarch64
= target_to_aarch64(target
);
1239 struct armv8_common
*armv8
= &aarch64
->armv8_common
;
1240 struct aarch64_brp
*brp_list
= aarch64
->brp_list
;
1242 if (breakpoint
->is_set
) {
1243 LOG_WARNING("breakpoint already set");
1247 if (breakpoint
->type
== BKPT_HARD
) {
1249 while (brp_list
[brp_i
].used
&& (brp_i
< aarch64
->brp_num
))
1251 if (brp_i
>= aarch64
->brp_num
) {
1252 LOG_ERROR("ERROR Can not find free Breakpoint Register Pair");
1253 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1255 breakpoint_hw_set(breakpoint
, brp_i
);
1256 if (breakpoint
->length
== 2)
1257 byte_addr_select
= (3 << (breakpoint
->address
& 0x02));
1258 control
= ((matchmode
& 0x7) << 20)
1260 | (byte_addr_select
<< 5)
1262 brp_list
[brp_i
].used
= 1;
1263 brp_list
[brp_i
].value
= breakpoint
->address
& 0xFFFFFFFFFFFFFFFCULL
;
1264 brp_list
[brp_i
].control
= control
;
1265 bpt_value
= brp_list
[brp_i
].value
;
1267 retval
= aarch64_dap_write_memap_register_u32(target
, armv8
->debug_base
1268 + CPUV8_DBG_BVR_BASE
+ 16 * brp_list
[brp_i
].brpn
,
1269 (uint32_t)(bpt_value
& 0xFFFFFFFF));
1270 if (retval
!= ERROR_OK
)
1272 retval
= aarch64_dap_write_memap_register_u32(target
, armv8
->debug_base
1273 + CPUV8_DBG_BVR_BASE
+ 4 + 16 * brp_list
[brp_i
].brpn
,
1274 (uint32_t)(bpt_value
>> 32));
1275 if (retval
!= ERROR_OK
)
1278 retval
= aarch64_dap_write_memap_register_u32(target
, armv8
->debug_base
1279 + CPUV8_DBG_BCR_BASE
+ 16 * brp_list
[brp_i
].brpn
,
1280 brp_list
[brp_i
].control
);
1281 if (retval
!= ERROR_OK
)
1283 LOG_DEBUG("brp %i control 0x%0" PRIx32
" value 0x%" TARGET_PRIxADDR
, brp_i
,
1284 brp_list
[brp_i
].control
,
1285 brp_list
[brp_i
].value
);
1287 } else if (breakpoint
->type
== BKPT_SOFT
) {
1291 if (armv8_dpm_get_core_state(&armv8
->dpm
) == ARM_STATE_AARCH64
) {
1292 opcode
= ARMV8_HLT(11);
1294 if (breakpoint
->length
!= 4)
1295 LOG_ERROR("bug: breakpoint length should be 4 in AArch64 mode");
1298 * core_state is ARM_STATE_ARM
1299 * in that case the opcode depends on breakpoint length:
1300 * - if length == 4 => A32 opcode
1301 * - if length == 2 => T32 opcode
1302 * - if length == 3 => T32 opcode (refer to gdb doc : ARM-Breakpoint-Kinds)
1303 * in that case the length should be changed from 3 to 4 bytes
1305 opcode
= (breakpoint
->length
== 4) ? ARMV8_HLT_A1(11) :
1306 (uint32_t) (ARMV8_HLT_T1(11) | ARMV8_HLT_T1(11) << 16);
1308 if (breakpoint
->length
== 3)
1309 breakpoint
->length
= 4;
1312 buf_set_u32(code
, 0, 32, opcode
);
1314 retval
= target_read_memory(target
,
1315 breakpoint
->address
& 0xFFFFFFFFFFFFFFFEULL
,
1316 breakpoint
->length
, 1,
1317 breakpoint
->orig_instr
);
1318 if (retval
!= ERROR_OK
)
1321 armv8_cache_d_inner_flush_virt(armv8
,
1322 breakpoint
->address
& 0xFFFFFFFFFFFFFFFEULL
,
1323 breakpoint
->length
);
1325 retval
= target_write_memory(target
,
1326 breakpoint
->address
& 0xFFFFFFFFFFFFFFFEULL
,
1327 breakpoint
->length
, 1, code
);
1328 if (retval
!= ERROR_OK
)
1331 armv8_cache_d_inner_flush_virt(armv8
,
1332 breakpoint
->address
& 0xFFFFFFFFFFFFFFFEULL
,
1333 breakpoint
->length
);
1335 armv8_cache_i_inner_inval_virt(armv8
,
1336 breakpoint
->address
& 0xFFFFFFFFFFFFFFFEULL
,
1337 breakpoint
->length
);
1339 breakpoint
->is_set
= true;
1342 /* Ensure that halting debug mode is enable */
1343 retval
= aarch64_set_dscr_bits(target
, DSCR_HDE
, DSCR_HDE
);
1344 if (retval
!= ERROR_OK
) {
1345 LOG_DEBUG("Failed to set DSCR.HDE");
1352 static int aarch64_set_context_breakpoint(struct target
*target
,
1353 struct breakpoint
*breakpoint
, uint8_t matchmode
)
1355 int retval
= ERROR_FAIL
;
1358 uint8_t byte_addr_select
= 0x0F;
1359 struct aarch64_common
*aarch64
= target_to_aarch64(target
);
1360 struct armv8_common
*armv8
= &aarch64
->armv8_common
;
1361 struct aarch64_brp
*brp_list
= aarch64
->brp_list
;
1363 if (breakpoint
->is_set
) {
1364 LOG_WARNING("breakpoint already set");
1367 /*check available context BRPs*/
1368 while ((brp_list
[brp_i
].used
||
1369 (brp_list
[brp_i
].type
!= BRP_CONTEXT
)) && (brp_i
< aarch64
->brp_num
))
1372 if (brp_i
>= aarch64
->brp_num
) {
1373 LOG_ERROR("ERROR Can not find free Breakpoint Register Pair");
1377 breakpoint_hw_set(breakpoint
, brp_i
);
1378 control
= ((matchmode
& 0x7) << 20)
1380 | (byte_addr_select
<< 5)
1382 brp_list
[brp_i
].used
= 1;
1383 brp_list
[brp_i
].value
= (breakpoint
->asid
);
1384 brp_list
[brp_i
].control
= control
;
1385 retval
= aarch64_dap_write_memap_register_u32(target
, armv8
->debug_base
1386 + CPUV8_DBG_BVR_BASE
+ 16 * brp_list
[brp_i
].brpn
,
1387 brp_list
[brp_i
].value
);
1388 if (retval
!= ERROR_OK
)
1390 retval
= aarch64_dap_write_memap_register_u32(target
, armv8
->debug_base
1391 + CPUV8_DBG_BCR_BASE
+ 16 * brp_list
[brp_i
].brpn
,
1392 brp_list
[brp_i
].control
);
1393 if (retval
!= ERROR_OK
)
1395 LOG_DEBUG("brp %i control 0x%0" PRIx32
" value 0x%" TARGET_PRIxADDR
, brp_i
,
1396 brp_list
[brp_i
].control
,
1397 brp_list
[brp_i
].value
);
1402 static int aarch64_set_hybrid_breakpoint(struct target
*target
, struct breakpoint
*breakpoint
)
1404 int retval
= ERROR_FAIL
;
1405 int brp_1
= 0; /* holds the contextID pair */
1406 int brp_2
= 0; /* holds the IVA pair */
1407 uint32_t control_ctx
, control_iva
;
1408 uint8_t ctx_byte_addr_select
= 0x0F;
1409 uint8_t iva_byte_addr_select
= 0x0F;
1410 uint8_t ctx_machmode
= 0x03;
1411 uint8_t iva_machmode
= 0x01;
1412 struct aarch64_common
*aarch64
= target_to_aarch64(target
);
1413 struct armv8_common
*armv8
= &aarch64
->armv8_common
;
1414 struct aarch64_brp
*brp_list
= aarch64
->brp_list
;
1416 if (breakpoint
->is_set
) {
1417 LOG_WARNING("breakpoint already set");
1420 /*check available context BRPs*/
1421 while ((brp_list
[brp_1
].used
||
1422 (brp_list
[brp_1
].type
!= BRP_CONTEXT
)) && (brp_1
< aarch64
->brp_num
))
1425 LOG_DEBUG("brp(CTX) found num: %d", brp_1
);
1426 if (brp_1
>= aarch64
->brp_num
) {
1427 LOG_ERROR("ERROR Can not find free Breakpoint Register Pair");
1431 while ((brp_list
[brp_2
].used
||
1432 (brp_list
[brp_2
].type
!= BRP_NORMAL
)) && (brp_2
< aarch64
->brp_num
))
1435 LOG_DEBUG("brp(IVA) found num: %d", brp_2
);
1436 if (brp_2
>= aarch64
->brp_num
) {
1437 LOG_ERROR("ERROR Can not find free Breakpoint Register Pair");
1441 breakpoint_hw_set(breakpoint
, brp_1
);
1442 breakpoint
->linked_brp
= brp_2
;
1443 control_ctx
= ((ctx_machmode
& 0x7) << 20)
1446 | (ctx_byte_addr_select
<< 5)
1448 brp_list
[brp_1
].used
= 1;
1449 brp_list
[brp_1
].value
= (breakpoint
->asid
);
1450 brp_list
[brp_1
].control
= control_ctx
;
1451 retval
= aarch64_dap_write_memap_register_u32(target
, armv8
->debug_base
1452 + CPUV8_DBG_BVR_BASE
+ 16 * brp_list
[brp_1
].brpn
,
1453 brp_list
[brp_1
].value
);
1454 if (retval
!= ERROR_OK
)
1456 retval
= aarch64_dap_write_memap_register_u32(target
, armv8
->debug_base
1457 + CPUV8_DBG_BCR_BASE
+ 16 * brp_list
[brp_1
].brpn
,
1458 brp_list
[brp_1
].control
);
1459 if (retval
!= ERROR_OK
)
1462 control_iva
= ((iva_machmode
& 0x7) << 20)
1465 | (iva_byte_addr_select
<< 5)
1467 brp_list
[brp_2
].used
= 1;
1468 brp_list
[brp_2
].value
= breakpoint
->address
& 0xFFFFFFFFFFFFFFFCULL
;
1469 brp_list
[brp_2
].control
= control_iva
;
1470 retval
= aarch64_dap_write_memap_register_u32(target
, armv8
->debug_base
1471 + CPUV8_DBG_BVR_BASE
+ 16 * brp_list
[brp_2
].brpn
,
1472 brp_list
[brp_2
].value
& 0xFFFFFFFF);
1473 if (retval
!= ERROR_OK
)
1475 retval
= aarch64_dap_write_memap_register_u32(target
, armv8
->debug_base
1476 + CPUV8_DBG_BVR_BASE
+ 4 + 16 * brp_list
[brp_2
].brpn
,
1477 brp_list
[brp_2
].value
>> 32);
1478 if (retval
!= ERROR_OK
)
1480 retval
= aarch64_dap_write_memap_register_u32(target
, armv8
->debug_base
1481 + CPUV8_DBG_BCR_BASE
+ 16 * brp_list
[brp_2
].brpn
,
1482 brp_list
[brp_2
].control
);
1483 if (retval
!= ERROR_OK
)
1489 static int aarch64_unset_breakpoint(struct target
*target
, struct breakpoint
*breakpoint
)
1492 struct aarch64_common
*aarch64
= target_to_aarch64(target
);
1493 struct armv8_common
*armv8
= &aarch64
->armv8_common
;
1494 struct aarch64_brp
*brp_list
= aarch64
->brp_list
;
1496 if (!breakpoint
->is_set
) {
1497 LOG_WARNING("breakpoint not set");
1501 if (breakpoint
->type
== BKPT_HARD
) {
1502 if ((breakpoint
->address
!= 0) && (breakpoint
->asid
!= 0)) {
1503 int brp_i
= breakpoint
->number
;
1504 int brp_j
= breakpoint
->linked_brp
;
1505 if (brp_i
>= aarch64
->brp_num
) {
1506 LOG_DEBUG("Invalid BRP number in breakpoint");
1509 LOG_DEBUG("rbp %i control 0x%0" PRIx32
" value 0x%" TARGET_PRIxADDR
, brp_i
,
1510 brp_list
[brp_i
].control
, brp_list
[brp_i
].value
);
1511 brp_list
[brp_i
].used
= 0;
1512 brp_list
[brp_i
].value
= 0;
1513 brp_list
[brp_i
].control
= 0;
1514 retval
= aarch64_dap_write_memap_register_u32(target
, armv8
->debug_base
1515 + CPUV8_DBG_BCR_BASE
+ 16 * brp_list
[brp_i
].brpn
,
1516 brp_list
[brp_i
].control
);
1517 if (retval
!= ERROR_OK
)
1519 retval
= aarch64_dap_write_memap_register_u32(target
, armv8
->debug_base
1520 + CPUV8_DBG_BVR_BASE
+ 16 * brp_list
[brp_i
].brpn
,
1521 (uint32_t)brp_list
[brp_i
].value
);
1522 if (retval
!= ERROR_OK
)
1524 retval
= aarch64_dap_write_memap_register_u32(target
, armv8
->debug_base
1525 + CPUV8_DBG_BVR_BASE
+ 4 + 16 * brp_list
[brp_i
].brpn
,
1526 (uint32_t)brp_list
[brp_i
].value
);
1527 if (retval
!= ERROR_OK
)
1529 if ((brp_j
< 0) || (brp_j
>= aarch64
->brp_num
)) {
1530 LOG_DEBUG("Invalid BRP number in breakpoint");
1533 LOG_DEBUG("rbp %i control 0x%0" PRIx32
" value 0x%0" PRIx64
, brp_j
,
1534 brp_list
[brp_j
].control
, brp_list
[brp_j
].value
);
1535 brp_list
[brp_j
].used
= 0;
1536 brp_list
[brp_j
].value
= 0;
1537 brp_list
[brp_j
].control
= 0;
1538 retval
= aarch64_dap_write_memap_register_u32(target
, armv8
->debug_base
1539 + CPUV8_DBG_BCR_BASE
+ 16 * brp_list
[brp_j
].brpn
,
1540 brp_list
[brp_j
].control
);
1541 if (retval
!= ERROR_OK
)
1543 retval
= aarch64_dap_write_memap_register_u32(target
, armv8
->debug_base
1544 + CPUV8_DBG_BVR_BASE
+ 16 * brp_list
[brp_j
].brpn
,
1545 (uint32_t)brp_list
[brp_j
].value
);
1546 if (retval
!= ERROR_OK
)
1548 retval
= aarch64_dap_write_memap_register_u32(target
, armv8
->debug_base
1549 + CPUV8_DBG_BVR_BASE
+ 4 + 16 * brp_list
[brp_j
].brpn
,
1550 (uint32_t)brp_list
[brp_j
].value
);
1551 if (retval
!= ERROR_OK
)
1554 breakpoint
->linked_brp
= 0;
1555 breakpoint
->is_set
= false;
1559 int brp_i
= breakpoint
->number
;
1560 if (brp_i
>= aarch64
->brp_num
) {
1561 LOG_DEBUG("Invalid BRP number in breakpoint");
1564 LOG_DEBUG("rbp %i control 0x%0" PRIx32
" value 0x%0" PRIx64
, brp_i
,
1565 brp_list
[brp_i
].control
, brp_list
[brp_i
].value
);
1566 brp_list
[brp_i
].used
= 0;
1567 brp_list
[brp_i
].value
= 0;
1568 brp_list
[brp_i
].control
= 0;
1569 retval
= aarch64_dap_write_memap_register_u32(target
, armv8
->debug_base
1570 + CPUV8_DBG_BCR_BASE
+ 16 * brp_list
[brp_i
].brpn
,
1571 brp_list
[brp_i
].control
);
1572 if (retval
!= ERROR_OK
)
1574 retval
= aarch64_dap_write_memap_register_u32(target
, armv8
->debug_base
1575 + CPUV8_DBG_BVR_BASE
+ 16 * brp_list
[brp_i
].brpn
,
1576 brp_list
[brp_i
].value
);
1577 if (retval
!= ERROR_OK
)
1580 retval
= aarch64_dap_write_memap_register_u32(target
, armv8
->debug_base
1581 + CPUV8_DBG_BVR_BASE
+ 4 + 16 * brp_list
[brp_i
].brpn
,
1582 (uint32_t)brp_list
[brp_i
].value
);
1583 if (retval
!= ERROR_OK
)
1585 breakpoint
->is_set
= false;
1589 /* restore original instruction (kept in target endianness) */
1591 armv8_cache_d_inner_flush_virt(armv8
,
1592 breakpoint
->address
& 0xFFFFFFFFFFFFFFFEULL
,
1593 breakpoint
->length
);
1595 if (breakpoint
->length
== 4) {
1596 retval
= target_write_memory(target
,
1597 breakpoint
->address
& 0xFFFFFFFFFFFFFFFEULL
,
1598 4, 1, breakpoint
->orig_instr
);
1599 if (retval
!= ERROR_OK
)
1602 retval
= target_write_memory(target
,
1603 breakpoint
->address
& 0xFFFFFFFFFFFFFFFEULL
,
1604 2, 1, breakpoint
->orig_instr
);
1605 if (retval
!= ERROR_OK
)
1609 armv8_cache_d_inner_flush_virt(armv8
,
1610 breakpoint
->address
& 0xFFFFFFFFFFFFFFFEULL
,
1611 breakpoint
->length
);
1613 armv8_cache_i_inner_inval_virt(armv8
,
1614 breakpoint
->address
& 0xFFFFFFFFFFFFFFFEULL
,
1615 breakpoint
->length
);
1617 breakpoint
->is_set
= false;
1622 static int aarch64_add_breakpoint(struct target
*target
,
1623 struct breakpoint
*breakpoint
)
1625 struct aarch64_common
*aarch64
= target_to_aarch64(target
);
1627 if ((breakpoint
->type
== BKPT_HARD
) && (aarch64
->brp_num_available
< 1)) {
1628 LOG_INFO("no hardware breakpoint available");
1629 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1632 if (breakpoint
->type
== BKPT_HARD
)
1633 aarch64
->brp_num_available
--;
1635 return aarch64_set_breakpoint(target
, breakpoint
, 0x00); /* Exact match */
1638 static int aarch64_add_context_breakpoint(struct target
*target
,
1639 struct breakpoint
*breakpoint
)
1641 struct aarch64_common
*aarch64
= target_to_aarch64(target
);
1643 if ((breakpoint
->type
== BKPT_HARD
) && (aarch64
->brp_num_available
< 1)) {
1644 LOG_INFO("no hardware breakpoint available");
1645 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1648 if (breakpoint
->type
== BKPT_HARD
)
1649 aarch64
->brp_num_available
--;
1651 return aarch64_set_context_breakpoint(target
, breakpoint
, 0x02); /* asid match */
1654 static int aarch64_add_hybrid_breakpoint(struct target
*target
,
1655 struct breakpoint
*breakpoint
)
1657 struct aarch64_common
*aarch64
= target_to_aarch64(target
);
1659 if ((breakpoint
->type
== BKPT_HARD
) && (aarch64
->brp_num_available
< 1)) {
1660 LOG_INFO("no hardware breakpoint available");
1661 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1664 if (breakpoint
->type
== BKPT_HARD
)
1665 aarch64
->brp_num_available
--;
1667 return aarch64_set_hybrid_breakpoint(target
, breakpoint
); /* ??? */
1670 static int aarch64_remove_breakpoint(struct target
*target
, struct breakpoint
*breakpoint
)
1672 struct aarch64_common
*aarch64
= target_to_aarch64(target
);
1675 /* It is perfectly possible to remove breakpoints while the target is running */
1676 if (target
->state
!= TARGET_HALTED
) {
1677 LOG_WARNING("target not halted");
1678 return ERROR_TARGET_NOT_HALTED
;
1682 if (breakpoint
->is_set
) {
1683 aarch64_unset_breakpoint(target
, breakpoint
);
1684 if (breakpoint
->type
== BKPT_HARD
)
1685 aarch64
->brp_num_available
++;
1691 /* Setup hardware Watchpoint Register Pair */
1692 static int aarch64_set_watchpoint(struct target
*target
,
1693 struct watchpoint
*watchpoint
)
1697 uint32_t control
, offset
, length
;
1698 struct aarch64_common
*aarch64
= target_to_aarch64(target
);
1699 struct armv8_common
*armv8
= &aarch64
->armv8_common
;
1700 struct aarch64_brp
*wp_list
= aarch64
->wp_list
;
1702 if (watchpoint
->is_set
) {
1703 LOG_WARNING("watchpoint already set");
1707 while (wp_list
[wp_i
].used
&& (wp_i
< aarch64
->wp_num
))
1709 if (wp_i
>= aarch64
->wp_num
) {
1710 LOG_ERROR("ERROR Can not find free Watchpoint Register Pair");
1711 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1714 control
= (1 << 0) /* enable */
1715 | (3 << 1) /* both user and privileged access */
1716 | (1 << 13); /* higher mode control */
1718 switch (watchpoint
->rw
) {
1730 /* Match up to 8 bytes. */
1731 offset
= watchpoint
->address
& 7;
1732 length
= watchpoint
->length
;
1733 if (offset
+ length
> sizeof(uint64_t)) {
1734 length
= sizeof(uint64_t) - offset
;
1735 LOG_WARNING("Adjust watchpoint match inside 8-byte boundary");
1737 for (; length
> 0; offset
++, length
--)
1738 control
|= (1 << offset
) << 5;
1740 wp_list
[wp_i
].value
= watchpoint
->address
& 0xFFFFFFFFFFFFFFF8ULL
;
1741 wp_list
[wp_i
].control
= control
;
1743 retval
= aarch64_dap_write_memap_register_u32(target
, armv8
->debug_base
1744 + CPUV8_DBG_WVR_BASE
+ 16 * wp_list
[wp_i
].brpn
,
1745 (uint32_t)(wp_list
[wp_i
].value
& 0xFFFFFFFF));
1746 if (retval
!= ERROR_OK
)
1748 retval
= aarch64_dap_write_memap_register_u32(target
, armv8
->debug_base
1749 + CPUV8_DBG_WVR_BASE
+ 4 + 16 * wp_list
[wp_i
].brpn
,
1750 (uint32_t)(wp_list
[wp_i
].value
>> 32));
1751 if (retval
!= ERROR_OK
)
1754 retval
= aarch64_dap_write_memap_register_u32(target
, armv8
->debug_base
1755 + CPUV8_DBG_WCR_BASE
+ 16 * wp_list
[wp_i
].brpn
,
1757 if (retval
!= ERROR_OK
)
1759 LOG_DEBUG("wp %i control 0x%0" PRIx32
" value 0x%" TARGET_PRIxADDR
, wp_i
,
1760 wp_list
[wp_i
].control
, wp_list
[wp_i
].value
);
1762 /* Ensure that halting debug mode is enable */
1763 retval
= aarch64_set_dscr_bits(target
, DSCR_HDE
, DSCR_HDE
);
1764 if (retval
!= ERROR_OK
) {
1765 LOG_DEBUG("Failed to set DSCR.HDE");
1769 wp_list
[wp_i
].used
= 1;
1770 watchpoint_set(watchpoint
, wp_i
);
1775 /* Clear hardware Watchpoint Register Pair */
1776 static int aarch64_unset_watchpoint(struct target
*target
,
1777 struct watchpoint
*watchpoint
)
1780 struct aarch64_common
*aarch64
= target_to_aarch64(target
);
1781 struct armv8_common
*armv8
= &aarch64
->armv8_common
;
1782 struct aarch64_brp
*wp_list
= aarch64
->wp_list
;
1784 if (!watchpoint
->is_set
) {
1785 LOG_WARNING("watchpoint not set");
1789 int wp_i
= watchpoint
->number
;
1790 if (wp_i
>= aarch64
->wp_num
) {
1791 LOG_DEBUG("Invalid WP number in watchpoint");
1794 LOG_DEBUG("rwp %i control 0x%0" PRIx32
" value 0x%0" PRIx64
, wp_i
,
1795 wp_list
[wp_i
].control
, wp_list
[wp_i
].value
);
1796 wp_list
[wp_i
].used
= 0;
1797 wp_list
[wp_i
].value
= 0;
1798 wp_list
[wp_i
].control
= 0;
1799 retval
= aarch64_dap_write_memap_register_u32(target
, armv8
->debug_base
1800 + CPUV8_DBG_WCR_BASE
+ 16 * wp_list
[wp_i
].brpn
,
1801 wp_list
[wp_i
].control
);
1802 if (retval
!= ERROR_OK
)
1804 retval
= aarch64_dap_write_memap_register_u32(target
, armv8
->debug_base
1805 + CPUV8_DBG_WVR_BASE
+ 16 * wp_list
[wp_i
].brpn
,
1806 wp_list
[wp_i
].value
);
1807 if (retval
!= ERROR_OK
)
1810 retval
= aarch64_dap_write_memap_register_u32(target
, armv8
->debug_base
1811 + CPUV8_DBG_WVR_BASE
+ 4 + 16 * wp_list
[wp_i
].brpn
,
1812 (uint32_t)wp_list
[wp_i
].value
);
1813 if (retval
!= ERROR_OK
)
1815 watchpoint
->is_set
= false;
1820 static int aarch64_add_watchpoint(struct target
*target
,
1821 struct watchpoint
*watchpoint
)
1824 struct aarch64_common
*aarch64
= target_to_aarch64(target
);
1826 if (aarch64
->wp_num_available
< 1) {
1827 LOG_INFO("no hardware watchpoint available");
1828 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1831 retval
= aarch64_set_watchpoint(target
, watchpoint
);
1832 if (retval
== ERROR_OK
)
1833 aarch64
->wp_num_available
--;
1838 static int aarch64_remove_watchpoint(struct target
*target
,
1839 struct watchpoint
*watchpoint
)
1841 struct aarch64_common
*aarch64
= target_to_aarch64(target
);
1843 if (watchpoint
->is_set
) {
1844 aarch64_unset_watchpoint(target
, watchpoint
);
1845 aarch64
->wp_num_available
++;
1852 * find out which watchpoint hits
1853 * get exception address and compare the address to watchpoints
1855 static int aarch64_hit_watchpoint(struct target
*target
,
1856 struct watchpoint
**hit_watchpoint
)
1858 if (target
->debug_reason
!= DBG_REASON_WATCHPOINT
)
1861 struct armv8_common
*armv8
= target_to_armv8(target
);
1863 target_addr_t exception_address
;
1864 struct watchpoint
*wp
;
1866 exception_address
= armv8
->dpm
.wp_addr
;
1868 if (exception_address
== 0xFFFFFFFF)
1871 for (wp
= target
->watchpoints
; wp
; wp
= wp
->next
)
1872 if (exception_address
>= wp
->address
&& exception_address
< (wp
->address
+ wp
->length
)) {
1873 *hit_watchpoint
= wp
;
1881 * Cortex-A8 Reset functions
1884 static int aarch64_enable_reset_catch(struct target
*target
, bool enable
)
1886 struct armv8_common
*armv8
= target_to_armv8(target
);
1890 retval
= mem_ap_read_atomic_u32(armv8
->debug_ap
,
1891 armv8
->debug_base
+ CPUV8_DBG_EDECR
, &edecr
);
1892 LOG_DEBUG("EDECR = 0x%08" PRIx32
", enable=%d", edecr
, enable
);
1893 if (retval
!= ERROR_OK
)
1901 return mem_ap_write_atomic_u32(armv8
->debug_ap
,
1902 armv8
->debug_base
+ CPUV8_DBG_EDECR
, edecr
);
1905 static int aarch64_clear_reset_catch(struct target
*target
)
1907 struct armv8_common
*armv8
= target_to_armv8(target
);
1912 /* check if Reset Catch debug event triggered as expected */
1913 retval
= mem_ap_read_atomic_u32(armv8
->debug_ap
,
1914 armv8
->debug_base
+ CPUV8_DBG_EDESR
, &edesr
);
1915 if (retval
!= ERROR_OK
)
1918 was_triggered
= !!(edesr
& ESR_RC
);
1919 LOG_DEBUG("Reset Catch debug event %s",
1920 was_triggered
? "triggered" : "NOT triggered!");
1922 if (was_triggered
) {
1923 /* clear pending Reset Catch debug event */
1925 retval
= mem_ap_write_atomic_u32(armv8
->debug_ap
,
1926 armv8
->debug_base
+ CPUV8_DBG_EDESR
, edesr
);
1927 if (retval
!= ERROR_OK
)
1934 static int aarch64_assert_reset(struct target
*target
)
1936 struct armv8_common
*armv8
= target_to_armv8(target
);
1937 enum reset_types reset_config
= jtag_get_reset_config();
1942 /* Issue some kind of warm reset. */
1943 if (target_has_event_action(target
, TARGET_EVENT_RESET_ASSERT
))
1944 target_handle_event(target
, TARGET_EVENT_RESET_ASSERT
);
1945 else if (reset_config
& RESET_HAS_SRST
) {
1946 bool srst_asserted
= false;
1948 if (target
->reset_halt
&& !(reset_config
& RESET_SRST_PULLS_TRST
)) {
1949 if (target_was_examined(target
)) {
1951 if (reset_config
& RESET_SRST_NO_GATING
) {
1953 * SRST needs to be asserted *before* Reset Catch
1954 * debug event can be set up.
1956 adapter_assert_reset();
1957 srst_asserted
= true;
1960 /* make sure to clear all sticky errors */
1961 mem_ap_write_atomic_u32(armv8
->debug_ap
,
1962 armv8
->debug_base
+ CPUV8_DBG_DRCR
, DRCR_CSE
);
1964 /* set up Reset Catch debug event to halt the CPU after reset */
1965 retval
= aarch64_enable_reset_catch(target
, true);
1966 if (retval
!= ERROR_OK
)
1967 LOG_WARNING("%s: Error enabling Reset Catch debug event; the CPU will not halt immediately after reset!",
1968 target_name(target
));
1970 LOG_WARNING("%s: Target not examined, will not halt immediately after reset!",
1971 target_name(target
));
1975 /* REVISIT handle "pulls" cases, if there's
1976 * hardware that needs them to work.
1979 adapter_assert_reset();
1981 LOG_ERROR("%s: how to reset?", target_name(target
));
1985 /* registers are now invalid */
1986 if (target_was_examined(target
)) {
1987 register_cache_invalidate(armv8
->arm
.core_cache
);
1988 register_cache_invalidate(armv8
->arm
.core_cache
->next
);
1991 target
->state
= TARGET_RESET
;
1996 static int aarch64_deassert_reset(struct target
*target
)
2002 /* be certain SRST is off */
2003 adapter_deassert_reset();
2005 if (!target_was_examined(target
))
2008 retval
= aarch64_init_debug_access(target
);
2009 if (retval
!= ERROR_OK
)
2012 retval
= aarch64_poll(target
);
2013 if (retval
!= ERROR_OK
)
2016 if (target
->reset_halt
) {
2017 /* clear pending Reset Catch debug event */
2018 retval
= aarch64_clear_reset_catch(target
);
2019 if (retval
!= ERROR_OK
)
2020 LOG_WARNING("%s: Clearing Reset Catch debug event failed",
2021 target_name(target
));
2023 /* disable Reset Catch debug event */
2024 retval
= aarch64_enable_reset_catch(target
, false);
2025 if (retval
!= ERROR_OK
)
2026 LOG_WARNING("%s: Disabling Reset Catch debug event failed",
2027 target_name(target
));
2029 if (target
->state
!= TARGET_HALTED
) {
2030 LOG_WARNING("%s: ran after reset and before halt ...",
2031 target_name(target
));
2032 if (target_was_examined(target
)) {
2033 retval
= aarch64_halt_one(target
, HALT_LAZY
);
2034 if (retval
!= ERROR_OK
)
2037 target
->state
= TARGET_UNKNOWN
;
2045 static int aarch64_write_cpu_memory_slow(struct target
*target
,
2046 uint32_t size
, uint32_t count
, const uint8_t *buffer
, uint32_t *dscr
)
2048 struct armv8_common
*armv8
= target_to_armv8(target
);
2049 struct arm_dpm
*dpm
= &armv8
->dpm
;
2050 struct arm
*arm
= &armv8
->arm
;
2053 if (size
> 4 && arm
->core_state
!= ARM_STATE_AARCH64
) {
2054 LOG_ERROR("memory write sizes greater than 4 bytes is only supported for AArch64 state");
2058 armv8_reg_current(arm
, 1)->dirty
= true;
2060 /* change DCC to normal mode if necessary */
2061 if (*dscr
& DSCR_MA
) {
2063 retval
= mem_ap_write_atomic_u32(armv8
->debug_ap
,
2064 armv8
->debug_base
+ CPUV8_DBG_DSCR
, *dscr
);
2065 if (retval
!= ERROR_OK
)
2073 /* write the data to store into DTRRX (and DTRTX for 64-bit) */
2077 data
= target_buffer_get_u16(target
, buffer
);
2079 data
= target_buffer_get_u32(target
, buffer
);
2081 data
= target_buffer_get_u64(target
, buffer
);
2083 retval
= mem_ap_write_atomic_u32(armv8
->debug_ap
,
2084 armv8
->debug_base
+ CPUV8_DBG_DTRRX
, (uint32_t)data
);
2085 if (retval
== ERROR_OK
&& size
> 4)
2086 retval
= mem_ap_write_atomic_u32(armv8
->debug_ap
,
2087 armv8
->debug_base
+ CPUV8_DBG_DTRTX
, (uint32_t)(data
>> 32));
2088 if (retval
!= ERROR_OK
)
2091 if (arm
->core_state
== ARM_STATE_AARCH64
)
2093 retval
= dpm
->instr_execute(dpm
, ARMV8_MRS(SYSTEM_DBG_DTRRX_EL0
, 1));
2095 retval
= dpm
->instr_execute(dpm
, ARMV8_MRS(SYSTEM_DBG_DBGDTR_EL0
, 1));
2097 retval
= dpm
->instr_execute(dpm
, ARMV4_5_MRC(14, 0, 1, 0, 5, 0));
2098 if (retval
!= ERROR_OK
)
2102 opcode
= armv8_opcode(armv8
, ARMV8_OPC_STRB_IP
);
2104 opcode
= armv8_opcode(armv8
, ARMV8_OPC_STRH_IP
);
2106 opcode
= armv8_opcode(armv8
, ARMV8_OPC_STRW_IP
);
2108 opcode
= armv8_opcode(armv8
, ARMV8_OPC_STRD_IP
);
2110 retval
= dpm
->instr_execute(dpm
, opcode
);
2111 if (retval
!= ERROR_OK
)
2122 static int aarch64_write_cpu_memory_fast(struct target
*target
,
2123 uint32_t count
, const uint8_t *buffer
, uint32_t *dscr
)
2125 struct armv8_common
*armv8
= target_to_armv8(target
);
2126 struct arm
*arm
= &armv8
->arm
;
2129 armv8_reg_current(arm
, 1)->dirty
= true;
2131 /* Step 1.d - Change DCC to memory mode */
2133 retval
= mem_ap_write_atomic_u32(armv8
->debug_ap
,
2134 armv8
->debug_base
+ CPUV8_DBG_DSCR
, *dscr
);
2135 if (retval
!= ERROR_OK
)
2139 /* Step 2.a - Do the write */
2140 retval
= mem_ap_write_buf_noincr(armv8
->debug_ap
,
2141 buffer
, 4, count
, armv8
->debug_base
+ CPUV8_DBG_DTRRX
);
2142 if (retval
!= ERROR_OK
)
2145 /* Step 3.a - Switch DTR mode back to Normal mode */
2147 retval
= mem_ap_write_atomic_u32(armv8
->debug_ap
,
2148 armv8
->debug_base
+ CPUV8_DBG_DSCR
, *dscr
);
2149 if (retval
!= ERROR_OK
)
2155 static int aarch64_write_cpu_memory(struct target
*target
,
2156 uint64_t address
, uint32_t size
,
2157 uint32_t count
, const uint8_t *buffer
)
2159 /* write memory through APB-AP */
2160 int retval
= ERROR_COMMAND_SYNTAX_ERROR
;
2161 struct armv8_common
*armv8
= target_to_armv8(target
);
2162 struct arm_dpm
*dpm
= &armv8
->dpm
;
2163 struct arm
*arm
= &armv8
->arm
;
2166 if (target
->state
!= TARGET_HALTED
) {
2167 LOG_TARGET_ERROR(target
, "not halted");
2168 return ERROR_TARGET_NOT_HALTED
;
2171 /* Mark register X0 as dirty, as it will be used
2172 * for transferring the data.
2173 * It will be restored automatically when exiting
2176 armv8_reg_current(arm
, 0)->dirty
= true;
2178 /* This algorithm comes from DDI0487A.g, chapter J9.1 */
2181 retval
= mem_ap_read_atomic_u32(armv8
->debug_ap
,
2182 armv8
->debug_base
+ CPUV8_DBG_DSCR
, &dscr
);
2183 if (retval
!= ERROR_OK
)
2186 /* Set Normal access mode */
2187 dscr
= (dscr
& ~DSCR_MA
);
2188 retval
= mem_ap_write_atomic_u32(armv8
->debug_ap
,
2189 armv8
->debug_base
+ CPUV8_DBG_DSCR
, dscr
);
2190 if (retval
!= ERROR_OK
)
2193 if (arm
->core_state
== ARM_STATE_AARCH64
) {
2194 /* Write X0 with value 'address' using write procedure */
2195 /* Step 1.a+b - Write the address for read access into DBGDTR_EL0 */
2196 /* Step 1.c - Copy value from DTR to R0 using instruction mrs DBGDTR_EL0, x0 */
2197 retval
= dpm
->instr_write_data_dcc_64(dpm
,
2198 ARMV8_MRS(SYSTEM_DBG_DBGDTR_EL0
, 0), address
);
2200 /* Write R0 with value 'address' using write procedure */
2201 /* Step 1.a+b - Write the address for read access into DBGDTRRX */
2202 /* Step 1.c - Copy value from DTR to R0 using instruction mrc DBGDTRTXint, r0 */
2203 retval
= dpm
->instr_write_data_dcc(dpm
,
2204 ARMV4_5_MRC(14, 0, 0, 0, 5, 0), address
);
2207 if (retval
!= ERROR_OK
)
2210 if (size
== 4 && (address
% 4) == 0)
2211 retval
= aarch64_write_cpu_memory_fast(target
, count
, buffer
, &dscr
);
2213 retval
= aarch64_write_cpu_memory_slow(target
, size
, count
, buffer
, &dscr
);
2215 if (retval
!= ERROR_OK
) {
2216 /* Unset DTR mode */
2217 mem_ap_read_atomic_u32(armv8
->debug_ap
,
2218 armv8
->debug_base
+ CPUV8_DBG_DSCR
, &dscr
);
2220 mem_ap_write_atomic_u32(armv8
->debug_ap
,
2221 armv8
->debug_base
+ CPUV8_DBG_DSCR
, dscr
);
2224 /* Check for sticky abort flags in the DSCR */
2225 retval
= mem_ap_read_atomic_u32(armv8
->debug_ap
,
2226 armv8
->debug_base
+ CPUV8_DBG_DSCR
, &dscr
);
2227 if (retval
!= ERROR_OK
)
2231 if (dscr
& (DSCR_ERR
| DSCR_SYS_ERROR_PEND
)) {
2232 /* Abort occurred - clear it and exit */
2233 LOG_ERROR("abort occurred - dscr = 0x%08" PRIx32
, dscr
);
2234 armv8_dpm_handle_exception(dpm
, true);
2242 static int aarch64_read_cpu_memory_slow(struct target
*target
,
2243 uint32_t size
, uint32_t count
, uint8_t *buffer
, uint32_t *dscr
)
2245 struct armv8_common
*armv8
= target_to_armv8(target
);
2246 struct arm_dpm
*dpm
= &armv8
->dpm
;
2247 struct arm
*arm
= &armv8
->arm
;
2250 if (size
> 4 && arm
->core_state
!= ARM_STATE_AARCH64
) {
2251 LOG_ERROR("memory read sizes greater than 4 bytes is only supported for AArch64 state");
2255 armv8_reg_current(arm
, 1)->dirty
= true;
2257 /* change DCC to normal mode (if necessary) */
2258 if (*dscr
& DSCR_MA
) {
2260 retval
= mem_ap_write_atomic_u32(armv8
->debug_ap
,
2261 armv8
->debug_base
+ CPUV8_DBG_DSCR
, *dscr
);
2262 if (retval
!= ERROR_OK
)
2273 opcode
= armv8_opcode(armv8
, ARMV8_OPC_LDRB_IP
);
2275 opcode
= armv8_opcode(armv8
, ARMV8_OPC_LDRH_IP
);
2277 opcode
= armv8_opcode(armv8
, ARMV8_OPC_LDRW_IP
);
2279 opcode
= armv8_opcode(armv8
, ARMV8_OPC_LDRD_IP
);
2281 retval
= dpm
->instr_execute(dpm
, opcode
);
2282 if (retval
!= ERROR_OK
)
2285 if (arm
->core_state
== ARM_STATE_AARCH64
)
2287 retval
= dpm
->instr_execute(dpm
, ARMV8_MSR_GP(SYSTEM_DBG_DTRTX_EL0
, 1));
2289 retval
= dpm
->instr_execute(dpm
, ARMV8_MSR_GP(SYSTEM_DBG_DBGDTR_EL0
, 1));
2291 retval
= dpm
->instr_execute(dpm
, ARMV4_5_MCR(14, 0, 1, 0, 5, 0));
2292 if (retval
!= ERROR_OK
)
2295 retval
= mem_ap_read_atomic_u32(armv8
->debug_ap
,
2296 armv8
->debug_base
+ CPUV8_DBG_DTRTX
, &lower
);
2297 if (retval
== ERROR_OK
) {
2299 retval
= mem_ap_read_atomic_u32(armv8
->debug_ap
,
2300 armv8
->debug_base
+ CPUV8_DBG_DTRRX
, &higher
);
2304 if (retval
!= ERROR_OK
)
2307 data
= (uint64_t)lower
| (uint64_t)higher
<< 32;
2310 *buffer
= (uint8_t)data
;
2312 target_buffer_set_u16(target
, buffer
, (uint16_t)data
);
2314 target_buffer_set_u32(target
, buffer
, (uint32_t)data
);
2316 target_buffer_set_u64(target
, buffer
, data
);
2326 static int aarch64_read_cpu_memory_fast(struct target
*target
,
2327 uint32_t count
, uint8_t *buffer
, uint32_t *dscr
)
2329 struct armv8_common
*armv8
= target_to_armv8(target
);
2330 struct arm_dpm
*dpm
= &armv8
->dpm
;
2331 struct arm
*arm
= &armv8
->arm
;
2335 /* Mark X1 as dirty */
2336 armv8_reg_current(arm
, 1)->dirty
= true;
2338 if (arm
->core_state
== ARM_STATE_AARCH64
) {
2339 /* Step 1.d - Dummy operation to ensure EDSCR.Txfull == 1 */
2340 retval
= dpm
->instr_execute(dpm
, ARMV8_MSR_GP(SYSTEM_DBG_DBGDTR_EL0
, 0));
2342 /* Step 1.d - Dummy operation to ensure EDSCR.Txfull == 1 */
2343 retval
= dpm
->instr_execute(dpm
, ARMV4_5_MCR(14, 0, 0, 0, 5, 0));
2346 if (retval
!= ERROR_OK
)
2349 /* Step 1.e - Change DCC to memory mode */
2351 retval
= mem_ap_write_atomic_u32(armv8
->debug_ap
,
2352 armv8
->debug_base
+ CPUV8_DBG_DSCR
, *dscr
);
2353 if (retval
!= ERROR_OK
)
2356 /* Step 1.f - read DBGDTRTX and discard the value */
2357 retval
= mem_ap_read_atomic_u32(armv8
->debug_ap
,
2358 armv8
->debug_base
+ CPUV8_DBG_DTRTX
, &value
);
2359 if (retval
!= ERROR_OK
)
2363 /* Read the data - Each read of the DTRTX register causes the instruction to be reissued
2364 * Abort flags are sticky, so can be read at end of transactions
2366 * This data is read in aligned to 32 bit boundary.
2370 /* Step 2.a - Loop n-1 times, each read of DBGDTRTX reads the data from [X0] and
2371 * increments X0 by 4. */
2372 retval
= mem_ap_read_buf_noincr(armv8
->debug_ap
, buffer
, 4, count
,
2373 armv8
->debug_base
+ CPUV8_DBG_DTRTX
);
2374 if (retval
!= ERROR_OK
)
2378 /* Step 3.a - set DTR access mode back to Normal mode */
2380 retval
= mem_ap_write_atomic_u32(armv8
->debug_ap
,
2381 armv8
->debug_base
+ CPUV8_DBG_DSCR
, *dscr
);
2382 if (retval
!= ERROR_OK
)
2385 /* Step 3.b - read DBGDTRTX for the final value */
2386 retval
= mem_ap_read_atomic_u32(armv8
->debug_ap
,
2387 armv8
->debug_base
+ CPUV8_DBG_DTRTX
, &value
);
2388 if (retval
!= ERROR_OK
)
2391 target_buffer_set_u32(target
, buffer
+ count
* 4, value
);
2395 static int aarch64_read_cpu_memory(struct target
*target
,
2396 target_addr_t address
, uint32_t size
,
2397 uint32_t count
, uint8_t *buffer
)
2399 /* read memory through APB-AP */
2400 int retval
= ERROR_COMMAND_SYNTAX_ERROR
;
2401 struct armv8_common
*armv8
= target_to_armv8(target
);
2402 struct arm_dpm
*dpm
= &armv8
->dpm
;
2403 struct arm
*arm
= &armv8
->arm
;
2406 LOG_DEBUG("Reading CPU memory address 0x%016" PRIx64
" size %" PRIu32
" count %" PRIu32
,
2407 address
, size
, count
);
2409 if (target
->state
!= TARGET_HALTED
) {
2410 LOG_TARGET_ERROR(target
, "not halted");
2411 return ERROR_TARGET_NOT_HALTED
;
2414 /* Mark register X0 as dirty, as it will be used
2415 * for transferring the data.
2416 * It will be restored automatically when exiting
2419 armv8_reg_current(arm
, 0)->dirty
= true;
2422 retval
= mem_ap_read_atomic_u32(armv8
->debug_ap
,
2423 armv8
->debug_base
+ CPUV8_DBG_DSCR
, &dscr
);
2424 if (retval
!= ERROR_OK
)
2427 /* This algorithm comes from DDI0487A.g, chapter J9.1 */
2429 /* Set Normal access mode */
2431 retval
= mem_ap_write_atomic_u32(armv8
->debug_ap
,
2432 armv8
->debug_base
+ CPUV8_DBG_DSCR
, dscr
);
2433 if (retval
!= ERROR_OK
)
2436 if (arm
->core_state
== ARM_STATE_AARCH64
) {
2437 /* Write X0 with value 'address' using write procedure */
2438 /* Step 1.a+b - Write the address for read access into DBGDTR_EL0 */
2439 /* Step 1.c - Copy value from DTR to R0 using instruction mrs DBGDTR_EL0, x0 */
2440 retval
= dpm
->instr_write_data_dcc_64(dpm
,
2441 ARMV8_MRS(SYSTEM_DBG_DBGDTR_EL0
, 0), address
);
2443 /* Write R0 with value 'address' using write procedure */
2444 /* Step 1.a+b - Write the address for read access into DBGDTRRXint */
2445 /* Step 1.c - Copy value from DTR to R0 using instruction mrc DBGDTRTXint, r0 */
2446 retval
= dpm
->instr_write_data_dcc(dpm
,
2447 ARMV4_5_MRC(14, 0, 0, 0, 5, 0), address
);
2450 if (retval
!= ERROR_OK
)
2453 if (size
== 4 && (address
% 4) == 0)
2454 retval
= aarch64_read_cpu_memory_fast(target
, count
, buffer
, &dscr
);
2456 retval
= aarch64_read_cpu_memory_slow(target
, size
, count
, buffer
, &dscr
);
2458 if (dscr
& DSCR_MA
) {
2460 mem_ap_write_atomic_u32(armv8
->debug_ap
,
2461 armv8
->debug_base
+ CPUV8_DBG_DSCR
, dscr
);
2464 if (retval
!= ERROR_OK
)
2467 /* Check for sticky abort flags in the DSCR */
2468 retval
= mem_ap_read_atomic_u32(armv8
->debug_ap
,
2469 armv8
->debug_base
+ CPUV8_DBG_DSCR
, &dscr
);
2470 if (retval
!= ERROR_OK
)
2475 if (dscr
& (DSCR_ERR
| DSCR_SYS_ERROR_PEND
)) {
2476 /* Abort occurred - clear it and exit */
2477 LOG_ERROR("abort occurred - dscr = 0x%08" PRIx32
, dscr
);
2478 armv8_dpm_handle_exception(dpm
, true);
2486 static int aarch64_read_phys_memory(struct target
*target
,
2487 target_addr_t address
, uint32_t size
,
2488 uint32_t count
, uint8_t *buffer
)
2490 int retval
= ERROR_COMMAND_SYNTAX_ERROR
;
2492 if (count
&& buffer
) {
2493 /* read memory through APB-AP */
2494 retval
= aarch64_mmu_modify(target
, 0);
2495 if (retval
!= ERROR_OK
)
2497 retval
= aarch64_read_cpu_memory(target
, address
, size
, count
, buffer
);
2502 static int aarch64_read_memory(struct target
*target
, target_addr_t address
,
2503 uint32_t size
, uint32_t count
, uint8_t *buffer
)
2505 int mmu_enabled
= 0;
2508 /* determine if MMU was enabled on target stop */
2509 retval
= aarch64_mmu(target
, &mmu_enabled
);
2510 if (retval
!= ERROR_OK
)
2514 /* enable MMU as we could have disabled it for phys access */
2515 retval
= aarch64_mmu_modify(target
, 1);
2516 if (retval
!= ERROR_OK
)
2519 return aarch64_read_cpu_memory(target
, address
, size
, count
, buffer
);
2522 static int aarch64_write_phys_memory(struct target
*target
,
2523 target_addr_t address
, uint32_t size
,
2524 uint32_t count
, const uint8_t *buffer
)
2526 int retval
= ERROR_COMMAND_SYNTAX_ERROR
;
2528 if (count
&& buffer
) {
2529 /* write memory through APB-AP */
2530 retval
= aarch64_mmu_modify(target
, 0);
2531 if (retval
!= ERROR_OK
)
2533 return aarch64_write_cpu_memory(target
, address
, size
, count
, buffer
);
2539 static int aarch64_write_memory(struct target
*target
, target_addr_t address
,
2540 uint32_t size
, uint32_t count
, const uint8_t *buffer
)
2542 int mmu_enabled
= 0;
2545 /* determine if MMU was enabled on target stop */
2546 retval
= aarch64_mmu(target
, &mmu_enabled
);
2547 if (retval
!= ERROR_OK
)
2551 /* enable MMU as we could have disabled it for phys access */
2552 retval
= aarch64_mmu_modify(target
, 1);
2553 if (retval
!= ERROR_OK
)
2556 return aarch64_write_cpu_memory(target
, address
, size
, count
, buffer
);
2559 static int aarch64_handle_target_request(void *priv
)
2561 struct target
*target
= priv
;
2562 struct armv8_common
*armv8
= target_to_armv8(target
);
2565 if (!target_was_examined(target
))
2567 if (!target
->dbg_msg_enabled
)
2570 if (target
->state
== TARGET_RUNNING
) {
2573 retval
= mem_ap_read_atomic_u32(armv8
->debug_ap
,
2574 armv8
->debug_base
+ CPUV8_DBG_DSCR
, &dscr
);
2576 /* check if we have data */
2577 while ((dscr
& DSCR_DTR_TX_FULL
) && (retval
== ERROR_OK
)) {
2578 retval
= mem_ap_read_atomic_u32(armv8
->debug_ap
,
2579 armv8
->debug_base
+ CPUV8_DBG_DTRTX
, &request
);
2580 if (retval
== ERROR_OK
) {
2581 target_request(target
, request
);
2582 retval
= mem_ap_read_atomic_u32(armv8
->debug_ap
,
2583 armv8
->debug_base
+ CPUV8_DBG_DSCR
, &dscr
);
2591 static int aarch64_examine_first(struct target
*target
)
2593 struct aarch64_common
*aarch64
= target_to_aarch64(target
);
2594 struct armv8_common
*armv8
= &aarch64
->armv8_common
;
2595 struct adiv5_dap
*swjdp
= armv8
->arm
.dap
;
2596 struct aarch64_private_config
*pc
= target
->private_config
;
2598 int retval
= ERROR_OK
;
2599 uint64_t debug
, ttypr
;
2601 uint32_t tmp0
, tmp1
, tmp2
, tmp3
;
2602 debug
= ttypr
= cpuid
= 0;
2607 if (!armv8
->debug_ap
) {
2608 if (pc
->adiv5_config
.ap_num
== DP_APSEL_INVALID
) {
2609 /* Search for the APB-AB */
2610 retval
= dap_find_get_ap(swjdp
, AP_TYPE_APB_AP
, &armv8
->debug_ap
);
2611 if (retval
!= ERROR_OK
) {
2612 LOG_ERROR("Could not find APB-AP for debug access");
2616 armv8
->debug_ap
= dap_get_ap(swjdp
, pc
->adiv5_config
.ap_num
);
2617 if (!armv8
->debug_ap
) {
2618 LOG_ERROR("Cannot get AP");
2624 retval
= mem_ap_init(armv8
->debug_ap
);
2625 if (retval
!= ERROR_OK
) {
2626 LOG_ERROR("Could not initialize the APB-AP");
2630 armv8
->debug_ap
->memaccess_tck
= 10;
2632 if (!target
->dbgbase_set
) {
2633 /* Lookup Processor DAP */
2634 retval
= dap_lookup_cs_component(armv8
->debug_ap
, ARM_CS_C9_DEVTYPE_CORE_DEBUG
,
2635 &armv8
->debug_base
, target
->coreid
);
2636 if (retval
!= ERROR_OK
)
2638 LOG_DEBUG("Detected core %" PRId32
" dbgbase: " TARGET_ADDR_FMT
,
2639 target
->coreid
, armv8
->debug_base
);
2641 armv8
->debug_base
= target
->dbgbase
;
2643 retval
= mem_ap_write_atomic_u32(armv8
->debug_ap
,
2644 armv8
->debug_base
+ CPUV8_DBG_OSLAR
, 0);
2645 if (retval
!= ERROR_OK
) {
2646 LOG_DEBUG("Examine %s failed", "oslock");
2650 retval
= mem_ap_read_u32(armv8
->debug_ap
,
2651 armv8
->debug_base
+ CPUV8_DBG_MAINID0
, &cpuid
);
2652 if (retval
!= ERROR_OK
) {
2653 LOG_DEBUG("Examine %s failed", "CPUID");
2657 retval
= mem_ap_read_u32(armv8
->debug_ap
,
2658 armv8
->debug_base
+ CPUV8_DBG_MEMFEATURE0
, &tmp0
);
2659 retval
+= mem_ap_read_u32(armv8
->debug_ap
,
2660 armv8
->debug_base
+ CPUV8_DBG_MEMFEATURE0
+ 4, &tmp1
);
2661 if (retval
!= ERROR_OK
) {
2662 LOG_DEBUG("Examine %s failed", "Memory Model Type");
2665 retval
= mem_ap_read_u32(armv8
->debug_ap
,
2666 armv8
->debug_base
+ CPUV8_DBG_DBGFEATURE0
, &tmp2
);
2667 retval
+= mem_ap_read_u32(armv8
->debug_ap
,
2668 armv8
->debug_base
+ CPUV8_DBG_DBGFEATURE0
+ 4, &tmp3
);
2669 if (retval
!= ERROR_OK
) {
2670 LOG_DEBUG("Examine %s failed", "ID_AA64DFR0_EL1");
2674 retval
= dap_run(armv8
->debug_ap
->dap
);
2675 if (retval
!= ERROR_OK
) {
2676 LOG_ERROR("%s: examination failed\n", target_name(target
));
2681 ttypr
= (ttypr
<< 32) | tmp0
;
2683 debug
= (debug
<< 32) | tmp2
;
2685 LOG_DEBUG("cpuid = 0x%08" PRIx32
, cpuid
);
2686 LOG_DEBUG("ttypr = 0x%08" PRIx64
, ttypr
);
2687 LOG_DEBUG("debug = 0x%08" PRIx64
, debug
);
2690 LOG_TARGET_ERROR(target
, "CTI not specified");
2694 armv8
->cti
= pc
->cti
;
2696 retval
= aarch64_dpm_setup(aarch64
, debug
);
2697 if (retval
!= ERROR_OK
)
2700 /* Setup Breakpoint Register Pairs */
2701 aarch64
->brp_num
= (uint32_t)((debug
>> 12) & 0x0F) + 1;
2702 aarch64
->brp_num_context
= (uint32_t)((debug
>> 28) & 0x0F) + 1;
2703 aarch64
->brp_num_available
= aarch64
->brp_num
;
2704 aarch64
->brp_list
= calloc(aarch64
->brp_num
, sizeof(struct aarch64_brp
));
2705 for (i
= 0; i
< aarch64
->brp_num
; i
++) {
2706 aarch64
->brp_list
[i
].used
= 0;
2707 if (i
< (aarch64
->brp_num
-aarch64
->brp_num_context
))
2708 aarch64
->brp_list
[i
].type
= BRP_NORMAL
;
2710 aarch64
->brp_list
[i
].type
= BRP_CONTEXT
;
2711 aarch64
->brp_list
[i
].value
= 0;
2712 aarch64
->brp_list
[i
].control
= 0;
2713 aarch64
->brp_list
[i
].brpn
= i
;
2716 /* Setup Watchpoint Register Pairs */
2717 aarch64
->wp_num
= (uint32_t)((debug
>> 20) & 0x0F) + 1;
2718 aarch64
->wp_num_available
= aarch64
->wp_num
;
2719 aarch64
->wp_list
= calloc(aarch64
->wp_num
, sizeof(struct aarch64_brp
));
2720 for (i
= 0; i
< aarch64
->wp_num
; i
++) {
2721 aarch64
->wp_list
[i
].used
= 0;
2722 aarch64
->wp_list
[i
].type
= BRP_NORMAL
;
2723 aarch64
->wp_list
[i
].value
= 0;
2724 aarch64
->wp_list
[i
].control
= 0;
2725 aarch64
->wp_list
[i
].brpn
= i
;
2728 LOG_DEBUG("Configured %i hw breakpoints, %i watchpoints",
2729 aarch64
->brp_num
, aarch64
->wp_num
);
2731 target
->state
= TARGET_UNKNOWN
;
2732 target
->debug_reason
= DBG_REASON_NOTHALTED
;
2733 aarch64
->isrmasking_mode
= AARCH64_ISRMASK_ON
;
2734 target_set_examined(target
);
2738 static int aarch64_examine(struct target
*target
)
2740 int retval
= ERROR_OK
;
2742 /* don't re-probe hardware after each reset */
2743 if (!target_was_examined(target
))
2744 retval
= aarch64_examine_first(target
);
2746 /* Configure core debug access */
2747 if (retval
== ERROR_OK
)
2748 retval
= aarch64_init_debug_access(target
);
2750 if (retval
== ERROR_OK
)
2751 retval
= aarch64_poll(target
);
2757 * Cortex-A8 target creation and initialization
2760 static int aarch64_init_target(struct command_context
*cmd_ctx
,
2761 struct target
*target
)
2763 /* examine_first() does a bunch of this */
2764 arm_semihosting_init(target
);
2768 static int aarch64_init_arch_info(struct target
*target
,
2769 struct aarch64_common
*aarch64
, struct adiv5_dap
*dap
)
2771 struct armv8_common
*armv8
= &aarch64
->armv8_common
;
2773 /* Setup struct aarch64_common */
2774 aarch64
->common_magic
= AARCH64_COMMON_MAGIC
;
2775 armv8
->arm
.dap
= dap
;
2777 /* register arch-specific functions */
2778 armv8
->examine_debug_reason
= NULL
;
2779 armv8
->post_debug_entry
= aarch64_post_debug_entry
;
2780 armv8
->pre_restore_context
= NULL
;
2781 armv8
->armv8_mmu
.read_physical_memory
= aarch64_read_phys_memory
;
2783 armv8_init_arch_info(target
, armv8
);
2784 target_register_timer_callback(aarch64_handle_target_request
, 1,
2785 TARGET_TIMER_TYPE_PERIODIC
, target
);
2790 static int armv8r_target_create(struct target
*target
, Jim_Interp
*interp
)
2792 struct aarch64_private_config
*pc
= target
->private_config
;
2793 struct aarch64_common
*aarch64
;
2795 if (adiv5_verify_config(&pc
->adiv5_config
) != ERROR_OK
)
2798 aarch64
= calloc(1, sizeof(struct aarch64_common
));
2800 LOG_ERROR("Out of memory");
2804 aarch64
->armv8_common
.is_armv8r
= true;
2806 return aarch64_init_arch_info(target
, aarch64
, pc
->adiv5_config
.dap
);
2809 static int aarch64_target_create(struct target
*target
, Jim_Interp
*interp
)
2811 struct aarch64_private_config
*pc
= target
->private_config
;
2812 struct aarch64_common
*aarch64
;
2814 if (adiv5_verify_config(&pc
->adiv5_config
) != ERROR_OK
)
2817 aarch64
= calloc(1, sizeof(struct aarch64_common
));
2819 LOG_ERROR("Out of memory");
2823 aarch64
->armv8_common
.is_armv8r
= false;
2825 return aarch64_init_arch_info(target
, aarch64
, pc
->adiv5_config
.dap
);
2828 static void aarch64_deinit_target(struct target
*target
)
2830 struct aarch64_common
*aarch64
= target_to_aarch64(target
);
2831 struct armv8_common
*armv8
= &aarch64
->armv8_common
;
2832 struct arm_dpm
*dpm
= &armv8
->dpm
;
2834 if (armv8
->debug_ap
)
2835 dap_put_ap(armv8
->debug_ap
);
2837 armv8_free_reg_cache(target
);
2838 free(aarch64
->brp_list
);
2841 free(target
->private_config
);
2845 static int aarch64_mmu(struct target
*target
, int *enabled
)
2847 struct aarch64_common
*aarch64
= target_to_aarch64(target
);
2848 struct armv8_common
*armv8
= &aarch64
->armv8_common
;
2849 if (target
->state
!= TARGET_HALTED
) {
2850 LOG_TARGET_ERROR(target
, "not halted");
2851 return ERROR_TARGET_NOT_HALTED
;
2853 if (armv8
->is_armv8r
)
2856 *enabled
= target_to_aarch64(target
)->armv8_common
.armv8_mmu
.mmu_enabled
;
2860 static int aarch64_virt2phys(struct target
*target
, target_addr_t virt
,
2861 target_addr_t
*phys
)
2863 return armv8_mmu_translate_va_pa(target
, virt
, phys
, 1);
2867 * private target configuration items
2869 enum aarch64_cfg_param
{
2873 static const struct jim_nvp nvp_config_opts
[] = {
2874 { .name
= "-cti", .value
= CFG_CTI
},
2875 { .name
= NULL
, .value
= -1 }
2878 static int aarch64_jim_configure(struct target
*target
, struct jim_getopt_info
*goi
)
2880 struct aarch64_private_config
*pc
;
2884 pc
= (struct aarch64_private_config
*)target
->private_config
;
2886 pc
= calloc(1, sizeof(struct aarch64_private_config
));
2887 pc
->adiv5_config
.ap_num
= DP_APSEL_INVALID
;
2888 target
->private_config
= pc
;
2892 * Call adiv5_jim_configure() to parse the common DAP options
2893 * It will return JIM_CONTINUE if it didn't find any known
2894 * options, JIM_OK if it correctly parsed the topmost option
2895 * and JIM_ERR if an error occurred during parameter evaluation.
2896 * For JIM_CONTINUE, we check our own params.
2898 e
= adiv5_jim_configure_ext(target
, goi
, &pc
->adiv5_config
, ADI_CONFIGURE_DAP_COMPULSORY
);
2899 if (e
!= JIM_CONTINUE
)
2902 /* parse config or cget options ... */
2903 if (goi
->argc
> 0) {
2904 Jim_SetEmptyResult(goi
->interp
);
2906 /* check first if topmost item is for us */
2907 e
= jim_nvp_name2value_obj(goi
->interp
, nvp_config_opts
,
2910 return JIM_CONTINUE
;
2912 e
= jim_getopt_obj(goi
, NULL
);
2918 if (goi
->isconfigure
) {
2920 struct arm_cti
*cti
;
2921 e
= jim_getopt_obj(goi
, &o_cti
);
2924 cti
= cti_instance_by_jim_obj(goi
->interp
, o_cti
);
2926 Jim_SetResultString(goi
->interp
, "CTI name invalid!", -1);
2931 if (goi
->argc
!= 0) {
2932 Jim_WrongNumArgs(goi
->interp
,
2933 goi
->argc
, goi
->argv
,
2938 if (!pc
|| !pc
->cti
) {
2939 Jim_SetResultString(goi
->interp
, "CTI not configured", -1);
2942 Jim_SetResultString(goi
->interp
, arm_cti_name(pc
->cti
), -1);
2948 return JIM_CONTINUE
;
2955 COMMAND_HANDLER(aarch64_handle_cache_info_command
)
2957 struct target
*target
= get_current_target(CMD_CTX
);
2958 struct armv8_common
*armv8
= target_to_armv8(target
);
2960 return armv8_handle_cache_info_command(CMD
,
2961 &armv8
->armv8_mmu
.armv8_cache
);
2964 COMMAND_HANDLER(aarch64_handle_dbginit_command
)
2966 struct target
*target
= get_current_target(CMD_CTX
);
2967 if (!target_was_examined(target
)) {
2968 LOG_ERROR("target not examined yet");
2972 return aarch64_init_debug_access(target
);
2975 COMMAND_HANDLER(aarch64_handle_disassemble_command
)
2977 struct target
*target
= get_current_target(CMD_CTX
);
2980 LOG_ERROR("No target selected");
2984 struct aarch64_common
*aarch64
= target_to_aarch64(target
);
2986 if (aarch64
->common_magic
!= AARCH64_COMMON_MAGIC
) {
2987 command_print(CMD
, "current target isn't an AArch64");
2992 target_addr_t address
;
2996 COMMAND_PARSE_NUMBER(int, CMD_ARGV
[1], count
);
2999 COMMAND_PARSE_ADDRESS(CMD_ARGV
[0], address
);
3002 return ERROR_COMMAND_SYNTAX_ERROR
;
3005 return a64_disassemble(CMD
, target
, address
, count
);
3008 COMMAND_HANDLER(aarch64_mask_interrupts_command
)
3010 struct target
*target
= get_current_target(CMD_CTX
);
3011 struct aarch64_common
*aarch64
= target_to_aarch64(target
);
3013 static const struct nvp nvp_maskisr_modes
[] = {
3014 { .name
= "off", .value
= AARCH64_ISRMASK_OFF
},
3015 { .name
= "on", .value
= AARCH64_ISRMASK_ON
},
3016 { .name
= NULL
, .value
= -1 },
3018 const struct nvp
*n
;
3021 n
= nvp_name2value(nvp_maskisr_modes
, CMD_ARGV
[0]);
3023 LOG_ERROR("Unknown parameter: %s - should be off or on", CMD_ARGV
[0]);
3024 return ERROR_COMMAND_SYNTAX_ERROR
;
3027 aarch64
->isrmasking_mode
= n
->value
;
3030 n
= nvp_value2name(nvp_maskisr_modes
, aarch64
->isrmasking_mode
);
3031 command_print(CMD
, "aarch64 interrupt mask %s", n
->name
);
3036 COMMAND_HANDLER(aarch64_mcrmrc_command
)
3038 bool is_mcr
= false;
3039 unsigned int arg_cnt
= 5;
3041 if (!strcmp(CMD_NAME
, "mcr")) {
3046 if (arg_cnt
!= CMD_ARGC
)
3047 return ERROR_COMMAND_SYNTAX_ERROR
;
3049 struct target
*target
= get_current_target(CMD_CTX
);
3051 command_print(CMD
, "no current target");
3054 if (!target_was_examined(target
)) {
3055 command_print(CMD
, "%s: not yet examined", target_name(target
));
3056 return ERROR_TARGET_NOT_EXAMINED
;
3059 struct arm
*arm
= target_to_arm(target
);
3061 command_print(CMD
, "%s: not an ARM", target_name(target
));
3065 if (target
->state
!= TARGET_HALTED
) {
3066 command_print(CMD
, "Error: [%s] not halted", target_name(target
));
3067 return ERROR_TARGET_NOT_HALTED
;
3070 if (arm
->core_state
== ARM_STATE_AARCH64
) {
3071 command_print(CMD
, "%s: not 32-bit arm target", target_name(target
));
3082 /* NOTE: parameter sequence matches ARM instruction set usage:
3083 * MCR pNUM, op1, rX, CRn, CRm, op2 ; write CP from rX
3084 * MRC pNUM, op1, rX, CRn, CRm, op2 ; read CP into rX
3085 * The "rX" is necessarily omitted; it uses Tcl mechanisms.
3087 COMMAND_PARSE_NUMBER(int, CMD_ARGV
[0], cpnum
);
3089 command_print(CMD
, "coprocessor %d out of range", cpnum
);
3090 return ERROR_COMMAND_ARGUMENT_INVALID
;
3093 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[1], op1
);
3095 command_print(CMD
, "op1 %d out of range", op1
);
3096 return ERROR_COMMAND_ARGUMENT_INVALID
;
3099 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[2], crn
);
3101 command_print(CMD
, "CRn %d out of range", crn
);
3102 return ERROR_COMMAND_ARGUMENT_INVALID
;
3105 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[3], crm
);
3107 command_print(CMD
, "CRm %d out of range", crm
);
3108 return ERROR_COMMAND_ARGUMENT_INVALID
;
3111 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[4], op2
);
3113 command_print(CMD
, "op2 %d out of range", op2
);
3114 return ERROR_COMMAND_ARGUMENT_INVALID
;
3118 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[5], value
);
3120 /* NOTE: parameters reordered! */
3121 /* ARMV4_5_MCR(cpnum, op1, 0, crn, crm, op2) */
3122 int retval
= arm
->mcr(target
, cpnum
, op1
, op2
, crn
, crm
, value
);
3123 if (retval
!= ERROR_OK
)
3127 /* NOTE: parameters reordered! */
3128 /* ARMV4_5_MRC(cpnum, op1, 0, crn, crm, op2) */
3129 int retval
= arm
->mrc(target
, cpnum
, op1
, op2
, crn
, crm
, &value
);
3130 if (retval
!= ERROR_OK
)
3133 command_print(CMD
, "0x%" PRIx32
, value
);
3139 static const struct command_registration aarch64_exec_command_handlers
[] = {
3141 .name
= "cache_info",
3142 .handler
= aarch64_handle_cache_info_command
,
3143 .mode
= COMMAND_EXEC
,
3144 .help
= "display information about target caches",
3149 .handler
= aarch64_handle_dbginit_command
,
3150 .mode
= COMMAND_EXEC
,
3151 .help
= "Initialize core debug",
3155 .name
= "disassemble",
3156 .handler
= aarch64_handle_disassemble_command
,
3157 .mode
= COMMAND_EXEC
,
3158 .help
= "Disassemble instructions",
3159 .usage
= "address [count]",
3163 .handler
= aarch64_mask_interrupts_command
,
3164 .mode
= COMMAND_ANY
,
3165 .help
= "mask aarch64 interrupts during single-step",
3166 .usage
= "['on'|'off']",
3170 .mode
= COMMAND_EXEC
,
3171 .handler
= aarch64_mcrmrc_command
,
3172 .help
= "write coprocessor register",
3173 .usage
= "cpnum op1 CRn CRm op2 value",
3177 .mode
= COMMAND_EXEC
,
3178 .handler
= aarch64_mcrmrc_command
,
3179 .help
= "read coprocessor register",
3180 .usage
= "cpnum op1 CRn CRm op2",
3183 .chain
= smp_command_handlers
,
3187 COMMAND_REGISTRATION_DONE
3190 static const struct command_registration aarch64_command_handlers
[] = {
3193 .mode
= COMMAND_ANY
,
3194 .help
= "ARM Command Group",
3196 .chain
= semihosting_common_handlers
3199 .chain
= armv8_command_handlers
,
3203 .mode
= COMMAND_ANY
,
3204 .help
= "Aarch64 command group",
3206 .chain
= aarch64_exec_command_handlers
,
3208 COMMAND_REGISTRATION_DONE
3211 struct target_type aarch64_target
= {
3214 .poll
= aarch64_poll
,
3215 .arch_state
= armv8_arch_state
,
3217 .halt
= aarch64_halt
,
3218 .resume
= aarch64_resume
,
3219 .step
= aarch64_step
,
3221 .assert_reset
= aarch64_assert_reset
,
3222 .deassert_reset
= aarch64_deassert_reset
,
3224 /* REVISIT allow exporting VFP3 registers ... */
3225 .get_gdb_arch
= armv8_get_gdb_arch
,
3226 .get_gdb_reg_list
= armv8_get_gdb_reg_list
,
3228 .read_memory
= aarch64_read_memory
,
3229 .write_memory
= aarch64_write_memory
,
3231 .add_breakpoint
= aarch64_add_breakpoint
,
3232 .add_context_breakpoint
= aarch64_add_context_breakpoint
,
3233 .add_hybrid_breakpoint
= aarch64_add_hybrid_breakpoint
,
3234 .remove_breakpoint
= aarch64_remove_breakpoint
,
3235 .add_watchpoint
= aarch64_add_watchpoint
,
3236 .remove_watchpoint
= aarch64_remove_watchpoint
,
3237 .hit_watchpoint
= aarch64_hit_watchpoint
,
3239 .commands
= aarch64_command_handlers
,
3240 .target_create
= aarch64_target_create
,
3241 .target_jim_configure
= aarch64_jim_configure
,
3242 .init_target
= aarch64_init_target
,
3243 .deinit_target
= aarch64_deinit_target
,
3244 .examine
= aarch64_examine
,
3246 .read_phys_memory
= aarch64_read_phys_memory
,
3247 .write_phys_memory
= aarch64_write_phys_memory
,
3249 .virt2phys
= aarch64_virt2phys
,
3252 struct target_type armv8r_target
= {
3255 .poll
= aarch64_poll
,
3256 .arch_state
= armv8_arch_state
,
3258 .halt
= aarch64_halt
,
3259 .resume
= aarch64_resume
,
3260 .step
= aarch64_step
,
3262 .assert_reset
= aarch64_assert_reset
,
3263 .deassert_reset
= aarch64_deassert_reset
,
3265 /* REVISIT allow exporting VFP3 registers ... */
3266 .get_gdb_arch
= armv8_get_gdb_arch
,
3267 .get_gdb_reg_list
= armv8_get_gdb_reg_list
,
3269 .read_memory
= aarch64_read_phys_memory
,
3270 .write_memory
= aarch64_write_phys_memory
,
3272 .add_breakpoint
= aarch64_add_breakpoint
,
3273 .add_context_breakpoint
= aarch64_add_context_breakpoint
,
3274 .add_hybrid_breakpoint
= aarch64_add_hybrid_breakpoint
,
3275 .remove_breakpoint
= aarch64_remove_breakpoint
,
3276 .add_watchpoint
= aarch64_add_watchpoint
,
3277 .remove_watchpoint
= aarch64_remove_watchpoint
,
3278 .hit_watchpoint
= aarch64_hit_watchpoint
,
3280 .commands
= aarch64_command_handlers
,
3281 .target_create
= armv8r_target_create
,
3282 .target_jim_configure
= aarch64_jim_configure
,
3283 .init_target
= aarch64_init_target
,
3284 .deinit_target
= aarch64_deinit_target
,
3285 .examine
= aarch64_examine
,
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)