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);
96 instr
= ARMV4_5_MCR(15, 0, 0, 1, 0, 0);
100 LOG_ERROR("cannot read system control register in this mode: (%s : 0x%x)",
101 armv8_mode_name(armv8
->arm
.core_mode
), armv8
->arm
.core_mode
);
105 if (target_mode
!= ARM_MODE_ANY
)
106 armv8_dpm_modeswitch(&armv8
->dpm
, target_mode
);
108 retval
= armv8
->dpm
.instr_write_data_r0(&armv8
->dpm
, instr
, aarch64
->system_control_reg
);
109 if (retval
!= ERROR_OK
)
112 if (target_mode
!= ARM_MODE_ANY
)
113 armv8_dpm_modeswitch(&armv8
->dpm
, ARM_MODE_ANY
);
119 /* modify system_control_reg in order to enable or disable mmu for :
120 * - virt2phys address conversion
121 * - read or write memory in phys or virt address */
122 static int aarch64_mmu_modify(struct target
*target
, int enable
)
124 struct aarch64_common
*aarch64
= target_to_aarch64(target
);
125 struct armv8_common
*armv8
= &aarch64
->armv8_common
;
126 int retval
= ERROR_OK
;
127 enum arm_mode target_mode
= ARM_MODE_ANY
;
131 /* if mmu enabled at target stop and mmu not enable */
132 if (!(aarch64
->system_control_reg
& 0x1U
)) {
133 LOG_ERROR("trying to enable mmu on target stopped with mmu disable");
136 if (!(aarch64
->system_control_reg_curr
& 0x1U
))
137 aarch64
->system_control_reg_curr
|= 0x1U
;
139 if (aarch64
->system_control_reg_curr
& 0x4U
) {
140 /* data cache is active */
141 aarch64
->system_control_reg_curr
&= ~0x4U
;
142 /* flush data cache armv8 function to be called */
143 if (armv8
->armv8_mmu
.armv8_cache
.flush_all_data_cache
)
144 armv8
->armv8_mmu
.armv8_cache
.flush_all_data_cache(target
);
146 if ((aarch64
->system_control_reg_curr
& 0x1U
)) {
147 aarch64
->system_control_reg_curr
&= ~0x1U
;
151 switch (armv8
->arm
.core_mode
) {
153 target_mode
= ARMV8_64_EL1H
;
157 instr
= ARMV8_MSR_GP(SYSTEM_SCTLR_EL1
, 0);
161 instr
= ARMV8_MSR_GP(SYSTEM_SCTLR_EL2
, 0);
165 instr
= ARMV8_MSR_GP(SYSTEM_SCTLR_EL3
, 0);
175 instr
= ARMV4_5_MCR(15, 0, 0, 1, 0, 0);
179 LOG_DEBUG("unknown cpu state 0x%x", armv8
->arm
.core_mode
);
182 if (target_mode
!= ARM_MODE_ANY
)
183 armv8_dpm_modeswitch(&armv8
->dpm
, target_mode
);
185 retval
= armv8
->dpm
.instr_write_data_r0(&armv8
->dpm
, instr
,
186 aarch64
->system_control_reg_curr
);
188 if (target_mode
!= ARM_MODE_ANY
)
189 armv8_dpm_modeswitch(&armv8
->dpm
, ARM_MODE_ANY
);
195 * Basic debug access, very low level assumes state is saved
197 static int aarch64_init_debug_access(struct target
*target
)
199 struct armv8_common
*armv8
= target_to_armv8(target
);
203 LOG_DEBUG("%s", target_name(target
));
205 retval
= mem_ap_write_atomic_u32(armv8
->debug_ap
,
206 armv8
->debug_base
+ CPUV8_DBG_OSLAR
, 0);
207 if (retval
!= ERROR_OK
) {
208 LOG_DEBUG("Examine %s failed", "oslock");
212 /* Clear Sticky Power Down status Bit in PRSR to enable access to
213 the registers in the Core Power Domain */
214 retval
= mem_ap_read_atomic_u32(armv8
->debug_ap
,
215 armv8
->debug_base
+ CPUV8_DBG_PRSR
, &dummy
);
216 if (retval
!= ERROR_OK
)
220 * Static CTI configuration:
221 * Channel 0 -> trigger outputs HALT request to PE
222 * Channel 1 -> trigger outputs Resume request to PE
223 * Gate all channel trigger events from entering the CTM
227 retval
= arm_cti_enable(armv8
->cti
, true);
228 /* By default, gate all channel events to and from the CTM */
229 if (retval
== ERROR_OK
)
230 retval
= arm_cti_write_reg(armv8
->cti
, CTI_GATE
, 0);
231 /* output halt requests to PE on channel 0 event */
232 if (retval
== ERROR_OK
)
233 retval
= arm_cti_write_reg(armv8
->cti
, CTI_OUTEN0
, CTI_CHNL(0));
234 /* output restart requests to PE on channel 1 event */
235 if (retval
== ERROR_OK
)
236 retval
= arm_cti_write_reg(armv8
->cti
, CTI_OUTEN1
, CTI_CHNL(1));
237 if (retval
!= ERROR_OK
)
240 /* Resync breakpoint registers */
245 /* Write to memory mapped registers directly with no cache or mmu handling */
246 static int aarch64_dap_write_memap_register_u32(struct target
*target
,
247 target_addr_t address
,
251 struct armv8_common
*armv8
= target_to_armv8(target
);
253 retval
= mem_ap_write_atomic_u32(armv8
->debug_ap
, address
, value
);
258 static int aarch64_dpm_setup(struct aarch64_common
*a8
, uint64_t debug
)
260 struct arm_dpm
*dpm
= &a8
->armv8_common
.dpm
;
263 dpm
->arm
= &a8
->armv8_common
.arm
;
266 retval
= armv8_dpm_setup(dpm
);
267 if (retval
== ERROR_OK
)
268 retval
= armv8_dpm_initialize(dpm
);
273 static int aarch64_set_dscr_bits(struct target
*target
, unsigned long bit_mask
, unsigned long value
)
275 struct armv8_common
*armv8
= target_to_armv8(target
);
276 return armv8_set_dbgreg_bits(armv8
, CPUV8_DBG_DSCR
, bit_mask
, value
);
279 static int aarch64_check_state_one(struct target
*target
,
280 uint32_t mask
, uint32_t val
, int *p_result
, uint32_t *p_prsr
)
282 struct armv8_common
*armv8
= target_to_armv8(target
);
286 retval
= mem_ap_read_atomic_u32(armv8
->debug_ap
,
287 armv8
->debug_base
+ CPUV8_DBG_PRSR
, &prsr
);
288 if (retval
!= ERROR_OK
)
295 *p_result
= (prsr
& mask
) == (val
& mask
);
300 static int aarch64_wait_halt_one(struct target
*target
)
302 int retval
= ERROR_OK
;
305 int64_t then
= timeval_ms();
309 retval
= aarch64_check_state_one(target
, PRSR_HALT
, PRSR_HALT
, &halted
, &prsr
);
310 if (retval
!= ERROR_OK
|| halted
)
313 if (timeval_ms() > then
+ 1000) {
314 retval
= ERROR_TARGET_TIMEOUT
;
315 LOG_DEBUG("target %s timeout, prsr=0x%08"PRIx32
, target_name(target
), prsr
);
322 static int aarch64_prepare_halt_smp(struct target
*target
, bool exc_target
, struct target
**p_first
)
324 int retval
= ERROR_OK
;
325 struct target_list
*head
;
326 struct target
*first
= NULL
;
328 LOG_DEBUG("target %s exc %i", target_name(target
), exc_target
);
330 foreach_smp_target(head
, target
->smp_targets
) {
331 struct target
*curr
= head
->target
;
332 struct armv8_common
*armv8
= target_to_armv8(curr
);
334 if (exc_target
&& curr
== target
)
336 if (!target_was_examined(curr
))
338 if (curr
->state
!= TARGET_RUNNING
)
341 /* HACK: mark this target as prepared for halting */
342 curr
->debug_reason
= DBG_REASON_DBGRQ
;
344 /* open the gate for channel 0 to let HALT requests pass to the CTM */
345 retval
= arm_cti_ungate_channel(armv8
->cti
, 0);
346 if (retval
== ERROR_OK
)
347 retval
= aarch64_set_dscr_bits(curr
, DSCR_HDE
, DSCR_HDE
);
348 if (retval
!= ERROR_OK
)
351 LOG_DEBUG("target %s prepared", target_name(curr
));
358 if (exc_target
&& first
)
367 static int aarch64_halt_one(struct target
*target
, enum halt_mode mode
)
369 int retval
= ERROR_OK
;
370 struct armv8_common
*armv8
= target_to_armv8(target
);
372 LOG_DEBUG("%s", target_name(target
));
374 /* allow Halting Debug Mode */
375 retval
= aarch64_set_dscr_bits(target
, DSCR_HDE
, DSCR_HDE
);
376 if (retval
!= ERROR_OK
)
379 /* trigger an event on channel 0, this outputs a halt request to the PE */
380 retval
= arm_cti_pulse_channel(armv8
->cti
, 0);
381 if (retval
!= ERROR_OK
)
384 if (mode
== HALT_SYNC
) {
385 retval
= aarch64_wait_halt_one(target
);
386 if (retval
!= ERROR_OK
) {
387 if (retval
== ERROR_TARGET_TIMEOUT
)
388 LOG_ERROR("Timeout waiting for target %s halt", target_name(target
));
396 static int aarch64_halt_smp(struct target
*target
, bool exc_target
)
398 struct target
*next
= target
;
401 /* prepare halt on all PEs of the group */
402 retval
= aarch64_prepare_halt_smp(target
, exc_target
, &next
);
404 if (exc_target
&& next
== target
)
407 /* halt the target PE */
408 if (retval
== ERROR_OK
)
409 retval
= aarch64_halt_one(next
, HALT_LAZY
);
411 if (retval
!= ERROR_OK
)
414 /* wait for all PEs to halt */
415 int64_t then
= timeval_ms();
417 bool all_halted
= true;
418 struct target_list
*head
;
421 foreach_smp_target(head
, target
->smp_targets
) {
426 if (!target_was_examined(curr
))
429 retval
= aarch64_check_state_one(curr
, PRSR_HALT
, PRSR_HALT
, &halted
, NULL
);
430 if (retval
!= ERROR_OK
|| !halted
) {
439 if (timeval_ms() > then
+ 1000) {
440 retval
= ERROR_TARGET_TIMEOUT
;
445 * HACK: on Hi6220 there are 8 cores organized in 2 clusters
446 * and it looks like the CTI's are not connected by a common
447 * trigger matrix. It seems that we need to halt one core in each
448 * cluster explicitly. So if we find that a core has not halted
449 * yet, we trigger an explicit halt for the second cluster.
451 retval
= aarch64_halt_one(curr
, HALT_LAZY
);
452 if (retval
!= ERROR_OK
)
459 static int update_halt_gdb(struct target
*target
, enum target_debug_reason debug_reason
)
461 struct target
*gdb_target
= NULL
;
462 struct target_list
*head
;
465 if (debug_reason
== DBG_REASON_NOTHALTED
) {
466 LOG_DEBUG("Halting remaining targets in SMP group");
467 aarch64_halt_smp(target
, true);
470 /* poll all targets in the group, but skip the target that serves GDB */
471 foreach_smp_target(head
, target
->smp_targets
) {
473 /* skip calling context */
476 if (!target_was_examined(curr
))
478 /* skip targets that were already halted */
479 if (curr
->state
== TARGET_HALTED
)
481 /* remember the gdb_service->target */
482 if (curr
->gdb_service
)
483 gdb_target
= curr
->gdb_service
->target
;
485 if (curr
== gdb_target
)
488 /* avoid recursion in aarch64_poll() */
494 /* after all targets were updated, poll the gdb serving target */
495 if (gdb_target
&& gdb_target
!= target
)
496 aarch64_poll(gdb_target
);
502 * Aarch64 Run control
505 static int aarch64_poll(struct target
*target
)
507 enum target_state prev_target_state
;
508 int retval
= ERROR_OK
;
511 retval
= aarch64_check_state_one(target
,
512 PRSR_HALT
, PRSR_HALT
, &halted
, NULL
);
513 if (retval
!= ERROR_OK
)
517 prev_target_state
= target
->state
;
518 if (prev_target_state
!= TARGET_HALTED
) {
519 enum target_debug_reason debug_reason
= target
->debug_reason
;
521 /* We have a halting debug event */
522 target
->state
= TARGET_HALTED
;
523 LOG_DEBUG("Target %s halted", target_name(target
));
524 retval
= aarch64_debug_entry(target
);
525 if (retval
!= ERROR_OK
)
529 update_halt_gdb(target
, debug_reason
);
531 if (arm_semihosting(target
, &retval
) != 0)
534 switch (prev_target_state
) {
538 target_call_event_callbacks(target
, TARGET_EVENT_HALTED
);
540 case TARGET_DEBUG_RUNNING
:
541 target_call_event_callbacks(target
, TARGET_EVENT_DEBUG_HALTED
);
548 target
->state
= TARGET_RUNNING
;
553 static int aarch64_halt(struct target
*target
)
555 struct armv8_common
*armv8
= target_to_armv8(target
);
556 armv8
->last_run_control_op
= ARMV8_RUNCONTROL_HALT
;
559 return aarch64_halt_smp(target
, false);
561 return aarch64_halt_one(target
, HALT_SYNC
);
564 static int aarch64_restore_one(struct target
*target
, int current
,
565 uint64_t *address
, int handle_breakpoints
, int debug_execution
)
567 struct armv8_common
*armv8
= target_to_armv8(target
);
568 struct arm
*arm
= &armv8
->arm
;
572 LOG_DEBUG("%s", target_name(target
));
574 if (!debug_execution
)
575 target_free_all_working_areas(target
);
577 /* current = 1: continue on current pc, otherwise continue at <address> */
578 resume_pc
= buf_get_u64(arm
->pc
->value
, 0, 64);
580 resume_pc
= *address
;
582 *address
= resume_pc
;
584 /* Make sure that the Armv7 gdb thumb fixups does not
585 * kill the return address
587 switch (arm
->core_state
) {
589 resume_pc
&= 0xFFFFFFFC;
591 case ARM_STATE_AARCH64
:
592 resume_pc
&= 0xFFFFFFFFFFFFFFFCULL
;
594 case ARM_STATE_THUMB
:
595 case ARM_STATE_THUMB_EE
:
596 /* When the return address is loaded into PC
597 * bit 0 must be 1 to stay in Thumb state
601 case ARM_STATE_JAZELLE
:
602 LOG_ERROR("How do I resume into Jazelle state??");
605 LOG_DEBUG("resume pc = 0x%016" PRIx64
, resume_pc
);
606 buf_set_u64(arm
->pc
->value
, 0, 64, resume_pc
);
607 arm
->pc
->dirty
= true;
608 arm
->pc
->valid
= true;
610 /* called it now before restoring context because it uses cpu
611 * register r0 for restoring system control register */
612 retval
= aarch64_restore_system_control_reg(target
);
613 if (retval
== ERROR_OK
)
614 retval
= aarch64_restore_context(target
, handle_breakpoints
);
620 * prepare single target for restart
624 static int aarch64_prepare_restart_one(struct target
*target
)
626 struct armv8_common
*armv8
= target_to_armv8(target
);
631 LOG_DEBUG("%s", target_name(target
));
633 retval
= mem_ap_read_atomic_u32(armv8
->debug_ap
,
634 armv8
->debug_base
+ CPUV8_DBG_DSCR
, &dscr
);
635 if (retval
!= ERROR_OK
)
638 if ((dscr
& DSCR_ITE
) == 0)
639 LOG_ERROR("DSCR.ITE must be set before leaving debug!");
640 if ((dscr
& DSCR_ERR
) != 0)
641 LOG_ERROR("DSCR.ERR must be cleared before leaving debug!");
643 /* acknowledge a pending CTI halt event */
644 retval
= arm_cti_ack_events(armv8
->cti
, CTI_TRIG(HALT
));
646 * open the CTI gate for channel 1 so that the restart events
647 * get passed along to all PEs. Also close gate for channel 0
648 * to isolate the PE from halt events.
650 if (retval
== ERROR_OK
)
651 retval
= arm_cti_ungate_channel(armv8
->cti
, 1);
652 if (retval
== ERROR_OK
)
653 retval
= arm_cti_gate_channel(armv8
->cti
, 0);
655 /* make sure that DSCR.HDE is set */
656 if (retval
== ERROR_OK
) {
658 retval
= mem_ap_write_atomic_u32(armv8
->debug_ap
,
659 armv8
->debug_base
+ CPUV8_DBG_DSCR
, dscr
);
662 if (retval
== ERROR_OK
) {
663 /* clear sticky bits in PRSR, SDR is now 0 */
664 retval
= mem_ap_read_atomic_u32(armv8
->debug_ap
,
665 armv8
->debug_base
+ CPUV8_DBG_PRSR
, &tmp
);
671 static int aarch64_do_restart_one(struct target
*target
, enum restart_mode mode
)
673 struct armv8_common
*armv8
= target_to_armv8(target
);
676 LOG_DEBUG("%s", target_name(target
));
678 /* trigger an event on channel 1, generates a restart request to the PE */
679 retval
= arm_cti_pulse_channel(armv8
->cti
, 1);
680 if (retval
!= ERROR_OK
)
683 if (mode
== RESTART_SYNC
) {
684 int64_t then
= timeval_ms();
688 * if PRSR.SDR is set now, the target did restart, even
689 * if it's now already halted again (e.g. due to breakpoint)
691 retval
= aarch64_check_state_one(target
,
692 PRSR_SDR
, PRSR_SDR
, &resumed
, NULL
);
693 if (retval
!= ERROR_OK
|| resumed
)
696 if (timeval_ms() > then
+ 1000) {
697 LOG_ERROR("%s: Timeout waiting for resume"PRIx32
, target_name(target
));
698 retval
= ERROR_TARGET_TIMEOUT
;
704 if (retval
!= ERROR_OK
)
707 target
->debug_reason
= DBG_REASON_NOTHALTED
;
708 target
->state
= TARGET_RUNNING
;
713 static int aarch64_restart_one(struct target
*target
, enum restart_mode mode
)
717 LOG_DEBUG("%s", target_name(target
));
719 retval
= aarch64_prepare_restart_one(target
);
720 if (retval
== ERROR_OK
)
721 retval
= aarch64_do_restart_one(target
, mode
);
727 * prepare all but the current target for restart
729 static int aarch64_prep_restart_smp(struct target
*target
, int handle_breakpoints
, struct target
**p_first
)
731 int retval
= ERROR_OK
;
732 struct target_list
*head
;
733 struct target
*first
= NULL
;
736 foreach_smp_target(head
, target
->smp_targets
) {
737 struct target
*curr
= head
->target
;
739 /* skip calling target */
742 if (!target_was_examined(curr
))
744 if (curr
->state
!= TARGET_HALTED
)
747 /* resume at current address, not in step mode */
748 retval
= aarch64_restore_one(curr
, 1, &address
, handle_breakpoints
, 0);
749 if (retval
== ERROR_OK
)
750 retval
= aarch64_prepare_restart_one(curr
);
751 if (retval
!= ERROR_OK
) {
752 LOG_ERROR("failed to restore target %s", target_name(curr
));
755 /* remember the first valid target in the group */
767 static int aarch64_step_restart_smp(struct target
*target
)
769 int retval
= ERROR_OK
;
770 struct target_list
*head
;
771 struct target
*first
= NULL
;
773 LOG_DEBUG("%s", target_name(target
));
775 retval
= aarch64_prep_restart_smp(target
, 0, &first
);
776 if (retval
!= ERROR_OK
)
780 retval
= aarch64_do_restart_one(first
, RESTART_LAZY
);
781 if (retval
!= ERROR_OK
) {
782 LOG_DEBUG("error restarting target %s", target_name(first
));
786 int64_t then
= timeval_ms();
788 struct target
*curr
= target
;
789 bool all_resumed
= true;
791 foreach_smp_target(head
, target
->smp_targets
) {
800 if (!target_was_examined(curr
))
803 retval
= aarch64_check_state_one(curr
,
804 PRSR_SDR
, PRSR_SDR
, &resumed
, &prsr
);
805 if (retval
!= ERROR_OK
|| (!resumed
&& (prsr
& PRSR_HALT
))) {
810 if (curr
->state
!= TARGET_RUNNING
) {
811 curr
->state
= TARGET_RUNNING
;
812 curr
->debug_reason
= DBG_REASON_NOTHALTED
;
813 target_call_event_callbacks(curr
, TARGET_EVENT_RESUMED
);
820 if (timeval_ms() > then
+ 1000) {
821 LOG_ERROR("%s: timeout waiting for target resume", __func__
);
822 retval
= ERROR_TARGET_TIMEOUT
;
826 * HACK: on Hi6220 there are 8 cores organized in 2 clusters
827 * and it looks like the CTI's are not connected by a common
828 * trigger matrix. It seems that we need to halt one core in each
829 * cluster explicitly. So if we find that a core has not halted
830 * yet, we trigger an explicit resume for the second cluster.
832 retval
= aarch64_do_restart_one(curr
, RESTART_LAZY
);
833 if (retval
!= ERROR_OK
)
840 static int aarch64_resume(struct target
*target
, int current
,
841 target_addr_t address
, int handle_breakpoints
, int debug_execution
)
844 uint64_t addr
= address
;
846 struct armv8_common
*armv8
= target_to_armv8(target
);
847 armv8
->last_run_control_op
= ARMV8_RUNCONTROL_RESUME
;
849 if (target
->state
!= TARGET_HALTED
) {
850 LOG_TARGET_ERROR(target
, "not halted");
851 return ERROR_TARGET_NOT_HALTED
;
855 * If this target is part of a SMP group, prepare the others
856 * targets for resuming. This involves restoring the complete
857 * target register context and setting up CTI gates to accept
858 * resume events from the trigger matrix.
861 retval
= aarch64_prep_restart_smp(target
, handle_breakpoints
, NULL
);
862 if (retval
!= ERROR_OK
)
866 /* all targets prepared, restore and restart the current target */
867 retval
= aarch64_restore_one(target
, current
, &addr
, handle_breakpoints
,
869 if (retval
== ERROR_OK
)
870 retval
= aarch64_restart_one(target
, RESTART_SYNC
);
871 if (retval
!= ERROR_OK
)
875 int64_t then
= timeval_ms();
877 struct target
*curr
= target
;
878 struct target_list
*head
;
879 bool all_resumed
= true;
881 foreach_smp_target(head
, target
->smp_targets
) {
888 if (!target_was_examined(curr
))
891 retval
= aarch64_check_state_one(curr
,
892 PRSR_SDR
, PRSR_SDR
, &resumed
, &prsr
);
893 if (retval
!= ERROR_OK
|| (!resumed
&& (prsr
& PRSR_HALT
))) {
898 if (curr
->state
!= TARGET_RUNNING
) {
899 curr
->state
= TARGET_RUNNING
;
900 curr
->debug_reason
= DBG_REASON_NOTHALTED
;
901 target_call_event_callbacks(curr
, TARGET_EVENT_RESUMED
);
908 if (timeval_ms() > then
+ 1000) {
909 LOG_ERROR("%s: timeout waiting for target %s to resume", __func__
, target_name(curr
));
910 retval
= ERROR_TARGET_TIMEOUT
;
915 * HACK: on Hi6220 there are 8 cores organized in 2 clusters
916 * and it looks like the CTI's are not connected by a common
917 * trigger matrix. It seems that we need to halt one core in each
918 * cluster explicitly. So if we find that a core has not halted
919 * yet, we trigger an explicit resume for the second cluster.
921 retval
= aarch64_do_restart_one(curr
, RESTART_LAZY
);
922 if (retval
!= ERROR_OK
)
927 if (retval
!= ERROR_OK
)
930 target
->debug_reason
= DBG_REASON_NOTHALTED
;
932 if (!debug_execution
) {
933 target
->state
= TARGET_RUNNING
;
934 target_call_event_callbacks(target
, TARGET_EVENT_RESUMED
);
935 LOG_DEBUG("target resumed at 0x%" PRIx64
, addr
);
937 target
->state
= TARGET_DEBUG_RUNNING
;
938 target_call_event_callbacks(target
, TARGET_EVENT_DEBUG_RESUMED
);
939 LOG_DEBUG("target debug resumed at 0x%" PRIx64
, addr
);
945 static int aarch64_debug_entry(struct target
*target
)
947 int retval
= ERROR_OK
;
948 struct armv8_common
*armv8
= target_to_armv8(target
);
949 struct arm_dpm
*dpm
= &armv8
->dpm
;
950 enum arm_state core_state
;
953 /* make sure to clear all sticky errors */
954 retval
= mem_ap_write_atomic_u32(armv8
->debug_ap
,
955 armv8
->debug_base
+ CPUV8_DBG_DRCR
, DRCR_CSE
);
956 if (retval
== ERROR_OK
)
957 retval
= mem_ap_read_atomic_u32(armv8
->debug_ap
,
958 armv8
->debug_base
+ CPUV8_DBG_DSCR
, &dscr
);
959 if (retval
== ERROR_OK
)
960 retval
= arm_cti_ack_events(armv8
->cti
, CTI_TRIG(HALT
));
962 if (retval
!= ERROR_OK
)
965 LOG_DEBUG("%s dscr = 0x%08" PRIx32
, target_name(target
), dscr
);
968 core_state
= armv8_dpm_get_core_state(dpm
);
969 armv8_select_opcodes(armv8
, core_state
== ARM_STATE_AARCH64
);
970 armv8_select_reg_access(armv8
, core_state
== ARM_STATE_AARCH64
);
972 /* close the CTI gate for all events */
973 if (retval
== ERROR_OK
)
974 retval
= arm_cti_write_reg(armv8
->cti
, CTI_GATE
, 0);
975 /* discard async exceptions */
976 if (retval
== ERROR_OK
)
977 retval
= dpm
->instr_cpsr_sync(dpm
);
978 if (retval
!= ERROR_OK
)
981 /* Examine debug reason */
982 armv8_dpm_report_dscr(dpm
, dscr
);
984 /* save the memory address that triggered the watchpoint */
985 if (target
->debug_reason
== DBG_REASON_WATCHPOINT
) {
988 retval
= mem_ap_read_atomic_u32(armv8
->debug_ap
,
989 armv8
->debug_base
+ CPUV8_DBG_EDWAR0
, &tmp
);
990 if (retval
!= ERROR_OK
)
992 target_addr_t edwar
= tmp
;
994 /* EDWAR[63:32] has unknown content in aarch32 state */
995 if (core_state
== ARM_STATE_AARCH64
) {
996 retval
= mem_ap_read_atomic_u32(armv8
->debug_ap
,
997 armv8
->debug_base
+ CPUV8_DBG_EDWAR1
, &tmp
);
998 if (retval
!= ERROR_OK
)
1000 edwar
|= ((target_addr_t
)tmp
) << 32;
1003 armv8
->dpm
.wp_addr
= edwar
;
1006 retval
= armv8_dpm_read_current_registers(&armv8
->dpm
);
1008 if (retval
== ERROR_OK
&& armv8
->post_debug_entry
)
1009 retval
= armv8
->post_debug_entry(target
);
1014 static int aarch64_post_debug_entry(struct target
*target
)
1016 struct aarch64_common
*aarch64
= target_to_aarch64(target
);
1017 struct armv8_common
*armv8
= &aarch64
->armv8_common
;
1019 enum arm_mode target_mode
= ARM_MODE_ANY
;
1022 switch (armv8
->arm
.core_mode
) {
1024 target_mode
= ARMV8_64_EL1H
;
1028 instr
= ARMV8_MRS(SYSTEM_SCTLR_EL1
, 0);
1032 instr
= ARMV8_MRS(SYSTEM_SCTLR_EL2
, 0);
1036 instr
= ARMV8_MRS(SYSTEM_SCTLR_EL3
, 0);
1046 instr
= ARMV4_5_MRC(15, 0, 0, 1, 0, 0);
1050 LOG_ERROR("cannot read system control register in this mode: (%s : 0x%x)",
1051 armv8_mode_name(armv8
->arm
.core_mode
), armv8
->arm
.core_mode
);
1055 if (target_mode
!= ARM_MODE_ANY
)
1056 armv8_dpm_modeswitch(&armv8
->dpm
, target_mode
);
1058 retval
= armv8
->dpm
.instr_read_data_r0(&armv8
->dpm
, instr
, &aarch64
->system_control_reg
);
1059 if (retval
!= ERROR_OK
)
1062 if (target_mode
!= ARM_MODE_ANY
)
1063 armv8_dpm_modeswitch(&armv8
->dpm
, ARM_MODE_ANY
);
1065 LOG_DEBUG("System_register: %8.8" PRIx32
, aarch64
->system_control_reg
);
1066 aarch64
->system_control_reg_curr
= aarch64
->system_control_reg
;
1068 if (armv8
->armv8_mmu
.armv8_cache
.info
== -1) {
1069 armv8_identify_cache(armv8
);
1070 armv8_read_mpidr(armv8
);
1072 if (armv8
->is_armv8r
) {
1073 armv8
->armv8_mmu
.mmu_enabled
= 0;
1075 armv8
->armv8_mmu
.mmu_enabled
=
1076 (aarch64
->system_control_reg
& 0x1U
) ? 1 : 0;
1078 armv8
->armv8_mmu
.armv8_cache
.d_u_cache_enabled
=
1079 (aarch64
->system_control_reg
& 0x4U
) ? 1 : 0;
1080 armv8
->armv8_mmu
.armv8_cache
.i_cache_enabled
=
1081 (aarch64
->system_control_reg
& 0x1000U
) ? 1 : 0;
1086 * single-step a target
1088 static int aarch64_step(struct target
*target
, int current
, target_addr_t address
,
1089 int handle_breakpoints
)
1091 struct armv8_common
*armv8
= target_to_armv8(target
);
1092 struct aarch64_common
*aarch64
= target_to_aarch64(target
);
1093 int saved_retval
= ERROR_OK
;
1097 armv8
->last_run_control_op
= ARMV8_RUNCONTROL_STEP
;
1099 if (target
->state
!= TARGET_HALTED
) {
1100 LOG_TARGET_ERROR(target
, "not halted");
1101 return ERROR_TARGET_NOT_HALTED
;
1104 retval
= mem_ap_read_atomic_u32(armv8
->debug_ap
,
1105 armv8
->debug_base
+ CPUV8_DBG_EDECR
, &edecr
);
1106 /* make sure EDECR.SS is not set when restoring the register */
1108 if (retval
== ERROR_OK
) {
1110 /* set EDECR.SS to enter hardware step mode */
1111 retval
= mem_ap_write_atomic_u32(armv8
->debug_ap
,
1112 armv8
->debug_base
+ CPUV8_DBG_EDECR
, (edecr
|0x4));
1114 /* disable interrupts while stepping */
1115 if (retval
== ERROR_OK
&& aarch64
->isrmasking_mode
== AARCH64_ISRMASK_ON
)
1116 retval
= aarch64_set_dscr_bits(target
, 0x3 << 22, 0x3 << 22);
1117 /* bail out if stepping setup has failed */
1118 if (retval
!= ERROR_OK
)
1121 if (target
->smp
&& (current
== 1)) {
1123 * isolate current target so that it doesn't get resumed
1124 * together with the others
1126 retval
= arm_cti_gate_channel(armv8
->cti
, 1);
1127 /* resume all other targets in the group */
1128 if (retval
== ERROR_OK
)
1129 retval
= aarch64_step_restart_smp(target
);
1130 if (retval
!= ERROR_OK
) {
1131 LOG_ERROR("Failed to restart non-stepping targets in SMP group");
1134 LOG_DEBUG("Restarted all non-stepping targets in SMP group");
1137 /* all other targets running, restore and restart the current target */
1138 retval
= aarch64_restore_one(target
, current
, &address
, 0, 0);
1139 if (retval
== ERROR_OK
)
1140 retval
= aarch64_restart_one(target
, RESTART_LAZY
);
1142 if (retval
!= ERROR_OK
)
1145 LOG_DEBUG("target step-resumed at 0x%" PRIx64
, address
);
1146 if (!handle_breakpoints
)
1147 target_call_event_callbacks(target
, TARGET_EVENT_RESUMED
);
1149 int64_t then
= timeval_ms();
1154 retval
= aarch64_check_state_one(target
,
1155 PRSR_SDR
|PRSR_HALT
, PRSR_SDR
|PRSR_HALT
, &stepped
, &prsr
);
1156 if (retval
!= ERROR_OK
|| stepped
)
1159 if (timeval_ms() > then
+ 100) {
1160 LOG_ERROR("timeout waiting for target %s halt after step",
1161 target_name(target
));
1162 retval
= ERROR_TARGET_TIMEOUT
;
1168 * At least on one SoC (Renesas R8A7795) stepping over a WFI instruction
1169 * causes a timeout. The core takes the step but doesn't complete it and so
1170 * debug state is never entered. However, you can manually halt the core
1171 * as an external debug even is also a WFI wakeup event.
1173 if (retval
== ERROR_TARGET_TIMEOUT
)
1174 saved_retval
= aarch64_halt_one(target
, HALT_SYNC
);
1177 retval
= mem_ap_write_atomic_u32(armv8
->debug_ap
,
1178 armv8
->debug_base
+ CPUV8_DBG_EDECR
, edecr
);
1179 if (retval
!= ERROR_OK
)
1182 /* restore interrupts */
1183 if (aarch64
->isrmasking_mode
== AARCH64_ISRMASK_ON
) {
1184 retval
= aarch64_set_dscr_bits(target
, 0x3 << 22, 0);
1185 if (retval
!= ERROR_OK
)
1189 if (saved_retval
!= ERROR_OK
)
1190 return saved_retval
;
1195 static int aarch64_restore_context(struct target
*target
, bool bpwp
)
1197 struct armv8_common
*armv8
= target_to_armv8(target
);
1198 struct arm
*arm
= &armv8
->arm
;
1202 LOG_DEBUG("%s", target_name(target
));
1204 if (armv8
->pre_restore_context
)
1205 armv8
->pre_restore_context(target
);
1207 retval
= armv8_dpm_write_dirty_registers(&armv8
->dpm
, bpwp
);
1208 if (retval
== ERROR_OK
) {
1209 /* registers are now invalid */
1210 register_cache_invalidate(arm
->core_cache
);
1211 register_cache_invalidate(arm
->core_cache
->next
);
1218 * Cortex-A8 Breakpoint and watchpoint functions
1221 /* Setup hardware Breakpoint Register Pair */
1222 static int aarch64_set_breakpoint(struct target
*target
,
1223 struct breakpoint
*breakpoint
, uint8_t matchmode
)
1228 uint8_t byte_addr_select
= 0x0F;
1229 struct aarch64_common
*aarch64
= target_to_aarch64(target
);
1230 struct armv8_common
*armv8
= &aarch64
->armv8_common
;
1231 struct aarch64_brp
*brp_list
= aarch64
->brp_list
;
1233 if (breakpoint
->is_set
) {
1234 LOG_WARNING("breakpoint already set");
1238 if (breakpoint
->type
== BKPT_HARD
) {
1240 while (brp_list
[brp_i
].used
&& (brp_i
< aarch64
->brp_num
))
1242 if (brp_i
>= aarch64
->brp_num
) {
1243 LOG_ERROR("ERROR Can not find free Breakpoint Register Pair");
1244 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1246 breakpoint_hw_set(breakpoint
, brp_i
);
1247 if (breakpoint
->length
== 2)
1248 byte_addr_select
= (3 << (breakpoint
->address
& 0x02));
1249 control
= ((matchmode
& 0x7) << 20)
1251 | (byte_addr_select
<< 5)
1253 brp_list
[brp_i
].used
= 1;
1254 brp_list
[brp_i
].value
= breakpoint
->address
& 0xFFFFFFFFFFFFFFFCULL
;
1255 brp_list
[brp_i
].control
= control
;
1256 bpt_value
= brp_list
[brp_i
].value
;
1258 retval
= aarch64_dap_write_memap_register_u32(target
, armv8
->debug_base
1259 + CPUV8_DBG_BVR_BASE
+ 16 * brp_list
[brp_i
].brpn
,
1260 (uint32_t)(bpt_value
& 0xFFFFFFFF));
1261 if (retval
!= ERROR_OK
)
1263 retval
= aarch64_dap_write_memap_register_u32(target
, armv8
->debug_base
1264 + CPUV8_DBG_BVR_BASE
+ 4 + 16 * brp_list
[brp_i
].brpn
,
1265 (uint32_t)(bpt_value
>> 32));
1266 if (retval
!= ERROR_OK
)
1269 retval
= aarch64_dap_write_memap_register_u32(target
, armv8
->debug_base
1270 + CPUV8_DBG_BCR_BASE
+ 16 * brp_list
[brp_i
].brpn
,
1271 brp_list
[brp_i
].control
);
1272 if (retval
!= ERROR_OK
)
1274 LOG_DEBUG("brp %i control 0x%0" PRIx32
" value 0x%" TARGET_PRIxADDR
, brp_i
,
1275 brp_list
[brp_i
].control
,
1276 brp_list
[brp_i
].value
);
1278 } else if (breakpoint
->type
== BKPT_SOFT
) {
1282 if (armv8_dpm_get_core_state(&armv8
->dpm
) == ARM_STATE_AARCH64
) {
1283 opcode
= ARMV8_HLT(11);
1285 if (breakpoint
->length
!= 4)
1286 LOG_ERROR("bug: breakpoint length should be 4 in AArch64 mode");
1289 * core_state is ARM_STATE_ARM
1290 * in that case the opcode depends on breakpoint length:
1291 * - if length == 4 => A32 opcode
1292 * - if length == 2 => T32 opcode
1293 * - if length == 3 => T32 opcode (refer to gdb doc : ARM-Breakpoint-Kinds)
1294 * in that case the length should be changed from 3 to 4 bytes
1296 opcode
= (breakpoint
->length
== 4) ? ARMV8_HLT_A1(11) :
1297 (uint32_t) (ARMV8_HLT_T1(11) | ARMV8_HLT_T1(11) << 16);
1299 if (breakpoint
->length
== 3)
1300 breakpoint
->length
= 4;
1303 buf_set_u32(code
, 0, 32, opcode
);
1305 retval
= target_read_memory(target
,
1306 breakpoint
->address
& 0xFFFFFFFFFFFFFFFEULL
,
1307 breakpoint
->length
, 1,
1308 breakpoint
->orig_instr
);
1309 if (retval
!= ERROR_OK
)
1312 armv8_cache_d_inner_flush_virt(armv8
,
1313 breakpoint
->address
& 0xFFFFFFFFFFFFFFFEULL
,
1314 breakpoint
->length
);
1316 retval
= target_write_memory(target
,
1317 breakpoint
->address
& 0xFFFFFFFFFFFFFFFEULL
,
1318 breakpoint
->length
, 1, code
);
1319 if (retval
!= ERROR_OK
)
1322 armv8_cache_d_inner_flush_virt(armv8
,
1323 breakpoint
->address
& 0xFFFFFFFFFFFFFFFEULL
,
1324 breakpoint
->length
);
1326 armv8_cache_i_inner_inval_virt(armv8
,
1327 breakpoint
->address
& 0xFFFFFFFFFFFFFFFEULL
,
1328 breakpoint
->length
);
1330 breakpoint
->is_set
= true;
1333 /* Ensure that halting debug mode is enable */
1334 retval
= aarch64_set_dscr_bits(target
, DSCR_HDE
, DSCR_HDE
);
1335 if (retval
!= ERROR_OK
) {
1336 LOG_DEBUG("Failed to set DSCR.HDE");
1343 static int aarch64_set_context_breakpoint(struct target
*target
,
1344 struct breakpoint
*breakpoint
, uint8_t matchmode
)
1346 int retval
= ERROR_FAIL
;
1349 uint8_t byte_addr_select
= 0x0F;
1350 struct aarch64_common
*aarch64
= target_to_aarch64(target
);
1351 struct armv8_common
*armv8
= &aarch64
->armv8_common
;
1352 struct aarch64_brp
*brp_list
= aarch64
->brp_list
;
1354 if (breakpoint
->is_set
) {
1355 LOG_WARNING("breakpoint already set");
1358 /*check available context BRPs*/
1359 while ((brp_list
[brp_i
].used
||
1360 (brp_list
[brp_i
].type
!= BRP_CONTEXT
)) && (brp_i
< aarch64
->brp_num
))
1363 if (brp_i
>= aarch64
->brp_num
) {
1364 LOG_ERROR("ERROR Can not find free Breakpoint Register Pair");
1368 breakpoint_hw_set(breakpoint
, brp_i
);
1369 control
= ((matchmode
& 0x7) << 20)
1371 | (byte_addr_select
<< 5)
1373 brp_list
[brp_i
].used
= 1;
1374 brp_list
[brp_i
].value
= (breakpoint
->asid
);
1375 brp_list
[brp_i
].control
= control
;
1376 retval
= aarch64_dap_write_memap_register_u32(target
, armv8
->debug_base
1377 + CPUV8_DBG_BVR_BASE
+ 16 * brp_list
[brp_i
].brpn
,
1378 brp_list
[brp_i
].value
);
1379 if (retval
!= ERROR_OK
)
1381 retval
= aarch64_dap_write_memap_register_u32(target
, armv8
->debug_base
1382 + CPUV8_DBG_BCR_BASE
+ 16 * brp_list
[brp_i
].brpn
,
1383 brp_list
[brp_i
].control
);
1384 if (retval
!= ERROR_OK
)
1386 LOG_DEBUG("brp %i control 0x%0" PRIx32
" value 0x%" TARGET_PRIxADDR
, brp_i
,
1387 brp_list
[brp_i
].control
,
1388 brp_list
[brp_i
].value
);
1393 static int aarch64_set_hybrid_breakpoint(struct target
*target
, struct breakpoint
*breakpoint
)
1395 int retval
= ERROR_FAIL
;
1396 int brp_1
= 0; /* holds the contextID pair */
1397 int brp_2
= 0; /* holds the IVA pair */
1398 uint32_t control_ctx
, control_iva
;
1399 uint8_t ctx_byte_addr_select
= 0x0F;
1400 uint8_t iva_byte_addr_select
= 0x0F;
1401 uint8_t ctx_machmode
= 0x03;
1402 uint8_t iva_machmode
= 0x01;
1403 struct aarch64_common
*aarch64
= target_to_aarch64(target
);
1404 struct armv8_common
*armv8
= &aarch64
->armv8_common
;
1405 struct aarch64_brp
*brp_list
= aarch64
->brp_list
;
1407 if (breakpoint
->is_set
) {
1408 LOG_WARNING("breakpoint already set");
1411 /*check available context BRPs*/
1412 while ((brp_list
[brp_1
].used
||
1413 (brp_list
[brp_1
].type
!= BRP_CONTEXT
)) && (brp_1
< aarch64
->brp_num
))
1416 LOG_DEBUG("brp(CTX) found num: %d", brp_1
);
1417 if (brp_1
>= aarch64
->brp_num
) {
1418 LOG_ERROR("ERROR Can not find free Breakpoint Register Pair");
1422 while ((brp_list
[brp_2
].used
||
1423 (brp_list
[brp_2
].type
!= BRP_NORMAL
)) && (brp_2
< aarch64
->brp_num
))
1426 LOG_DEBUG("brp(IVA) found num: %d", brp_2
);
1427 if (brp_2
>= aarch64
->brp_num
) {
1428 LOG_ERROR("ERROR Can not find free Breakpoint Register Pair");
1432 breakpoint_hw_set(breakpoint
, brp_1
);
1433 breakpoint
->linked_brp
= brp_2
;
1434 control_ctx
= ((ctx_machmode
& 0x7) << 20)
1437 | (ctx_byte_addr_select
<< 5)
1439 brp_list
[brp_1
].used
= 1;
1440 brp_list
[brp_1
].value
= (breakpoint
->asid
);
1441 brp_list
[brp_1
].control
= control_ctx
;
1442 retval
= aarch64_dap_write_memap_register_u32(target
, armv8
->debug_base
1443 + CPUV8_DBG_BVR_BASE
+ 16 * brp_list
[brp_1
].brpn
,
1444 brp_list
[brp_1
].value
);
1445 if (retval
!= ERROR_OK
)
1447 retval
= aarch64_dap_write_memap_register_u32(target
, armv8
->debug_base
1448 + CPUV8_DBG_BCR_BASE
+ 16 * brp_list
[brp_1
].brpn
,
1449 brp_list
[brp_1
].control
);
1450 if (retval
!= ERROR_OK
)
1453 control_iva
= ((iva_machmode
& 0x7) << 20)
1456 | (iva_byte_addr_select
<< 5)
1458 brp_list
[brp_2
].used
= 1;
1459 brp_list
[brp_2
].value
= breakpoint
->address
& 0xFFFFFFFFFFFFFFFCULL
;
1460 brp_list
[brp_2
].control
= control_iva
;
1461 retval
= aarch64_dap_write_memap_register_u32(target
, armv8
->debug_base
1462 + CPUV8_DBG_BVR_BASE
+ 16 * brp_list
[brp_2
].brpn
,
1463 brp_list
[brp_2
].value
& 0xFFFFFFFF);
1464 if (retval
!= ERROR_OK
)
1466 retval
= aarch64_dap_write_memap_register_u32(target
, armv8
->debug_base
1467 + CPUV8_DBG_BVR_BASE
+ 4 + 16 * brp_list
[brp_2
].brpn
,
1468 brp_list
[brp_2
].value
>> 32);
1469 if (retval
!= ERROR_OK
)
1471 retval
= aarch64_dap_write_memap_register_u32(target
, armv8
->debug_base
1472 + CPUV8_DBG_BCR_BASE
+ 16 * brp_list
[brp_2
].brpn
,
1473 brp_list
[brp_2
].control
);
1474 if (retval
!= ERROR_OK
)
1480 static int aarch64_unset_breakpoint(struct target
*target
, struct breakpoint
*breakpoint
)
1483 struct aarch64_common
*aarch64
= target_to_aarch64(target
);
1484 struct armv8_common
*armv8
= &aarch64
->armv8_common
;
1485 struct aarch64_brp
*brp_list
= aarch64
->brp_list
;
1487 if (!breakpoint
->is_set
) {
1488 LOG_WARNING("breakpoint not set");
1492 if (breakpoint
->type
== BKPT_HARD
) {
1493 if ((breakpoint
->address
!= 0) && (breakpoint
->asid
!= 0)) {
1494 int brp_i
= breakpoint
->number
;
1495 int brp_j
= breakpoint
->linked_brp
;
1496 if (brp_i
>= aarch64
->brp_num
) {
1497 LOG_DEBUG("Invalid BRP number in breakpoint");
1500 LOG_DEBUG("rbp %i control 0x%0" PRIx32
" value 0x%" TARGET_PRIxADDR
, brp_i
,
1501 brp_list
[brp_i
].control
, brp_list
[brp_i
].value
);
1502 brp_list
[brp_i
].used
= 0;
1503 brp_list
[brp_i
].value
= 0;
1504 brp_list
[brp_i
].control
= 0;
1505 retval
= aarch64_dap_write_memap_register_u32(target
, armv8
->debug_base
1506 + CPUV8_DBG_BCR_BASE
+ 16 * brp_list
[brp_i
].brpn
,
1507 brp_list
[brp_i
].control
);
1508 if (retval
!= ERROR_OK
)
1510 retval
= aarch64_dap_write_memap_register_u32(target
, armv8
->debug_base
1511 + CPUV8_DBG_BVR_BASE
+ 16 * brp_list
[brp_i
].brpn
,
1512 (uint32_t)brp_list
[brp_i
].value
);
1513 if (retval
!= ERROR_OK
)
1515 retval
= aarch64_dap_write_memap_register_u32(target
, armv8
->debug_base
1516 + CPUV8_DBG_BVR_BASE
+ 4 + 16 * brp_list
[brp_i
].brpn
,
1517 (uint32_t)brp_list
[brp_i
].value
);
1518 if (retval
!= ERROR_OK
)
1520 if ((brp_j
< 0) || (brp_j
>= aarch64
->brp_num
)) {
1521 LOG_DEBUG("Invalid BRP number in breakpoint");
1524 LOG_DEBUG("rbp %i control 0x%0" PRIx32
" value 0x%0" PRIx64
, brp_j
,
1525 brp_list
[brp_j
].control
, brp_list
[brp_j
].value
);
1526 brp_list
[brp_j
].used
= 0;
1527 brp_list
[brp_j
].value
= 0;
1528 brp_list
[brp_j
].control
= 0;
1529 retval
= aarch64_dap_write_memap_register_u32(target
, armv8
->debug_base
1530 + CPUV8_DBG_BCR_BASE
+ 16 * brp_list
[brp_j
].brpn
,
1531 brp_list
[brp_j
].control
);
1532 if (retval
!= ERROR_OK
)
1534 retval
= aarch64_dap_write_memap_register_u32(target
, armv8
->debug_base
1535 + CPUV8_DBG_BVR_BASE
+ 16 * brp_list
[brp_j
].brpn
,
1536 (uint32_t)brp_list
[brp_j
].value
);
1537 if (retval
!= ERROR_OK
)
1539 retval
= aarch64_dap_write_memap_register_u32(target
, armv8
->debug_base
1540 + CPUV8_DBG_BVR_BASE
+ 4 + 16 * brp_list
[brp_j
].brpn
,
1541 (uint32_t)brp_list
[brp_j
].value
);
1542 if (retval
!= ERROR_OK
)
1545 breakpoint
->linked_brp
= 0;
1546 breakpoint
->is_set
= false;
1550 int brp_i
= breakpoint
->number
;
1551 if (brp_i
>= aarch64
->brp_num
) {
1552 LOG_DEBUG("Invalid BRP number in breakpoint");
1555 LOG_DEBUG("rbp %i control 0x%0" PRIx32
" value 0x%0" PRIx64
, brp_i
,
1556 brp_list
[brp_i
].control
, brp_list
[brp_i
].value
);
1557 brp_list
[brp_i
].used
= 0;
1558 brp_list
[brp_i
].value
= 0;
1559 brp_list
[brp_i
].control
= 0;
1560 retval
= aarch64_dap_write_memap_register_u32(target
, armv8
->debug_base
1561 + CPUV8_DBG_BCR_BASE
+ 16 * brp_list
[brp_i
].brpn
,
1562 brp_list
[brp_i
].control
);
1563 if (retval
!= ERROR_OK
)
1565 retval
= aarch64_dap_write_memap_register_u32(target
, armv8
->debug_base
1566 + CPUV8_DBG_BVR_BASE
+ 16 * brp_list
[brp_i
].brpn
,
1567 brp_list
[brp_i
].value
);
1568 if (retval
!= ERROR_OK
)
1571 retval
= aarch64_dap_write_memap_register_u32(target
, armv8
->debug_base
1572 + CPUV8_DBG_BVR_BASE
+ 4 + 16 * brp_list
[brp_i
].brpn
,
1573 (uint32_t)brp_list
[brp_i
].value
);
1574 if (retval
!= ERROR_OK
)
1576 breakpoint
->is_set
= false;
1580 /* restore original instruction (kept in target endianness) */
1582 armv8_cache_d_inner_flush_virt(armv8
,
1583 breakpoint
->address
& 0xFFFFFFFFFFFFFFFEULL
,
1584 breakpoint
->length
);
1586 if (breakpoint
->length
== 4) {
1587 retval
= target_write_memory(target
,
1588 breakpoint
->address
& 0xFFFFFFFFFFFFFFFEULL
,
1589 4, 1, breakpoint
->orig_instr
);
1590 if (retval
!= ERROR_OK
)
1593 retval
= target_write_memory(target
,
1594 breakpoint
->address
& 0xFFFFFFFFFFFFFFFEULL
,
1595 2, 1, breakpoint
->orig_instr
);
1596 if (retval
!= ERROR_OK
)
1600 armv8_cache_d_inner_flush_virt(armv8
,
1601 breakpoint
->address
& 0xFFFFFFFFFFFFFFFEULL
,
1602 breakpoint
->length
);
1604 armv8_cache_i_inner_inval_virt(armv8
,
1605 breakpoint
->address
& 0xFFFFFFFFFFFFFFFEULL
,
1606 breakpoint
->length
);
1608 breakpoint
->is_set
= false;
1613 static int aarch64_add_breakpoint(struct target
*target
,
1614 struct breakpoint
*breakpoint
)
1616 struct aarch64_common
*aarch64
= target_to_aarch64(target
);
1618 if ((breakpoint
->type
== BKPT_HARD
) && (aarch64
->brp_num_available
< 1)) {
1619 LOG_INFO("no hardware breakpoint available");
1620 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1623 if (breakpoint
->type
== BKPT_HARD
)
1624 aarch64
->brp_num_available
--;
1626 return aarch64_set_breakpoint(target
, breakpoint
, 0x00); /* Exact match */
1629 static int aarch64_add_context_breakpoint(struct target
*target
,
1630 struct breakpoint
*breakpoint
)
1632 struct aarch64_common
*aarch64
= target_to_aarch64(target
);
1634 if ((breakpoint
->type
== BKPT_HARD
) && (aarch64
->brp_num_available
< 1)) {
1635 LOG_INFO("no hardware breakpoint available");
1636 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1639 if (breakpoint
->type
== BKPT_HARD
)
1640 aarch64
->brp_num_available
--;
1642 return aarch64_set_context_breakpoint(target
, breakpoint
, 0x02); /* asid match */
1645 static int aarch64_add_hybrid_breakpoint(struct target
*target
,
1646 struct breakpoint
*breakpoint
)
1648 struct aarch64_common
*aarch64
= target_to_aarch64(target
);
1650 if ((breakpoint
->type
== BKPT_HARD
) && (aarch64
->brp_num_available
< 1)) {
1651 LOG_INFO("no hardware breakpoint available");
1652 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1655 if (breakpoint
->type
== BKPT_HARD
)
1656 aarch64
->brp_num_available
--;
1658 return aarch64_set_hybrid_breakpoint(target
, breakpoint
); /* ??? */
1661 static int aarch64_remove_breakpoint(struct target
*target
, struct breakpoint
*breakpoint
)
1663 struct aarch64_common
*aarch64
= target_to_aarch64(target
);
1666 /* It is perfectly possible to remove breakpoints while the target is running */
1667 if (target
->state
!= TARGET_HALTED
) {
1668 LOG_WARNING("target not halted");
1669 return ERROR_TARGET_NOT_HALTED
;
1673 if (breakpoint
->is_set
) {
1674 aarch64_unset_breakpoint(target
, breakpoint
);
1675 if (breakpoint
->type
== BKPT_HARD
)
1676 aarch64
->brp_num_available
++;
1682 /* Setup hardware Watchpoint Register Pair */
1683 static int aarch64_set_watchpoint(struct target
*target
,
1684 struct watchpoint
*watchpoint
)
1688 uint32_t control
, offset
, length
;
1689 struct aarch64_common
*aarch64
= target_to_aarch64(target
);
1690 struct armv8_common
*armv8
= &aarch64
->armv8_common
;
1691 struct aarch64_brp
*wp_list
= aarch64
->wp_list
;
1693 if (watchpoint
->is_set
) {
1694 LOG_WARNING("watchpoint already set");
1698 while (wp_list
[wp_i
].used
&& (wp_i
< aarch64
->wp_num
))
1700 if (wp_i
>= aarch64
->wp_num
) {
1701 LOG_ERROR("ERROR Can not find free Watchpoint Register Pair");
1702 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1705 control
= (1 << 0) /* enable */
1706 | (3 << 1) /* both user and privileged access */
1707 | (1 << 13); /* higher mode control */
1709 switch (watchpoint
->rw
) {
1721 /* Match up to 8 bytes. */
1722 offset
= watchpoint
->address
& 7;
1723 length
= watchpoint
->length
;
1724 if (offset
+ length
> sizeof(uint64_t)) {
1725 length
= sizeof(uint64_t) - offset
;
1726 LOG_WARNING("Adjust watchpoint match inside 8-byte boundary");
1728 for (; length
> 0; offset
++, length
--)
1729 control
|= (1 << offset
) << 5;
1731 wp_list
[wp_i
].value
= watchpoint
->address
& 0xFFFFFFFFFFFFFFF8ULL
;
1732 wp_list
[wp_i
].control
= control
;
1734 retval
= aarch64_dap_write_memap_register_u32(target
, armv8
->debug_base
1735 + CPUV8_DBG_WVR_BASE
+ 16 * wp_list
[wp_i
].brpn
,
1736 (uint32_t)(wp_list
[wp_i
].value
& 0xFFFFFFFF));
1737 if (retval
!= ERROR_OK
)
1739 retval
= aarch64_dap_write_memap_register_u32(target
, armv8
->debug_base
1740 + CPUV8_DBG_WVR_BASE
+ 4 + 16 * wp_list
[wp_i
].brpn
,
1741 (uint32_t)(wp_list
[wp_i
].value
>> 32));
1742 if (retval
!= ERROR_OK
)
1745 retval
= aarch64_dap_write_memap_register_u32(target
, armv8
->debug_base
1746 + CPUV8_DBG_WCR_BASE
+ 16 * wp_list
[wp_i
].brpn
,
1748 if (retval
!= ERROR_OK
)
1750 LOG_DEBUG("wp %i control 0x%0" PRIx32
" value 0x%" TARGET_PRIxADDR
, wp_i
,
1751 wp_list
[wp_i
].control
, wp_list
[wp_i
].value
);
1753 /* Ensure that halting debug mode is enable */
1754 retval
= aarch64_set_dscr_bits(target
, DSCR_HDE
, DSCR_HDE
);
1755 if (retval
!= ERROR_OK
) {
1756 LOG_DEBUG("Failed to set DSCR.HDE");
1760 wp_list
[wp_i
].used
= 1;
1761 watchpoint_set(watchpoint
, wp_i
);
1766 /* Clear hardware Watchpoint Register Pair */
1767 static int aarch64_unset_watchpoint(struct target
*target
,
1768 struct watchpoint
*watchpoint
)
1771 struct aarch64_common
*aarch64
= target_to_aarch64(target
);
1772 struct armv8_common
*armv8
= &aarch64
->armv8_common
;
1773 struct aarch64_brp
*wp_list
= aarch64
->wp_list
;
1775 if (!watchpoint
->is_set
) {
1776 LOG_WARNING("watchpoint not set");
1780 int wp_i
= watchpoint
->number
;
1781 if (wp_i
>= aarch64
->wp_num
) {
1782 LOG_DEBUG("Invalid WP number in watchpoint");
1785 LOG_DEBUG("rwp %i control 0x%0" PRIx32
" value 0x%0" PRIx64
, wp_i
,
1786 wp_list
[wp_i
].control
, wp_list
[wp_i
].value
);
1787 wp_list
[wp_i
].used
= 0;
1788 wp_list
[wp_i
].value
= 0;
1789 wp_list
[wp_i
].control
= 0;
1790 retval
= aarch64_dap_write_memap_register_u32(target
, armv8
->debug_base
1791 + CPUV8_DBG_WCR_BASE
+ 16 * wp_list
[wp_i
].brpn
,
1792 wp_list
[wp_i
].control
);
1793 if (retval
!= ERROR_OK
)
1795 retval
= aarch64_dap_write_memap_register_u32(target
, armv8
->debug_base
1796 + CPUV8_DBG_WVR_BASE
+ 16 * wp_list
[wp_i
].brpn
,
1797 wp_list
[wp_i
].value
);
1798 if (retval
!= ERROR_OK
)
1801 retval
= aarch64_dap_write_memap_register_u32(target
, armv8
->debug_base
1802 + CPUV8_DBG_WVR_BASE
+ 4 + 16 * wp_list
[wp_i
].brpn
,
1803 (uint32_t)wp_list
[wp_i
].value
);
1804 if (retval
!= ERROR_OK
)
1806 watchpoint
->is_set
= false;
1811 static int aarch64_add_watchpoint(struct target
*target
,
1812 struct watchpoint
*watchpoint
)
1815 struct aarch64_common
*aarch64
= target_to_aarch64(target
);
1817 if (aarch64
->wp_num_available
< 1) {
1818 LOG_INFO("no hardware watchpoint available");
1819 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1822 retval
= aarch64_set_watchpoint(target
, watchpoint
);
1823 if (retval
== ERROR_OK
)
1824 aarch64
->wp_num_available
--;
1829 static int aarch64_remove_watchpoint(struct target
*target
,
1830 struct watchpoint
*watchpoint
)
1832 struct aarch64_common
*aarch64
= target_to_aarch64(target
);
1834 if (watchpoint
->is_set
) {
1835 aarch64_unset_watchpoint(target
, watchpoint
);
1836 aarch64
->wp_num_available
++;
1843 * find out which watchpoint hits
1844 * get exception address and compare the address to watchpoints
1846 static int aarch64_hit_watchpoint(struct target
*target
,
1847 struct watchpoint
**hit_watchpoint
)
1849 if (target
->debug_reason
!= DBG_REASON_WATCHPOINT
)
1852 struct armv8_common
*armv8
= target_to_armv8(target
);
1854 target_addr_t exception_address
;
1855 struct watchpoint
*wp
;
1857 exception_address
= armv8
->dpm
.wp_addr
;
1859 if (exception_address
== 0xFFFFFFFF)
1862 for (wp
= target
->watchpoints
; wp
; wp
= wp
->next
)
1863 if (exception_address
>= wp
->address
&& exception_address
< (wp
->address
+ wp
->length
)) {
1864 *hit_watchpoint
= wp
;
1872 * Cortex-A8 Reset functions
1875 static int aarch64_enable_reset_catch(struct target
*target
, bool enable
)
1877 struct armv8_common
*armv8
= target_to_armv8(target
);
1881 retval
= mem_ap_read_atomic_u32(armv8
->debug_ap
,
1882 armv8
->debug_base
+ CPUV8_DBG_EDECR
, &edecr
);
1883 LOG_DEBUG("EDECR = 0x%08" PRIx32
", enable=%d", edecr
, enable
);
1884 if (retval
!= ERROR_OK
)
1892 return mem_ap_write_atomic_u32(armv8
->debug_ap
,
1893 armv8
->debug_base
+ CPUV8_DBG_EDECR
, edecr
);
1896 static int aarch64_clear_reset_catch(struct target
*target
)
1898 struct armv8_common
*armv8
= target_to_armv8(target
);
1903 /* check if Reset Catch debug event triggered as expected */
1904 retval
= mem_ap_read_atomic_u32(armv8
->debug_ap
,
1905 armv8
->debug_base
+ CPUV8_DBG_EDESR
, &edesr
);
1906 if (retval
!= ERROR_OK
)
1909 was_triggered
= !!(edesr
& ESR_RC
);
1910 LOG_DEBUG("Reset Catch debug event %s",
1911 was_triggered
? "triggered" : "NOT triggered!");
1913 if (was_triggered
) {
1914 /* clear pending Reset Catch debug event */
1916 retval
= mem_ap_write_atomic_u32(armv8
->debug_ap
,
1917 armv8
->debug_base
+ CPUV8_DBG_EDESR
, edesr
);
1918 if (retval
!= ERROR_OK
)
1925 static int aarch64_assert_reset(struct target
*target
)
1927 struct armv8_common
*armv8
= target_to_armv8(target
);
1928 enum reset_types reset_config
= jtag_get_reset_config();
1933 /* Issue some kind of warm reset. */
1934 if (target_has_event_action(target
, TARGET_EVENT_RESET_ASSERT
))
1935 target_handle_event(target
, TARGET_EVENT_RESET_ASSERT
);
1936 else if (reset_config
& RESET_HAS_SRST
) {
1937 bool srst_asserted
= false;
1939 if (target
->reset_halt
&& !(reset_config
& RESET_SRST_PULLS_TRST
)) {
1940 if (target_was_examined(target
)) {
1942 if (reset_config
& RESET_SRST_NO_GATING
) {
1944 * SRST needs to be asserted *before* Reset Catch
1945 * debug event can be set up.
1947 adapter_assert_reset();
1948 srst_asserted
= true;
1951 /* make sure to clear all sticky errors */
1952 mem_ap_write_atomic_u32(armv8
->debug_ap
,
1953 armv8
->debug_base
+ CPUV8_DBG_DRCR
, DRCR_CSE
);
1955 /* set up Reset Catch debug event to halt the CPU after reset */
1956 retval
= aarch64_enable_reset_catch(target
, true);
1957 if (retval
!= ERROR_OK
)
1958 LOG_WARNING("%s: Error enabling Reset Catch debug event; the CPU will not halt immediately after reset!",
1959 target_name(target
));
1961 LOG_WARNING("%s: Target not examined, will not halt immediately after reset!",
1962 target_name(target
));
1966 /* REVISIT handle "pulls" cases, if there's
1967 * hardware that needs them to work.
1970 adapter_assert_reset();
1972 LOG_ERROR("%s: how to reset?", target_name(target
));
1976 /* registers are now invalid */
1977 if (target_was_examined(target
)) {
1978 register_cache_invalidate(armv8
->arm
.core_cache
);
1979 register_cache_invalidate(armv8
->arm
.core_cache
->next
);
1982 target
->state
= TARGET_RESET
;
1987 static int aarch64_deassert_reset(struct target
*target
)
1993 /* be certain SRST is off */
1994 adapter_deassert_reset();
1996 if (!target_was_examined(target
))
1999 retval
= aarch64_init_debug_access(target
);
2000 if (retval
!= ERROR_OK
)
2003 retval
= aarch64_poll(target
);
2004 if (retval
!= ERROR_OK
)
2007 if (target
->reset_halt
) {
2008 /* clear pending Reset Catch debug event */
2009 retval
= aarch64_clear_reset_catch(target
);
2010 if (retval
!= ERROR_OK
)
2011 LOG_WARNING("%s: Clearing Reset Catch debug event failed",
2012 target_name(target
));
2014 /* disable Reset Catch debug event */
2015 retval
= aarch64_enable_reset_catch(target
, false);
2016 if (retval
!= ERROR_OK
)
2017 LOG_WARNING("%s: Disabling Reset Catch debug event failed",
2018 target_name(target
));
2020 if (target
->state
!= TARGET_HALTED
) {
2021 LOG_WARNING("%s: ran after reset and before halt ...",
2022 target_name(target
));
2023 if (target_was_examined(target
)) {
2024 retval
= aarch64_halt_one(target
, HALT_LAZY
);
2025 if (retval
!= ERROR_OK
)
2028 target
->state
= TARGET_UNKNOWN
;
2036 static int aarch64_write_cpu_memory_slow(struct target
*target
,
2037 uint32_t size
, uint32_t count
, const uint8_t *buffer
, uint32_t *dscr
)
2039 struct armv8_common
*armv8
= target_to_armv8(target
);
2040 struct arm_dpm
*dpm
= &armv8
->dpm
;
2041 struct arm
*arm
= &armv8
->arm
;
2044 armv8_reg_current(arm
, 1)->dirty
= true;
2046 /* change DCC to normal mode if necessary */
2047 if (*dscr
& DSCR_MA
) {
2049 retval
= mem_ap_write_atomic_u32(armv8
->debug_ap
,
2050 armv8
->debug_base
+ CPUV8_DBG_DSCR
, *dscr
);
2051 if (retval
!= ERROR_OK
)
2056 uint32_t data
, opcode
;
2058 /* write the data to store into DTRRX */
2062 data
= target_buffer_get_u16(target
, buffer
);
2064 data
= target_buffer_get_u32(target
, buffer
);
2065 retval
= mem_ap_write_atomic_u32(armv8
->debug_ap
,
2066 armv8
->debug_base
+ CPUV8_DBG_DTRRX
, data
);
2067 if (retval
!= ERROR_OK
)
2070 if (arm
->core_state
== ARM_STATE_AARCH64
)
2071 retval
= dpm
->instr_execute(dpm
, ARMV8_MRS(SYSTEM_DBG_DTRRX_EL0
, 1));
2073 retval
= dpm
->instr_execute(dpm
, ARMV4_5_MRC(14, 0, 1, 0, 5, 0));
2074 if (retval
!= ERROR_OK
)
2078 opcode
= armv8_opcode(armv8
, ARMV8_OPC_STRB_IP
);
2080 opcode
= armv8_opcode(armv8
, ARMV8_OPC_STRH_IP
);
2082 opcode
= armv8_opcode(armv8
, ARMV8_OPC_STRW_IP
);
2083 retval
= dpm
->instr_execute(dpm
, opcode
);
2084 if (retval
!= ERROR_OK
)
2095 static int aarch64_write_cpu_memory_fast(struct target
*target
,
2096 uint32_t count
, const uint8_t *buffer
, uint32_t *dscr
)
2098 struct armv8_common
*armv8
= target_to_armv8(target
);
2099 struct arm
*arm
= &armv8
->arm
;
2102 armv8_reg_current(arm
, 1)->dirty
= true;
2104 /* Step 1.d - Change DCC to memory mode */
2106 retval
= mem_ap_write_atomic_u32(armv8
->debug_ap
,
2107 armv8
->debug_base
+ CPUV8_DBG_DSCR
, *dscr
);
2108 if (retval
!= ERROR_OK
)
2112 /* Step 2.a - Do the write */
2113 retval
= mem_ap_write_buf_noincr(armv8
->debug_ap
,
2114 buffer
, 4, count
, armv8
->debug_base
+ CPUV8_DBG_DTRRX
);
2115 if (retval
!= ERROR_OK
)
2118 /* Step 3.a - Switch DTR mode back to Normal mode */
2120 retval
= mem_ap_write_atomic_u32(armv8
->debug_ap
,
2121 armv8
->debug_base
+ CPUV8_DBG_DSCR
, *dscr
);
2122 if (retval
!= ERROR_OK
)
2128 static int aarch64_write_cpu_memory(struct target
*target
,
2129 uint64_t address
, uint32_t size
,
2130 uint32_t count
, const uint8_t *buffer
)
2132 /* write memory through APB-AP */
2133 int retval
= ERROR_COMMAND_SYNTAX_ERROR
;
2134 struct armv8_common
*armv8
= target_to_armv8(target
);
2135 struct arm_dpm
*dpm
= &armv8
->dpm
;
2136 struct arm
*arm
= &armv8
->arm
;
2139 if (target
->state
!= TARGET_HALTED
) {
2140 LOG_TARGET_ERROR(target
, "not halted");
2141 return ERROR_TARGET_NOT_HALTED
;
2144 /* Mark register X0 as dirty, as it will be used
2145 * for transferring the data.
2146 * It will be restored automatically when exiting
2149 armv8_reg_current(arm
, 0)->dirty
= true;
2151 /* This algorithm comes from DDI0487A.g, chapter J9.1 */
2154 retval
= mem_ap_read_atomic_u32(armv8
->debug_ap
,
2155 armv8
->debug_base
+ CPUV8_DBG_DSCR
, &dscr
);
2156 if (retval
!= ERROR_OK
)
2159 /* Set Normal access mode */
2160 dscr
= (dscr
& ~DSCR_MA
);
2161 retval
= mem_ap_write_atomic_u32(armv8
->debug_ap
,
2162 armv8
->debug_base
+ CPUV8_DBG_DSCR
, dscr
);
2163 if (retval
!= ERROR_OK
)
2166 if (arm
->core_state
== ARM_STATE_AARCH64
) {
2167 /* Write X0 with value 'address' using write procedure */
2168 /* Step 1.a+b - Write the address for read access into DBGDTR_EL0 */
2169 /* Step 1.c - Copy value from DTR to R0 using instruction mrs DBGDTR_EL0, x0 */
2170 retval
= dpm
->instr_write_data_dcc_64(dpm
,
2171 ARMV8_MRS(SYSTEM_DBG_DBGDTR_EL0
, 0), address
);
2173 /* Write R0 with value 'address' using write procedure */
2174 /* Step 1.a+b - Write the address for read access into DBGDTRRX */
2175 /* Step 1.c - Copy value from DTR to R0 using instruction mrc DBGDTRTXint, r0 */
2176 retval
= dpm
->instr_write_data_dcc(dpm
,
2177 ARMV4_5_MRC(14, 0, 0, 0, 5, 0), address
);
2180 if (retval
!= ERROR_OK
)
2183 if (size
== 4 && (address
% 4) == 0)
2184 retval
= aarch64_write_cpu_memory_fast(target
, count
, buffer
, &dscr
);
2186 retval
= aarch64_write_cpu_memory_slow(target
, size
, count
, buffer
, &dscr
);
2188 if (retval
!= ERROR_OK
) {
2189 /* Unset DTR mode */
2190 mem_ap_read_atomic_u32(armv8
->debug_ap
,
2191 armv8
->debug_base
+ CPUV8_DBG_DSCR
, &dscr
);
2193 mem_ap_write_atomic_u32(armv8
->debug_ap
,
2194 armv8
->debug_base
+ CPUV8_DBG_DSCR
, dscr
);
2197 /* Check for sticky abort flags in the DSCR */
2198 retval
= mem_ap_read_atomic_u32(armv8
->debug_ap
,
2199 armv8
->debug_base
+ CPUV8_DBG_DSCR
, &dscr
);
2200 if (retval
!= ERROR_OK
)
2204 if (dscr
& (DSCR_ERR
| DSCR_SYS_ERROR_PEND
)) {
2205 /* Abort occurred - clear it and exit */
2206 LOG_ERROR("abort occurred - dscr = 0x%08" PRIx32
, dscr
);
2207 armv8_dpm_handle_exception(dpm
, true);
2215 static int aarch64_read_cpu_memory_slow(struct target
*target
,
2216 uint32_t size
, uint32_t count
, uint8_t *buffer
, uint32_t *dscr
)
2218 struct armv8_common
*armv8
= target_to_armv8(target
);
2219 struct arm_dpm
*dpm
= &armv8
->dpm
;
2220 struct arm
*arm
= &armv8
->arm
;
2223 armv8_reg_current(arm
, 1)->dirty
= true;
2225 /* change DCC to normal mode (if necessary) */
2226 if (*dscr
& DSCR_MA
) {
2228 retval
= mem_ap_write_atomic_u32(armv8
->debug_ap
,
2229 armv8
->debug_base
+ CPUV8_DBG_DSCR
, *dscr
);
2230 if (retval
!= ERROR_OK
)
2235 uint32_t opcode
, data
;
2238 opcode
= armv8_opcode(armv8
, ARMV8_OPC_LDRB_IP
);
2240 opcode
= armv8_opcode(armv8
, ARMV8_OPC_LDRH_IP
);
2242 opcode
= armv8_opcode(armv8
, ARMV8_OPC_LDRW_IP
);
2243 retval
= dpm
->instr_execute(dpm
, opcode
);
2244 if (retval
!= ERROR_OK
)
2247 if (arm
->core_state
== ARM_STATE_AARCH64
)
2248 retval
= dpm
->instr_execute(dpm
, ARMV8_MSR_GP(SYSTEM_DBG_DTRTX_EL0
, 1));
2250 retval
= dpm
->instr_execute(dpm
, ARMV4_5_MCR(14, 0, 1, 0, 5, 0));
2251 if (retval
!= ERROR_OK
)
2254 retval
= mem_ap_read_atomic_u32(armv8
->debug_ap
,
2255 armv8
->debug_base
+ CPUV8_DBG_DTRTX
, &data
);
2256 if (retval
!= ERROR_OK
)
2260 *buffer
= (uint8_t)data
;
2262 target_buffer_set_u16(target
, buffer
, (uint16_t)data
);
2264 target_buffer_set_u32(target
, buffer
, data
);
2274 static int aarch64_read_cpu_memory_fast(struct target
*target
,
2275 uint32_t count
, uint8_t *buffer
, uint32_t *dscr
)
2277 struct armv8_common
*armv8
= target_to_armv8(target
);
2278 struct arm_dpm
*dpm
= &armv8
->dpm
;
2279 struct arm
*arm
= &armv8
->arm
;
2283 /* Mark X1 as dirty */
2284 armv8_reg_current(arm
, 1)->dirty
= true;
2286 if (arm
->core_state
== ARM_STATE_AARCH64
) {
2287 /* Step 1.d - Dummy operation to ensure EDSCR.Txfull == 1 */
2288 retval
= dpm
->instr_execute(dpm
, ARMV8_MSR_GP(SYSTEM_DBG_DBGDTR_EL0
, 0));
2290 /* Step 1.d - Dummy operation to ensure EDSCR.Txfull == 1 */
2291 retval
= dpm
->instr_execute(dpm
, ARMV4_5_MCR(14, 0, 0, 0, 5, 0));
2294 if (retval
!= ERROR_OK
)
2297 /* Step 1.e - Change DCC to memory mode */
2299 retval
= mem_ap_write_atomic_u32(armv8
->debug_ap
,
2300 armv8
->debug_base
+ CPUV8_DBG_DSCR
, *dscr
);
2301 if (retval
!= ERROR_OK
)
2304 /* Step 1.f - read DBGDTRTX and discard the value */
2305 retval
= mem_ap_read_atomic_u32(armv8
->debug_ap
,
2306 armv8
->debug_base
+ CPUV8_DBG_DTRTX
, &value
);
2307 if (retval
!= ERROR_OK
)
2311 /* Read the data - Each read of the DTRTX register causes the instruction to be reissued
2312 * Abort flags are sticky, so can be read at end of transactions
2314 * This data is read in aligned to 32 bit boundary.
2318 /* Step 2.a - Loop n-1 times, each read of DBGDTRTX reads the data from [X0] and
2319 * increments X0 by 4. */
2320 retval
= mem_ap_read_buf_noincr(armv8
->debug_ap
, buffer
, 4, count
,
2321 armv8
->debug_base
+ CPUV8_DBG_DTRTX
);
2322 if (retval
!= ERROR_OK
)
2326 /* Step 3.a - set DTR access mode back to Normal mode */
2328 retval
= mem_ap_write_atomic_u32(armv8
->debug_ap
,
2329 armv8
->debug_base
+ CPUV8_DBG_DSCR
, *dscr
);
2330 if (retval
!= ERROR_OK
)
2333 /* Step 3.b - read DBGDTRTX for the final value */
2334 retval
= mem_ap_read_atomic_u32(armv8
->debug_ap
,
2335 armv8
->debug_base
+ CPUV8_DBG_DTRTX
, &value
);
2336 if (retval
!= ERROR_OK
)
2339 target_buffer_set_u32(target
, buffer
+ count
* 4, value
);
2343 static int aarch64_read_cpu_memory(struct target
*target
,
2344 target_addr_t address
, uint32_t size
,
2345 uint32_t count
, uint8_t *buffer
)
2347 /* read memory through APB-AP */
2348 int retval
= ERROR_COMMAND_SYNTAX_ERROR
;
2349 struct armv8_common
*armv8
= target_to_armv8(target
);
2350 struct arm_dpm
*dpm
= &armv8
->dpm
;
2351 struct arm
*arm
= &armv8
->arm
;
2354 LOG_DEBUG("Reading CPU memory address 0x%016" PRIx64
" size %" PRIu32
" count %" PRIu32
,
2355 address
, size
, count
);
2357 if (target
->state
!= TARGET_HALTED
) {
2358 LOG_TARGET_ERROR(target
, "not halted");
2359 return ERROR_TARGET_NOT_HALTED
;
2362 /* Mark register X0 as dirty, as it will be used
2363 * for transferring the data.
2364 * It will be restored automatically when exiting
2367 armv8_reg_current(arm
, 0)->dirty
= true;
2370 retval
= mem_ap_read_atomic_u32(armv8
->debug_ap
,
2371 armv8
->debug_base
+ CPUV8_DBG_DSCR
, &dscr
);
2372 if (retval
!= ERROR_OK
)
2375 /* This algorithm comes from DDI0487A.g, chapter J9.1 */
2377 /* Set Normal access mode */
2379 retval
= mem_ap_write_atomic_u32(armv8
->debug_ap
,
2380 armv8
->debug_base
+ CPUV8_DBG_DSCR
, dscr
);
2381 if (retval
!= ERROR_OK
)
2384 if (arm
->core_state
== ARM_STATE_AARCH64
) {
2385 /* Write X0 with value 'address' using write procedure */
2386 /* Step 1.a+b - Write the address for read access into DBGDTR_EL0 */
2387 /* Step 1.c - Copy value from DTR to R0 using instruction mrs DBGDTR_EL0, x0 */
2388 retval
= dpm
->instr_write_data_dcc_64(dpm
,
2389 ARMV8_MRS(SYSTEM_DBG_DBGDTR_EL0
, 0), address
);
2391 /* Write R0 with value 'address' using write procedure */
2392 /* Step 1.a+b - Write the address for read access into DBGDTRRXint */
2393 /* Step 1.c - Copy value from DTR to R0 using instruction mrc DBGDTRTXint, r0 */
2394 retval
= dpm
->instr_write_data_dcc(dpm
,
2395 ARMV4_5_MRC(14, 0, 0, 0, 5, 0), address
);
2398 if (retval
!= ERROR_OK
)
2401 if (size
== 4 && (address
% 4) == 0)
2402 retval
= aarch64_read_cpu_memory_fast(target
, count
, buffer
, &dscr
);
2404 retval
= aarch64_read_cpu_memory_slow(target
, size
, count
, buffer
, &dscr
);
2406 if (dscr
& DSCR_MA
) {
2408 mem_ap_write_atomic_u32(armv8
->debug_ap
,
2409 armv8
->debug_base
+ CPUV8_DBG_DSCR
, dscr
);
2412 if (retval
!= ERROR_OK
)
2415 /* Check for sticky abort flags in the DSCR */
2416 retval
= mem_ap_read_atomic_u32(armv8
->debug_ap
,
2417 armv8
->debug_base
+ CPUV8_DBG_DSCR
, &dscr
);
2418 if (retval
!= ERROR_OK
)
2423 if (dscr
& (DSCR_ERR
| DSCR_SYS_ERROR_PEND
)) {
2424 /* Abort occurred - clear it and exit */
2425 LOG_ERROR("abort occurred - dscr = 0x%08" PRIx32
, dscr
);
2426 armv8_dpm_handle_exception(dpm
, true);
2434 static int aarch64_read_phys_memory(struct target
*target
,
2435 target_addr_t address
, uint32_t size
,
2436 uint32_t count
, uint8_t *buffer
)
2438 int retval
= ERROR_COMMAND_SYNTAX_ERROR
;
2440 if (count
&& buffer
) {
2441 /* read memory through APB-AP */
2442 retval
= aarch64_mmu_modify(target
, 0);
2443 if (retval
!= ERROR_OK
)
2445 retval
= aarch64_read_cpu_memory(target
, address
, size
, count
, buffer
);
2450 static int aarch64_read_memory(struct target
*target
, target_addr_t address
,
2451 uint32_t size
, uint32_t count
, uint8_t *buffer
)
2453 int mmu_enabled
= 0;
2456 /* determine if MMU was enabled on target stop */
2457 retval
= aarch64_mmu(target
, &mmu_enabled
);
2458 if (retval
!= ERROR_OK
)
2462 /* enable MMU as we could have disabled it for phys access */
2463 retval
= aarch64_mmu_modify(target
, 1);
2464 if (retval
!= ERROR_OK
)
2467 return aarch64_read_cpu_memory(target
, address
, size
, count
, buffer
);
2470 static int aarch64_write_phys_memory(struct target
*target
,
2471 target_addr_t address
, uint32_t size
,
2472 uint32_t count
, const uint8_t *buffer
)
2474 int retval
= ERROR_COMMAND_SYNTAX_ERROR
;
2476 if (count
&& buffer
) {
2477 /* write memory through APB-AP */
2478 retval
= aarch64_mmu_modify(target
, 0);
2479 if (retval
!= ERROR_OK
)
2481 return aarch64_write_cpu_memory(target
, address
, size
, count
, buffer
);
2487 static int aarch64_write_memory(struct target
*target
, target_addr_t address
,
2488 uint32_t size
, uint32_t count
, const uint8_t *buffer
)
2490 int mmu_enabled
= 0;
2493 /* determine if MMU was enabled on target stop */
2494 retval
= aarch64_mmu(target
, &mmu_enabled
);
2495 if (retval
!= ERROR_OK
)
2499 /* enable MMU as we could have disabled it for phys access */
2500 retval
= aarch64_mmu_modify(target
, 1);
2501 if (retval
!= ERROR_OK
)
2504 return aarch64_write_cpu_memory(target
, address
, size
, count
, buffer
);
2507 static int aarch64_handle_target_request(void *priv
)
2509 struct target
*target
= priv
;
2510 struct armv8_common
*armv8
= target_to_armv8(target
);
2513 if (!target_was_examined(target
))
2515 if (!target
->dbg_msg_enabled
)
2518 if (target
->state
== TARGET_RUNNING
) {
2521 retval
= mem_ap_read_atomic_u32(armv8
->debug_ap
,
2522 armv8
->debug_base
+ CPUV8_DBG_DSCR
, &dscr
);
2524 /* check if we have data */
2525 while ((dscr
& DSCR_DTR_TX_FULL
) && (retval
== ERROR_OK
)) {
2526 retval
= mem_ap_read_atomic_u32(armv8
->debug_ap
,
2527 armv8
->debug_base
+ CPUV8_DBG_DTRTX
, &request
);
2528 if (retval
== ERROR_OK
) {
2529 target_request(target
, request
);
2530 retval
= mem_ap_read_atomic_u32(armv8
->debug_ap
,
2531 armv8
->debug_base
+ CPUV8_DBG_DSCR
, &dscr
);
2539 static int aarch64_examine_first(struct target
*target
)
2541 struct aarch64_common
*aarch64
= target_to_aarch64(target
);
2542 struct armv8_common
*armv8
= &aarch64
->armv8_common
;
2543 struct adiv5_dap
*swjdp
= armv8
->arm
.dap
;
2544 struct aarch64_private_config
*pc
= target
->private_config
;
2546 int retval
= ERROR_OK
;
2547 uint64_t debug
, ttypr
;
2549 uint32_t tmp0
, tmp1
, tmp2
, tmp3
;
2550 debug
= ttypr
= cpuid
= 0;
2555 if (!armv8
->debug_ap
) {
2556 if (pc
->adiv5_config
.ap_num
== DP_APSEL_INVALID
) {
2557 /* Search for the APB-AB */
2558 retval
= dap_find_get_ap(swjdp
, AP_TYPE_APB_AP
, &armv8
->debug_ap
);
2559 if (retval
!= ERROR_OK
) {
2560 LOG_ERROR("Could not find APB-AP for debug access");
2564 armv8
->debug_ap
= dap_get_ap(swjdp
, pc
->adiv5_config
.ap_num
);
2565 if (!armv8
->debug_ap
) {
2566 LOG_ERROR("Cannot get AP");
2572 retval
= mem_ap_init(armv8
->debug_ap
);
2573 if (retval
!= ERROR_OK
) {
2574 LOG_ERROR("Could not initialize the APB-AP");
2578 armv8
->debug_ap
->memaccess_tck
= 10;
2580 if (!target
->dbgbase_set
) {
2581 /* Lookup Processor DAP */
2582 retval
= dap_lookup_cs_component(armv8
->debug_ap
, ARM_CS_C9_DEVTYPE_CORE_DEBUG
,
2583 &armv8
->debug_base
, target
->coreid
);
2584 if (retval
!= ERROR_OK
)
2586 LOG_DEBUG("Detected core %" PRId32
" dbgbase: " TARGET_ADDR_FMT
,
2587 target
->coreid
, armv8
->debug_base
);
2589 armv8
->debug_base
= target
->dbgbase
;
2591 retval
= mem_ap_write_atomic_u32(armv8
->debug_ap
,
2592 armv8
->debug_base
+ CPUV8_DBG_OSLAR
, 0);
2593 if (retval
!= ERROR_OK
) {
2594 LOG_DEBUG("Examine %s failed", "oslock");
2598 retval
= mem_ap_read_u32(armv8
->debug_ap
,
2599 armv8
->debug_base
+ CPUV8_DBG_MAINID0
, &cpuid
);
2600 if (retval
!= ERROR_OK
) {
2601 LOG_DEBUG("Examine %s failed", "CPUID");
2605 retval
= mem_ap_read_u32(armv8
->debug_ap
,
2606 armv8
->debug_base
+ CPUV8_DBG_MEMFEATURE0
, &tmp0
);
2607 retval
+= mem_ap_read_u32(armv8
->debug_ap
,
2608 armv8
->debug_base
+ CPUV8_DBG_MEMFEATURE0
+ 4, &tmp1
);
2609 if (retval
!= ERROR_OK
) {
2610 LOG_DEBUG("Examine %s failed", "Memory Model Type");
2613 retval
= mem_ap_read_u32(armv8
->debug_ap
,
2614 armv8
->debug_base
+ CPUV8_DBG_DBGFEATURE0
, &tmp2
);
2615 retval
+= mem_ap_read_u32(armv8
->debug_ap
,
2616 armv8
->debug_base
+ CPUV8_DBG_DBGFEATURE0
+ 4, &tmp3
);
2617 if (retval
!= ERROR_OK
) {
2618 LOG_DEBUG("Examine %s failed", "ID_AA64DFR0_EL1");
2622 retval
= dap_run(armv8
->debug_ap
->dap
);
2623 if (retval
!= ERROR_OK
) {
2624 LOG_ERROR("%s: examination failed\n", target_name(target
));
2629 ttypr
= (ttypr
<< 32) | tmp0
;
2631 debug
= (debug
<< 32) | tmp2
;
2633 LOG_DEBUG("cpuid = 0x%08" PRIx32
, cpuid
);
2634 LOG_DEBUG("ttypr = 0x%08" PRIx64
, ttypr
);
2635 LOG_DEBUG("debug = 0x%08" PRIx64
, debug
);
2638 LOG_TARGET_ERROR(target
, "CTI not specified");
2642 armv8
->cti
= pc
->cti
;
2644 retval
= aarch64_dpm_setup(aarch64
, debug
);
2645 if (retval
!= ERROR_OK
)
2648 /* Setup Breakpoint Register Pairs */
2649 aarch64
->brp_num
= (uint32_t)((debug
>> 12) & 0x0F) + 1;
2650 aarch64
->brp_num_context
= (uint32_t)((debug
>> 28) & 0x0F) + 1;
2651 aarch64
->brp_num_available
= aarch64
->brp_num
;
2652 aarch64
->brp_list
= calloc(aarch64
->brp_num
, sizeof(struct aarch64_brp
));
2653 for (i
= 0; i
< aarch64
->brp_num
; i
++) {
2654 aarch64
->brp_list
[i
].used
= 0;
2655 if (i
< (aarch64
->brp_num
-aarch64
->brp_num_context
))
2656 aarch64
->brp_list
[i
].type
= BRP_NORMAL
;
2658 aarch64
->brp_list
[i
].type
= BRP_CONTEXT
;
2659 aarch64
->brp_list
[i
].value
= 0;
2660 aarch64
->brp_list
[i
].control
= 0;
2661 aarch64
->brp_list
[i
].brpn
= i
;
2664 /* Setup Watchpoint Register Pairs */
2665 aarch64
->wp_num
= (uint32_t)((debug
>> 20) & 0x0F) + 1;
2666 aarch64
->wp_num_available
= aarch64
->wp_num
;
2667 aarch64
->wp_list
= calloc(aarch64
->wp_num
, sizeof(struct aarch64_brp
));
2668 for (i
= 0; i
< aarch64
->wp_num
; i
++) {
2669 aarch64
->wp_list
[i
].used
= 0;
2670 aarch64
->wp_list
[i
].type
= BRP_NORMAL
;
2671 aarch64
->wp_list
[i
].value
= 0;
2672 aarch64
->wp_list
[i
].control
= 0;
2673 aarch64
->wp_list
[i
].brpn
= i
;
2676 LOG_DEBUG("Configured %i hw breakpoints, %i watchpoints",
2677 aarch64
->brp_num
, aarch64
->wp_num
);
2679 target
->state
= TARGET_UNKNOWN
;
2680 target
->debug_reason
= DBG_REASON_NOTHALTED
;
2681 aarch64
->isrmasking_mode
= AARCH64_ISRMASK_ON
;
2682 target_set_examined(target
);
2686 static int aarch64_examine(struct target
*target
)
2688 int retval
= ERROR_OK
;
2690 /* don't re-probe hardware after each reset */
2691 if (!target_was_examined(target
))
2692 retval
= aarch64_examine_first(target
);
2694 /* Configure core debug access */
2695 if (retval
== ERROR_OK
)
2696 retval
= aarch64_init_debug_access(target
);
2702 * Cortex-A8 target creation and initialization
2705 static int aarch64_init_target(struct command_context
*cmd_ctx
,
2706 struct target
*target
)
2708 /* examine_first() does a bunch of this */
2709 arm_semihosting_init(target
);
2713 static int aarch64_init_arch_info(struct target
*target
,
2714 struct aarch64_common
*aarch64
, struct adiv5_dap
*dap
)
2716 struct armv8_common
*armv8
= &aarch64
->armv8_common
;
2718 /* Setup struct aarch64_common */
2719 aarch64
->common_magic
= AARCH64_COMMON_MAGIC
;
2720 armv8
->arm
.dap
= dap
;
2722 /* register arch-specific functions */
2723 armv8
->examine_debug_reason
= NULL
;
2724 armv8
->post_debug_entry
= aarch64_post_debug_entry
;
2725 armv8
->pre_restore_context
= NULL
;
2726 armv8
->armv8_mmu
.read_physical_memory
= aarch64_read_phys_memory
;
2728 armv8_init_arch_info(target
, armv8
);
2729 target_register_timer_callback(aarch64_handle_target_request
, 1,
2730 TARGET_TIMER_TYPE_PERIODIC
, target
);
2735 static int armv8r_target_create(struct target
*target
, Jim_Interp
*interp
)
2737 struct aarch64_private_config
*pc
= target
->private_config
;
2738 struct aarch64_common
*aarch64
;
2740 if (adiv5_verify_config(&pc
->adiv5_config
) != ERROR_OK
)
2743 aarch64
= calloc(1, sizeof(struct aarch64_common
));
2745 LOG_ERROR("Out of memory");
2749 aarch64
->armv8_common
.is_armv8r
= true;
2751 return aarch64_init_arch_info(target
, aarch64
, pc
->adiv5_config
.dap
);
2754 static int aarch64_target_create(struct target
*target
, Jim_Interp
*interp
)
2756 struct aarch64_private_config
*pc
= target
->private_config
;
2757 struct aarch64_common
*aarch64
;
2759 if (adiv5_verify_config(&pc
->adiv5_config
) != ERROR_OK
)
2762 aarch64
= calloc(1, sizeof(struct aarch64_common
));
2764 LOG_ERROR("Out of memory");
2768 aarch64
->armv8_common
.is_armv8r
= false;
2770 return aarch64_init_arch_info(target
, aarch64
, pc
->adiv5_config
.dap
);
2773 static void aarch64_deinit_target(struct target
*target
)
2775 struct aarch64_common
*aarch64
= target_to_aarch64(target
);
2776 struct armv8_common
*armv8
= &aarch64
->armv8_common
;
2777 struct arm_dpm
*dpm
= &armv8
->dpm
;
2779 if (armv8
->debug_ap
)
2780 dap_put_ap(armv8
->debug_ap
);
2782 armv8_free_reg_cache(target
);
2783 free(aarch64
->brp_list
);
2786 free(target
->private_config
);
2790 static int aarch64_mmu(struct target
*target
, int *enabled
)
2792 struct aarch64_common
*aarch64
= target_to_aarch64(target
);
2793 struct armv8_common
*armv8
= &aarch64
->armv8_common
;
2794 if (target
->state
!= TARGET_HALTED
) {
2795 LOG_TARGET_ERROR(target
, "not halted");
2796 return ERROR_TARGET_NOT_HALTED
;
2798 if (armv8
->is_armv8r
)
2801 *enabled
= target_to_aarch64(target
)->armv8_common
.armv8_mmu
.mmu_enabled
;
2805 static int aarch64_virt2phys(struct target
*target
, target_addr_t virt
,
2806 target_addr_t
*phys
)
2808 return armv8_mmu_translate_va_pa(target
, virt
, phys
, 1);
2812 * private target configuration items
2814 enum aarch64_cfg_param
{
2818 static const struct jim_nvp nvp_config_opts
[] = {
2819 { .name
= "-cti", .value
= CFG_CTI
},
2820 { .name
= NULL
, .value
= -1 }
2823 static int aarch64_jim_configure(struct target
*target
, struct jim_getopt_info
*goi
)
2825 struct aarch64_private_config
*pc
;
2829 pc
= (struct aarch64_private_config
*)target
->private_config
;
2831 pc
= calloc(1, sizeof(struct aarch64_private_config
));
2832 pc
->adiv5_config
.ap_num
= DP_APSEL_INVALID
;
2833 target
->private_config
= pc
;
2837 * Call adiv5_jim_configure() to parse the common DAP options
2838 * It will return JIM_CONTINUE if it didn't find any known
2839 * options, JIM_OK if it correctly parsed the topmost option
2840 * and JIM_ERR if an error occurred during parameter evaluation.
2841 * For JIM_CONTINUE, we check our own params.
2843 * adiv5_jim_configure() assumes 'private_config' to point to
2844 * 'struct adiv5_private_config'. Override 'private_config'!
2846 target
->private_config
= &pc
->adiv5_config
;
2847 e
= adiv5_jim_configure(target
, goi
);
2848 target
->private_config
= pc
;
2849 if (e
!= JIM_CONTINUE
)
2852 /* parse config or cget options ... */
2853 if (goi
->argc
> 0) {
2854 Jim_SetEmptyResult(goi
->interp
);
2856 /* check first if topmost item is for us */
2857 e
= jim_nvp_name2value_obj(goi
->interp
, nvp_config_opts
,
2860 return JIM_CONTINUE
;
2862 e
= jim_getopt_obj(goi
, NULL
);
2868 if (goi
->isconfigure
) {
2870 struct arm_cti
*cti
;
2871 e
= jim_getopt_obj(goi
, &o_cti
);
2874 cti
= cti_instance_by_jim_obj(goi
->interp
, o_cti
);
2876 Jim_SetResultString(goi
->interp
, "CTI name invalid!", -1);
2881 if (goi
->argc
!= 0) {
2882 Jim_WrongNumArgs(goi
->interp
,
2883 goi
->argc
, goi
->argv
,
2888 if (!pc
|| !pc
->cti
) {
2889 Jim_SetResultString(goi
->interp
, "CTI not configured", -1);
2892 Jim_SetResultString(goi
->interp
, arm_cti_name(pc
->cti
), -1);
2898 return JIM_CONTINUE
;
2905 COMMAND_HANDLER(aarch64_handle_cache_info_command
)
2907 struct target
*target
= get_current_target(CMD_CTX
);
2908 struct armv8_common
*armv8
= target_to_armv8(target
);
2910 return armv8_handle_cache_info_command(CMD
,
2911 &armv8
->armv8_mmu
.armv8_cache
);
2914 COMMAND_HANDLER(aarch64_handle_dbginit_command
)
2916 struct target
*target
= get_current_target(CMD_CTX
);
2917 if (!target_was_examined(target
)) {
2918 LOG_ERROR("target not examined yet");
2922 return aarch64_init_debug_access(target
);
2925 COMMAND_HANDLER(aarch64_handle_disassemble_command
)
2927 struct target
*target
= get_current_target(CMD_CTX
);
2930 LOG_ERROR("No target selected");
2934 struct aarch64_common
*aarch64
= target_to_aarch64(target
);
2936 if (aarch64
->common_magic
!= AARCH64_COMMON_MAGIC
) {
2937 command_print(CMD
, "current target isn't an AArch64");
2942 target_addr_t address
;
2946 COMMAND_PARSE_NUMBER(int, CMD_ARGV
[1], count
);
2949 COMMAND_PARSE_ADDRESS(CMD_ARGV
[0], address
);
2952 return ERROR_COMMAND_SYNTAX_ERROR
;
2955 return a64_disassemble(CMD
, target
, address
, count
);
2958 COMMAND_HANDLER(aarch64_mask_interrupts_command
)
2960 struct target
*target
= get_current_target(CMD_CTX
);
2961 struct aarch64_common
*aarch64
= target_to_aarch64(target
);
2963 static const struct nvp nvp_maskisr_modes
[] = {
2964 { .name
= "off", .value
= AARCH64_ISRMASK_OFF
},
2965 { .name
= "on", .value
= AARCH64_ISRMASK_ON
},
2966 { .name
= NULL
, .value
= -1 },
2968 const struct nvp
*n
;
2971 n
= nvp_name2value(nvp_maskisr_modes
, CMD_ARGV
[0]);
2973 LOG_ERROR("Unknown parameter: %s - should be off or on", CMD_ARGV
[0]);
2974 return ERROR_COMMAND_SYNTAX_ERROR
;
2977 aarch64
->isrmasking_mode
= n
->value
;
2980 n
= nvp_value2name(nvp_maskisr_modes
, aarch64
->isrmasking_mode
);
2981 command_print(CMD
, "aarch64 interrupt mask %s", n
->name
);
2986 COMMAND_HANDLER(aarch64_mcrmrc_command
)
2988 bool is_mcr
= false;
2989 unsigned int arg_cnt
= 5;
2991 if (!strcmp(CMD_NAME
, "mcr")) {
2996 if (arg_cnt
!= CMD_ARGC
)
2997 return ERROR_COMMAND_SYNTAX_ERROR
;
2999 struct target
*target
= get_current_target(CMD_CTX
);
3001 command_print(CMD
, "no current target");
3004 if (!target_was_examined(target
)) {
3005 command_print(CMD
, "%s: not yet examined", target_name(target
));
3006 return ERROR_TARGET_NOT_EXAMINED
;
3009 struct arm
*arm
= target_to_arm(target
);
3011 command_print(CMD
, "%s: not an ARM", target_name(target
));
3015 if (target
->state
!= TARGET_HALTED
) {
3016 command_print(CMD
, "Error: [%s] not halted", target_name(target
));
3017 return ERROR_TARGET_NOT_HALTED
;
3020 if (arm
->core_state
== ARM_STATE_AARCH64
) {
3021 command_print(CMD
, "%s: not 32-bit arm target", target_name(target
));
3032 /* NOTE: parameter sequence matches ARM instruction set usage:
3033 * MCR pNUM, op1, rX, CRn, CRm, op2 ; write CP from rX
3034 * MRC pNUM, op1, rX, CRn, CRm, op2 ; read CP into rX
3035 * The "rX" is necessarily omitted; it uses Tcl mechanisms.
3037 COMMAND_PARSE_NUMBER(int, CMD_ARGV
[0], cpnum
);
3039 command_print(CMD
, "coprocessor %d out of range", cpnum
);
3040 return ERROR_COMMAND_ARGUMENT_INVALID
;
3043 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[1], op1
);
3045 command_print(CMD
, "op1 %d out of range", op1
);
3046 return ERROR_COMMAND_ARGUMENT_INVALID
;
3049 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[2], crn
);
3051 command_print(CMD
, "CRn %d out of range", crn
);
3052 return ERROR_COMMAND_ARGUMENT_INVALID
;
3055 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[3], crm
);
3057 command_print(CMD
, "CRm %d out of range", crm
);
3058 return ERROR_COMMAND_ARGUMENT_INVALID
;
3061 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[4], op2
);
3063 command_print(CMD
, "op2 %d out of range", op2
);
3064 return ERROR_COMMAND_ARGUMENT_INVALID
;
3068 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[5], value
);
3070 /* NOTE: parameters reordered! */
3071 /* ARMV4_5_MCR(cpnum, op1, 0, crn, crm, op2) */
3072 int retval
= arm
->mcr(target
, cpnum
, op1
, op2
, crn
, crm
, value
);
3073 if (retval
!= ERROR_OK
)
3077 /* NOTE: parameters reordered! */
3078 /* ARMV4_5_MRC(cpnum, op1, 0, crn, crm, op2) */
3079 int retval
= arm
->mrc(target
, cpnum
, op1
, op2
, crn
, crm
, &value
);
3080 if (retval
!= ERROR_OK
)
3083 command_print(CMD
, "0x%" PRIx32
, value
);
3089 static const struct command_registration aarch64_exec_command_handlers
[] = {
3091 .name
= "cache_info",
3092 .handler
= aarch64_handle_cache_info_command
,
3093 .mode
= COMMAND_EXEC
,
3094 .help
= "display information about target caches",
3099 .handler
= aarch64_handle_dbginit_command
,
3100 .mode
= COMMAND_EXEC
,
3101 .help
= "Initialize core debug",
3105 .name
= "disassemble",
3106 .handler
= aarch64_handle_disassemble_command
,
3107 .mode
= COMMAND_EXEC
,
3108 .help
= "Disassemble instructions",
3109 .usage
= "address [count]",
3113 .handler
= aarch64_mask_interrupts_command
,
3114 .mode
= COMMAND_ANY
,
3115 .help
= "mask aarch64 interrupts during single-step",
3116 .usage
= "['on'|'off']",
3120 .mode
= COMMAND_EXEC
,
3121 .handler
= aarch64_mcrmrc_command
,
3122 .help
= "write coprocessor register",
3123 .usage
= "cpnum op1 CRn CRm op2 value",
3127 .mode
= COMMAND_EXEC
,
3128 .handler
= aarch64_mcrmrc_command
,
3129 .help
= "read coprocessor register",
3130 .usage
= "cpnum op1 CRn CRm op2",
3133 .chain
= smp_command_handlers
,
3137 COMMAND_REGISTRATION_DONE
3140 static const struct command_registration aarch64_command_handlers
[] = {
3143 .mode
= COMMAND_ANY
,
3144 .help
= "ARM Command Group",
3146 .chain
= semihosting_common_handlers
3149 .chain
= armv8_command_handlers
,
3153 .mode
= COMMAND_ANY
,
3154 .help
= "Aarch64 command group",
3156 .chain
= aarch64_exec_command_handlers
,
3158 COMMAND_REGISTRATION_DONE
3161 struct target_type aarch64_target
= {
3164 .poll
= aarch64_poll
,
3165 .arch_state
= armv8_arch_state
,
3167 .halt
= aarch64_halt
,
3168 .resume
= aarch64_resume
,
3169 .step
= aarch64_step
,
3171 .assert_reset
= aarch64_assert_reset
,
3172 .deassert_reset
= aarch64_deassert_reset
,
3174 /* REVISIT allow exporting VFP3 registers ... */
3175 .get_gdb_arch
= armv8_get_gdb_arch
,
3176 .get_gdb_reg_list
= armv8_get_gdb_reg_list
,
3178 .read_memory
= aarch64_read_memory
,
3179 .write_memory
= aarch64_write_memory
,
3181 .add_breakpoint
= aarch64_add_breakpoint
,
3182 .add_context_breakpoint
= aarch64_add_context_breakpoint
,
3183 .add_hybrid_breakpoint
= aarch64_add_hybrid_breakpoint
,
3184 .remove_breakpoint
= aarch64_remove_breakpoint
,
3185 .add_watchpoint
= aarch64_add_watchpoint
,
3186 .remove_watchpoint
= aarch64_remove_watchpoint
,
3187 .hit_watchpoint
= aarch64_hit_watchpoint
,
3189 .commands
= aarch64_command_handlers
,
3190 .target_create
= aarch64_target_create
,
3191 .target_jim_configure
= aarch64_jim_configure
,
3192 .init_target
= aarch64_init_target
,
3193 .deinit_target
= aarch64_deinit_target
,
3194 .examine
= aarch64_examine
,
3196 .read_phys_memory
= aarch64_read_phys_memory
,
3197 .write_phys_memory
= aarch64_write_phys_memory
,
3199 .virt2phys
= aarch64_virt2phys
,
3202 struct target_type armv8r_target
= {
3205 .poll
= aarch64_poll
,
3206 .arch_state
= armv8_arch_state
,
3208 .halt
= aarch64_halt
,
3209 .resume
= aarch64_resume
,
3210 .step
= aarch64_step
,
3212 .assert_reset
= aarch64_assert_reset
,
3213 .deassert_reset
= aarch64_deassert_reset
,
3215 /* REVISIT allow exporting VFP3 registers ... */
3216 .get_gdb_arch
= armv8_get_gdb_arch
,
3217 .get_gdb_reg_list
= armv8_get_gdb_reg_list
,
3219 .read_memory
= aarch64_read_phys_memory
,
3220 .write_memory
= aarch64_write_phys_memory
,
3222 .add_breakpoint
= aarch64_add_breakpoint
,
3223 .add_context_breakpoint
= aarch64_add_context_breakpoint
,
3224 .add_hybrid_breakpoint
= aarch64_add_hybrid_breakpoint
,
3225 .remove_breakpoint
= aarch64_remove_breakpoint
,
3226 .add_watchpoint
= aarch64_add_watchpoint
,
3227 .remove_watchpoint
= aarch64_remove_watchpoint
,
3228 .hit_watchpoint
= aarch64_hit_watchpoint
,
3230 .commands
= aarch64_command_handlers
,
3231 .target_create
= armv8r_target_create
,
3232 .target_jim_configure
= aarch64_jim_configure
,
3233 .init_target
= aarch64_init_target
,
3234 .deinit_target
= aarch64_deinit_target
,
3235 .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)