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
;
1098 armv8
->last_run_control_op
= ARMV8_RUNCONTROL_STEP
;
1100 if (target
->state
!= TARGET_HALTED
) {
1101 LOG_TARGET_ERROR(target
, "not halted");
1102 return ERROR_TARGET_NOT_HALTED
;
1105 retval
= mem_ap_read_atomic_u32(armv8
->debug_ap
,
1106 armv8
->debug_base
+ CPUV8_DBG_EDECR
, &edecr
);
1107 /* make sure EDECR.SS is not set when restoring the register */
1109 if (retval
== ERROR_OK
) {
1111 /* set EDECR.SS to enter hardware step mode */
1112 retval
= mem_ap_write_atomic_u32(armv8
->debug_ap
,
1113 armv8
->debug_base
+ CPUV8_DBG_EDECR
, (edecr
|0x4));
1115 /* disable interrupts while stepping */
1116 if (retval
== ERROR_OK
&& aarch64
->isrmasking_mode
== AARCH64_ISRMASK_ON
)
1117 retval
= aarch64_set_dscr_bits(target
, 0x3 << 22, 0x3 << 22);
1118 /* bail out if stepping setup has failed */
1119 if (retval
!= ERROR_OK
)
1122 if (target
->smp
&& (current
== 1)) {
1124 * isolate current target so that it doesn't get resumed
1125 * together with the others
1127 retval
= arm_cti_gate_channel(armv8
->cti
, 1);
1128 /* resume all other targets in the group */
1129 if (retval
== ERROR_OK
)
1130 retval
= aarch64_step_restart_smp(target
);
1131 if (retval
!= ERROR_OK
) {
1132 LOG_ERROR("Failed to restart non-stepping targets in SMP group");
1135 LOG_DEBUG("Restarted all non-stepping targets in SMP group");
1138 /* all other targets running, restore and restart the current target */
1139 retval
= aarch64_restore_one(target
, current
, &address
, 0, 0);
1140 if (retval
== ERROR_OK
)
1141 retval
= aarch64_restart_one(target
, RESTART_LAZY
);
1143 if (retval
!= ERROR_OK
)
1146 LOG_DEBUG("target step-resumed at 0x%" PRIx64
, address
);
1147 if (!handle_breakpoints
)
1148 target_call_event_callbacks(target
, TARGET_EVENT_RESUMED
);
1150 int64_t then
= timeval_ms();
1155 retval
= aarch64_check_state_one(target
,
1156 PRSR_SDR
|PRSR_HALT
, PRSR_SDR
|PRSR_HALT
, &stepped
, &prsr
);
1157 if (retval
!= ERROR_OK
|| stepped
)
1160 if (timeval_ms() > then
+ 100) {
1161 LOG_ERROR("timeout waiting for target %s halt after step",
1162 target_name(target
));
1163 retval
= ERROR_TARGET_TIMEOUT
;
1169 * At least on one SoC (Renesas R8A7795) stepping over a WFI instruction
1170 * causes a timeout. The core takes the step but doesn't complete it and so
1171 * debug state is never entered. However, you can manually halt the core
1172 * as an external debug even is also a WFI wakeup event.
1174 if (retval
== ERROR_TARGET_TIMEOUT
)
1175 saved_retval
= aarch64_halt_one(target
, HALT_SYNC
);
1177 poll_retval
= aarch64_poll(target
);
1180 retval
= mem_ap_write_atomic_u32(armv8
->debug_ap
,
1181 armv8
->debug_base
+ CPUV8_DBG_EDECR
, edecr
);
1182 if (retval
!= ERROR_OK
)
1185 /* restore interrupts */
1186 if (aarch64
->isrmasking_mode
== AARCH64_ISRMASK_ON
) {
1187 retval
= aarch64_set_dscr_bits(target
, 0x3 << 22, 0);
1188 if (retval
!= ERROR_OK
)
1192 if (saved_retval
!= ERROR_OK
)
1193 return saved_retval
;
1195 if (poll_retval
!= ERROR_OK
)
1201 static int aarch64_restore_context(struct target
*target
, bool bpwp
)
1203 struct armv8_common
*armv8
= target_to_armv8(target
);
1204 struct arm
*arm
= &armv8
->arm
;
1208 LOG_DEBUG("%s", target_name(target
));
1210 if (armv8
->pre_restore_context
)
1211 armv8
->pre_restore_context(target
);
1213 retval
= armv8_dpm_write_dirty_registers(&armv8
->dpm
, bpwp
);
1214 if (retval
== ERROR_OK
) {
1215 /* registers are now invalid */
1216 register_cache_invalidate(arm
->core_cache
);
1217 register_cache_invalidate(arm
->core_cache
->next
);
1224 * Cortex-A8 Breakpoint and watchpoint functions
1227 /* Setup hardware Breakpoint Register Pair */
1228 static int aarch64_set_breakpoint(struct target
*target
,
1229 struct breakpoint
*breakpoint
, uint8_t matchmode
)
1234 uint8_t byte_addr_select
= 0x0F;
1235 struct aarch64_common
*aarch64
= target_to_aarch64(target
);
1236 struct armv8_common
*armv8
= &aarch64
->armv8_common
;
1237 struct aarch64_brp
*brp_list
= aarch64
->brp_list
;
1239 if (breakpoint
->is_set
) {
1240 LOG_WARNING("breakpoint already set");
1244 if (breakpoint
->type
== BKPT_HARD
) {
1246 while (brp_list
[brp_i
].used
&& (brp_i
< aarch64
->brp_num
))
1248 if (brp_i
>= aarch64
->brp_num
) {
1249 LOG_ERROR("ERROR Can not find free Breakpoint Register Pair");
1250 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1252 breakpoint_hw_set(breakpoint
, brp_i
);
1253 if (breakpoint
->length
== 2)
1254 byte_addr_select
= (3 << (breakpoint
->address
& 0x02));
1255 control
= ((matchmode
& 0x7) << 20)
1257 | (byte_addr_select
<< 5)
1259 brp_list
[brp_i
].used
= 1;
1260 brp_list
[brp_i
].value
= breakpoint
->address
& 0xFFFFFFFFFFFFFFFCULL
;
1261 brp_list
[brp_i
].control
= control
;
1262 bpt_value
= brp_list
[brp_i
].value
;
1264 retval
= aarch64_dap_write_memap_register_u32(target
, armv8
->debug_base
1265 + CPUV8_DBG_BVR_BASE
+ 16 * brp_list
[brp_i
].brpn
,
1266 (uint32_t)(bpt_value
& 0xFFFFFFFF));
1267 if (retval
!= ERROR_OK
)
1269 retval
= aarch64_dap_write_memap_register_u32(target
, armv8
->debug_base
1270 + CPUV8_DBG_BVR_BASE
+ 4 + 16 * brp_list
[brp_i
].brpn
,
1271 (uint32_t)(bpt_value
>> 32));
1272 if (retval
!= ERROR_OK
)
1275 retval
= aarch64_dap_write_memap_register_u32(target
, armv8
->debug_base
1276 + CPUV8_DBG_BCR_BASE
+ 16 * brp_list
[brp_i
].brpn
,
1277 brp_list
[brp_i
].control
);
1278 if (retval
!= ERROR_OK
)
1280 LOG_DEBUG("brp %i control 0x%0" PRIx32
" value 0x%" TARGET_PRIxADDR
, brp_i
,
1281 brp_list
[brp_i
].control
,
1282 brp_list
[brp_i
].value
);
1284 } else if (breakpoint
->type
== BKPT_SOFT
) {
1288 if (armv8_dpm_get_core_state(&armv8
->dpm
) == ARM_STATE_AARCH64
) {
1289 opcode
= ARMV8_HLT(11);
1291 if (breakpoint
->length
!= 4)
1292 LOG_ERROR("bug: breakpoint length should be 4 in AArch64 mode");
1295 * core_state is ARM_STATE_ARM
1296 * in that case the opcode depends on breakpoint length:
1297 * - if length == 4 => A32 opcode
1298 * - if length == 2 => T32 opcode
1299 * - if length == 3 => T32 opcode (refer to gdb doc : ARM-Breakpoint-Kinds)
1300 * in that case the length should be changed from 3 to 4 bytes
1302 opcode
= (breakpoint
->length
== 4) ? ARMV8_HLT_A1(11) :
1303 (uint32_t) (ARMV8_HLT_T1(11) | ARMV8_HLT_T1(11) << 16);
1305 if (breakpoint
->length
== 3)
1306 breakpoint
->length
= 4;
1309 buf_set_u32(code
, 0, 32, opcode
);
1311 retval
= target_read_memory(target
,
1312 breakpoint
->address
& 0xFFFFFFFFFFFFFFFEULL
,
1313 breakpoint
->length
, 1,
1314 breakpoint
->orig_instr
);
1315 if (retval
!= ERROR_OK
)
1318 armv8_cache_d_inner_flush_virt(armv8
,
1319 breakpoint
->address
& 0xFFFFFFFFFFFFFFFEULL
,
1320 breakpoint
->length
);
1322 retval
= target_write_memory(target
,
1323 breakpoint
->address
& 0xFFFFFFFFFFFFFFFEULL
,
1324 breakpoint
->length
, 1, code
);
1325 if (retval
!= ERROR_OK
)
1328 armv8_cache_d_inner_flush_virt(armv8
,
1329 breakpoint
->address
& 0xFFFFFFFFFFFFFFFEULL
,
1330 breakpoint
->length
);
1332 armv8_cache_i_inner_inval_virt(armv8
,
1333 breakpoint
->address
& 0xFFFFFFFFFFFFFFFEULL
,
1334 breakpoint
->length
);
1336 breakpoint
->is_set
= true;
1339 /* Ensure that halting debug mode is enable */
1340 retval
= aarch64_set_dscr_bits(target
, DSCR_HDE
, DSCR_HDE
);
1341 if (retval
!= ERROR_OK
) {
1342 LOG_DEBUG("Failed to set DSCR.HDE");
1349 static int aarch64_set_context_breakpoint(struct target
*target
,
1350 struct breakpoint
*breakpoint
, uint8_t matchmode
)
1352 int retval
= ERROR_FAIL
;
1355 uint8_t byte_addr_select
= 0x0F;
1356 struct aarch64_common
*aarch64
= target_to_aarch64(target
);
1357 struct armv8_common
*armv8
= &aarch64
->armv8_common
;
1358 struct aarch64_brp
*brp_list
= aarch64
->brp_list
;
1360 if (breakpoint
->is_set
) {
1361 LOG_WARNING("breakpoint already set");
1364 /*check available context BRPs*/
1365 while ((brp_list
[brp_i
].used
||
1366 (brp_list
[brp_i
].type
!= BRP_CONTEXT
)) && (brp_i
< aarch64
->brp_num
))
1369 if (brp_i
>= aarch64
->brp_num
) {
1370 LOG_ERROR("ERROR Can not find free Breakpoint Register Pair");
1374 breakpoint_hw_set(breakpoint
, brp_i
);
1375 control
= ((matchmode
& 0x7) << 20)
1377 | (byte_addr_select
<< 5)
1379 brp_list
[brp_i
].used
= 1;
1380 brp_list
[brp_i
].value
= (breakpoint
->asid
);
1381 brp_list
[brp_i
].control
= control
;
1382 retval
= aarch64_dap_write_memap_register_u32(target
, armv8
->debug_base
1383 + CPUV8_DBG_BVR_BASE
+ 16 * brp_list
[brp_i
].brpn
,
1384 brp_list
[brp_i
].value
);
1385 if (retval
!= ERROR_OK
)
1387 retval
= aarch64_dap_write_memap_register_u32(target
, armv8
->debug_base
1388 + CPUV8_DBG_BCR_BASE
+ 16 * brp_list
[brp_i
].brpn
,
1389 brp_list
[brp_i
].control
);
1390 if (retval
!= ERROR_OK
)
1392 LOG_DEBUG("brp %i control 0x%0" PRIx32
" value 0x%" TARGET_PRIxADDR
, brp_i
,
1393 brp_list
[brp_i
].control
,
1394 brp_list
[brp_i
].value
);
1399 static int aarch64_set_hybrid_breakpoint(struct target
*target
, struct breakpoint
*breakpoint
)
1401 int retval
= ERROR_FAIL
;
1402 int brp_1
= 0; /* holds the contextID pair */
1403 int brp_2
= 0; /* holds the IVA pair */
1404 uint32_t control_ctx
, control_iva
;
1405 uint8_t ctx_byte_addr_select
= 0x0F;
1406 uint8_t iva_byte_addr_select
= 0x0F;
1407 uint8_t ctx_machmode
= 0x03;
1408 uint8_t iva_machmode
= 0x01;
1409 struct aarch64_common
*aarch64
= target_to_aarch64(target
);
1410 struct armv8_common
*armv8
= &aarch64
->armv8_common
;
1411 struct aarch64_brp
*brp_list
= aarch64
->brp_list
;
1413 if (breakpoint
->is_set
) {
1414 LOG_WARNING("breakpoint already set");
1417 /*check available context BRPs*/
1418 while ((brp_list
[brp_1
].used
||
1419 (brp_list
[brp_1
].type
!= BRP_CONTEXT
)) && (brp_1
< aarch64
->brp_num
))
1422 LOG_DEBUG("brp(CTX) found num: %d", brp_1
);
1423 if (brp_1
>= aarch64
->brp_num
) {
1424 LOG_ERROR("ERROR Can not find free Breakpoint Register Pair");
1428 while ((brp_list
[brp_2
].used
||
1429 (brp_list
[brp_2
].type
!= BRP_NORMAL
)) && (brp_2
< aarch64
->brp_num
))
1432 LOG_DEBUG("brp(IVA) found num: %d", brp_2
);
1433 if (brp_2
>= aarch64
->brp_num
) {
1434 LOG_ERROR("ERROR Can not find free Breakpoint Register Pair");
1438 breakpoint_hw_set(breakpoint
, brp_1
);
1439 breakpoint
->linked_brp
= brp_2
;
1440 control_ctx
= ((ctx_machmode
& 0x7) << 20)
1443 | (ctx_byte_addr_select
<< 5)
1445 brp_list
[brp_1
].used
= 1;
1446 brp_list
[brp_1
].value
= (breakpoint
->asid
);
1447 brp_list
[brp_1
].control
= control_ctx
;
1448 retval
= aarch64_dap_write_memap_register_u32(target
, armv8
->debug_base
1449 + CPUV8_DBG_BVR_BASE
+ 16 * brp_list
[brp_1
].brpn
,
1450 brp_list
[brp_1
].value
);
1451 if (retval
!= ERROR_OK
)
1453 retval
= aarch64_dap_write_memap_register_u32(target
, armv8
->debug_base
1454 + CPUV8_DBG_BCR_BASE
+ 16 * brp_list
[brp_1
].brpn
,
1455 brp_list
[brp_1
].control
);
1456 if (retval
!= ERROR_OK
)
1459 control_iva
= ((iva_machmode
& 0x7) << 20)
1462 | (iva_byte_addr_select
<< 5)
1464 brp_list
[brp_2
].used
= 1;
1465 brp_list
[brp_2
].value
= breakpoint
->address
& 0xFFFFFFFFFFFFFFFCULL
;
1466 brp_list
[brp_2
].control
= control_iva
;
1467 retval
= aarch64_dap_write_memap_register_u32(target
, armv8
->debug_base
1468 + CPUV8_DBG_BVR_BASE
+ 16 * brp_list
[brp_2
].brpn
,
1469 brp_list
[brp_2
].value
& 0xFFFFFFFF);
1470 if (retval
!= ERROR_OK
)
1472 retval
= aarch64_dap_write_memap_register_u32(target
, armv8
->debug_base
1473 + CPUV8_DBG_BVR_BASE
+ 4 + 16 * brp_list
[brp_2
].brpn
,
1474 brp_list
[brp_2
].value
>> 32);
1475 if (retval
!= ERROR_OK
)
1477 retval
= aarch64_dap_write_memap_register_u32(target
, armv8
->debug_base
1478 + CPUV8_DBG_BCR_BASE
+ 16 * brp_list
[brp_2
].brpn
,
1479 brp_list
[brp_2
].control
);
1480 if (retval
!= ERROR_OK
)
1486 static int aarch64_unset_breakpoint(struct target
*target
, struct breakpoint
*breakpoint
)
1489 struct aarch64_common
*aarch64
= target_to_aarch64(target
);
1490 struct armv8_common
*armv8
= &aarch64
->armv8_common
;
1491 struct aarch64_brp
*brp_list
= aarch64
->brp_list
;
1493 if (!breakpoint
->is_set
) {
1494 LOG_WARNING("breakpoint not set");
1498 if (breakpoint
->type
== BKPT_HARD
) {
1499 if ((breakpoint
->address
!= 0) && (breakpoint
->asid
!= 0)) {
1500 int brp_i
= breakpoint
->number
;
1501 int brp_j
= breakpoint
->linked_brp
;
1502 if (brp_i
>= aarch64
->brp_num
) {
1503 LOG_DEBUG("Invalid BRP number in breakpoint");
1506 LOG_DEBUG("rbp %i control 0x%0" PRIx32
" value 0x%" TARGET_PRIxADDR
, brp_i
,
1507 brp_list
[brp_i
].control
, brp_list
[brp_i
].value
);
1508 brp_list
[brp_i
].used
= 0;
1509 brp_list
[brp_i
].value
= 0;
1510 brp_list
[brp_i
].control
= 0;
1511 retval
= aarch64_dap_write_memap_register_u32(target
, armv8
->debug_base
1512 + CPUV8_DBG_BCR_BASE
+ 16 * brp_list
[brp_i
].brpn
,
1513 brp_list
[brp_i
].control
);
1514 if (retval
!= ERROR_OK
)
1516 retval
= aarch64_dap_write_memap_register_u32(target
, armv8
->debug_base
1517 + CPUV8_DBG_BVR_BASE
+ 16 * brp_list
[brp_i
].brpn
,
1518 (uint32_t)brp_list
[brp_i
].value
);
1519 if (retval
!= ERROR_OK
)
1521 retval
= aarch64_dap_write_memap_register_u32(target
, armv8
->debug_base
1522 + CPUV8_DBG_BVR_BASE
+ 4 + 16 * brp_list
[brp_i
].brpn
,
1523 (uint32_t)brp_list
[brp_i
].value
);
1524 if (retval
!= ERROR_OK
)
1526 if ((brp_j
< 0) || (brp_j
>= aarch64
->brp_num
)) {
1527 LOG_DEBUG("Invalid BRP number in breakpoint");
1530 LOG_DEBUG("rbp %i control 0x%0" PRIx32
" value 0x%0" PRIx64
, brp_j
,
1531 brp_list
[brp_j
].control
, brp_list
[brp_j
].value
);
1532 brp_list
[brp_j
].used
= 0;
1533 brp_list
[brp_j
].value
= 0;
1534 brp_list
[brp_j
].control
= 0;
1535 retval
= aarch64_dap_write_memap_register_u32(target
, armv8
->debug_base
1536 + CPUV8_DBG_BCR_BASE
+ 16 * brp_list
[brp_j
].brpn
,
1537 brp_list
[brp_j
].control
);
1538 if (retval
!= ERROR_OK
)
1540 retval
= aarch64_dap_write_memap_register_u32(target
, armv8
->debug_base
1541 + CPUV8_DBG_BVR_BASE
+ 16 * brp_list
[brp_j
].brpn
,
1542 (uint32_t)brp_list
[brp_j
].value
);
1543 if (retval
!= ERROR_OK
)
1545 retval
= aarch64_dap_write_memap_register_u32(target
, armv8
->debug_base
1546 + CPUV8_DBG_BVR_BASE
+ 4 + 16 * brp_list
[brp_j
].brpn
,
1547 (uint32_t)brp_list
[brp_j
].value
);
1548 if (retval
!= ERROR_OK
)
1551 breakpoint
->linked_brp
= 0;
1552 breakpoint
->is_set
= false;
1556 int brp_i
= breakpoint
->number
;
1557 if (brp_i
>= aarch64
->brp_num
) {
1558 LOG_DEBUG("Invalid BRP number in breakpoint");
1561 LOG_DEBUG("rbp %i control 0x%0" PRIx32
" value 0x%0" PRIx64
, brp_i
,
1562 brp_list
[brp_i
].control
, brp_list
[brp_i
].value
);
1563 brp_list
[brp_i
].used
= 0;
1564 brp_list
[brp_i
].value
= 0;
1565 brp_list
[brp_i
].control
= 0;
1566 retval
= aarch64_dap_write_memap_register_u32(target
, armv8
->debug_base
1567 + CPUV8_DBG_BCR_BASE
+ 16 * brp_list
[brp_i
].brpn
,
1568 brp_list
[brp_i
].control
);
1569 if (retval
!= ERROR_OK
)
1571 retval
= aarch64_dap_write_memap_register_u32(target
, armv8
->debug_base
1572 + CPUV8_DBG_BVR_BASE
+ 16 * brp_list
[brp_i
].brpn
,
1573 brp_list
[brp_i
].value
);
1574 if (retval
!= ERROR_OK
)
1577 retval
= aarch64_dap_write_memap_register_u32(target
, armv8
->debug_base
1578 + CPUV8_DBG_BVR_BASE
+ 4 + 16 * brp_list
[brp_i
].brpn
,
1579 (uint32_t)brp_list
[brp_i
].value
);
1580 if (retval
!= ERROR_OK
)
1582 breakpoint
->is_set
= false;
1586 /* restore original instruction (kept in target endianness) */
1588 armv8_cache_d_inner_flush_virt(armv8
,
1589 breakpoint
->address
& 0xFFFFFFFFFFFFFFFEULL
,
1590 breakpoint
->length
);
1592 if (breakpoint
->length
== 4) {
1593 retval
= target_write_memory(target
,
1594 breakpoint
->address
& 0xFFFFFFFFFFFFFFFEULL
,
1595 4, 1, breakpoint
->orig_instr
);
1596 if (retval
!= ERROR_OK
)
1599 retval
= target_write_memory(target
,
1600 breakpoint
->address
& 0xFFFFFFFFFFFFFFFEULL
,
1601 2, 1, breakpoint
->orig_instr
);
1602 if (retval
!= ERROR_OK
)
1606 armv8_cache_d_inner_flush_virt(armv8
,
1607 breakpoint
->address
& 0xFFFFFFFFFFFFFFFEULL
,
1608 breakpoint
->length
);
1610 armv8_cache_i_inner_inval_virt(armv8
,
1611 breakpoint
->address
& 0xFFFFFFFFFFFFFFFEULL
,
1612 breakpoint
->length
);
1614 breakpoint
->is_set
= false;
1619 static int aarch64_add_breakpoint(struct target
*target
,
1620 struct breakpoint
*breakpoint
)
1622 struct aarch64_common
*aarch64
= target_to_aarch64(target
);
1624 if ((breakpoint
->type
== BKPT_HARD
) && (aarch64
->brp_num_available
< 1)) {
1625 LOG_INFO("no hardware breakpoint available");
1626 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1629 if (breakpoint
->type
== BKPT_HARD
)
1630 aarch64
->brp_num_available
--;
1632 return aarch64_set_breakpoint(target
, breakpoint
, 0x00); /* Exact match */
1635 static int aarch64_add_context_breakpoint(struct target
*target
,
1636 struct breakpoint
*breakpoint
)
1638 struct aarch64_common
*aarch64
= target_to_aarch64(target
);
1640 if ((breakpoint
->type
== BKPT_HARD
) && (aarch64
->brp_num_available
< 1)) {
1641 LOG_INFO("no hardware breakpoint available");
1642 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1645 if (breakpoint
->type
== BKPT_HARD
)
1646 aarch64
->brp_num_available
--;
1648 return aarch64_set_context_breakpoint(target
, breakpoint
, 0x02); /* asid match */
1651 static int aarch64_add_hybrid_breakpoint(struct target
*target
,
1652 struct breakpoint
*breakpoint
)
1654 struct aarch64_common
*aarch64
= target_to_aarch64(target
);
1656 if ((breakpoint
->type
== BKPT_HARD
) && (aarch64
->brp_num_available
< 1)) {
1657 LOG_INFO("no hardware breakpoint available");
1658 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1661 if (breakpoint
->type
== BKPT_HARD
)
1662 aarch64
->brp_num_available
--;
1664 return aarch64_set_hybrid_breakpoint(target
, breakpoint
); /* ??? */
1667 static int aarch64_remove_breakpoint(struct target
*target
, struct breakpoint
*breakpoint
)
1669 struct aarch64_common
*aarch64
= target_to_aarch64(target
);
1672 /* It is perfectly possible to remove breakpoints while the target is running */
1673 if (target
->state
!= TARGET_HALTED
) {
1674 LOG_WARNING("target not halted");
1675 return ERROR_TARGET_NOT_HALTED
;
1679 if (breakpoint
->is_set
) {
1680 aarch64_unset_breakpoint(target
, breakpoint
);
1681 if (breakpoint
->type
== BKPT_HARD
)
1682 aarch64
->brp_num_available
++;
1688 /* Setup hardware Watchpoint Register Pair */
1689 static int aarch64_set_watchpoint(struct target
*target
,
1690 struct watchpoint
*watchpoint
)
1694 uint32_t control
, offset
, length
;
1695 struct aarch64_common
*aarch64
= target_to_aarch64(target
);
1696 struct armv8_common
*armv8
= &aarch64
->armv8_common
;
1697 struct aarch64_brp
*wp_list
= aarch64
->wp_list
;
1699 if (watchpoint
->is_set
) {
1700 LOG_WARNING("watchpoint already set");
1704 while (wp_list
[wp_i
].used
&& (wp_i
< aarch64
->wp_num
))
1706 if (wp_i
>= aarch64
->wp_num
) {
1707 LOG_ERROR("ERROR Can not find free Watchpoint Register Pair");
1708 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1711 control
= (1 << 0) /* enable */
1712 | (3 << 1) /* both user and privileged access */
1713 | (1 << 13); /* higher mode control */
1715 switch (watchpoint
->rw
) {
1727 /* Match up to 8 bytes. */
1728 offset
= watchpoint
->address
& 7;
1729 length
= watchpoint
->length
;
1730 if (offset
+ length
> sizeof(uint64_t)) {
1731 length
= sizeof(uint64_t) - offset
;
1732 LOG_WARNING("Adjust watchpoint match inside 8-byte boundary");
1734 for (; length
> 0; offset
++, length
--)
1735 control
|= (1 << offset
) << 5;
1737 wp_list
[wp_i
].value
= watchpoint
->address
& 0xFFFFFFFFFFFFFFF8ULL
;
1738 wp_list
[wp_i
].control
= control
;
1740 retval
= aarch64_dap_write_memap_register_u32(target
, armv8
->debug_base
1741 + CPUV8_DBG_WVR_BASE
+ 16 * wp_list
[wp_i
].brpn
,
1742 (uint32_t)(wp_list
[wp_i
].value
& 0xFFFFFFFF));
1743 if (retval
!= ERROR_OK
)
1745 retval
= aarch64_dap_write_memap_register_u32(target
, armv8
->debug_base
1746 + CPUV8_DBG_WVR_BASE
+ 4 + 16 * wp_list
[wp_i
].brpn
,
1747 (uint32_t)(wp_list
[wp_i
].value
>> 32));
1748 if (retval
!= ERROR_OK
)
1751 retval
= aarch64_dap_write_memap_register_u32(target
, armv8
->debug_base
1752 + CPUV8_DBG_WCR_BASE
+ 16 * wp_list
[wp_i
].brpn
,
1754 if (retval
!= ERROR_OK
)
1756 LOG_DEBUG("wp %i control 0x%0" PRIx32
" value 0x%" TARGET_PRIxADDR
, wp_i
,
1757 wp_list
[wp_i
].control
, wp_list
[wp_i
].value
);
1759 /* Ensure that halting debug mode is enable */
1760 retval
= aarch64_set_dscr_bits(target
, DSCR_HDE
, DSCR_HDE
);
1761 if (retval
!= ERROR_OK
) {
1762 LOG_DEBUG("Failed to set DSCR.HDE");
1766 wp_list
[wp_i
].used
= 1;
1767 watchpoint_set(watchpoint
, wp_i
);
1772 /* Clear hardware Watchpoint Register Pair */
1773 static int aarch64_unset_watchpoint(struct target
*target
,
1774 struct watchpoint
*watchpoint
)
1777 struct aarch64_common
*aarch64
= target_to_aarch64(target
);
1778 struct armv8_common
*armv8
= &aarch64
->armv8_common
;
1779 struct aarch64_brp
*wp_list
= aarch64
->wp_list
;
1781 if (!watchpoint
->is_set
) {
1782 LOG_WARNING("watchpoint not set");
1786 int wp_i
= watchpoint
->number
;
1787 if (wp_i
>= aarch64
->wp_num
) {
1788 LOG_DEBUG("Invalid WP number in watchpoint");
1791 LOG_DEBUG("rwp %i control 0x%0" PRIx32
" value 0x%0" PRIx64
, wp_i
,
1792 wp_list
[wp_i
].control
, wp_list
[wp_i
].value
);
1793 wp_list
[wp_i
].used
= 0;
1794 wp_list
[wp_i
].value
= 0;
1795 wp_list
[wp_i
].control
= 0;
1796 retval
= aarch64_dap_write_memap_register_u32(target
, armv8
->debug_base
1797 + CPUV8_DBG_WCR_BASE
+ 16 * wp_list
[wp_i
].brpn
,
1798 wp_list
[wp_i
].control
);
1799 if (retval
!= ERROR_OK
)
1801 retval
= aarch64_dap_write_memap_register_u32(target
, armv8
->debug_base
1802 + CPUV8_DBG_WVR_BASE
+ 16 * wp_list
[wp_i
].brpn
,
1803 wp_list
[wp_i
].value
);
1804 if (retval
!= ERROR_OK
)
1807 retval
= aarch64_dap_write_memap_register_u32(target
, armv8
->debug_base
1808 + CPUV8_DBG_WVR_BASE
+ 4 + 16 * wp_list
[wp_i
].brpn
,
1809 (uint32_t)wp_list
[wp_i
].value
);
1810 if (retval
!= ERROR_OK
)
1812 watchpoint
->is_set
= false;
1817 static int aarch64_add_watchpoint(struct target
*target
,
1818 struct watchpoint
*watchpoint
)
1821 struct aarch64_common
*aarch64
= target_to_aarch64(target
);
1823 if (aarch64
->wp_num_available
< 1) {
1824 LOG_INFO("no hardware watchpoint available");
1825 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1828 retval
= aarch64_set_watchpoint(target
, watchpoint
);
1829 if (retval
== ERROR_OK
)
1830 aarch64
->wp_num_available
--;
1835 static int aarch64_remove_watchpoint(struct target
*target
,
1836 struct watchpoint
*watchpoint
)
1838 struct aarch64_common
*aarch64
= target_to_aarch64(target
);
1840 if (watchpoint
->is_set
) {
1841 aarch64_unset_watchpoint(target
, watchpoint
);
1842 aarch64
->wp_num_available
++;
1849 * find out which watchpoint hits
1850 * get exception address and compare the address to watchpoints
1852 static int aarch64_hit_watchpoint(struct target
*target
,
1853 struct watchpoint
**hit_watchpoint
)
1855 if (target
->debug_reason
!= DBG_REASON_WATCHPOINT
)
1858 struct armv8_common
*armv8
= target_to_armv8(target
);
1860 target_addr_t exception_address
;
1861 struct watchpoint
*wp
;
1863 exception_address
= armv8
->dpm
.wp_addr
;
1865 if (exception_address
== 0xFFFFFFFF)
1868 for (wp
= target
->watchpoints
; wp
; wp
= wp
->next
)
1869 if (exception_address
>= wp
->address
&& exception_address
< (wp
->address
+ wp
->length
)) {
1870 *hit_watchpoint
= wp
;
1878 * Cortex-A8 Reset functions
1881 static int aarch64_enable_reset_catch(struct target
*target
, bool enable
)
1883 struct armv8_common
*armv8
= target_to_armv8(target
);
1887 retval
= mem_ap_read_atomic_u32(armv8
->debug_ap
,
1888 armv8
->debug_base
+ CPUV8_DBG_EDECR
, &edecr
);
1889 LOG_DEBUG("EDECR = 0x%08" PRIx32
", enable=%d", edecr
, enable
);
1890 if (retval
!= ERROR_OK
)
1898 return mem_ap_write_atomic_u32(armv8
->debug_ap
,
1899 armv8
->debug_base
+ CPUV8_DBG_EDECR
, edecr
);
1902 static int aarch64_clear_reset_catch(struct target
*target
)
1904 struct armv8_common
*armv8
= target_to_armv8(target
);
1909 /* check if Reset Catch debug event triggered as expected */
1910 retval
= mem_ap_read_atomic_u32(armv8
->debug_ap
,
1911 armv8
->debug_base
+ CPUV8_DBG_EDESR
, &edesr
);
1912 if (retval
!= ERROR_OK
)
1915 was_triggered
= !!(edesr
& ESR_RC
);
1916 LOG_DEBUG("Reset Catch debug event %s",
1917 was_triggered
? "triggered" : "NOT triggered!");
1919 if (was_triggered
) {
1920 /* clear pending Reset Catch debug event */
1922 retval
= mem_ap_write_atomic_u32(armv8
->debug_ap
,
1923 armv8
->debug_base
+ CPUV8_DBG_EDESR
, edesr
);
1924 if (retval
!= ERROR_OK
)
1931 static int aarch64_assert_reset(struct target
*target
)
1933 struct armv8_common
*armv8
= target_to_armv8(target
);
1934 enum reset_types reset_config
= jtag_get_reset_config();
1939 /* Issue some kind of warm reset. */
1940 if (target_has_event_action(target
, TARGET_EVENT_RESET_ASSERT
))
1941 target_handle_event(target
, TARGET_EVENT_RESET_ASSERT
);
1942 else if (reset_config
& RESET_HAS_SRST
) {
1943 bool srst_asserted
= false;
1945 if (target
->reset_halt
&& !(reset_config
& RESET_SRST_PULLS_TRST
)) {
1946 if (target_was_examined(target
)) {
1948 if (reset_config
& RESET_SRST_NO_GATING
) {
1950 * SRST needs to be asserted *before* Reset Catch
1951 * debug event can be set up.
1953 adapter_assert_reset();
1954 srst_asserted
= true;
1957 /* make sure to clear all sticky errors */
1958 mem_ap_write_atomic_u32(armv8
->debug_ap
,
1959 armv8
->debug_base
+ CPUV8_DBG_DRCR
, DRCR_CSE
);
1961 /* set up Reset Catch debug event to halt the CPU after reset */
1962 retval
= aarch64_enable_reset_catch(target
, true);
1963 if (retval
!= ERROR_OK
)
1964 LOG_WARNING("%s: Error enabling Reset Catch debug event; the CPU will not halt immediately after reset!",
1965 target_name(target
));
1967 LOG_WARNING("%s: Target not examined, will not halt immediately after reset!",
1968 target_name(target
));
1972 /* REVISIT handle "pulls" cases, if there's
1973 * hardware that needs them to work.
1976 adapter_assert_reset();
1978 LOG_ERROR("%s: how to reset?", target_name(target
));
1982 /* registers are now invalid */
1983 if (target_was_examined(target
)) {
1984 register_cache_invalidate(armv8
->arm
.core_cache
);
1985 register_cache_invalidate(armv8
->arm
.core_cache
->next
);
1988 target
->state
= TARGET_RESET
;
1993 static int aarch64_deassert_reset(struct target
*target
)
1999 /* be certain SRST is off */
2000 adapter_deassert_reset();
2002 if (!target_was_examined(target
))
2005 retval
= aarch64_init_debug_access(target
);
2006 if (retval
!= ERROR_OK
)
2009 retval
= aarch64_poll(target
);
2010 if (retval
!= ERROR_OK
)
2013 if (target
->reset_halt
) {
2014 /* clear pending Reset Catch debug event */
2015 retval
= aarch64_clear_reset_catch(target
);
2016 if (retval
!= ERROR_OK
)
2017 LOG_WARNING("%s: Clearing Reset Catch debug event failed",
2018 target_name(target
));
2020 /* disable Reset Catch debug event */
2021 retval
= aarch64_enable_reset_catch(target
, false);
2022 if (retval
!= ERROR_OK
)
2023 LOG_WARNING("%s: Disabling Reset Catch debug event failed",
2024 target_name(target
));
2026 if (target
->state
!= TARGET_HALTED
) {
2027 LOG_WARNING("%s: ran after reset and before halt ...",
2028 target_name(target
));
2029 if (target_was_examined(target
)) {
2030 retval
= aarch64_halt_one(target
, HALT_LAZY
);
2031 if (retval
!= ERROR_OK
)
2034 target
->state
= TARGET_UNKNOWN
;
2042 static int aarch64_write_cpu_memory_slow(struct target
*target
,
2043 uint32_t size
, uint32_t count
, const uint8_t *buffer
, uint32_t *dscr
)
2045 struct armv8_common
*armv8
= target_to_armv8(target
);
2046 struct arm_dpm
*dpm
= &armv8
->dpm
;
2047 struct arm
*arm
= &armv8
->arm
;
2050 armv8_reg_current(arm
, 1)->dirty
= true;
2052 /* change DCC to normal mode if necessary */
2053 if (*dscr
& DSCR_MA
) {
2055 retval
= mem_ap_write_atomic_u32(armv8
->debug_ap
,
2056 armv8
->debug_base
+ CPUV8_DBG_DSCR
, *dscr
);
2057 if (retval
!= ERROR_OK
)
2062 uint32_t data
, opcode
;
2064 /* write the data to store into DTRRX */
2068 data
= target_buffer_get_u16(target
, buffer
);
2070 data
= target_buffer_get_u32(target
, buffer
);
2071 retval
= mem_ap_write_atomic_u32(armv8
->debug_ap
,
2072 armv8
->debug_base
+ CPUV8_DBG_DTRRX
, data
);
2073 if (retval
!= ERROR_OK
)
2076 if (arm
->core_state
== ARM_STATE_AARCH64
)
2077 retval
= dpm
->instr_execute(dpm
, ARMV8_MRS(SYSTEM_DBG_DTRRX_EL0
, 1));
2079 retval
= dpm
->instr_execute(dpm
, ARMV4_5_MRC(14, 0, 1, 0, 5, 0));
2080 if (retval
!= ERROR_OK
)
2084 opcode
= armv8_opcode(armv8
, ARMV8_OPC_STRB_IP
);
2086 opcode
= armv8_opcode(armv8
, ARMV8_OPC_STRH_IP
);
2088 opcode
= armv8_opcode(armv8
, ARMV8_OPC_STRW_IP
);
2089 retval
= dpm
->instr_execute(dpm
, opcode
);
2090 if (retval
!= ERROR_OK
)
2101 static int aarch64_write_cpu_memory_fast(struct target
*target
,
2102 uint32_t count
, const uint8_t *buffer
, uint32_t *dscr
)
2104 struct armv8_common
*armv8
= target_to_armv8(target
);
2105 struct arm
*arm
= &armv8
->arm
;
2108 armv8_reg_current(arm
, 1)->dirty
= true;
2110 /* Step 1.d - Change DCC to memory mode */
2112 retval
= mem_ap_write_atomic_u32(armv8
->debug_ap
,
2113 armv8
->debug_base
+ CPUV8_DBG_DSCR
, *dscr
);
2114 if (retval
!= ERROR_OK
)
2118 /* Step 2.a - Do the write */
2119 retval
= mem_ap_write_buf_noincr(armv8
->debug_ap
,
2120 buffer
, 4, count
, armv8
->debug_base
+ CPUV8_DBG_DTRRX
);
2121 if (retval
!= ERROR_OK
)
2124 /* Step 3.a - Switch DTR mode back to Normal mode */
2126 retval
= mem_ap_write_atomic_u32(armv8
->debug_ap
,
2127 armv8
->debug_base
+ CPUV8_DBG_DSCR
, *dscr
);
2128 if (retval
!= ERROR_OK
)
2134 static int aarch64_write_cpu_memory(struct target
*target
,
2135 uint64_t address
, uint32_t size
,
2136 uint32_t count
, const uint8_t *buffer
)
2138 /* write memory through APB-AP */
2139 int retval
= ERROR_COMMAND_SYNTAX_ERROR
;
2140 struct armv8_common
*armv8
= target_to_armv8(target
);
2141 struct arm_dpm
*dpm
= &armv8
->dpm
;
2142 struct arm
*arm
= &armv8
->arm
;
2145 if (target
->state
!= TARGET_HALTED
) {
2146 LOG_TARGET_ERROR(target
, "not halted");
2147 return ERROR_TARGET_NOT_HALTED
;
2150 /* Mark register X0 as dirty, as it will be used
2151 * for transferring the data.
2152 * It will be restored automatically when exiting
2155 armv8_reg_current(arm
, 0)->dirty
= true;
2157 /* This algorithm comes from DDI0487A.g, chapter J9.1 */
2160 retval
= mem_ap_read_atomic_u32(armv8
->debug_ap
,
2161 armv8
->debug_base
+ CPUV8_DBG_DSCR
, &dscr
);
2162 if (retval
!= ERROR_OK
)
2165 /* Set Normal access mode */
2166 dscr
= (dscr
& ~DSCR_MA
);
2167 retval
= mem_ap_write_atomic_u32(armv8
->debug_ap
,
2168 armv8
->debug_base
+ CPUV8_DBG_DSCR
, dscr
);
2169 if (retval
!= ERROR_OK
)
2172 if (arm
->core_state
== ARM_STATE_AARCH64
) {
2173 /* Write X0 with value 'address' using write procedure */
2174 /* Step 1.a+b - Write the address for read access into DBGDTR_EL0 */
2175 /* Step 1.c - Copy value from DTR to R0 using instruction mrs DBGDTR_EL0, x0 */
2176 retval
= dpm
->instr_write_data_dcc_64(dpm
,
2177 ARMV8_MRS(SYSTEM_DBG_DBGDTR_EL0
, 0), address
);
2179 /* Write R0 with value 'address' using write procedure */
2180 /* Step 1.a+b - Write the address for read access into DBGDTRRX */
2181 /* Step 1.c - Copy value from DTR to R0 using instruction mrc DBGDTRTXint, r0 */
2182 retval
= dpm
->instr_write_data_dcc(dpm
,
2183 ARMV4_5_MRC(14, 0, 0, 0, 5, 0), address
);
2186 if (retval
!= ERROR_OK
)
2189 if (size
== 4 && (address
% 4) == 0)
2190 retval
= aarch64_write_cpu_memory_fast(target
, count
, buffer
, &dscr
);
2192 retval
= aarch64_write_cpu_memory_slow(target
, size
, count
, buffer
, &dscr
);
2194 if (retval
!= ERROR_OK
) {
2195 /* Unset DTR mode */
2196 mem_ap_read_atomic_u32(armv8
->debug_ap
,
2197 armv8
->debug_base
+ CPUV8_DBG_DSCR
, &dscr
);
2199 mem_ap_write_atomic_u32(armv8
->debug_ap
,
2200 armv8
->debug_base
+ CPUV8_DBG_DSCR
, dscr
);
2203 /* Check for sticky abort flags in the DSCR */
2204 retval
= mem_ap_read_atomic_u32(armv8
->debug_ap
,
2205 armv8
->debug_base
+ CPUV8_DBG_DSCR
, &dscr
);
2206 if (retval
!= ERROR_OK
)
2210 if (dscr
& (DSCR_ERR
| DSCR_SYS_ERROR_PEND
)) {
2211 /* Abort occurred - clear it and exit */
2212 LOG_ERROR("abort occurred - dscr = 0x%08" PRIx32
, dscr
);
2213 armv8_dpm_handle_exception(dpm
, true);
2221 static int aarch64_read_cpu_memory_slow(struct target
*target
,
2222 uint32_t size
, uint32_t count
, uint8_t *buffer
, uint32_t *dscr
)
2224 struct armv8_common
*armv8
= target_to_armv8(target
);
2225 struct arm_dpm
*dpm
= &armv8
->dpm
;
2226 struct arm
*arm
= &armv8
->arm
;
2229 armv8_reg_current(arm
, 1)->dirty
= true;
2231 /* change DCC to normal mode (if necessary) */
2232 if (*dscr
& DSCR_MA
) {
2234 retval
= mem_ap_write_atomic_u32(armv8
->debug_ap
,
2235 armv8
->debug_base
+ CPUV8_DBG_DSCR
, *dscr
);
2236 if (retval
!= ERROR_OK
)
2241 uint32_t opcode
, data
;
2244 opcode
= armv8_opcode(armv8
, ARMV8_OPC_LDRB_IP
);
2246 opcode
= armv8_opcode(armv8
, ARMV8_OPC_LDRH_IP
);
2248 opcode
= armv8_opcode(armv8
, ARMV8_OPC_LDRW_IP
);
2249 retval
= dpm
->instr_execute(dpm
, opcode
);
2250 if (retval
!= ERROR_OK
)
2253 if (arm
->core_state
== ARM_STATE_AARCH64
)
2254 retval
= dpm
->instr_execute(dpm
, ARMV8_MSR_GP(SYSTEM_DBG_DTRTX_EL0
, 1));
2256 retval
= dpm
->instr_execute(dpm
, ARMV4_5_MCR(14, 0, 1, 0, 5, 0));
2257 if (retval
!= ERROR_OK
)
2260 retval
= mem_ap_read_atomic_u32(armv8
->debug_ap
,
2261 armv8
->debug_base
+ CPUV8_DBG_DTRTX
, &data
);
2262 if (retval
!= ERROR_OK
)
2266 *buffer
= (uint8_t)data
;
2268 target_buffer_set_u16(target
, buffer
, (uint16_t)data
);
2270 target_buffer_set_u32(target
, buffer
, data
);
2280 static int aarch64_read_cpu_memory_fast(struct target
*target
,
2281 uint32_t count
, uint8_t *buffer
, uint32_t *dscr
)
2283 struct armv8_common
*armv8
= target_to_armv8(target
);
2284 struct arm_dpm
*dpm
= &armv8
->dpm
;
2285 struct arm
*arm
= &armv8
->arm
;
2289 /* Mark X1 as dirty */
2290 armv8_reg_current(arm
, 1)->dirty
= true;
2292 if (arm
->core_state
== ARM_STATE_AARCH64
) {
2293 /* Step 1.d - Dummy operation to ensure EDSCR.Txfull == 1 */
2294 retval
= dpm
->instr_execute(dpm
, ARMV8_MSR_GP(SYSTEM_DBG_DBGDTR_EL0
, 0));
2296 /* Step 1.d - Dummy operation to ensure EDSCR.Txfull == 1 */
2297 retval
= dpm
->instr_execute(dpm
, ARMV4_5_MCR(14, 0, 0, 0, 5, 0));
2300 if (retval
!= ERROR_OK
)
2303 /* Step 1.e - Change DCC to memory mode */
2305 retval
= mem_ap_write_atomic_u32(armv8
->debug_ap
,
2306 armv8
->debug_base
+ CPUV8_DBG_DSCR
, *dscr
);
2307 if (retval
!= ERROR_OK
)
2310 /* Step 1.f - read DBGDTRTX and discard the value */
2311 retval
= mem_ap_read_atomic_u32(armv8
->debug_ap
,
2312 armv8
->debug_base
+ CPUV8_DBG_DTRTX
, &value
);
2313 if (retval
!= ERROR_OK
)
2317 /* Read the data - Each read of the DTRTX register causes the instruction to be reissued
2318 * Abort flags are sticky, so can be read at end of transactions
2320 * This data is read in aligned to 32 bit boundary.
2324 /* Step 2.a - Loop n-1 times, each read of DBGDTRTX reads the data from [X0] and
2325 * increments X0 by 4. */
2326 retval
= mem_ap_read_buf_noincr(armv8
->debug_ap
, buffer
, 4, count
,
2327 armv8
->debug_base
+ CPUV8_DBG_DTRTX
);
2328 if (retval
!= ERROR_OK
)
2332 /* Step 3.a - set DTR access mode back to Normal mode */
2334 retval
= mem_ap_write_atomic_u32(armv8
->debug_ap
,
2335 armv8
->debug_base
+ CPUV8_DBG_DSCR
, *dscr
);
2336 if (retval
!= ERROR_OK
)
2339 /* Step 3.b - read DBGDTRTX for the final value */
2340 retval
= mem_ap_read_atomic_u32(armv8
->debug_ap
,
2341 armv8
->debug_base
+ CPUV8_DBG_DTRTX
, &value
);
2342 if (retval
!= ERROR_OK
)
2345 target_buffer_set_u32(target
, buffer
+ count
* 4, value
);
2349 static int aarch64_read_cpu_memory(struct target
*target
,
2350 target_addr_t address
, uint32_t size
,
2351 uint32_t count
, uint8_t *buffer
)
2353 /* read memory through APB-AP */
2354 int retval
= ERROR_COMMAND_SYNTAX_ERROR
;
2355 struct armv8_common
*armv8
= target_to_armv8(target
);
2356 struct arm_dpm
*dpm
= &armv8
->dpm
;
2357 struct arm
*arm
= &armv8
->arm
;
2360 LOG_DEBUG("Reading CPU memory address 0x%016" PRIx64
" size %" PRIu32
" count %" PRIu32
,
2361 address
, size
, count
);
2363 if (target
->state
!= TARGET_HALTED
) {
2364 LOG_TARGET_ERROR(target
, "not halted");
2365 return ERROR_TARGET_NOT_HALTED
;
2368 /* Mark register X0 as dirty, as it will be used
2369 * for transferring the data.
2370 * It will be restored automatically when exiting
2373 armv8_reg_current(arm
, 0)->dirty
= true;
2376 retval
= mem_ap_read_atomic_u32(armv8
->debug_ap
,
2377 armv8
->debug_base
+ CPUV8_DBG_DSCR
, &dscr
);
2378 if (retval
!= ERROR_OK
)
2381 /* This algorithm comes from DDI0487A.g, chapter J9.1 */
2383 /* Set Normal access mode */
2385 retval
= mem_ap_write_atomic_u32(armv8
->debug_ap
,
2386 armv8
->debug_base
+ CPUV8_DBG_DSCR
, dscr
);
2387 if (retval
!= ERROR_OK
)
2390 if (arm
->core_state
== ARM_STATE_AARCH64
) {
2391 /* Write X0 with value 'address' using write procedure */
2392 /* Step 1.a+b - Write the address for read access into DBGDTR_EL0 */
2393 /* Step 1.c - Copy value from DTR to R0 using instruction mrs DBGDTR_EL0, x0 */
2394 retval
= dpm
->instr_write_data_dcc_64(dpm
,
2395 ARMV8_MRS(SYSTEM_DBG_DBGDTR_EL0
, 0), address
);
2397 /* Write R0 with value 'address' using write procedure */
2398 /* Step 1.a+b - Write the address for read access into DBGDTRRXint */
2399 /* Step 1.c - Copy value from DTR to R0 using instruction mrc DBGDTRTXint, r0 */
2400 retval
= dpm
->instr_write_data_dcc(dpm
,
2401 ARMV4_5_MRC(14, 0, 0, 0, 5, 0), address
);
2404 if (retval
!= ERROR_OK
)
2407 if (size
== 4 && (address
% 4) == 0)
2408 retval
= aarch64_read_cpu_memory_fast(target
, count
, buffer
, &dscr
);
2410 retval
= aarch64_read_cpu_memory_slow(target
, size
, count
, buffer
, &dscr
);
2412 if (dscr
& DSCR_MA
) {
2414 mem_ap_write_atomic_u32(armv8
->debug_ap
,
2415 armv8
->debug_base
+ CPUV8_DBG_DSCR
, dscr
);
2418 if (retval
!= ERROR_OK
)
2421 /* Check for sticky abort flags in the DSCR */
2422 retval
= mem_ap_read_atomic_u32(armv8
->debug_ap
,
2423 armv8
->debug_base
+ CPUV8_DBG_DSCR
, &dscr
);
2424 if (retval
!= ERROR_OK
)
2429 if (dscr
& (DSCR_ERR
| DSCR_SYS_ERROR_PEND
)) {
2430 /* Abort occurred - clear it and exit */
2431 LOG_ERROR("abort occurred - dscr = 0x%08" PRIx32
, dscr
);
2432 armv8_dpm_handle_exception(dpm
, true);
2440 static int aarch64_read_phys_memory(struct target
*target
,
2441 target_addr_t address
, uint32_t size
,
2442 uint32_t count
, uint8_t *buffer
)
2444 int retval
= ERROR_COMMAND_SYNTAX_ERROR
;
2446 if (count
&& buffer
) {
2447 /* read memory through APB-AP */
2448 retval
= aarch64_mmu_modify(target
, 0);
2449 if (retval
!= ERROR_OK
)
2451 retval
= aarch64_read_cpu_memory(target
, address
, size
, count
, buffer
);
2456 static int aarch64_read_memory(struct target
*target
, target_addr_t address
,
2457 uint32_t size
, uint32_t count
, uint8_t *buffer
)
2459 int mmu_enabled
= 0;
2462 /* determine if MMU was enabled on target stop */
2463 retval
= aarch64_mmu(target
, &mmu_enabled
);
2464 if (retval
!= ERROR_OK
)
2468 /* enable MMU as we could have disabled it for phys access */
2469 retval
= aarch64_mmu_modify(target
, 1);
2470 if (retval
!= ERROR_OK
)
2473 return aarch64_read_cpu_memory(target
, address
, size
, count
, buffer
);
2476 static int aarch64_write_phys_memory(struct target
*target
,
2477 target_addr_t address
, uint32_t size
,
2478 uint32_t count
, const uint8_t *buffer
)
2480 int retval
= ERROR_COMMAND_SYNTAX_ERROR
;
2482 if (count
&& buffer
) {
2483 /* write memory through APB-AP */
2484 retval
= aarch64_mmu_modify(target
, 0);
2485 if (retval
!= ERROR_OK
)
2487 return aarch64_write_cpu_memory(target
, address
, size
, count
, buffer
);
2493 static int aarch64_write_memory(struct target
*target
, target_addr_t address
,
2494 uint32_t size
, uint32_t count
, const uint8_t *buffer
)
2496 int mmu_enabled
= 0;
2499 /* determine if MMU was enabled on target stop */
2500 retval
= aarch64_mmu(target
, &mmu_enabled
);
2501 if (retval
!= ERROR_OK
)
2505 /* enable MMU as we could have disabled it for phys access */
2506 retval
= aarch64_mmu_modify(target
, 1);
2507 if (retval
!= ERROR_OK
)
2510 return aarch64_write_cpu_memory(target
, address
, size
, count
, buffer
);
2513 static int aarch64_handle_target_request(void *priv
)
2515 struct target
*target
= priv
;
2516 struct armv8_common
*armv8
= target_to_armv8(target
);
2519 if (!target_was_examined(target
))
2521 if (!target
->dbg_msg_enabled
)
2524 if (target
->state
== TARGET_RUNNING
) {
2527 retval
= mem_ap_read_atomic_u32(armv8
->debug_ap
,
2528 armv8
->debug_base
+ CPUV8_DBG_DSCR
, &dscr
);
2530 /* check if we have data */
2531 while ((dscr
& DSCR_DTR_TX_FULL
) && (retval
== ERROR_OK
)) {
2532 retval
= mem_ap_read_atomic_u32(armv8
->debug_ap
,
2533 armv8
->debug_base
+ CPUV8_DBG_DTRTX
, &request
);
2534 if (retval
== ERROR_OK
) {
2535 target_request(target
, request
);
2536 retval
= mem_ap_read_atomic_u32(armv8
->debug_ap
,
2537 armv8
->debug_base
+ CPUV8_DBG_DSCR
, &dscr
);
2545 static int aarch64_examine_first(struct target
*target
)
2547 struct aarch64_common
*aarch64
= target_to_aarch64(target
);
2548 struct armv8_common
*armv8
= &aarch64
->armv8_common
;
2549 struct adiv5_dap
*swjdp
= armv8
->arm
.dap
;
2550 struct aarch64_private_config
*pc
= target
->private_config
;
2552 int retval
= ERROR_OK
;
2553 uint64_t debug
, ttypr
;
2555 uint32_t tmp0
, tmp1
, tmp2
, tmp3
;
2556 debug
= ttypr
= cpuid
= 0;
2561 if (!armv8
->debug_ap
) {
2562 if (pc
->adiv5_config
.ap_num
== DP_APSEL_INVALID
) {
2563 /* Search for the APB-AB */
2564 retval
= dap_find_get_ap(swjdp
, AP_TYPE_APB_AP
, &armv8
->debug_ap
);
2565 if (retval
!= ERROR_OK
) {
2566 LOG_ERROR("Could not find APB-AP for debug access");
2570 armv8
->debug_ap
= dap_get_ap(swjdp
, pc
->adiv5_config
.ap_num
);
2571 if (!armv8
->debug_ap
) {
2572 LOG_ERROR("Cannot get AP");
2578 retval
= mem_ap_init(armv8
->debug_ap
);
2579 if (retval
!= ERROR_OK
) {
2580 LOG_ERROR("Could not initialize the APB-AP");
2584 armv8
->debug_ap
->memaccess_tck
= 10;
2586 if (!target
->dbgbase_set
) {
2587 /* Lookup Processor DAP */
2588 retval
= dap_lookup_cs_component(armv8
->debug_ap
, ARM_CS_C9_DEVTYPE_CORE_DEBUG
,
2589 &armv8
->debug_base
, target
->coreid
);
2590 if (retval
!= ERROR_OK
)
2592 LOG_DEBUG("Detected core %" PRId32
" dbgbase: " TARGET_ADDR_FMT
,
2593 target
->coreid
, armv8
->debug_base
);
2595 armv8
->debug_base
= target
->dbgbase
;
2597 retval
= mem_ap_write_atomic_u32(armv8
->debug_ap
,
2598 armv8
->debug_base
+ CPUV8_DBG_OSLAR
, 0);
2599 if (retval
!= ERROR_OK
) {
2600 LOG_DEBUG("Examine %s failed", "oslock");
2604 retval
= mem_ap_read_u32(armv8
->debug_ap
,
2605 armv8
->debug_base
+ CPUV8_DBG_MAINID0
, &cpuid
);
2606 if (retval
!= ERROR_OK
) {
2607 LOG_DEBUG("Examine %s failed", "CPUID");
2611 retval
= mem_ap_read_u32(armv8
->debug_ap
,
2612 armv8
->debug_base
+ CPUV8_DBG_MEMFEATURE0
, &tmp0
);
2613 retval
+= mem_ap_read_u32(armv8
->debug_ap
,
2614 armv8
->debug_base
+ CPUV8_DBG_MEMFEATURE0
+ 4, &tmp1
);
2615 if (retval
!= ERROR_OK
) {
2616 LOG_DEBUG("Examine %s failed", "Memory Model Type");
2619 retval
= mem_ap_read_u32(armv8
->debug_ap
,
2620 armv8
->debug_base
+ CPUV8_DBG_DBGFEATURE0
, &tmp2
);
2621 retval
+= mem_ap_read_u32(armv8
->debug_ap
,
2622 armv8
->debug_base
+ CPUV8_DBG_DBGFEATURE0
+ 4, &tmp3
);
2623 if (retval
!= ERROR_OK
) {
2624 LOG_DEBUG("Examine %s failed", "ID_AA64DFR0_EL1");
2628 retval
= dap_run(armv8
->debug_ap
->dap
);
2629 if (retval
!= ERROR_OK
) {
2630 LOG_ERROR("%s: examination failed\n", target_name(target
));
2635 ttypr
= (ttypr
<< 32) | tmp0
;
2637 debug
= (debug
<< 32) | tmp2
;
2639 LOG_DEBUG("cpuid = 0x%08" PRIx32
, cpuid
);
2640 LOG_DEBUG("ttypr = 0x%08" PRIx64
, ttypr
);
2641 LOG_DEBUG("debug = 0x%08" PRIx64
, debug
);
2644 LOG_TARGET_ERROR(target
, "CTI not specified");
2648 armv8
->cti
= pc
->cti
;
2650 retval
= aarch64_dpm_setup(aarch64
, debug
);
2651 if (retval
!= ERROR_OK
)
2654 /* Setup Breakpoint Register Pairs */
2655 aarch64
->brp_num
= (uint32_t)((debug
>> 12) & 0x0F) + 1;
2656 aarch64
->brp_num_context
= (uint32_t)((debug
>> 28) & 0x0F) + 1;
2657 aarch64
->brp_num_available
= aarch64
->brp_num
;
2658 aarch64
->brp_list
= calloc(aarch64
->brp_num
, sizeof(struct aarch64_brp
));
2659 for (i
= 0; i
< aarch64
->brp_num
; i
++) {
2660 aarch64
->brp_list
[i
].used
= 0;
2661 if (i
< (aarch64
->brp_num
-aarch64
->brp_num_context
))
2662 aarch64
->brp_list
[i
].type
= BRP_NORMAL
;
2664 aarch64
->brp_list
[i
].type
= BRP_CONTEXT
;
2665 aarch64
->brp_list
[i
].value
= 0;
2666 aarch64
->brp_list
[i
].control
= 0;
2667 aarch64
->brp_list
[i
].brpn
= i
;
2670 /* Setup Watchpoint Register Pairs */
2671 aarch64
->wp_num
= (uint32_t)((debug
>> 20) & 0x0F) + 1;
2672 aarch64
->wp_num_available
= aarch64
->wp_num
;
2673 aarch64
->wp_list
= calloc(aarch64
->wp_num
, sizeof(struct aarch64_brp
));
2674 for (i
= 0; i
< aarch64
->wp_num
; i
++) {
2675 aarch64
->wp_list
[i
].used
= 0;
2676 aarch64
->wp_list
[i
].type
= BRP_NORMAL
;
2677 aarch64
->wp_list
[i
].value
= 0;
2678 aarch64
->wp_list
[i
].control
= 0;
2679 aarch64
->wp_list
[i
].brpn
= i
;
2682 LOG_DEBUG("Configured %i hw breakpoints, %i watchpoints",
2683 aarch64
->brp_num
, aarch64
->wp_num
);
2685 target
->state
= TARGET_UNKNOWN
;
2686 target
->debug_reason
= DBG_REASON_NOTHALTED
;
2687 aarch64
->isrmasking_mode
= AARCH64_ISRMASK_ON
;
2688 target_set_examined(target
);
2692 static int aarch64_examine(struct target
*target
)
2694 int retval
= ERROR_OK
;
2696 /* don't re-probe hardware after each reset */
2697 if (!target_was_examined(target
))
2698 retval
= aarch64_examine_first(target
);
2700 /* Configure core debug access */
2701 if (retval
== ERROR_OK
)
2702 retval
= aarch64_init_debug_access(target
);
2704 if (retval
== ERROR_OK
)
2705 retval
= aarch64_poll(target
);
2711 * Cortex-A8 target creation and initialization
2714 static int aarch64_init_target(struct command_context
*cmd_ctx
,
2715 struct target
*target
)
2717 /* examine_first() does a bunch of this */
2718 arm_semihosting_init(target
);
2722 static int aarch64_init_arch_info(struct target
*target
,
2723 struct aarch64_common
*aarch64
, struct adiv5_dap
*dap
)
2725 struct armv8_common
*armv8
= &aarch64
->armv8_common
;
2727 /* Setup struct aarch64_common */
2728 aarch64
->common_magic
= AARCH64_COMMON_MAGIC
;
2729 armv8
->arm
.dap
= dap
;
2731 /* register arch-specific functions */
2732 armv8
->examine_debug_reason
= NULL
;
2733 armv8
->post_debug_entry
= aarch64_post_debug_entry
;
2734 armv8
->pre_restore_context
= NULL
;
2735 armv8
->armv8_mmu
.read_physical_memory
= aarch64_read_phys_memory
;
2737 armv8_init_arch_info(target
, armv8
);
2738 target_register_timer_callback(aarch64_handle_target_request
, 1,
2739 TARGET_TIMER_TYPE_PERIODIC
, target
);
2744 static int armv8r_target_create(struct target
*target
, Jim_Interp
*interp
)
2746 struct aarch64_private_config
*pc
= target
->private_config
;
2747 struct aarch64_common
*aarch64
;
2749 if (adiv5_verify_config(&pc
->adiv5_config
) != ERROR_OK
)
2752 aarch64
= calloc(1, sizeof(struct aarch64_common
));
2754 LOG_ERROR("Out of memory");
2758 aarch64
->armv8_common
.is_armv8r
= true;
2760 return aarch64_init_arch_info(target
, aarch64
, pc
->adiv5_config
.dap
);
2763 static int aarch64_target_create(struct target
*target
, Jim_Interp
*interp
)
2765 struct aarch64_private_config
*pc
= target
->private_config
;
2766 struct aarch64_common
*aarch64
;
2768 if (adiv5_verify_config(&pc
->adiv5_config
) != ERROR_OK
)
2771 aarch64
= calloc(1, sizeof(struct aarch64_common
));
2773 LOG_ERROR("Out of memory");
2777 aarch64
->armv8_common
.is_armv8r
= false;
2779 return aarch64_init_arch_info(target
, aarch64
, pc
->adiv5_config
.dap
);
2782 static void aarch64_deinit_target(struct target
*target
)
2784 struct aarch64_common
*aarch64
= target_to_aarch64(target
);
2785 struct armv8_common
*armv8
= &aarch64
->armv8_common
;
2786 struct arm_dpm
*dpm
= &armv8
->dpm
;
2788 if (armv8
->debug_ap
)
2789 dap_put_ap(armv8
->debug_ap
);
2791 armv8_free_reg_cache(target
);
2792 free(aarch64
->brp_list
);
2795 free(target
->private_config
);
2799 static int aarch64_mmu(struct target
*target
, int *enabled
)
2801 struct aarch64_common
*aarch64
= target_to_aarch64(target
);
2802 struct armv8_common
*armv8
= &aarch64
->armv8_common
;
2803 if (target
->state
!= TARGET_HALTED
) {
2804 LOG_TARGET_ERROR(target
, "not halted");
2805 return ERROR_TARGET_NOT_HALTED
;
2807 if (armv8
->is_armv8r
)
2810 *enabled
= target_to_aarch64(target
)->armv8_common
.armv8_mmu
.mmu_enabled
;
2814 static int aarch64_virt2phys(struct target
*target
, target_addr_t virt
,
2815 target_addr_t
*phys
)
2817 return armv8_mmu_translate_va_pa(target
, virt
, phys
, 1);
2821 * private target configuration items
2823 enum aarch64_cfg_param
{
2827 static const struct jim_nvp nvp_config_opts
[] = {
2828 { .name
= "-cti", .value
= CFG_CTI
},
2829 { .name
= NULL
, .value
= -1 }
2832 static int aarch64_jim_configure(struct target
*target
, struct jim_getopt_info
*goi
)
2834 struct aarch64_private_config
*pc
;
2838 pc
= (struct aarch64_private_config
*)target
->private_config
;
2840 pc
= calloc(1, sizeof(struct aarch64_private_config
));
2841 pc
->adiv5_config
.ap_num
= DP_APSEL_INVALID
;
2842 target
->private_config
= pc
;
2846 * Call adiv5_jim_configure() to parse the common DAP options
2847 * It will return JIM_CONTINUE if it didn't find any known
2848 * options, JIM_OK if it correctly parsed the topmost option
2849 * and JIM_ERR if an error occurred during parameter evaluation.
2850 * For JIM_CONTINUE, we check our own params.
2852 * adiv5_jim_configure() assumes 'private_config' to point to
2853 * 'struct adiv5_private_config'. Override 'private_config'!
2855 target
->private_config
= &pc
->adiv5_config
;
2856 e
= adiv5_jim_configure(target
, goi
);
2857 target
->private_config
= pc
;
2858 if (e
!= JIM_CONTINUE
)
2861 /* parse config or cget options ... */
2862 if (goi
->argc
> 0) {
2863 Jim_SetEmptyResult(goi
->interp
);
2865 /* check first if topmost item is for us */
2866 e
= jim_nvp_name2value_obj(goi
->interp
, nvp_config_opts
,
2869 return JIM_CONTINUE
;
2871 e
= jim_getopt_obj(goi
, NULL
);
2877 if (goi
->isconfigure
) {
2879 struct arm_cti
*cti
;
2880 e
= jim_getopt_obj(goi
, &o_cti
);
2883 cti
= cti_instance_by_jim_obj(goi
->interp
, o_cti
);
2885 Jim_SetResultString(goi
->interp
, "CTI name invalid!", -1);
2890 if (goi
->argc
!= 0) {
2891 Jim_WrongNumArgs(goi
->interp
,
2892 goi
->argc
, goi
->argv
,
2897 if (!pc
|| !pc
->cti
) {
2898 Jim_SetResultString(goi
->interp
, "CTI not configured", -1);
2901 Jim_SetResultString(goi
->interp
, arm_cti_name(pc
->cti
), -1);
2907 return JIM_CONTINUE
;
2914 COMMAND_HANDLER(aarch64_handle_cache_info_command
)
2916 struct target
*target
= get_current_target(CMD_CTX
);
2917 struct armv8_common
*armv8
= target_to_armv8(target
);
2919 return armv8_handle_cache_info_command(CMD
,
2920 &armv8
->armv8_mmu
.armv8_cache
);
2923 COMMAND_HANDLER(aarch64_handle_dbginit_command
)
2925 struct target
*target
= get_current_target(CMD_CTX
);
2926 if (!target_was_examined(target
)) {
2927 LOG_ERROR("target not examined yet");
2931 return aarch64_init_debug_access(target
);
2934 COMMAND_HANDLER(aarch64_handle_disassemble_command
)
2936 struct target
*target
= get_current_target(CMD_CTX
);
2939 LOG_ERROR("No target selected");
2943 struct aarch64_common
*aarch64
= target_to_aarch64(target
);
2945 if (aarch64
->common_magic
!= AARCH64_COMMON_MAGIC
) {
2946 command_print(CMD
, "current target isn't an AArch64");
2951 target_addr_t address
;
2955 COMMAND_PARSE_NUMBER(int, CMD_ARGV
[1], count
);
2958 COMMAND_PARSE_ADDRESS(CMD_ARGV
[0], address
);
2961 return ERROR_COMMAND_SYNTAX_ERROR
;
2964 return a64_disassemble(CMD
, target
, address
, count
);
2967 COMMAND_HANDLER(aarch64_mask_interrupts_command
)
2969 struct target
*target
= get_current_target(CMD_CTX
);
2970 struct aarch64_common
*aarch64
= target_to_aarch64(target
);
2972 static const struct nvp nvp_maskisr_modes
[] = {
2973 { .name
= "off", .value
= AARCH64_ISRMASK_OFF
},
2974 { .name
= "on", .value
= AARCH64_ISRMASK_ON
},
2975 { .name
= NULL
, .value
= -1 },
2977 const struct nvp
*n
;
2980 n
= nvp_name2value(nvp_maskisr_modes
, CMD_ARGV
[0]);
2982 LOG_ERROR("Unknown parameter: %s - should be off or on", CMD_ARGV
[0]);
2983 return ERROR_COMMAND_SYNTAX_ERROR
;
2986 aarch64
->isrmasking_mode
= n
->value
;
2989 n
= nvp_value2name(nvp_maskisr_modes
, aarch64
->isrmasking_mode
);
2990 command_print(CMD
, "aarch64 interrupt mask %s", n
->name
);
2995 COMMAND_HANDLER(aarch64_mcrmrc_command
)
2997 bool is_mcr
= false;
2998 unsigned int arg_cnt
= 5;
3000 if (!strcmp(CMD_NAME
, "mcr")) {
3005 if (arg_cnt
!= CMD_ARGC
)
3006 return ERROR_COMMAND_SYNTAX_ERROR
;
3008 struct target
*target
= get_current_target(CMD_CTX
);
3010 command_print(CMD
, "no current target");
3013 if (!target_was_examined(target
)) {
3014 command_print(CMD
, "%s: not yet examined", target_name(target
));
3015 return ERROR_TARGET_NOT_EXAMINED
;
3018 struct arm
*arm
= target_to_arm(target
);
3020 command_print(CMD
, "%s: not an ARM", target_name(target
));
3024 if (target
->state
!= TARGET_HALTED
) {
3025 command_print(CMD
, "Error: [%s] not halted", target_name(target
));
3026 return ERROR_TARGET_NOT_HALTED
;
3029 if (arm
->core_state
== ARM_STATE_AARCH64
) {
3030 command_print(CMD
, "%s: not 32-bit arm target", target_name(target
));
3041 /* NOTE: parameter sequence matches ARM instruction set usage:
3042 * MCR pNUM, op1, rX, CRn, CRm, op2 ; write CP from rX
3043 * MRC pNUM, op1, rX, CRn, CRm, op2 ; read CP into rX
3044 * The "rX" is necessarily omitted; it uses Tcl mechanisms.
3046 COMMAND_PARSE_NUMBER(int, CMD_ARGV
[0], cpnum
);
3048 command_print(CMD
, "coprocessor %d out of range", cpnum
);
3049 return ERROR_COMMAND_ARGUMENT_INVALID
;
3052 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[1], op1
);
3054 command_print(CMD
, "op1 %d out of range", op1
);
3055 return ERROR_COMMAND_ARGUMENT_INVALID
;
3058 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[2], crn
);
3060 command_print(CMD
, "CRn %d out of range", crn
);
3061 return ERROR_COMMAND_ARGUMENT_INVALID
;
3064 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[3], crm
);
3066 command_print(CMD
, "CRm %d out of range", crm
);
3067 return ERROR_COMMAND_ARGUMENT_INVALID
;
3070 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[4], op2
);
3072 command_print(CMD
, "op2 %d out of range", op2
);
3073 return ERROR_COMMAND_ARGUMENT_INVALID
;
3077 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[5], value
);
3079 /* NOTE: parameters reordered! */
3080 /* ARMV4_5_MCR(cpnum, op1, 0, crn, crm, op2) */
3081 int retval
= arm
->mcr(target
, cpnum
, op1
, op2
, crn
, crm
, value
);
3082 if (retval
!= ERROR_OK
)
3086 /* NOTE: parameters reordered! */
3087 /* ARMV4_5_MRC(cpnum, op1, 0, crn, crm, op2) */
3088 int retval
= arm
->mrc(target
, cpnum
, op1
, op2
, crn
, crm
, &value
);
3089 if (retval
!= ERROR_OK
)
3092 command_print(CMD
, "0x%" PRIx32
, value
);
3098 static const struct command_registration aarch64_exec_command_handlers
[] = {
3100 .name
= "cache_info",
3101 .handler
= aarch64_handle_cache_info_command
,
3102 .mode
= COMMAND_EXEC
,
3103 .help
= "display information about target caches",
3108 .handler
= aarch64_handle_dbginit_command
,
3109 .mode
= COMMAND_EXEC
,
3110 .help
= "Initialize core debug",
3114 .name
= "disassemble",
3115 .handler
= aarch64_handle_disassemble_command
,
3116 .mode
= COMMAND_EXEC
,
3117 .help
= "Disassemble instructions",
3118 .usage
= "address [count]",
3122 .handler
= aarch64_mask_interrupts_command
,
3123 .mode
= COMMAND_ANY
,
3124 .help
= "mask aarch64 interrupts during single-step",
3125 .usage
= "['on'|'off']",
3129 .mode
= COMMAND_EXEC
,
3130 .handler
= aarch64_mcrmrc_command
,
3131 .help
= "write coprocessor register",
3132 .usage
= "cpnum op1 CRn CRm op2 value",
3136 .mode
= COMMAND_EXEC
,
3137 .handler
= aarch64_mcrmrc_command
,
3138 .help
= "read coprocessor register",
3139 .usage
= "cpnum op1 CRn CRm op2",
3142 .chain
= smp_command_handlers
,
3146 COMMAND_REGISTRATION_DONE
3149 static const struct command_registration aarch64_command_handlers
[] = {
3152 .mode
= COMMAND_ANY
,
3153 .help
= "ARM Command Group",
3155 .chain
= semihosting_common_handlers
3158 .chain
= armv8_command_handlers
,
3162 .mode
= COMMAND_ANY
,
3163 .help
= "Aarch64 command group",
3165 .chain
= aarch64_exec_command_handlers
,
3167 COMMAND_REGISTRATION_DONE
3170 struct target_type aarch64_target
= {
3173 .poll
= aarch64_poll
,
3174 .arch_state
= armv8_arch_state
,
3176 .halt
= aarch64_halt
,
3177 .resume
= aarch64_resume
,
3178 .step
= aarch64_step
,
3180 .assert_reset
= aarch64_assert_reset
,
3181 .deassert_reset
= aarch64_deassert_reset
,
3183 /* REVISIT allow exporting VFP3 registers ... */
3184 .get_gdb_arch
= armv8_get_gdb_arch
,
3185 .get_gdb_reg_list
= armv8_get_gdb_reg_list
,
3187 .read_memory
= aarch64_read_memory
,
3188 .write_memory
= aarch64_write_memory
,
3190 .add_breakpoint
= aarch64_add_breakpoint
,
3191 .add_context_breakpoint
= aarch64_add_context_breakpoint
,
3192 .add_hybrid_breakpoint
= aarch64_add_hybrid_breakpoint
,
3193 .remove_breakpoint
= aarch64_remove_breakpoint
,
3194 .add_watchpoint
= aarch64_add_watchpoint
,
3195 .remove_watchpoint
= aarch64_remove_watchpoint
,
3196 .hit_watchpoint
= aarch64_hit_watchpoint
,
3198 .commands
= aarch64_command_handlers
,
3199 .target_create
= aarch64_target_create
,
3200 .target_jim_configure
= aarch64_jim_configure
,
3201 .init_target
= aarch64_init_target
,
3202 .deinit_target
= aarch64_deinit_target
,
3203 .examine
= aarch64_examine
,
3205 .read_phys_memory
= aarch64_read_phys_memory
,
3206 .write_phys_memory
= aarch64_write_phys_memory
,
3208 .virt2phys
= aarch64_virt2phys
,
3211 struct target_type armv8r_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_phys_memory
,
3229 .write_memory
= aarch64_write_phys_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
= armv8r_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
,
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)