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"
27 #include "target_request.h"
28 #include "target_type.h"
29 #include "armv8_opcodes.h"
30 #include <helper/time_support.h>
32 static int aarch64_poll(struct target
*target
);
33 static int aarch64_debug_entry(struct target
*target
);
34 static int aarch64_restore_context(struct target
*target
, bool bpwp
);
35 static int aarch64_set_breakpoint(struct target
*target
,
36 struct breakpoint
*breakpoint
, uint8_t matchmode
);
37 static int aarch64_set_context_breakpoint(struct target
*target
,
38 struct breakpoint
*breakpoint
, uint8_t matchmode
);
39 static int aarch64_set_hybrid_breakpoint(struct target
*target
,
40 struct breakpoint
*breakpoint
);
41 static int aarch64_unset_breakpoint(struct target
*target
,
42 struct breakpoint
*breakpoint
);
43 static int aarch64_mmu(struct target
*target
, int *enabled
);
44 static int aarch64_virt2phys(struct target
*target
,
45 target_addr_t virt
, target_addr_t
*phys
);
46 static int aarch64_read_apb_ap_memory(struct target
*target
,
47 uint64_t address
, uint32_t size
, uint32_t count
, uint8_t *buffer
);
48 static int aarch64_instr_write_data_r0(struct arm_dpm
*dpm
,
49 uint32_t opcode
, uint32_t data
);
51 static int aarch64_restore_system_control_reg(struct target
*target
)
53 int retval
= ERROR_OK
;
55 struct aarch64_common
*aarch64
= target_to_aarch64(target
);
56 struct armv8_common
*armv8
= target_to_armv8(target
);
58 if (aarch64
->system_control_reg
!= aarch64
->system_control_reg_curr
) {
59 aarch64
->system_control_reg_curr
= aarch64
->system_control_reg
;
60 /* LOG_INFO("cp15_control_reg: %8.8" PRIx32, cortex_v8->cp15_control_reg); */
62 switch (armv8
->arm
.core_mode
) {
66 retval
= armv8
->arm
.msr(target
, 3, /*op 0*/
69 aarch64
->system_control_reg
);
70 if (retval
!= ERROR_OK
)
75 retval
= armv8
->arm
.msr(target
, 3, /*op 0*/
78 aarch64
->system_control_reg
);
79 if (retval
!= ERROR_OK
)
84 retval
= armv8
->arm
.msr(target
, 3, /*op 0*/
87 aarch64
->system_control_reg
);
88 if (retval
!= ERROR_OK
)
92 LOG_DEBUG("unknow cpu state 0x%x" PRIx32
, armv8
->arm
.core_state
);
98 /* check address before aarch64_apb read write access with mmu on
99 * remove apb predictible data abort */
100 static int aarch64_check_address(struct target
*target
, uint32_t address
)
105 /* modify system_control_reg in order to enable or disable mmu for :
106 * - virt2phys address conversion
107 * - read or write memory in phys or virt address */
108 static int aarch64_mmu_modify(struct target
*target
, int enable
)
110 struct aarch64_common
*aarch64
= target_to_aarch64(target
);
111 struct armv8_common
*armv8
= &aarch64
->armv8_common
;
112 int retval
= ERROR_OK
;
115 /* if mmu enabled at target stop and mmu not enable */
116 if (!(aarch64
->system_control_reg
& 0x1U
)) {
117 LOG_ERROR("trying to enable mmu on target stopped with mmu disable");
120 if (!(aarch64
->system_control_reg_curr
& 0x1U
)) {
121 aarch64
->system_control_reg_curr
|= 0x1U
;
122 switch (armv8
->arm
.core_mode
) {
126 retval
= armv8
->arm
.msr(target
, 3, /*op 0*/
129 aarch64
->system_control_reg_curr
);
130 if (retval
!= ERROR_OK
)
135 retval
= armv8
->arm
.msr(target
, 3, /*op 0*/
138 aarch64
->system_control_reg_curr
);
139 if (retval
!= ERROR_OK
)
144 retval
= armv8
->arm
.msr(target
, 3, /*op 0*/
147 aarch64
->system_control_reg_curr
);
148 if (retval
!= ERROR_OK
)
152 LOG_DEBUG("unknow cpu state 0x%x" PRIx32
, armv8
->arm
.core_state
);
156 if (aarch64
->system_control_reg_curr
& 0x4U
) {
157 /* data cache is active */
158 aarch64
->system_control_reg_curr
&= ~0x4U
;
159 /* flush data cache armv7 function to be called */
160 if (armv8
->armv8_mmu
.armv8_cache
.flush_all_data_cache
)
161 armv8
->armv8_mmu
.armv8_cache
.flush_all_data_cache(target
);
163 if ((aarch64
->system_control_reg_curr
& 0x1U
)) {
164 aarch64
->system_control_reg_curr
&= ~0x1U
;
165 switch (armv8
->arm
.core_mode
) {
169 retval
= armv8
->arm
.msr(target
, 3, /*op 0*/
172 aarch64
->system_control_reg_curr
);
173 if (retval
!= ERROR_OK
)
178 retval
= armv8
->arm
.msr(target
, 3, /*op 0*/
181 aarch64
->system_control_reg_curr
);
182 if (retval
!= ERROR_OK
)
187 retval
= armv8
->arm
.msr(target
, 3, /*op 0*/
190 aarch64
->system_control_reg_curr
);
191 if (retval
!= ERROR_OK
)
195 LOG_DEBUG("unknow cpu state 0x%x" PRIx32
, armv8
->arm
.core_state
);
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
);
214 /* Unlocking the debug registers for modification
215 * The debugport might be uninitialised so try twice */
216 retval
= mem_ap_write_atomic_u32(armv8
->debug_ap
,
217 armv8
->debug_base
+ CPUV8_DBG_LOCKACCESS
, 0xC5ACCE55);
218 if (retval
!= ERROR_OK
) {
220 retval
= mem_ap_write_atomic_u32(armv8
->debug_ap
,
221 armv8
->debug_base
+ CPUV8_DBG_LOCKACCESS
, 0xC5ACCE55);
222 if (retval
== ERROR_OK
)
223 LOG_USER("Locking debug access failed on first, but succeeded on second try.");
225 if (retval
!= ERROR_OK
)
227 /* Clear Sticky Power Down status Bit in PRSR to enable access to
228 the registers in the Core Power Domain */
229 retval
= mem_ap_read_atomic_u32(armv8
->debug_ap
,
230 armv8
->debug_base
+ CPUV8_DBG_PRSR
, &dummy
);
231 if (retval
!= ERROR_OK
)
234 /* Enabling of instruction execution in debug mode is done in debug_entry code */
236 /* Resync breakpoint registers */
238 /* Since this is likely called from init or reset, update target state information*/
239 return aarch64_poll(target
);
242 /* To reduce needless round-trips, pass in a pointer to the current
243 * DSCR value. Initialize it to zero if you just need to know the
244 * value on return from this function; or DSCR_ITE if you
245 * happen to know that no instruction is pending.
247 static int aarch64_exec_opcode(struct target
*target
,
248 uint32_t opcode
, uint32_t *dscr_p
)
252 struct armv8_common
*armv8
= target_to_armv8(target
);
253 dscr
= dscr_p
? *dscr_p
: 0;
255 LOG_DEBUG("exec opcode 0x%08" PRIx32
, opcode
);
257 /* Wait for InstrCompl bit to be set */
258 long long then
= timeval_ms();
259 while ((dscr
& DSCR_ITE
) == 0) {
260 retval
= mem_ap_read_atomic_u32(armv8
->debug_ap
,
261 armv8
->debug_base
+ CPUV8_DBG_DSCR
, &dscr
);
262 if (retval
!= ERROR_OK
) {
263 LOG_ERROR("Could not read DSCR register, opcode = 0x%08" PRIx32
, opcode
);
266 if (timeval_ms() > then
+ 1000) {
267 LOG_ERROR("Timeout waiting for aarch64_exec_opcode");
272 retval
= mem_ap_write_u32(armv8
->debug_ap
,
273 armv8
->debug_base
+ CPUV8_DBG_ITR
, opcode
);
274 if (retval
!= ERROR_OK
)
279 retval
= mem_ap_read_atomic_u32(armv8
->debug_ap
,
280 armv8
->debug_base
+ CPUV8_DBG_DSCR
, &dscr
);
281 if (retval
!= ERROR_OK
) {
282 LOG_ERROR("Could not read DSCR register");
285 if (timeval_ms() > then
+ 1000) {
286 LOG_ERROR("Timeout waiting for aarch64_exec_opcode");
289 } while ((dscr
& DSCR_ITE
) == 0); /* Wait for InstrCompl bit to be set */
297 /* Write to memory mapped registers directly with no cache or mmu handling */
298 static int aarch64_dap_write_memap_register_u32(struct target
*target
,
303 struct armv8_common
*armv8
= target_to_armv8(target
);
305 retval
= mem_ap_write_atomic_u32(armv8
->debug_ap
, address
, value
);
311 * AARCH64 implementation of Debug Programmer's Model
313 * NOTE the invariant: these routines return with DSCR_ITE set,
314 * so there's no need to poll for it before executing an instruction.
316 * NOTE that in several of these cases the "stall" mode might be useful.
317 * It'd let us queue a few operations together... prepare/finish might
318 * be the places to enable/disable that mode.
321 static inline struct aarch64_common
*dpm_to_a8(struct arm_dpm
*dpm
)
323 return container_of(dpm
, struct aarch64_common
, armv8_common
.dpm
);
326 static int aarch64_write_dcc(struct armv8_common
*armv8
, uint32_t data
)
328 LOG_DEBUG("write DCC 0x%08" PRIx32
, data
);
329 return mem_ap_write_u32(armv8
->debug_ap
,
330 armv8
->debug_base
+ CPUV8_DBG_DTRRX
, data
);
333 static int aarch64_write_dcc_64(struct armv8_common
*armv8
, uint64_t data
)
336 LOG_DEBUG("write DCC Low word0x%08" PRIx32
, (unsigned)data
);
337 LOG_DEBUG("write DCC High word 0x%08" PRIx32
, (unsigned)(data
>> 32));
338 ret
= mem_ap_write_u32(armv8
->debug_ap
,
339 armv8
->debug_base
+ CPUV8_DBG_DTRRX
, data
);
340 ret
+= mem_ap_write_u32(armv8
->debug_ap
,
341 armv8
->debug_base
+ CPUV8_DBG_DTRTX
, data
>> 32);
345 static int aarch64_read_dcc(struct armv8_common
*armv8
, uint32_t *data
,
348 uint32_t dscr
= DSCR_ITE
;
354 /* Wait for DTRRXfull */
355 long long then
= timeval_ms();
356 while ((dscr
& DSCR_DTR_TX_FULL
) == 0) {
357 retval
= mem_ap_read_atomic_u32(armv8
->debug_ap
,
358 armv8
->debug_base
+ CPUV8_DBG_DSCR
,
360 if (retval
!= ERROR_OK
)
362 if (timeval_ms() > then
+ 1000) {
363 LOG_ERROR("Timeout waiting for read dcc");
368 retval
= mem_ap_read_atomic_u32(armv8
->debug_ap
,
369 armv8
->debug_base
+ CPUV8_DBG_DTRTX
,
371 if (retval
!= ERROR_OK
)
373 LOG_DEBUG("read DCC 0x%08" PRIx32
, *data
);
381 static int aarch64_read_dcc_64(struct armv8_common
*armv8
, uint64_t *data
,
384 uint32_t dscr
= DSCR_ITE
;
391 /* Wait for DTRRXfull */
392 long long then
= timeval_ms();
393 while ((dscr
& DSCR_DTR_TX_FULL
) == 0) {
394 retval
= mem_ap_read_atomic_u32(armv8
->debug_ap
,
395 armv8
->debug_base
+ CPUV8_DBG_DSCR
,
397 if (retval
!= ERROR_OK
)
399 if (timeval_ms() > then
+ 1000) {
400 LOG_ERROR("Timeout waiting for read dcc");
405 retval
= mem_ap_read_atomic_u32(armv8
->debug_ap
,
406 armv8
->debug_base
+ CPUV8_DBG_DTRTX
,
408 if (retval
!= ERROR_OK
)
411 retval
= mem_ap_read_atomic_u32(armv8
->debug_ap
,
412 armv8
->debug_base
+ CPUV8_DBG_DTRRX
,
414 if (retval
!= ERROR_OK
)
417 *data
= *(uint32_t *)data
| (uint64_t)higher
<< 32;
418 LOG_DEBUG("read DCC 0x%16.16" PRIx64
, *data
);
426 static int aarch64_dpm_prepare(struct arm_dpm
*dpm
)
428 struct aarch64_common
*a8
= dpm_to_a8(dpm
);
432 /* set up invariant: INSTR_COMP is set after ever DPM operation */
433 long long then
= timeval_ms();
435 retval
= mem_ap_read_atomic_u32(a8
->armv8_common
.debug_ap
,
436 a8
->armv8_common
.debug_base
+ CPUV8_DBG_DSCR
,
438 if (retval
!= ERROR_OK
)
440 if ((dscr
& DSCR_ITE
) != 0)
442 if (timeval_ms() > then
+ 1000) {
443 LOG_ERROR("Timeout waiting for dpm prepare");
448 /* this "should never happen" ... */
449 if (dscr
& DSCR_DTR_RX_FULL
) {
450 LOG_ERROR("DSCR_DTR_RX_FULL, dscr 0x%08" PRIx32
, dscr
);
452 retval
= mem_ap_read_u32(a8
->armv8_common
.debug_ap
,
453 a8
->armv8_common
.debug_base
+ CPUV8_DBG_DTRRX
, &dscr
);
454 if (retval
!= ERROR_OK
)
457 /* Clear sticky error */
458 retval
= mem_ap_write_u32(a8
->armv8_common
.debug_ap
,
459 a8
->armv8_common
.debug_base
+ CPUV8_DBG_DRCR
, DRCR_CSE
);
460 if (retval
!= ERROR_OK
)
467 static int aarch64_dpm_finish(struct arm_dpm
*dpm
)
469 /* REVISIT what could be done here? */
473 static int aarch64_instr_execute(struct arm_dpm
*dpm
,
476 struct aarch64_common
*a8
= dpm_to_a8(dpm
);
477 uint32_t dscr
= DSCR_ITE
;
479 return aarch64_exec_opcode(
480 a8
->armv8_common
.arm
.target
,
485 static int aarch64_instr_write_data_dcc(struct arm_dpm
*dpm
,
486 uint32_t opcode
, uint32_t data
)
488 struct aarch64_common
*a8
= dpm_to_a8(dpm
);
490 uint32_t dscr
= DSCR_ITE
;
492 retval
= aarch64_write_dcc(&a8
->armv8_common
, data
);
493 if (retval
!= ERROR_OK
)
496 return aarch64_exec_opcode(
497 a8
->armv8_common
.arm
.target
,
502 static int aarch64_instr_write_data_dcc_64(struct arm_dpm
*dpm
,
503 uint32_t opcode
, uint64_t data
)
505 struct aarch64_common
*a8
= dpm_to_a8(dpm
);
507 uint32_t dscr
= DSCR_ITE
;
509 retval
= aarch64_write_dcc_64(&a8
->armv8_common
, data
);
510 if (retval
!= ERROR_OK
)
513 return aarch64_exec_opcode(
514 a8
->armv8_common
.arm
.target
,
519 static int aarch64_instr_write_data_r0(struct arm_dpm
*dpm
,
520 uint32_t opcode
, uint32_t data
)
522 struct aarch64_common
*a8
= dpm_to_a8(dpm
);
523 uint32_t dscr
= DSCR_ITE
;
526 retval
= aarch64_write_dcc(&a8
->armv8_common
, data
);
527 if (retval
!= ERROR_OK
)
530 retval
= aarch64_exec_opcode(
531 a8
->armv8_common
.arm
.target
,
532 ARMV8_MRS(SYSTEM_DBG_DTRRX_EL0
, 0),
534 if (retval
!= ERROR_OK
)
537 /* then the opcode, taking data from R0 */
538 retval
= aarch64_exec_opcode(
539 a8
->armv8_common
.arm
.target
,
546 static int aarch64_instr_write_data_r0_64(struct arm_dpm
*dpm
,
547 uint32_t opcode
, uint64_t data
)
549 struct aarch64_common
*a8
= dpm_to_a8(dpm
);
550 uint32_t dscr
= DSCR_ITE
;
553 retval
= aarch64_write_dcc_64(&a8
->armv8_common
, data
);
554 if (retval
!= ERROR_OK
)
557 retval
= aarch64_exec_opcode(
558 a8
->armv8_common
.arm
.target
,
559 ARMV8_MRS(SYSTEM_DBG_DBGDTR_EL0
, 0),
561 if (retval
!= ERROR_OK
)
564 /* then the opcode, taking data from R0 */
565 retval
= aarch64_exec_opcode(
566 a8
->armv8_common
.arm
.target
,
573 static int aarch64_instr_cpsr_sync(struct arm_dpm
*dpm
)
575 struct target
*target
= dpm
->arm
->target
;
576 uint32_t dscr
= DSCR_ITE
;
578 /* "Prefetch flush" after modifying execution status in CPSR */
579 return aarch64_exec_opcode(target
,
584 static int aarch64_instr_read_data_dcc(struct arm_dpm
*dpm
,
585 uint32_t opcode
, uint32_t *data
)
587 struct aarch64_common
*a8
= dpm_to_a8(dpm
);
589 uint32_t dscr
= DSCR_ITE
;
591 /* the opcode, writing data to DCC */
592 retval
= aarch64_exec_opcode(
593 a8
->armv8_common
.arm
.target
,
596 if (retval
!= ERROR_OK
)
599 return aarch64_read_dcc(&a8
->armv8_common
, data
, &dscr
);
602 static int aarch64_instr_read_data_dcc_64(struct arm_dpm
*dpm
,
603 uint32_t opcode
, uint64_t *data
)
605 struct aarch64_common
*a8
= dpm_to_a8(dpm
);
607 uint32_t dscr
= DSCR_ITE
;
609 /* the opcode, writing data to DCC */
610 retval
= aarch64_exec_opcode(
611 a8
->armv8_common
.arm
.target
,
614 if (retval
!= ERROR_OK
)
617 return aarch64_read_dcc_64(&a8
->armv8_common
, data
, &dscr
);
620 static int aarch64_instr_read_data_r0(struct arm_dpm
*dpm
,
621 uint32_t opcode
, uint32_t *data
)
623 struct aarch64_common
*a8
= dpm_to_a8(dpm
);
624 uint32_t dscr
= DSCR_ITE
;
627 /* the opcode, writing data to R0 */
628 retval
= aarch64_exec_opcode(
629 a8
->armv8_common
.arm
.target
,
632 if (retval
!= ERROR_OK
)
635 /* write R0 to DCC */
636 retval
= aarch64_exec_opcode(
637 a8
->armv8_common
.arm
.target
,
638 ARMV8_MSR_GP(SYSTEM_DBG_DTRTX_EL0
, 0), /* msr dbgdtr_el0, x0 */
640 if (retval
!= ERROR_OK
)
643 return aarch64_read_dcc(&a8
->armv8_common
, data
, &dscr
);
646 static int aarch64_instr_read_data_r0_64(struct arm_dpm
*dpm
,
647 uint32_t opcode
, uint64_t *data
)
649 struct aarch64_common
*a8
= dpm_to_a8(dpm
);
650 uint32_t dscr
= DSCR_ITE
;
653 /* the opcode, writing data to R0 */
654 retval
= aarch64_exec_opcode(
655 a8
->armv8_common
.arm
.target
,
658 if (retval
!= ERROR_OK
)
661 /* write R0 to DCC */
662 retval
= aarch64_exec_opcode(
663 a8
->armv8_common
.arm
.target
,
664 ARMV8_MSR_GP(SYSTEM_DBG_DBGDTR_EL0
, 0), /* msr dbgdtr_el0, x0 */
666 if (retval
!= ERROR_OK
)
669 return aarch64_read_dcc_64(&a8
->armv8_common
, data
, &dscr
);
672 static int aarch64_bpwp_enable(struct arm_dpm
*dpm
, unsigned index_t
,
673 uint32_t addr
, uint32_t control
)
675 struct aarch64_common
*a8
= dpm_to_a8(dpm
);
676 uint32_t vr
= a8
->armv8_common
.debug_base
;
677 uint32_t cr
= a8
->armv8_common
.debug_base
;
681 case 0 ... 15: /* breakpoints */
682 vr
+= CPUV8_DBG_BVR_BASE
;
683 cr
+= CPUV8_DBG_BCR_BASE
;
685 case 16 ... 31: /* watchpoints */
686 vr
+= CPUV8_DBG_WVR_BASE
;
687 cr
+= CPUV8_DBG_WCR_BASE
;
696 LOG_DEBUG("A8: bpwp enable, vr %08x cr %08x",
697 (unsigned) vr
, (unsigned) cr
);
699 retval
= aarch64_dap_write_memap_register_u32(dpm
->arm
->target
,
701 if (retval
!= ERROR_OK
)
703 retval
= aarch64_dap_write_memap_register_u32(dpm
->arm
->target
,
708 static int aarch64_bpwp_disable(struct arm_dpm
*dpm
, unsigned index_t
)
710 struct aarch64_common
*a
= dpm_to_a8(dpm
);
715 cr
= a
->armv8_common
.debug_base
+ CPUV8_DBG_BCR_BASE
;
718 cr
= a
->armv8_common
.debug_base
+ CPUV8_DBG_WCR_BASE
;
726 LOG_DEBUG("A: bpwp disable, cr %08x", (unsigned) cr
);
728 /* clear control register */
729 return aarch64_dap_write_memap_register_u32(dpm
->arm
->target
, cr
, 0);
733 static int aarch64_dpm_setup(struct aarch64_common
*a8
, uint64_t debug
)
735 struct arm_dpm
*dpm
= &a8
->armv8_common
.dpm
;
738 dpm
->arm
= &a8
->armv8_common
.arm
;
741 dpm
->prepare
= aarch64_dpm_prepare
;
742 dpm
->finish
= aarch64_dpm_finish
;
744 dpm
->instr_execute
= aarch64_instr_execute
;
745 dpm
->instr_write_data_dcc
= aarch64_instr_write_data_dcc
;
746 dpm
->instr_write_data_dcc_64
= aarch64_instr_write_data_dcc_64
;
747 dpm
->instr_write_data_r0
= aarch64_instr_write_data_r0
;
748 dpm
->instr_write_data_r0_64
= aarch64_instr_write_data_r0_64
;
749 dpm
->instr_cpsr_sync
= aarch64_instr_cpsr_sync
;
751 dpm
->instr_read_data_dcc
= aarch64_instr_read_data_dcc
;
752 dpm
->instr_read_data_dcc_64
= aarch64_instr_read_data_dcc_64
;
753 dpm
->instr_read_data_r0
= aarch64_instr_read_data_r0
;
754 dpm
->instr_read_data_r0_64
= aarch64_instr_read_data_r0_64
;
756 dpm
->arm_reg_current
= armv8_reg_current
;
758 dpm
->bpwp_enable
= aarch64_bpwp_enable
;
759 dpm
->bpwp_disable
= aarch64_bpwp_disable
;
761 retval
= armv8_dpm_setup(dpm
);
762 if (retval
== ERROR_OK
)
763 retval
= armv8_dpm_initialize(dpm
);
767 static struct target
*get_aarch64(struct target
*target
, int32_t coreid
)
769 struct target_list
*head
;
773 while (head
!= (struct target_list
*)NULL
) {
775 if ((curr
->coreid
== coreid
) && (curr
->state
== TARGET_HALTED
))
781 static int aarch64_halt(struct target
*target
);
783 static int aarch64_halt_smp(struct target
*target
)
786 struct target_list
*head
;
789 while (head
!= (struct target_list
*)NULL
) {
791 if ((curr
!= target
) && (curr
->state
!= TARGET_HALTED
))
792 retval
+= aarch64_halt(curr
);
798 static int update_halt_gdb(struct target
*target
)
801 if (target
->gdb_service
&& target
->gdb_service
->core
[0] == -1) {
802 target
->gdb_service
->target
= target
;
803 target
->gdb_service
->core
[0] = target
->coreid
;
804 retval
+= aarch64_halt_smp(target
);
810 * Cortex-A8 Run control
813 static int aarch64_poll(struct target
*target
)
815 int retval
= ERROR_OK
;
817 struct aarch64_common
*aarch64
= target_to_aarch64(target
);
818 struct armv8_common
*armv8
= &aarch64
->armv8_common
;
819 enum target_state prev_target_state
= target
->state
;
820 /* toggle to another core is done by gdb as follow */
821 /* maint packet J core_id */
823 /* the next polling trigger an halt event sent to gdb */
824 if ((target
->state
== TARGET_HALTED
) && (target
->smp
) &&
825 (target
->gdb_service
) &&
826 (target
->gdb_service
->target
== NULL
)) {
827 target
->gdb_service
->target
=
828 get_aarch64(target
, target
->gdb_service
->core
[1]);
829 target_call_event_callbacks(target
, TARGET_EVENT_HALTED
);
832 retval
= mem_ap_read_atomic_u32(armv8
->debug_ap
,
833 armv8
->debug_base
+ CPUV8_DBG_DSCR
, &dscr
);
834 if (retval
!= ERROR_OK
)
836 aarch64
->cpudbg_dscr
= dscr
;
838 if (DSCR_RUN_MODE(dscr
) == 0x3) {
839 if (prev_target_state
!= TARGET_HALTED
) {
840 /* We have a halting debug event */
841 LOG_DEBUG("Target halted");
842 target
->state
= TARGET_HALTED
;
843 if ((prev_target_state
== TARGET_RUNNING
)
844 || (prev_target_state
== TARGET_UNKNOWN
)
845 || (prev_target_state
== TARGET_RESET
)) {
846 retval
= aarch64_debug_entry(target
);
847 if (retval
!= ERROR_OK
)
850 retval
= update_halt_gdb(target
);
851 if (retval
!= ERROR_OK
)
854 target_call_event_callbacks(target
,
855 TARGET_EVENT_HALTED
);
857 if (prev_target_state
== TARGET_DEBUG_RUNNING
) {
860 retval
= aarch64_debug_entry(target
);
861 if (retval
!= ERROR_OK
)
864 retval
= update_halt_gdb(target
);
865 if (retval
!= ERROR_OK
)
869 target_call_event_callbacks(target
,
870 TARGET_EVENT_DEBUG_HALTED
);
874 target
->state
= TARGET_RUNNING
;
879 static int aarch64_halt(struct target
*target
)
881 int retval
= ERROR_OK
;
883 struct armv8_common
*armv8
= target_to_armv8(target
);
886 retval
= mem_ap_write_atomic_u32(armv8
->debug_ap
,
887 armv8
->cti_base
+ CTI_CTR
, 1);
888 if (retval
!= ERROR_OK
)
891 retval
= mem_ap_write_atomic_u32(armv8
->debug_ap
,
892 armv8
->cti_base
+ CTI_GATE
, 3);
893 if (retval
!= ERROR_OK
)
896 retval
= mem_ap_write_atomic_u32(armv8
->debug_ap
,
897 armv8
->cti_base
+ CTI_OUTEN0
, 1);
898 if (retval
!= ERROR_OK
)
901 retval
= mem_ap_write_atomic_u32(armv8
->debug_ap
,
902 armv8
->cti_base
+ CTI_OUTEN1
, 2);
903 if (retval
!= ERROR_OK
)
907 * add HDE in halting debug mode
909 retval
= mem_ap_read_atomic_u32(armv8
->debug_ap
,
910 armv8
->debug_base
+ CPUV8_DBG_DSCR
, &dscr
);
911 if (retval
!= ERROR_OK
)
914 retval
= mem_ap_write_atomic_u32(armv8
->debug_ap
,
915 armv8
->debug_base
+ CPUV8_DBG_DSCR
, dscr
| DSCR_HDE
);
916 if (retval
!= ERROR_OK
)
919 retval
= mem_ap_write_atomic_u32(armv8
->debug_ap
,
920 armv8
->cti_base
+ CTI_APPPULSE
, 1);
921 if (retval
!= ERROR_OK
)
924 retval
= mem_ap_write_atomic_u32(armv8
->debug_ap
,
925 armv8
->cti_base
+ CTI_INACK
, 1);
926 if (retval
!= ERROR_OK
)
930 long long then
= timeval_ms();
932 retval
= mem_ap_read_atomic_u32(armv8
->debug_ap
,
933 armv8
->debug_base
+ CPUV8_DBG_DSCR
, &dscr
);
934 if (retval
!= ERROR_OK
)
936 if ((dscr
& DSCRV8_HALT_MASK
) != 0)
938 if (timeval_ms() > then
+ 1000) {
939 LOG_ERROR("Timeout waiting for halt");
944 target
->debug_reason
= DBG_REASON_DBGRQ
;
949 static int aarch64_internal_restore(struct target
*target
, int current
,
950 uint64_t *address
, int handle_breakpoints
, int debug_execution
)
952 struct armv8_common
*armv8
= target_to_armv8(target
);
953 struct arm
*arm
= &armv8
->arm
;
957 if (!debug_execution
)
958 target_free_all_working_areas(target
);
960 /* current = 1: continue on current pc, otherwise continue at <address> */
961 resume_pc
= buf_get_u64(arm
->pc
->value
, 0, 64);
963 resume_pc
= *address
;
965 *address
= resume_pc
;
967 /* Make sure that the Armv7 gdb thumb fixups does not
968 * kill the return address
970 switch (arm
->core_state
) {
972 resume_pc
&= 0xFFFFFFFC;
974 case ARM_STATE_AARCH64
:
975 resume_pc
&= 0xFFFFFFFFFFFFFFFC;
977 case ARM_STATE_THUMB
:
978 case ARM_STATE_THUMB_EE
:
979 /* When the return address is loaded into PC
980 * bit 0 must be 1 to stay in Thumb state
984 case ARM_STATE_JAZELLE
:
985 LOG_ERROR("How do I resume into Jazelle state??");
988 LOG_DEBUG("resume pc = 0x%16" PRIx64
, resume_pc
);
989 buf_set_u64(arm
->pc
->value
, 0, 64, resume_pc
);
992 dpmv8_modeswitch(&armv8
->dpm
, ARM_MODE_ANY
);
994 /* called it now before restoring context because it uses cpu
995 * register r0 for restoring system control register */
996 retval
= aarch64_restore_system_control_reg(target
);
997 if (retval
!= ERROR_OK
)
999 retval
= aarch64_restore_context(target
, handle_breakpoints
);
1000 if (retval
!= ERROR_OK
)
1002 target
->debug_reason
= DBG_REASON_NOTHALTED
;
1003 target
->state
= TARGET_RUNNING
;
1005 /* registers are now invalid */
1006 register_cache_invalidate(arm
->core_cache
);
1009 /* the front-end may request us not to handle breakpoints */
1010 if (handle_breakpoints
) {
1011 /* Single step past breakpoint at current address */
1012 breakpoint
= breakpoint_find(target
, resume_pc
);
1014 LOG_DEBUG("unset breakpoint at 0x%8.8x", breakpoint
->address
);
1015 cortex_m3_unset_breakpoint(target
, breakpoint
);
1016 cortex_m3_single_step_core(target
);
1017 cortex_m3_set_breakpoint(target
, breakpoint
);
1025 static int aarch64_internal_restart(struct target
*target
)
1027 struct armv8_common
*armv8
= target_to_armv8(target
);
1028 struct arm
*arm
= &armv8
->arm
;
1032 * * Restart core and wait for it to be started. Clear ITRen and sticky
1033 * * exception flags: see ARMv7 ARM, C5.9.
1035 * REVISIT: for single stepping, we probably want to
1036 * disable IRQs by default, with optional override...
1039 retval
= mem_ap_read_atomic_u32(armv8
->debug_ap
,
1040 armv8
->debug_base
+ CPUV8_DBG_DSCR
, &dscr
);
1041 if (retval
!= ERROR_OK
)
1044 if ((dscr
& DSCR_ITE
) == 0)
1045 LOG_ERROR("DSCR InstrCompl must be set before leaving debug!");
1047 retval
= mem_ap_write_atomic_u32(armv8
->debug_ap
,
1048 armv8
->cti_base
+ CTI_APPPULSE
, 2);
1049 if (retval
!= ERROR_OK
)
1052 long long then
= timeval_ms();
1054 retval
= mem_ap_read_atomic_u32(armv8
->debug_ap
,
1055 armv8
->debug_base
+ CPUV8_DBG_DSCR
, &dscr
);
1056 if (retval
!= ERROR_OK
)
1058 if ((dscr
& DSCR_HDE
) != 0)
1060 if (timeval_ms() > then
+ 1000) {
1061 LOG_ERROR("Timeout waiting for resume");
1066 target
->debug_reason
= DBG_REASON_NOTHALTED
;
1067 target
->state
= TARGET_RUNNING
;
1069 /* registers are now invalid */
1070 register_cache_invalidate(arm
->core_cache
);
1075 static int aarch64_restore_smp(struct target
*target
, int handle_breakpoints
)
1078 struct target_list
*head
;
1079 struct target
*curr
;
1081 head
= target
->head
;
1082 while (head
!= (struct target_list
*)NULL
) {
1083 curr
= head
->target
;
1084 if ((curr
!= target
) && (curr
->state
!= TARGET_RUNNING
)) {
1085 /* resume current address , not in step mode */
1086 retval
+= aarch64_internal_restore(curr
, 1, &address
,
1087 handle_breakpoints
, 0);
1088 retval
+= aarch64_internal_restart(curr
);
1096 static int aarch64_resume(struct target
*target
, int current
,
1097 target_addr_t address
, int handle_breakpoints
, int debug_execution
)
1100 uint64_t addr
= address
;
1102 /* dummy resume for smp toggle in order to reduce gdb impact */
1103 if ((target
->smp
) && (target
->gdb_service
->core
[1] != -1)) {
1104 /* simulate a start and halt of target */
1105 target
->gdb_service
->target
= NULL
;
1106 target
->gdb_service
->core
[0] = target
->gdb_service
->core
[1];
1107 /* fake resume at next poll we play the target core[1], see poll*/
1108 target_call_event_callbacks(target
, TARGET_EVENT_RESUMED
);
1111 aarch64_internal_restore(target
, current
, &addr
, handle_breakpoints
,
1114 target
->gdb_service
->core
[0] = -1;
1115 retval
= aarch64_restore_smp(target
, handle_breakpoints
);
1116 if (retval
!= ERROR_OK
)
1119 aarch64_internal_restart(target
);
1121 if (!debug_execution
) {
1122 target
->state
= TARGET_RUNNING
;
1123 target_call_event_callbacks(target
, TARGET_EVENT_RESUMED
);
1124 LOG_DEBUG("target resumed at 0x%" PRIx64
, addr
);
1126 target
->state
= TARGET_DEBUG_RUNNING
;
1127 target_call_event_callbacks(target
, TARGET_EVENT_DEBUG_RESUMED
);
1128 LOG_DEBUG("target debug resumed at 0x%" PRIx64
, addr
);
1134 static int aarch64_debug_entry(struct target
*target
)
1136 int retval
= ERROR_OK
;
1137 struct aarch64_common
*aarch64
= target_to_aarch64(target
);
1138 struct armv8_common
*armv8
= target_to_armv8(target
);
1140 LOG_DEBUG("dscr = 0x%08" PRIx32
, aarch64
->cpudbg_dscr
);
1142 /* REVISIT see A8 TRM 12.11.4 steps 2..3 -- make sure that any
1143 * imprecise data aborts get discarded by issuing a Data
1144 * Synchronization Barrier: ARMV4_5_MCR(15, 0, 0, 7, 10, 4).
1147 /* make sure to clear all sticky errors */
1148 retval
= mem_ap_write_atomic_u32(armv8
->debug_ap
,
1149 armv8
->debug_base
+ CPUV8_DBG_DRCR
, DRCR_CSE
);
1150 if (retval
!= ERROR_OK
)
1153 /* Examine debug reason */
1154 armv8_dpm_report_dscr(&armv8
->dpm
, aarch64
->cpudbg_dscr
);
1156 /* save address of instruction that triggered the watchpoint? */
1157 if (target
->debug_reason
== DBG_REASON_WATCHPOINT
) {
1161 retval
= mem_ap_read_atomic_u32(armv8
->debug_ap
,
1162 armv8
->debug_base
+ CPUV8_DBG_WFAR1
,
1164 if (retval
!= ERROR_OK
)
1167 wfar
= (wfar
<< 32);
1168 retval
= mem_ap_read_atomic_u32(armv8
->debug_ap
,
1169 armv8
->debug_base
+ CPUV8_DBG_WFAR0
,
1171 if (retval
!= ERROR_OK
)
1174 armv8_dpm_report_wfar(&armv8
->dpm
, wfar
);
1177 retval
= armv8_dpm_read_current_registers(&armv8
->dpm
);
1179 if (armv8
->post_debug_entry
) {
1180 retval
= armv8
->post_debug_entry(target
);
1181 if (retval
!= ERROR_OK
)
1188 static int aarch64_post_debug_entry(struct target
*target
)
1190 struct aarch64_common
*aarch64
= target_to_aarch64(target
);
1191 struct armv8_common
*armv8
= &aarch64
->armv8_common
;
1194 mem_ap_write_atomic_u32(armv8
->debug_ap
,
1195 armv8
->debug_base
+ CPUV8_DBG_DRCR
, 1<<2);
1196 switch (armv8
->arm
.core_mode
) {
1200 retval
= armv8
->arm
.mrs(target
, 3, /*op 0*/
1201 0, 0, /* op1, op2 */
1202 1, 0, /* CRn, CRm */
1203 &aarch64
->system_control_reg
);
1204 if (retval
!= ERROR_OK
)
1209 retval
= armv8
->arm
.mrs(target
, 3, /*op 0*/
1210 4, 0, /* op1, op2 */
1211 1, 0, /* CRn, CRm */
1212 &aarch64
->system_control_reg
);
1213 if (retval
!= ERROR_OK
)
1218 retval
= armv8
->arm
.mrs(target
, 3, /*op 0*/
1219 6, 0, /* op1, op2 */
1220 1, 0, /* CRn, CRm */
1221 &aarch64
->system_control_reg
);
1222 if (retval
!= ERROR_OK
)
1226 LOG_DEBUG("unknow cpu state 0x%x" PRIx32
, armv8
->arm
.core_state
);
1228 LOG_DEBUG("System_register: %8.8" PRIx32
, aarch64
->system_control_reg
);
1229 aarch64
->system_control_reg_curr
= aarch64
->system_control_reg
;
1231 if (armv8
->armv8_mmu
.armv8_cache
.ctype
== -1)
1232 armv8_identify_cache(target
);
1234 armv8
->armv8_mmu
.mmu_enabled
=
1235 (aarch64
->system_control_reg
& 0x1U
) ? 1 : 0;
1236 armv8
->armv8_mmu
.armv8_cache
.d_u_cache_enabled
=
1237 (aarch64
->system_control_reg
& 0x4U
) ? 1 : 0;
1238 armv8
->armv8_mmu
.armv8_cache
.i_cache_enabled
=
1239 (aarch64
->system_control_reg
& 0x1000U
) ? 1 : 0;
1240 aarch64
->curr_mode
= armv8
->arm
.core_mode
;
1244 static int aarch64_step(struct target
*target
, int current
, target_addr_t address
,
1245 int handle_breakpoints
)
1247 struct armv8_common
*armv8
= target_to_armv8(target
);
1251 if (target
->state
!= TARGET_HALTED
) {
1252 LOG_WARNING("target not halted");
1253 return ERROR_TARGET_NOT_HALTED
;
1256 retval
= mem_ap_read_atomic_u32(armv8
->debug_ap
,
1257 armv8
->debug_base
+ CPUV8_DBG_EDECR
, &tmp
);
1258 if (retval
!= ERROR_OK
)
1261 retval
= mem_ap_write_atomic_u32(armv8
->debug_ap
,
1262 armv8
->debug_base
+ CPUV8_DBG_EDECR
, (tmp
|0x4));
1263 if (retval
!= ERROR_OK
)
1266 target
->debug_reason
= DBG_REASON_SINGLESTEP
;
1267 retval
= aarch64_resume(target
, 1, address
, 0, 0);
1268 if (retval
!= ERROR_OK
)
1271 long long then
= timeval_ms();
1272 while (target
->state
!= TARGET_HALTED
) {
1273 mem_ap_read_atomic_u32(armv8
->debug_ap
,
1274 armv8
->debug_base
+ CPUV8_DBG_EDESR
, &tmp
);
1275 LOG_DEBUG("DESR = %#x", tmp
);
1276 retval
= aarch64_poll(target
);
1277 if (retval
!= ERROR_OK
)
1279 if (timeval_ms() > then
+ 1000) {
1280 LOG_ERROR("timeout waiting for target halt");
1285 retval
= mem_ap_write_atomic_u32(armv8
->debug_ap
,
1286 armv8
->debug_base
+ CPUV8_DBG_EDECR
, (tmp
&(~0x4)));
1287 if (retval
!= ERROR_OK
)
1290 target_call_event_callbacks(target
, TARGET_EVENT_HALTED
);
1291 if (target
->state
== TARGET_HALTED
)
1292 LOG_DEBUG("target stepped");
1297 static int aarch64_restore_context(struct target
*target
, bool bpwp
)
1299 struct armv8_common
*armv8
= target_to_armv8(target
);
1303 if (armv8
->pre_restore_context
)
1304 armv8
->pre_restore_context(target
);
1306 return armv8_dpm_write_dirty_registers(&armv8
->dpm
, bpwp
);
1311 * Cortex-A8 Breakpoint and watchpoint functions
1314 /* Setup hardware Breakpoint Register Pair */
1315 static int aarch64_set_breakpoint(struct target
*target
,
1316 struct breakpoint
*breakpoint
, uint8_t matchmode
)
1321 uint8_t byte_addr_select
= 0x0F;
1322 struct aarch64_common
*aarch64
= target_to_aarch64(target
);
1323 struct armv8_common
*armv8
= &aarch64
->armv8_common
;
1324 struct aarch64_brp
*brp_list
= aarch64
->brp_list
;
1327 if (breakpoint
->set
) {
1328 LOG_WARNING("breakpoint already set");
1332 if (breakpoint
->type
== BKPT_HARD
) {
1334 while (brp_list
[brp_i
].used
&& (brp_i
< aarch64
->brp_num
))
1336 if (brp_i
>= aarch64
->brp_num
) {
1337 LOG_ERROR("ERROR Can not find free Breakpoint Register Pair");
1338 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1340 breakpoint
->set
= brp_i
+ 1;
1341 if (breakpoint
->length
== 2)
1342 byte_addr_select
= (3 << (breakpoint
->address
& 0x02));
1343 control
= ((matchmode
& 0x7) << 20)
1345 | (byte_addr_select
<< 5)
1347 brp_list
[brp_i
].used
= 1;
1348 brp_list
[brp_i
].value
= breakpoint
->address
& 0xFFFFFFFFFFFFFFFC;
1349 brp_list
[brp_i
].control
= control
;
1350 bpt_value
= brp_list
[brp_i
].value
;
1352 retval
= aarch64_dap_write_memap_register_u32(target
, armv8
->debug_base
1353 + CPUV8_DBG_BVR_BASE
+ 16 * brp_list
[brp_i
].BRPn
,
1354 (uint32_t)(bpt_value
& 0xFFFFFFFF));
1355 if (retval
!= ERROR_OK
)
1357 retval
= aarch64_dap_write_memap_register_u32(target
, armv8
->debug_base
1358 + CPUV8_DBG_BVR_BASE
+ 4 + 16 * brp_list
[brp_i
].BRPn
,
1359 (uint32_t)(bpt_value
>> 32));
1360 if (retval
!= ERROR_OK
)
1363 retval
= aarch64_dap_write_memap_register_u32(target
, armv8
->debug_base
1364 + CPUV8_DBG_BCR_BASE
+ 16 * brp_list
[brp_i
].BRPn
,
1365 brp_list
[brp_i
].control
);
1366 if (retval
!= ERROR_OK
)
1368 LOG_DEBUG("brp %i control 0x%0" PRIx32
" value 0x%" TARGET_PRIxADDR
, brp_i
,
1369 brp_list
[brp_i
].control
,
1370 brp_list
[brp_i
].value
);
1372 } else if (breakpoint
->type
== BKPT_SOFT
) {
1374 buf_set_u32(code
, 0, 32, ARMV8_BKPT(0x11));
1375 retval
= target_read_memory(target
,
1376 breakpoint
->address
& 0xFFFFFFFFFFFFFFFE,
1377 breakpoint
->length
, 1,
1378 breakpoint
->orig_instr
);
1379 if (retval
!= ERROR_OK
)
1381 retval
= target_write_memory(target
,
1382 breakpoint
->address
& 0xFFFFFFFFFFFFFFFE,
1383 breakpoint
->length
, 1, code
);
1384 if (retval
!= ERROR_OK
)
1386 breakpoint
->set
= 0x11; /* Any nice value but 0 */
1389 retval
= mem_ap_read_atomic_u32(armv8
->debug_ap
,
1390 armv8
->debug_base
+ CPUV8_DBG_DSCR
, &dscr
);
1391 /* Ensure that halting debug mode is enable */
1392 dscr
= dscr
| DSCR_HDE
;
1393 retval
= mem_ap_write_atomic_u32(armv8
->debug_ap
,
1394 armv8
->debug_base
+ CPUV8_DBG_DSCR
, dscr
);
1395 if (retval
!= ERROR_OK
) {
1396 LOG_DEBUG("Failed to set DSCR.HDE");
1403 static int aarch64_set_context_breakpoint(struct target
*target
,
1404 struct breakpoint
*breakpoint
, uint8_t matchmode
)
1406 int retval
= ERROR_FAIL
;
1409 uint8_t byte_addr_select
= 0x0F;
1410 struct aarch64_common
*aarch64
= target_to_aarch64(target
);
1411 struct armv8_common
*armv8
= &aarch64
->armv8_common
;
1412 struct aarch64_brp
*brp_list
= aarch64
->brp_list
;
1414 if (breakpoint
->set
) {
1415 LOG_WARNING("breakpoint already set");
1418 /*check available context BRPs*/
1419 while ((brp_list
[brp_i
].used
||
1420 (brp_list
[brp_i
].type
!= BRP_CONTEXT
)) && (brp_i
< aarch64
->brp_num
))
1423 if (brp_i
>= aarch64
->brp_num
) {
1424 LOG_ERROR("ERROR Can not find free Breakpoint Register Pair");
1428 breakpoint
->set
= brp_i
+ 1;
1429 control
= ((matchmode
& 0x7) << 20)
1431 | (byte_addr_select
<< 5)
1433 brp_list
[brp_i
].used
= 1;
1434 brp_list
[brp_i
].value
= (breakpoint
->asid
);
1435 brp_list
[brp_i
].control
= control
;
1436 retval
= aarch64_dap_write_memap_register_u32(target
, armv8
->debug_base
1437 + CPUV8_DBG_BVR_BASE
+ 16 * brp_list
[brp_i
].BRPn
,
1438 brp_list
[brp_i
].value
);
1439 if (retval
!= ERROR_OK
)
1441 retval
= aarch64_dap_write_memap_register_u32(target
, armv8
->debug_base
1442 + CPUV8_DBG_BCR_BASE
+ 16 * brp_list
[brp_i
].BRPn
,
1443 brp_list
[brp_i
].control
);
1444 if (retval
!= ERROR_OK
)
1446 LOG_DEBUG("brp %i control 0x%0" PRIx32
" value 0x%" TARGET_PRIxADDR
, brp_i
,
1447 brp_list
[brp_i
].control
,
1448 brp_list
[brp_i
].value
);
1453 static int aarch64_set_hybrid_breakpoint(struct target
*target
, struct breakpoint
*breakpoint
)
1455 int retval
= ERROR_FAIL
;
1456 int brp_1
= 0; /* holds the contextID pair */
1457 int brp_2
= 0; /* holds the IVA pair */
1458 uint32_t control_CTX
, control_IVA
;
1459 uint8_t CTX_byte_addr_select
= 0x0F;
1460 uint8_t IVA_byte_addr_select
= 0x0F;
1461 uint8_t CTX_machmode
= 0x03;
1462 uint8_t IVA_machmode
= 0x01;
1463 struct aarch64_common
*aarch64
= target_to_aarch64(target
);
1464 struct armv8_common
*armv8
= &aarch64
->armv8_common
;
1465 struct aarch64_brp
*brp_list
= aarch64
->brp_list
;
1467 if (breakpoint
->set
) {
1468 LOG_WARNING("breakpoint already set");
1471 /*check available context BRPs*/
1472 while ((brp_list
[brp_1
].used
||
1473 (brp_list
[brp_1
].type
!= BRP_CONTEXT
)) && (brp_1
< aarch64
->brp_num
))
1476 printf("brp(CTX) found num: %d\n", brp_1
);
1477 if (brp_1
>= aarch64
->brp_num
) {
1478 LOG_ERROR("ERROR Can not find free Breakpoint Register Pair");
1482 while ((brp_list
[brp_2
].used
||
1483 (brp_list
[brp_2
].type
!= BRP_NORMAL
)) && (brp_2
< aarch64
->brp_num
))
1486 printf("brp(IVA) found num: %d\n", brp_2
);
1487 if (brp_2
>= aarch64
->brp_num
) {
1488 LOG_ERROR("ERROR Can not find free Breakpoint Register Pair");
1492 breakpoint
->set
= brp_1
+ 1;
1493 breakpoint
->linked_BRP
= brp_2
;
1494 control_CTX
= ((CTX_machmode
& 0x7) << 20)
1497 | (CTX_byte_addr_select
<< 5)
1499 brp_list
[brp_1
].used
= 1;
1500 brp_list
[brp_1
].value
= (breakpoint
->asid
);
1501 brp_list
[brp_1
].control
= control_CTX
;
1502 retval
= aarch64_dap_write_memap_register_u32(target
, armv8
->debug_base
1503 + CPUV8_DBG_BVR_BASE
+ 16 * brp_list
[brp_1
].BRPn
,
1504 brp_list
[brp_1
].value
);
1505 if (retval
!= ERROR_OK
)
1507 retval
= aarch64_dap_write_memap_register_u32(target
, armv8
->debug_base
1508 + CPUV8_DBG_BCR_BASE
+ 16 * brp_list
[brp_1
].BRPn
,
1509 brp_list
[brp_1
].control
);
1510 if (retval
!= ERROR_OK
)
1513 control_IVA
= ((IVA_machmode
& 0x7) << 20)
1516 | (IVA_byte_addr_select
<< 5)
1518 brp_list
[brp_2
].used
= 1;
1519 brp_list
[brp_2
].value
= breakpoint
->address
& 0xFFFFFFFFFFFFFFFC;
1520 brp_list
[brp_2
].control
= control_IVA
;
1521 retval
= aarch64_dap_write_memap_register_u32(target
, armv8
->debug_base
1522 + CPUV8_DBG_BVR_BASE
+ 16 * brp_list
[brp_2
].BRPn
,
1523 brp_list
[brp_2
].value
& 0xFFFFFFFF);
1524 if (retval
!= ERROR_OK
)
1526 retval
= aarch64_dap_write_memap_register_u32(target
, armv8
->debug_base
1527 + CPUV8_DBG_BVR_BASE
+ 4 + 16 * brp_list
[brp_2
].BRPn
,
1528 brp_list
[brp_2
].value
>> 32);
1529 if (retval
!= ERROR_OK
)
1531 retval
= aarch64_dap_write_memap_register_u32(target
, armv8
->debug_base
1532 + CPUV8_DBG_BCR_BASE
+ 16 * brp_list
[brp_2
].BRPn
,
1533 brp_list
[brp_2
].control
);
1534 if (retval
!= ERROR_OK
)
1540 static int aarch64_unset_breakpoint(struct target
*target
, struct breakpoint
*breakpoint
)
1543 struct aarch64_common
*aarch64
= target_to_aarch64(target
);
1544 struct armv8_common
*armv8
= &aarch64
->armv8_common
;
1545 struct aarch64_brp
*brp_list
= aarch64
->brp_list
;
1547 if (!breakpoint
->set
) {
1548 LOG_WARNING("breakpoint not set");
1552 if (breakpoint
->type
== BKPT_HARD
) {
1553 if ((breakpoint
->address
!= 0) && (breakpoint
->asid
!= 0)) {
1554 int brp_i
= breakpoint
->set
- 1;
1555 int brp_j
= breakpoint
->linked_BRP
;
1556 if ((brp_i
< 0) || (brp_i
>= aarch64
->brp_num
)) {
1557 LOG_DEBUG("Invalid BRP number in breakpoint");
1560 LOG_DEBUG("rbp %i control 0x%0" PRIx32
" value 0x%" TARGET_PRIxADDR
, brp_i
,
1561 brp_list
[brp_i
].control
, brp_list
[brp_i
].value
);
1562 brp_list
[brp_i
].used
= 0;
1563 brp_list
[brp_i
].value
= 0;
1564 brp_list
[brp_i
].control
= 0;
1565 retval
= aarch64_dap_write_memap_register_u32(target
, armv8
->debug_base
1566 + CPUV8_DBG_BCR_BASE
+ 16 * brp_list
[brp_i
].BRPn
,
1567 brp_list
[brp_i
].control
);
1568 if (retval
!= ERROR_OK
)
1570 retval
= aarch64_dap_write_memap_register_u32(target
, armv8
->debug_base
1571 + CPUV8_DBG_BVR_BASE
+ 16 * brp_list
[brp_i
].BRPn
,
1572 (uint32_t)brp_list
[brp_i
].value
);
1573 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 if ((brp_j
< 0) || (brp_j
>= aarch64
->brp_num
)) {
1581 LOG_DEBUG("Invalid BRP number in breakpoint");
1584 LOG_DEBUG("rbp %i control 0x%0" PRIx32
" value 0x%0" PRIx64
, brp_j
,
1585 brp_list
[brp_j
].control
, brp_list
[brp_j
].value
);
1586 brp_list
[brp_j
].used
= 0;
1587 brp_list
[brp_j
].value
= 0;
1588 brp_list
[brp_j
].control
= 0;
1589 retval
= aarch64_dap_write_memap_register_u32(target
, armv8
->debug_base
1590 + CPUV8_DBG_BCR_BASE
+ 16 * brp_list
[brp_j
].BRPn
,
1591 brp_list
[brp_j
].control
);
1592 if (retval
!= ERROR_OK
)
1594 retval
= aarch64_dap_write_memap_register_u32(target
, armv8
->debug_base
1595 + CPUV8_DBG_BVR_BASE
+ 16 * brp_list
[brp_j
].BRPn
,
1596 (uint32_t)brp_list
[brp_j
].value
);
1597 if (retval
!= ERROR_OK
)
1599 retval
= aarch64_dap_write_memap_register_u32(target
, armv8
->debug_base
1600 + CPUV8_DBG_BVR_BASE
+ 4 + 16 * brp_list
[brp_j
].BRPn
,
1601 (uint32_t)brp_list
[brp_j
].value
);
1602 if (retval
!= ERROR_OK
)
1605 breakpoint
->linked_BRP
= 0;
1606 breakpoint
->set
= 0;
1610 int brp_i
= breakpoint
->set
- 1;
1611 if ((brp_i
< 0) || (brp_i
>= aarch64
->brp_num
)) {
1612 LOG_DEBUG("Invalid BRP number in breakpoint");
1615 LOG_DEBUG("rbp %i control 0x%0" PRIx32
" value 0x%0" PRIx64
, brp_i
,
1616 brp_list
[brp_i
].control
, brp_list
[brp_i
].value
);
1617 brp_list
[brp_i
].used
= 0;
1618 brp_list
[brp_i
].value
= 0;
1619 brp_list
[brp_i
].control
= 0;
1620 retval
= aarch64_dap_write_memap_register_u32(target
, armv8
->debug_base
1621 + CPUV8_DBG_BCR_BASE
+ 16 * brp_list
[brp_i
].BRPn
,
1622 brp_list
[brp_i
].control
);
1623 if (retval
!= ERROR_OK
)
1625 retval
= aarch64_dap_write_memap_register_u32(target
, armv8
->debug_base
1626 + CPUV8_DBG_BVR_BASE
+ 16 * brp_list
[brp_i
].BRPn
,
1627 brp_list
[brp_i
].value
);
1628 if (retval
!= ERROR_OK
)
1631 retval
= aarch64_dap_write_memap_register_u32(target
, armv8
->debug_base
1632 + CPUV8_DBG_BVR_BASE
+ 4 + 16 * brp_list
[brp_i
].BRPn
,
1633 (uint32_t)brp_list
[brp_i
].value
);
1634 if (retval
!= ERROR_OK
)
1636 breakpoint
->set
= 0;
1640 /* restore original instruction (kept in target endianness) */
1641 if (breakpoint
->length
== 4) {
1642 retval
= target_write_memory(target
,
1643 breakpoint
->address
& 0xFFFFFFFFFFFFFFFE,
1644 4, 1, breakpoint
->orig_instr
);
1645 if (retval
!= ERROR_OK
)
1648 retval
= target_write_memory(target
,
1649 breakpoint
->address
& 0xFFFFFFFFFFFFFFFE,
1650 2, 1, breakpoint
->orig_instr
);
1651 if (retval
!= ERROR_OK
)
1655 breakpoint
->set
= 0;
1660 static int aarch64_add_breakpoint(struct target
*target
,
1661 struct breakpoint
*breakpoint
)
1663 struct aarch64_common
*aarch64
= target_to_aarch64(target
);
1665 if ((breakpoint
->type
== BKPT_HARD
) && (aarch64
->brp_num_available
< 1)) {
1666 LOG_INFO("no hardware breakpoint available");
1667 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1670 if (breakpoint
->type
== BKPT_HARD
)
1671 aarch64
->brp_num_available
--;
1673 return aarch64_set_breakpoint(target
, breakpoint
, 0x00); /* Exact match */
1676 static int aarch64_add_context_breakpoint(struct target
*target
,
1677 struct breakpoint
*breakpoint
)
1679 struct aarch64_common
*aarch64
= target_to_aarch64(target
);
1681 if ((breakpoint
->type
== BKPT_HARD
) && (aarch64
->brp_num_available
< 1)) {
1682 LOG_INFO("no hardware breakpoint available");
1683 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1686 if (breakpoint
->type
== BKPT_HARD
)
1687 aarch64
->brp_num_available
--;
1689 return aarch64_set_context_breakpoint(target
, breakpoint
, 0x02); /* asid match */
1692 static int aarch64_add_hybrid_breakpoint(struct target
*target
,
1693 struct breakpoint
*breakpoint
)
1695 struct aarch64_common
*aarch64
= target_to_aarch64(target
);
1697 if ((breakpoint
->type
== BKPT_HARD
) && (aarch64
->brp_num_available
< 1)) {
1698 LOG_INFO("no hardware breakpoint available");
1699 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1702 if (breakpoint
->type
== BKPT_HARD
)
1703 aarch64
->brp_num_available
--;
1705 return aarch64_set_hybrid_breakpoint(target
, breakpoint
); /* ??? */
1709 static int aarch64_remove_breakpoint(struct target
*target
, struct breakpoint
*breakpoint
)
1711 struct aarch64_common
*aarch64
= target_to_aarch64(target
);
1714 /* It is perfectly possible to remove breakpoints while the target is running */
1715 if (target
->state
!= TARGET_HALTED
) {
1716 LOG_WARNING("target not halted");
1717 return ERROR_TARGET_NOT_HALTED
;
1721 if (breakpoint
->set
) {
1722 aarch64_unset_breakpoint(target
, breakpoint
);
1723 if (breakpoint
->type
== BKPT_HARD
)
1724 aarch64
->brp_num_available
++;
1731 * Cortex-A8 Reset functions
1734 static int aarch64_assert_reset(struct target
*target
)
1736 struct armv8_common
*armv8
= target_to_armv8(target
);
1740 /* FIXME when halt is requested, make it work somehow... */
1742 /* Issue some kind of warm reset. */
1743 if (target_has_event_action(target
, TARGET_EVENT_RESET_ASSERT
))
1744 target_handle_event(target
, TARGET_EVENT_RESET_ASSERT
);
1745 else if (jtag_get_reset_config() & RESET_HAS_SRST
) {
1746 /* REVISIT handle "pulls" cases, if there's
1747 * hardware that needs them to work.
1749 jtag_add_reset(0, 1);
1751 LOG_ERROR("%s: how to reset?", target_name(target
));
1755 /* registers are now invalid */
1756 register_cache_invalidate(armv8
->arm
.core_cache
);
1758 target
->state
= TARGET_RESET
;
1763 static int aarch64_deassert_reset(struct target
*target
)
1769 /* be certain SRST is off */
1770 jtag_add_reset(0, 0);
1772 retval
= aarch64_poll(target
);
1773 if (retval
!= ERROR_OK
)
1776 if (target
->reset_halt
) {
1777 if (target
->state
!= TARGET_HALTED
) {
1778 LOG_WARNING("%s: ran after reset and before halt ...",
1779 target_name(target
));
1780 retval
= target_halt(target
);
1781 if (retval
!= ERROR_OK
)
1789 static int aarch64_write_apb_ap_memory(struct target
*target
,
1790 uint64_t address
, uint32_t size
,
1791 uint32_t count
, const uint8_t *buffer
)
1793 /* write memory through APB-AP */
1794 int retval
= ERROR_COMMAND_SYNTAX_ERROR
;
1795 struct armv8_common
*armv8
= target_to_armv8(target
);
1796 struct arm
*arm
= &armv8
->arm
;
1797 int total_bytes
= count
* size
;
1799 int start_byte
= address
& 0x3;
1800 int end_byte
= (address
+ total_bytes
) & 0x3;
1803 uint8_t *tmp_buff
= NULL
;
1805 LOG_DEBUG("Writing APB-AP memory address 0x%" PRIx64
" size %" PRIu32
" count%" PRIu32
,
1806 address
, size
, count
);
1807 if (target
->state
!= TARGET_HALTED
) {
1808 LOG_WARNING("target not halted");
1809 return ERROR_TARGET_NOT_HALTED
;
1812 total_u32
= DIV_ROUND_UP((address
& 3) + total_bytes
, 4);
1814 /* Mark register R0 as dirty, as it will be used
1815 * for transferring the data.
1816 * It will be restored automatically when exiting
1819 reg
= armv8_reg_current(arm
, 1);
1822 reg
= armv8_reg_current(arm
, 0);
1825 /* clear any abort */
1826 retval
= mem_ap_write_atomic_u32(armv8
->debug_ap
,
1827 armv8
->debug_base
+ CPUV8_DBG_DRCR
, DRCR_CSE
);
1828 if (retval
!= ERROR_OK
)
1832 /* This algorithm comes from DDI0487A.g, chapter J9.1 */
1834 /* The algorithm only copies 32 bit words, so the buffer
1835 * should be expanded to include the words at either end.
1836 * The first and last words will be read first to avoid
1837 * corruption if needed.
1839 tmp_buff
= malloc(total_u32
* 4);
1841 if ((start_byte
!= 0) && (total_u32
> 1)) {
1842 /* First bytes not aligned - read the 32 bit word to avoid corrupting
1843 * the other bytes in the word.
1845 retval
= aarch64_read_apb_ap_memory(target
, (address
& ~0x3), 4, 1, tmp_buff
);
1846 if (retval
!= ERROR_OK
)
1847 goto error_free_buff_w
;
1850 /* If end of write is not aligned, or the write is less than 4 bytes */
1851 if ((end_byte
!= 0) ||
1852 ((total_u32
== 1) && (total_bytes
!= 4))) {
1854 /* Read the last word to avoid corruption during 32 bit write */
1855 int mem_offset
= (total_u32
-1) * 4;
1856 retval
= aarch64_read_apb_ap_memory(target
, (address
& ~0x3) + mem_offset
, 4, 1, &tmp_buff
[mem_offset
]);
1857 if (retval
!= ERROR_OK
)
1858 goto error_free_buff_w
;
1861 /* Copy the write buffer over the top of the temporary buffer */
1862 memcpy(&tmp_buff
[start_byte
], buffer
, total_bytes
);
1864 /* We now have a 32 bit aligned buffer that can be written */
1867 retval
= mem_ap_read_atomic_u32(armv8
->debug_ap
,
1868 armv8
->debug_base
+ CPUV8_DBG_DSCR
, &dscr
);
1869 if (retval
!= ERROR_OK
)
1870 goto error_free_buff_w
;
1872 /* Set Normal access mode */
1873 dscr
= (dscr
& ~DSCR_MA
);
1874 retval
= mem_ap_write_atomic_u32(armv8
->debug_ap
,
1875 armv8
->debug_base
+ CPUV8_DBG_DSCR
, dscr
);
1877 if (arm
->core_state
== ARM_STATE_AARCH64
) {
1878 /* Write X0 with value 'address' using write procedure */
1879 /* Step 1.a+b - Write the address for read access into DBGDTR_EL0 */
1880 retval
+= aarch64_write_dcc_64(armv8
, address
& ~0x3ULL
);
1881 /* Step 1.c - Copy value from DTR to R0 using instruction mrs DBGDTR_EL0, x0 */
1882 retval
+= aarch64_exec_opcode(target
,
1883 ARMV8_MRS(SYSTEM_DBG_DBGDTR_EL0
, 0), &dscr
);
1885 /* Write R0 with value 'address' using write procedure */
1886 /* Step 1.a+b - Write the address for read access into DBGDTRRX */
1887 retval
+= aarch64_write_dcc(armv8
, address
& ~0x3ULL
);
1888 /* Step 1.c - Copy value from DTR to R0 using instruction mrc DBGDTRTXint, r0 */
1889 retval
+= aarch64_exec_opcode(target
,
1890 T32_FMTITR(ARMV4_5_MRC(14, 0, 0, 0, 5, 0)), &dscr
);
1893 /* Step 1.d - Change DCC to memory mode */
1894 dscr
= dscr
| DSCR_MA
;
1895 retval
+= mem_ap_write_atomic_u32(armv8
->debug_ap
,
1896 armv8
->debug_base
+ CPUV8_DBG_DSCR
, dscr
);
1897 if (retval
!= ERROR_OK
)
1898 goto error_unset_dtr_w
;
1901 /* Step 2.a - Do the write */
1902 retval
= mem_ap_write_buf_noincr(armv8
->debug_ap
,
1903 tmp_buff
, 4, total_u32
, armv8
->debug_base
+ CPUV8_DBG_DTRRX
);
1904 if (retval
!= ERROR_OK
)
1905 goto error_unset_dtr_w
;
1907 /* Step 3.a - Switch DTR mode back to Normal mode */
1908 dscr
= (dscr
& ~DSCR_MA
);
1909 retval
= mem_ap_write_atomic_u32(armv8
->debug_ap
,
1910 armv8
->debug_base
+ CPUV8_DBG_DSCR
, dscr
);
1911 if (retval
!= ERROR_OK
)
1912 goto error_unset_dtr_w
;
1914 /* Check for sticky abort flags in the DSCR */
1915 retval
= mem_ap_read_atomic_u32(armv8
->debug_ap
,
1916 armv8
->debug_base
+ CPUV8_DBG_DSCR
, &dscr
);
1917 if (retval
!= ERROR_OK
)
1918 goto error_free_buff_w
;
1919 if (dscr
& (DSCR_ERR
| DSCR_SYS_ERROR_PEND
)) {
1920 /* Abort occurred - clear it and exit */
1921 LOG_ERROR("abort occurred - dscr = 0x%08" PRIx32
, dscr
);
1922 mem_ap_write_atomic_u32(armv8
->debug_ap
,
1923 armv8
->debug_base
+ CPUV8_DBG_DRCR
, 1<<2);
1924 goto error_free_buff_w
;
1932 /* Unset DTR mode */
1933 mem_ap_read_atomic_u32(armv8
->debug_ap
,
1934 armv8
->debug_base
+ CPUV8_DBG_DSCR
, &dscr
);
1935 dscr
= (dscr
& ~DSCR_MA
);
1936 mem_ap_write_atomic_u32(armv8
->debug_ap
,
1937 armv8
->debug_base
+ CPUV8_DBG_DSCR
, dscr
);
1944 static int aarch64_read_apb_ap_memory(struct target
*target
,
1945 target_addr_t address
, uint32_t size
,
1946 uint32_t count
, uint8_t *buffer
)
1948 /* read memory through APB-AP */
1949 int retval
= ERROR_COMMAND_SYNTAX_ERROR
;
1950 struct armv8_common
*armv8
= target_to_armv8(target
);
1951 struct arm
*arm
= &armv8
->arm
;
1952 int total_bytes
= count
* size
;
1954 int start_byte
= address
& 0x3;
1955 int end_byte
= (address
+ total_bytes
) & 0x3;
1958 uint8_t *tmp_buff
= NULL
;
1962 LOG_DEBUG("Reading APB-AP memory address 0x%" TARGET_PRIxADDR
" size %" PRIu32
" count%" PRIu32
,
1963 address
, size
, count
);
1964 if (target
->state
!= TARGET_HALTED
) {
1965 LOG_WARNING("target not halted");
1966 return ERROR_TARGET_NOT_HALTED
;
1969 total_u32
= DIV_ROUND_UP((address
& 3) + total_bytes
, 4);
1970 /* Mark register X0, X1 as dirty, as it will be used
1971 * for transferring the data.
1972 * It will be restored automatically when exiting
1975 reg
= armv8_reg_current(arm
, 1);
1978 reg
= armv8_reg_current(arm
, 0);
1981 /* clear any abort */
1982 retval
= mem_ap_write_atomic_u32(armv8
->debug_ap
,
1983 armv8
->debug_base
+ CPUV8_DBG_DRCR
, DRCR_CSE
);
1984 if (retval
!= ERROR_OK
)
1985 goto error_free_buff_r
;
1988 retval
= mem_ap_read_atomic_u32(armv8
->debug_ap
,
1989 armv8
->debug_base
+ CPUV8_DBG_DSCR
, &dscr
);
1991 /* This algorithm comes from DDI0487A.g, chapter J9.1 */
1993 /* Set Normal access mode */
1994 dscr
= (dscr
& ~DSCR_MA
);
1995 retval
+= mem_ap_write_atomic_u32(armv8
->debug_ap
,
1996 armv8
->debug_base
+ CPUV8_DBG_DSCR
, dscr
);
1998 if (arm
->core_state
== ARM_STATE_AARCH64
) {
1999 /* Write X0 with value 'address' using write procedure */
2000 /* Step 1.a+b - Write the address for read access into DBGDTR_EL0 */
2001 retval
+= aarch64_write_dcc_64(armv8
, address
& ~0x3ULL
);
2002 /* Step 1.c - Copy value from DTR to R0 using instruction mrs DBGDTR_EL0, x0 */
2003 retval
+= aarch64_exec_opcode(target
, ARMV8_MRS(SYSTEM_DBG_DBGDTR_EL0
, 0), &dscr
);
2004 /* Step 1.d - Dummy operation to ensure EDSCR.Txfull == 1 */
2005 retval
+= aarch64_exec_opcode(target
, ARMV8_MSR_GP(SYSTEM_DBG_DBGDTR_EL0
, 0), &dscr
);
2006 /* Step 1.e - Change DCC to memory mode */
2007 dscr
= dscr
| DSCR_MA
;
2008 retval
+= mem_ap_write_atomic_u32(armv8
->debug_ap
,
2009 armv8
->debug_base
+ CPUV8_DBG_DSCR
, dscr
);
2010 /* Step 1.f - read DBGDTRTX and discard the value */
2011 retval
+= mem_ap_read_atomic_u32(armv8
->debug_ap
,
2012 armv8
->debug_base
+ CPUV8_DBG_DTRTX
, &value
);
2014 /* Write R0 with value 'address' using write procedure */
2015 /* Step 1.a+b - Write the address for read access into DBGDTRRXint */
2016 retval
+= aarch64_write_dcc(armv8
, address
& ~0x3ULL
);
2017 /* Step 1.c - Copy value from DTR to R0 using instruction mrc DBGDTRTXint, r0 */
2018 retval
+= aarch64_exec_opcode(target
,
2019 T32_FMTITR(ARMV4_5_MRC(14, 0, 0, 0, 5, 0)), &dscr
);
2020 /* Step 1.d - Dummy operation to ensure EDSCR.Txfull == 1 */
2021 retval
+= aarch64_exec_opcode(target
,
2022 T32_FMTITR(ARMV4_5_MCR(14, 0, 0, 0, 5, 0)), &dscr
);
2023 /* Step 1.e - Change DCC to memory mode */
2024 dscr
= dscr
| DSCR_MA
;
2025 retval
+= mem_ap_write_atomic_u32(armv8
->debug_ap
,
2026 armv8
->debug_base
+ CPUV8_DBG_DSCR
, dscr
);
2027 /* Step 1.f - read DBGDTRTX and discard the value */
2028 retval
+= mem_ap_read_atomic_u32(armv8
->debug_ap
,
2029 armv8
->debug_base
+ CPUV8_DBG_DTRTX
, &value
);
2032 if (retval
!= ERROR_OK
)
2033 goto error_unset_dtr_r
;
2035 /* Optimize the read as much as we can, either way we read in a single pass */
2036 if ((start_byte
) || (end_byte
)) {
2037 /* The algorithm only copies 32 bit words, so the buffer
2038 * should be expanded to include the words at either end.
2039 * The first and last words will be read into a temp buffer
2040 * to avoid corruption
2042 tmp_buff
= malloc(total_u32
* 4);
2044 goto error_unset_dtr_r
;
2046 /* use the tmp buffer to read the entire data */
2047 u8buf_ptr
= tmp_buff
;
2049 /* address and read length are aligned so read directly into the passed buffer */
2052 /* Read the data - Each read of the DTRTX register causes the instruction to be reissued
2053 * Abort flags are sticky, so can be read at end of transactions
2055 * This data is read in aligned to 32 bit boundary.
2058 /* Step 2.a - Loop n-1 times, each read of DBGDTRTX reads the data from [X0] and
2059 * increments X0 by 4. */
2060 retval
= mem_ap_read_buf_noincr(armv8
->debug_ap
, u8buf_ptr
, 4, total_u32
-1,
2061 armv8
->debug_base
+ CPUV8_DBG_DTRTX
);
2062 if (retval
!= ERROR_OK
)
2063 goto error_unset_dtr_r
;
2065 /* Step 3.a - set DTR access mode back to Normal mode */
2066 dscr
= (dscr
& ~DSCR_MA
);
2067 retval
= mem_ap_write_atomic_u32(armv8
->debug_ap
,
2068 armv8
->debug_base
+ CPUV8_DBG_DSCR
, dscr
);
2069 if (retval
!= ERROR_OK
)
2070 goto error_free_buff_r
;
2072 /* Step 3.b - read DBGDTRTX for the final value */
2073 retval
= mem_ap_read_atomic_u32(armv8
->debug_ap
,
2074 armv8
->debug_base
+ CPUV8_DBG_DTRTX
, &value
);
2075 memcpy(u8buf_ptr
+ (total_u32
-1) * 4, &value
, 4);
2077 /* Check for sticky abort flags in the DSCR */
2078 retval
= mem_ap_read_atomic_u32(armv8
->debug_ap
,
2079 armv8
->debug_base
+ CPUV8_DBG_DSCR
, &dscr
);
2080 if (retval
!= ERROR_OK
)
2081 goto error_free_buff_r
;
2082 if (dscr
& (DSCR_ERR
| DSCR_SYS_ERROR_PEND
)) {
2083 /* Abort occurred - clear it and exit */
2084 LOG_ERROR("abort occurred - dscr = 0x%08" PRIx32
, dscr
);
2085 mem_ap_write_atomic_u32(armv8
->debug_ap
,
2086 armv8
->debug_base
+ CPUV8_DBG_DRCR
, DRCR_CSE
);
2087 goto error_free_buff_r
;
2090 /* check if we need to copy aligned data by applying any shift necessary */
2092 memcpy(buffer
, tmp_buff
+ start_byte
, total_bytes
);
2100 /* Unset DTR mode */
2101 mem_ap_read_atomic_u32(armv8
->debug_ap
,
2102 armv8
->debug_base
+ CPUV8_DBG_DSCR
, &dscr
);
2103 dscr
= (dscr
& ~DSCR_MA
);
2104 mem_ap_write_atomic_u32(armv8
->debug_ap
,
2105 armv8
->debug_base
+ CPUV8_DBG_DSCR
, dscr
);
2112 static int aarch64_read_phys_memory(struct target
*target
,
2113 target_addr_t address
, uint32_t size
,
2114 uint32_t count
, uint8_t *buffer
)
2116 struct armv8_common
*armv8
= target_to_armv8(target
);
2117 int retval
= ERROR_COMMAND_SYNTAX_ERROR
;
2118 struct adiv5_dap
*swjdp
= armv8
->arm
.dap
;
2119 uint8_t apsel
= swjdp
->apsel
;
2120 LOG_DEBUG("Reading memory at real address 0x%" TARGET_PRIxADDR
"; size %" PRId32
"; count %" PRId32
,
2121 address
, size
, count
);
2123 if (count
&& buffer
) {
2125 if (armv8
->memory_ap_available
&& (apsel
== armv8
->memory_ap
->ap_num
)) {
2127 /* read memory through AHB-AP */
2128 retval
= mem_ap_read_buf(armv8
->memory_ap
, buffer
, size
, count
, address
);
2130 /* read memory through APB-AP */
2131 retval
= aarch64_mmu_modify(target
, 0);
2132 if (retval
!= ERROR_OK
)
2134 retval
= aarch64_read_apb_ap_memory(target
, address
, size
, count
, buffer
);
2140 static int aarch64_read_memory(struct target
*target
, target_addr_t address
,
2141 uint32_t size
, uint32_t count
, uint8_t *buffer
)
2143 int mmu_enabled
= 0;
2144 target_addr_t virt
, phys
;
2146 struct armv8_common
*armv8
= target_to_armv8(target
);
2147 struct adiv5_dap
*swjdp
= armv8
->arm
.dap
;
2148 uint8_t apsel
= swjdp
->apsel
;
2150 /* aarch64 handles unaligned memory access */
2151 LOG_DEBUG("Reading memory at address 0x%" TARGET_PRIxADDR
"; size %" PRId32
"; count %" PRId32
, address
,
2154 /* determine if MMU was enabled on target stop */
2155 if (!armv8
->is_armv7r
) {
2156 retval
= aarch64_mmu(target
, &mmu_enabled
);
2157 if (retval
!= ERROR_OK
)
2161 if (armv8
->memory_ap_available
&& (apsel
== armv8
->memory_ap
->ap_num
)) {
2164 retval
= aarch64_virt2phys(target
, virt
, &phys
);
2165 if (retval
!= ERROR_OK
)
2168 LOG_DEBUG("Reading at virtual address. Translating v:0x%" TARGET_PRIxADDR
" to r:0x%" TARGET_PRIxADDR
,
2172 retval
= aarch64_read_phys_memory(target
, address
, size
, count
,
2176 retval
= aarch64_check_address(target
, address
);
2177 if (retval
!= ERROR_OK
)
2179 /* enable MMU as we could have disabled it for phys
2181 retval
= aarch64_mmu_modify(target
, 1);
2182 if (retval
!= ERROR_OK
)
2185 retval
= aarch64_read_apb_ap_memory(target
, address
, size
,
2191 static int aarch64_write_phys_memory(struct target
*target
,
2192 target_addr_t address
, uint32_t size
,
2193 uint32_t count
, const uint8_t *buffer
)
2195 struct armv8_common
*armv8
= target_to_armv8(target
);
2196 struct adiv5_dap
*swjdp
= armv8
->arm
.dap
;
2197 int retval
= ERROR_COMMAND_SYNTAX_ERROR
;
2198 uint8_t apsel
= swjdp
->apsel
;
2200 LOG_DEBUG("Writing memory to real address 0x%" TARGET_PRIxADDR
"; size %" PRId32
"; count %" PRId32
, address
,
2203 if (count
&& buffer
) {
2205 if (armv8
->memory_ap_available
&& (apsel
== armv8
->memory_ap
->ap_num
)) {
2207 /* write memory through AHB-AP */
2208 retval
= mem_ap_write_buf(armv8
->memory_ap
, buffer
, size
, count
, address
);
2211 /* write memory through APB-AP */
2212 if (!armv8
->is_armv7r
) {
2213 retval
= aarch64_mmu_modify(target
, 0);
2214 if (retval
!= ERROR_OK
)
2217 return aarch64_write_apb_ap_memory(target
, address
, size
, count
, buffer
);
2222 /* REVISIT this op is generic ARMv7-A/R stuff */
2223 if (retval
== ERROR_OK
&& target
->state
== TARGET_HALTED
) {
2224 struct arm_dpm
*dpm
= armv8
->arm
.dpm
;
2226 retval
= dpm
->prepare(dpm
);
2227 if (retval
!= ERROR_OK
)
2230 /* The Cache handling will NOT work with MMU active, the
2231 * wrong addresses will be invalidated!
2233 * For both ICache and DCache, walk all cache lines in the
2234 * address range. Cortex-A has fixed 64 byte line length.
2236 * REVISIT per ARMv7, these may trigger watchpoints ...
2239 /* invalidate I-Cache */
2240 if (armv8
->armv8_mmu
.armv8_cache
.i_cache_enabled
) {
2241 /* ICIMVAU - Invalidate Cache single entry
2243 * MCR p15, 0, r0, c7, c5, 1
2245 for (uint32_t cacheline
= 0;
2246 cacheline
< size
* count
;
2248 retval
= dpm
->instr_write_data_r0(dpm
,
2249 ARMV8_MSR_GP(SYSTEM_ICIVAU
, 0),
2250 address
+ cacheline
);
2251 if (retval
!= ERROR_OK
)
2256 /* invalidate D-Cache */
2257 if (armv8
->armv8_mmu
.armv8_cache
.d_u_cache_enabled
) {
2258 /* DCIMVAC - Invalidate data Cache line
2260 * MCR p15, 0, r0, c7, c6, 1
2262 for (uint32_t cacheline
= 0;
2263 cacheline
< size
* count
;
2265 retval
= dpm
->instr_write_data_r0(dpm
,
2266 ARMV8_MSR_GP(SYSTEM_DCCVAU
, 0),
2267 address
+ cacheline
);
2268 if (retval
!= ERROR_OK
)
2273 /* (void) */ dpm
->finish(dpm
);
2279 static int aarch64_write_memory(struct target
*target
, target_addr_t address
,
2280 uint32_t size
, uint32_t count
, const uint8_t *buffer
)
2282 int mmu_enabled
= 0;
2283 target_addr_t virt
, phys
;
2285 struct armv8_common
*armv8
= target_to_armv8(target
);
2286 struct adiv5_dap
*swjdp
= armv8
->arm
.dap
;
2287 uint8_t apsel
= swjdp
->apsel
;
2289 /* aarch64 handles unaligned memory access */
2290 LOG_DEBUG("Writing memory at address 0x%" TARGET_PRIxADDR
"; size %" PRId32
2291 "; count %" PRId32
, address
, size
, count
);
2293 /* determine if MMU was enabled on target stop */
2294 if (!armv8
->is_armv7r
) {
2295 retval
= aarch64_mmu(target
, &mmu_enabled
);
2296 if (retval
!= ERROR_OK
)
2300 if (armv8
->memory_ap_available
&& (apsel
== armv8
->memory_ap
->ap_num
)) {
2301 LOG_DEBUG("Writing memory to address 0x%" TARGET_PRIxADDR
"; size %"
2302 PRId32
"; count %" PRId32
, address
, size
, count
);
2305 retval
= aarch64_virt2phys(target
, virt
, &phys
);
2306 if (retval
!= ERROR_OK
)
2309 LOG_DEBUG("Writing to virtual address. Translating v:0x%"
2310 TARGET_PRIxADDR
" to r:0x%" TARGET_PRIxADDR
, virt
, phys
);
2313 retval
= aarch64_write_phys_memory(target
, address
, size
,
2317 retval
= aarch64_check_address(target
, address
);
2318 if (retval
!= ERROR_OK
)
2320 /* enable MMU as we could have disabled it for phys access */
2321 retval
= aarch64_mmu_modify(target
, 1);
2322 if (retval
!= ERROR_OK
)
2325 retval
= aarch64_write_apb_ap_memory(target
, address
, size
, count
, buffer
);
2330 static int aarch64_handle_target_request(void *priv
)
2332 struct target
*target
= priv
;
2333 struct armv8_common
*armv8
= target_to_armv8(target
);
2336 if (!target_was_examined(target
))
2338 if (!target
->dbg_msg_enabled
)
2341 if (target
->state
== TARGET_RUNNING
) {
2344 retval
= mem_ap_read_atomic_u32(armv8
->debug_ap
,
2345 armv8
->debug_base
+ CPUV8_DBG_DSCR
, &dscr
);
2347 /* check if we have data */
2348 while ((dscr
& DSCR_DTR_TX_FULL
) && (retval
== ERROR_OK
)) {
2349 retval
= mem_ap_read_atomic_u32(armv8
->debug_ap
,
2350 armv8
->debug_base
+ CPUV8_DBG_DTRTX
, &request
);
2351 if (retval
== ERROR_OK
) {
2352 target_request(target
, request
);
2353 retval
= mem_ap_read_atomic_u32(armv8
->debug_ap
,
2354 armv8
->debug_base
+ CPUV8_DBG_DSCR
, &dscr
);
2362 static int aarch64_examine_first(struct target
*target
)
2364 struct aarch64_common
*aarch64
= target_to_aarch64(target
);
2365 struct armv8_common
*armv8
= &aarch64
->armv8_common
;
2366 struct adiv5_dap
*swjdp
= armv8
->arm
.dap
;
2368 int retval
= ERROR_OK
;
2369 uint64_t debug
, ttypr
;
2371 uint32_t tmp0
, tmp1
;
2372 debug
= ttypr
= cpuid
= 0;
2374 /* We do one extra read to ensure DAP is configured,
2375 * we call ahbap_debugport_init(swjdp) instead
2377 retval
= dap_dp_init(swjdp
);
2378 if (retval
!= ERROR_OK
)
2381 /* Search for the APB-AB - it is needed for access to debug registers */
2382 retval
= dap_find_ap(swjdp
, AP_TYPE_APB_AP
, &armv8
->debug_ap
);
2383 if (retval
!= ERROR_OK
) {
2384 LOG_ERROR("Could not find APB-AP for debug access");
2388 retval
= mem_ap_init(armv8
->debug_ap
);
2389 if (retval
!= ERROR_OK
) {
2390 LOG_ERROR("Could not initialize the APB-AP");
2394 armv8
->debug_ap
->memaccess_tck
= 80;
2396 /* Search for the AHB-AB */
2397 armv8
->memory_ap_available
= false;
2398 retval
= dap_find_ap(swjdp
, AP_TYPE_AHB_AP
, &armv8
->memory_ap
);
2399 if (retval
== ERROR_OK
) {
2400 retval
= mem_ap_init(armv8
->memory_ap
);
2401 if (retval
== ERROR_OK
)
2402 armv8
->memory_ap_available
= true;
2404 if (retval
!= ERROR_OK
) {
2405 /* AHB-AP not found or unavailable - use the CPU */
2406 LOG_DEBUG("No AHB-AP available for memory access");
2410 if (!target
->dbgbase_set
) {
2412 /* Get ROM Table base */
2414 int32_t coreidx
= target
->coreid
;
2415 retval
= dap_get_debugbase(armv8
->debug_ap
, &dbgbase
, &apid
);
2416 if (retval
!= ERROR_OK
)
2418 /* Lookup 0x15 -- Processor DAP */
2419 retval
= dap_lookup_cs_component(armv8
->debug_ap
, dbgbase
, 0x15,
2420 &armv8
->debug_base
, &coreidx
);
2421 if (retval
!= ERROR_OK
)
2423 LOG_DEBUG("Detected core %" PRId32
" dbgbase: %08" PRIx32
2424 " apid: %08" PRIx32
, coreidx
, armv8
->debug_base
, apid
);
2426 armv8
->debug_base
= target
->dbgbase
;
2428 retval
= mem_ap_write_atomic_u32(armv8
->debug_ap
,
2429 armv8
->debug_base
+ CPUV8_DBG_LOCKACCESS
, 0xC5ACCE55);
2430 if (retval
!= ERROR_OK
) {
2431 LOG_DEBUG("LOCK debug access fail");
2435 retval
= mem_ap_write_atomic_u32(armv8
->debug_ap
,
2436 armv8
->debug_base
+ CPUV8_DBG_OSLAR
, 0);
2437 if (retval
!= ERROR_OK
) {
2438 LOG_DEBUG("Examine %s failed", "oslock");
2442 retval
= mem_ap_read_atomic_u32(armv8
->debug_ap
,
2443 armv8
->debug_base
+ CPUV8_DBG_MAINID0
, &cpuid
);
2444 if (retval
!= ERROR_OK
) {
2445 LOG_DEBUG("Examine %s failed", "CPUID");
2449 retval
= mem_ap_read_atomic_u32(armv8
->debug_ap
,
2450 armv8
->debug_base
+ CPUV8_DBG_MEMFEATURE0
, &tmp0
);
2451 retval
+= mem_ap_read_atomic_u32(armv8
->debug_ap
,
2452 armv8
->debug_base
+ CPUV8_DBG_MEMFEATURE0
+ 4, &tmp1
);
2453 if (retval
!= ERROR_OK
) {
2454 LOG_DEBUG("Examine %s failed", "Memory Model Type");
2458 ttypr
= (ttypr
<< 32) | tmp0
;
2460 retval
= mem_ap_read_atomic_u32(armv8
->debug_ap
,
2461 armv8
->debug_base
+ CPUV8_DBG_DBGFEATURE0
, &tmp0
);
2462 retval
+= mem_ap_read_atomic_u32(armv8
->debug_ap
,
2463 armv8
->debug_base
+ CPUV8_DBG_DBGFEATURE0
+ 4, &tmp1
);
2464 if (retval
!= ERROR_OK
) {
2465 LOG_DEBUG("Examine %s failed", "ID_AA64DFR0_EL1");
2469 debug
= (debug
<< 32) | tmp0
;
2471 LOG_DEBUG("cpuid = 0x%08" PRIx32
, cpuid
);
2472 LOG_DEBUG("ttypr = 0x%08" PRIx64
, ttypr
);
2473 LOG_DEBUG("debug = 0x%08" PRIx64
, debug
);
2475 if (target
->ctibase
== 0) {
2476 /* assume a v8 rom table layout */
2477 armv8
->cti_base
= target
->ctibase
= armv8
->debug_base
+ 0x10000;
2478 LOG_INFO("Target ctibase is not set, assuming 0x%0" PRIx32
, target
->ctibase
);
2480 armv8
->cti_base
= target
->ctibase
;
2482 retval
= mem_ap_write_atomic_u32(armv8
->debug_ap
,
2483 armv8
->cti_base
+ CTI_UNLOCK
, 0xC5ACCE55);
2484 if (retval
!= ERROR_OK
)
2488 armv8
->arm
.core_type
= ARM_MODE_MON
;
2489 retval
= aarch64_dpm_setup(aarch64
, debug
);
2490 if (retval
!= ERROR_OK
)
2493 /* Setup Breakpoint Register Pairs */
2494 aarch64
->brp_num
= (uint32_t)((debug
>> 12) & 0x0F) + 1;
2495 aarch64
->brp_num_context
= (uint32_t)((debug
>> 28) & 0x0F) + 1;
2496 aarch64
->brp_num_available
= aarch64
->brp_num
;
2497 aarch64
->brp_list
= calloc(aarch64
->brp_num
, sizeof(struct aarch64_brp
));
2498 for (i
= 0; i
< aarch64
->brp_num
; i
++) {
2499 aarch64
->brp_list
[i
].used
= 0;
2500 if (i
< (aarch64
->brp_num
-aarch64
->brp_num_context
))
2501 aarch64
->brp_list
[i
].type
= BRP_NORMAL
;
2503 aarch64
->brp_list
[i
].type
= BRP_CONTEXT
;
2504 aarch64
->brp_list
[i
].value
= 0;
2505 aarch64
->brp_list
[i
].control
= 0;
2506 aarch64
->brp_list
[i
].BRPn
= i
;
2509 LOG_DEBUG("Configured %i hw breakpoints", aarch64
->brp_num
);
2511 target_set_examined(target
);
2515 static int aarch64_examine(struct target
*target
)
2517 int retval
= ERROR_OK
;
2519 /* don't re-probe hardware after each reset */
2520 if (!target_was_examined(target
))
2521 retval
= aarch64_examine_first(target
);
2523 /* Configure core debug access */
2524 if (retval
== ERROR_OK
)
2525 retval
= aarch64_init_debug_access(target
);
2531 * Cortex-A8 target creation and initialization
2534 static int aarch64_init_target(struct command_context
*cmd_ctx
,
2535 struct target
*target
)
2537 /* examine_first() does a bunch of this */
2541 static int aarch64_init_arch_info(struct target
*target
,
2542 struct aarch64_common
*aarch64
, struct jtag_tap
*tap
)
2544 struct armv8_common
*armv8
= &aarch64
->armv8_common
;
2545 struct adiv5_dap
*dap
= armv8
->arm
.dap
;
2547 armv8
->arm
.dap
= dap
;
2549 /* Setup struct aarch64_common */
2550 aarch64
->common_magic
= AARCH64_COMMON_MAGIC
;
2551 /* tap has no dap initialized */
2553 tap
->dap
= dap_init();
2555 /* Leave (only) generic DAP stuff for debugport_init() */
2556 tap
->dap
->tap
= tap
;
2559 armv8
->arm
.dap
= tap
->dap
;
2561 aarch64
->fast_reg_read
= 0;
2563 /* register arch-specific functions */
2564 armv8
->examine_debug_reason
= NULL
;
2566 armv8
->post_debug_entry
= aarch64_post_debug_entry
;
2568 armv8
->pre_restore_context
= NULL
;
2570 armv8
->armv8_mmu
.read_physical_memory
= aarch64_read_phys_memory
;
2572 /* REVISIT v7a setup should be in a v7a-specific routine */
2573 armv8_init_arch_info(target
, armv8
);
2574 target_register_timer_callback(aarch64_handle_target_request
, 1, 1, target
);
2579 static int aarch64_target_create(struct target
*target
, Jim_Interp
*interp
)
2581 struct aarch64_common
*aarch64
= calloc(1, sizeof(struct aarch64_common
));
2583 aarch64
->armv8_common
.is_armv7r
= false;
2585 return aarch64_init_arch_info(target
, aarch64
, target
->tap
);
2588 static int aarch64_mmu(struct target
*target
, int *enabled
)
2590 if (target
->state
!= TARGET_HALTED
) {
2591 LOG_ERROR("%s: target not halted", __func__
);
2592 return ERROR_TARGET_INVALID
;
2595 *enabled
= target_to_aarch64(target
)->armv8_common
.armv8_mmu
.mmu_enabled
;
2599 static int aarch64_virt2phys(struct target
*target
, target_addr_t virt
,
2600 target_addr_t
*phys
)
2602 int retval
= ERROR_FAIL
;
2603 struct armv8_common
*armv8
= target_to_armv8(target
);
2604 struct adiv5_dap
*swjdp
= armv8
->arm
.dap
;
2605 uint8_t apsel
= swjdp
->apsel
;
2606 if (armv8
->memory_ap_available
&& (apsel
== armv8
->memory_ap
->ap_num
)) {
2608 retval
= armv8_mmu_translate_va(target
,
2610 if (retval
!= ERROR_OK
)
2614 LOG_ERROR("AAR64 processor not support translate va to pa");
2620 COMMAND_HANDLER(aarch64_handle_cache_info_command
)
2622 struct target
*target
= get_current_target(CMD_CTX
);
2623 struct armv8_common
*armv8
= target_to_armv8(target
);
2625 return armv8_handle_cache_info_command(CMD_CTX
,
2626 &armv8
->armv8_mmu
.armv8_cache
);
2630 COMMAND_HANDLER(aarch64_handle_dbginit_command
)
2632 struct target
*target
= get_current_target(CMD_CTX
);
2633 if (!target_was_examined(target
)) {
2634 LOG_ERROR("target not examined yet");
2638 return aarch64_init_debug_access(target
);
2640 COMMAND_HANDLER(aarch64_handle_smp_off_command
)
2642 struct target
*target
= get_current_target(CMD_CTX
);
2643 /* check target is an smp target */
2644 struct target_list
*head
;
2645 struct target
*curr
;
2646 head
= target
->head
;
2648 if (head
!= (struct target_list
*)NULL
) {
2649 while (head
!= (struct target_list
*)NULL
) {
2650 curr
= head
->target
;
2654 /* fixes the target display to the debugger */
2655 target
->gdb_service
->target
= target
;
2660 COMMAND_HANDLER(aarch64_handle_smp_on_command
)
2662 struct target
*target
= get_current_target(CMD_CTX
);
2663 struct target_list
*head
;
2664 struct target
*curr
;
2665 head
= target
->head
;
2666 if (head
!= (struct target_list
*)NULL
) {
2668 while (head
!= (struct target_list
*)NULL
) {
2669 curr
= head
->target
;
2677 COMMAND_HANDLER(aarch64_handle_smp_gdb_command
)
2679 struct target
*target
= get_current_target(CMD_CTX
);
2680 int retval
= ERROR_OK
;
2681 struct target_list
*head
;
2682 head
= target
->head
;
2683 if (head
!= (struct target_list
*)NULL
) {
2684 if (CMD_ARGC
== 1) {
2686 COMMAND_PARSE_NUMBER(int, CMD_ARGV
[0], coreid
);
2687 if (ERROR_OK
!= retval
)
2689 target
->gdb_service
->core
[1] = coreid
;
2692 command_print(CMD_CTX
, "gdb coreid %" PRId32
" -> %" PRId32
, target
->gdb_service
->core
[0]
2693 , target
->gdb_service
->core
[1]);
2698 static const struct command_registration aarch64_exec_command_handlers
[] = {
2700 .name
= "cache_info",
2701 .handler
= aarch64_handle_cache_info_command
,
2702 .mode
= COMMAND_EXEC
,
2703 .help
= "display information about target caches",
2708 .handler
= aarch64_handle_dbginit_command
,
2709 .mode
= COMMAND_EXEC
,
2710 .help
= "Initialize core debug",
2713 { .name
= "smp_off",
2714 .handler
= aarch64_handle_smp_off_command
,
2715 .mode
= COMMAND_EXEC
,
2716 .help
= "Stop smp handling",
2721 .handler
= aarch64_handle_smp_on_command
,
2722 .mode
= COMMAND_EXEC
,
2723 .help
= "Restart smp handling",
2728 .handler
= aarch64_handle_smp_gdb_command
,
2729 .mode
= COMMAND_EXEC
,
2730 .help
= "display/fix current core played to gdb",
2735 COMMAND_REGISTRATION_DONE
2737 static const struct command_registration aarch64_command_handlers
[] = {
2739 .chain
= arm_command_handlers
,
2742 .chain
= armv8_command_handlers
,
2746 .mode
= COMMAND_ANY
,
2747 .help
= "Cortex-A command group",
2749 .chain
= aarch64_exec_command_handlers
,
2751 COMMAND_REGISTRATION_DONE
2754 struct target_type aarch64_target
= {
2757 .poll
= aarch64_poll
,
2758 .arch_state
= armv8_arch_state
,
2760 .halt
= aarch64_halt
,
2761 .resume
= aarch64_resume
,
2762 .step
= aarch64_step
,
2764 .assert_reset
= aarch64_assert_reset
,
2765 .deassert_reset
= aarch64_deassert_reset
,
2767 /* REVISIT allow exporting VFP3 registers ... */
2768 .get_gdb_reg_list
= armv8_get_gdb_reg_list
,
2770 .read_memory
= aarch64_read_memory
,
2771 .write_memory
= aarch64_write_memory
,
2773 .checksum_memory
= arm_checksum_memory
,
2774 .blank_check_memory
= arm_blank_check_memory
,
2776 .run_algorithm
= armv4_5_run_algorithm
,
2778 .add_breakpoint
= aarch64_add_breakpoint
,
2779 .add_context_breakpoint
= aarch64_add_context_breakpoint
,
2780 .add_hybrid_breakpoint
= aarch64_add_hybrid_breakpoint
,
2781 .remove_breakpoint
= aarch64_remove_breakpoint
,
2782 .add_watchpoint
= NULL
,
2783 .remove_watchpoint
= NULL
,
2785 .commands
= aarch64_command_handlers
,
2786 .target_create
= aarch64_target_create
,
2787 .init_target
= aarch64_init_target
,
2788 .examine
= aarch64_examine
,
2790 .read_phys_memory
= aarch64_read_phys_memory
,
2791 .write_phys_memory
= aarch64_write_phys_memory
,
2793 .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)