1 /***************************************************************************
2 * Copyright (C) 2015 by David Ung *
4 * This program is free software; you can redistribute it and/or modify *
5 * it under the terms of the GNU General Public License as published by *
6 * the Free Software Foundation; either version 2 of the License, or *
7 * (at your option) any later version. *
9 * This program is distributed in the hope that it will be useful, *
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
12 * GNU General Public License for more details. *
14 * You should have received a copy of the GNU General Public License *
15 * along with this program; if not, write to the *
16 * Free Software Foundation, Inc., *
18 ***************************************************************************/
24 #include "breakpoints.h"
26 #include "a64_disassembler.h"
28 #include "target_request.h"
29 #include "target_type.h"
30 #include "armv8_opcodes.h"
31 #include "armv8_cache.h"
32 #include "arm_coresight.h"
33 #include "arm_semihosting.h"
34 #include "jtag/interface.h"
36 #include <helper/time_support.h>
48 struct aarch64_private_config
{
49 struct adiv5_private_config adiv5_config
;
53 static int aarch64_poll(struct target
*target
);
54 static int aarch64_debug_entry(struct target
*target
);
55 static int aarch64_restore_context(struct target
*target
, bool bpwp
);
56 static int aarch64_set_breakpoint(struct target
*target
,
57 struct breakpoint
*breakpoint
, uint8_t matchmode
);
58 static int aarch64_set_context_breakpoint(struct target
*target
,
59 struct breakpoint
*breakpoint
, uint8_t matchmode
);
60 static int aarch64_set_hybrid_breakpoint(struct target
*target
,
61 struct breakpoint
*breakpoint
);
62 static int aarch64_unset_breakpoint(struct target
*target
,
63 struct breakpoint
*breakpoint
);
64 static int aarch64_mmu(struct target
*target
, int *enabled
);
65 static int aarch64_virt2phys(struct target
*target
,
66 target_addr_t virt
, target_addr_t
*phys
);
67 static int aarch64_read_cpu_memory(struct target
*target
,
68 uint64_t address
, uint32_t size
, uint32_t count
, uint8_t *buffer
);
70 static int aarch64_restore_system_control_reg(struct target
*target
)
72 enum arm_mode target_mode
= ARM_MODE_ANY
;
73 int retval
= ERROR_OK
;
76 struct aarch64_common
*aarch64
= target_to_aarch64(target
);
77 struct armv8_common
*armv8
= target_to_armv8(target
);
79 if (aarch64
->system_control_reg
!= aarch64
->system_control_reg_curr
) {
80 aarch64
->system_control_reg_curr
= aarch64
->system_control_reg
;
81 /* LOG_INFO("cp15_control_reg: %8.8" PRIx32, cortex_v8->cp15_control_reg); */
83 switch (armv8
->arm
.core_mode
) {
85 target_mode
= ARMV8_64_EL1H
;
89 instr
= ARMV8_MSR_GP(SYSTEM_SCTLR_EL1
, 0);
93 instr
= ARMV8_MSR_GP(SYSTEM_SCTLR_EL2
, 0);
97 instr
= ARMV8_MSR_GP(SYSTEM_SCTLR_EL3
, 0);
106 instr
= ARMV4_5_MCR(15, 0, 0, 1, 0, 0);
110 LOG_ERROR("cannot read system control register in this mode: (%s : 0x%x)",
111 armv8_mode_name(armv8
->arm
.core_mode
), armv8
->arm
.core_mode
);
115 if (target_mode
!= ARM_MODE_ANY
)
116 armv8_dpm_modeswitch(&armv8
->dpm
, target_mode
);
118 retval
= armv8
->dpm
.instr_write_data_r0(&armv8
->dpm
, instr
, aarch64
->system_control_reg
);
119 if (retval
!= ERROR_OK
)
122 if (target_mode
!= ARM_MODE_ANY
)
123 armv8_dpm_modeswitch(&armv8
->dpm
, ARM_MODE_ANY
);
129 /* modify system_control_reg in order to enable or disable mmu for :
130 * - virt2phys address conversion
131 * - read or write memory in phys or virt address */
132 static int aarch64_mmu_modify(struct target
*target
, int enable
)
134 struct aarch64_common
*aarch64
= target_to_aarch64(target
);
135 struct armv8_common
*armv8
= &aarch64
->armv8_common
;
136 int retval
= ERROR_OK
;
137 enum arm_mode target_mode
= ARM_MODE_ANY
;
141 /* if mmu enabled at target stop and mmu not enable */
142 if (!(aarch64
->system_control_reg
& 0x1U
)) {
143 LOG_ERROR("trying to enable mmu on target stopped with mmu disable");
146 if (!(aarch64
->system_control_reg_curr
& 0x1U
))
147 aarch64
->system_control_reg_curr
|= 0x1U
;
149 if (aarch64
->system_control_reg_curr
& 0x4U
) {
150 /* data cache is active */
151 aarch64
->system_control_reg_curr
&= ~0x4U
;
152 /* flush data cache armv8 function to be called */
153 if (armv8
->armv8_mmu
.armv8_cache
.flush_all_data_cache
)
154 armv8
->armv8_mmu
.armv8_cache
.flush_all_data_cache(target
);
156 if ((aarch64
->system_control_reg_curr
& 0x1U
)) {
157 aarch64
->system_control_reg_curr
&= ~0x1U
;
161 switch (armv8
->arm
.core_mode
) {
163 target_mode
= ARMV8_64_EL1H
;
167 instr
= ARMV8_MSR_GP(SYSTEM_SCTLR_EL1
, 0);
171 instr
= ARMV8_MSR_GP(SYSTEM_SCTLR_EL2
, 0);
175 instr
= ARMV8_MSR_GP(SYSTEM_SCTLR_EL3
, 0);
184 instr
= ARMV4_5_MCR(15, 0, 0, 1, 0, 0);
188 LOG_DEBUG("unknown cpu state 0x%x", armv8
->arm
.core_mode
);
191 if (target_mode
!= ARM_MODE_ANY
)
192 armv8_dpm_modeswitch(&armv8
->dpm
, target_mode
);
194 retval
= armv8
->dpm
.instr_write_data_r0(&armv8
->dpm
, instr
,
195 aarch64
->system_control_reg_curr
);
197 if (target_mode
!= ARM_MODE_ANY
)
198 armv8_dpm_modeswitch(&armv8
->dpm
, ARM_MODE_ANY
);
204 * Basic debug access, very low level assumes state is saved
206 static int aarch64_init_debug_access(struct target
*target
)
208 struct armv8_common
*armv8
= target_to_armv8(target
);
212 LOG_DEBUG("%s", target_name(target
));
214 retval
= mem_ap_write_atomic_u32(armv8
->debug_ap
,
215 armv8
->debug_base
+ CPUV8_DBG_OSLAR
, 0);
216 if (retval
!= ERROR_OK
) {
217 LOG_DEBUG("Examine %s failed", "oslock");
221 /* Clear Sticky Power Down status Bit in PRSR to enable access to
222 the registers in the Core Power Domain */
223 retval
= mem_ap_read_atomic_u32(armv8
->debug_ap
,
224 armv8
->debug_base
+ CPUV8_DBG_PRSR
, &dummy
);
225 if (retval
!= ERROR_OK
)
229 * Static CTI configuration:
230 * Channel 0 -> trigger outputs HALT request to PE
231 * Channel 1 -> trigger outputs Resume request to PE
232 * Gate all channel trigger events from entering the CTM
236 retval
= arm_cti_enable(armv8
->cti
, true);
237 /* By default, gate all channel events to and from the CTM */
238 if (retval
== ERROR_OK
)
239 retval
= arm_cti_write_reg(armv8
->cti
, CTI_GATE
, 0);
240 /* output halt requests to PE on channel 0 event */
241 if (retval
== ERROR_OK
)
242 retval
= arm_cti_write_reg(armv8
->cti
, CTI_OUTEN0
, CTI_CHNL(0));
243 /* output restart requests to PE on channel 1 event */
244 if (retval
== ERROR_OK
)
245 retval
= arm_cti_write_reg(armv8
->cti
, CTI_OUTEN1
, CTI_CHNL(1));
246 if (retval
!= ERROR_OK
)
249 /* Resync breakpoint registers */
254 /* Write to memory mapped registers directly with no cache or mmu handling */
255 static int aarch64_dap_write_memap_register_u32(struct target
*target
,
256 target_addr_t address
,
260 struct armv8_common
*armv8
= target_to_armv8(target
);
262 retval
= mem_ap_write_atomic_u32(armv8
->debug_ap
, address
, value
);
267 static int aarch64_dpm_setup(struct aarch64_common
*a8
, uint64_t debug
)
269 struct arm_dpm
*dpm
= &a8
->armv8_common
.dpm
;
272 dpm
->arm
= &a8
->armv8_common
.arm
;
275 retval
= armv8_dpm_setup(dpm
);
276 if (retval
== ERROR_OK
)
277 retval
= armv8_dpm_initialize(dpm
);
282 static int aarch64_set_dscr_bits(struct target
*target
, unsigned long bit_mask
, unsigned long value
)
284 struct armv8_common
*armv8
= target_to_armv8(target
);
285 return armv8_set_dbgreg_bits(armv8
, CPUV8_DBG_DSCR
, bit_mask
, value
);
288 static int aarch64_check_state_one(struct target
*target
,
289 uint32_t mask
, uint32_t val
, int *p_result
, uint32_t *p_prsr
)
291 struct armv8_common
*armv8
= target_to_armv8(target
);
295 retval
= mem_ap_read_atomic_u32(armv8
->debug_ap
,
296 armv8
->debug_base
+ CPUV8_DBG_PRSR
, &prsr
);
297 if (retval
!= ERROR_OK
)
304 *p_result
= (prsr
& mask
) == (val
& mask
);
309 static int aarch64_wait_halt_one(struct target
*target
)
311 int retval
= ERROR_OK
;
314 int64_t then
= timeval_ms();
318 retval
= aarch64_check_state_one(target
, PRSR_HALT
, PRSR_HALT
, &halted
, &prsr
);
319 if (retval
!= ERROR_OK
|| halted
)
322 if (timeval_ms() > then
+ 1000) {
323 retval
= ERROR_TARGET_TIMEOUT
;
324 LOG_DEBUG("target %s timeout, prsr=0x%08"PRIx32
, target_name(target
), prsr
);
331 static int aarch64_prepare_halt_smp(struct target
*target
, bool exc_target
, struct target
**p_first
)
333 int retval
= ERROR_OK
;
334 struct target_list
*head
= target
->head
;
335 struct target
*first
= NULL
;
337 LOG_DEBUG("target %s exc %i", target_name(target
), exc_target
);
340 struct target
*curr
= head
->target
;
341 struct armv8_common
*armv8
= target_to_armv8(curr
);
344 if (exc_target
&& curr
== target
)
346 if (!target_was_examined(curr
))
348 if (curr
->state
!= TARGET_RUNNING
)
351 /* HACK: mark this target as prepared for halting */
352 curr
->debug_reason
= DBG_REASON_DBGRQ
;
354 /* open the gate for channel 0 to let HALT requests pass to the CTM */
355 retval
= arm_cti_ungate_channel(armv8
->cti
, 0);
356 if (retval
== ERROR_OK
)
357 retval
= aarch64_set_dscr_bits(curr
, DSCR_HDE
, DSCR_HDE
);
358 if (retval
!= ERROR_OK
)
361 LOG_DEBUG("target %s prepared", target_name(curr
));
368 if (exc_target
&& first
)
377 static int aarch64_halt_one(struct target
*target
, enum halt_mode mode
)
379 int retval
= ERROR_OK
;
380 struct armv8_common
*armv8
= target_to_armv8(target
);
382 LOG_DEBUG("%s", target_name(target
));
384 /* allow Halting Debug Mode */
385 retval
= aarch64_set_dscr_bits(target
, DSCR_HDE
, DSCR_HDE
);
386 if (retval
!= ERROR_OK
)
389 /* trigger an event on channel 0, this outputs a halt request to the PE */
390 retval
= arm_cti_pulse_channel(armv8
->cti
, 0);
391 if (retval
!= ERROR_OK
)
394 if (mode
== HALT_SYNC
) {
395 retval
= aarch64_wait_halt_one(target
);
396 if (retval
!= ERROR_OK
) {
397 if (retval
== ERROR_TARGET_TIMEOUT
)
398 LOG_ERROR("Timeout waiting for target %s halt", target_name(target
));
406 static int aarch64_halt_smp(struct target
*target
, bool exc_target
)
408 struct target
*next
= target
;
411 /* prepare halt on all PEs of the group */
412 retval
= aarch64_prepare_halt_smp(target
, exc_target
, &next
);
414 if (exc_target
&& next
== target
)
417 /* halt the target PE */
418 if (retval
== ERROR_OK
)
419 retval
= aarch64_halt_one(next
, HALT_LAZY
);
421 if (retval
!= ERROR_OK
)
424 /* wait for all PEs to halt */
425 int64_t then
= timeval_ms();
427 bool all_halted
= true;
428 struct target_list
*head
;
431 foreach_smp_target(head
, target
->head
) {
436 if (!target_was_examined(curr
))
439 retval
= aarch64_check_state_one(curr
, PRSR_HALT
, PRSR_HALT
, &halted
, NULL
);
440 if (retval
!= ERROR_OK
|| !halted
) {
449 if (timeval_ms() > then
+ 1000) {
450 retval
= ERROR_TARGET_TIMEOUT
;
455 * HACK: on Hi6220 there are 8 cores organized in 2 clusters
456 * and it looks like the CTI's are not connected by a common
457 * trigger matrix. It seems that we need to halt one core in each
458 * cluster explicitly. So if we find that a core has not halted
459 * yet, we trigger an explicit halt for the second cluster.
461 retval
= aarch64_halt_one(curr
, HALT_LAZY
);
462 if (retval
!= ERROR_OK
)
469 static int update_halt_gdb(struct target
*target
, enum target_debug_reason debug_reason
)
471 struct target
*gdb_target
= NULL
;
472 struct target_list
*head
;
475 if (debug_reason
== DBG_REASON_NOTHALTED
) {
476 LOG_DEBUG("Halting remaining targets in SMP group");
477 aarch64_halt_smp(target
, true);
480 /* poll all targets in the group, but skip the target that serves GDB */
481 foreach_smp_target(head
, target
->head
) {
483 /* skip calling context */
486 if (!target_was_examined(curr
))
488 /* skip targets that were already halted */
489 if (curr
->state
== TARGET_HALTED
)
491 /* remember the gdb_service->target */
492 if (curr
->gdb_service
)
493 gdb_target
= curr
->gdb_service
->target
;
495 if (curr
== gdb_target
)
498 /* avoid recursion in aarch64_poll() */
504 /* after all targets were updated, poll the gdb serving target */
505 if (gdb_target
&& gdb_target
!= target
)
506 aarch64_poll(gdb_target
);
512 * Aarch64 Run control
515 static int aarch64_poll(struct target
*target
)
517 enum target_state prev_target_state
;
518 int retval
= ERROR_OK
;
521 retval
= aarch64_check_state_one(target
,
522 PRSR_HALT
, PRSR_HALT
, &halted
, NULL
);
523 if (retval
!= ERROR_OK
)
527 prev_target_state
= target
->state
;
528 if (prev_target_state
!= TARGET_HALTED
) {
529 enum target_debug_reason debug_reason
= target
->debug_reason
;
531 /* We have a halting debug event */
532 target
->state
= TARGET_HALTED
;
533 LOG_DEBUG("Target %s halted", target_name(target
));
534 retval
= aarch64_debug_entry(target
);
535 if (retval
!= ERROR_OK
)
539 update_halt_gdb(target
, debug_reason
);
541 if (arm_semihosting(target
, &retval
) != 0)
544 switch (prev_target_state
) {
548 target_call_event_callbacks(target
, TARGET_EVENT_HALTED
);
550 case TARGET_DEBUG_RUNNING
:
551 target_call_event_callbacks(target
, TARGET_EVENT_DEBUG_HALTED
);
558 target
->state
= TARGET_RUNNING
;
563 static int aarch64_halt(struct target
*target
)
565 struct armv8_common
*armv8
= target_to_armv8(target
);
566 armv8
->last_run_control_op
= ARMV8_RUNCONTROL_HALT
;
569 return aarch64_halt_smp(target
, false);
571 return aarch64_halt_one(target
, HALT_SYNC
);
574 static int aarch64_restore_one(struct target
*target
, int current
,
575 uint64_t *address
, int handle_breakpoints
, int debug_execution
)
577 struct armv8_common
*armv8
= target_to_armv8(target
);
578 struct arm
*arm
= &armv8
->arm
;
582 LOG_DEBUG("%s", target_name(target
));
584 if (!debug_execution
)
585 target_free_all_working_areas(target
);
587 /* current = 1: continue on current pc, otherwise continue at <address> */
588 resume_pc
= buf_get_u64(arm
->pc
->value
, 0, 64);
590 resume_pc
= *address
;
592 *address
= resume_pc
;
594 /* Make sure that the Armv7 gdb thumb fixups does not
595 * kill the return address
597 switch (arm
->core_state
) {
599 resume_pc
&= 0xFFFFFFFC;
601 case ARM_STATE_AARCH64
:
602 resume_pc
&= 0xFFFFFFFFFFFFFFFC;
604 case ARM_STATE_THUMB
:
605 case ARM_STATE_THUMB_EE
:
606 /* When the return address is loaded into PC
607 * bit 0 must be 1 to stay in Thumb state
611 case ARM_STATE_JAZELLE
:
612 LOG_ERROR("How do I resume into Jazelle state??");
615 LOG_DEBUG("resume pc = 0x%016" PRIx64
, resume_pc
);
616 buf_set_u64(arm
->pc
->value
, 0, 64, resume_pc
);
617 arm
->pc
->dirty
= true;
618 arm
->pc
->valid
= true;
620 /* called it now before restoring context because it uses cpu
621 * register r0 for restoring system control register */
622 retval
= aarch64_restore_system_control_reg(target
);
623 if (retval
== ERROR_OK
)
624 retval
= aarch64_restore_context(target
, handle_breakpoints
);
630 * prepare single target for restart
634 static int aarch64_prepare_restart_one(struct target
*target
)
636 struct armv8_common
*armv8
= target_to_armv8(target
);
641 LOG_DEBUG("%s", target_name(target
));
643 retval
= mem_ap_read_atomic_u32(armv8
->debug_ap
,
644 armv8
->debug_base
+ CPUV8_DBG_DSCR
, &dscr
);
645 if (retval
!= ERROR_OK
)
648 if ((dscr
& DSCR_ITE
) == 0)
649 LOG_ERROR("DSCR.ITE must be set before leaving debug!");
650 if ((dscr
& DSCR_ERR
) != 0)
651 LOG_ERROR("DSCR.ERR must be cleared before leaving debug!");
653 /* acknowledge a pending CTI halt event */
654 retval
= arm_cti_ack_events(armv8
->cti
, CTI_TRIG(HALT
));
656 * open the CTI gate for channel 1 so that the restart events
657 * get passed along to all PEs. Also close gate for channel 0
658 * to isolate the PE from halt events.
660 if (retval
== ERROR_OK
)
661 retval
= arm_cti_ungate_channel(armv8
->cti
, 1);
662 if (retval
== ERROR_OK
)
663 retval
= arm_cti_gate_channel(armv8
->cti
, 0);
665 /* make sure that DSCR.HDE is set */
666 if (retval
== ERROR_OK
) {
668 retval
= mem_ap_write_atomic_u32(armv8
->debug_ap
,
669 armv8
->debug_base
+ CPUV8_DBG_DSCR
, dscr
);
672 if (retval
== ERROR_OK
) {
673 /* clear sticky bits in PRSR, SDR is now 0 */
674 retval
= mem_ap_read_atomic_u32(armv8
->debug_ap
,
675 armv8
->debug_base
+ CPUV8_DBG_PRSR
, &tmp
);
681 static int aarch64_do_restart_one(struct target
*target
, enum restart_mode mode
)
683 struct armv8_common
*armv8
= target_to_armv8(target
);
686 LOG_DEBUG("%s", target_name(target
));
688 /* trigger an event on channel 1, generates a restart request to the PE */
689 retval
= arm_cti_pulse_channel(armv8
->cti
, 1);
690 if (retval
!= ERROR_OK
)
693 if (mode
== RESTART_SYNC
) {
694 int64_t then
= timeval_ms();
698 * if PRSR.SDR is set now, the target did restart, even
699 * if it's now already halted again (e.g. due to breakpoint)
701 retval
= aarch64_check_state_one(target
,
702 PRSR_SDR
, PRSR_SDR
, &resumed
, NULL
);
703 if (retval
!= ERROR_OK
|| resumed
)
706 if (timeval_ms() > then
+ 1000) {
707 LOG_ERROR("%s: Timeout waiting for resume"PRIx32
, target_name(target
));
708 retval
= ERROR_TARGET_TIMEOUT
;
714 if (retval
!= ERROR_OK
)
717 target
->debug_reason
= DBG_REASON_NOTHALTED
;
718 target
->state
= TARGET_RUNNING
;
723 static int aarch64_restart_one(struct target
*target
, enum restart_mode mode
)
727 LOG_DEBUG("%s", target_name(target
));
729 retval
= aarch64_prepare_restart_one(target
);
730 if (retval
== ERROR_OK
)
731 retval
= aarch64_do_restart_one(target
, mode
);
737 * prepare all but the current target for restart
739 static int aarch64_prep_restart_smp(struct target
*target
, int handle_breakpoints
, struct target
**p_first
)
741 int retval
= ERROR_OK
;
742 struct target_list
*head
;
743 struct target
*first
= NULL
;
746 foreach_smp_target(head
, target
->head
) {
747 struct target
*curr
= head
->target
;
749 /* skip calling target */
752 if (!target_was_examined(curr
))
754 if (curr
->state
!= TARGET_HALTED
)
757 /* resume at current address, not in step mode */
758 retval
= aarch64_restore_one(curr
, 1, &address
, handle_breakpoints
, 0);
759 if (retval
== ERROR_OK
)
760 retval
= aarch64_prepare_restart_one(curr
);
761 if (retval
!= ERROR_OK
) {
762 LOG_ERROR("failed to restore target %s", target_name(curr
));
765 /* remember the first valid target in the group */
777 static int aarch64_step_restart_smp(struct target
*target
)
779 int retval
= ERROR_OK
;
780 struct target_list
*head
;
781 struct target
*first
= NULL
;
783 LOG_DEBUG("%s", target_name(target
));
785 retval
= aarch64_prep_restart_smp(target
, 0, &first
);
786 if (retval
!= ERROR_OK
)
790 retval
= aarch64_do_restart_one(first
, RESTART_LAZY
);
791 if (retval
!= ERROR_OK
) {
792 LOG_DEBUG("error restarting target %s", target_name(first
));
796 int64_t then
= timeval_ms();
798 struct target
*curr
= target
;
799 bool all_resumed
= true;
801 foreach_smp_target(head
, target
->head
) {
810 if (!target_was_examined(curr
))
813 retval
= aarch64_check_state_one(curr
,
814 PRSR_SDR
, PRSR_SDR
, &resumed
, &prsr
);
815 if (retval
!= ERROR_OK
|| (!resumed
&& (prsr
& PRSR_HALT
))) {
820 if (curr
->state
!= TARGET_RUNNING
) {
821 curr
->state
= TARGET_RUNNING
;
822 curr
->debug_reason
= DBG_REASON_NOTHALTED
;
823 target_call_event_callbacks(curr
, TARGET_EVENT_RESUMED
);
830 if (timeval_ms() > then
+ 1000) {
831 LOG_ERROR("%s: timeout waiting for target resume", __func__
);
832 retval
= ERROR_TARGET_TIMEOUT
;
836 * HACK: on Hi6220 there are 8 cores organized in 2 clusters
837 * and it looks like the CTI's are not connected by a common
838 * trigger matrix. It seems that we need to halt one core in each
839 * cluster explicitly. So if we find that a core has not halted
840 * yet, we trigger an explicit resume for the second cluster.
842 retval
= aarch64_do_restart_one(curr
, RESTART_LAZY
);
843 if (retval
!= ERROR_OK
)
850 static int aarch64_resume(struct target
*target
, int current
,
851 target_addr_t address
, int handle_breakpoints
, int debug_execution
)
854 uint64_t addr
= address
;
856 struct armv8_common
*armv8
= target_to_armv8(target
);
857 armv8
->last_run_control_op
= ARMV8_RUNCONTROL_RESUME
;
859 if (target
->state
!= TARGET_HALTED
)
860 return ERROR_TARGET_NOT_HALTED
;
863 * If this target is part of a SMP group, prepare the others
864 * targets for resuming. This involves restoring the complete
865 * target register context and setting up CTI gates to accept
866 * resume events from the trigger matrix.
869 retval
= aarch64_prep_restart_smp(target
, handle_breakpoints
, NULL
);
870 if (retval
!= ERROR_OK
)
874 /* all targets prepared, restore and restart the current target */
875 retval
= aarch64_restore_one(target
, current
, &addr
, handle_breakpoints
,
877 if (retval
== ERROR_OK
)
878 retval
= aarch64_restart_one(target
, RESTART_SYNC
);
879 if (retval
!= ERROR_OK
)
883 int64_t then
= timeval_ms();
885 struct target
*curr
= target
;
886 struct target_list
*head
;
887 bool all_resumed
= true;
889 foreach_smp_target(head
, target
->head
) {
896 if (!target_was_examined(curr
))
899 retval
= aarch64_check_state_one(curr
,
900 PRSR_SDR
, PRSR_SDR
, &resumed
, &prsr
);
901 if (retval
!= ERROR_OK
|| (!resumed
&& (prsr
& PRSR_HALT
))) {
906 if (curr
->state
!= TARGET_RUNNING
) {
907 curr
->state
= TARGET_RUNNING
;
908 curr
->debug_reason
= DBG_REASON_NOTHALTED
;
909 target_call_event_callbacks(curr
, TARGET_EVENT_RESUMED
);
916 if (timeval_ms() > then
+ 1000) {
917 LOG_ERROR("%s: timeout waiting for target %s to resume", __func__
, target_name(curr
));
918 retval
= ERROR_TARGET_TIMEOUT
;
923 * HACK: on Hi6220 there are 8 cores organized in 2 clusters
924 * and it looks like the CTI's are not connected by a common
925 * trigger matrix. It seems that we need to halt one core in each
926 * cluster explicitly. So if we find that a core has not halted
927 * yet, we trigger an explicit resume for the second cluster.
929 retval
= aarch64_do_restart_one(curr
, RESTART_LAZY
);
930 if (retval
!= ERROR_OK
)
935 if (retval
!= ERROR_OK
)
938 target
->debug_reason
= DBG_REASON_NOTHALTED
;
940 if (!debug_execution
) {
941 target
->state
= TARGET_RUNNING
;
942 target_call_event_callbacks(target
, TARGET_EVENT_RESUMED
);
943 LOG_DEBUG("target resumed at 0x%" PRIx64
, addr
);
945 target
->state
= TARGET_DEBUG_RUNNING
;
946 target_call_event_callbacks(target
, TARGET_EVENT_DEBUG_RESUMED
);
947 LOG_DEBUG("target debug resumed at 0x%" PRIx64
, addr
);
953 static int aarch64_debug_entry(struct target
*target
)
955 int retval
= ERROR_OK
;
956 struct armv8_common
*armv8
= target_to_armv8(target
);
957 struct arm_dpm
*dpm
= &armv8
->dpm
;
958 enum arm_state core_state
;
961 /* make sure to clear all sticky errors */
962 retval
= mem_ap_write_atomic_u32(armv8
->debug_ap
,
963 armv8
->debug_base
+ CPUV8_DBG_DRCR
, DRCR_CSE
);
964 if (retval
== ERROR_OK
)
965 retval
= mem_ap_read_atomic_u32(armv8
->debug_ap
,
966 armv8
->debug_base
+ CPUV8_DBG_DSCR
, &dscr
);
967 if (retval
== ERROR_OK
)
968 retval
= arm_cti_ack_events(armv8
->cti
, CTI_TRIG(HALT
));
970 if (retval
!= ERROR_OK
)
973 LOG_DEBUG("%s dscr = 0x%08" PRIx32
, target_name(target
), dscr
);
976 core_state
= armv8_dpm_get_core_state(dpm
);
977 armv8_select_opcodes(armv8
, core_state
== ARM_STATE_AARCH64
);
978 armv8_select_reg_access(armv8
, core_state
== ARM_STATE_AARCH64
);
980 /* close the CTI gate for all events */
981 if (retval
== ERROR_OK
)
982 retval
= arm_cti_write_reg(armv8
->cti
, CTI_GATE
, 0);
983 /* discard async exceptions */
984 if (retval
== ERROR_OK
)
985 retval
= dpm
->instr_cpsr_sync(dpm
);
986 if (retval
!= ERROR_OK
)
989 /* Examine debug reason */
990 armv8_dpm_report_dscr(dpm
, dscr
);
992 /* save the memory address that triggered the watchpoint */
993 if (target
->debug_reason
== DBG_REASON_WATCHPOINT
) {
996 retval
= mem_ap_read_atomic_u32(armv8
->debug_ap
,
997 armv8
->debug_base
+ CPUV8_DBG_EDWAR0
, &tmp
);
998 if (retval
!= ERROR_OK
)
1000 target_addr_t edwar
= tmp
;
1002 /* EDWAR[63:32] has unknown content in aarch32 state */
1003 if (core_state
== ARM_STATE_AARCH64
) {
1004 retval
= mem_ap_read_atomic_u32(armv8
->debug_ap
,
1005 armv8
->debug_base
+ CPUV8_DBG_EDWAR1
, &tmp
);
1006 if (retval
!= ERROR_OK
)
1008 edwar
|= ((target_addr_t
)tmp
) << 32;
1011 armv8
->dpm
.wp_addr
= edwar
;
1014 retval
= armv8_dpm_read_current_registers(&armv8
->dpm
);
1016 if (retval
== ERROR_OK
&& armv8
->post_debug_entry
)
1017 retval
= armv8
->post_debug_entry(target
);
1022 static int aarch64_post_debug_entry(struct target
*target
)
1024 struct aarch64_common
*aarch64
= target_to_aarch64(target
);
1025 struct armv8_common
*armv8
= &aarch64
->armv8_common
;
1027 enum arm_mode target_mode
= ARM_MODE_ANY
;
1030 switch (armv8
->arm
.core_mode
) {
1032 target_mode
= ARMV8_64_EL1H
;
1036 instr
= ARMV8_MRS(SYSTEM_SCTLR_EL1
, 0);
1040 instr
= ARMV8_MRS(SYSTEM_SCTLR_EL2
, 0);
1044 instr
= ARMV8_MRS(SYSTEM_SCTLR_EL3
, 0);
1053 instr
= ARMV4_5_MRC(15, 0, 0, 1, 0, 0);
1057 LOG_ERROR("cannot read system control register in this mode: (%s : 0x%x)",
1058 armv8_mode_name(armv8
->arm
.core_mode
), armv8
->arm
.core_mode
);
1062 if (target_mode
!= ARM_MODE_ANY
)
1063 armv8_dpm_modeswitch(&armv8
->dpm
, target_mode
);
1065 retval
= armv8
->dpm
.instr_read_data_r0(&armv8
->dpm
, instr
, &aarch64
->system_control_reg
);
1066 if (retval
!= ERROR_OK
)
1069 if (target_mode
!= ARM_MODE_ANY
)
1070 armv8_dpm_modeswitch(&armv8
->dpm
, ARM_MODE_ANY
);
1072 LOG_DEBUG("System_register: %8.8" PRIx32
, aarch64
->system_control_reg
);
1073 aarch64
->system_control_reg_curr
= aarch64
->system_control_reg
;
1075 if (armv8
->armv8_mmu
.armv8_cache
.info
== -1) {
1076 armv8_identify_cache(armv8
);
1077 armv8_read_mpidr(armv8
);
1080 armv8
->armv8_mmu
.mmu_enabled
=
1081 (aarch64
->system_control_reg
& 0x1U
) ? 1 : 0;
1082 armv8
->armv8_mmu
.armv8_cache
.d_u_cache_enabled
=
1083 (aarch64
->system_control_reg
& 0x4U
) ? 1 : 0;
1084 armv8
->armv8_mmu
.armv8_cache
.i_cache_enabled
=
1085 (aarch64
->system_control_reg
& 0x1000U
) ? 1 : 0;
1090 * single-step a target
1092 static int aarch64_step(struct target
*target
, int current
, target_addr_t address
,
1093 int handle_breakpoints
)
1095 struct armv8_common
*armv8
= target_to_armv8(target
);
1096 struct aarch64_common
*aarch64
= target_to_aarch64(target
);
1097 int saved_retval
= ERROR_OK
;
1101 armv8
->last_run_control_op
= ARMV8_RUNCONTROL_STEP
;
1103 if (target
->state
!= TARGET_HALTED
) {
1104 LOG_WARNING("target not halted");
1105 return ERROR_TARGET_NOT_HALTED
;
1108 retval
= mem_ap_read_atomic_u32(armv8
->debug_ap
,
1109 armv8
->debug_base
+ CPUV8_DBG_EDECR
, &edecr
);
1110 /* make sure EDECR.SS is not set when restoring the register */
1112 if (retval
== ERROR_OK
) {
1114 /* set EDECR.SS to enter hardware step mode */
1115 retval
= mem_ap_write_atomic_u32(armv8
->debug_ap
,
1116 armv8
->debug_base
+ CPUV8_DBG_EDECR
, (edecr
|0x4));
1118 /* disable interrupts while stepping */
1119 if (retval
== ERROR_OK
&& aarch64
->isrmasking_mode
== AARCH64_ISRMASK_ON
)
1120 retval
= aarch64_set_dscr_bits(target
, 0x3 << 22, 0x3 << 22);
1121 /* bail out if stepping setup has failed */
1122 if (retval
!= ERROR_OK
)
1125 if (target
->smp
&& (current
== 1)) {
1127 * isolate current target so that it doesn't get resumed
1128 * together with the others
1130 retval
= arm_cti_gate_channel(armv8
->cti
, 1);
1131 /* resume all other targets in the group */
1132 if (retval
== ERROR_OK
)
1133 retval
= aarch64_step_restart_smp(target
);
1134 if (retval
!= ERROR_OK
) {
1135 LOG_ERROR("Failed to restart non-stepping targets in SMP group");
1138 LOG_DEBUG("Restarted all non-stepping targets in SMP group");
1141 /* all other targets running, restore and restart the current target */
1142 retval
= aarch64_restore_one(target
, current
, &address
, 0, 0);
1143 if (retval
== ERROR_OK
)
1144 retval
= aarch64_restart_one(target
, RESTART_LAZY
);
1146 if (retval
!= ERROR_OK
)
1149 LOG_DEBUG("target step-resumed at 0x%" PRIx64
, address
);
1150 if (!handle_breakpoints
)
1151 target_call_event_callbacks(target
, TARGET_EVENT_RESUMED
);
1153 int64_t then
= timeval_ms();
1158 retval
= aarch64_check_state_one(target
,
1159 PRSR_SDR
|PRSR_HALT
, PRSR_SDR
|PRSR_HALT
, &stepped
, &prsr
);
1160 if (retval
!= ERROR_OK
|| stepped
)
1163 if (timeval_ms() > then
+ 100) {
1164 LOG_ERROR("timeout waiting for target %s halt after step",
1165 target_name(target
));
1166 retval
= ERROR_TARGET_TIMEOUT
;
1172 * At least on one SoC (Renesas R8A7795) stepping over a WFI instruction
1173 * causes a timeout. The core takes the step but doesn't complete it and so
1174 * debug state is never entered. However, you can manually halt the core
1175 * as an external debug even is also a WFI wakeup event.
1177 if (retval
== ERROR_TARGET_TIMEOUT
)
1178 saved_retval
= aarch64_halt_one(target
, HALT_SYNC
);
1181 retval
= mem_ap_write_atomic_u32(armv8
->debug_ap
,
1182 armv8
->debug_base
+ CPUV8_DBG_EDECR
, edecr
);
1183 if (retval
!= ERROR_OK
)
1186 /* restore interrupts */
1187 if (aarch64
->isrmasking_mode
== AARCH64_ISRMASK_ON
) {
1188 retval
= aarch64_set_dscr_bits(target
, 0x3 << 22, 0);
1189 if (retval
!= ERROR_OK
)
1193 if (saved_retval
!= ERROR_OK
)
1194 return saved_retval
;
1199 static int aarch64_restore_context(struct target
*target
, bool bpwp
)
1201 struct armv8_common
*armv8
= target_to_armv8(target
);
1202 struct arm
*arm
= &armv8
->arm
;
1206 LOG_DEBUG("%s", target_name(target
));
1208 if (armv8
->pre_restore_context
)
1209 armv8
->pre_restore_context(target
);
1211 retval
= armv8_dpm_write_dirty_registers(&armv8
->dpm
, bpwp
);
1212 if (retval
== ERROR_OK
) {
1213 /* registers are now invalid */
1214 register_cache_invalidate(arm
->core_cache
);
1215 register_cache_invalidate(arm
->core_cache
->next
);
1222 * Cortex-A8 Breakpoint and watchpoint functions
1225 /* Setup hardware Breakpoint Register Pair */
1226 static int aarch64_set_breakpoint(struct target
*target
,
1227 struct breakpoint
*breakpoint
, uint8_t matchmode
)
1232 uint8_t byte_addr_select
= 0x0F;
1233 struct aarch64_common
*aarch64
= target_to_aarch64(target
);
1234 struct armv8_common
*armv8
= &aarch64
->armv8_common
;
1235 struct aarch64_brp
*brp_list
= aarch64
->brp_list
;
1237 if (breakpoint
->set
) {
1238 LOG_WARNING("breakpoint already set");
1242 if (breakpoint
->type
== BKPT_HARD
) {
1244 while (brp_list
[brp_i
].used
&& (brp_i
< aarch64
->brp_num
))
1246 if (brp_i
>= aarch64
->brp_num
) {
1247 LOG_ERROR("ERROR Can not find free Breakpoint Register Pair");
1248 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1250 breakpoint
->set
= brp_i
+ 1;
1251 if (breakpoint
->length
== 2)
1252 byte_addr_select
= (3 << (breakpoint
->address
& 0x02));
1253 control
= ((matchmode
& 0x7) << 20)
1255 | (byte_addr_select
<< 5)
1257 brp_list
[brp_i
].used
= 1;
1258 brp_list
[brp_i
].value
= breakpoint
->address
& 0xFFFFFFFFFFFFFFFC;
1259 brp_list
[brp_i
].control
= control
;
1260 bpt_value
= brp_list
[brp_i
].value
;
1262 retval
= aarch64_dap_write_memap_register_u32(target
, armv8
->debug_base
1263 + CPUV8_DBG_BVR_BASE
+ 16 * brp_list
[brp_i
].brpn
,
1264 (uint32_t)(bpt_value
& 0xFFFFFFFF));
1265 if (retval
!= ERROR_OK
)
1267 retval
= aarch64_dap_write_memap_register_u32(target
, armv8
->debug_base
1268 + CPUV8_DBG_BVR_BASE
+ 4 + 16 * brp_list
[brp_i
].brpn
,
1269 (uint32_t)(bpt_value
>> 32));
1270 if (retval
!= ERROR_OK
)
1273 retval
= aarch64_dap_write_memap_register_u32(target
, armv8
->debug_base
1274 + CPUV8_DBG_BCR_BASE
+ 16 * brp_list
[brp_i
].brpn
,
1275 brp_list
[brp_i
].control
);
1276 if (retval
!= ERROR_OK
)
1278 LOG_DEBUG("brp %i control 0x%0" PRIx32
" value 0x%" TARGET_PRIxADDR
, brp_i
,
1279 brp_list
[brp_i
].control
,
1280 brp_list
[brp_i
].value
);
1282 } else if (breakpoint
->type
== BKPT_SOFT
) {
1286 if (armv8_dpm_get_core_state(&armv8
->dpm
) == ARM_STATE_AARCH64
) {
1287 opcode
= ARMV8_HLT(11);
1289 if (breakpoint
->length
!= 4)
1290 LOG_ERROR("bug: breakpoint length should be 4 in AArch64 mode");
1293 * core_state is ARM_STATE_ARM
1294 * in that case the opcode depends on breakpoint length:
1295 * - if length == 4 => A32 opcode
1296 * - if length == 2 => T32 opcode
1297 * - if length == 3 => T32 opcode (refer to gdb doc : ARM-Breakpoint-Kinds)
1298 * in that case the length should be changed from 3 to 4 bytes
1300 opcode
= (breakpoint
->length
== 4) ? ARMV8_HLT_A1(11) :
1301 (uint32_t) (ARMV8_HLT_T1(11) | ARMV8_HLT_T1(11) << 16);
1303 if (breakpoint
->length
== 3)
1304 breakpoint
->length
= 4;
1307 buf_set_u32(code
, 0, 32, opcode
);
1309 retval
= target_read_memory(target
,
1310 breakpoint
->address
& 0xFFFFFFFFFFFFFFFE,
1311 breakpoint
->length
, 1,
1312 breakpoint
->orig_instr
);
1313 if (retval
!= ERROR_OK
)
1316 armv8_cache_d_inner_flush_virt(armv8
,
1317 breakpoint
->address
& 0xFFFFFFFFFFFFFFFE,
1318 breakpoint
->length
);
1320 retval
= target_write_memory(target
,
1321 breakpoint
->address
& 0xFFFFFFFFFFFFFFFE,
1322 breakpoint
->length
, 1, code
);
1323 if (retval
!= ERROR_OK
)
1326 armv8_cache_d_inner_flush_virt(armv8
,
1327 breakpoint
->address
& 0xFFFFFFFFFFFFFFFE,
1328 breakpoint
->length
);
1330 armv8_cache_i_inner_inval_virt(armv8
,
1331 breakpoint
->address
& 0xFFFFFFFFFFFFFFFE,
1332 breakpoint
->length
);
1334 breakpoint
->set
= 0x11; /* Any nice value but 0 */
1337 /* Ensure that halting debug mode is enable */
1338 retval
= aarch64_set_dscr_bits(target
, DSCR_HDE
, DSCR_HDE
);
1339 if (retval
!= ERROR_OK
) {
1340 LOG_DEBUG("Failed to set DSCR.HDE");
1347 static int aarch64_set_context_breakpoint(struct target
*target
,
1348 struct breakpoint
*breakpoint
, uint8_t matchmode
)
1350 int retval
= ERROR_FAIL
;
1353 uint8_t byte_addr_select
= 0x0F;
1354 struct aarch64_common
*aarch64
= target_to_aarch64(target
);
1355 struct armv8_common
*armv8
= &aarch64
->armv8_common
;
1356 struct aarch64_brp
*brp_list
= aarch64
->brp_list
;
1358 if (breakpoint
->set
) {
1359 LOG_WARNING("breakpoint already set");
1362 /*check available context BRPs*/
1363 while ((brp_list
[brp_i
].used
||
1364 (brp_list
[brp_i
].type
!= BRP_CONTEXT
)) && (brp_i
< aarch64
->brp_num
))
1367 if (brp_i
>= aarch64
->brp_num
) {
1368 LOG_ERROR("ERROR Can not find free Breakpoint Register Pair");
1372 breakpoint
->set
= brp_i
+ 1;
1373 control
= ((matchmode
& 0x7) << 20)
1375 | (byte_addr_select
<< 5)
1377 brp_list
[brp_i
].used
= 1;
1378 brp_list
[brp_i
].value
= (breakpoint
->asid
);
1379 brp_list
[brp_i
].control
= control
;
1380 retval
= aarch64_dap_write_memap_register_u32(target
, armv8
->debug_base
1381 + CPUV8_DBG_BVR_BASE
+ 16 * brp_list
[brp_i
].brpn
,
1382 brp_list
[brp_i
].value
);
1383 if (retval
!= ERROR_OK
)
1385 retval
= aarch64_dap_write_memap_register_u32(target
, armv8
->debug_base
1386 + CPUV8_DBG_BCR_BASE
+ 16 * brp_list
[brp_i
].brpn
,
1387 brp_list
[brp_i
].control
);
1388 if (retval
!= ERROR_OK
)
1390 LOG_DEBUG("brp %i control 0x%0" PRIx32
" value 0x%" TARGET_PRIxADDR
, brp_i
,
1391 brp_list
[brp_i
].control
,
1392 brp_list
[brp_i
].value
);
1397 static int aarch64_set_hybrid_breakpoint(struct target
*target
, struct breakpoint
*breakpoint
)
1399 int retval
= ERROR_FAIL
;
1400 int brp_1
= 0; /* holds the contextID pair */
1401 int brp_2
= 0; /* holds the IVA pair */
1402 uint32_t control_ctx
, control_iva
;
1403 uint8_t ctx_byte_addr_select
= 0x0F;
1404 uint8_t iva_byte_addr_select
= 0x0F;
1405 uint8_t ctx_machmode
= 0x03;
1406 uint8_t iva_machmode
= 0x01;
1407 struct aarch64_common
*aarch64
= target_to_aarch64(target
);
1408 struct armv8_common
*armv8
= &aarch64
->armv8_common
;
1409 struct aarch64_brp
*brp_list
= aarch64
->brp_list
;
1411 if (breakpoint
->set
) {
1412 LOG_WARNING("breakpoint already set");
1415 /*check available context BRPs*/
1416 while ((brp_list
[brp_1
].used
||
1417 (brp_list
[brp_1
].type
!= BRP_CONTEXT
)) && (brp_1
< aarch64
->brp_num
))
1420 LOG_DEBUG("brp(CTX) found num: %d", brp_1
);
1421 if (brp_1
>= aarch64
->brp_num
) {
1422 LOG_ERROR("ERROR Can not find free Breakpoint Register Pair");
1426 while ((brp_list
[brp_2
].used
||
1427 (brp_list
[brp_2
].type
!= BRP_NORMAL
)) && (brp_2
< aarch64
->brp_num
))
1430 LOG_DEBUG("brp(IVA) found num: %d", brp_2
);
1431 if (brp_2
>= aarch64
->brp_num
) {
1432 LOG_ERROR("ERROR Can not find free Breakpoint Register Pair");
1436 breakpoint
->set
= brp_1
+ 1;
1437 breakpoint
->linked_brp
= brp_2
;
1438 control_ctx
= ((ctx_machmode
& 0x7) << 20)
1441 | (ctx_byte_addr_select
<< 5)
1443 brp_list
[brp_1
].used
= 1;
1444 brp_list
[brp_1
].value
= (breakpoint
->asid
);
1445 brp_list
[brp_1
].control
= control_ctx
;
1446 retval
= aarch64_dap_write_memap_register_u32(target
, armv8
->debug_base
1447 + CPUV8_DBG_BVR_BASE
+ 16 * brp_list
[brp_1
].brpn
,
1448 brp_list
[brp_1
].value
);
1449 if (retval
!= ERROR_OK
)
1451 retval
= aarch64_dap_write_memap_register_u32(target
, armv8
->debug_base
1452 + CPUV8_DBG_BCR_BASE
+ 16 * brp_list
[brp_1
].brpn
,
1453 brp_list
[brp_1
].control
);
1454 if (retval
!= ERROR_OK
)
1457 control_iva
= ((iva_machmode
& 0x7) << 20)
1460 | (iva_byte_addr_select
<< 5)
1462 brp_list
[brp_2
].used
= 1;
1463 brp_list
[brp_2
].value
= breakpoint
->address
& 0xFFFFFFFFFFFFFFFC;
1464 brp_list
[brp_2
].control
= control_iva
;
1465 retval
= aarch64_dap_write_memap_register_u32(target
, armv8
->debug_base
1466 + CPUV8_DBG_BVR_BASE
+ 16 * brp_list
[brp_2
].brpn
,
1467 brp_list
[brp_2
].value
& 0xFFFFFFFF);
1468 if (retval
!= ERROR_OK
)
1470 retval
= aarch64_dap_write_memap_register_u32(target
, armv8
->debug_base
1471 + CPUV8_DBG_BVR_BASE
+ 4 + 16 * brp_list
[brp_2
].brpn
,
1472 brp_list
[brp_2
].value
>> 32);
1473 if (retval
!= ERROR_OK
)
1475 retval
= aarch64_dap_write_memap_register_u32(target
, armv8
->debug_base
1476 + CPUV8_DBG_BCR_BASE
+ 16 * brp_list
[brp_2
].brpn
,
1477 brp_list
[brp_2
].control
);
1478 if (retval
!= ERROR_OK
)
1484 static int aarch64_unset_breakpoint(struct target
*target
, struct breakpoint
*breakpoint
)
1487 struct aarch64_common
*aarch64
= target_to_aarch64(target
);
1488 struct armv8_common
*armv8
= &aarch64
->armv8_common
;
1489 struct aarch64_brp
*brp_list
= aarch64
->brp_list
;
1491 if (!breakpoint
->set
) {
1492 LOG_WARNING("breakpoint not set");
1496 if (breakpoint
->type
== BKPT_HARD
) {
1497 if ((breakpoint
->address
!= 0) && (breakpoint
->asid
!= 0)) {
1498 int brp_i
= breakpoint
->set
- 1;
1499 int brp_j
= breakpoint
->linked_brp
;
1500 if ((brp_i
< 0) || (brp_i
>= aarch64
->brp_num
)) {
1501 LOG_DEBUG("Invalid BRP number in breakpoint");
1504 LOG_DEBUG("rbp %i control 0x%0" PRIx32
" value 0x%" TARGET_PRIxADDR
, brp_i
,
1505 brp_list
[brp_i
].control
, brp_list
[brp_i
].value
);
1506 brp_list
[brp_i
].used
= 0;
1507 brp_list
[brp_i
].value
= 0;
1508 brp_list
[brp_i
].control
= 0;
1509 retval
= aarch64_dap_write_memap_register_u32(target
, armv8
->debug_base
1510 + CPUV8_DBG_BCR_BASE
+ 16 * brp_list
[brp_i
].brpn
,
1511 brp_list
[brp_i
].control
);
1512 if (retval
!= ERROR_OK
)
1514 retval
= aarch64_dap_write_memap_register_u32(target
, armv8
->debug_base
1515 + CPUV8_DBG_BVR_BASE
+ 16 * brp_list
[brp_i
].brpn
,
1516 (uint32_t)brp_list
[brp_i
].value
);
1517 if (retval
!= ERROR_OK
)
1519 retval
= aarch64_dap_write_memap_register_u32(target
, armv8
->debug_base
1520 + CPUV8_DBG_BVR_BASE
+ 4 + 16 * brp_list
[brp_i
].brpn
,
1521 (uint32_t)brp_list
[brp_i
].value
);
1522 if (retval
!= ERROR_OK
)
1524 if ((brp_j
< 0) || (brp_j
>= aarch64
->brp_num
)) {
1525 LOG_DEBUG("Invalid BRP number in breakpoint");
1528 LOG_DEBUG("rbp %i control 0x%0" PRIx32
" value 0x%0" PRIx64
, brp_j
,
1529 brp_list
[brp_j
].control
, brp_list
[brp_j
].value
);
1530 brp_list
[brp_j
].used
= 0;
1531 brp_list
[brp_j
].value
= 0;
1532 brp_list
[brp_j
].control
= 0;
1533 retval
= aarch64_dap_write_memap_register_u32(target
, armv8
->debug_base
1534 + CPUV8_DBG_BCR_BASE
+ 16 * brp_list
[brp_j
].brpn
,
1535 brp_list
[brp_j
].control
);
1536 if (retval
!= ERROR_OK
)
1538 retval
= aarch64_dap_write_memap_register_u32(target
, armv8
->debug_base
1539 + CPUV8_DBG_BVR_BASE
+ 16 * brp_list
[brp_j
].brpn
,
1540 (uint32_t)brp_list
[brp_j
].value
);
1541 if (retval
!= ERROR_OK
)
1543 retval
= aarch64_dap_write_memap_register_u32(target
, armv8
->debug_base
1544 + CPUV8_DBG_BVR_BASE
+ 4 + 16 * brp_list
[brp_j
].brpn
,
1545 (uint32_t)brp_list
[brp_j
].value
);
1546 if (retval
!= ERROR_OK
)
1549 breakpoint
->linked_brp
= 0;
1550 breakpoint
->set
= 0;
1554 int brp_i
= breakpoint
->set
- 1;
1555 if ((brp_i
< 0) || (brp_i
>= aarch64
->brp_num
)) {
1556 LOG_DEBUG("Invalid BRP number in breakpoint");
1559 LOG_DEBUG("rbp %i control 0x%0" PRIx32
" value 0x%0" PRIx64
, brp_i
,
1560 brp_list
[brp_i
].control
, brp_list
[brp_i
].value
);
1561 brp_list
[brp_i
].used
= 0;
1562 brp_list
[brp_i
].value
= 0;
1563 brp_list
[brp_i
].control
= 0;
1564 retval
= aarch64_dap_write_memap_register_u32(target
, armv8
->debug_base
1565 + CPUV8_DBG_BCR_BASE
+ 16 * brp_list
[brp_i
].brpn
,
1566 brp_list
[brp_i
].control
);
1567 if (retval
!= ERROR_OK
)
1569 retval
= aarch64_dap_write_memap_register_u32(target
, armv8
->debug_base
1570 + CPUV8_DBG_BVR_BASE
+ 16 * brp_list
[brp_i
].brpn
,
1571 brp_list
[brp_i
].value
);
1572 if (retval
!= ERROR_OK
)
1575 retval
= aarch64_dap_write_memap_register_u32(target
, armv8
->debug_base
1576 + CPUV8_DBG_BVR_BASE
+ 4 + 16 * brp_list
[brp_i
].brpn
,
1577 (uint32_t)brp_list
[brp_i
].value
);
1578 if (retval
!= ERROR_OK
)
1580 breakpoint
->set
= 0;
1584 /* restore original instruction (kept in target endianness) */
1586 armv8_cache_d_inner_flush_virt(armv8
,
1587 breakpoint
->address
& 0xFFFFFFFFFFFFFFFE,
1588 breakpoint
->length
);
1590 if (breakpoint
->length
== 4) {
1591 retval
= target_write_memory(target
,
1592 breakpoint
->address
& 0xFFFFFFFFFFFFFFFE,
1593 4, 1, breakpoint
->orig_instr
);
1594 if (retval
!= ERROR_OK
)
1597 retval
= target_write_memory(target
,
1598 breakpoint
->address
& 0xFFFFFFFFFFFFFFFE,
1599 2, 1, breakpoint
->orig_instr
);
1600 if (retval
!= ERROR_OK
)
1604 armv8_cache_d_inner_flush_virt(armv8
,
1605 breakpoint
->address
& 0xFFFFFFFFFFFFFFFE,
1606 breakpoint
->length
);
1608 armv8_cache_i_inner_inval_virt(armv8
,
1609 breakpoint
->address
& 0xFFFFFFFFFFFFFFFE,
1610 breakpoint
->length
);
1612 breakpoint
->set
= 0;
1617 static int aarch64_add_breakpoint(struct target
*target
,
1618 struct breakpoint
*breakpoint
)
1620 struct aarch64_common
*aarch64
= target_to_aarch64(target
);
1622 if ((breakpoint
->type
== BKPT_HARD
) && (aarch64
->brp_num_available
< 1)) {
1623 LOG_INFO("no hardware breakpoint available");
1624 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1627 if (breakpoint
->type
== BKPT_HARD
)
1628 aarch64
->brp_num_available
--;
1630 return aarch64_set_breakpoint(target
, breakpoint
, 0x00); /* Exact match */
1633 static int aarch64_add_context_breakpoint(struct target
*target
,
1634 struct breakpoint
*breakpoint
)
1636 struct aarch64_common
*aarch64
= target_to_aarch64(target
);
1638 if ((breakpoint
->type
== BKPT_HARD
) && (aarch64
->brp_num_available
< 1)) {
1639 LOG_INFO("no hardware breakpoint available");
1640 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1643 if (breakpoint
->type
== BKPT_HARD
)
1644 aarch64
->brp_num_available
--;
1646 return aarch64_set_context_breakpoint(target
, breakpoint
, 0x02); /* asid match */
1649 static int aarch64_add_hybrid_breakpoint(struct target
*target
,
1650 struct breakpoint
*breakpoint
)
1652 struct aarch64_common
*aarch64
= target_to_aarch64(target
);
1654 if ((breakpoint
->type
== BKPT_HARD
) && (aarch64
->brp_num_available
< 1)) {
1655 LOG_INFO("no hardware breakpoint available");
1656 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1659 if (breakpoint
->type
== BKPT_HARD
)
1660 aarch64
->brp_num_available
--;
1662 return aarch64_set_hybrid_breakpoint(target
, breakpoint
); /* ??? */
1665 static int aarch64_remove_breakpoint(struct target
*target
, struct breakpoint
*breakpoint
)
1667 struct aarch64_common
*aarch64
= target_to_aarch64(target
);
1670 /* It is perfectly possible to remove breakpoints while the target is running */
1671 if (target
->state
!= TARGET_HALTED
) {
1672 LOG_WARNING("target not halted");
1673 return ERROR_TARGET_NOT_HALTED
;
1677 if (breakpoint
->set
) {
1678 aarch64_unset_breakpoint(target
, breakpoint
);
1679 if (breakpoint
->type
== BKPT_HARD
)
1680 aarch64
->brp_num_available
++;
1686 /* Setup hardware Watchpoint Register Pair */
1687 static int aarch64_set_watchpoint(struct target
*target
,
1688 struct watchpoint
*watchpoint
)
1692 uint32_t control
, offset
, length
;
1693 struct aarch64_common
*aarch64
= target_to_aarch64(target
);
1694 struct armv8_common
*armv8
= &aarch64
->armv8_common
;
1695 struct aarch64_brp
*wp_list
= aarch64
->wp_list
;
1697 if (watchpoint
->set
) {
1698 LOG_WARNING("watchpoint already set");
1702 while (wp_list
[wp_i
].used
&& (wp_i
< aarch64
->wp_num
))
1704 if (wp_i
>= aarch64
->wp_num
) {
1705 LOG_ERROR("ERROR Can not find free Watchpoint Register Pair");
1706 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1709 control
= (1 << 0) /* enable */
1710 | (3 << 1) /* both user and privileged access */
1711 | (1 << 13); /* higher mode control */
1713 switch (watchpoint
->rw
) {
1725 /* Match up to 8 bytes. */
1726 offset
= watchpoint
->address
& 7;
1727 length
= watchpoint
->length
;
1728 if (offset
+ length
> sizeof(uint64_t)) {
1729 length
= sizeof(uint64_t) - offset
;
1730 LOG_WARNING("Adjust watchpoint match inside 8-byte boundary");
1732 for (; length
> 0; offset
++, length
--)
1733 control
|= (1 << offset
) << 5;
1735 wp_list
[wp_i
].value
= watchpoint
->address
& 0xFFFFFFFFFFFFFFF8ULL
;
1736 wp_list
[wp_i
].control
= control
;
1738 retval
= aarch64_dap_write_memap_register_u32(target
, armv8
->debug_base
1739 + CPUV8_DBG_WVR_BASE
+ 16 * wp_list
[wp_i
].brpn
,
1740 (uint32_t)(wp_list
[wp_i
].value
& 0xFFFFFFFF));
1741 if (retval
!= ERROR_OK
)
1743 retval
= aarch64_dap_write_memap_register_u32(target
, armv8
->debug_base
1744 + CPUV8_DBG_WVR_BASE
+ 4 + 16 * wp_list
[wp_i
].brpn
,
1745 (uint32_t)(wp_list
[wp_i
].value
>> 32));
1746 if (retval
!= ERROR_OK
)
1749 retval
= aarch64_dap_write_memap_register_u32(target
, armv8
->debug_base
1750 + CPUV8_DBG_WCR_BASE
+ 16 * wp_list
[wp_i
].brpn
,
1752 if (retval
!= ERROR_OK
)
1754 LOG_DEBUG("wp %i control 0x%0" PRIx32
" value 0x%" TARGET_PRIxADDR
, wp_i
,
1755 wp_list
[wp_i
].control
, wp_list
[wp_i
].value
);
1757 /* Ensure that halting debug mode is enable */
1758 retval
= aarch64_set_dscr_bits(target
, DSCR_HDE
, DSCR_HDE
);
1759 if (retval
!= ERROR_OK
) {
1760 LOG_DEBUG("Failed to set DSCR.HDE");
1764 wp_list
[wp_i
].used
= 1;
1765 watchpoint
->set
= wp_i
+ 1;
1770 /* Clear hardware Watchpoint Register Pair */
1771 static int aarch64_unset_watchpoint(struct target
*target
,
1772 struct watchpoint
*watchpoint
)
1775 struct aarch64_common
*aarch64
= target_to_aarch64(target
);
1776 struct armv8_common
*armv8
= &aarch64
->armv8_common
;
1777 struct aarch64_brp
*wp_list
= aarch64
->wp_list
;
1779 if (!watchpoint
->set
) {
1780 LOG_WARNING("watchpoint not set");
1784 wp_i
= watchpoint
->set
- 1;
1785 if ((wp_i
< 0) || (wp_i
>= aarch64
->wp_num
)) {
1786 LOG_DEBUG("Invalid WP number in watchpoint");
1789 LOG_DEBUG("rwp %i control 0x%0" PRIx32
" value 0x%0" PRIx64
, wp_i
,
1790 wp_list
[wp_i
].control
, wp_list
[wp_i
].value
);
1791 wp_list
[wp_i
].used
= 0;
1792 wp_list
[wp_i
].value
= 0;
1793 wp_list
[wp_i
].control
= 0;
1794 retval
= aarch64_dap_write_memap_register_u32(target
, armv8
->debug_base
1795 + CPUV8_DBG_WCR_BASE
+ 16 * wp_list
[wp_i
].brpn
,
1796 wp_list
[wp_i
].control
);
1797 if (retval
!= ERROR_OK
)
1799 retval
= aarch64_dap_write_memap_register_u32(target
, armv8
->debug_base
1800 + CPUV8_DBG_WVR_BASE
+ 16 * wp_list
[wp_i
].brpn
,
1801 wp_list
[wp_i
].value
);
1802 if (retval
!= ERROR_OK
)
1805 retval
= aarch64_dap_write_memap_register_u32(target
, armv8
->debug_base
1806 + CPUV8_DBG_WVR_BASE
+ 4 + 16 * wp_list
[wp_i
].brpn
,
1807 (uint32_t)wp_list
[wp_i
].value
);
1808 if (retval
!= ERROR_OK
)
1810 watchpoint
->set
= 0;
1815 static int aarch64_add_watchpoint(struct target
*target
,
1816 struct watchpoint
*watchpoint
)
1819 struct aarch64_common
*aarch64
= target_to_aarch64(target
);
1821 if (aarch64
->wp_num_available
< 1) {
1822 LOG_INFO("no hardware watchpoint available");
1823 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1826 retval
= aarch64_set_watchpoint(target
, watchpoint
);
1827 if (retval
== ERROR_OK
)
1828 aarch64
->wp_num_available
--;
1833 static int aarch64_remove_watchpoint(struct target
*target
,
1834 struct watchpoint
*watchpoint
)
1836 struct aarch64_common
*aarch64
= target_to_aarch64(target
);
1838 if (watchpoint
->set
) {
1839 aarch64_unset_watchpoint(target
, watchpoint
);
1840 aarch64
->wp_num_available
++;
1847 * find out which watchpoint hits
1848 * get exception address and compare the address to watchpoints
1850 int aarch64_hit_watchpoint(struct target
*target
,
1851 struct watchpoint
**hit_watchpoint
)
1853 if (target
->debug_reason
!= DBG_REASON_WATCHPOINT
)
1856 struct armv8_common
*armv8
= target_to_armv8(target
);
1858 target_addr_t exception_address
;
1859 struct watchpoint
*wp
;
1861 exception_address
= armv8
->dpm
.wp_addr
;
1863 if (exception_address
== 0xFFFFFFFF)
1866 for (wp
= target
->watchpoints
; wp
; wp
= wp
->next
)
1867 if (exception_address
>= wp
->address
&& exception_address
< (wp
->address
+ wp
->length
)) {
1868 *hit_watchpoint
= wp
;
1876 * Cortex-A8 Reset functions
1879 static int aarch64_enable_reset_catch(struct target
*target
, bool enable
)
1881 struct armv8_common
*armv8
= target_to_armv8(target
);
1885 retval
= mem_ap_read_atomic_u32(armv8
->debug_ap
,
1886 armv8
->debug_base
+ CPUV8_DBG_EDECR
, &edecr
);
1887 LOG_DEBUG("EDECR = 0x%08" PRIx32
", enable=%d", edecr
, enable
);
1888 if (retval
!= ERROR_OK
)
1896 return mem_ap_write_atomic_u32(armv8
->debug_ap
,
1897 armv8
->debug_base
+ CPUV8_DBG_EDECR
, edecr
);
1900 static int aarch64_clear_reset_catch(struct target
*target
)
1902 struct armv8_common
*armv8
= target_to_armv8(target
);
1907 /* check if Reset Catch debug event triggered as expected */
1908 retval
= mem_ap_read_atomic_u32(armv8
->debug_ap
,
1909 armv8
->debug_base
+ CPUV8_DBG_EDESR
, &edesr
);
1910 if (retval
!= ERROR_OK
)
1913 was_triggered
= !!(edesr
& ESR_RC
);
1914 LOG_DEBUG("Reset Catch debug event %s",
1915 was_triggered
? "triggered" : "NOT triggered!");
1917 if (was_triggered
) {
1918 /* clear pending Reset Catch debug event */
1920 retval
= mem_ap_write_atomic_u32(armv8
->debug_ap
,
1921 armv8
->debug_base
+ CPUV8_DBG_EDESR
, edesr
);
1922 if (retval
!= ERROR_OK
)
1929 static int aarch64_assert_reset(struct target
*target
)
1931 struct armv8_common
*armv8
= target_to_armv8(target
);
1932 enum reset_types reset_config
= jtag_get_reset_config();
1937 /* Issue some kind of warm reset. */
1938 if (target_has_event_action(target
, TARGET_EVENT_RESET_ASSERT
))
1939 target_handle_event(target
, TARGET_EVENT_RESET_ASSERT
);
1940 else if (reset_config
& RESET_HAS_SRST
) {
1941 bool srst_asserted
= false;
1943 if (target
->reset_halt
) {
1944 if (target_was_examined(target
)) {
1946 if (reset_config
& RESET_SRST_NO_GATING
) {
1948 * SRST needs to be asserted *before* Reset Catch
1949 * debug event can be set up.
1951 adapter_assert_reset();
1952 srst_asserted
= true;
1954 /* make sure to clear all sticky errors */
1955 mem_ap_write_atomic_u32(armv8
->debug_ap
,
1956 armv8
->debug_base
+ CPUV8_DBG_DRCR
, DRCR_CSE
);
1959 /* set up Reset Catch debug event to halt the CPU after reset */
1960 retval
= aarch64_enable_reset_catch(target
, true);
1961 if (retval
!= ERROR_OK
)
1962 LOG_WARNING("%s: Error enabling Reset Catch debug event; the CPU will not halt immediately after reset!",
1963 target_name(target
));
1965 LOG_WARNING("%s: Target not examined, will not halt immediately after reset!",
1966 target_name(target
));
1970 /* REVISIT handle "pulls" cases, if there's
1971 * hardware that needs them to work.
1974 adapter_assert_reset();
1976 LOG_ERROR("%s: how to reset?", target_name(target
));
1980 /* registers are now invalid */
1981 if (target_was_examined(target
)) {
1982 register_cache_invalidate(armv8
->arm
.core_cache
);
1983 register_cache_invalidate(armv8
->arm
.core_cache
->next
);
1986 target
->state
= TARGET_RESET
;
1991 static int aarch64_deassert_reset(struct target
*target
)
1997 /* be certain SRST is off */
1998 adapter_deassert_reset();
2000 if (!target_was_examined(target
))
2003 retval
= aarch64_init_debug_access(target
);
2004 if (retval
!= ERROR_OK
)
2007 retval
= aarch64_poll(target
);
2008 if (retval
!= ERROR_OK
)
2011 if (target
->reset_halt
) {
2012 /* clear pending Reset Catch debug event */
2013 retval
= aarch64_clear_reset_catch(target
);
2014 if (retval
!= ERROR_OK
)
2015 LOG_WARNING("%s: Clearing Reset Catch debug event failed",
2016 target_name(target
));
2018 /* disable Reset Catch debug event */
2019 retval
= aarch64_enable_reset_catch(target
, false);
2020 if (retval
!= ERROR_OK
)
2021 LOG_WARNING("%s: Disabling Reset Catch debug event failed",
2022 target_name(target
));
2024 if (target
->state
!= TARGET_HALTED
) {
2025 LOG_WARNING("%s: ran after reset and before halt ...",
2026 target_name(target
));
2027 retval
= target_halt(target
);
2028 if (retval
!= ERROR_OK
)
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_WARNING("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_WARNING("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 (pc
->adiv5_config
.ap_num
== DP_APSEL_INVALID
) {
2556 /* Search for the APB-AB */
2557 retval
= dap_find_ap(swjdp
, AP_TYPE_APB_AP
, &armv8
->debug_ap
);
2558 if (retval
!= ERROR_OK
) {
2559 LOG_ERROR("Could not find APB-AP for debug access");
2563 armv8
->debug_ap
= dap_ap(swjdp
, pc
->adiv5_config
.ap_num
);
2566 retval
= mem_ap_init(armv8
->debug_ap
);
2567 if (retval
!= ERROR_OK
) {
2568 LOG_ERROR("Could not initialize the APB-AP");
2572 armv8
->debug_ap
->memaccess_tck
= 10;
2574 if (!target
->dbgbase_set
) {
2575 target_addr_t dbgbase
;
2576 /* Get ROM Table base */
2578 int32_t coreidx
= target
->coreid
;
2579 retval
= dap_get_debugbase(armv8
->debug_ap
, &dbgbase
, &apid
);
2580 if (retval
!= ERROR_OK
)
2582 /* Lookup Processor DAP */
2583 retval
= dap_lookup_cs_component(armv8
->debug_ap
, dbgbase
, ARM_CS_C9_DEVTYPE_CORE_DEBUG
,
2584 &armv8
->debug_base
, &coreidx
);
2585 if (retval
!= ERROR_OK
)
2587 LOG_DEBUG("Detected core %" PRId32
" dbgbase: " TARGET_ADDR_FMT
2588 " apid: %08" PRIx32
, coreidx
, armv8
->debug_base
, apid
);
2590 armv8
->debug_base
= target
->dbgbase
;
2592 retval
= mem_ap_write_atomic_u32(armv8
->debug_ap
,
2593 armv8
->debug_base
+ CPUV8_DBG_OSLAR
, 0);
2594 if (retval
!= ERROR_OK
) {
2595 LOG_DEBUG("Examine %s failed", "oslock");
2599 retval
= mem_ap_read_u32(armv8
->debug_ap
,
2600 armv8
->debug_base
+ CPUV8_DBG_MAINID0
, &cpuid
);
2601 if (retval
!= ERROR_OK
) {
2602 LOG_DEBUG("Examine %s failed", "CPUID");
2606 retval
= mem_ap_read_u32(armv8
->debug_ap
,
2607 armv8
->debug_base
+ CPUV8_DBG_MEMFEATURE0
, &tmp0
);
2608 retval
+= mem_ap_read_u32(armv8
->debug_ap
,
2609 armv8
->debug_base
+ CPUV8_DBG_MEMFEATURE0
+ 4, &tmp1
);
2610 if (retval
!= ERROR_OK
) {
2611 LOG_DEBUG("Examine %s failed", "Memory Model Type");
2614 retval
= mem_ap_read_u32(armv8
->debug_ap
,
2615 armv8
->debug_base
+ CPUV8_DBG_DBGFEATURE0
, &tmp2
);
2616 retval
+= mem_ap_read_u32(armv8
->debug_ap
,
2617 armv8
->debug_base
+ CPUV8_DBG_DBGFEATURE0
+ 4, &tmp3
);
2618 if (retval
!= ERROR_OK
) {
2619 LOG_DEBUG("Examine %s failed", "ID_AA64DFR0_EL1");
2623 retval
= dap_run(armv8
->debug_ap
->dap
);
2624 if (retval
!= ERROR_OK
) {
2625 LOG_ERROR("%s: examination failed\n", target_name(target
));
2630 ttypr
= (ttypr
<< 32) | tmp0
;
2632 debug
= (debug
<< 32) | tmp2
;
2634 LOG_DEBUG("cpuid = 0x%08" PRIx32
, cpuid
);
2635 LOG_DEBUG("ttypr = 0x%08" PRIx64
, ttypr
);
2636 LOG_DEBUG("debug = 0x%08" PRIx64
, debug
);
2639 LOG_TARGET_ERROR(target
, "CTI not specified");
2643 armv8
->cti
= pc
->cti
;
2645 retval
= aarch64_dpm_setup(aarch64
, debug
);
2646 if (retval
!= ERROR_OK
)
2649 /* Setup Breakpoint Register Pairs */
2650 aarch64
->brp_num
= (uint32_t)((debug
>> 12) & 0x0F) + 1;
2651 aarch64
->brp_num_context
= (uint32_t)((debug
>> 28) & 0x0F) + 1;
2652 aarch64
->brp_num_available
= aarch64
->brp_num
;
2653 aarch64
->brp_list
= calloc(aarch64
->brp_num
, sizeof(struct aarch64_brp
));
2654 for (i
= 0; i
< aarch64
->brp_num
; i
++) {
2655 aarch64
->brp_list
[i
].used
= 0;
2656 if (i
< (aarch64
->brp_num
-aarch64
->brp_num_context
))
2657 aarch64
->brp_list
[i
].type
= BRP_NORMAL
;
2659 aarch64
->brp_list
[i
].type
= BRP_CONTEXT
;
2660 aarch64
->brp_list
[i
].value
= 0;
2661 aarch64
->brp_list
[i
].control
= 0;
2662 aarch64
->brp_list
[i
].brpn
= i
;
2665 /* Setup Watchpoint Register Pairs */
2666 aarch64
->wp_num
= (uint32_t)((debug
>> 20) & 0x0F) + 1;
2667 aarch64
->wp_num_available
= aarch64
->wp_num
;
2668 aarch64
->wp_list
= calloc(aarch64
->wp_num
, sizeof(struct aarch64_brp
));
2669 for (i
= 0; i
< aarch64
->wp_num
; i
++) {
2670 aarch64
->wp_list
[i
].used
= 0;
2671 aarch64
->wp_list
[i
].type
= BRP_NORMAL
;
2672 aarch64
->wp_list
[i
].value
= 0;
2673 aarch64
->wp_list
[i
].control
= 0;
2674 aarch64
->wp_list
[i
].brpn
= i
;
2677 LOG_DEBUG("Configured %i hw breakpoints, %i watchpoints",
2678 aarch64
->brp_num
, aarch64
->wp_num
);
2680 target
->state
= TARGET_UNKNOWN
;
2681 target
->debug_reason
= DBG_REASON_NOTHALTED
;
2682 aarch64
->isrmasking_mode
= AARCH64_ISRMASK_ON
;
2683 target_set_examined(target
);
2687 static int aarch64_examine(struct target
*target
)
2689 int retval
= ERROR_OK
;
2691 /* don't re-probe hardware after each reset */
2692 if (!target_was_examined(target
))
2693 retval
= aarch64_examine_first(target
);
2695 /* Configure core debug access */
2696 if (retval
== ERROR_OK
)
2697 retval
= aarch64_init_debug_access(target
);
2703 * Cortex-A8 target creation and initialization
2706 static int aarch64_init_target(struct command_context
*cmd_ctx
,
2707 struct target
*target
)
2709 /* examine_first() does a bunch of this */
2710 arm_semihosting_init(target
);
2714 static int aarch64_init_arch_info(struct target
*target
,
2715 struct aarch64_common
*aarch64
, struct adiv5_dap
*dap
)
2717 struct armv8_common
*armv8
= &aarch64
->armv8_common
;
2719 /* Setup struct aarch64_common */
2720 aarch64
->common_magic
= AARCH64_COMMON_MAGIC
;
2721 armv8
->arm
.dap
= dap
;
2723 /* register arch-specific functions */
2724 armv8
->examine_debug_reason
= NULL
;
2725 armv8
->post_debug_entry
= aarch64_post_debug_entry
;
2726 armv8
->pre_restore_context
= NULL
;
2727 armv8
->armv8_mmu
.read_physical_memory
= aarch64_read_phys_memory
;
2729 armv8_init_arch_info(target
, armv8
);
2730 target_register_timer_callback(aarch64_handle_target_request
, 1,
2731 TARGET_TIMER_TYPE_PERIODIC
, target
);
2736 static int aarch64_target_create(struct target
*target
, Jim_Interp
*interp
)
2738 struct aarch64_private_config
*pc
= target
->private_config
;
2739 struct aarch64_common
*aarch64
;
2741 if (adiv5_verify_config(&pc
->adiv5_config
) != ERROR_OK
)
2744 aarch64
= calloc(1, sizeof(struct aarch64_common
));
2746 LOG_ERROR("Out of memory");
2750 return aarch64_init_arch_info(target
, aarch64
, pc
->adiv5_config
.dap
);
2753 static void aarch64_deinit_target(struct target
*target
)
2755 struct aarch64_common
*aarch64
= target_to_aarch64(target
);
2756 struct armv8_common
*armv8
= &aarch64
->armv8_common
;
2757 struct arm_dpm
*dpm
= &armv8
->dpm
;
2759 armv8_free_reg_cache(target
);
2760 free(aarch64
->brp_list
);
2763 free(target
->private_config
);
2767 static int aarch64_mmu(struct target
*target
, int *enabled
)
2769 if (target
->state
!= TARGET_HALTED
) {
2770 LOG_ERROR("%s: target %s not halted", __func__
, target_name(target
));
2771 return ERROR_TARGET_INVALID
;
2774 *enabled
= target_to_aarch64(target
)->armv8_common
.armv8_mmu
.mmu_enabled
;
2778 static int aarch64_virt2phys(struct target
*target
, target_addr_t virt
,
2779 target_addr_t
*phys
)
2781 return armv8_mmu_translate_va_pa(target
, virt
, phys
, 1);
2785 * private target configuration items
2787 enum aarch64_cfg_param
{
2791 static const struct jim_nvp nvp_config_opts
[] = {
2792 { .name
= "-cti", .value
= CFG_CTI
},
2793 { .name
= NULL
, .value
= -1 }
2796 static int aarch64_jim_configure(struct target
*target
, struct jim_getopt_info
*goi
)
2798 struct aarch64_private_config
*pc
;
2802 pc
= (struct aarch64_private_config
*)target
->private_config
;
2804 pc
= calloc(1, sizeof(struct aarch64_private_config
));
2805 pc
->adiv5_config
.ap_num
= DP_APSEL_INVALID
;
2806 target
->private_config
= pc
;
2810 * Call adiv5_jim_configure() to parse the common DAP options
2811 * It will return JIM_CONTINUE if it didn't find any known
2812 * options, JIM_OK if it correctly parsed the topmost option
2813 * and JIM_ERR if an error occurred during parameter evaluation.
2814 * For JIM_CONTINUE, we check our own params.
2816 * adiv5_jim_configure() assumes 'private_config' to point to
2817 * 'struct adiv5_private_config'. Override 'private_config'!
2819 target
->private_config
= &pc
->adiv5_config
;
2820 e
= adiv5_jim_configure(target
, goi
);
2821 target
->private_config
= pc
;
2822 if (e
!= JIM_CONTINUE
)
2825 /* parse config or cget options ... */
2826 if (goi
->argc
> 0) {
2827 Jim_SetEmptyResult(goi
->interp
);
2829 /* check first if topmost item is for us */
2830 e
= jim_nvp_name2value_obj(goi
->interp
, nvp_config_opts
,
2833 return JIM_CONTINUE
;
2835 e
= jim_getopt_obj(goi
, NULL
);
2841 if (goi
->isconfigure
) {
2843 struct arm_cti
*cti
;
2844 e
= jim_getopt_obj(goi
, &o_cti
);
2847 cti
= cti_instance_by_jim_obj(goi
->interp
, o_cti
);
2849 Jim_SetResultString(goi
->interp
, "CTI name invalid!", -1);
2854 if (goi
->argc
!= 0) {
2855 Jim_WrongNumArgs(goi
->interp
,
2856 goi
->argc
, goi
->argv
,
2861 if (!pc
|| !pc
->cti
) {
2862 Jim_SetResultString(goi
->interp
, "CTI not configured", -1);
2865 Jim_SetResultString(goi
->interp
, arm_cti_name(pc
->cti
), -1);
2871 return JIM_CONTINUE
;
2878 COMMAND_HANDLER(aarch64_handle_cache_info_command
)
2880 struct target
*target
= get_current_target(CMD_CTX
);
2881 struct armv8_common
*armv8
= target_to_armv8(target
);
2883 return armv8_handle_cache_info_command(CMD
,
2884 &armv8
->armv8_mmu
.armv8_cache
);
2887 COMMAND_HANDLER(aarch64_handle_dbginit_command
)
2889 struct target
*target
= get_current_target(CMD_CTX
);
2890 if (!target_was_examined(target
)) {
2891 LOG_ERROR("target not examined yet");
2895 return aarch64_init_debug_access(target
);
2898 COMMAND_HANDLER(aarch64_handle_disassemble_command
)
2900 struct target
*target
= get_current_target(CMD_CTX
);
2903 LOG_ERROR("No target selected");
2907 struct aarch64_common
*aarch64
= target_to_aarch64(target
);
2909 if (aarch64
->common_magic
!= AARCH64_COMMON_MAGIC
) {
2910 command_print(CMD
, "current target isn't an AArch64");
2915 target_addr_t address
;
2919 COMMAND_PARSE_NUMBER(int, CMD_ARGV
[1], count
);
2922 COMMAND_PARSE_ADDRESS(CMD_ARGV
[0], address
);
2925 return ERROR_COMMAND_SYNTAX_ERROR
;
2928 return a64_disassemble(CMD
, target
, address
, count
);
2931 COMMAND_HANDLER(aarch64_mask_interrupts_command
)
2933 struct target
*target
= get_current_target(CMD_CTX
);
2934 struct aarch64_common
*aarch64
= target_to_aarch64(target
);
2936 static const struct jim_nvp nvp_maskisr_modes
[] = {
2937 { .name
= "off", .value
= AARCH64_ISRMASK_OFF
},
2938 { .name
= "on", .value
= AARCH64_ISRMASK_ON
},
2939 { .name
= NULL
, .value
= -1 },
2941 const struct jim_nvp
*n
;
2944 n
= jim_nvp_name2value_simple(nvp_maskisr_modes
, CMD_ARGV
[0]);
2946 LOG_ERROR("Unknown parameter: %s - should be off or on", CMD_ARGV
[0]);
2947 return ERROR_COMMAND_SYNTAX_ERROR
;
2950 aarch64
->isrmasking_mode
= n
->value
;
2953 n
= jim_nvp_value2name_simple(nvp_maskisr_modes
, aarch64
->isrmasking_mode
);
2954 command_print(CMD
, "aarch64 interrupt mask %s", n
->name
);
2959 static int jim_mcrmrc(Jim_Interp
*interp
, int argc
, Jim_Obj
* const *argv
)
2961 struct command
*c
= jim_to_command(interp
);
2962 struct command_context
*context
;
2963 struct target
*target
;
2966 bool is_mcr
= false;
2969 if (!strcmp(c
->name
, "mcr")) {
2976 context
= current_command_context(interp
);
2979 target
= get_current_target(context
);
2981 LOG_ERROR("%s: no current target", __func__
);
2984 if (!target_was_examined(target
)) {
2985 LOG_ERROR("%s: not yet examined", target_name(target
));
2989 arm
= target_to_arm(target
);
2991 LOG_ERROR("%s: not an ARM", target_name(target
));
2995 if (target
->state
!= TARGET_HALTED
)
2996 return ERROR_TARGET_NOT_HALTED
;
2998 if (arm
->core_state
== ARM_STATE_AARCH64
) {
2999 LOG_ERROR("%s: not 32-bit arm target", target_name(target
));
3003 if (argc
!= arg_cnt
) {
3004 LOG_ERROR("%s: wrong number of arguments", __func__
);
3016 /* NOTE: parameter sequence matches ARM instruction set usage:
3017 * MCR pNUM, op1, rX, CRn, CRm, op2 ; write CP from rX
3018 * MRC pNUM, op1, rX, CRn, CRm, op2 ; read CP into rX
3019 * The "rX" is necessarily omitted; it uses Tcl mechanisms.
3021 retval
= Jim_GetLong(interp
, argv
[1], &l
);
3022 if (retval
!= JIM_OK
)
3025 LOG_ERROR("%s: %s %d out of range", __func__
,
3026 "coprocessor", (int) l
);
3031 retval
= Jim_GetLong(interp
, argv
[2], &l
);
3032 if (retval
!= JIM_OK
)
3035 LOG_ERROR("%s: %s %d out of range", __func__
,
3041 retval
= Jim_GetLong(interp
, argv
[3], &l
);
3042 if (retval
!= JIM_OK
)
3045 LOG_ERROR("%s: %s %d out of range", __func__
,
3051 retval
= Jim_GetLong(interp
, argv
[4], &l
);
3052 if (retval
!= JIM_OK
)
3055 LOG_ERROR("%s: %s %d out of range", __func__
,
3061 retval
= Jim_GetLong(interp
, argv
[5], &l
);
3062 if (retval
!= JIM_OK
)
3065 LOG_ERROR("%s: %s %d out of range", __func__
,
3073 if (is_mcr
== true) {
3074 retval
= Jim_GetLong(interp
, argv
[6], &l
);
3075 if (retval
!= JIM_OK
)
3079 /* NOTE: parameters reordered! */
3080 /* ARMV4_5_MCR(cpnum, op1, 0, crn, crm, op2) */
3081 retval
= arm
->mcr(target
, cpnum
, op1
, op2
, crn
, crm
, value
);
3082 if (retval
!= ERROR_OK
)
3085 /* NOTE: parameters reordered! */
3086 /* ARMV4_5_MRC(cpnum, op1, 0, crn, crm, op2) */
3087 retval
= arm
->mrc(target
, cpnum
, op1
, op2
, crn
, crm
, &value
);
3088 if (retval
!= ERROR_OK
)
3091 Jim_SetResult(interp
, Jim_NewIntObj(interp
, value
));
3097 static const struct command_registration aarch64_exec_command_handlers
[] = {
3099 .name
= "cache_info",
3100 .handler
= aarch64_handle_cache_info_command
,
3101 .mode
= COMMAND_EXEC
,
3102 .help
= "display information about target caches",
3107 .handler
= aarch64_handle_dbginit_command
,
3108 .mode
= COMMAND_EXEC
,
3109 .help
= "Initialize core debug",
3113 .name
= "disassemble",
3114 .handler
= aarch64_handle_disassemble_command
,
3115 .mode
= COMMAND_EXEC
,
3116 .help
= "Disassemble instructions",
3117 .usage
= "address [count]",
3121 .handler
= aarch64_mask_interrupts_command
,
3122 .mode
= COMMAND_ANY
,
3123 .help
= "mask aarch64 interrupts during single-step",
3124 .usage
= "['on'|'off']",
3128 .mode
= COMMAND_EXEC
,
3129 .jim_handler
= jim_mcrmrc
,
3130 .help
= "write coprocessor register",
3131 .usage
= "cpnum op1 CRn CRm op2 value",
3135 .mode
= COMMAND_EXEC
,
3136 .jim_handler
= jim_mcrmrc
,
3137 .help
= "read coprocessor register",
3138 .usage
= "cpnum op1 CRn CRm op2",
3141 .chain
= smp_command_handlers
,
3145 COMMAND_REGISTRATION_DONE
3148 extern const struct command_registration semihosting_common_handlers
[];
3150 static const struct command_registration aarch64_command_handlers
[] = {
3153 .mode
= COMMAND_ANY
,
3154 .help
= "ARM Command Group",
3156 .chain
= semihosting_common_handlers
3159 .chain
= armv8_command_handlers
,
3163 .mode
= COMMAND_ANY
,
3164 .help
= "Aarch64 command group",
3166 .chain
= aarch64_exec_command_handlers
,
3168 COMMAND_REGISTRATION_DONE
3171 struct target_type aarch64_target
= {
3174 .poll
= aarch64_poll
,
3175 .arch_state
= armv8_arch_state
,
3177 .halt
= aarch64_halt
,
3178 .resume
= aarch64_resume
,
3179 .step
= aarch64_step
,
3181 .assert_reset
= aarch64_assert_reset
,
3182 .deassert_reset
= aarch64_deassert_reset
,
3184 /* REVISIT allow exporting VFP3 registers ... */
3185 .get_gdb_arch
= armv8_get_gdb_arch
,
3186 .get_gdb_reg_list
= armv8_get_gdb_reg_list
,
3188 .read_memory
= aarch64_read_memory
,
3189 .write_memory
= aarch64_write_memory
,
3191 .add_breakpoint
= aarch64_add_breakpoint
,
3192 .add_context_breakpoint
= aarch64_add_context_breakpoint
,
3193 .add_hybrid_breakpoint
= aarch64_add_hybrid_breakpoint
,
3194 .remove_breakpoint
= aarch64_remove_breakpoint
,
3195 .add_watchpoint
= aarch64_add_watchpoint
,
3196 .remove_watchpoint
= aarch64_remove_watchpoint
,
3197 .hit_watchpoint
= aarch64_hit_watchpoint
,
3199 .commands
= aarch64_command_handlers
,
3200 .target_create
= aarch64_target_create
,
3201 .target_jim_configure
= aarch64_jim_configure
,
3202 .init_target
= aarch64_init_target
,
3203 .deinit_target
= aarch64_deinit_target
,
3204 .examine
= aarch64_examine
,
3206 .read_phys_memory
= aarch64_read_phys_memory
,
3207 .write_phys_memory
= aarch64_write_phys_memory
,
3209 .virt2phys
= aarch64_virt2phys
,
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)