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 retval
= aarch64_instr_write_data_r0(armv8
->arm
.dpm
,
62 aarch64
->system_control_reg
);
68 /* check address before aarch64_apb read write access with mmu on
69 * remove apb predictible data abort */
70 static int aarch64_check_address(struct target
*target
, uint32_t address
)
75 /* modify system_control_reg in order to enable or disable mmu for :
76 * - virt2phys address conversion
77 * - read or write memory in phys or virt address */
78 static int aarch64_mmu_modify(struct target
*target
, int enable
)
80 struct aarch64_common
*aarch64
= target_to_aarch64(target
);
81 struct armv8_common
*armv8
= &aarch64
->armv8_common
;
82 int retval
= ERROR_OK
;
85 /* if mmu enabled at target stop and mmu not enable */
86 if (!(aarch64
->system_control_reg
& 0x1U
)) {
87 LOG_ERROR("trying to enable mmu on target stopped with mmu disable");
90 if (!(aarch64
->system_control_reg_curr
& 0x1U
)) {
91 aarch64
->system_control_reg_curr
|= 0x1U
;
92 retval
= aarch64_instr_write_data_r0(armv8
->arm
.dpm
,
94 aarch64
->system_control_reg_curr
);
97 if (aarch64
->system_control_reg_curr
& 0x4U
) {
98 /* data cache is active */
99 aarch64
->system_control_reg_curr
&= ~0x4U
;
100 /* flush data cache armv7 function to be called */
101 if (armv8
->armv8_mmu
.armv8_cache
.flush_all_data_cache
)
102 armv8
->armv8_mmu
.armv8_cache
.flush_all_data_cache(target
);
104 if ((aarch64
->system_control_reg_curr
& 0x1U
)) {
105 aarch64
->system_control_reg_curr
&= ~0x1U
;
106 retval
= aarch64_instr_write_data_r0(armv8
->arm
.dpm
,
108 aarch64
->system_control_reg_curr
);
115 * Basic debug access, very low level assumes state is saved
117 static int aarch64_init_debug_access(struct target
*target
)
119 struct armv8_common
*armv8
= target_to_armv8(target
);
125 /* Unlocking the debug registers for modification
126 * The debugport might be uninitialised so try twice */
127 retval
= mem_ap_write_atomic_u32(armv8
->debug_ap
,
128 armv8
->debug_base
+ CPUDBG_LOCKACCESS
, 0xC5ACCE55);
129 if (retval
!= ERROR_OK
) {
131 retval
= mem_ap_write_atomic_u32(armv8
->debug_ap
,
132 armv8
->debug_base
+ CPUDBG_LOCKACCESS
, 0xC5ACCE55);
133 if (retval
== ERROR_OK
)
134 LOG_USER("Locking debug access failed on first, but succeeded on second try.");
136 if (retval
!= ERROR_OK
)
138 /* Clear Sticky Power Down status Bit in PRSR to enable access to
139 the registers in the Core Power Domain */
140 retval
= mem_ap_read_atomic_u32(armv8
->debug_ap
,
141 armv8
->debug_base
+ CPUDBG_PRSR
, &dummy
);
142 if (retval
!= ERROR_OK
)
145 /* Enabling of instruction execution in debug mode is done in debug_entry code */
147 /* Resync breakpoint registers */
149 /* Since this is likely called from init or reset, update target state information*/
150 return aarch64_poll(target
);
153 /* To reduce needless round-trips, pass in a pointer to the current
154 * DSCR value. Initialize it to zero if you just need to know the
155 * value on return from this function; or DSCR_INSTR_COMP if you
156 * happen to know that no instruction is pending.
158 static int aarch64_exec_opcode(struct target
*target
,
159 uint32_t opcode
, uint32_t *dscr_p
)
163 struct armv8_common
*armv8
= target_to_armv8(target
);
164 dscr
= dscr_p
? *dscr_p
: 0;
166 LOG_DEBUG("exec opcode 0x%08" PRIx32
, opcode
);
168 /* Wait for InstrCompl bit to be set */
169 long long then
= timeval_ms();
170 while ((dscr
& DSCR_INSTR_COMP
) == 0) {
171 retval
= mem_ap_read_atomic_u32(armv8
->debug_ap
,
172 armv8
->debug_base
+ CPUDBG_DSCR
, &dscr
);
173 if (retval
!= ERROR_OK
) {
174 LOG_ERROR("Could not read DSCR register, opcode = 0x%08" PRIx32
, opcode
);
177 if (timeval_ms() > then
+ 1000) {
178 LOG_ERROR("Timeout waiting for aarch64_exec_opcode");
183 retval
= mem_ap_write_u32(armv8
->debug_ap
,
184 armv8
->debug_base
+ CPUDBG_ITR
, opcode
);
185 if (retval
!= ERROR_OK
)
190 retval
= mem_ap_read_atomic_u32(armv8
->debug_ap
,
191 armv8
->debug_base
+ CPUDBG_DSCR
, &dscr
);
192 if (retval
!= ERROR_OK
) {
193 LOG_ERROR("Could not read DSCR register");
196 if (timeval_ms() > then
+ 1000) {
197 LOG_ERROR("Timeout waiting for aarch64_exec_opcode");
200 } while ((dscr
& DSCR_INSTR_COMP
) == 0); /* Wait for InstrCompl bit to be set */
208 /* Write to memory mapped registers directly with no cache or mmu handling */
209 static int aarch64_dap_write_memap_register_u32(struct target
*target
,
214 struct armv8_common
*armv8
= target_to_armv8(target
);
216 retval
= mem_ap_write_atomic_u32(armv8
->debug_ap
, address
, value
);
222 * AARCH64 implementation of Debug Programmer's Model
224 * NOTE the invariant: these routines return with DSCR_INSTR_COMP set,
225 * so there's no need to poll for it before executing an instruction.
227 * NOTE that in several of these cases the "stall" mode might be useful.
228 * It'd let us queue a few operations together... prepare/finish might
229 * be the places to enable/disable that mode.
232 static inline struct aarch64_common
*dpm_to_a8(struct arm_dpm
*dpm
)
234 return container_of(dpm
, struct aarch64_common
, armv8_common
.dpm
);
237 static int aarch64_write_dcc(struct armv8_common
*armv8
, uint32_t data
)
239 LOG_DEBUG("write DCC 0x%08" PRIx32
, data
);
240 return mem_ap_write_u32(armv8
->debug_ap
,
241 armv8
->debug_base
+ CPUDBG_DTRRX
, data
);
244 static int aarch64_write_dcc_64(struct armv8_common
*armv8
, uint64_t data
)
247 LOG_DEBUG("write DCC Low word0x%08" PRIx32
, (unsigned)data
);
248 LOG_DEBUG("write DCC High word 0x%08" PRIx32
, (unsigned)(data
>> 32));
249 ret
= mem_ap_write_u32(armv8
->debug_ap
,
250 armv8
->debug_base
+ CPUDBG_DTRRX
, data
);
251 ret
+= mem_ap_write_u32(armv8
->debug_ap
,
252 armv8
->debug_base
+ CPUDBG_DTRTX
, data
>> 32);
256 static int aarch64_read_dcc(struct armv8_common
*armv8
, uint32_t *data
,
259 uint32_t dscr
= DSCR_INSTR_COMP
;
265 /* Wait for DTRRXfull */
266 long long then
= timeval_ms();
267 while ((dscr
& DSCR_DTR_TX_FULL
) == 0) {
268 retval
= mem_ap_read_atomic_u32(armv8
->debug_ap
,
269 armv8
->debug_base
+ CPUDBG_DSCR
,
271 if (retval
!= ERROR_OK
)
273 if (timeval_ms() > then
+ 1000) {
274 LOG_ERROR("Timeout waiting for read dcc");
279 retval
= mem_ap_read_atomic_u32(armv8
->debug_ap
,
280 armv8
->debug_base
+ CPUDBG_DTRTX
,
282 if (retval
!= ERROR_OK
)
284 LOG_DEBUG("read DCC 0x%08" PRIx32
, *data
);
292 static int aarch64_read_dcc_64(struct armv8_common
*armv8
, uint64_t *data
,
295 uint32_t dscr
= DSCR_INSTR_COMP
;
302 /* Wait for DTRRXfull */
303 long long then
= timeval_ms();
304 while ((dscr
& DSCR_DTR_TX_FULL
) == 0) {
305 retval
= mem_ap_read_atomic_u32(armv8
->debug_ap
,
306 armv8
->debug_base
+ CPUDBG_DSCR
,
308 if (retval
!= ERROR_OK
)
310 if (timeval_ms() > then
+ 1000) {
311 LOG_ERROR("Timeout waiting for read dcc");
316 retval
= mem_ap_read_atomic_u32(armv8
->debug_ap
,
317 armv8
->debug_base
+ CPUDBG_DTRTX
,
319 if (retval
!= ERROR_OK
)
322 retval
= mem_ap_read_atomic_u32(armv8
->debug_ap
,
323 armv8
->debug_base
+ CPUDBG_DTRRX
,
325 if (retval
!= ERROR_OK
)
328 *data
= *(uint32_t *)data
| (uint64_t)higher
<< 32;
329 LOG_DEBUG("read DCC 0x%16.16" PRIx64
, *data
);
337 static int aarch64_dpm_prepare(struct arm_dpm
*dpm
)
339 struct aarch64_common
*a8
= dpm_to_a8(dpm
);
343 /* set up invariant: INSTR_COMP is set after ever DPM operation */
344 long long then
= timeval_ms();
346 retval
= mem_ap_read_atomic_u32(a8
->armv8_common
.debug_ap
,
347 a8
->armv8_common
.debug_base
+ CPUDBG_DSCR
,
349 if (retval
!= ERROR_OK
)
351 if ((dscr
& DSCR_INSTR_COMP
) != 0)
353 if (timeval_ms() > then
+ 1000) {
354 LOG_ERROR("Timeout waiting for dpm prepare");
359 /* this "should never happen" ... */
360 if (dscr
& DSCR_DTR_RX_FULL
) {
361 LOG_ERROR("DSCR_DTR_RX_FULL, dscr 0x%08" PRIx32
, dscr
);
363 retval
= aarch64_exec_opcode(
364 a8
->armv8_common
.arm
.target
,
367 if (retval
!= ERROR_OK
)
374 static int aarch64_dpm_finish(struct arm_dpm
*dpm
)
376 /* REVISIT what could be done here? */
380 static int aarch64_instr_execute(struct arm_dpm
*dpm
,
383 struct aarch64_common
*a8
= dpm_to_a8(dpm
);
384 uint32_t dscr
= DSCR_ITE
;
386 return aarch64_exec_opcode(
387 a8
->armv8_common
.arm
.target
,
392 static int aarch64_instr_write_data_dcc(struct arm_dpm
*dpm
,
393 uint32_t opcode
, uint32_t data
)
395 struct aarch64_common
*a8
= dpm_to_a8(dpm
);
397 uint32_t dscr
= DSCR_INSTR_COMP
;
399 retval
= aarch64_write_dcc(&a8
->armv8_common
, data
);
400 if (retval
!= ERROR_OK
)
403 return aarch64_exec_opcode(
404 a8
->armv8_common
.arm
.target
,
409 static int aarch64_instr_write_data_dcc_64(struct arm_dpm
*dpm
,
410 uint32_t opcode
, uint64_t data
)
412 struct aarch64_common
*a8
= dpm_to_a8(dpm
);
414 uint32_t dscr
= DSCR_INSTR_COMP
;
416 retval
= aarch64_write_dcc_64(&a8
->armv8_common
, data
);
417 if (retval
!= ERROR_OK
)
420 return aarch64_exec_opcode(
421 a8
->armv8_common
.arm
.target
,
426 static int aarch64_instr_write_data_r0(struct arm_dpm
*dpm
,
427 uint32_t opcode
, uint32_t data
)
429 struct aarch64_common
*a8
= dpm_to_a8(dpm
);
430 uint32_t dscr
= DSCR_INSTR_COMP
;
433 retval
= aarch64_write_dcc(&a8
->armv8_common
, data
);
434 if (retval
!= ERROR_OK
)
437 retval
= aarch64_exec_opcode(
438 a8
->armv8_common
.arm
.target
,
441 if (retval
!= ERROR_OK
)
444 /* then the opcode, taking data from R0 */
445 retval
= aarch64_exec_opcode(
446 a8
->armv8_common
.arm
.target
,
453 static int aarch64_instr_write_data_r0_64(struct arm_dpm
*dpm
,
454 uint32_t opcode
, uint64_t data
)
456 struct aarch64_common
*a8
= dpm_to_a8(dpm
);
457 uint32_t dscr
= DSCR_INSTR_COMP
;
460 retval
= aarch64_write_dcc_64(&a8
->armv8_common
, data
);
461 if (retval
!= ERROR_OK
)
464 retval
= aarch64_exec_opcode(
465 a8
->armv8_common
.arm
.target
,
468 if (retval
!= ERROR_OK
)
471 /* then the opcode, taking data from R0 */
472 retval
= aarch64_exec_opcode(
473 a8
->armv8_common
.arm
.target
,
480 static int aarch64_instr_cpsr_sync(struct arm_dpm
*dpm
)
482 struct target
*target
= dpm
->arm
->target
;
483 uint32_t dscr
= DSCR_INSTR_COMP
;
485 /* "Prefetch flush" after modifying execution status in CPSR */
486 return aarch64_exec_opcode(target
,
487 ARMV4_5_MCR(15, 0, 0, 7, 5, 4),
491 static int aarch64_instr_read_data_dcc(struct arm_dpm
*dpm
,
492 uint32_t opcode
, uint32_t *data
)
494 struct aarch64_common
*a8
= dpm_to_a8(dpm
);
496 uint32_t dscr
= DSCR_INSTR_COMP
;
498 /* the opcode, writing data to DCC */
499 retval
= aarch64_exec_opcode(
500 a8
->armv8_common
.arm
.target
,
503 if (retval
!= ERROR_OK
)
506 return aarch64_read_dcc(&a8
->armv8_common
, data
, &dscr
);
509 static int aarch64_instr_read_data_dcc_64(struct arm_dpm
*dpm
,
510 uint32_t opcode
, uint64_t *data
)
512 struct aarch64_common
*a8
= dpm_to_a8(dpm
);
514 uint32_t dscr
= DSCR_INSTR_COMP
;
516 /* the opcode, writing data to DCC */
517 retval
= aarch64_exec_opcode(
518 a8
->armv8_common
.arm
.target
,
521 if (retval
!= ERROR_OK
)
524 return aarch64_read_dcc_64(&a8
->armv8_common
, data
, &dscr
);
527 static int aarch64_instr_read_data_r0(struct arm_dpm
*dpm
,
528 uint32_t opcode
, uint32_t *data
)
530 struct aarch64_common
*a8
= dpm_to_a8(dpm
);
531 uint32_t dscr
= DSCR_INSTR_COMP
;
534 /* the opcode, writing data to R0 */
535 retval
= aarch64_exec_opcode(
536 a8
->armv8_common
.arm
.target
,
539 if (retval
!= ERROR_OK
)
542 /* write R0 to DCC */
543 retval
= aarch64_exec_opcode(
544 a8
->armv8_common
.arm
.target
,
545 0xd5130400, /* msr dbgdtr_el0, x0 */
547 if (retval
!= ERROR_OK
)
550 return aarch64_read_dcc(&a8
->armv8_common
, data
, &dscr
);
553 static int aarch64_instr_read_data_r0_64(struct arm_dpm
*dpm
,
554 uint32_t opcode
, uint64_t *data
)
556 struct aarch64_common
*a8
= dpm_to_a8(dpm
);
557 uint32_t dscr
= DSCR_INSTR_COMP
;
560 /* the opcode, writing data to R0 */
561 retval
= aarch64_exec_opcode(
562 a8
->armv8_common
.arm
.target
,
565 if (retval
!= ERROR_OK
)
568 /* write R0 to DCC */
569 retval
= aarch64_exec_opcode(
570 a8
->armv8_common
.arm
.target
,
571 0xd5130400, /* msr dbgdtr_el0, x0 */
573 if (retval
!= ERROR_OK
)
576 return aarch64_read_dcc_64(&a8
->armv8_common
, data
, &dscr
);
579 static int aarch64_bpwp_enable(struct arm_dpm
*dpm
, unsigned index_t
,
580 uint32_t addr
, uint32_t control
)
582 struct aarch64_common
*a8
= dpm_to_a8(dpm
);
583 uint32_t vr
= a8
->armv8_common
.debug_base
;
584 uint32_t cr
= a8
->armv8_common
.debug_base
;
588 case 0 ... 15: /* breakpoints */
589 vr
+= CPUDBG_BVR_BASE
;
590 cr
+= CPUDBG_BCR_BASE
;
592 case 16 ... 31: /* watchpoints */
593 vr
+= CPUDBG_WVR_BASE
;
594 cr
+= CPUDBG_WCR_BASE
;
603 LOG_DEBUG("A8: bpwp enable, vr %08x cr %08x",
604 (unsigned) vr
, (unsigned) cr
);
606 retval
= aarch64_dap_write_memap_register_u32(dpm
->arm
->target
,
608 if (retval
!= ERROR_OK
)
610 retval
= aarch64_dap_write_memap_register_u32(dpm
->arm
->target
,
615 static int aarch64_bpwp_disable(struct arm_dpm
*dpm
, unsigned index_t
)
620 struct aarch64_common
*a8
= dpm_to_a8(dpm
);
625 cr
= a8
->armv8_common
.debug_base
+ CPUDBG_BCR_BASE
;
628 cr
= a8
->armv8_common
.debug_base
+ CPUDBG_WCR_BASE
;
636 LOG_DEBUG("A8: bpwp disable, cr %08x", (unsigned) cr
);
638 /* clear control register */
639 return aarch64_dap_write_memap_register_u32(dpm
->arm
->target
, cr
, 0);
643 static int aarch64_dpm_setup(struct aarch64_common
*a8
, uint32_t debug
)
645 struct arm_dpm
*dpm
= &a8
->armv8_common
.dpm
;
648 dpm
->arm
= &a8
->armv8_common
.arm
;
651 dpm
->prepare
= aarch64_dpm_prepare
;
652 dpm
->finish
= aarch64_dpm_finish
;
654 dpm
->instr_execute
= aarch64_instr_execute
;
655 dpm
->instr_write_data_dcc
= aarch64_instr_write_data_dcc
;
656 dpm
->instr_write_data_dcc_64
= aarch64_instr_write_data_dcc_64
;
657 dpm
->instr_write_data_r0
= aarch64_instr_write_data_r0
;
658 dpm
->instr_write_data_r0_64
= aarch64_instr_write_data_r0_64
;
659 dpm
->instr_cpsr_sync
= aarch64_instr_cpsr_sync
;
661 dpm
->instr_read_data_dcc
= aarch64_instr_read_data_dcc
;
662 dpm
->instr_read_data_dcc_64
= aarch64_instr_read_data_dcc_64
;
663 dpm
->instr_read_data_r0
= aarch64_instr_read_data_r0
;
664 dpm
->instr_read_data_r0_64
= aarch64_instr_read_data_r0_64
;
666 dpm
->arm_reg_current
= armv8_reg_current
;
668 dpm
->bpwp_enable
= aarch64_bpwp_enable
;
669 dpm
->bpwp_disable
= aarch64_bpwp_disable
;
671 retval
= armv8_dpm_setup(dpm
);
672 if (retval
== ERROR_OK
)
673 retval
= armv8_dpm_initialize(dpm
);
677 static struct target
*get_aarch64(struct target
*target
, int32_t coreid
)
679 struct target_list
*head
;
683 while (head
!= (struct target_list
*)NULL
) {
685 if ((curr
->coreid
== coreid
) && (curr
->state
== TARGET_HALTED
))
691 static int aarch64_halt(struct target
*target
);
693 static int aarch64_halt_smp(struct target
*target
)
696 struct target_list
*head
;
699 while (head
!= (struct target_list
*)NULL
) {
701 if ((curr
!= target
) && (curr
->state
!= TARGET_HALTED
))
702 retval
+= aarch64_halt(curr
);
708 static int update_halt_gdb(struct target
*target
)
711 if (target
->gdb_service
&& target
->gdb_service
->core
[0] == -1) {
712 target
->gdb_service
->target
= target
;
713 target
->gdb_service
->core
[0] = target
->coreid
;
714 retval
+= aarch64_halt_smp(target
);
720 * Cortex-A8 Run control
723 static int aarch64_poll(struct target
*target
)
725 int retval
= ERROR_OK
;
727 struct aarch64_common
*aarch64
= target_to_aarch64(target
);
728 struct armv8_common
*armv8
= &aarch64
->armv8_common
;
729 enum target_state prev_target_state
= target
->state
;
730 /* toggle to another core is done by gdb as follow */
731 /* maint packet J core_id */
733 /* the next polling trigger an halt event sent to gdb */
734 if ((target
->state
== TARGET_HALTED
) && (target
->smp
) &&
735 (target
->gdb_service
) &&
736 (target
->gdb_service
->target
== NULL
)) {
737 target
->gdb_service
->target
=
738 get_aarch64(target
, target
->gdb_service
->core
[1]);
739 target_call_event_callbacks(target
, TARGET_EVENT_HALTED
);
742 retval
= mem_ap_read_atomic_u32(armv8
->debug_ap
,
743 armv8
->debug_base
+ CPUDBG_DSCR
, &dscr
);
744 if (retval
!= ERROR_OK
)
746 aarch64
->cpudbg_dscr
= dscr
;
748 if (DSCR_RUN_MODE(dscr
) == (DSCR_CORE_HALTED
| DSCR_CORE_RESTARTED
)) {
749 if (prev_target_state
!= TARGET_HALTED
) {
750 /* We have a halting debug event */
751 LOG_DEBUG("Target halted");
752 target
->state
= TARGET_HALTED
;
753 if ((prev_target_state
== TARGET_RUNNING
)
754 || (prev_target_state
== TARGET_UNKNOWN
)
755 || (prev_target_state
== TARGET_RESET
)) {
756 retval
= aarch64_debug_entry(target
);
757 if (retval
!= ERROR_OK
)
760 retval
= update_halt_gdb(target
);
761 if (retval
!= ERROR_OK
)
764 target_call_event_callbacks(target
,
765 TARGET_EVENT_HALTED
);
767 if (prev_target_state
== TARGET_DEBUG_RUNNING
) {
770 retval
= aarch64_debug_entry(target
);
771 if (retval
!= ERROR_OK
)
774 retval
= update_halt_gdb(target
);
775 if (retval
!= ERROR_OK
)
779 target_call_event_callbacks(target
,
780 TARGET_EVENT_DEBUG_HALTED
);
783 } else if (DSCR_RUN_MODE(dscr
) == DSCR_CORE_RESTARTED
)
784 target
->state
= TARGET_RUNNING
;
786 LOG_DEBUG("Unknown target state dscr = 0x%08" PRIx32
, dscr
);
787 target
->state
= TARGET_UNKNOWN
;
793 static int aarch64_halt(struct target
*target
)
795 int retval
= ERROR_OK
;
797 struct armv8_common
*armv8
= target_to_armv8(target
);
799 retval
= mem_ap_read_atomic_u32(armv8
->debug_ap
,
800 armv8
->debug_base
+ 0x10000 + 0, &dscr
);
801 retval
= mem_ap_write_atomic_u32(armv8
->debug_ap
,
802 armv8
->debug_base
+ 0x10000 + 0, 1);
803 retval
= mem_ap_read_atomic_u32(armv8
->debug_ap
,
804 armv8
->debug_base
+ 0x10000 + 0, &dscr
);
806 retval
= mem_ap_read_atomic_u32(armv8
->debug_ap
,
807 armv8
->debug_base
+ 0x10000 + 0x140, &dscr
);
808 retval
= mem_ap_write_atomic_u32(armv8
->debug_ap
,
809 armv8
->debug_base
+ 0x10000 + 0x140, 6);
810 retval
= mem_ap_read_atomic_u32(armv8
->debug_ap
,
811 armv8
->debug_base
+ 0x10000 + 0x140, &dscr
);
813 retval
= mem_ap_read_atomic_u32(armv8
->debug_ap
,
814 armv8
->debug_base
+ 0x10000 + 0xa0, &dscr
);
815 retval
= mem_ap_write_atomic_u32(armv8
->debug_ap
,
816 armv8
->debug_base
+ 0x10000 + 0xa0, 5);
817 retval
= mem_ap_read_atomic_u32(armv8
->debug_ap
,
818 armv8
->debug_base
+ 0x10000 + 0xa0, &dscr
);
820 retval
= mem_ap_read_atomic_u32(armv8
->debug_ap
,
821 armv8
->debug_base
+ 0x10000 + 0xa4, &dscr
);
822 retval
= mem_ap_write_atomic_u32(armv8
->debug_ap
,
823 armv8
->debug_base
+ 0x10000 + 0xa4, 2);
824 retval
= mem_ap_read_atomic_u32(armv8
->debug_ap
,
825 armv8
->debug_base
+ 0x10000 + 0xa4, &dscr
);
827 retval
= mem_ap_read_atomic_u32(armv8
->debug_ap
,
828 armv8
->debug_base
+ 0x10000 + 0x20, &dscr
);
829 retval
= mem_ap_write_atomic_u32(armv8
->debug_ap
,
830 armv8
->debug_base
+ 0x10000 + 0x20, 4);
831 retval
= mem_ap_read_atomic_u32(armv8
->debug_ap
,
832 armv8
->debug_base
+ 0x10000 + 0x20, &dscr
);
835 * enter halting debug mode
837 retval
= mem_ap_read_atomic_u32(armv8
->debug_ap
,
838 armv8
->debug_base
+ CPUDBG_DSCR
, &dscr
);
839 if (retval
!= ERROR_OK
)
843 retval
= mem_ap_read_atomic_u32(armv8
->debug_ap
,
844 armv8
->debug_base
+ 0x10000 + 0x134, &dscr
);
846 retval
= mem_ap_read_atomic_u32(armv8
->debug_ap
,
847 armv8
->debug_base
+ 0x10000 + 0x1c, &dscr
);
848 retval
= mem_ap_write_atomic_u32(armv8
->debug_ap
,
849 armv8
->debug_base
+ 0x10000 + 0x1c, 1);
850 retval
= mem_ap_read_atomic_u32(armv8
->debug_ap
,
851 armv8
->debug_base
+ 0x10000 + 0x1c, &dscr
);
854 long long then
= timeval_ms();
856 retval
= mem_ap_read_atomic_u32(armv8
->debug_ap
,
857 armv8
->debug_base
+ CPUDBG_DSCR
, &dscr
);
858 if (retval
!= ERROR_OK
)
860 if ((dscr
& DSCR_CORE_HALTED
) != 0)
862 if (timeval_ms() > then
+ 1000) {
863 LOG_ERROR("Timeout waiting for halt");
868 target
->debug_reason
= DBG_REASON_DBGRQ
;
873 static int aarch64_internal_restore(struct target
*target
, int current
,
874 uint64_t *address
, int handle_breakpoints
, int debug_execution
)
876 struct armv8_common
*armv8
= target_to_armv8(target
);
877 struct arm
*arm
= &armv8
->arm
;
881 if (!debug_execution
)
882 target_free_all_working_areas(target
);
884 /* current = 1: continue on current pc, otherwise continue at <address> */
885 resume_pc
= buf_get_u64(arm
->pc
->value
, 0, 64);
887 resume_pc
= *address
;
889 *address
= resume_pc
;
891 /* Make sure that the Armv7 gdb thumb fixups does not
892 * kill the return address
894 switch (arm
->core_state
) {
896 resume_pc
&= 0xFFFFFFFC;
898 case ARM_STATE_AARCH64
:
899 resume_pc
&= 0xFFFFFFFFFFFFFFFC;
901 case ARM_STATE_THUMB
:
902 case ARM_STATE_THUMB_EE
:
903 /* When the return address is loaded into PC
904 * bit 0 must be 1 to stay in Thumb state
908 case ARM_STATE_JAZELLE
:
909 LOG_ERROR("How do I resume into Jazelle state??");
912 LOG_DEBUG("resume pc = 0x%16" PRIx64
, resume_pc
);
913 buf_set_u64(arm
->pc
->value
, 0, 64, resume_pc
);
916 dpmv8_modeswitch(&armv8
->dpm
, ARM_MODE_ANY
);
918 /* called it now before restoring context because it uses cpu
919 * register r0 for restoring system control register */
920 retval
= aarch64_restore_system_control_reg(target
);
921 if (retval
!= ERROR_OK
)
923 retval
= aarch64_restore_context(target
, handle_breakpoints
);
924 if (retval
!= ERROR_OK
)
926 target
->debug_reason
= DBG_REASON_NOTHALTED
;
927 target
->state
= TARGET_RUNNING
;
929 /* registers are now invalid */
930 register_cache_invalidate(arm
->core_cache
);
933 /* the front-end may request us not to handle breakpoints */
934 if (handle_breakpoints
) {
935 /* Single step past breakpoint at current address */
936 breakpoint
= breakpoint_find(target
, resume_pc
);
938 LOG_DEBUG("unset breakpoint at 0x%8.8x", breakpoint
->address
);
939 cortex_m3_unset_breakpoint(target
, breakpoint
);
940 cortex_m3_single_step_core(target
);
941 cortex_m3_set_breakpoint(target
, breakpoint
);
949 static int aarch64_internal_restart(struct target
*target
)
951 struct armv8_common
*armv8
= target_to_armv8(target
);
952 struct arm
*arm
= &armv8
->arm
;
956 * * Restart core and wait for it to be started. Clear ITRen and sticky
957 * * exception flags: see ARMv7 ARM, C5.9.
959 * REVISIT: for single stepping, we probably want to
960 * disable IRQs by default, with optional override...
963 retval
= mem_ap_read_atomic_u32(armv8
->debug_ap
,
964 armv8
->debug_base
+ CPUDBG_DSCR
, &dscr
);
965 if (retval
!= ERROR_OK
)
968 if ((dscr
& DSCR_INSTR_COMP
) == 0)
969 LOG_ERROR("DSCR InstrCompl must be set before leaving debug!");
971 retval
= mem_ap_write_atomic_u32(armv8
->debug_ap
,
972 armv8
->debug_base
+ CPUDBG_DSCR
, dscr
& ~DSCR_ITR_EN
);
973 if (retval
!= ERROR_OK
)
976 retval
= mem_ap_write_atomic_u32(armv8
->debug_ap
,
977 armv8
->debug_base
+ CPUDBG_DRCR
, DRCR_RESTART
|
978 DRCR_CLEAR_EXCEPTIONS
);
979 if (retval
!= ERROR_OK
)
982 retval
= mem_ap_write_atomic_u32(armv8
->debug_ap
,
983 armv8
->debug_base
+ 0x10000 + 0x10, 1);
984 if (retval
!= ERROR_OK
)
987 retval
= mem_ap_write_atomic_u32(armv8
->debug_ap
,
988 armv8
->debug_base
+ 0x10000 + 0x1c, 2);
989 if (retval
!= ERROR_OK
)
992 long long then
= timeval_ms();
994 retval
= mem_ap_read_atomic_u32(armv8
->debug_ap
,
995 armv8
->debug_base
+ CPUDBG_DSCR
, &dscr
);
996 if (retval
!= ERROR_OK
)
998 if ((dscr
& DSCR_CORE_RESTARTED
) != 0)
1000 if (timeval_ms() > then
+ 1000) {
1001 LOG_ERROR("Timeout waiting for resume");
1006 target
->debug_reason
= DBG_REASON_NOTHALTED
;
1007 target
->state
= TARGET_RUNNING
;
1009 /* registers are now invalid */
1010 register_cache_invalidate(arm
->core_cache
);
1015 static int aarch64_restore_smp(struct target
*target
, int handle_breakpoints
)
1018 struct target_list
*head
;
1019 struct target
*curr
;
1021 head
= target
->head
;
1022 while (head
!= (struct target_list
*)NULL
) {
1023 curr
= head
->target
;
1024 if ((curr
!= target
) && (curr
->state
!= TARGET_RUNNING
)) {
1025 /* resume current address , not in step mode */
1026 retval
+= aarch64_internal_restore(curr
, 1, &address
,
1027 handle_breakpoints
, 0);
1028 retval
+= aarch64_internal_restart(curr
);
1036 static int aarch64_resume(struct target
*target
, int current
,
1037 target_addr_t address
, int handle_breakpoints
, int debug_execution
)
1040 uint64_t addr
= address
;
1042 /* dummy resume for smp toggle in order to reduce gdb impact */
1043 if ((target
->smp
) && (target
->gdb_service
->core
[1] != -1)) {
1044 /* simulate a start and halt of target */
1045 target
->gdb_service
->target
= NULL
;
1046 target
->gdb_service
->core
[0] = target
->gdb_service
->core
[1];
1047 /* fake resume at next poll we play the target core[1], see poll*/
1048 target_call_event_callbacks(target
, TARGET_EVENT_RESUMED
);
1051 aarch64_internal_restore(target
, current
, &addr
, handle_breakpoints
,
1054 target
->gdb_service
->core
[0] = -1;
1055 retval
= aarch64_restore_smp(target
, handle_breakpoints
);
1056 if (retval
!= ERROR_OK
)
1059 aarch64_internal_restart(target
);
1061 if (!debug_execution
) {
1062 target
->state
= TARGET_RUNNING
;
1063 target_call_event_callbacks(target
, TARGET_EVENT_RESUMED
);
1064 LOG_DEBUG("target resumed at 0x%" PRIu64
, addr
);
1066 target
->state
= TARGET_DEBUG_RUNNING
;
1067 target_call_event_callbacks(target
, TARGET_EVENT_DEBUG_RESUMED
);
1068 LOG_DEBUG("target debug resumed at 0x%" PRIu64
, addr
);
1074 static int aarch64_debug_entry(struct target
*target
)
1077 int retval
= ERROR_OK
;
1078 struct aarch64_common
*aarch64
= target_to_aarch64(target
);
1079 struct armv8_common
*armv8
= target_to_armv8(target
);
1082 LOG_DEBUG("dscr = 0x%08" PRIx32
, aarch64
->cpudbg_dscr
);
1084 /* REVISIT surely we should not re-read DSCR !! */
1085 retval
= mem_ap_read_atomic_u32(armv8
->debug_ap
,
1086 armv8
->debug_base
+ CPUDBG_DSCR
, &dscr
);
1087 if (retval
!= ERROR_OK
)
1090 /* REVISIT see A8 TRM 12.11.4 steps 2..3 -- make sure that any
1091 * imprecise data aborts get discarded by issuing a Data
1092 * Synchronization Barrier: ARMV4_5_MCR(15, 0, 0, 7, 10, 4).
1095 /* Enable the ITR execution once we are in debug mode */
1096 dscr
|= DSCR_ITR_EN
;
1097 retval
= mem_ap_write_atomic_u32(armv8
->debug_ap
,
1098 armv8
->debug_base
+ CPUDBG_DSCR
, dscr
);
1099 if (retval
!= ERROR_OK
)
1102 /* Examine debug reason */
1103 arm_dpm_report_dscr(&armv8
->dpm
, aarch64
->cpudbg_dscr
);
1104 mem_ap_read_atomic_u32(armv8
->debug_ap
,
1105 armv8
->debug_base
+ CPUDBG_DESR
, &tmp
);
1106 if ((tmp
& 0x7) == 0x4)
1107 target
->debug_reason
= DBG_REASON_SINGLESTEP
;
1109 /* save address of instruction that triggered the watchpoint? */
1110 if (target
->debug_reason
== DBG_REASON_WATCHPOINT
) {
1113 retval
= mem_ap_read_atomic_u32(armv8
->debug_ap
,
1114 armv8
->debug_base
+ CPUDBG_WFAR
,
1116 if (retval
!= ERROR_OK
)
1118 arm_dpm_report_wfar(&armv8
->dpm
, wfar
);
1121 retval
= armv8_dpm_read_current_registers(&armv8
->dpm
);
1123 if (armv8
->post_debug_entry
) {
1124 retval
= armv8
->post_debug_entry(target
);
1125 if (retval
!= ERROR_OK
)
1132 static int aarch64_post_debug_entry(struct target
*target
)
1134 struct aarch64_common
*aarch64
= target_to_aarch64(target
);
1135 struct armv8_common
*armv8
= &aarch64
->armv8_common
;
1136 struct armv8_mmu_common
*armv8_mmu
= &armv8
->armv8_mmu
;
1137 uint32_t sctlr_el1
= 0;
1140 mem_ap_write_atomic_u32(armv8
->debug_ap
,
1141 armv8
->debug_base
+ CPUDBG_DRCR
, 1<<2);
1142 retval
= aarch64_instr_read_data_r0(armv8
->arm
.dpm
,
1143 0xd5381000, &sctlr_el1
);
1144 if (retval
!= ERROR_OK
)
1147 LOG_DEBUG("sctlr_el1 = %#8.8x", sctlr_el1
);
1148 aarch64
->system_control_reg
= sctlr_el1
;
1149 aarch64
->system_control_reg_curr
= sctlr_el1
;
1150 aarch64
->curr_mode
= armv8
->arm
.core_mode
;
1152 armv8_mmu
->mmu_enabled
= sctlr_el1
& 0x1U
? 1 : 0;
1153 armv8_mmu
->armv8_cache
.d_u_cache_enabled
= sctlr_el1
& 0x4U
? 1 : 0;
1154 armv8_mmu
->armv8_cache
.i_cache_enabled
= sctlr_el1
& 0x1000U
? 1 : 0;
1157 if (armv8
->armv8_mmu
.armv8_cache
.ctype
== -1)
1158 armv8_identify_cache(target
);
1164 static int aarch64_step(struct target
*target
, int current
, target_addr_t address
,
1165 int handle_breakpoints
)
1167 struct armv8_common
*armv8
= target_to_armv8(target
);
1171 if (target
->state
!= TARGET_HALTED
) {
1172 LOG_WARNING("target not halted");
1173 return ERROR_TARGET_NOT_HALTED
;
1176 retval
= mem_ap_read_atomic_u32(armv8
->debug_ap
,
1177 armv8
->debug_base
+ CPUDBG_DECR
, &tmp
);
1178 if (retval
!= ERROR_OK
)
1181 retval
= mem_ap_write_atomic_u32(armv8
->debug_ap
,
1182 armv8
->debug_base
+ CPUDBG_DECR
, (tmp
|0x4));
1183 if (retval
!= ERROR_OK
)
1186 target
->debug_reason
= DBG_REASON_SINGLESTEP
;
1187 retval
= aarch64_resume(target
, 1, address
, 0, 0);
1188 if (retval
!= ERROR_OK
)
1191 long long then
= timeval_ms();
1192 while (target
->state
!= TARGET_HALTED
) {
1193 mem_ap_read_atomic_u32(armv8
->debug_ap
,
1194 armv8
->debug_base
+ CPUDBG_DESR
, &tmp
);
1195 LOG_DEBUG("DESR = %#x", tmp
);
1196 retval
= aarch64_poll(target
);
1197 if (retval
!= ERROR_OK
)
1199 if (timeval_ms() > then
+ 1000) {
1200 LOG_ERROR("timeout waiting for target halt");
1205 retval
= mem_ap_write_atomic_u32(armv8
->debug_ap
,
1206 armv8
->debug_base
+ CPUDBG_DECR
, (tmp
&(~0x4)));
1207 if (retval
!= ERROR_OK
)
1210 target_call_event_callbacks(target
, TARGET_EVENT_HALTED
);
1211 if (target
->state
== TARGET_HALTED
)
1212 LOG_DEBUG("target stepped");
1217 static int aarch64_restore_context(struct target
*target
, bool bpwp
)
1219 struct armv8_common
*armv8
= target_to_armv8(target
);
1223 if (armv8
->pre_restore_context
)
1224 armv8
->pre_restore_context(target
);
1226 return armv8_dpm_write_dirty_registers(&armv8
->dpm
, bpwp
);
1231 * Cortex-A8 Breakpoint and watchpoint functions
1234 /* Setup hardware Breakpoint Register Pair */
1235 static int aarch64_set_breakpoint(struct target
*target
,
1236 struct breakpoint
*breakpoint
, uint8_t matchmode
)
1241 uint8_t byte_addr_select
= 0x0F;
1242 struct aarch64_common
*aarch64
= target_to_aarch64(target
);
1243 struct armv8_common
*armv8
= &aarch64
->armv8_common
;
1244 struct aarch64_brp
*brp_list
= aarch64
->brp_list
;
1247 if (breakpoint
->set
) {
1248 LOG_WARNING("breakpoint already set");
1252 if (breakpoint
->type
== BKPT_HARD
) {
1254 while (brp_list
[brp_i
].used
&& (brp_i
< aarch64
->brp_num
))
1256 if (brp_i
>= aarch64
->brp_num
) {
1257 LOG_ERROR("ERROR Can not find free Breakpoint Register Pair");
1258 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1260 breakpoint
->set
= brp_i
+ 1;
1261 if (breakpoint
->length
== 2)
1262 byte_addr_select
= (3 << (breakpoint
->address
& 0x02));
1263 control
= ((matchmode
& 0x7) << 20)
1265 | (byte_addr_select
<< 5)
1267 brp_list
[brp_i
].used
= 1;
1268 brp_list
[brp_i
].value
= breakpoint
->address
& 0xFFFFFFFFFFFFFFFC;
1269 brp_list
[brp_i
].control
= control
;
1270 bpt_value
= brp_list
[brp_i
].value
;
1272 retval
= aarch64_dap_write_memap_register_u32(target
, armv8
->debug_base
1273 + CPUDBG_BVR_BASE
+ 16 * brp_list
[brp_i
].BRPn
,
1274 (uint32_t)(bpt_value
& 0xFFFFFFFF));
1275 if (retval
!= ERROR_OK
)
1277 retval
= aarch64_dap_write_memap_register_u32(target
, armv8
->debug_base
1278 + CPUDBG_BVR_BASE
+ 4 + 16 * brp_list
[brp_i
].BRPn
,
1279 (uint32_t)(bpt_value
>> 32));
1280 if (retval
!= ERROR_OK
)
1283 retval
= aarch64_dap_write_memap_register_u32(target
, armv8
->debug_base
1284 + CPUDBG_BCR_BASE
+ 16 * brp_list
[brp_i
].BRPn
,
1285 brp_list
[brp_i
].control
);
1286 if (retval
!= ERROR_OK
)
1288 LOG_DEBUG("brp %i control 0x%0" PRIx32
" value 0x%" TARGET_PRIxADDR
, brp_i
,
1289 brp_list
[brp_i
].control
,
1290 brp_list
[brp_i
].value
);
1292 } else if (breakpoint
->type
== BKPT_SOFT
) {
1294 buf_set_u32(code
, 0, 32, 0xD4400000);
1296 retval
= target_read_memory(target
,
1297 breakpoint
->address
& 0xFFFFFFFFFFFFFFFE,
1298 breakpoint
->length
, 1,
1299 breakpoint
->orig_instr
);
1300 if (retval
!= ERROR_OK
)
1302 retval
= target_write_memory(target
,
1303 breakpoint
->address
& 0xFFFFFFFFFFFFFFFE,
1304 breakpoint
->length
, 1, code
);
1305 if (retval
!= ERROR_OK
)
1307 breakpoint
->set
= 0x11; /* Any nice value but 0 */
1310 retval
= mem_ap_read_atomic_u32(armv8
->debug_ap
,
1311 armv8
->debug_base
+ CPUDBG_DSCR
, &dscr
);
1312 /* Ensure that halting debug mode is enable */
1313 dscr
= dscr
| DSCR_HALT_DBG_MODE
;
1314 retval
= mem_ap_write_atomic_u32(armv8
->debug_ap
,
1315 armv8
->debug_base
+ CPUDBG_DSCR
, dscr
);
1316 if (retval
!= ERROR_OK
) {
1317 LOG_DEBUG("Failed to set DSCR.HDE");
1324 static int aarch64_set_context_breakpoint(struct target
*target
,
1325 struct breakpoint
*breakpoint
, uint8_t matchmode
)
1327 int retval
= ERROR_FAIL
;
1330 uint8_t byte_addr_select
= 0x0F;
1331 struct aarch64_common
*aarch64
= target_to_aarch64(target
);
1332 struct armv8_common
*armv8
= &aarch64
->armv8_common
;
1333 struct aarch64_brp
*brp_list
= aarch64
->brp_list
;
1335 if (breakpoint
->set
) {
1336 LOG_WARNING("breakpoint already set");
1339 /*check available context BRPs*/
1340 while ((brp_list
[brp_i
].used
||
1341 (brp_list
[brp_i
].type
!= BRP_CONTEXT
)) && (brp_i
< aarch64
->brp_num
))
1344 if (brp_i
>= aarch64
->brp_num
) {
1345 LOG_ERROR("ERROR Can not find free Breakpoint Register Pair");
1349 breakpoint
->set
= brp_i
+ 1;
1350 control
= ((matchmode
& 0x7) << 20)
1351 | (byte_addr_select
<< 5)
1353 brp_list
[brp_i
].used
= 1;
1354 brp_list
[brp_i
].value
= (breakpoint
->asid
);
1355 brp_list
[brp_i
].control
= control
;
1356 retval
= aarch64_dap_write_memap_register_u32(target
, armv8
->debug_base
1357 + CPUDBG_BVR_BASE
+ 4 * brp_list
[brp_i
].BRPn
,
1358 brp_list
[brp_i
].value
);
1359 if (retval
!= ERROR_OK
)
1361 retval
= aarch64_dap_write_memap_register_u32(target
, armv8
->debug_base
1362 + CPUDBG_BCR_BASE
+ 4 * brp_list
[brp_i
].BRPn
,
1363 brp_list
[brp_i
].control
);
1364 if (retval
!= ERROR_OK
)
1366 LOG_DEBUG("brp %i control 0x%0" PRIx32
" value 0x%" TARGET_PRIxADDR
, brp_i
,
1367 brp_list
[brp_i
].control
,
1368 brp_list
[brp_i
].value
);
1373 static int aarch64_set_hybrid_breakpoint(struct target
*target
, struct breakpoint
*breakpoint
)
1375 int retval
= ERROR_FAIL
;
1376 int brp_1
= 0; /* holds the contextID pair */
1377 int brp_2
= 0; /* holds the IVA pair */
1378 uint32_t control_CTX
, control_IVA
;
1379 uint8_t CTX_byte_addr_select
= 0x0F;
1380 uint8_t IVA_byte_addr_select
= 0x0F;
1381 uint8_t CTX_machmode
= 0x03;
1382 uint8_t IVA_machmode
= 0x01;
1383 struct aarch64_common
*aarch64
= target_to_aarch64(target
);
1384 struct armv8_common
*armv8
= &aarch64
->armv8_common
;
1385 struct aarch64_brp
*brp_list
= aarch64
->brp_list
;
1387 if (breakpoint
->set
) {
1388 LOG_WARNING("breakpoint already set");
1391 /*check available context BRPs*/
1392 while ((brp_list
[brp_1
].used
||
1393 (brp_list
[brp_1
].type
!= BRP_CONTEXT
)) && (brp_1
< aarch64
->brp_num
))
1396 printf("brp(CTX) found num: %d\n", brp_1
);
1397 if (brp_1
>= aarch64
->brp_num
) {
1398 LOG_ERROR("ERROR Can not find free Breakpoint Register Pair");
1402 while ((brp_list
[brp_2
].used
||
1403 (brp_list
[brp_2
].type
!= BRP_NORMAL
)) && (brp_2
< aarch64
->brp_num
))
1406 printf("brp(IVA) found num: %d\n", brp_2
);
1407 if (brp_2
>= aarch64
->brp_num
) {
1408 LOG_ERROR("ERROR Can not find free Breakpoint Register Pair");
1412 breakpoint
->set
= brp_1
+ 1;
1413 breakpoint
->linked_BRP
= brp_2
;
1414 control_CTX
= ((CTX_machmode
& 0x7) << 20)
1417 | (CTX_byte_addr_select
<< 5)
1419 brp_list
[brp_1
].used
= 1;
1420 brp_list
[brp_1
].value
= (breakpoint
->asid
);
1421 brp_list
[brp_1
].control
= control_CTX
;
1422 retval
= aarch64_dap_write_memap_register_u32(target
, armv8
->debug_base
1423 + CPUDBG_BVR_BASE
+ 4 * brp_list
[brp_1
].BRPn
,
1424 brp_list
[brp_1
].value
);
1425 if (retval
!= ERROR_OK
)
1427 retval
= aarch64_dap_write_memap_register_u32(target
, armv8
->debug_base
1428 + CPUDBG_BCR_BASE
+ 4 * brp_list
[brp_1
].BRPn
,
1429 brp_list
[brp_1
].control
);
1430 if (retval
!= ERROR_OK
)
1433 control_IVA
= ((IVA_machmode
& 0x7) << 20)
1435 | (IVA_byte_addr_select
<< 5)
1437 brp_list
[brp_2
].used
= 1;
1438 brp_list
[brp_2
].value
= (breakpoint
->address
& 0xFFFFFFFC);
1439 brp_list
[brp_2
].control
= control_IVA
;
1440 retval
= aarch64_dap_write_memap_register_u32(target
, armv8
->debug_base
1441 + CPUDBG_BVR_BASE
+ 4 * brp_list
[brp_2
].BRPn
,
1442 brp_list
[brp_2
].value
);
1443 if (retval
!= ERROR_OK
)
1445 retval
= aarch64_dap_write_memap_register_u32(target
, armv8
->debug_base
1446 + CPUDBG_BCR_BASE
+ 4 * brp_list
[brp_2
].BRPn
,
1447 brp_list
[brp_2
].control
);
1448 if (retval
!= ERROR_OK
)
1454 static int aarch64_unset_breakpoint(struct target
*target
, struct breakpoint
*breakpoint
)
1457 struct aarch64_common
*aarch64
= target_to_aarch64(target
);
1458 struct armv8_common
*armv8
= &aarch64
->armv8_common
;
1459 struct aarch64_brp
*brp_list
= aarch64
->brp_list
;
1461 if (!breakpoint
->set
) {
1462 LOG_WARNING("breakpoint not set");
1466 if (breakpoint
->type
== BKPT_HARD
) {
1467 if ((breakpoint
->address
!= 0) && (breakpoint
->asid
!= 0)) {
1468 int brp_i
= breakpoint
->set
- 1;
1469 int brp_j
= breakpoint
->linked_BRP
;
1470 if ((brp_i
< 0) || (brp_i
>= aarch64
->brp_num
)) {
1471 LOG_DEBUG("Invalid BRP number in breakpoint");
1474 LOG_DEBUG("rbp %i control 0x%0" PRIx32
" value 0x%" TARGET_PRIxADDR
, brp_i
,
1475 brp_list
[brp_i
].control
, brp_list
[brp_i
].value
);
1476 brp_list
[brp_i
].used
= 0;
1477 brp_list
[brp_i
].value
= 0;
1478 brp_list
[brp_i
].control
= 0;
1479 retval
= aarch64_dap_write_memap_register_u32(target
, armv8
->debug_base
1480 + CPUDBG_BCR_BASE
+ 16 * brp_list
[brp_i
].BRPn
,
1481 brp_list
[brp_i
].control
);
1482 if (retval
!= ERROR_OK
)
1484 if ((brp_j
< 0) || (brp_j
>= aarch64
->brp_num
)) {
1485 LOG_DEBUG("Invalid BRP number in breakpoint");
1488 LOG_DEBUG("rbp %i control 0x%0" PRIx32
" value 0x%0" PRIx64
, brp_j
,
1489 brp_list
[brp_j
].control
, brp_list
[brp_j
].value
);
1490 brp_list
[brp_j
].used
= 0;
1491 brp_list
[brp_j
].value
= 0;
1492 brp_list
[brp_j
].control
= 0;
1493 retval
= aarch64_dap_write_memap_register_u32(target
, armv8
->debug_base
1494 + CPUDBG_BCR_BASE
+ 16 * brp_list
[brp_j
].BRPn
,
1495 brp_list
[brp_j
].control
);
1496 if (retval
!= ERROR_OK
)
1498 breakpoint
->linked_BRP
= 0;
1499 breakpoint
->set
= 0;
1503 int brp_i
= breakpoint
->set
- 1;
1504 if ((brp_i
< 0) || (brp_i
>= aarch64
->brp_num
)) {
1505 LOG_DEBUG("Invalid BRP number in breakpoint");
1508 LOG_DEBUG("rbp %i control 0x%0" PRIx32
" value 0x%0" PRIx64
, brp_i
,
1509 brp_list
[brp_i
].control
, brp_list
[brp_i
].value
);
1510 brp_list
[brp_i
].used
= 0;
1511 brp_list
[brp_i
].value
= 0;
1512 brp_list
[brp_i
].control
= 0;
1513 retval
= aarch64_dap_write_memap_register_u32(target
, armv8
->debug_base
1514 + CPUDBG_BCR_BASE
+ 4 * brp_list
[brp_i
].BRPn
,
1515 brp_list
[brp_i
].control
);
1516 if (retval
!= ERROR_OK
)
1518 retval
= aarch64_dap_write_memap_register_u32(target
, armv8
->debug_base
1519 + CPUDBG_BVR_BASE
+ 4 * brp_list
[brp_i
].BRPn
,
1520 brp_list
[brp_i
].value
);
1521 if (retval
!= ERROR_OK
)
1523 breakpoint
->set
= 0;
1527 /* restore original instruction (kept in target endianness) */
1528 if (breakpoint
->length
== 4) {
1529 retval
= target_write_memory(target
,
1530 breakpoint
->address
& 0xFFFFFFFFFFFFFFFE,
1531 4, 1, breakpoint
->orig_instr
);
1532 if (retval
!= ERROR_OK
)
1535 retval
= target_write_memory(target
,
1536 breakpoint
->address
& 0xFFFFFFFFFFFFFFFE,
1537 2, 1, breakpoint
->orig_instr
);
1538 if (retval
!= ERROR_OK
)
1542 breakpoint
->set
= 0;
1547 static int aarch64_add_breakpoint(struct target
*target
,
1548 struct breakpoint
*breakpoint
)
1550 struct aarch64_common
*aarch64
= target_to_aarch64(target
);
1552 if ((breakpoint
->type
== BKPT_HARD
) && (aarch64
->brp_num_available
< 1)) {
1553 LOG_INFO("no hardware breakpoint available");
1554 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1557 if (breakpoint
->type
== BKPT_HARD
)
1558 aarch64
->brp_num_available
--;
1560 return aarch64_set_breakpoint(target
, breakpoint
, 0x00); /* Exact match */
1563 static int aarch64_add_context_breakpoint(struct target
*target
,
1564 struct breakpoint
*breakpoint
)
1566 struct aarch64_common
*aarch64
= target_to_aarch64(target
);
1568 if ((breakpoint
->type
== BKPT_HARD
) && (aarch64
->brp_num_available
< 1)) {
1569 LOG_INFO("no hardware breakpoint available");
1570 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1573 if (breakpoint
->type
== BKPT_HARD
)
1574 aarch64
->brp_num_available
--;
1576 return aarch64_set_context_breakpoint(target
, breakpoint
, 0x02); /* asid match */
1579 static int aarch64_add_hybrid_breakpoint(struct target
*target
,
1580 struct breakpoint
*breakpoint
)
1582 struct aarch64_common
*aarch64
= target_to_aarch64(target
);
1584 if ((breakpoint
->type
== BKPT_HARD
) && (aarch64
->brp_num_available
< 1)) {
1585 LOG_INFO("no hardware breakpoint available");
1586 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1589 if (breakpoint
->type
== BKPT_HARD
)
1590 aarch64
->brp_num_available
--;
1592 return aarch64_set_hybrid_breakpoint(target
, breakpoint
); /* ??? */
1596 static int aarch64_remove_breakpoint(struct target
*target
, struct breakpoint
*breakpoint
)
1598 struct aarch64_common
*aarch64
= target_to_aarch64(target
);
1601 /* It is perfectly possible to remove breakpoints while the target is running */
1602 if (target
->state
!= TARGET_HALTED
) {
1603 LOG_WARNING("target not halted");
1604 return ERROR_TARGET_NOT_HALTED
;
1608 if (breakpoint
->set
) {
1609 aarch64_unset_breakpoint(target
, breakpoint
);
1610 if (breakpoint
->type
== BKPT_HARD
)
1611 aarch64
->brp_num_available
++;
1618 * Cortex-A8 Reset functions
1621 static int aarch64_assert_reset(struct target
*target
)
1623 struct armv8_common
*armv8
= target_to_armv8(target
);
1627 /* FIXME when halt is requested, make it work somehow... */
1629 /* Issue some kind of warm reset. */
1630 if (target_has_event_action(target
, TARGET_EVENT_RESET_ASSERT
))
1631 target_handle_event(target
, TARGET_EVENT_RESET_ASSERT
);
1632 else if (jtag_get_reset_config() & RESET_HAS_SRST
) {
1633 /* REVISIT handle "pulls" cases, if there's
1634 * hardware that needs them to work.
1636 jtag_add_reset(0, 1);
1638 LOG_ERROR("%s: how to reset?", target_name(target
));
1642 /* registers are now invalid */
1643 register_cache_invalidate(armv8
->arm
.core_cache
);
1645 target
->state
= TARGET_RESET
;
1650 static int aarch64_deassert_reset(struct target
*target
)
1656 /* be certain SRST is off */
1657 jtag_add_reset(0, 0);
1659 retval
= aarch64_poll(target
);
1660 if (retval
!= ERROR_OK
)
1663 if (target
->reset_halt
) {
1664 if (target
->state
!= TARGET_HALTED
) {
1665 LOG_WARNING("%s: ran after reset and before halt ...",
1666 target_name(target
));
1667 retval
= target_halt(target
);
1668 if (retval
!= ERROR_OK
)
1676 static int aarch64_write_apb_ap_memory(struct target
*target
,
1677 uint64_t address
, uint32_t size
,
1678 uint32_t count
, const uint8_t *buffer
)
1680 /* write memory through APB-AP */
1681 int retval
= ERROR_COMMAND_SYNTAX_ERROR
;
1682 struct armv8_common
*armv8
= target_to_armv8(target
);
1683 struct arm
*arm
= &armv8
->arm
;
1684 int total_bytes
= count
* size
;
1686 int start_byte
= address
& 0x3;
1687 int end_byte
= (address
+ total_bytes
) & 0x3;
1690 uint8_t *tmp_buff
= NULL
;
1692 LOG_DEBUG("Writing APB-AP memory address 0x%" PRIx64
" size %" PRIu32
" count%" PRIu32
,
1693 address
, size
, count
);
1694 if (target
->state
!= TARGET_HALTED
) {
1695 LOG_WARNING("target not halted");
1696 return ERROR_TARGET_NOT_HALTED
;
1699 total_u32
= DIV_ROUND_UP((address
& 3) + total_bytes
, 4);
1701 /* Mark register R0 as dirty, as it will be used
1702 * for transferring the data.
1703 * It will be restored automatically when exiting
1706 reg
= armv8_reg_current(arm
, 1);
1709 reg
= armv8_reg_current(arm
, 0);
1712 /* clear any abort */
1713 retval
= mem_ap_write_atomic_u32(armv8
->debug_ap
,
1714 armv8
->debug_base
+ CPUDBG_DRCR
, DRCR_CSE
);
1715 if (retval
!= ERROR_OK
)
1719 /* This algorithm comes from DDI0487A.g, chapter J9.1 */
1721 /* The algorithm only copies 32 bit words, so the buffer
1722 * should be expanded to include the words at either end.
1723 * The first and last words will be read first to avoid
1724 * corruption if needed.
1726 tmp_buff
= malloc(total_u32
* 4);
1728 if ((start_byte
!= 0) && (total_u32
> 1)) {
1729 /* First bytes not aligned - read the 32 bit word to avoid corrupting
1730 * the other bytes in the word.
1732 retval
= aarch64_read_apb_ap_memory(target
, (address
& ~0x3), 4, 1, tmp_buff
);
1733 if (retval
!= ERROR_OK
)
1734 goto error_free_buff_w
;
1737 /* If end of write is not aligned, or the write is less than 4 bytes */
1738 if ((end_byte
!= 0) ||
1739 ((total_u32
== 1) && (total_bytes
!= 4))) {
1741 /* Read the last word to avoid corruption during 32 bit write */
1742 int mem_offset
= (total_u32
-1) * 4;
1743 retval
= aarch64_read_apb_ap_memory(target
, (address
& ~0x3) + mem_offset
, 4, 1, &tmp_buff
[mem_offset
]);
1744 if (retval
!= ERROR_OK
)
1745 goto error_free_buff_w
;
1748 /* Copy the write buffer over the top of the temporary buffer */
1749 memcpy(&tmp_buff
[start_byte
], buffer
, total_bytes
);
1751 /* We now have a 32 bit aligned buffer that can be written */
1754 retval
= mem_ap_read_atomic_u32(armv8
->debug_ap
,
1755 armv8
->debug_base
+ CPUDBG_DSCR
, &dscr
);
1756 if (retval
!= ERROR_OK
)
1757 goto error_free_buff_w
;
1759 /* Set Normal access mode */
1760 dscr
= (dscr
& ~DSCR_MA
);
1761 retval
= mem_ap_write_atomic_u32(armv8
->debug_ap
,
1762 armv8
->debug_base
+ CPUDBG_DSCR
, dscr
);
1764 if (arm
->core_state
== ARM_STATE_AARCH64
) {
1765 /* Write X0 with value 'address' using write procedure */
1766 /* Step 1.a+b - Write the address for read access into DBGDTR_EL0 */
1767 retval
+= aarch64_write_dcc_64(armv8
, address
& ~0x3ULL
);
1768 /* Step 1.c - Copy value from DTR to R0 using instruction mrs DBGDTR_EL0, x0 */
1769 retval
+= aarch64_exec_opcode(target
,
1770 ARMV8_MRS(SYSTEM_DBG_DBGDTR_EL0
, 0), &dscr
);
1772 /* Write R0 with value 'address' using write procedure */
1773 /* Step 1.a+b - Write the address for read access into DBGDTRRX */
1774 retval
+= aarch64_write_dcc(armv8
, address
& ~0x3ULL
);
1775 /* Step 1.c - Copy value from DTR to R0 using instruction mrc DBGDTRTXint, r0 */
1776 retval
+= aarch64_exec_opcode(target
,
1777 T32_FMTITR(ARMV4_5_MRC(14, 0, 0, 0, 5, 0)), &dscr
);
1780 /* Step 1.d - Change DCC to memory mode */
1781 dscr
= dscr
| DSCR_MA
;
1782 retval
+= mem_ap_write_atomic_u32(armv8
->debug_ap
,
1783 armv8
->debug_base
+ CPUDBG_DSCR
, dscr
);
1784 if (retval
!= ERROR_OK
)
1785 goto error_unset_dtr_w
;
1788 /* Step 2.a - Do the write */
1789 retval
= mem_ap_write_buf_noincr(armv8
->debug_ap
,
1790 tmp_buff
, 4, total_u32
, armv8
->debug_base
+ CPUDBG_DTRRX
);
1791 if (retval
!= ERROR_OK
)
1792 goto error_unset_dtr_w
;
1794 /* Step 3.a - Switch DTR mode back to Normal mode */
1795 dscr
= (dscr
& ~DSCR_MA
);
1796 retval
= mem_ap_write_atomic_u32(armv8
->debug_ap
,
1797 armv8
->debug_base
+ CPUDBG_DSCR
, dscr
);
1798 if (retval
!= ERROR_OK
)
1799 goto error_unset_dtr_w
;
1801 /* Check for sticky abort flags in the DSCR */
1802 retval
= mem_ap_read_atomic_u32(armv8
->debug_ap
,
1803 armv8
->debug_base
+ CPUDBG_DSCR
, &dscr
);
1804 if (retval
!= ERROR_OK
)
1805 goto error_free_buff_w
;
1806 if (dscr
& (DSCR_ERR
| DSCR_SYS_ERROR_PEND
)) {
1807 /* Abort occurred - clear it and exit */
1808 LOG_ERROR("abort occurred - dscr = 0x%08" PRIx32
, dscr
);
1809 mem_ap_write_atomic_u32(armv8
->debug_ap
,
1810 armv8
->debug_base
+ CPUDBG_DRCR
, 1<<2);
1811 goto error_free_buff_w
;
1819 /* Unset DTR mode */
1820 mem_ap_read_atomic_u32(armv8
->debug_ap
,
1821 armv8
->debug_base
+ CPUDBG_DSCR
, &dscr
);
1822 dscr
= (dscr
& ~DSCR_MA
);
1823 mem_ap_write_atomic_u32(armv8
->debug_ap
,
1824 armv8
->debug_base
+ CPUDBG_DSCR
, dscr
);
1831 static int aarch64_read_apb_ap_memory(struct target
*target
,
1832 target_addr_t address
, uint32_t size
,
1833 uint32_t count
, uint8_t *buffer
)
1835 /* read memory through APB-AP */
1836 int retval
= ERROR_COMMAND_SYNTAX_ERROR
;
1837 struct armv8_common
*armv8
= target_to_armv8(target
);
1838 struct arm
*arm
= &armv8
->arm
;
1839 int total_bytes
= count
* size
;
1841 int start_byte
= address
& 0x3;
1842 int end_byte
= (address
+ total_bytes
) & 0x3;
1845 uint8_t *tmp_buff
= NULL
;
1849 LOG_DEBUG("Reading APB-AP memory address 0x%" TARGET_PRIxADDR
" size %" PRIu32
" count%" PRIu32
,
1850 address
, size
, count
);
1851 if (target
->state
!= TARGET_HALTED
) {
1852 LOG_WARNING("target not halted");
1853 return ERROR_TARGET_NOT_HALTED
;
1856 total_u32
= DIV_ROUND_UP((address
& 3) + total_bytes
, 4);
1857 /* Mark register X0, X1 as dirty, as it will be used
1858 * for transferring the data.
1859 * It will be restored automatically when exiting
1862 reg
= armv8_reg_current(arm
, 1);
1865 reg
= armv8_reg_current(arm
, 0);
1868 /* clear any abort */
1869 retval
= mem_ap_write_atomic_u32(armv8
->debug_ap
,
1870 armv8
->debug_base
+ CPUDBG_DRCR
, DRCR_CSE
);
1871 if (retval
!= ERROR_OK
)
1872 goto error_free_buff_r
;
1875 retval
= mem_ap_read_atomic_u32(armv8
->debug_ap
,
1876 armv8
->debug_base
+ CPUDBG_DSCR
, &dscr
);
1878 /* This algorithm comes from DDI0487A.g, chapter J9.1 */
1880 /* Set Normal access mode */
1881 dscr
= (dscr
& ~DSCR_MA
);
1882 retval
+= mem_ap_write_atomic_u32(armv8
->debug_ap
,
1883 armv8
->debug_base
+ CPUDBG_DSCR
, dscr
);
1885 if (arm
->core_state
== ARM_STATE_AARCH64
) {
1886 /* Write X0 with value 'address' using write procedure */
1887 /* Step 1.a+b - Write the address for read access into DBGDTR_EL0 */
1888 retval
+= aarch64_write_dcc_64(armv8
, address
& ~0x3ULL
);
1889 /* Step 1.c - Copy value from DTR to R0 using instruction mrs DBGDTR_EL0, x0 */
1890 retval
+= aarch64_exec_opcode(target
, ARMV8_MRS(SYSTEM_DBG_DBGDTR_EL0
, 0), &dscr
);
1891 /* Step 1.d - Dummy operation to ensure EDSCR.Txfull == 1 */
1892 retval
+= aarch64_exec_opcode(target
, ARMV8_MSR_GP(SYSTEM_DBG_DBGDTR_EL0
, 0), &dscr
);
1893 /* Step 1.e - Change DCC to memory mode */
1894 dscr
= dscr
| DSCR_MA
;
1895 retval
+= mem_ap_write_atomic_u32(armv8
->debug_ap
,
1896 armv8
->debug_base
+ CPUDBG_DSCR
, dscr
);
1897 /* Step 1.f - read DBGDTRTX and discard the value */
1898 retval
+= mem_ap_read_atomic_u32(armv8
->debug_ap
,
1899 armv8
->debug_base
+ CPUDBG_DTRTX
, &value
);
1901 /* Write R0 with value 'address' using write procedure */
1902 /* Step 1.a+b - Write the address for read access into DBGDTRRXint */
1903 retval
+= aarch64_write_dcc(armv8
, address
& ~0x3ULL
);
1904 /* Step 1.c - Copy value from DTR to R0 using instruction mrc DBGDTRTXint, r0 */
1905 retval
+= aarch64_exec_opcode(target
,
1906 T32_FMTITR(ARMV4_5_MRC(14, 0, 0, 0, 5, 0)), &dscr
);
1907 /* Step 1.d - Dummy operation to ensure EDSCR.Txfull == 1 */
1908 retval
+= aarch64_exec_opcode(target
,
1909 T32_FMTITR(ARMV4_5_MCR(14, 0, 0, 0, 5, 0)), &dscr
);
1910 /* Step 1.e - Change DCC to memory mode */
1911 dscr
= dscr
| DSCR_MA
;
1912 retval
+= mem_ap_write_atomic_u32(armv8
->debug_ap
,
1913 armv8
->debug_base
+ CPUDBG_DSCR
, dscr
);
1914 /* Step 1.f - read DBGDTRTX and discard the value */
1915 retval
+= mem_ap_read_atomic_u32(armv8
->debug_ap
,
1916 armv8
->debug_base
+ CPUDBG_DTRTX
, &value
);
1919 if (retval
!= ERROR_OK
)
1920 goto error_unset_dtr_r
;
1922 /* Optimize the read as much as we can, either way we read in a single pass */
1923 if ((start_byte
) || (end_byte
)) {
1924 /* The algorithm only copies 32 bit words, so the buffer
1925 * should be expanded to include the words at either end.
1926 * The first and last words will be read into a temp buffer
1927 * to avoid corruption
1929 tmp_buff
= malloc(total_u32
* 4);
1931 goto error_unset_dtr_r
;
1933 /* use the tmp buffer to read the entire data */
1934 u8buf_ptr
= tmp_buff
;
1936 /* address and read length are aligned so read directly into the passed buffer */
1939 /* Read the data - Each read of the DTRTX register causes the instruction to be reissued
1940 * Abort flags are sticky, so can be read at end of transactions
1942 * This data is read in aligned to 32 bit boundary.
1945 /* Step 2.a - Loop n-1 times, each read of DBGDTRTX reads the data from [X0] and
1946 * increments X0 by 4. */
1947 retval
= mem_ap_read_buf_noincr(armv8
->debug_ap
, u8buf_ptr
, 4, total_u32
-1,
1948 armv8
->debug_base
+ CPUDBG_DTRTX
);
1949 if (retval
!= ERROR_OK
)
1950 goto error_unset_dtr_r
;
1952 /* Step 3.a - set DTR access mode back to Normal mode */
1953 dscr
= (dscr
& ~DSCR_MA
);
1954 retval
= mem_ap_write_atomic_u32(armv8
->debug_ap
,
1955 armv8
->debug_base
+ CPUDBG_DSCR
, dscr
);
1956 if (retval
!= ERROR_OK
)
1957 goto error_free_buff_r
;
1959 /* Step 3.b - read DBGDTRTX for the final value */
1960 retval
= mem_ap_read_atomic_u32(armv8
->debug_ap
,
1961 armv8
->debug_base
+ CPUDBG_DTRTX
, &value
);
1962 memcpy(u8buf_ptr
+ (total_u32
-1) * 4, &value
, 4);
1964 /* Check for sticky abort flags in the DSCR */
1965 retval
= mem_ap_read_atomic_u32(armv8
->debug_ap
,
1966 armv8
->debug_base
+ CPUDBG_DSCR
, &dscr
);
1967 if (retval
!= ERROR_OK
)
1968 goto error_free_buff_r
;
1969 if (dscr
& (DSCR_ERR
| DSCR_SYS_ERROR_PEND
)) {
1970 /* Abort occurred - clear it and exit */
1971 LOG_ERROR("abort occurred - dscr = 0x%08" PRIx32
, dscr
);
1972 mem_ap_write_atomic_u32(armv8
->debug_ap
,
1973 armv8
->debug_base
+ CPUDBG_DRCR
, DRCR_CSE
);
1974 goto error_free_buff_r
;
1977 /* check if we need to copy aligned data by applying any shift necessary */
1979 memcpy(buffer
, tmp_buff
+ start_byte
, total_bytes
);
1987 /* Unset DTR mode */
1988 mem_ap_read_atomic_u32(armv8
->debug_ap
,
1989 armv8
->debug_base
+ CPUDBG_DSCR
, &dscr
);
1990 dscr
= (dscr
& ~DSCR_MA
);
1991 mem_ap_write_atomic_u32(armv8
->debug_ap
,
1992 armv8
->debug_base
+ CPUDBG_DSCR
, dscr
);
1999 static int aarch64_read_phys_memory(struct target
*target
,
2000 target_addr_t address
, uint32_t size
,
2001 uint32_t count
, uint8_t *buffer
)
2003 struct armv8_common
*armv8
= target_to_armv8(target
);
2004 int retval
= ERROR_COMMAND_SYNTAX_ERROR
;
2005 struct adiv5_dap
*swjdp
= armv8
->arm
.dap
;
2006 uint8_t apsel
= swjdp
->apsel
;
2007 LOG_DEBUG("Reading memory at real address 0x%" TARGET_PRIxADDR
"; size %" PRId32
"; count %" PRId32
,
2008 address
, size
, count
);
2010 if (count
&& buffer
) {
2012 if (armv8
->memory_ap_available
&& (apsel
== armv8
->memory_ap
->ap_num
)) {
2014 /* read memory through AHB-AP */
2015 retval
= mem_ap_read_buf(armv8
->memory_ap
, buffer
, size
, count
, address
);
2017 /* read memory through APB-AP */
2018 retval
= aarch64_mmu_modify(target
, 0);
2019 if (retval
!= ERROR_OK
)
2021 retval
= aarch64_read_apb_ap_memory(target
, address
, size
, count
, buffer
);
2027 static int aarch64_read_memory(struct target
*target
, target_addr_t address
,
2028 uint32_t size
, uint32_t count
, uint8_t *buffer
)
2030 int mmu_enabled
= 0;
2031 target_addr_t virt
, phys
;
2033 struct armv8_common
*armv8
= target_to_armv8(target
);
2034 struct adiv5_dap
*swjdp
= armv8
->arm
.dap
;
2035 uint8_t apsel
= swjdp
->apsel
;
2037 /* aarch64 handles unaligned memory access */
2038 LOG_DEBUG("Reading memory at address 0x%" TARGET_PRIxADDR
"; size %" PRId32
"; count %" PRId32
, address
,
2041 /* determine if MMU was enabled on target stop */
2042 if (!armv8
->is_armv7r
) {
2043 retval
= aarch64_mmu(target
, &mmu_enabled
);
2044 if (retval
!= ERROR_OK
)
2048 if (armv8
->memory_ap_available
&& (apsel
== armv8
->memory_ap
->ap_num
)) {
2051 retval
= aarch64_virt2phys(target
, virt
, &phys
);
2052 if (retval
!= ERROR_OK
)
2055 LOG_DEBUG("Reading at virtual address. Translating v:0x%" TARGET_PRIxADDR
" to r:0x%" TARGET_PRIxADDR
,
2059 retval
= aarch64_read_phys_memory(target
, address
, size
, count
,
2063 retval
= aarch64_check_address(target
, address
);
2064 if (retval
!= ERROR_OK
)
2066 /* enable MMU as we could have disabled it for phys
2068 retval
= aarch64_mmu_modify(target
, 1);
2069 if (retval
!= ERROR_OK
)
2072 retval
= aarch64_read_apb_ap_memory(target
, address
, size
,
2078 static int aarch64_write_phys_memory(struct target
*target
,
2079 target_addr_t address
, uint32_t size
,
2080 uint32_t count
, const uint8_t *buffer
)
2082 struct armv8_common
*armv8
= target_to_armv8(target
);
2083 struct adiv5_dap
*swjdp
= armv8
->arm
.dap
;
2084 int retval
= ERROR_COMMAND_SYNTAX_ERROR
;
2085 uint8_t apsel
= swjdp
->apsel
;
2087 LOG_DEBUG("Writing memory to real address 0x%" TARGET_PRIxADDR
"; size %" PRId32
"; count %" PRId32
, address
,
2090 if (count
&& buffer
) {
2092 if (armv8
->memory_ap_available
&& (apsel
== armv8
->memory_ap
->ap_num
)) {
2094 /* write memory through AHB-AP */
2095 retval
= mem_ap_write_buf(armv8
->memory_ap
, buffer
, size
, count
, address
);
2098 /* write memory through APB-AP */
2099 if (!armv8
->is_armv7r
) {
2100 retval
= aarch64_mmu_modify(target
, 0);
2101 if (retval
!= ERROR_OK
)
2104 return aarch64_write_apb_ap_memory(target
, address
, size
, count
, buffer
);
2109 /* REVISIT this op is generic ARMv7-A/R stuff */
2110 if (retval
== ERROR_OK
&& target
->state
== TARGET_HALTED
) {
2111 struct arm_dpm
*dpm
= armv8
->arm
.dpm
;
2113 retval
= dpm
->prepare(dpm
);
2114 if (retval
!= ERROR_OK
)
2117 /* The Cache handling will NOT work with MMU active, the
2118 * wrong addresses will be invalidated!
2120 * For both ICache and DCache, walk all cache lines in the
2121 * address range. Cortex-A8 has fixed 64 byte line length.
2123 * REVISIT per ARMv7, these may trigger watchpoints ...
2126 /* invalidate I-Cache */
2127 if (armv8
->armv8_mmu
.armv8_cache
.i_cache_enabled
) {
2128 /* ICIMVAU - Invalidate Cache single entry
2130 * MCR p15, 0, r0, c7, c5, 1
2132 for (uint32_t cacheline
= address
;
2133 cacheline
< address
+ size
* count
;
2135 retval
= dpm
->instr_write_data_r0(dpm
,
2136 ARMV4_5_MCR(15, 0, 0, 7, 5, 1),
2138 if (retval
!= ERROR_OK
)
2143 /* invalidate D-Cache */
2144 if (armv8
->armv8_mmu
.armv8_cache
.d_u_cache_enabled
) {
2145 /* DCIMVAC - Invalidate data Cache line
2147 * MCR p15, 0, r0, c7, c6, 1
2149 for (uint32_t cacheline
= address
;
2150 cacheline
< address
+ size
* count
;
2152 retval
= dpm
->instr_write_data_r0(dpm
,
2153 ARMV4_5_MCR(15, 0, 0, 7, 6, 1),
2155 if (retval
!= ERROR_OK
)
2160 /* (void) */ dpm
->finish(dpm
);
2166 static int aarch64_write_memory(struct target
*target
, target_addr_t address
,
2167 uint32_t size
, uint32_t count
, const uint8_t *buffer
)
2169 int mmu_enabled
= 0;
2170 target_addr_t virt
, phys
;
2172 struct armv8_common
*armv8
= target_to_armv8(target
);
2173 struct adiv5_dap
*swjdp
= armv8
->arm
.dap
;
2174 uint8_t apsel
= swjdp
->apsel
;
2176 /* aarch64 handles unaligned memory access */
2177 LOG_DEBUG("Writing memory at address 0x%" TARGET_PRIxADDR
"; size %" PRId32
2178 "; count %" PRId32
, address
, size
, count
);
2180 /* determine if MMU was enabled on target stop */
2181 if (!armv8
->is_armv7r
) {
2182 retval
= aarch64_mmu(target
, &mmu_enabled
);
2183 if (retval
!= ERROR_OK
)
2187 if (armv8
->memory_ap_available
&& (apsel
== armv8
->memory_ap
->ap_num
)) {
2188 LOG_DEBUG("Writing memory to address 0x%" TARGET_PRIxADDR
"; size %"
2189 PRId32
"; count %" PRId32
, address
, size
, count
);
2192 retval
= aarch64_virt2phys(target
, virt
, &phys
);
2193 if (retval
!= ERROR_OK
)
2196 LOG_DEBUG("Writing to virtual address. Translating v:0x%"
2197 TARGET_PRIxADDR
" to r:0x%" TARGET_PRIxADDR
, virt
, phys
);
2200 retval
= aarch64_write_phys_memory(target
, address
, size
,
2204 retval
= aarch64_check_address(target
, address
);
2205 if (retval
!= ERROR_OK
)
2207 /* enable MMU as we could have disabled it for phys access */
2208 retval
= aarch64_mmu_modify(target
, 1);
2209 if (retval
!= ERROR_OK
)
2212 retval
= aarch64_write_apb_ap_memory(target
, address
, size
, count
, buffer
);
2217 static int aarch64_handle_target_request(void *priv
)
2219 struct target
*target
= priv
;
2220 struct armv8_common
*armv8
= target_to_armv8(target
);
2223 if (!target_was_examined(target
))
2225 if (!target
->dbg_msg_enabled
)
2228 if (target
->state
== TARGET_RUNNING
) {
2231 retval
= mem_ap_read_atomic_u32(armv8
->debug_ap
,
2232 armv8
->debug_base
+ CPUDBG_DSCR
, &dscr
);
2234 /* check if we have data */
2235 while ((dscr
& DSCR_DTR_TX_FULL
) && (retval
== ERROR_OK
)) {
2236 retval
= mem_ap_read_atomic_u32(armv8
->debug_ap
,
2237 armv8
->debug_base
+ CPUDBG_DTRTX
, &request
);
2238 if (retval
== ERROR_OK
) {
2239 target_request(target
, request
);
2240 retval
= mem_ap_read_atomic_u32(armv8
->debug_ap
,
2241 armv8
->debug_base
+ CPUDBG_DSCR
, &dscr
);
2249 static int aarch64_examine_first(struct target
*target
)
2251 struct aarch64_common
*aarch64
= target_to_aarch64(target
);
2252 struct armv8_common
*armv8
= &aarch64
->armv8_common
;
2253 struct adiv5_dap
*swjdp
= armv8
->arm
.dap
;
2254 int retval
= ERROR_OK
;
2255 uint32_t pfr
, debug
, ctypr
, ttypr
, cpuid
;
2258 /* We do one extra read to ensure DAP is configured,
2259 * we call ahbap_debugport_init(swjdp) instead
2261 retval
= dap_dp_init(swjdp
);
2262 if (retval
!= ERROR_OK
)
2265 /* Search for the APB-AB - it is needed for access to debug registers */
2266 retval
= dap_find_ap(swjdp
, AP_TYPE_APB_AP
, &armv8
->debug_ap
);
2267 if (retval
!= ERROR_OK
) {
2268 LOG_ERROR("Could not find APB-AP for debug access");
2272 retval
= mem_ap_init(armv8
->debug_ap
);
2273 if (retval
!= ERROR_OK
) {
2274 LOG_ERROR("Could not initialize the APB-AP");
2278 armv8
->debug_ap
->memaccess_tck
= 80;
2280 /* Search for the AHB-AB */
2281 armv8
->memory_ap_available
= false;
2282 retval
= dap_find_ap(swjdp
, AP_TYPE_AHB_AP
, &armv8
->memory_ap
);
2283 if (retval
== ERROR_OK
) {
2284 retval
= mem_ap_init(armv8
->memory_ap
);
2285 if (retval
== ERROR_OK
)
2286 armv8
->memory_ap_available
= true;
2288 if (retval
!= ERROR_OK
) {
2289 /* AHB-AP not found or unavailable - use the CPU */
2290 LOG_DEBUG("No AHB-AP available for memory access");
2294 if (!target
->dbgbase_set
) {
2296 /* Get ROM Table base */
2298 int32_t coreidx
= target
->coreid
;
2299 retval
= dap_get_debugbase(armv8
->debug_ap
, &dbgbase
, &apid
);
2300 if (retval
!= ERROR_OK
)
2302 /* Lookup 0x15 -- Processor DAP */
2303 retval
= dap_lookup_cs_component(armv8
->debug_ap
, dbgbase
, 0x15,
2304 &armv8
->debug_base
, &coreidx
);
2305 if (retval
!= ERROR_OK
)
2307 LOG_DEBUG("Detected core %" PRId32
" dbgbase: %08" PRIx32
,
2308 coreidx
, armv8
->debug_base
);
2310 armv8
->debug_base
= target
->dbgbase
;
2312 retval
= mem_ap_write_atomic_u32(armv8
->debug_ap
,
2313 armv8
->debug_base
+ 0x300, 0);
2314 if (retval
!= ERROR_OK
) {
2315 LOG_DEBUG("Examine %s failed", "oslock");
2319 retval
= mem_ap_read_atomic_u32(armv8
->debug_ap
,
2320 armv8
->debug_base
+ 0x88, &cpuid
);
2321 LOG_DEBUG("0x88 = %x", cpuid
);
2323 retval
= mem_ap_read_atomic_u32(armv8
->debug_ap
,
2324 armv8
->debug_base
+ 0x314, &cpuid
);
2325 LOG_DEBUG("0x314 = %x", cpuid
);
2327 retval
= mem_ap_read_atomic_u32(armv8
->debug_ap
,
2328 armv8
->debug_base
+ 0x310, &cpuid
);
2329 LOG_DEBUG("0x310 = %x", cpuid
);
2330 if (retval
!= ERROR_OK
)
2333 retval
= mem_ap_read_atomic_u32(armv8
->debug_ap
,
2334 armv8
->debug_base
+ CPUDBG_CPUID
, &cpuid
);
2335 if (retval
!= ERROR_OK
) {
2336 LOG_DEBUG("Examine %s failed", "CPUID");
2340 retval
= mem_ap_read_atomic_u32(armv8
->debug_ap
,
2341 armv8
->debug_base
+ CPUDBG_CTYPR
, &ctypr
);
2342 if (retval
!= ERROR_OK
) {
2343 LOG_DEBUG("Examine %s failed", "CTYPR");
2347 retval
= mem_ap_read_atomic_u32(armv8
->debug_ap
,
2348 armv8
->debug_base
+ CPUDBG_TTYPR
, &ttypr
);
2349 if (retval
!= ERROR_OK
) {
2350 LOG_DEBUG("Examine %s failed", "TTYPR");
2354 retval
= mem_ap_read_atomic_u32(armv8
->debug_ap
,
2355 armv8
->debug_base
+ ID_AA64PFR0_EL1
, &pfr
);
2356 if (retval
!= ERROR_OK
) {
2357 LOG_DEBUG("Examine %s failed", "ID_AA64DFR0_EL1");
2360 retval
= mem_ap_read_atomic_u32(armv8
->debug_ap
,
2361 armv8
->debug_base
+ ID_AA64DFR0_EL1
, &debug
);
2362 if (retval
!= ERROR_OK
) {
2363 LOG_DEBUG("Examine %s failed", "ID_AA64DFR0_EL1");
2367 LOG_DEBUG("cpuid = 0x%08" PRIx32
, cpuid
);
2368 LOG_DEBUG("ctypr = 0x%08" PRIx32
, ctypr
);
2369 LOG_DEBUG("ttypr = 0x%08" PRIx32
, ttypr
);
2370 LOG_DEBUG("ID_AA64PFR0_EL1 = 0x%08" PRIx32
, pfr
);
2371 LOG_DEBUG("ID_AA64DFR0_EL1 = 0x%08" PRIx32
, debug
);
2373 armv8
->arm
.core_type
= ARM_MODE_MON
;
2374 armv8
->arm
.core_state
= ARM_STATE_AARCH64
;
2375 retval
= aarch64_dpm_setup(aarch64
, debug
);
2376 if (retval
!= ERROR_OK
)
2379 /* Setup Breakpoint Register Pairs */
2380 aarch64
->brp_num
= ((debug
>> 12) & 0x0F) + 1;
2381 aarch64
->brp_num_context
= ((debug
>> 28) & 0x0F) + 1;
2383 /* hack - no context bpt support yet */
2384 aarch64
->brp_num_context
= 0;
2386 aarch64
->brp_num_available
= aarch64
->brp_num
;
2387 aarch64
->brp_list
= calloc(aarch64
->brp_num
, sizeof(struct aarch64_brp
));
2388 for (i
= 0; i
< aarch64
->brp_num
; i
++) {
2389 aarch64
->brp_list
[i
].used
= 0;
2390 if (i
< (aarch64
->brp_num
-aarch64
->brp_num_context
))
2391 aarch64
->brp_list
[i
].type
= BRP_NORMAL
;
2393 aarch64
->brp_list
[i
].type
= BRP_CONTEXT
;
2394 aarch64
->brp_list
[i
].value
= 0;
2395 aarch64
->brp_list
[i
].control
= 0;
2396 aarch64
->brp_list
[i
].BRPn
= i
;
2399 LOG_DEBUG("Configured %i hw breakpoints", aarch64
->brp_num
);
2401 target_set_examined(target
);
2405 static int aarch64_examine(struct target
*target
)
2407 int retval
= ERROR_OK
;
2409 /* don't re-probe hardware after each reset */
2410 if (!target_was_examined(target
))
2411 retval
= aarch64_examine_first(target
);
2413 /* Configure core debug access */
2414 if (retval
== ERROR_OK
)
2415 retval
= aarch64_init_debug_access(target
);
2421 * Cortex-A8 target creation and initialization
2424 static int aarch64_init_target(struct command_context
*cmd_ctx
,
2425 struct target
*target
)
2427 /* examine_first() does a bunch of this */
2431 static int aarch64_init_arch_info(struct target
*target
,
2432 struct aarch64_common
*aarch64
, struct jtag_tap
*tap
)
2434 struct armv8_common
*armv8
= &aarch64
->armv8_common
;
2435 struct adiv5_dap
*dap
= armv8
->arm
.dap
;
2437 armv8
->arm
.dap
= dap
;
2439 /* Setup struct aarch64_common */
2440 aarch64
->common_magic
= AARCH64_COMMON_MAGIC
;
2441 /* tap has no dap initialized */
2443 tap
->dap
= dap_init();
2445 /* Leave (only) generic DAP stuff for debugport_init() */
2446 tap
->dap
->tap
= tap
;
2449 armv8
->arm
.dap
= tap
->dap
;
2451 aarch64
->fast_reg_read
= 0;
2453 /* register arch-specific functions */
2454 armv8
->examine_debug_reason
= NULL
;
2456 armv8
->post_debug_entry
= aarch64_post_debug_entry
;
2458 armv8
->pre_restore_context
= NULL
;
2460 armv8
->armv8_mmu
.read_physical_memory
= aarch64_read_phys_memory
;
2462 /* REVISIT v7a setup should be in a v7a-specific routine */
2463 armv8_init_arch_info(target
, armv8
);
2464 target_register_timer_callback(aarch64_handle_target_request
, 1, 1, target
);
2469 static int aarch64_target_create(struct target
*target
, Jim_Interp
*interp
)
2471 struct aarch64_common
*aarch64
= calloc(1, sizeof(struct aarch64_common
));
2473 aarch64
->armv8_common
.is_armv7r
= false;
2475 return aarch64_init_arch_info(target
, aarch64
, target
->tap
);
2478 static int aarch64_mmu(struct target
*target
, int *enabled
)
2480 if (target
->state
!= TARGET_HALTED
) {
2481 LOG_ERROR("%s: target not halted", __func__
);
2482 return ERROR_TARGET_INVALID
;
2485 *enabled
= target_to_aarch64(target
)->armv8_common
.armv8_mmu
.mmu_enabled
;
2489 static int aarch64_virt2phys(struct target
*target
, target_addr_t virt
,
2490 target_addr_t
*phys
)
2492 int retval
= ERROR_FAIL
;
2493 struct armv8_common
*armv8
= target_to_armv8(target
);
2494 struct adiv5_dap
*swjdp
= armv8
->arm
.dap
;
2495 uint8_t apsel
= swjdp
->apsel
;
2496 if (armv8
->memory_ap_available
&& (apsel
== armv8
->memory_ap
->ap_num
)) {
2498 retval
= armv8_mmu_translate_va(target
,
2500 if (retval
!= ERROR_OK
)
2503 } else {/* use this method if armv8->memory_ap not selected
2504 * mmu must be enable in order to get a correct translation */
2505 retval
= aarch64_mmu_modify(target
, 1);
2506 if (retval
!= ERROR_OK
)
2508 retval
= armv8_mmu_translate_va_pa(target
, virt
, phys
, 1);
2514 COMMAND_HANDLER(aarch64_handle_cache_info_command
)
2516 struct target
*target
= get_current_target(CMD_CTX
);
2517 struct armv8_common
*armv8
= target_to_armv8(target
);
2519 return armv8_handle_cache_info_command(CMD_CTX
,
2520 &armv8
->armv8_mmu
.armv8_cache
);
2524 COMMAND_HANDLER(aarch64_handle_dbginit_command
)
2526 struct target
*target
= get_current_target(CMD_CTX
);
2527 if (!target_was_examined(target
)) {
2528 LOG_ERROR("target not examined yet");
2532 return aarch64_init_debug_access(target
);
2534 COMMAND_HANDLER(aarch64_handle_smp_off_command
)
2536 struct target
*target
= get_current_target(CMD_CTX
);
2537 /* check target is an smp target */
2538 struct target_list
*head
;
2539 struct target
*curr
;
2540 head
= target
->head
;
2542 if (head
!= (struct target_list
*)NULL
) {
2543 while (head
!= (struct target_list
*)NULL
) {
2544 curr
= head
->target
;
2548 /* fixes the target display to the debugger */
2549 target
->gdb_service
->target
= target
;
2554 COMMAND_HANDLER(aarch64_handle_smp_on_command
)
2556 struct target
*target
= get_current_target(CMD_CTX
);
2557 struct target_list
*head
;
2558 struct target
*curr
;
2559 head
= target
->head
;
2560 if (head
!= (struct target_list
*)NULL
) {
2562 while (head
!= (struct target_list
*)NULL
) {
2563 curr
= head
->target
;
2571 COMMAND_HANDLER(aarch64_handle_smp_gdb_command
)
2573 struct target
*target
= get_current_target(CMD_CTX
);
2574 int retval
= ERROR_OK
;
2575 struct target_list
*head
;
2576 head
= target
->head
;
2577 if (head
!= (struct target_list
*)NULL
) {
2578 if (CMD_ARGC
== 1) {
2580 COMMAND_PARSE_NUMBER(int, CMD_ARGV
[0], coreid
);
2581 if (ERROR_OK
!= retval
)
2583 target
->gdb_service
->core
[1] = coreid
;
2586 command_print(CMD_CTX
, "gdb coreid %" PRId32
" -> %" PRId32
, target
->gdb_service
->core
[0]
2587 , target
->gdb_service
->core
[1]);
2592 static const struct command_registration aarch64_exec_command_handlers
[] = {
2594 .name
= "cache_info",
2595 .handler
= aarch64_handle_cache_info_command
,
2596 .mode
= COMMAND_EXEC
,
2597 .help
= "display information about target caches",
2602 .handler
= aarch64_handle_dbginit_command
,
2603 .mode
= COMMAND_EXEC
,
2604 .help
= "Initialize core debug",
2607 { .name
= "smp_off",
2608 .handler
= aarch64_handle_smp_off_command
,
2609 .mode
= COMMAND_EXEC
,
2610 .help
= "Stop smp handling",
2615 .handler
= aarch64_handle_smp_on_command
,
2616 .mode
= COMMAND_EXEC
,
2617 .help
= "Restart smp handling",
2622 .handler
= aarch64_handle_smp_gdb_command
,
2623 .mode
= COMMAND_EXEC
,
2624 .help
= "display/fix current core played to gdb",
2629 COMMAND_REGISTRATION_DONE
2631 static const struct command_registration aarch64_command_handlers
[] = {
2633 .chain
= arm_command_handlers
,
2636 .chain
= armv8_command_handlers
,
2640 .mode
= COMMAND_ANY
,
2641 .help
= "Cortex-A command group",
2643 .chain
= aarch64_exec_command_handlers
,
2645 COMMAND_REGISTRATION_DONE
2648 struct target_type aarch64_target
= {
2651 .poll
= aarch64_poll
,
2652 .arch_state
= armv8_arch_state
,
2654 .halt
= aarch64_halt
,
2655 .resume
= aarch64_resume
,
2656 .step
= aarch64_step
,
2658 .assert_reset
= aarch64_assert_reset
,
2659 .deassert_reset
= aarch64_deassert_reset
,
2661 /* REVISIT allow exporting VFP3 registers ... */
2662 .get_gdb_reg_list
= armv8_get_gdb_reg_list
,
2664 .read_memory
= aarch64_read_memory
,
2665 .write_memory
= aarch64_write_memory
,
2667 .checksum_memory
= arm_checksum_memory
,
2668 .blank_check_memory
= arm_blank_check_memory
,
2670 .run_algorithm
= armv4_5_run_algorithm
,
2672 .add_breakpoint
= aarch64_add_breakpoint
,
2673 .add_context_breakpoint
= aarch64_add_context_breakpoint
,
2674 .add_hybrid_breakpoint
= aarch64_add_hybrid_breakpoint
,
2675 .remove_breakpoint
= aarch64_remove_breakpoint
,
2676 .add_watchpoint
= NULL
,
2677 .remove_watchpoint
= NULL
,
2679 .commands
= aarch64_command_handlers
,
2680 .target_create
= aarch64_target_create
,
2681 .init_target
= aarch64_init_target
,
2682 .examine
= aarch64_examine
,
2684 .read_phys_memory
= aarch64_read_phys_memory
,
2685 .write_phys_memory
= aarch64_write_phys_memory
,
2687 .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)