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 "armv8_cache.h"
31 #include <helper/time_support.h>
33 static int aarch64_poll(struct target
*target
);
34 static int aarch64_debug_entry(struct target
*target
);
35 static int aarch64_restore_context(struct target
*target
, bool bpwp
);
36 static int aarch64_set_breakpoint(struct target
*target
,
37 struct breakpoint
*breakpoint
, uint8_t matchmode
);
38 static int aarch64_set_context_breakpoint(struct target
*target
,
39 struct breakpoint
*breakpoint
, uint8_t matchmode
);
40 static int aarch64_set_hybrid_breakpoint(struct target
*target
,
41 struct breakpoint
*breakpoint
);
42 static int aarch64_unset_breakpoint(struct target
*target
,
43 struct breakpoint
*breakpoint
);
44 static int aarch64_mmu(struct target
*target
, int *enabled
);
45 static int aarch64_virt2phys(struct target
*target
,
46 target_addr_t virt
, target_addr_t
*phys
);
47 static int aarch64_read_apb_ap_memory(struct target
*target
,
48 uint64_t address
, uint32_t size
, uint32_t count
, uint8_t *buffer
);
50 static int aarch64_restore_system_control_reg(struct target
*target
)
52 enum arm_mode target_mode
= ARM_MODE_ANY
;
53 int retval
= ERROR_OK
;
56 struct aarch64_common
*aarch64
= target_to_aarch64(target
);
57 struct armv8_common
*armv8
= target_to_armv8(target
);
59 if (aarch64
->system_control_reg
!= aarch64
->system_control_reg_curr
) {
60 aarch64
->system_control_reg_curr
= aarch64
->system_control_reg
;
61 /* LOG_INFO("cp15_control_reg: %8.8" PRIx32, cortex_v8->cp15_control_reg); */
63 switch (armv8
->arm
.core_mode
) {
65 target_mode
= ARMV8_64_EL1H
;
69 instr
= ARMV8_MSR_GP(SYSTEM_SCTLR_EL1
, 0);
73 instr
= ARMV8_MSR_GP(SYSTEM_SCTLR_EL2
, 0);
77 instr
= ARMV8_MSR_GP(SYSTEM_SCTLR_EL3
, 0);
84 instr
= ARMV4_5_MCR(15, 0, 0, 1, 0, 0);
88 LOG_INFO("cannot read system control register in this mode");
92 if (target_mode
!= ARM_MODE_ANY
)
93 armv8_dpm_modeswitch(&armv8
->dpm
, target_mode
);
95 retval
= armv8
->dpm
.instr_write_data_r0(&armv8
->dpm
, instr
, aarch64
->system_control_reg
);
96 if (retval
!= ERROR_OK
)
99 if (target_mode
!= ARM_MODE_ANY
)
100 armv8_dpm_modeswitch(&armv8
->dpm
, ARM_MODE_ANY
);
106 /* modify system_control_reg in order to enable or disable mmu for :
107 * - virt2phys address conversion
108 * - read or write memory in phys or virt address */
109 static int aarch64_mmu_modify(struct target
*target
, int enable
)
111 struct aarch64_common
*aarch64
= target_to_aarch64(target
);
112 struct armv8_common
*armv8
= &aarch64
->armv8_common
;
113 int retval
= ERROR_OK
;
117 /* if mmu enabled at target stop and mmu not enable */
118 if (!(aarch64
->system_control_reg
& 0x1U
)) {
119 LOG_ERROR("trying to enable mmu on target stopped with mmu disable");
122 if (!(aarch64
->system_control_reg_curr
& 0x1U
))
123 aarch64
->system_control_reg_curr
|= 0x1U
;
125 if (aarch64
->system_control_reg_curr
& 0x4U
) {
126 /* data cache is active */
127 aarch64
->system_control_reg_curr
&= ~0x4U
;
128 /* flush data cache armv8 function to be called */
129 if (armv8
->armv8_mmu
.armv8_cache
.flush_all_data_cache
)
130 armv8
->armv8_mmu
.armv8_cache
.flush_all_data_cache(target
);
132 if ((aarch64
->system_control_reg_curr
& 0x1U
)) {
133 aarch64
->system_control_reg_curr
&= ~0x1U
;
137 switch (armv8
->arm
.core_mode
) {
141 instr
= ARMV8_MSR_GP(SYSTEM_SCTLR_EL1
, 0);
145 instr
= ARMV8_MSR_GP(SYSTEM_SCTLR_EL2
, 0);
149 instr
= ARMV8_MSR_GP(SYSTEM_SCTLR_EL3
, 0);
152 LOG_DEBUG("unknown cpu state 0x%x" PRIx32
, armv8
->arm
.core_state
);
156 retval
= armv8
->dpm
.instr_write_data_r0(&armv8
->dpm
, instr
,
157 aarch64
->system_control_reg_curr
);
162 * Basic debug access, very low level assumes state is saved
164 static int aarch64_init_debug_access(struct target
*target
)
166 struct armv8_common
*armv8
= target_to_armv8(target
);
172 retval
= mem_ap_write_atomic_u32(armv8
->debug_ap
,
173 armv8
->debug_base
+ CPUV8_DBG_OSLAR
, 0);
174 if (retval
!= ERROR_OK
) {
175 LOG_DEBUG("Examine %s failed", "oslock");
179 /* Clear Sticky Power Down status Bit in PRSR to enable access to
180 the registers in the Core Power Domain */
181 retval
= mem_ap_read_atomic_u32(armv8
->debug_ap
,
182 armv8
->debug_base
+ CPUV8_DBG_PRSR
, &dummy
);
183 if (retval
!= ERROR_OK
)
187 * Static CTI configuration:
188 * Channel 0 -> trigger outputs HALT request to PE
189 * Channel 1 -> trigger outputs Resume request to PE
190 * Gate all channel trigger events from entering the CTM
194 retval
= mem_ap_write_atomic_u32(armv8
->debug_ap
,
195 armv8
->cti_base
+ CTI_CTR
, 1);
196 /* By default, gate all channel triggers to and from the CTM */
197 if (retval
== ERROR_OK
)
198 retval
= mem_ap_write_atomic_u32(armv8
->debug_ap
,
199 armv8
->cti_base
+ CTI_GATE
, 0);
200 /* output halt requests to PE on channel 0 trigger */
201 if (retval
== ERROR_OK
)
202 retval
= mem_ap_write_atomic_u32(armv8
->debug_ap
,
203 armv8
->cti_base
+ CTI_OUTEN0
, CTI_CHNL(0));
204 /* output restart requests to PE on channel 1 trigger */
205 if (retval
== ERROR_OK
)
206 retval
= mem_ap_write_atomic_u32(armv8
->debug_ap
,
207 armv8
->cti_base
+ CTI_OUTEN1
, CTI_CHNL(1));
208 if (retval
!= ERROR_OK
)
211 /* Resync breakpoint registers */
213 /* Since this is likely called from init or reset, update target state information*/
214 return aarch64_poll(target
);
217 /* Write to memory mapped registers directly with no cache or mmu handling */
218 static int aarch64_dap_write_memap_register_u32(struct target
*target
,
223 struct armv8_common
*armv8
= target_to_armv8(target
);
225 retval
= mem_ap_write_atomic_u32(armv8
->debug_ap
, address
, value
);
230 static int aarch64_dpm_setup(struct aarch64_common
*a8
, uint64_t debug
)
232 struct arm_dpm
*dpm
= &a8
->armv8_common
.dpm
;
235 dpm
->arm
= &a8
->armv8_common
.arm
;
238 retval
= armv8_dpm_setup(dpm
);
239 if (retval
== ERROR_OK
)
240 retval
= armv8_dpm_initialize(dpm
);
245 static int aarch64_set_dscr_bits(struct target
*target
, unsigned long bit_mask
, unsigned long value
)
247 struct armv8_common
*armv8
= target_to_armv8(target
);
248 return armv8_set_dbgreg_bits(armv8
, CPUV8_DBG_DSCR
, bit_mask
, value
);
251 static struct target
*get_aarch64(struct target
*target
, int32_t coreid
)
253 struct target_list
*head
;
257 while (head
!= (struct target_list
*)NULL
) {
259 if ((curr
->coreid
== coreid
) && (curr
->state
== TARGET_HALTED
))
265 static int aarch64_halt(struct target
*target
);
267 static int aarch64_halt_smp(struct target
*target
)
269 int retval
= ERROR_OK
;
270 struct target_list
*head
= target
->head
;
272 while (head
!= (struct target_list
*)NULL
) {
273 struct target
*curr
= head
->target
;
274 struct armv8_common
*armv8
= target_to_armv8(curr
);
276 /* open the gate for channel 0 to let HALT requests pass to the CTM */
278 retval
= mem_ap_write_atomic_u32(armv8
->debug_ap
,
279 armv8
->cti_base
+ CTI_GATE
, CTI_CHNL(0));
280 if (retval
== ERROR_OK
)
281 retval
= aarch64_set_dscr_bits(curr
, DSCR_HDE
, DSCR_HDE
);
283 if (retval
!= ERROR_OK
)
289 /* halt the target PE */
290 if (retval
== ERROR_OK
)
291 retval
= aarch64_halt(target
);
296 static int update_halt_gdb(struct target
*target
)
299 if (target
->gdb_service
&& target
->gdb_service
->core
[0] == -1) {
300 target
->gdb_service
->target
= target
;
301 target
->gdb_service
->core
[0] = target
->coreid
;
302 retval
+= aarch64_halt_smp(target
);
308 * Cortex-A8 Run control
311 static int aarch64_poll(struct target
*target
)
313 int retval
= ERROR_OK
;
315 struct aarch64_common
*aarch64
= target_to_aarch64(target
);
316 struct armv8_common
*armv8
= &aarch64
->armv8_common
;
317 enum target_state prev_target_state
= target
->state
;
318 /* toggle to another core is done by gdb as follow */
319 /* maint packet J core_id */
321 /* the next polling trigger an halt event sent to gdb */
322 if ((target
->state
== TARGET_HALTED
) && (target
->smp
) &&
323 (target
->gdb_service
) &&
324 (target
->gdb_service
->target
== NULL
)) {
325 target
->gdb_service
->target
=
326 get_aarch64(target
, target
->gdb_service
->core
[1]);
327 target_call_event_callbacks(target
, TARGET_EVENT_HALTED
);
330 retval
= mem_ap_read_atomic_u32(armv8
->debug_ap
,
331 armv8
->debug_base
+ CPUV8_DBG_DSCR
, &dscr
);
332 if (retval
!= ERROR_OK
)
334 aarch64
->cpudbg_dscr
= dscr
;
336 if (DSCR_RUN_MODE(dscr
) == 0x3) {
337 if (prev_target_state
!= TARGET_HALTED
) {
338 /* We have a halting debug event */
339 LOG_DEBUG("Target %s halted", target_name(target
));
340 target
->state
= TARGET_HALTED
;
341 if ((prev_target_state
== TARGET_RUNNING
)
342 || (prev_target_state
== TARGET_UNKNOWN
)
343 || (prev_target_state
== TARGET_RESET
)) {
344 retval
= aarch64_debug_entry(target
);
345 if (retval
!= ERROR_OK
)
348 retval
= update_halt_gdb(target
);
349 if (retval
!= ERROR_OK
)
352 target_call_event_callbacks(target
,
353 TARGET_EVENT_HALTED
);
355 if (prev_target_state
== TARGET_DEBUG_RUNNING
) {
358 retval
= aarch64_debug_entry(target
);
359 if (retval
!= ERROR_OK
)
362 retval
= update_halt_gdb(target
);
363 if (retval
!= ERROR_OK
)
367 target_call_event_callbacks(target
,
368 TARGET_EVENT_DEBUG_HALTED
);
372 target
->state
= TARGET_RUNNING
;
377 static int aarch64_halt(struct target
*target
)
379 int retval
= ERROR_OK
;
381 struct armv8_common
*armv8
= target_to_armv8(target
);
384 * add HDE in halting debug mode
386 retval
= aarch64_set_dscr_bits(target
, DSCR_HDE
, DSCR_HDE
);
387 if (retval
!= ERROR_OK
)
390 /* trigger an event on channel 0, this outputs a halt request to the PE */
391 retval
= mem_ap_write_atomic_u32(armv8
->debug_ap
,
392 armv8
->cti_base
+ CTI_APPPULSE
, CTI_CHNL(0));
393 if (retval
!= ERROR_OK
)
396 long long then
= timeval_ms();
398 retval
= mem_ap_read_atomic_u32(armv8
->debug_ap
,
399 armv8
->debug_base
+ CPUV8_DBG_DSCR
, &dscr
);
400 if (retval
!= ERROR_OK
)
402 if ((dscr
& DSCRV8_HALT_MASK
) != 0)
404 if (timeval_ms() > then
+ 1000) {
405 LOG_ERROR("Timeout waiting for halt");
410 target
->debug_reason
= DBG_REASON_DBGRQ
;
415 static int aarch64_internal_restore(struct target
*target
, int current
,
416 uint64_t *address
, int handle_breakpoints
, int debug_execution
)
418 struct armv8_common
*armv8
= target_to_armv8(target
);
419 struct arm
*arm
= &armv8
->arm
;
423 if (!debug_execution
)
424 target_free_all_working_areas(target
);
426 /* current = 1: continue on current pc, otherwise continue at <address> */
427 resume_pc
= buf_get_u64(arm
->pc
->value
, 0, 64);
429 resume_pc
= *address
;
431 *address
= resume_pc
;
433 /* Make sure that the Armv7 gdb thumb fixups does not
434 * kill the return address
436 switch (arm
->core_state
) {
438 resume_pc
&= 0xFFFFFFFC;
440 case ARM_STATE_AARCH64
:
441 resume_pc
&= 0xFFFFFFFFFFFFFFFC;
443 case ARM_STATE_THUMB
:
444 case ARM_STATE_THUMB_EE
:
445 /* When the return address is loaded into PC
446 * bit 0 must be 1 to stay in Thumb state
450 case ARM_STATE_JAZELLE
:
451 LOG_ERROR("How do I resume into Jazelle state??");
454 LOG_DEBUG("resume pc = 0x%016" PRIx64
, resume_pc
);
455 buf_set_u64(arm
->pc
->value
, 0, 64, resume_pc
);
459 /* called it now before restoring context because it uses cpu
460 * register r0 for restoring system control register */
461 retval
= aarch64_restore_system_control_reg(target
);
462 if (retval
== ERROR_OK
)
463 retval
= aarch64_restore_context(target
, handle_breakpoints
);
468 static int aarch64_internal_restart(struct target
*target
, bool slave_pe
)
470 struct armv8_common
*armv8
= target_to_armv8(target
);
471 struct arm
*arm
= &armv8
->arm
;
475 * * Restart core and wait for it to be started. Clear ITRen and sticky
476 * * exception flags: see ARMv7 ARM, C5.9.
478 * REVISIT: for single stepping, we probably want to
479 * disable IRQs by default, with optional override...
482 retval
= mem_ap_read_atomic_u32(armv8
->debug_ap
,
483 armv8
->debug_base
+ CPUV8_DBG_DSCR
, &dscr
);
484 if (retval
!= ERROR_OK
)
487 if ((dscr
& DSCR_ITE
) == 0)
488 LOG_ERROR("DSCR.ITE must be set before leaving debug!");
489 if ((dscr
& DSCR_ERR
) != 0)
490 LOG_ERROR("DSCR.ERR must be cleared before leaving debug!");
492 /* make sure to acknowledge the halt event before resuming */
493 retval
= mem_ap_write_atomic_u32(armv8
->debug_ap
,
494 armv8
->cti_base
+ CTI_INACK
, CTI_TRIG(HALT
));
497 * open the CTI gate for channel 1 so that the restart events
498 * get passed along to all PEs
500 if (retval
== ERROR_OK
)
501 retval
= mem_ap_write_atomic_u32(armv8
->debug_ap
,
502 armv8
->cti_base
+ CTI_GATE
, CTI_CHNL(1));
503 if (retval
!= ERROR_OK
)
507 /* trigger an event on channel 1, generates a restart request to the PE */
508 retval
= mem_ap_write_atomic_u32(armv8
->debug_ap
,
509 armv8
->cti_base
+ CTI_APPPULSE
, CTI_CHNL(1));
510 if (retval
!= ERROR_OK
)
513 long long then
= timeval_ms();
515 retval
= mem_ap_read_atomic_u32(armv8
->debug_ap
,
516 armv8
->debug_base
+ CPUV8_DBG_DSCR
, &dscr
);
517 if (retval
!= ERROR_OK
)
519 if ((dscr
& DSCR_HDE
) != 0)
521 if (timeval_ms() > then
+ 1000) {
522 LOG_ERROR("Timeout waiting for resume");
528 target
->debug_reason
= DBG_REASON_NOTHALTED
;
529 target
->state
= TARGET_RUNNING
;
531 /* registers are now invalid */
532 register_cache_invalidate(arm
->core_cache
);
533 register_cache_invalidate(arm
->core_cache
->next
);
538 static int aarch64_restore_smp(struct target
*target
, int handle_breakpoints
)
541 struct target_list
*head
;
545 while (head
!= (struct target_list
*)NULL
) {
547 if ((curr
!= target
) && (curr
->state
!= TARGET_RUNNING
)) {
548 /* resume current address , not in step mode */
549 retval
+= aarch64_internal_restore(curr
, 1, &address
,
550 handle_breakpoints
, 0);
551 retval
+= aarch64_internal_restart(curr
, true);
559 static int aarch64_resume(struct target
*target
, int current
,
560 target_addr_t address
, int handle_breakpoints
, int debug_execution
)
563 uint64_t addr
= address
;
565 /* dummy resume for smp toggle in order to reduce gdb impact */
566 if ((target
->smp
) && (target
->gdb_service
->core
[1] != -1)) {
567 /* simulate a start and halt of target */
568 target
->gdb_service
->target
= NULL
;
569 target
->gdb_service
->core
[0] = target
->gdb_service
->core
[1];
570 /* fake resume at next poll we play the target core[1], see poll*/
571 target_call_event_callbacks(target
, TARGET_EVENT_RESUMED
);
575 if (target
->state
!= TARGET_HALTED
)
576 return ERROR_TARGET_NOT_HALTED
;
578 aarch64_internal_restore(target
, current
, &addr
, handle_breakpoints
,
581 target
->gdb_service
->core
[0] = -1;
582 retval
= aarch64_restore_smp(target
, handle_breakpoints
);
583 if (retval
!= ERROR_OK
)
586 aarch64_internal_restart(target
, false);
588 if (!debug_execution
) {
589 target
->state
= TARGET_RUNNING
;
590 target_call_event_callbacks(target
, TARGET_EVENT_RESUMED
);
591 LOG_DEBUG("target resumed at 0x%" PRIx64
, addr
);
593 target
->state
= TARGET_DEBUG_RUNNING
;
594 target_call_event_callbacks(target
, TARGET_EVENT_DEBUG_RESUMED
);
595 LOG_DEBUG("target debug resumed at 0x%" PRIx64
, addr
);
601 static int aarch64_debug_entry(struct target
*target
)
603 int retval
= ERROR_OK
;
604 struct aarch64_common
*aarch64
= target_to_aarch64(target
);
605 struct armv8_common
*armv8
= target_to_armv8(target
);
606 struct arm_dpm
*dpm
= &armv8
->dpm
;
607 enum arm_state core_state
;
609 LOG_DEBUG("%s dscr = 0x%08" PRIx32
, target_name(target
), aarch64
->cpudbg_dscr
);
611 dpm
->dscr
= aarch64
->cpudbg_dscr
;
612 core_state
= armv8_dpm_get_core_state(dpm
);
613 armv8_select_opcodes(armv8
, core_state
== ARM_STATE_AARCH64
);
614 armv8_select_reg_access(armv8
, core_state
== ARM_STATE_AARCH64
);
616 /* make sure to clear all sticky errors */
617 retval
= mem_ap_write_atomic_u32(armv8
->debug_ap
,
618 armv8
->debug_base
+ CPUV8_DBG_DRCR
, DRCR_CSE
);
620 /* discard async exceptions */
621 if (retval
== ERROR_OK
)
622 retval
= dpm
->instr_cpsr_sync(dpm
);
624 if (retval
!= ERROR_OK
)
627 /* Examine debug reason */
628 armv8_dpm_report_dscr(dpm
, aarch64
->cpudbg_dscr
);
630 /* save address of instruction that triggered the watchpoint? */
631 if (target
->debug_reason
== DBG_REASON_WATCHPOINT
) {
635 retval
= mem_ap_read_atomic_u32(armv8
->debug_ap
,
636 armv8
->debug_base
+ CPUV8_DBG_WFAR1
,
638 if (retval
!= ERROR_OK
)
642 retval
= mem_ap_read_atomic_u32(armv8
->debug_ap
,
643 armv8
->debug_base
+ CPUV8_DBG_WFAR0
,
645 if (retval
!= ERROR_OK
)
648 armv8_dpm_report_wfar(&armv8
->dpm
, wfar
);
651 retval
= armv8_dpm_read_current_registers(&armv8
->dpm
);
653 if (retval
== ERROR_OK
&& armv8
->post_debug_entry
)
654 retval
= armv8
->post_debug_entry(target
);
659 static int aarch64_post_debug_entry(struct target
*target
)
661 struct aarch64_common
*aarch64
= target_to_aarch64(target
);
662 struct armv8_common
*armv8
= &aarch64
->armv8_common
;
664 enum arm_mode target_mode
= ARM_MODE_ANY
;
667 switch (armv8
->arm
.core_mode
) {
669 target_mode
= ARMV8_64_EL1H
;
673 instr
= ARMV8_MRS(SYSTEM_SCTLR_EL1
, 0);
677 instr
= ARMV8_MRS(SYSTEM_SCTLR_EL2
, 0);
681 instr
= ARMV8_MRS(SYSTEM_SCTLR_EL3
, 0);
688 instr
= ARMV4_5_MRC(15, 0, 0, 1, 0, 0);
692 LOG_INFO("cannot read system control register in this mode");
696 if (target_mode
!= ARM_MODE_ANY
)
697 armv8_dpm_modeswitch(&armv8
->dpm
, target_mode
);
699 retval
= armv8
->dpm
.instr_read_data_r0(&armv8
->dpm
, instr
, &aarch64
->system_control_reg
);
700 if (retval
!= ERROR_OK
)
703 if (target_mode
!= ARM_MODE_ANY
)
704 armv8_dpm_modeswitch(&armv8
->dpm
, ARM_MODE_ANY
);
706 LOG_DEBUG("System_register: %8.8" PRIx32
, aarch64
->system_control_reg
);
707 aarch64
->system_control_reg_curr
= aarch64
->system_control_reg
;
709 if (armv8
->armv8_mmu
.armv8_cache
.info
== -1) {
710 armv8_identify_cache(armv8
);
711 armv8_read_mpidr(armv8
);
714 armv8
->armv8_mmu
.mmu_enabled
=
715 (aarch64
->system_control_reg
& 0x1U
) ? 1 : 0;
716 armv8
->armv8_mmu
.armv8_cache
.d_u_cache_enabled
=
717 (aarch64
->system_control_reg
& 0x4U
) ? 1 : 0;
718 armv8
->armv8_mmu
.armv8_cache
.i_cache_enabled
=
719 (aarch64
->system_control_reg
& 0x1000U
) ? 1 : 0;
720 aarch64
->curr_mode
= armv8
->arm
.core_mode
;
724 static int aarch64_step(struct target
*target
, int current
, target_addr_t address
,
725 int handle_breakpoints
)
727 struct armv8_common
*armv8
= target_to_armv8(target
);
731 if (target
->state
!= TARGET_HALTED
) {
732 LOG_WARNING("target not halted");
733 return ERROR_TARGET_NOT_HALTED
;
736 retval
= mem_ap_read_atomic_u32(armv8
->debug_ap
,
737 armv8
->debug_base
+ CPUV8_DBG_EDECR
, &edecr
);
738 if (retval
!= ERROR_OK
)
741 /* make sure EDECR.SS is not set when restoring the register */
744 /* set EDECR.SS to enter hardware step mode */
745 retval
= mem_ap_write_atomic_u32(armv8
->debug_ap
,
746 armv8
->debug_base
+ CPUV8_DBG_EDECR
, (edecr
|0x4));
747 if (retval
!= ERROR_OK
)
750 /* disable interrupts while stepping */
751 retval
= aarch64_set_dscr_bits(target
, 0x3 << 22, 0x3 << 22);
752 if (retval
!= ERROR_OK
)
755 /* resume the target */
756 retval
= aarch64_resume(target
, current
, address
, 0, 0);
757 if (retval
!= ERROR_OK
)
760 long long then
= timeval_ms();
761 while (target
->state
!= TARGET_HALTED
) {
762 retval
= aarch64_poll(target
);
763 if (retval
!= ERROR_OK
)
765 if (timeval_ms() > then
+ 1000) {
766 LOG_ERROR("timeout waiting for target halt");
772 retval
= mem_ap_write_atomic_u32(armv8
->debug_ap
,
773 armv8
->debug_base
+ CPUV8_DBG_EDECR
, edecr
);
774 if (retval
!= ERROR_OK
)
777 /* restore interrupts */
778 retval
= aarch64_set_dscr_bits(target
, 0x3 << 22, 0);
779 if (retval
!= ERROR_OK
)
785 static int aarch64_restore_context(struct target
*target
, bool bpwp
)
787 struct armv8_common
*armv8
= target_to_armv8(target
);
789 LOG_DEBUG("%s", target_name(target
));
791 if (armv8
->pre_restore_context
)
792 armv8
->pre_restore_context(target
);
794 return armv8_dpm_write_dirty_registers(&armv8
->dpm
, bpwp
);
798 * Cortex-A8 Breakpoint and watchpoint functions
801 /* Setup hardware Breakpoint Register Pair */
802 static int aarch64_set_breakpoint(struct target
*target
,
803 struct breakpoint
*breakpoint
, uint8_t matchmode
)
808 uint8_t byte_addr_select
= 0x0F;
809 struct aarch64_common
*aarch64
= target_to_aarch64(target
);
810 struct armv8_common
*armv8
= &aarch64
->armv8_common
;
811 struct aarch64_brp
*brp_list
= aarch64
->brp_list
;
813 if (breakpoint
->set
) {
814 LOG_WARNING("breakpoint already set");
818 if (breakpoint
->type
== BKPT_HARD
) {
820 while (brp_list
[brp_i
].used
&& (brp_i
< aarch64
->brp_num
))
822 if (brp_i
>= aarch64
->brp_num
) {
823 LOG_ERROR("ERROR Can not find free Breakpoint Register Pair");
824 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
826 breakpoint
->set
= brp_i
+ 1;
827 if (breakpoint
->length
== 2)
828 byte_addr_select
= (3 << (breakpoint
->address
& 0x02));
829 control
= ((matchmode
& 0x7) << 20)
831 | (byte_addr_select
<< 5)
833 brp_list
[brp_i
].used
= 1;
834 brp_list
[brp_i
].value
= breakpoint
->address
& 0xFFFFFFFFFFFFFFFC;
835 brp_list
[brp_i
].control
= control
;
836 bpt_value
= brp_list
[brp_i
].value
;
838 retval
= aarch64_dap_write_memap_register_u32(target
, armv8
->debug_base
839 + CPUV8_DBG_BVR_BASE
+ 16 * brp_list
[brp_i
].BRPn
,
840 (uint32_t)(bpt_value
& 0xFFFFFFFF));
841 if (retval
!= ERROR_OK
)
843 retval
= aarch64_dap_write_memap_register_u32(target
, armv8
->debug_base
844 + CPUV8_DBG_BVR_BASE
+ 4 + 16 * brp_list
[brp_i
].BRPn
,
845 (uint32_t)(bpt_value
>> 32));
846 if (retval
!= ERROR_OK
)
849 retval
= aarch64_dap_write_memap_register_u32(target
, armv8
->debug_base
850 + CPUV8_DBG_BCR_BASE
+ 16 * brp_list
[brp_i
].BRPn
,
851 brp_list
[brp_i
].control
);
852 if (retval
!= ERROR_OK
)
854 LOG_DEBUG("brp %i control 0x%0" PRIx32
" value 0x%" TARGET_PRIxADDR
, brp_i
,
855 brp_list
[brp_i
].control
,
856 brp_list
[brp_i
].value
);
858 } else if (breakpoint
->type
== BKPT_SOFT
) {
861 buf_set_u32(code
, 0, 32, armv8_opcode(armv8
, ARMV8_OPC_HLT
));
862 retval
= target_read_memory(target
,
863 breakpoint
->address
& 0xFFFFFFFFFFFFFFFE,
864 breakpoint
->length
, 1,
865 breakpoint
->orig_instr
);
866 if (retval
!= ERROR_OK
)
869 armv8_cache_d_inner_flush_virt(armv8
,
870 breakpoint
->address
& 0xFFFFFFFFFFFFFFFE,
873 retval
= target_write_memory(target
,
874 breakpoint
->address
& 0xFFFFFFFFFFFFFFFE,
875 breakpoint
->length
, 1, code
);
876 if (retval
!= ERROR_OK
)
879 armv8_cache_d_inner_flush_virt(armv8
,
880 breakpoint
->address
& 0xFFFFFFFFFFFFFFFE,
883 armv8_cache_i_inner_inval_virt(armv8
,
884 breakpoint
->address
& 0xFFFFFFFFFFFFFFFE,
887 breakpoint
->set
= 0x11; /* Any nice value but 0 */
890 /* Ensure that halting debug mode is enable */
891 retval
= aarch64_set_dscr_bits(target
, DSCR_HDE
, DSCR_HDE
);
892 if (retval
!= ERROR_OK
) {
893 LOG_DEBUG("Failed to set DSCR.HDE");
900 static int aarch64_set_context_breakpoint(struct target
*target
,
901 struct breakpoint
*breakpoint
, uint8_t matchmode
)
903 int retval
= ERROR_FAIL
;
906 uint8_t byte_addr_select
= 0x0F;
907 struct aarch64_common
*aarch64
= target_to_aarch64(target
);
908 struct armv8_common
*armv8
= &aarch64
->armv8_common
;
909 struct aarch64_brp
*brp_list
= aarch64
->brp_list
;
911 if (breakpoint
->set
) {
912 LOG_WARNING("breakpoint already set");
915 /*check available context BRPs*/
916 while ((brp_list
[brp_i
].used
||
917 (brp_list
[brp_i
].type
!= BRP_CONTEXT
)) && (brp_i
< aarch64
->brp_num
))
920 if (brp_i
>= aarch64
->brp_num
) {
921 LOG_ERROR("ERROR Can not find free Breakpoint Register Pair");
925 breakpoint
->set
= brp_i
+ 1;
926 control
= ((matchmode
& 0x7) << 20)
928 | (byte_addr_select
<< 5)
930 brp_list
[brp_i
].used
= 1;
931 brp_list
[brp_i
].value
= (breakpoint
->asid
);
932 brp_list
[brp_i
].control
= control
;
933 retval
= aarch64_dap_write_memap_register_u32(target
, armv8
->debug_base
934 + CPUV8_DBG_BVR_BASE
+ 16 * brp_list
[brp_i
].BRPn
,
935 brp_list
[brp_i
].value
);
936 if (retval
!= ERROR_OK
)
938 retval
= aarch64_dap_write_memap_register_u32(target
, armv8
->debug_base
939 + CPUV8_DBG_BCR_BASE
+ 16 * brp_list
[brp_i
].BRPn
,
940 brp_list
[brp_i
].control
);
941 if (retval
!= ERROR_OK
)
943 LOG_DEBUG("brp %i control 0x%0" PRIx32
" value 0x%" TARGET_PRIxADDR
, brp_i
,
944 brp_list
[brp_i
].control
,
945 brp_list
[brp_i
].value
);
950 static int aarch64_set_hybrid_breakpoint(struct target
*target
, struct breakpoint
*breakpoint
)
952 int retval
= ERROR_FAIL
;
953 int brp_1
= 0; /* holds the contextID pair */
954 int brp_2
= 0; /* holds the IVA pair */
955 uint32_t control_CTX
, control_IVA
;
956 uint8_t CTX_byte_addr_select
= 0x0F;
957 uint8_t IVA_byte_addr_select
= 0x0F;
958 uint8_t CTX_machmode
= 0x03;
959 uint8_t IVA_machmode
= 0x01;
960 struct aarch64_common
*aarch64
= target_to_aarch64(target
);
961 struct armv8_common
*armv8
= &aarch64
->armv8_common
;
962 struct aarch64_brp
*brp_list
= aarch64
->brp_list
;
964 if (breakpoint
->set
) {
965 LOG_WARNING("breakpoint already set");
968 /*check available context BRPs*/
969 while ((brp_list
[brp_1
].used
||
970 (brp_list
[brp_1
].type
!= BRP_CONTEXT
)) && (brp_1
< aarch64
->brp_num
))
973 printf("brp(CTX) found num: %d\n", brp_1
);
974 if (brp_1
>= aarch64
->brp_num
) {
975 LOG_ERROR("ERROR Can not find free Breakpoint Register Pair");
979 while ((brp_list
[brp_2
].used
||
980 (brp_list
[brp_2
].type
!= BRP_NORMAL
)) && (brp_2
< aarch64
->brp_num
))
983 printf("brp(IVA) found num: %d\n", brp_2
);
984 if (brp_2
>= aarch64
->brp_num
) {
985 LOG_ERROR("ERROR Can not find free Breakpoint Register Pair");
989 breakpoint
->set
= brp_1
+ 1;
990 breakpoint
->linked_BRP
= brp_2
;
991 control_CTX
= ((CTX_machmode
& 0x7) << 20)
994 | (CTX_byte_addr_select
<< 5)
996 brp_list
[brp_1
].used
= 1;
997 brp_list
[brp_1
].value
= (breakpoint
->asid
);
998 brp_list
[brp_1
].control
= control_CTX
;
999 retval
= aarch64_dap_write_memap_register_u32(target
, armv8
->debug_base
1000 + CPUV8_DBG_BVR_BASE
+ 16 * brp_list
[brp_1
].BRPn
,
1001 brp_list
[brp_1
].value
);
1002 if (retval
!= ERROR_OK
)
1004 retval
= aarch64_dap_write_memap_register_u32(target
, armv8
->debug_base
1005 + CPUV8_DBG_BCR_BASE
+ 16 * brp_list
[brp_1
].BRPn
,
1006 brp_list
[brp_1
].control
);
1007 if (retval
!= ERROR_OK
)
1010 control_IVA
= ((IVA_machmode
& 0x7) << 20)
1013 | (IVA_byte_addr_select
<< 5)
1015 brp_list
[brp_2
].used
= 1;
1016 brp_list
[brp_2
].value
= breakpoint
->address
& 0xFFFFFFFFFFFFFFFC;
1017 brp_list
[brp_2
].control
= control_IVA
;
1018 retval
= aarch64_dap_write_memap_register_u32(target
, armv8
->debug_base
1019 + CPUV8_DBG_BVR_BASE
+ 16 * brp_list
[brp_2
].BRPn
,
1020 brp_list
[brp_2
].value
& 0xFFFFFFFF);
1021 if (retval
!= ERROR_OK
)
1023 retval
= aarch64_dap_write_memap_register_u32(target
, armv8
->debug_base
1024 + CPUV8_DBG_BVR_BASE
+ 4 + 16 * brp_list
[brp_2
].BRPn
,
1025 brp_list
[brp_2
].value
>> 32);
1026 if (retval
!= ERROR_OK
)
1028 retval
= aarch64_dap_write_memap_register_u32(target
, armv8
->debug_base
1029 + CPUV8_DBG_BCR_BASE
+ 16 * brp_list
[brp_2
].BRPn
,
1030 brp_list
[brp_2
].control
);
1031 if (retval
!= ERROR_OK
)
1037 static int aarch64_unset_breakpoint(struct target
*target
, struct breakpoint
*breakpoint
)
1040 struct aarch64_common
*aarch64
= target_to_aarch64(target
);
1041 struct armv8_common
*armv8
= &aarch64
->armv8_common
;
1042 struct aarch64_brp
*brp_list
= aarch64
->brp_list
;
1044 if (!breakpoint
->set
) {
1045 LOG_WARNING("breakpoint not set");
1049 if (breakpoint
->type
== BKPT_HARD
) {
1050 if ((breakpoint
->address
!= 0) && (breakpoint
->asid
!= 0)) {
1051 int brp_i
= breakpoint
->set
- 1;
1052 int brp_j
= breakpoint
->linked_BRP
;
1053 if ((brp_i
< 0) || (brp_i
>= aarch64
->brp_num
)) {
1054 LOG_DEBUG("Invalid BRP number in breakpoint");
1057 LOG_DEBUG("rbp %i control 0x%0" PRIx32
" value 0x%" TARGET_PRIxADDR
, brp_i
,
1058 brp_list
[brp_i
].control
, brp_list
[brp_i
].value
);
1059 brp_list
[brp_i
].used
= 0;
1060 brp_list
[brp_i
].value
= 0;
1061 brp_list
[brp_i
].control
= 0;
1062 retval
= aarch64_dap_write_memap_register_u32(target
, armv8
->debug_base
1063 + CPUV8_DBG_BCR_BASE
+ 16 * brp_list
[brp_i
].BRPn
,
1064 brp_list
[brp_i
].control
);
1065 if (retval
!= ERROR_OK
)
1067 retval
= aarch64_dap_write_memap_register_u32(target
, armv8
->debug_base
1068 + CPUV8_DBG_BVR_BASE
+ 16 * brp_list
[brp_i
].BRPn
,
1069 (uint32_t)brp_list
[brp_i
].value
);
1070 if (retval
!= ERROR_OK
)
1072 retval
= aarch64_dap_write_memap_register_u32(target
, armv8
->debug_base
1073 + CPUV8_DBG_BVR_BASE
+ 4 + 16 * brp_list
[brp_i
].BRPn
,
1074 (uint32_t)brp_list
[brp_i
].value
);
1075 if (retval
!= ERROR_OK
)
1077 if ((brp_j
< 0) || (brp_j
>= aarch64
->brp_num
)) {
1078 LOG_DEBUG("Invalid BRP number in breakpoint");
1081 LOG_DEBUG("rbp %i control 0x%0" PRIx32
" value 0x%0" PRIx64
, brp_j
,
1082 brp_list
[brp_j
].control
, brp_list
[brp_j
].value
);
1083 brp_list
[brp_j
].used
= 0;
1084 brp_list
[brp_j
].value
= 0;
1085 brp_list
[brp_j
].control
= 0;
1086 retval
= aarch64_dap_write_memap_register_u32(target
, armv8
->debug_base
1087 + CPUV8_DBG_BCR_BASE
+ 16 * brp_list
[brp_j
].BRPn
,
1088 brp_list
[brp_j
].control
);
1089 if (retval
!= ERROR_OK
)
1091 retval
= aarch64_dap_write_memap_register_u32(target
, armv8
->debug_base
1092 + CPUV8_DBG_BVR_BASE
+ 16 * brp_list
[brp_j
].BRPn
,
1093 (uint32_t)brp_list
[brp_j
].value
);
1094 if (retval
!= ERROR_OK
)
1096 retval
= aarch64_dap_write_memap_register_u32(target
, armv8
->debug_base
1097 + CPUV8_DBG_BVR_BASE
+ 4 + 16 * brp_list
[brp_j
].BRPn
,
1098 (uint32_t)brp_list
[brp_j
].value
);
1099 if (retval
!= ERROR_OK
)
1102 breakpoint
->linked_BRP
= 0;
1103 breakpoint
->set
= 0;
1107 int brp_i
= breakpoint
->set
- 1;
1108 if ((brp_i
< 0) || (brp_i
>= aarch64
->brp_num
)) {
1109 LOG_DEBUG("Invalid BRP number in breakpoint");
1112 LOG_DEBUG("rbp %i control 0x%0" PRIx32
" value 0x%0" PRIx64
, brp_i
,
1113 brp_list
[brp_i
].control
, brp_list
[brp_i
].value
);
1114 brp_list
[brp_i
].used
= 0;
1115 brp_list
[brp_i
].value
= 0;
1116 brp_list
[brp_i
].control
= 0;
1117 retval
= aarch64_dap_write_memap_register_u32(target
, armv8
->debug_base
1118 + CPUV8_DBG_BCR_BASE
+ 16 * brp_list
[brp_i
].BRPn
,
1119 brp_list
[brp_i
].control
);
1120 if (retval
!= ERROR_OK
)
1122 retval
= aarch64_dap_write_memap_register_u32(target
, armv8
->debug_base
1123 + CPUV8_DBG_BVR_BASE
+ 16 * brp_list
[brp_i
].BRPn
,
1124 brp_list
[brp_i
].value
);
1125 if (retval
!= ERROR_OK
)
1128 retval
= aarch64_dap_write_memap_register_u32(target
, armv8
->debug_base
1129 + CPUV8_DBG_BVR_BASE
+ 4 + 16 * brp_list
[brp_i
].BRPn
,
1130 (uint32_t)brp_list
[brp_i
].value
);
1131 if (retval
!= ERROR_OK
)
1133 breakpoint
->set
= 0;
1137 /* restore original instruction (kept in target endianness) */
1139 armv8_cache_d_inner_flush_virt(armv8
,
1140 breakpoint
->address
& 0xFFFFFFFFFFFFFFFE,
1141 breakpoint
->length
);
1143 if (breakpoint
->length
== 4) {
1144 retval
= target_write_memory(target
,
1145 breakpoint
->address
& 0xFFFFFFFFFFFFFFFE,
1146 4, 1, breakpoint
->orig_instr
);
1147 if (retval
!= ERROR_OK
)
1150 retval
= target_write_memory(target
,
1151 breakpoint
->address
& 0xFFFFFFFFFFFFFFFE,
1152 2, 1, breakpoint
->orig_instr
);
1153 if (retval
!= ERROR_OK
)
1157 armv8_cache_d_inner_flush_virt(armv8
,
1158 breakpoint
->address
& 0xFFFFFFFFFFFFFFFE,
1159 breakpoint
->length
);
1161 armv8_cache_i_inner_inval_virt(armv8
,
1162 breakpoint
->address
& 0xFFFFFFFFFFFFFFFE,
1163 breakpoint
->length
);
1165 breakpoint
->set
= 0;
1170 static int aarch64_add_breakpoint(struct target
*target
,
1171 struct breakpoint
*breakpoint
)
1173 struct aarch64_common
*aarch64
= target_to_aarch64(target
);
1175 if ((breakpoint
->type
== BKPT_HARD
) && (aarch64
->brp_num_available
< 1)) {
1176 LOG_INFO("no hardware breakpoint available");
1177 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1180 if (breakpoint
->type
== BKPT_HARD
)
1181 aarch64
->brp_num_available
--;
1183 return aarch64_set_breakpoint(target
, breakpoint
, 0x00); /* Exact match */
1186 static int aarch64_add_context_breakpoint(struct target
*target
,
1187 struct breakpoint
*breakpoint
)
1189 struct aarch64_common
*aarch64
= target_to_aarch64(target
);
1191 if ((breakpoint
->type
== BKPT_HARD
) && (aarch64
->brp_num_available
< 1)) {
1192 LOG_INFO("no hardware breakpoint available");
1193 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1196 if (breakpoint
->type
== BKPT_HARD
)
1197 aarch64
->brp_num_available
--;
1199 return aarch64_set_context_breakpoint(target
, breakpoint
, 0x02); /* asid match */
1202 static int aarch64_add_hybrid_breakpoint(struct target
*target
,
1203 struct breakpoint
*breakpoint
)
1205 struct aarch64_common
*aarch64
= target_to_aarch64(target
);
1207 if ((breakpoint
->type
== BKPT_HARD
) && (aarch64
->brp_num_available
< 1)) {
1208 LOG_INFO("no hardware breakpoint available");
1209 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1212 if (breakpoint
->type
== BKPT_HARD
)
1213 aarch64
->brp_num_available
--;
1215 return aarch64_set_hybrid_breakpoint(target
, breakpoint
); /* ??? */
1219 static int aarch64_remove_breakpoint(struct target
*target
, struct breakpoint
*breakpoint
)
1221 struct aarch64_common
*aarch64
= target_to_aarch64(target
);
1224 /* It is perfectly possible to remove breakpoints while the target is running */
1225 if (target
->state
!= TARGET_HALTED
) {
1226 LOG_WARNING("target not halted");
1227 return ERROR_TARGET_NOT_HALTED
;
1231 if (breakpoint
->set
) {
1232 aarch64_unset_breakpoint(target
, breakpoint
);
1233 if (breakpoint
->type
== BKPT_HARD
)
1234 aarch64
->brp_num_available
++;
1241 * Cortex-A8 Reset functions
1244 static int aarch64_assert_reset(struct target
*target
)
1246 struct armv8_common
*armv8
= target_to_armv8(target
);
1250 /* FIXME when halt is requested, make it work somehow... */
1252 /* Issue some kind of warm reset. */
1253 if (target_has_event_action(target
, TARGET_EVENT_RESET_ASSERT
))
1254 target_handle_event(target
, TARGET_EVENT_RESET_ASSERT
);
1255 else if (jtag_get_reset_config() & RESET_HAS_SRST
) {
1256 /* REVISIT handle "pulls" cases, if there's
1257 * hardware that needs them to work.
1259 jtag_add_reset(0, 1);
1261 LOG_ERROR("%s: how to reset?", target_name(target
));
1265 /* registers are now invalid */
1266 if (target_was_examined(target
)) {
1267 register_cache_invalidate(armv8
->arm
.core_cache
);
1268 register_cache_invalidate(armv8
->arm
.core_cache
->next
);
1271 target
->state
= TARGET_RESET
;
1276 static int aarch64_deassert_reset(struct target
*target
)
1282 /* be certain SRST is off */
1283 jtag_add_reset(0, 0);
1285 if (!target_was_examined(target
))
1288 retval
= aarch64_poll(target
);
1289 if (retval
!= ERROR_OK
)
1292 if (target
->reset_halt
) {
1293 if (target
->state
!= TARGET_HALTED
) {
1294 LOG_WARNING("%s: ran after reset and before halt ...",
1295 target_name(target
));
1296 retval
= target_halt(target
);
1297 if (retval
!= ERROR_OK
)
1302 return aarch64_init_debug_access(target
);
1305 static int aarch64_write_apb_ap_memory(struct target
*target
,
1306 uint64_t address
, uint32_t size
,
1307 uint32_t count
, const uint8_t *buffer
)
1309 /* write memory through APB-AP */
1310 int retval
= ERROR_COMMAND_SYNTAX_ERROR
;
1311 struct armv8_common
*armv8
= target_to_armv8(target
);
1312 struct arm_dpm
*dpm
= &armv8
->dpm
;
1313 struct arm
*arm
= &armv8
->arm
;
1314 int total_bytes
= count
* size
;
1316 int start_byte
= address
& 0x3;
1317 int end_byte
= (address
+ total_bytes
) & 0x3;
1320 uint8_t *tmp_buff
= NULL
;
1322 if (target
->state
!= TARGET_HALTED
) {
1323 LOG_WARNING("target not halted");
1324 return ERROR_TARGET_NOT_HALTED
;
1327 total_u32
= DIV_ROUND_UP((address
& 3) + total_bytes
, 4);
1329 /* Mark register R0 as dirty, as it will be used
1330 * for transferring the data.
1331 * It will be restored automatically when exiting
1334 reg
= armv8_reg_current(arm
, 1);
1337 reg
= armv8_reg_current(arm
, 0);
1340 /* This algorithm comes from DDI0487A.g, chapter J9.1 */
1342 /* The algorithm only copies 32 bit words, so the buffer
1343 * should be expanded to include the words at either end.
1344 * The first and last words will be read first to avoid
1345 * corruption if needed.
1347 tmp_buff
= malloc(total_u32
* 4);
1349 if ((start_byte
!= 0) && (total_u32
> 1)) {
1350 /* First bytes not aligned - read the 32 bit word to avoid corrupting
1351 * the other bytes in the word.
1353 retval
= aarch64_read_apb_ap_memory(target
, (address
& ~0x3), 4, 1, tmp_buff
);
1354 if (retval
!= ERROR_OK
)
1355 goto error_free_buff_w
;
1358 /* If end of write is not aligned, or the write is less than 4 bytes */
1359 if ((end_byte
!= 0) ||
1360 ((total_u32
== 1) && (total_bytes
!= 4))) {
1362 /* Read the last word to avoid corruption during 32 bit write */
1363 int mem_offset
= (total_u32
-1) * 4;
1364 retval
= aarch64_read_apb_ap_memory(target
, (address
& ~0x3) + mem_offset
, 4, 1, &tmp_buff
[mem_offset
]);
1365 if (retval
!= ERROR_OK
)
1366 goto error_free_buff_w
;
1369 /* Copy the write buffer over the top of the temporary buffer */
1370 memcpy(&tmp_buff
[start_byte
], buffer
, total_bytes
);
1372 /* We now have a 32 bit aligned buffer that can be written */
1375 retval
= mem_ap_read_atomic_u32(armv8
->debug_ap
,
1376 armv8
->debug_base
+ CPUV8_DBG_DSCR
, &dscr
);
1377 if (retval
!= ERROR_OK
)
1378 goto error_free_buff_w
;
1380 /* Set Normal access mode */
1381 dscr
= (dscr
& ~DSCR_MA
);
1382 retval
= mem_ap_write_atomic_u32(armv8
->debug_ap
,
1383 armv8
->debug_base
+ CPUV8_DBG_DSCR
, dscr
);
1385 if (arm
->core_state
== ARM_STATE_AARCH64
) {
1386 /* Write X0 with value 'address' using write procedure */
1387 /* Step 1.a+b - Write the address for read access into DBGDTR_EL0 */
1388 /* Step 1.c - Copy value from DTR to R0 using instruction mrs DBGDTR_EL0, x0 */
1389 retval
= dpm
->instr_write_data_dcc_64(dpm
,
1390 ARMV8_MRS(SYSTEM_DBG_DBGDTR_EL0
, 0), address
& ~0x3ULL
);
1392 /* Write R0 with value 'address' using write procedure */
1393 /* Step 1.a+b - Write the address for read access into DBGDTRRX */
1394 /* Step 1.c - Copy value from DTR to R0 using instruction mrc DBGDTRTXint, r0 */
1395 dpm
->instr_write_data_dcc(dpm
,
1396 ARMV4_5_MRC(14, 0, 0, 0, 5, 0), address
& ~0x3ULL
);
1399 /* Step 1.d - Change DCC to memory mode */
1400 dscr
= dscr
| DSCR_MA
;
1401 retval
+= mem_ap_write_atomic_u32(armv8
->debug_ap
,
1402 armv8
->debug_base
+ CPUV8_DBG_DSCR
, dscr
);
1403 if (retval
!= ERROR_OK
)
1404 goto error_unset_dtr_w
;
1407 /* Step 2.a - Do the write */
1408 retval
= mem_ap_write_buf_noincr(armv8
->debug_ap
,
1409 tmp_buff
, 4, total_u32
, armv8
->debug_base
+ CPUV8_DBG_DTRRX
);
1410 if (retval
!= ERROR_OK
)
1411 goto error_unset_dtr_w
;
1413 /* Step 3.a - Switch DTR mode back to Normal mode */
1414 dscr
= (dscr
& ~DSCR_MA
);
1415 retval
= mem_ap_write_atomic_u32(armv8
->debug_ap
,
1416 armv8
->debug_base
+ CPUV8_DBG_DSCR
, dscr
);
1417 if (retval
!= ERROR_OK
)
1418 goto error_unset_dtr_w
;
1420 /* Check for sticky abort flags in the DSCR */
1421 retval
= mem_ap_read_atomic_u32(armv8
->debug_ap
,
1422 armv8
->debug_base
+ CPUV8_DBG_DSCR
, &dscr
);
1423 if (retval
!= ERROR_OK
)
1424 goto error_free_buff_w
;
1427 if (dscr
& (DSCR_ERR
| DSCR_SYS_ERROR_PEND
)) {
1428 /* Abort occurred - clear it and exit */
1429 LOG_ERROR("abort occurred - dscr = 0x%08" PRIx32
, dscr
);
1430 armv8_dpm_handle_exception(dpm
);
1431 goto error_free_buff_w
;
1439 /* Unset DTR mode */
1440 mem_ap_read_atomic_u32(armv8
->debug_ap
,
1441 armv8
->debug_base
+ CPUV8_DBG_DSCR
, &dscr
);
1442 dscr
= (dscr
& ~DSCR_MA
);
1443 mem_ap_write_atomic_u32(armv8
->debug_ap
,
1444 armv8
->debug_base
+ CPUV8_DBG_DSCR
, dscr
);
1451 static int aarch64_read_apb_ap_memory(struct target
*target
,
1452 target_addr_t address
, uint32_t size
,
1453 uint32_t count
, uint8_t *buffer
)
1455 /* read memory through APB-AP */
1456 int retval
= ERROR_COMMAND_SYNTAX_ERROR
;
1457 struct armv8_common
*armv8
= target_to_armv8(target
);
1458 struct arm_dpm
*dpm
= &armv8
->dpm
;
1459 struct arm
*arm
= &armv8
->arm
;
1460 int total_bytes
= count
* size
;
1462 int start_byte
= address
& 0x3;
1463 int end_byte
= (address
+ total_bytes
) & 0x3;
1466 uint8_t *tmp_buff
= NULL
;
1470 if (target
->state
!= TARGET_HALTED
) {
1471 LOG_WARNING("target not halted");
1472 return ERROR_TARGET_NOT_HALTED
;
1475 total_u32
= DIV_ROUND_UP((address
& 3) + total_bytes
, 4);
1476 /* Mark register X0, X1 as dirty, as it will be used
1477 * for transferring the data.
1478 * It will be restored automatically when exiting
1481 reg
= armv8_reg_current(arm
, 1);
1484 reg
= armv8_reg_current(arm
, 0);
1488 retval
= mem_ap_read_atomic_u32(armv8
->debug_ap
,
1489 armv8
->debug_base
+ CPUV8_DBG_DSCR
, &dscr
);
1491 /* This algorithm comes from DDI0487A.g, chapter J9.1 */
1493 /* Set Normal access mode */
1494 dscr
= (dscr
& ~DSCR_MA
);
1495 retval
+= mem_ap_write_atomic_u32(armv8
->debug_ap
,
1496 armv8
->debug_base
+ CPUV8_DBG_DSCR
, dscr
);
1498 if (arm
->core_state
== ARM_STATE_AARCH64
) {
1499 /* Write X0 with value 'address' using write procedure */
1500 /* Step 1.a+b - Write the address for read access into DBGDTR_EL0 */
1501 /* Step 1.c - Copy value from DTR to R0 using instruction mrs DBGDTR_EL0, x0 */
1502 retval
+= dpm
->instr_write_data_dcc_64(dpm
,
1503 ARMV8_MRS(SYSTEM_DBG_DBGDTR_EL0
, 0), address
& ~0x3ULL
);
1504 /* Step 1.d - Dummy operation to ensure EDSCR.Txfull == 1 */
1505 retval
+= dpm
->instr_execute(dpm
, ARMV8_MSR_GP(SYSTEM_DBG_DBGDTR_EL0
, 0));
1506 /* Step 1.e - Change DCC to memory mode */
1507 dscr
= dscr
| DSCR_MA
;
1508 retval
+= mem_ap_write_atomic_u32(armv8
->debug_ap
,
1509 armv8
->debug_base
+ CPUV8_DBG_DSCR
, dscr
);
1510 /* Step 1.f - read DBGDTRTX and discard the value */
1511 retval
+= mem_ap_read_atomic_u32(armv8
->debug_ap
,
1512 armv8
->debug_base
+ CPUV8_DBG_DTRTX
, &value
);
1514 /* Write R0 with value 'address' using write procedure */
1515 /* Step 1.a+b - Write the address for read access into DBGDTRRXint */
1516 /* Step 1.c - Copy value from DTR to R0 using instruction mrc DBGDTRTXint, r0 */
1517 retval
+= dpm
->instr_write_data_dcc(dpm
,
1518 ARMV4_5_MRC(14, 0, 0, 0, 5, 0), address
& ~0x3ULL
);
1519 /* Step 1.d - Dummy operation to ensure EDSCR.Txfull == 1 */
1520 retval
+= dpm
->instr_execute(dpm
, ARMV4_5_MCR(14, 0, 0, 0, 5, 0));
1521 /* Step 1.e - Change DCC to memory mode */
1522 dscr
= dscr
| DSCR_MA
;
1523 retval
+= mem_ap_write_atomic_u32(armv8
->debug_ap
,
1524 armv8
->debug_base
+ CPUV8_DBG_DSCR
, dscr
);
1525 /* Step 1.f - read DBGDTRTX and discard the value */
1526 retval
+= mem_ap_read_atomic_u32(armv8
->debug_ap
,
1527 armv8
->debug_base
+ CPUV8_DBG_DTRTX
, &value
);
1530 if (retval
!= ERROR_OK
)
1531 goto error_unset_dtr_r
;
1533 /* Optimize the read as much as we can, either way we read in a single pass */
1534 if ((start_byte
) || (end_byte
)) {
1535 /* The algorithm only copies 32 bit words, so the buffer
1536 * should be expanded to include the words at either end.
1537 * The first and last words will be read into a temp buffer
1538 * to avoid corruption
1540 tmp_buff
= malloc(total_u32
* 4);
1542 goto error_unset_dtr_r
;
1544 /* use the tmp buffer to read the entire data */
1545 u8buf_ptr
= tmp_buff
;
1547 /* address and read length are aligned so read directly into the passed buffer */
1550 /* Read the data - Each read of the DTRTX register causes the instruction to be reissued
1551 * Abort flags are sticky, so can be read at end of transactions
1553 * This data is read in aligned to 32 bit boundary.
1556 /* Step 2.a - Loop n-1 times, each read of DBGDTRTX reads the data from [X0] and
1557 * increments X0 by 4. */
1558 retval
= mem_ap_read_buf_noincr(armv8
->debug_ap
, u8buf_ptr
, 4, total_u32
-1,
1559 armv8
->debug_base
+ CPUV8_DBG_DTRTX
);
1560 if (retval
!= ERROR_OK
)
1561 goto error_unset_dtr_r
;
1563 /* Step 3.a - set DTR access mode back to Normal mode */
1564 dscr
= (dscr
& ~DSCR_MA
);
1565 retval
= mem_ap_write_atomic_u32(armv8
->debug_ap
,
1566 armv8
->debug_base
+ CPUV8_DBG_DSCR
, dscr
);
1567 if (retval
!= ERROR_OK
)
1568 goto error_free_buff_r
;
1570 /* Step 3.b - read DBGDTRTX for the final value */
1571 retval
= mem_ap_read_atomic_u32(armv8
->debug_ap
,
1572 armv8
->debug_base
+ CPUV8_DBG_DTRTX
, &value
);
1573 memcpy(u8buf_ptr
+ (total_u32
-1) * 4, &value
, 4);
1575 /* Check for sticky abort flags in the DSCR */
1576 retval
= mem_ap_read_atomic_u32(armv8
->debug_ap
,
1577 armv8
->debug_base
+ CPUV8_DBG_DSCR
, &dscr
);
1578 if (retval
!= ERROR_OK
)
1579 goto error_free_buff_r
;
1583 if (dscr
& (DSCR_ERR
| DSCR_SYS_ERROR_PEND
)) {
1584 /* Abort occurred - clear it and exit */
1585 LOG_ERROR("abort occurred - dscr = 0x%08" PRIx32
, dscr
);
1586 armv8_dpm_handle_exception(dpm
);
1587 goto error_free_buff_r
;
1590 /* check if we need to copy aligned data by applying any shift necessary */
1592 memcpy(buffer
, tmp_buff
+ start_byte
, total_bytes
);
1600 /* Unset DTR mode */
1601 mem_ap_read_atomic_u32(armv8
->debug_ap
,
1602 armv8
->debug_base
+ CPUV8_DBG_DSCR
, &dscr
);
1603 dscr
= (dscr
& ~DSCR_MA
);
1604 mem_ap_write_atomic_u32(armv8
->debug_ap
,
1605 armv8
->debug_base
+ CPUV8_DBG_DSCR
, dscr
);
1612 static int aarch64_read_phys_memory(struct target
*target
,
1613 target_addr_t address
, uint32_t size
,
1614 uint32_t count
, uint8_t *buffer
)
1616 int retval
= ERROR_COMMAND_SYNTAX_ERROR
;
1618 if (count
&& buffer
) {
1619 /* read memory through APB-AP */
1620 retval
= aarch64_mmu_modify(target
, 0);
1621 if (retval
!= ERROR_OK
)
1623 retval
= aarch64_read_apb_ap_memory(target
, address
, size
, count
, buffer
);
1628 static int aarch64_read_memory(struct target
*target
, target_addr_t address
,
1629 uint32_t size
, uint32_t count
, uint8_t *buffer
)
1631 int mmu_enabled
= 0;
1634 /* determine if MMU was enabled on target stop */
1635 retval
= aarch64_mmu(target
, &mmu_enabled
);
1636 if (retval
!= ERROR_OK
)
1640 /* enable MMU as we could have disabled it for phys access */
1641 retval
= aarch64_mmu_modify(target
, 1);
1642 if (retval
!= ERROR_OK
)
1645 return aarch64_read_apb_ap_memory(target
, address
, size
, count
, buffer
);
1648 static int aarch64_write_phys_memory(struct target
*target
,
1649 target_addr_t address
, uint32_t size
,
1650 uint32_t count
, const uint8_t *buffer
)
1652 int retval
= ERROR_COMMAND_SYNTAX_ERROR
;
1654 if (count
&& buffer
) {
1655 /* write memory through APB-AP */
1656 retval
= aarch64_mmu_modify(target
, 0);
1657 if (retval
!= ERROR_OK
)
1659 return aarch64_write_apb_ap_memory(target
, address
, size
, count
, buffer
);
1665 static int aarch64_write_memory(struct target
*target
, target_addr_t address
,
1666 uint32_t size
, uint32_t count
, const uint8_t *buffer
)
1668 int mmu_enabled
= 0;
1671 /* determine if MMU was enabled on target stop */
1672 retval
= aarch64_mmu(target
, &mmu_enabled
);
1673 if (retval
!= ERROR_OK
)
1677 /* enable MMU as we could have disabled it for phys access */
1678 retval
= aarch64_mmu_modify(target
, 1);
1679 if (retval
!= ERROR_OK
)
1682 return aarch64_write_apb_ap_memory(target
, address
, size
, count
, buffer
);
1685 static int aarch64_handle_target_request(void *priv
)
1687 struct target
*target
= priv
;
1688 struct armv8_common
*armv8
= target_to_armv8(target
);
1691 if (!target_was_examined(target
))
1693 if (!target
->dbg_msg_enabled
)
1696 if (target
->state
== TARGET_RUNNING
) {
1699 retval
= mem_ap_read_atomic_u32(armv8
->debug_ap
,
1700 armv8
->debug_base
+ CPUV8_DBG_DSCR
, &dscr
);
1702 /* check if we have data */
1703 while ((dscr
& DSCR_DTR_TX_FULL
) && (retval
== ERROR_OK
)) {
1704 retval
= mem_ap_read_atomic_u32(armv8
->debug_ap
,
1705 armv8
->debug_base
+ CPUV8_DBG_DTRTX
, &request
);
1706 if (retval
== ERROR_OK
) {
1707 target_request(target
, request
);
1708 retval
= mem_ap_read_atomic_u32(armv8
->debug_ap
,
1709 armv8
->debug_base
+ CPUV8_DBG_DSCR
, &dscr
);
1717 static int aarch64_examine_first(struct target
*target
)
1719 struct aarch64_common
*aarch64
= target_to_aarch64(target
);
1720 struct armv8_common
*armv8
= &aarch64
->armv8_common
;
1721 struct adiv5_dap
*swjdp
= armv8
->arm
.dap
;
1723 int retval
= ERROR_OK
;
1724 uint64_t debug
, ttypr
;
1726 uint32_t tmp0
, tmp1
;
1727 debug
= ttypr
= cpuid
= 0;
1729 /* We do one extra read to ensure DAP is configured,
1730 * we call ahbap_debugport_init(swjdp) instead
1732 retval
= dap_dp_init(swjdp
);
1733 if (retval
!= ERROR_OK
)
1736 /* Search for the APB-AB - it is needed for access to debug registers */
1737 retval
= dap_find_ap(swjdp
, AP_TYPE_APB_AP
, &armv8
->debug_ap
);
1738 if (retval
!= ERROR_OK
) {
1739 LOG_ERROR("Could not find APB-AP for debug access");
1743 retval
= mem_ap_init(armv8
->debug_ap
);
1744 if (retval
!= ERROR_OK
) {
1745 LOG_ERROR("Could not initialize the APB-AP");
1749 armv8
->debug_ap
->memaccess_tck
= 80;
1751 if (!target
->dbgbase_set
) {
1753 /* Get ROM Table base */
1755 int32_t coreidx
= target
->coreid
;
1756 retval
= dap_get_debugbase(armv8
->debug_ap
, &dbgbase
, &apid
);
1757 if (retval
!= ERROR_OK
)
1759 /* Lookup 0x15 -- Processor DAP */
1760 retval
= dap_lookup_cs_component(armv8
->debug_ap
, dbgbase
, 0x15,
1761 &armv8
->debug_base
, &coreidx
);
1762 if (retval
!= ERROR_OK
)
1764 LOG_DEBUG("Detected core %" PRId32
" dbgbase: %08" PRIx32
1765 " apid: %08" PRIx32
, coreidx
, armv8
->debug_base
, apid
);
1767 armv8
->debug_base
= target
->dbgbase
;
1769 retval
= mem_ap_write_atomic_u32(armv8
->debug_ap
,
1770 armv8
->debug_base
+ CPUV8_DBG_LOCKACCESS
, 0xC5ACCE55);
1771 if (retval
!= ERROR_OK
) {
1772 LOG_DEBUG("LOCK debug access fail");
1776 retval
= mem_ap_write_atomic_u32(armv8
->debug_ap
,
1777 armv8
->debug_base
+ CPUV8_DBG_OSLAR
, 0);
1778 if (retval
!= ERROR_OK
) {
1779 LOG_DEBUG("Examine %s failed", "oslock");
1783 retval
= mem_ap_read_atomic_u32(armv8
->debug_ap
,
1784 armv8
->debug_base
+ CPUV8_DBG_MAINID0
, &cpuid
);
1785 if (retval
!= ERROR_OK
) {
1786 LOG_DEBUG("Examine %s failed", "CPUID");
1790 retval
= mem_ap_read_atomic_u32(armv8
->debug_ap
,
1791 armv8
->debug_base
+ CPUV8_DBG_MEMFEATURE0
, &tmp0
);
1792 retval
+= mem_ap_read_atomic_u32(armv8
->debug_ap
,
1793 armv8
->debug_base
+ CPUV8_DBG_MEMFEATURE0
+ 4, &tmp1
);
1794 if (retval
!= ERROR_OK
) {
1795 LOG_DEBUG("Examine %s failed", "Memory Model Type");
1799 ttypr
= (ttypr
<< 32) | tmp0
;
1801 retval
= mem_ap_read_atomic_u32(armv8
->debug_ap
,
1802 armv8
->debug_base
+ CPUV8_DBG_DBGFEATURE0
, &tmp0
);
1803 retval
+= mem_ap_read_atomic_u32(armv8
->debug_ap
,
1804 armv8
->debug_base
+ CPUV8_DBG_DBGFEATURE0
+ 4, &tmp1
);
1805 if (retval
!= ERROR_OK
) {
1806 LOG_DEBUG("Examine %s failed", "ID_AA64DFR0_EL1");
1810 debug
= (debug
<< 32) | tmp0
;
1812 LOG_DEBUG("cpuid = 0x%08" PRIx32
, cpuid
);
1813 LOG_DEBUG("ttypr = 0x%08" PRIx64
, ttypr
);
1814 LOG_DEBUG("debug = 0x%08" PRIx64
, debug
);
1816 if (target
->ctibase
== 0) {
1817 /* assume a v8 rom table layout */
1818 armv8
->cti_base
= target
->ctibase
= armv8
->debug_base
+ 0x10000;
1819 LOG_INFO("Target ctibase is not set, assuming 0x%0" PRIx32
, target
->ctibase
);
1821 armv8
->cti_base
= target
->ctibase
;
1823 armv8
->arm
.core_type
= ARM_MODE_MON
;
1824 retval
= aarch64_dpm_setup(aarch64
, debug
);
1825 if (retval
!= ERROR_OK
)
1828 /* Setup Breakpoint Register Pairs */
1829 aarch64
->brp_num
= (uint32_t)((debug
>> 12) & 0x0F) + 1;
1830 aarch64
->brp_num_context
= (uint32_t)((debug
>> 28) & 0x0F) + 1;
1831 aarch64
->brp_num_available
= aarch64
->brp_num
;
1832 aarch64
->brp_list
= calloc(aarch64
->brp_num
, sizeof(struct aarch64_brp
));
1833 for (i
= 0; i
< aarch64
->brp_num
; i
++) {
1834 aarch64
->brp_list
[i
].used
= 0;
1835 if (i
< (aarch64
->brp_num
-aarch64
->brp_num_context
))
1836 aarch64
->brp_list
[i
].type
= BRP_NORMAL
;
1838 aarch64
->brp_list
[i
].type
= BRP_CONTEXT
;
1839 aarch64
->brp_list
[i
].value
= 0;
1840 aarch64
->brp_list
[i
].control
= 0;
1841 aarch64
->brp_list
[i
].BRPn
= i
;
1844 LOG_DEBUG("Configured %i hw breakpoints", aarch64
->brp_num
);
1846 target_set_examined(target
);
1850 static int aarch64_examine(struct target
*target
)
1852 int retval
= ERROR_OK
;
1854 /* don't re-probe hardware after each reset */
1855 if (!target_was_examined(target
))
1856 retval
= aarch64_examine_first(target
);
1858 /* Configure core debug access */
1859 if (retval
== ERROR_OK
)
1860 retval
= aarch64_init_debug_access(target
);
1866 * Cortex-A8 target creation and initialization
1869 static int aarch64_init_target(struct command_context
*cmd_ctx
,
1870 struct target
*target
)
1872 /* examine_first() does a bunch of this */
1876 static int aarch64_init_arch_info(struct target
*target
,
1877 struct aarch64_common
*aarch64
, struct jtag_tap
*tap
)
1879 struct armv8_common
*armv8
= &aarch64
->armv8_common
;
1880 struct adiv5_dap
*dap
= armv8
->arm
.dap
;
1882 armv8
->arm
.dap
= dap
;
1884 /* Setup struct aarch64_common */
1885 aarch64
->common_magic
= AARCH64_COMMON_MAGIC
;
1886 /* tap has no dap initialized */
1888 tap
->dap
= dap_init();
1890 /* Leave (only) generic DAP stuff for debugport_init() */
1891 tap
->dap
->tap
= tap
;
1894 armv8
->arm
.dap
= tap
->dap
;
1896 aarch64
->fast_reg_read
= 0;
1898 /* register arch-specific functions */
1899 armv8
->examine_debug_reason
= NULL
;
1901 armv8
->post_debug_entry
= aarch64_post_debug_entry
;
1903 armv8
->pre_restore_context
= NULL
;
1905 armv8
->armv8_mmu
.read_physical_memory
= aarch64_read_phys_memory
;
1907 /* REVISIT v7a setup should be in a v7a-specific routine */
1908 armv8_init_arch_info(target
, armv8
);
1909 target_register_timer_callback(aarch64_handle_target_request
, 1, 1, target
);
1914 static int aarch64_target_create(struct target
*target
, Jim_Interp
*interp
)
1916 struct aarch64_common
*aarch64
= calloc(1, sizeof(struct aarch64_common
));
1918 return aarch64_init_arch_info(target
, aarch64
, target
->tap
);
1921 static int aarch64_mmu(struct target
*target
, int *enabled
)
1923 if (target
->state
!= TARGET_HALTED
) {
1924 LOG_ERROR("%s: target not halted", __func__
);
1925 return ERROR_TARGET_INVALID
;
1928 *enabled
= target_to_aarch64(target
)->armv8_common
.armv8_mmu
.mmu_enabled
;
1932 static int aarch64_virt2phys(struct target
*target
, target_addr_t virt
,
1933 target_addr_t
*phys
)
1935 return armv8_mmu_translate_va_pa(target
, virt
, phys
, 1);
1938 COMMAND_HANDLER(aarch64_handle_cache_info_command
)
1940 struct target
*target
= get_current_target(CMD_CTX
);
1941 struct armv8_common
*armv8
= target_to_armv8(target
);
1943 return armv8_handle_cache_info_command(CMD_CTX
,
1944 &armv8
->armv8_mmu
.armv8_cache
);
1948 COMMAND_HANDLER(aarch64_handle_dbginit_command
)
1950 struct target
*target
= get_current_target(CMD_CTX
);
1951 if (!target_was_examined(target
)) {
1952 LOG_ERROR("target not examined yet");
1956 return aarch64_init_debug_access(target
);
1958 COMMAND_HANDLER(aarch64_handle_smp_off_command
)
1960 struct target
*target
= get_current_target(CMD_CTX
);
1961 /* check target is an smp target */
1962 struct target_list
*head
;
1963 struct target
*curr
;
1964 head
= target
->head
;
1966 if (head
!= (struct target_list
*)NULL
) {
1967 while (head
!= (struct target_list
*)NULL
) {
1968 curr
= head
->target
;
1972 /* fixes the target display to the debugger */
1973 target
->gdb_service
->target
= target
;
1978 COMMAND_HANDLER(aarch64_handle_smp_on_command
)
1980 struct target
*target
= get_current_target(CMD_CTX
);
1981 struct target_list
*head
;
1982 struct target
*curr
;
1983 head
= target
->head
;
1984 if (head
!= (struct target_list
*)NULL
) {
1986 while (head
!= (struct target_list
*)NULL
) {
1987 curr
= head
->target
;
1995 COMMAND_HANDLER(aarch64_handle_smp_gdb_command
)
1997 struct target
*target
= get_current_target(CMD_CTX
);
1998 int retval
= ERROR_OK
;
1999 struct target_list
*head
;
2000 head
= target
->head
;
2001 if (head
!= (struct target_list
*)NULL
) {
2002 if (CMD_ARGC
== 1) {
2004 COMMAND_PARSE_NUMBER(int, CMD_ARGV
[0], coreid
);
2005 if (ERROR_OK
!= retval
)
2007 target
->gdb_service
->core
[1] = coreid
;
2010 command_print(CMD_CTX
, "gdb coreid %" PRId32
" -> %" PRId32
, target
->gdb_service
->core
[0]
2011 , target
->gdb_service
->core
[1]);
2016 static const struct command_registration aarch64_exec_command_handlers
[] = {
2018 .name
= "cache_info",
2019 .handler
= aarch64_handle_cache_info_command
,
2020 .mode
= COMMAND_EXEC
,
2021 .help
= "display information about target caches",
2026 .handler
= aarch64_handle_dbginit_command
,
2027 .mode
= COMMAND_EXEC
,
2028 .help
= "Initialize core debug",
2031 { .name
= "smp_off",
2032 .handler
= aarch64_handle_smp_off_command
,
2033 .mode
= COMMAND_EXEC
,
2034 .help
= "Stop smp handling",
2039 .handler
= aarch64_handle_smp_on_command
,
2040 .mode
= COMMAND_EXEC
,
2041 .help
= "Restart smp handling",
2046 .handler
= aarch64_handle_smp_gdb_command
,
2047 .mode
= COMMAND_EXEC
,
2048 .help
= "display/fix current core played to gdb",
2053 COMMAND_REGISTRATION_DONE
2055 static const struct command_registration aarch64_command_handlers
[] = {
2057 .chain
= armv8_command_handlers
,
2061 .mode
= COMMAND_ANY
,
2062 .help
= "Aarch64 command group",
2064 .chain
= aarch64_exec_command_handlers
,
2066 COMMAND_REGISTRATION_DONE
2069 struct target_type aarch64_target
= {
2072 .poll
= aarch64_poll
,
2073 .arch_state
= armv8_arch_state
,
2075 .halt
= aarch64_halt
,
2076 .resume
= aarch64_resume
,
2077 .step
= aarch64_step
,
2079 .assert_reset
= aarch64_assert_reset
,
2080 .deassert_reset
= aarch64_deassert_reset
,
2082 /* REVISIT allow exporting VFP3 registers ... */
2083 .get_gdb_reg_list
= armv8_get_gdb_reg_list
,
2085 .read_memory
= aarch64_read_memory
,
2086 .write_memory
= aarch64_write_memory
,
2088 .add_breakpoint
= aarch64_add_breakpoint
,
2089 .add_context_breakpoint
= aarch64_add_context_breakpoint
,
2090 .add_hybrid_breakpoint
= aarch64_add_hybrid_breakpoint
,
2091 .remove_breakpoint
= aarch64_remove_breakpoint
,
2092 .add_watchpoint
= NULL
,
2093 .remove_watchpoint
= NULL
,
2095 .commands
= aarch64_command_handlers
,
2096 .target_create
= aarch64_target_create
,
2097 .init_target
= aarch64_init_target
,
2098 .examine
= aarch64_examine
,
2100 .read_phys_memory
= aarch64_read_phys_memory
,
2101 .write_phys_memory
= aarch64_write_phys_memory
,
2103 .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)