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., *
17 ***************************************************************************/
23 #include <helper/replacements.h>
26 #include "arm_disassembler.h"
29 #include <helper/binarybuffer.h>
30 #include <helper/command.h>
36 #include "armv8_opcodes.h"
38 #include "target_type.h"
40 #define __unused __attribute__((unused))
42 static const char * const armv8_state_strings
[] = {
43 "AArch32", "Thumb", "Jazelle", "ThumbEE", "AArch64",
49 /* For user and system modes, these list indices for all registers.
50 * otherwise they're just indices for the shadow registers and SPSR.
52 unsigned short n_indices
;
53 const uint8_t *indices
;
54 } armv8_mode_data
[] = {
55 /* These special modes are currently only supported
56 * by ARMv6M and ARMv7M profiles */
103 .psr
= ARMV8_64_EL3T
,
107 .psr
= ARMV8_64_EL3H
,
111 /** Map PSR mode bits to the name of an ARM processor operating mode. */
112 const char *armv8_mode_name(unsigned psr_mode
)
114 for (unsigned i
= 0; i
< ARRAY_SIZE(armv8_mode_data
); i
++) {
115 if (armv8_mode_data
[i
].psr
== psr_mode
)
116 return armv8_mode_data
[i
].name
;
118 LOG_ERROR("unrecognized psr mode: %#02x", psr_mode
);
119 return "UNRECOGNIZED";
122 int armv8_mode_to_number(enum arm_mode mode
)
126 /* map MODE_ANY to user mode */
159 LOG_ERROR("invalid mode value encountered %d", mode
);
164 static int armv8_read_reg(struct armv8_common
*armv8
, int regnum
, uint64_t *regval
)
166 struct arm_dpm
*dpm
= &armv8
->dpm
;
173 retval
= dpm
->instr_read_data_dcc_64(dpm
,
174 ARMV8_MSR_GP(SYSTEM_DBG_DBGDTR_EL0
, regnum
), &value_64
);
177 retval
= dpm
->instr_read_data_r0_64(dpm
,
178 ARMV8_MOVFSP_64(0), &value_64
);
181 retval
= dpm
->instr_read_data_r0_64(dpm
,
182 ARMV8_MRS_DLR(0), &value_64
);
185 retval
= dpm
->instr_read_data_r0(dpm
,
186 ARMV8_MRS_DSPSR(0), &value
);
190 retval
= dpm
->instr_read_data_r0_64(dpm
,
191 ARMV8_MRS(SYSTEM_ELR_EL1
, 0), &value_64
);
194 retval
= dpm
->instr_read_data_r0_64(dpm
,
195 ARMV8_MRS(SYSTEM_ELR_EL2
, 0), &value_64
);
198 retval
= dpm
->instr_read_data_r0_64(dpm
,
199 ARMV8_MRS(SYSTEM_ELR_EL3
, 0), &value_64
);
202 retval
= dpm
->instr_read_data_r0(dpm
,
203 ARMV8_MRS(SYSTEM_ESR_EL1
, 0), &value
);
207 retval
= dpm
->instr_read_data_r0(dpm
,
208 ARMV8_MRS(SYSTEM_ESR_EL2
, 0), &value
);
212 retval
= dpm
->instr_read_data_r0(dpm
,
213 ARMV8_MRS(SYSTEM_ESR_EL3
, 0), &value
);
217 retval
= dpm
->instr_read_data_r0(dpm
,
218 ARMV8_MRS(SYSTEM_SPSR_EL1
, 0), &value
);
222 retval
= dpm
->instr_read_data_r0(dpm
,
223 ARMV8_MRS(SYSTEM_SPSR_EL2
, 0), &value
);
227 retval
= dpm
->instr_read_data_r0(dpm
,
228 ARMV8_MRS(SYSTEM_SPSR_EL3
, 0), &value
);
236 if (retval
== ERROR_OK
&& regval
!= NULL
)
242 static int armv8_write_reg(struct armv8_common
*armv8
, int regnum
, uint64_t value_64
)
244 struct arm_dpm
*dpm
= &armv8
->dpm
;
250 retval
= dpm
->instr_write_data_dcc_64(dpm
,
251 ARMV8_MRS(SYSTEM_DBG_DBGDTR_EL0
, regnum
),
255 retval
= dpm
->instr_write_data_r0_64(dpm
,
260 retval
= dpm
->instr_write_data_r0_64(dpm
,
266 retval
= dpm
->instr_write_data_r0(dpm
,
270 /* registers clobbered by taking exception in debug state */
272 retval
= dpm
->instr_write_data_r0_64(dpm
,
273 ARMV8_MSR_GP(SYSTEM_ELR_EL1
, 0), value_64
);
276 retval
= dpm
->instr_write_data_r0_64(dpm
,
277 ARMV8_MSR_GP(SYSTEM_ELR_EL2
, 0), value_64
);
280 retval
= dpm
->instr_write_data_r0_64(dpm
,
281 ARMV8_MSR_GP(SYSTEM_ELR_EL3
, 0), value_64
);
285 retval
= dpm
->instr_write_data_r0(dpm
,
286 ARMV8_MSR_GP(SYSTEM_ESR_EL1
, 0), value
);
290 retval
= dpm
->instr_write_data_r0(dpm
,
291 ARMV8_MSR_GP(SYSTEM_ESR_EL2
, 0), value
);
295 retval
= dpm
->instr_write_data_r0(dpm
,
296 ARMV8_MSR_GP(SYSTEM_ESR_EL3
, 0), value
);
300 retval
= dpm
->instr_write_data_r0(dpm
,
301 ARMV8_MSR_GP(SYSTEM_SPSR_EL1
, 0), value
);
305 retval
= dpm
->instr_write_data_r0(dpm
,
306 ARMV8_MSR_GP(SYSTEM_SPSR_EL2
, 0), value
);
310 retval
= dpm
->instr_write_data_r0(dpm
,
311 ARMV8_MSR_GP(SYSTEM_SPSR_EL3
, 0), value
);
321 static int armv8_read_reg32(struct armv8_common
*armv8
, int regnum
, uint64_t *regval
)
323 struct arm_dpm
*dpm
= &armv8
->dpm
;
328 case ARMV8_R0
... ARMV8_R14
:
329 /* return via DCC: "MCR p14, 0, Rnum, c0, c5, 0" */
330 retval
= dpm
->instr_read_data_dcc(dpm
,
331 ARMV4_5_MCR(14, 0, regnum
, 0, 5, 0),
335 retval
= dpm
->instr_read_data_dcc(dpm
,
336 ARMV4_5_MCR(14, 0, 13, 0, 5, 0),
340 retval
= dpm
->instr_read_data_r0(dpm
,
345 retval
= dpm
->instr_read_data_r0(dpm
,
349 case ARMV8_ELR_EL1
: /* mapped to LR_svc */
350 retval
= dpm
->instr_read_data_dcc(dpm
,
351 ARMV4_5_MCR(14, 0, 14, 0, 5, 0),
354 case ARMV8_ELR_EL2
: /* mapped to ELR_hyp */
355 retval
= dpm
->instr_read_data_r0(dpm
,
356 ARMV8_MRS_T1(0, 14, 0, 1),
359 case ARMV8_ELR_EL3
: /* mapped to LR_mon */
360 retval
= dpm
->instr_read_data_dcc(dpm
,
361 ARMV4_5_MCR(14, 0, 14, 0, 5, 0),
364 case ARMV8_ESR_EL1
: /* mapped to DFSR */
365 retval
= dpm
->instr_read_data_r0(dpm
,
366 ARMV4_5_MRC(15, 0, 0, 5, 0, 0),
369 case ARMV8_ESR_EL2
: /* mapped to HSR */
370 retval
= dpm
->instr_read_data_r0(dpm
,
371 ARMV4_5_MRC(15, 4, 0, 5, 2, 0),
374 case ARMV8_ESR_EL3
: /* FIXME: no equivalent in aarch32? */
377 case ARMV8_SPSR_EL1
: /* mapped to SPSR_svc */
378 retval
= dpm
->instr_read_data_r0(dpm
,
379 ARMV8_MRS_xPSR_T1(1, 0),
382 case ARMV8_SPSR_EL2
: /* mapped to SPSR_hyp */
383 retval
= dpm
->instr_read_data_r0(dpm
,
384 ARMV8_MRS_xPSR_T1(1, 0),
387 case ARMV8_SPSR_EL3
: /* mapped to SPSR_mon */
388 retval
= dpm
->instr_read_data_r0(dpm
,
389 ARMV8_MRS_xPSR_T1(1, 0),
397 if (retval
== ERROR_OK
&& regval
!= NULL
)
403 static int armv8_write_reg32(struct armv8_common
*armv8
, int regnum
, uint64_t value
)
405 struct arm_dpm
*dpm
= &armv8
->dpm
;
409 case ARMV8_R0
... ARMV8_R14
:
410 /* load register from DCC: "MRC p14, 0, Rnum, c0, c5, 0" */
411 retval
= dpm
->instr_write_data_dcc(dpm
,
412 ARMV4_5_MRC(14, 0, regnum
, 0, 5, 0), value
);
415 retval
= dpm
->instr_write_data_dcc(dpm
,
416 ARMV4_5_MRC(14, 0, 13, 0, 5, 0),
420 * read r0 from DCC; then "MOV pc, r0" */
421 retval
= dpm
->instr_write_data_r0(dpm
,
422 ARMV8_MCR_DLR(0), value
);
424 case ARMV8_xPSR
: /* CPSR */
425 /* read r0 from DCC, then "MCR r0, DSPSR" */
426 retval
= dpm
->instr_write_data_r0(dpm
,
427 ARMV8_MCR_DSPSR(0), value
);
429 case ARMV8_ELR_EL1
: /* mapped to LR_svc */
430 retval
= dpm
->instr_write_data_dcc(dpm
,
431 ARMV4_5_MRC(14, 0, 14, 0, 5, 0),
434 case ARMV8_ELR_EL2
: /* mapped to ELR_hyp */
435 retval
= dpm
->instr_write_data_r0(dpm
,
436 ARMV8_MSR_GP_T1(0, 14, 0, 1),
439 case ARMV8_ELR_EL3
: /* mapped to LR_mon */
440 retval
= dpm
->instr_write_data_dcc(dpm
,
441 ARMV4_5_MRC(14, 0, 14, 0, 5, 0),
444 case ARMV8_ESR_EL1
: /* mapped to DFSR */
445 retval
= dpm
->instr_write_data_r0(dpm
,
446 ARMV4_5_MCR(15, 0, 0, 5, 0, 0),
449 case ARMV8_ESR_EL2
: /* mapped to HSR */
450 retval
= dpm
->instr_write_data_r0(dpm
,
451 ARMV4_5_MCR(15, 4, 0, 5, 2, 0),
454 case ARMV8_ESR_EL3
: /* FIXME: no equivalent in aarch32? */
457 case ARMV8_SPSR_EL1
: /* mapped to SPSR_svc */
458 retval
= dpm
->instr_write_data_r0(dpm
,
459 ARMV8_MSR_GP_xPSR_T1(1, 0, 15),
462 case ARMV8_SPSR_EL2
: /* mapped to SPSR_hyp */
463 retval
= dpm
->instr_write_data_r0(dpm
,
464 ARMV8_MSR_GP_xPSR_T1(1, 0, 15),
467 case ARMV8_SPSR_EL3
: /* mapped to SPSR_mon */
468 retval
= dpm
->instr_write_data_r0(dpm
,
469 ARMV8_MSR_GP_xPSR_T1(1, 0, 15),
481 void armv8_select_reg_access(struct armv8_common
*armv8
, bool is_aarch64
)
484 armv8
->read_reg_u64
= armv8_read_reg
;
485 armv8
->write_reg_u64
= armv8_write_reg
;
487 armv8
->read_reg_u64
= armv8_read_reg32
;
488 armv8
->write_reg_u64
= armv8_write_reg32
;
492 /* retrieve core id cluster id */
493 int armv8_read_mpidr(struct armv8_common
*armv8
)
495 int retval
= ERROR_FAIL
;
496 struct arm_dpm
*dpm
= armv8
->arm
.dpm
;
499 retval
= dpm
->prepare(dpm
);
500 if (retval
!= ERROR_OK
)
503 retval
= dpm
->instr_read_data_r0(dpm
, armv8_opcode(armv8
, READ_REG_MPIDR
), &mpidr
);
504 if (retval
!= ERROR_OK
)
507 armv8
->multi_processor_system
= (mpidr
>> 30) & 1;
508 armv8
->cluster_id
= (mpidr
>> 8) & 0xf;
509 armv8
->cpu_id
= mpidr
& 0x3;
510 LOG_INFO("%s cluster %x core %x %s", target_name(armv8
->arm
.target
),
513 armv8
->multi_processor_system
== 0 ? "multi core" : "mono core");
516 LOG_ERROR("mpdir not in multiprocessor format");
524 * Configures host-side ARM records to reflect the specified CPSR.
525 * Later, code can use arm_reg_current() to map register numbers
526 * according to how they are exposed by this mode.
528 void armv8_set_cpsr(struct arm
*arm
, uint32_t cpsr
)
530 uint32_t mode
= cpsr
& 0x1F;
532 /* NOTE: this may be called very early, before the register
533 * cache is set up. We can't defend against many errors, in
534 * particular against CPSRs that aren't valid *here* ...
537 buf_set_u32(arm
->cpsr
->value
, 0, 32, cpsr
);
538 arm
->cpsr
->valid
= 1;
539 arm
->cpsr
->dirty
= 0;
542 /* Older ARMs won't have the J bit */
543 enum arm_state state
= 0xFF;
545 if (((cpsr
& 0x10) >> 4) == 0) {
546 state
= ARM_STATE_AARCH64
;
548 if (cpsr
& (1 << 5)) { /* T */
549 if (cpsr
& (1 << 24)) { /* J */
550 LOG_WARNING("ThumbEE -- incomplete support");
551 state
= ARM_STATE_THUMB_EE
;
553 state
= ARM_STATE_THUMB
;
555 if (cpsr
& (1 << 24)) { /* J */
556 LOG_ERROR("Jazelle state handling is BROKEN!");
557 state
= ARM_STATE_JAZELLE
;
559 state
= ARM_STATE_ARM
;
562 arm
->core_state
= state
;
563 if (arm
->core_state
== ARM_STATE_AARCH64
)
564 arm
->core_mode
= (mode
<< 4) | 0xf;
566 arm
->core_mode
= mode
;
568 LOG_DEBUG("set CPSR %#8.8x: %s mode, %s state", (unsigned) cpsr
,
569 armv8_mode_name(arm
->core_mode
),
570 armv8_state_strings
[arm
->core_state
]);
573 static void armv8_show_fault_registers32(struct armv8_common
*armv8
)
575 uint32_t dfsr
, ifsr
, dfar
, ifar
;
576 struct arm_dpm
*dpm
= armv8
->arm
.dpm
;
579 retval
= dpm
->prepare(dpm
);
580 if (retval
!= ERROR_OK
)
583 /* ARMV4_5_MRC(cpnum, op1, r0, CRn, CRm, op2) */
585 /* c5/c0 - {data, instruction} fault status registers */
586 retval
= dpm
->instr_read_data_r0(dpm
,
587 ARMV4_5_MRC(15, 0, 0, 5, 0, 0),
589 if (retval
!= ERROR_OK
)
592 retval
= dpm
->instr_read_data_r0(dpm
,
593 ARMV4_5_MRC(15, 0, 0, 5, 0, 1),
595 if (retval
!= ERROR_OK
)
598 /* c6/c0 - {data, instruction} fault address registers */
599 retval
= dpm
->instr_read_data_r0(dpm
,
600 ARMV4_5_MRC(15, 0, 0, 6, 0, 0),
602 if (retval
!= ERROR_OK
)
605 retval
= dpm
->instr_read_data_r0(dpm
,
606 ARMV4_5_MRC(15, 0, 0, 6, 0, 2),
608 if (retval
!= ERROR_OK
)
611 LOG_USER("Data fault registers DFSR: %8.8" PRIx32
612 ", DFAR: %8.8" PRIx32
, dfsr
, dfar
);
613 LOG_USER("Instruction fault registers IFSR: %8.8" PRIx32
614 ", IFAR: %8.8" PRIx32
, ifsr
, ifar
);
617 /* (void) */ dpm
->finish(dpm
);
620 static void armv8_show_fault_registers(struct target
*target
)
622 struct armv8_common
*armv8
= target_to_armv8(target
);
624 if (armv8
->arm
.core_state
!= ARM_STATE_AARCH64
)
625 armv8_show_fault_registers32(armv8
);
628 static uint8_t armv8_pa_size(uint32_t ps
)
651 LOG_INFO("Unknow physicall address size");
657 static __unused
int armv8_read_ttbcr32(struct target
*target
)
659 struct armv8_common
*armv8
= target_to_armv8(target
);
660 struct arm_dpm
*dpm
= armv8
->arm
.dpm
;
661 uint32_t ttbcr
, ttbcr_n
;
662 int retval
= dpm
->prepare(dpm
);
663 if (retval
!= ERROR_OK
)
665 /* MRC p15,0,<Rt>,c2,c0,2 ; Read CP15 Translation Table Base Control Register*/
666 retval
= dpm
->instr_read_data_r0(dpm
,
667 ARMV4_5_MRC(15, 0, 0, 2, 0, 2),
669 if (retval
!= ERROR_OK
)
672 LOG_DEBUG("ttbcr %" PRIx32
, ttbcr
);
674 ttbcr_n
= ttbcr
& 0x7;
675 armv8
->armv8_mmu
.ttbcr
= ttbcr
;
678 * ARM Architecture Reference Manual (ARMv7-A and ARMv7-Redition),
679 * document # ARM DDI 0406C
681 armv8
->armv8_mmu
.ttbr_range
[0] = 0xffffffff >> ttbcr_n
;
682 armv8
->armv8_mmu
.ttbr_range
[1] = 0xffffffff;
683 armv8
->armv8_mmu
.ttbr_mask
[0] = 0xffffffff << (14 - ttbcr_n
);
684 armv8
->armv8_mmu
.ttbr_mask
[1] = 0xffffffff << 14;
686 LOG_DEBUG("ttbr1 %s, ttbr0_mask %" PRIx32
" ttbr1_mask %" PRIx32
,
687 (ttbcr_n
!= 0) ? "used" : "not used",
688 armv8
->armv8_mmu
.ttbr_mask
[0],
689 armv8
->armv8_mmu
.ttbr_mask
[1]);
696 static __unused
int armv8_read_ttbcr(struct target
*target
)
698 struct armv8_common
*armv8
= target_to_armv8(target
);
699 struct arm_dpm
*dpm
= armv8
->arm
.dpm
;
700 struct arm
*arm
= &armv8
->arm
;
704 int retval
= dpm
->prepare(dpm
);
705 if (retval
!= ERROR_OK
)
708 /* claaer ttrr1_used and ttbr0_mask */
709 memset(&armv8
->armv8_mmu
.ttbr1_used
, 0, sizeof(armv8
->armv8_mmu
.ttbr1_used
));
710 memset(&armv8
->armv8_mmu
.ttbr0_mask
, 0, sizeof(armv8
->armv8_mmu
.ttbr0_mask
));
712 switch (armv8_curel_from_core_mode(arm
->core_mode
)) {
713 case SYSTEM_CUREL_EL3
:
714 retval
= dpm
->instr_read_data_r0(dpm
,
715 ARMV8_MRS(SYSTEM_TCR_EL3
, 0),
717 retval
+= dpm
->instr_read_data_r0_64(dpm
,
718 ARMV8_MRS(SYSTEM_TTBR0_EL3
, 0),
720 if (retval
!= ERROR_OK
)
722 armv8
->va_size
= 64 - (ttbcr
& 0x3F);
723 armv8
->pa_size
= armv8_pa_size((ttbcr
>> 16) & 7);
724 armv8
->page_size
= (ttbcr
>> 14) & 3;
726 case SYSTEM_CUREL_EL2
:
727 retval
= dpm
->instr_read_data_r0(dpm
,
728 ARMV8_MRS(SYSTEM_TCR_EL2
, 0),
730 retval
+= dpm
->instr_read_data_r0_64(dpm
,
731 ARMV8_MRS(SYSTEM_TTBR0_EL2
, 0),
733 if (retval
!= ERROR_OK
)
735 armv8
->va_size
= 64 - (ttbcr
& 0x3F);
736 armv8
->pa_size
= armv8_pa_size((ttbcr
>> 16) & 7);
737 armv8
->page_size
= (ttbcr
>> 14) & 3;
739 case SYSTEM_CUREL_EL0
:
740 armv8_dpm_modeswitch(dpm
, ARMV8_64_EL1H
);
742 case SYSTEM_CUREL_EL1
:
743 retval
= dpm
->instr_read_data_r0_64(dpm
,
744 ARMV8_MRS(SYSTEM_TCR_EL1
, 0),
746 armv8
->va_size
= 64 - (ttbcr_64
& 0x3F);
747 armv8
->pa_size
= armv8_pa_size((ttbcr_64
>> 32) & 7);
748 armv8
->page_size
= (ttbcr_64
>> 14) & 3;
749 armv8
->armv8_mmu
.ttbr1_used
= (((ttbcr_64
>> 16) & 0x3F) != 0) ? 1 : 0;
750 armv8
->armv8_mmu
.ttbr0_mask
= 0x0000FFFFFFFFFFFF;
751 retval
+= dpm
->instr_read_data_r0_64(dpm
,
752 ARMV8_MRS(SYSTEM_TTBR0_EL1
| (armv8
->armv8_mmu
.ttbr1_used
), 0),
754 if (retval
!= ERROR_OK
)
758 LOG_ERROR("unknow core state");
762 if (retval
!= ERROR_OK
)
765 if (armv8
->armv8_mmu
.ttbr1_used
== 1)
766 LOG_INFO("TTBR0 access above %" PRIx64
, (uint64_t)(armv8
->armv8_mmu
.ttbr0_mask
));
769 armv8_dpm_modeswitch(dpm
, ARM_MODE_ANY
);
774 /* method adapted to cortex A : reused arm v4 v5 method*/
775 int armv8_mmu_translate_va(struct target
*target
, target_addr_t va
, target_addr_t
*val
)
780 /* V8 method VA TO PA */
781 int armv8_mmu_translate_va_pa(struct target
*target
, target_addr_t va
,
782 target_addr_t
*val
, int meminfo
)
784 struct armv8_common
*armv8
= target_to_armv8(target
);
785 struct arm
*arm
= target_to_arm(target
);
786 struct arm_dpm
*dpm
= &armv8
->dpm
;
787 enum arm_mode target_mode
= ARM_MODE_ANY
;
792 static const char * const shared_name
[] = {
793 "Non-", "UNDEFINED ", "Outer ", "Inner "
796 static const char * const secure_name
[] = {
797 "Secure", "Not Secure"
800 retval
= dpm
->prepare(dpm
);
801 if (retval
!= ERROR_OK
)
804 switch (armv8_curel_from_core_mode(arm
->core_mode
)) {
805 case SYSTEM_CUREL_EL0
:
806 instr
= ARMV8_SYS(SYSTEM_ATS12E0R
, 0);
807 /* can only execute instruction at EL2 */
808 target_mode
= ARMV8_64_EL2H
;
810 case SYSTEM_CUREL_EL1
:
811 instr
= ARMV8_SYS(SYSTEM_ATS12E1R
, 0);
812 /* can only execute instruction at EL2 */
813 target_mode
= ARMV8_64_EL2H
;
815 case SYSTEM_CUREL_EL2
:
816 instr
= ARMV8_SYS(SYSTEM_ATS1E2R
, 0);
818 case SYSTEM_CUREL_EL3
:
819 instr
= ARMV8_SYS(SYSTEM_ATS1E3R
, 0);
826 if (target_mode
!= ARM_MODE_ANY
)
827 armv8_dpm_modeswitch(dpm
, target_mode
);
829 /* write VA to R0 and execute translation instruction */
830 retval
= dpm
->instr_write_data_r0_64(dpm
, instr
, (uint64_t)va
);
831 /* read result from PAR_EL1 */
832 if (retval
== ERROR_OK
)
833 retval
= dpm
->instr_read_data_r0_64(dpm
, ARMV8_MRS(SYSTEM_PAR_EL1
, 0), &par
);
835 /* switch back to saved PE mode */
836 if (target_mode
!= ARM_MODE_ANY
)
837 armv8_dpm_modeswitch(dpm
, ARM_MODE_ANY
);
841 if (retval
!= ERROR_OK
)
844 if (retval
!= ERROR_OK
)
848 LOG_ERROR("Address translation failed at stage %i, FST=%x, PTW=%i",
849 ((int)(par
>> 9) & 1)+1, (int)(par
>> 1) & 0x3f, (int)(par
>> 8) & 1);
854 *val
= (par
& 0xFFFFFFFFF000UL
) | (va
& 0xFFF);
856 int SH
= (par
>> 7) & 3;
857 int NS
= (par
>> 9) & 1;
858 int ATTR
= (par
>> 56) & 0xFF;
860 char *memtype
= (ATTR
& 0xF0) == 0 ? "Device Memory" : "Normal Memory";
862 LOG_USER("%sshareable, %s",
863 shared_name
[SH
], secure_name
[NS
]);
864 LOG_USER("%s", memtype
);
871 int armv8_handle_cache_info_command(struct command_context
*cmd_ctx
,
872 struct armv8_cache_common
*armv8_cache
)
874 if (armv8_cache
->info
== -1) {
875 command_print(cmd_ctx
, "cache not yet identified");
879 if (armv8_cache
->display_cache_info
)
880 armv8_cache
->display_cache_info(cmd_ctx
, armv8_cache
);
884 int armv8_init_arch_info(struct target
*target
, struct armv8_common
*armv8
)
886 struct arm
*arm
= &armv8
->arm
;
887 arm
->arch_info
= armv8
;
888 target
->arch_info
= &armv8
->arm
;
889 /* target is useful in all function arm v4 5 compatible */
890 armv8
->arm
.target
= target
;
891 armv8
->arm
.common_magic
= ARM_COMMON_MAGIC
;
892 armv8
->common_magic
= ARMV8_COMMON_MAGIC
;
894 armv8
->armv8_mmu
.armv8_cache
.l2_cache
= NULL
;
895 armv8
->armv8_mmu
.armv8_cache
.info
= -1;
896 armv8
->armv8_mmu
.armv8_cache
.flush_all_data_cache
= NULL
;
897 armv8
->armv8_mmu
.armv8_cache
.display_cache_info
= NULL
;
901 int armv8_aarch64_state(struct target
*target
)
903 struct arm
*arm
= target_to_arm(target
);
905 if (arm
->common_magic
!= ARM_COMMON_MAGIC
) {
906 LOG_ERROR("BUG: called for a non-ARM target");
910 LOG_USER("target halted in %s state due to %s, current mode: %s\n"
911 "cpsr: 0x%8.8" PRIx32
" pc: 0x%" PRIx64
"%s",
912 armv8_state_strings
[arm
->core_state
],
913 debug_reason_name(target
),
914 armv8_mode_name(arm
->core_mode
),
915 buf_get_u32(arm
->cpsr
->value
, 0, 32),
916 buf_get_u64(arm
->pc
->value
, 0, 64),
917 arm
->is_semihosting
? ", semihosting" : "");
922 int armv8_arch_state(struct target
*target
)
924 static const char * const state
[] = {
925 "disabled", "enabled"
928 struct armv8_common
*armv8
= target_to_armv8(target
);
929 struct arm
*arm
= &armv8
->arm
;
931 if (armv8
->common_magic
!= ARMV8_COMMON_MAGIC
) {
932 LOG_ERROR("BUG: called for a non-Armv8 target");
933 return ERROR_COMMAND_SYNTAX_ERROR
;
936 if (arm
->core_state
== ARM_STATE_AARCH64
)
937 armv8_aarch64_state(target
);
939 arm_arch_state(target
);
941 LOG_USER("MMU: %s, D-Cache: %s, I-Cache: %s",
942 state
[armv8
->armv8_mmu
.mmu_enabled
],
943 state
[armv8
->armv8_mmu
.armv8_cache
.d_u_cache_enabled
],
944 state
[armv8
->armv8_mmu
.armv8_cache
.i_cache_enabled
]);
946 if (arm
->core_mode
== ARM_MODE_ABT
)
947 armv8_show_fault_registers(target
);
949 if (target
->debug_reason
== DBG_REASON_WATCHPOINT
)
950 LOG_USER("Watchpoint triggered at PC %#08x",
951 (unsigned) armv8
->dpm
.wp_pc
);
956 static const struct {
965 { ARMV8_R0
, "x0", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core" },
966 { ARMV8_R1
, "x1", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core" },
967 { ARMV8_R2
, "x2", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core" },
968 { ARMV8_R3
, "x3", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core" },
969 { ARMV8_R4
, "x4", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core" },
970 { ARMV8_R5
, "x5", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core" },
971 { ARMV8_R6
, "x6", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core" },
972 { ARMV8_R7
, "x7", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core" },
973 { ARMV8_R8
, "x8", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core" },
974 { ARMV8_R9
, "x9", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core" },
975 { ARMV8_R10
, "x10", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core" },
976 { ARMV8_R11
, "x11", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core" },
977 { ARMV8_R12
, "x12", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core" },
978 { ARMV8_R13
, "x13", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core" },
979 { ARMV8_R14
, "x14", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core" },
980 { ARMV8_R15
, "x15", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core" },
981 { ARMV8_R16
, "x16", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core" },
982 { ARMV8_R17
, "x17", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core" },
983 { ARMV8_R18
, "x18", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core" },
984 { ARMV8_R19
, "x19", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core" },
985 { ARMV8_R20
, "x20", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core" },
986 { ARMV8_R21
, "x21", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core" },
987 { ARMV8_R22
, "x22", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core" },
988 { ARMV8_R23
, "x23", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core" },
989 { ARMV8_R24
, "x24", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core" },
990 { ARMV8_R25
, "x25", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core" },
991 { ARMV8_R26
, "x26", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core" },
992 { ARMV8_R27
, "x27", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core" },
993 { ARMV8_R28
, "x28", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core" },
994 { ARMV8_R29
, "x29", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core" },
995 { ARMV8_R30
, "x30", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core" },
997 { ARMV8_SP
, "sp", 64, ARM_MODE_ANY
, REG_TYPE_DATA_PTR
, "general", "org.gnu.gdb.aarch64.core" },
998 { ARMV8_PC
, "pc", 64, ARM_MODE_ANY
, REG_TYPE_CODE_PTR
, "general", "org.gnu.gdb.aarch64.core" },
1000 { ARMV8_xPSR
, "CPSR", 32, ARM_MODE_ANY
, REG_TYPE_UINT32
, "general", "org.gnu.gdb.aarch64.core" },
1002 { ARMV8_ELR_EL1
, "ELR_EL1", 64, ARMV8_64_EL1H
, REG_TYPE_CODE_PTR
, "banked", "net.sourceforge.openocd.banked" },
1003 { ARMV8_ESR_EL1
, "ESR_EL1", 32, ARMV8_64_EL1H
, REG_TYPE_UINT32
, "banked", "net.sourceforge.openocd.banked" },
1004 { ARMV8_SPSR_EL1
, "SPSR_EL1", 32, ARMV8_64_EL1H
, REG_TYPE_UINT32
, "banked", "net.sourceforge.openocd.banked" },
1006 { ARMV8_ELR_EL2
, "ELR_EL2", 64, ARMV8_64_EL2H
, REG_TYPE_CODE_PTR
, "banked", "net.sourceforge.openocd.banked" },
1007 { ARMV8_ESR_EL2
, "ESR_EL2", 32, ARMV8_64_EL2H
, REG_TYPE_UINT32
, "banked", "net.sourceforge.openocd.banked" },
1008 { ARMV8_SPSR_EL2
, "SPSR_EL2", 32, ARMV8_64_EL2H
, REG_TYPE_UINT32
, "banked", "net.sourceforge.openocd.banked" },
1010 { ARMV8_ELR_EL3
, "ELR_EL3", 64, ARMV8_64_EL3H
, REG_TYPE_CODE_PTR
, "banked", "net.sourceforge.openocd.banked" },
1011 { ARMV8_ESR_EL3
, "ESR_EL3", 32, ARMV8_64_EL3H
, REG_TYPE_UINT32
, "banked", "net.sourceforge.openocd.banked" },
1012 { ARMV8_SPSR_EL3
, "SPSR_EL3", 32, ARMV8_64_EL3H
, REG_TYPE_UINT32
, "banked", "net.sourceforge.openocd.banked" },
1015 #define ARMV8_NUM_REGS ARRAY_SIZE(armv8_regs)
1018 static int armv8_get_core_reg(struct reg
*reg
)
1021 struct arm_reg
*armv8_reg
= reg
->arch_info
;
1022 struct target
*target
= armv8_reg
->target
;
1023 struct arm
*arm
= target_to_arm(target
);
1025 if (target
->state
!= TARGET_HALTED
)
1026 return ERROR_TARGET_NOT_HALTED
;
1028 retval
= arm
->read_core_reg(target
, reg
, armv8_reg
->num
, arm
->core_mode
);
1033 static int armv8_set_core_reg(struct reg
*reg
, uint8_t *buf
)
1035 struct arm_reg
*armv8_reg
= reg
->arch_info
;
1036 struct target
*target
= armv8_reg
->target
;
1037 struct arm
*arm
= target_to_arm(target
);
1038 uint64_t value
= buf_get_u64(buf
, 0, 64);
1040 if (target
->state
!= TARGET_HALTED
)
1041 return ERROR_TARGET_NOT_HALTED
;
1043 if (reg
== arm
->cpsr
) {
1044 armv8_set_cpsr(arm
, (uint32_t)value
);
1046 buf_set_u64(reg
->value
, 0, 64, value
);
1055 static const struct reg_arch_type armv8_reg_type
= {
1056 .get
= armv8_get_core_reg
,
1057 .set
= armv8_set_core_reg
,
1060 /** Builds cache of architecturally defined registers. */
1061 struct reg_cache
*armv8_build_reg_cache(struct target
*target
)
1063 struct armv8_common
*armv8
= target_to_armv8(target
);
1064 struct arm
*arm
= &armv8
->arm
;
1065 int num_regs
= ARMV8_NUM_REGS
;
1066 struct reg_cache
**cache_p
= register_get_last_cache_p(&target
->reg_cache
);
1067 struct reg_cache
*cache
= malloc(sizeof(struct reg_cache
));
1068 struct reg
*reg_list
= calloc(num_regs
, sizeof(struct reg
));
1069 struct arm_reg
*arch_info
= calloc(num_regs
, sizeof(struct arm_reg
));
1070 struct reg_feature
*feature
;
1073 /* Build the process context cache */
1074 cache
->name
= "arm v8 registers";
1076 cache
->reg_list
= reg_list
;
1077 cache
->num_regs
= num_regs
;
1080 for (i
= 0; i
< num_regs
; i
++) {
1081 arch_info
[i
].num
= armv8_regs
[i
].id
;
1082 arch_info
[i
].mode
= armv8_regs
[i
].mode
;
1083 arch_info
[i
].target
= target
;
1084 arch_info
[i
].arm
= arm
;
1086 reg_list
[i
].name
= armv8_regs
[i
].name
;
1087 reg_list
[i
].size
= armv8_regs
[i
].bits
;
1088 reg_list
[i
].value
= calloc(1, 8);
1089 reg_list
[i
].dirty
= 0;
1090 reg_list
[i
].valid
= 0;
1091 reg_list
[i
].type
= &armv8_reg_type
;
1092 reg_list
[i
].arch_info
= &arch_info
[i
];
1094 reg_list
[i
].group
= armv8_regs
[i
].group
;
1095 reg_list
[i
].number
= i
;
1096 reg_list
[i
].exist
= true;
1097 reg_list
[i
].caller_save
= true; /* gdb defaults to true */
1099 feature
= calloc(1, sizeof(struct reg_feature
));
1101 feature
->name
= armv8_regs
[i
].feature
;
1102 reg_list
[i
].feature
= feature
;
1104 LOG_ERROR("unable to allocate feature list");
1106 reg_list
[i
].reg_data_type
= calloc(1, sizeof(struct reg_data_type
));
1107 if (reg_list
[i
].reg_data_type
)
1108 reg_list
[i
].reg_data_type
->type
= armv8_regs
[i
].type
;
1110 LOG_ERROR("unable to allocate reg type list");
1113 arm
->cpsr
= reg_list
+ ARMV8_xPSR
;
1114 arm
->pc
= reg_list
+ ARMV8_PC
;
1115 arm
->core_cache
= cache
;
1120 struct reg
*armv8_reg_current(struct arm
*arm
, unsigned regnum
)
1124 if (regnum
> (ARMV8_LAST_REG
- 1))
1127 r
= arm
->core_cache
->reg_list
+ regnum
;
1131 const struct command_registration armv8_command_handlers
[] = {
1133 .chain
= dap_command_handlers
,
1135 COMMAND_REGISTRATION_DONE
1139 int armv8_get_gdb_reg_list(struct target
*target
,
1140 struct reg
**reg_list
[], int *reg_list_size
,
1141 enum target_register_class reg_class
)
1143 struct arm
*arm
= target_to_arm(target
);
1146 switch (reg_class
) {
1147 case REG_CLASS_GENERAL
:
1148 *reg_list_size
= ARMV8_ELR_EL1
;
1149 *reg_list
= malloc(sizeof(struct reg
*) * (*reg_list_size
));
1151 for (i
= 0; i
< *reg_list_size
; i
++)
1152 (*reg_list
)[i
] = armv8_reg_current(arm
, i
);
1156 *reg_list_size
= ARMV8_LAST_REG
;
1157 *reg_list
= malloc(sizeof(struct reg
*) * (*reg_list_size
));
1159 for (i
= 0; i
< *reg_list_size
; i
++)
1160 (*reg_list
)[i
] = armv8_reg_current(arm
, i
);
1165 LOG_ERROR("not a valid register class type in query.");
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)