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 static const char * const armv8_state_strings
[] = {
41 "AArch32", "Thumb", "Jazelle", "ThumbEE", "AArch64",
47 } armv8_mode_data
[] = {
102 /** Map PSR mode bits to the name of an ARM processor operating mode. */
103 const char *armv8_mode_name(unsigned psr_mode
)
105 for (unsigned i
= 0; i
< ARRAY_SIZE(armv8_mode_data
); i
++) {
106 if (armv8_mode_data
[i
].psr
== psr_mode
)
107 return armv8_mode_data
[i
].name
;
109 LOG_ERROR("unrecognized psr mode: %#02x", psr_mode
);
110 return "UNRECOGNIZED";
113 static int armv8_read_reg(struct armv8_common
*armv8
, int regnum
, uint64_t *regval
)
115 struct arm_dpm
*dpm
= &armv8
->dpm
;
122 retval
= dpm
->instr_read_data_dcc_64(dpm
,
123 ARMV8_MSR_GP(SYSTEM_DBG_DBGDTR_EL0
, regnum
), &value_64
);
126 retval
= dpm
->instr_read_data_r0_64(dpm
,
127 ARMV8_MOVFSP_64(0), &value_64
);
130 retval
= dpm
->instr_read_data_r0_64(dpm
,
131 ARMV8_MRS_DLR(0), &value_64
);
134 retval
= dpm
->instr_read_data_r0(dpm
,
135 ARMV8_MRS_DSPSR(0), &value
);
139 retval
= dpm
->instr_read_data_r0(dpm
,
140 ARMV8_MRS_FPSR(0), &value
);
144 retval
= dpm
->instr_read_data_r0(dpm
,
145 ARMV8_MRS_FPCR(0), &value
);
149 retval
= dpm
->instr_read_data_r0_64(dpm
,
150 ARMV8_MRS(SYSTEM_ELR_EL1
, 0), &value_64
);
153 retval
= dpm
->instr_read_data_r0_64(dpm
,
154 ARMV8_MRS(SYSTEM_ELR_EL2
, 0), &value_64
);
157 retval
= dpm
->instr_read_data_r0_64(dpm
,
158 ARMV8_MRS(SYSTEM_ELR_EL3
, 0), &value_64
);
161 retval
= dpm
->instr_read_data_r0(dpm
,
162 ARMV8_MRS(SYSTEM_ESR_EL1
, 0), &value
);
166 retval
= dpm
->instr_read_data_r0(dpm
,
167 ARMV8_MRS(SYSTEM_ESR_EL2
, 0), &value
);
171 retval
= dpm
->instr_read_data_r0(dpm
,
172 ARMV8_MRS(SYSTEM_ESR_EL3
, 0), &value
);
176 retval
= dpm
->instr_read_data_r0(dpm
,
177 ARMV8_MRS(SYSTEM_SPSR_EL1
, 0), &value
);
181 retval
= dpm
->instr_read_data_r0(dpm
,
182 ARMV8_MRS(SYSTEM_SPSR_EL2
, 0), &value
);
186 retval
= dpm
->instr_read_data_r0(dpm
,
187 ARMV8_MRS(SYSTEM_SPSR_EL3
, 0), &value
);
195 if (retval
== ERROR_OK
&& regval
!= NULL
)
203 static int armv8_read_reg_simdfp_aarch64(struct armv8_common
*armv8
, int regnum
, uint64_t *lvalue
, uint64_t *hvalue
)
205 int retval
= ERROR_FAIL
;
206 struct arm_dpm
*dpm
= &armv8
->dpm
;
209 case ARMV8_V0
... ARMV8_V31
:
210 retval
= dpm
->instr_read_data_r0_64(dpm
,
211 ARMV8_MOV_GPR_VFP(0, (regnum
- ARMV8_V0
), 1), hvalue
);
212 if (retval
!= ERROR_OK
)
214 retval
= dpm
->instr_read_data_r0_64(dpm
,
215 ARMV8_MOV_GPR_VFP(0, (regnum
- ARMV8_V0
), 0), lvalue
);
226 static int armv8_write_reg(struct armv8_common
*armv8
, int regnum
, uint64_t value_64
)
228 struct arm_dpm
*dpm
= &armv8
->dpm
;
234 retval
= dpm
->instr_write_data_dcc_64(dpm
,
235 ARMV8_MRS(SYSTEM_DBG_DBGDTR_EL0
, regnum
),
239 retval
= dpm
->instr_write_data_r0_64(dpm
,
244 retval
= dpm
->instr_write_data_r0_64(dpm
,
250 retval
= dpm
->instr_write_data_r0(dpm
,
256 retval
= dpm
->instr_write_data_r0(dpm
,
262 retval
= dpm
->instr_write_data_r0(dpm
,
266 /* registers clobbered by taking exception in debug state */
268 retval
= dpm
->instr_write_data_r0_64(dpm
,
269 ARMV8_MSR_GP(SYSTEM_ELR_EL1
, 0), value_64
);
272 retval
= dpm
->instr_write_data_r0_64(dpm
,
273 ARMV8_MSR_GP(SYSTEM_ELR_EL2
, 0), value_64
);
276 retval
= dpm
->instr_write_data_r0_64(dpm
,
277 ARMV8_MSR_GP(SYSTEM_ELR_EL3
, 0), value_64
);
281 retval
= dpm
->instr_write_data_r0(dpm
,
282 ARMV8_MSR_GP(SYSTEM_ESR_EL1
, 0), value
);
286 retval
= dpm
->instr_write_data_r0(dpm
,
287 ARMV8_MSR_GP(SYSTEM_ESR_EL2
, 0), value
);
291 retval
= dpm
->instr_write_data_r0(dpm
,
292 ARMV8_MSR_GP(SYSTEM_ESR_EL3
, 0), value
);
296 retval
= dpm
->instr_write_data_r0(dpm
,
297 ARMV8_MSR_GP(SYSTEM_SPSR_EL1
, 0), value
);
301 retval
= dpm
->instr_write_data_r0(dpm
,
302 ARMV8_MSR_GP(SYSTEM_SPSR_EL2
, 0), value
);
306 retval
= dpm
->instr_write_data_r0(dpm
,
307 ARMV8_MSR_GP(SYSTEM_SPSR_EL3
, 0), value
);
317 static int armv8_write_reg_simdfp_aarch64(struct armv8_common
*armv8
, int regnum
, uint64_t lvalue
, uint64_t hvalue
)
319 int retval
= ERROR_FAIL
;
320 struct arm_dpm
*dpm
= &armv8
->dpm
;
323 case ARMV8_V0
... ARMV8_V31
:
324 retval
= dpm
->instr_write_data_r0_64(dpm
,
325 ARMV8_MOV_VFP_GPR((regnum
- ARMV8_V0
), 0, 1), hvalue
);
326 if (retval
!= ERROR_OK
)
328 retval
= dpm
->instr_write_data_r0_64(dpm
,
329 ARMV8_MOV_VFP_GPR((regnum
- ARMV8_V0
), 0, 0), lvalue
);
340 static int armv8_read_reg32(struct armv8_common
*armv8
, int regnum
, uint64_t *regval
)
342 struct arm_dpm
*dpm
= &armv8
->dpm
;
347 case ARMV8_R0
... ARMV8_R14
:
348 /* return via DCC: "MCR p14, 0, Rnum, c0, c5, 0" */
349 retval
= dpm
->instr_read_data_dcc(dpm
,
350 ARMV4_5_MCR(14, 0, regnum
, 0, 5, 0),
354 retval
= dpm
->instr_read_data_dcc(dpm
,
355 ARMV4_5_MCR(14, 0, 13, 0, 5, 0),
359 retval
= dpm
->instr_read_data_r0(dpm
,
364 retval
= dpm
->instr_read_data_r0(dpm
,
368 case ARMV8_ELR_EL1
: /* mapped to LR_svc */
369 retval
= dpm
->instr_read_data_dcc(dpm
,
370 ARMV4_5_MCR(14, 0, 14, 0, 5, 0),
373 case ARMV8_ELR_EL2
: /* mapped to ELR_hyp */
374 retval
= dpm
->instr_read_data_r0(dpm
,
375 ARMV8_MRS_T1(0, 14, 0, 1),
378 case ARMV8_ELR_EL3
: /* mapped to LR_mon */
379 retval
= dpm
->instr_read_data_dcc(dpm
,
380 ARMV4_5_MCR(14, 0, 14, 0, 5, 0),
383 case ARMV8_ESR_EL1
: /* mapped to DFSR */
384 retval
= dpm
->instr_read_data_r0(dpm
,
385 ARMV4_5_MRC(15, 0, 0, 5, 0, 0),
388 case ARMV8_ESR_EL2
: /* mapped to HSR */
389 retval
= dpm
->instr_read_data_r0(dpm
,
390 ARMV4_5_MRC(15, 4, 0, 5, 2, 0),
393 case ARMV8_ESR_EL3
: /* FIXME: no equivalent in aarch32? */
396 case ARMV8_SPSR_EL1
: /* mapped to SPSR_svc */
397 retval
= dpm
->instr_read_data_r0(dpm
,
398 ARMV8_MRS_xPSR_T1(1, 0),
401 case ARMV8_SPSR_EL2
: /* mapped to SPSR_hyp */
402 retval
= dpm
->instr_read_data_r0(dpm
,
403 ARMV8_MRS_xPSR_T1(1, 0),
406 case ARMV8_SPSR_EL3
: /* mapped to SPSR_mon */
407 retval
= dpm
->instr_read_data_r0(dpm
,
408 ARMV8_MRS_xPSR_T1(1, 0),
416 if (retval
== ERROR_OK
&& regval
!= NULL
)
422 static int armv8_write_reg32(struct armv8_common
*armv8
, int regnum
, uint64_t value
)
424 struct arm_dpm
*dpm
= &armv8
->dpm
;
428 case ARMV8_R0
... ARMV8_R14
:
429 /* load register from DCC: "MRC p14, 0, Rnum, c0, c5, 0" */
430 retval
= dpm
->instr_write_data_dcc(dpm
,
431 ARMV4_5_MRC(14, 0, regnum
, 0, 5, 0), value
);
434 retval
= dpm
->instr_write_data_dcc(dpm
,
435 ARMV4_5_MRC(14, 0, 13, 0, 5, 0), value
);
438 * read r0 from DCC; then "MOV pc, r0" */
439 retval
= dpm
->instr_write_data_r0(dpm
,
440 ARMV8_MCR_DLR(0), value
);
442 case ARMV8_xPSR
: /* CPSR */
443 /* read r0 from DCC, then "MCR r0, DSPSR" */
444 retval
= dpm
->instr_write_data_r0(dpm
,
445 ARMV8_MCR_DSPSR(0), value
);
447 case ARMV8_ELR_EL1
: /* mapped to LR_svc */
448 retval
= dpm
->instr_write_data_dcc(dpm
,
449 ARMV4_5_MRC(14, 0, 14, 0, 5, 0),
452 case ARMV8_ELR_EL2
: /* mapped to ELR_hyp */
453 retval
= dpm
->instr_write_data_r0(dpm
,
454 ARMV8_MSR_GP_T1(0, 14, 0, 1),
457 case ARMV8_ELR_EL3
: /* mapped to LR_mon */
458 retval
= dpm
->instr_write_data_dcc(dpm
,
459 ARMV4_5_MRC(14, 0, 14, 0, 5, 0),
462 case ARMV8_ESR_EL1
: /* mapped to DFSR */
463 retval
= dpm
->instr_write_data_r0(dpm
,
464 ARMV4_5_MCR(15, 0, 0, 5, 0, 0),
467 case ARMV8_ESR_EL2
: /* mapped to HSR */
468 retval
= dpm
->instr_write_data_r0(dpm
,
469 ARMV4_5_MCR(15, 4, 0, 5, 2, 0),
472 case ARMV8_ESR_EL3
: /* FIXME: no equivalent in aarch32? */
475 case ARMV8_SPSR_EL1
: /* mapped to SPSR_svc */
476 retval
= dpm
->instr_write_data_r0(dpm
,
477 ARMV8_MSR_GP_xPSR_T1(1, 0, 15),
480 case ARMV8_SPSR_EL2
: /* mapped to SPSR_hyp */
481 retval
= dpm
->instr_write_data_r0(dpm
,
482 ARMV8_MSR_GP_xPSR_T1(1, 0, 15),
485 case ARMV8_SPSR_EL3
: /* mapped to SPSR_mon */
486 retval
= dpm
->instr_write_data_r0(dpm
,
487 ARMV8_MSR_GP_xPSR_T1(1, 0, 15),
499 void armv8_select_reg_access(struct armv8_common
*armv8
, bool is_aarch64
)
502 armv8
->read_reg_u64
= armv8_read_reg
;
503 armv8
->write_reg_u64
= armv8_write_reg
;
504 armv8
->read_reg_u128
= armv8_read_reg_simdfp_aarch64
;
505 armv8
->write_reg_u128
= armv8_write_reg_simdfp_aarch64
;
508 armv8
->read_reg_u64
= armv8_read_reg32
;
509 armv8
->write_reg_u64
= armv8_write_reg32
;
513 /* retrieve core id cluster id */
514 int armv8_read_mpidr(struct armv8_common
*armv8
)
516 int retval
= ERROR_FAIL
;
517 struct arm_dpm
*dpm
= armv8
->arm
.dpm
;
520 retval
= dpm
->prepare(dpm
);
521 if (retval
!= ERROR_OK
)
524 retval
= dpm
->instr_read_data_r0(dpm
, armv8_opcode(armv8
, READ_REG_MPIDR
), &mpidr
);
525 if (retval
!= ERROR_OK
)
528 armv8
->multi_processor_system
= (mpidr
>> 30) & 1;
529 armv8
->cluster_id
= (mpidr
>> 8) & 0xf;
530 armv8
->cpu_id
= mpidr
& 0x3;
531 LOG_INFO("%s cluster %x core %x %s", target_name(armv8
->arm
.target
),
534 armv8
->multi_processor_system
== 0 ? "multi core" : "single core");
536 LOG_ERROR("mpidr not in multiprocessor format");
544 * Configures host-side ARM records to reflect the specified CPSR.
545 * Later, code can use arm_reg_current() to map register numbers
546 * according to how they are exposed by this mode.
548 void armv8_set_cpsr(struct arm
*arm
, uint32_t cpsr
)
550 uint32_t mode
= cpsr
& 0x1F;
552 /* NOTE: this may be called very early, before the register
553 * cache is set up. We can't defend against many errors, in
554 * particular against CPSRs that aren't valid *here* ...
557 buf_set_u32(arm
->cpsr
->value
, 0, 32, cpsr
);
558 arm
->cpsr
->valid
= 1;
559 arm
->cpsr
->dirty
= 0;
562 /* Older ARMs won't have the J bit */
563 enum arm_state state
= 0xFF;
565 if ((cpsr
& 0x10) != 0) {
567 if (cpsr
& (1 << 5)) { /* T */
568 if (cpsr
& (1 << 24)) { /* J */
569 LOG_WARNING("ThumbEE -- incomplete support");
570 state
= ARM_STATE_THUMB_EE
;
572 state
= ARM_STATE_THUMB
;
574 if (cpsr
& (1 << 24)) { /* J */
575 LOG_ERROR("Jazelle state handling is BROKEN!");
576 state
= ARM_STATE_JAZELLE
;
578 state
= ARM_STATE_ARM
;
582 state
= ARM_STATE_AARCH64
;
585 arm
->core_state
= state
;
586 arm
->core_mode
= mode
;
588 LOG_DEBUG("set CPSR %#8.8x: %s mode, %s state", (unsigned) cpsr
,
589 armv8_mode_name(arm
->core_mode
),
590 armv8_state_strings
[arm
->core_state
]);
593 static void armv8_show_fault_registers32(struct armv8_common
*armv8
)
595 uint32_t dfsr
, ifsr
, dfar
, ifar
;
596 struct arm_dpm
*dpm
= armv8
->arm
.dpm
;
599 retval
= dpm
->prepare(dpm
);
600 if (retval
!= ERROR_OK
)
603 /* ARMV4_5_MRC(cpnum, op1, r0, CRn, CRm, op2) */
605 /* c5/c0 - {data, instruction} fault status registers */
606 retval
= dpm
->instr_read_data_r0(dpm
,
607 ARMV4_5_MRC(15, 0, 0, 5, 0, 0),
609 if (retval
!= ERROR_OK
)
612 retval
= dpm
->instr_read_data_r0(dpm
,
613 ARMV4_5_MRC(15, 0, 0, 5, 0, 1),
615 if (retval
!= ERROR_OK
)
618 /* c6/c0 - {data, instruction} fault address registers */
619 retval
= dpm
->instr_read_data_r0(dpm
,
620 ARMV4_5_MRC(15, 0, 0, 6, 0, 0),
622 if (retval
!= ERROR_OK
)
625 retval
= dpm
->instr_read_data_r0(dpm
,
626 ARMV4_5_MRC(15, 0, 0, 6, 0, 2),
628 if (retval
!= ERROR_OK
)
631 LOG_USER("Data fault registers DFSR: %8.8" PRIx32
632 ", DFAR: %8.8" PRIx32
, dfsr
, dfar
);
633 LOG_USER("Instruction fault registers IFSR: %8.8" PRIx32
634 ", IFAR: %8.8" PRIx32
, ifsr
, ifar
);
637 /* (void) */ dpm
->finish(dpm
);
640 static __attribute__((unused
)) void armv8_show_fault_registers(struct target
*target
)
642 struct armv8_common
*armv8
= target_to_armv8(target
);
644 if (armv8
->arm
.core_state
!= ARM_STATE_AARCH64
)
645 armv8_show_fault_registers32(armv8
);
648 static uint8_t armv8_pa_size(uint32_t ps
)
671 LOG_INFO("Unknow physicall address size");
677 static __attribute__((unused
)) int armv8_read_ttbcr32(struct target
*target
)
679 struct armv8_common
*armv8
= target_to_armv8(target
);
680 struct arm_dpm
*dpm
= armv8
->arm
.dpm
;
681 uint32_t ttbcr
, ttbcr_n
;
682 int retval
= dpm
->prepare(dpm
);
683 if (retval
!= ERROR_OK
)
685 /* MRC p15,0,<Rt>,c2,c0,2 ; Read CP15 Translation Table Base Control Register*/
686 retval
= dpm
->instr_read_data_r0(dpm
,
687 ARMV4_5_MRC(15, 0, 0, 2, 0, 2),
689 if (retval
!= ERROR_OK
)
692 LOG_DEBUG("ttbcr %" PRIx32
, ttbcr
);
694 ttbcr_n
= ttbcr
& 0x7;
695 armv8
->armv8_mmu
.ttbcr
= ttbcr
;
698 * ARM Architecture Reference Manual (ARMv7-A and ARMv7-Redition),
699 * document # ARM DDI 0406C
701 armv8
->armv8_mmu
.ttbr_range
[0] = 0xffffffff >> ttbcr_n
;
702 armv8
->armv8_mmu
.ttbr_range
[1] = 0xffffffff;
703 armv8
->armv8_mmu
.ttbr_mask
[0] = 0xffffffff << (14 - ttbcr_n
);
704 armv8
->armv8_mmu
.ttbr_mask
[1] = 0xffffffff << 14;
706 LOG_DEBUG("ttbr1 %s, ttbr0_mask %" PRIx32
" ttbr1_mask %" PRIx32
,
707 (ttbcr_n
!= 0) ? "used" : "not used",
708 armv8
->armv8_mmu
.ttbr_mask
[0],
709 armv8
->armv8_mmu
.ttbr_mask
[1]);
716 static __attribute__((unused
)) int armv8_read_ttbcr(struct target
*target
)
718 struct armv8_common
*armv8
= target_to_armv8(target
);
719 struct arm_dpm
*dpm
= armv8
->arm
.dpm
;
720 struct arm
*arm
= &armv8
->arm
;
724 int retval
= dpm
->prepare(dpm
);
725 if (retval
!= ERROR_OK
)
728 /* claaer ttrr1_used and ttbr0_mask */
729 memset(&armv8
->armv8_mmu
.ttbr1_used
, 0, sizeof(armv8
->armv8_mmu
.ttbr1_used
));
730 memset(&armv8
->armv8_mmu
.ttbr0_mask
, 0, sizeof(armv8
->armv8_mmu
.ttbr0_mask
));
732 switch (armv8_curel_from_core_mode(arm
->core_mode
)) {
733 case SYSTEM_CUREL_EL3
:
734 retval
= dpm
->instr_read_data_r0(dpm
,
735 ARMV8_MRS(SYSTEM_TCR_EL3
, 0),
737 retval
+= dpm
->instr_read_data_r0_64(dpm
,
738 ARMV8_MRS(SYSTEM_TTBR0_EL3
, 0),
740 if (retval
!= ERROR_OK
)
742 armv8
->va_size
= 64 - (ttbcr
& 0x3F);
743 armv8
->pa_size
= armv8_pa_size((ttbcr
>> 16) & 7);
744 armv8
->page_size
= (ttbcr
>> 14) & 3;
746 case SYSTEM_CUREL_EL2
:
747 retval
= dpm
->instr_read_data_r0(dpm
,
748 ARMV8_MRS(SYSTEM_TCR_EL2
, 0),
750 retval
+= dpm
->instr_read_data_r0_64(dpm
,
751 ARMV8_MRS(SYSTEM_TTBR0_EL2
, 0),
753 if (retval
!= ERROR_OK
)
755 armv8
->va_size
= 64 - (ttbcr
& 0x3F);
756 armv8
->pa_size
= armv8_pa_size((ttbcr
>> 16) & 7);
757 armv8
->page_size
= (ttbcr
>> 14) & 3;
759 case SYSTEM_CUREL_EL0
:
760 armv8_dpm_modeswitch(dpm
, ARMV8_64_EL1H
);
762 case SYSTEM_CUREL_EL1
:
763 retval
= dpm
->instr_read_data_r0_64(dpm
,
764 ARMV8_MRS(SYSTEM_TCR_EL1
, 0),
766 armv8
->va_size
= 64 - (ttbcr_64
& 0x3F);
767 armv8
->pa_size
= armv8_pa_size((ttbcr_64
>> 32) & 7);
768 armv8
->page_size
= (ttbcr_64
>> 14) & 3;
769 armv8
->armv8_mmu
.ttbr1_used
= (((ttbcr_64
>> 16) & 0x3F) != 0) ? 1 : 0;
770 armv8
->armv8_mmu
.ttbr0_mask
= 0x0000FFFFFFFFFFFF;
771 retval
+= dpm
->instr_read_data_r0_64(dpm
,
772 ARMV8_MRS(SYSTEM_TTBR0_EL1
| (armv8
->armv8_mmu
.ttbr1_used
), 0),
774 if (retval
!= ERROR_OK
)
778 LOG_ERROR("unknow core state");
782 if (retval
!= ERROR_OK
)
785 if (armv8
->armv8_mmu
.ttbr1_used
== 1)
786 LOG_INFO("TTBR0 access above %" PRIx64
, (uint64_t)(armv8
->armv8_mmu
.ttbr0_mask
));
789 armv8_dpm_modeswitch(dpm
, ARM_MODE_ANY
);
794 /* method adapted to cortex A : reused arm v4 v5 method*/
795 int armv8_mmu_translate_va(struct target
*target
, target_addr_t va
, target_addr_t
*val
)
800 /* V8 method VA TO PA */
801 int armv8_mmu_translate_va_pa(struct target
*target
, target_addr_t va
,
802 target_addr_t
*val
, int meminfo
)
804 struct armv8_common
*armv8
= target_to_armv8(target
);
805 struct arm
*arm
= target_to_arm(target
);
806 struct arm_dpm
*dpm
= &armv8
->dpm
;
807 enum arm_mode target_mode
= ARM_MODE_ANY
;
812 static const char * const shared_name
[] = {
813 "Non-", "UNDEFINED ", "Outer ", "Inner "
816 static const char * const secure_name
[] = {
817 "Secure", "Not Secure"
820 retval
= dpm
->prepare(dpm
);
821 if (retval
!= ERROR_OK
)
824 switch (armv8_curel_from_core_mode(arm
->core_mode
)) {
825 case SYSTEM_CUREL_EL0
:
826 instr
= ARMV8_SYS(SYSTEM_ATS12E0R
, 0);
827 /* can only execute instruction at EL2 */
828 target_mode
= ARMV8_64_EL2H
;
830 case SYSTEM_CUREL_EL1
:
831 instr
= ARMV8_SYS(SYSTEM_ATS12E1R
, 0);
832 /* can only execute instruction at EL2 */
833 target_mode
= ARMV8_64_EL2H
;
835 case SYSTEM_CUREL_EL2
:
836 instr
= ARMV8_SYS(SYSTEM_ATS1E2R
, 0);
838 case SYSTEM_CUREL_EL3
:
839 instr
= ARMV8_SYS(SYSTEM_ATS1E3R
, 0);
846 if (target_mode
!= ARM_MODE_ANY
)
847 armv8_dpm_modeswitch(dpm
, target_mode
);
849 /* write VA to R0 and execute translation instruction */
850 retval
= dpm
->instr_write_data_r0_64(dpm
, instr
, (uint64_t)va
);
851 /* read result from PAR_EL1 */
852 if (retval
== ERROR_OK
)
853 retval
= dpm
->instr_read_data_r0_64(dpm
, ARMV8_MRS(SYSTEM_PAR_EL1
, 0), &par
);
855 /* switch back to saved PE mode */
856 if (target_mode
!= ARM_MODE_ANY
)
857 armv8_dpm_modeswitch(dpm
, ARM_MODE_ANY
);
861 if (retval
!= ERROR_OK
)
865 LOG_ERROR("Address translation failed at stage %i, FST=%x, PTW=%i",
866 ((int)(par
>> 9) & 1)+1, (int)(par
>> 1) & 0x3f, (int)(par
>> 8) & 1);
871 *val
= (par
& 0xFFFFFFFFF000UL
) | (va
& 0xFFF);
873 int SH
= (par
>> 7) & 3;
874 int NS
= (par
>> 9) & 1;
875 int ATTR
= (par
>> 56) & 0xFF;
877 char *memtype
= (ATTR
& 0xF0) == 0 ? "Device Memory" : "Normal Memory";
879 LOG_USER("%sshareable, %s",
880 shared_name
[SH
], secure_name
[NS
]);
881 LOG_USER("%s", memtype
);
888 int armv8_handle_cache_info_command(struct command_context
*cmd_ctx
,
889 struct armv8_cache_common
*armv8_cache
)
891 if (armv8_cache
->info
== -1) {
892 command_print(cmd_ctx
, "cache not yet identified");
896 if (armv8_cache
->display_cache_info
)
897 armv8_cache
->display_cache_info(cmd_ctx
, armv8_cache
);
901 int armv8_init_arch_info(struct target
*target
, struct armv8_common
*armv8
)
903 struct arm
*arm
= &armv8
->arm
;
904 arm
->arch_info
= armv8
;
905 target
->arch_info
= &armv8
->arm
;
906 /* target is useful in all function arm v4 5 compatible */
907 armv8
->arm
.target
= target
;
908 armv8
->arm
.common_magic
= ARM_COMMON_MAGIC
;
909 armv8
->common_magic
= ARMV8_COMMON_MAGIC
;
911 armv8
->armv8_mmu
.armv8_cache
.l2_cache
= NULL
;
912 armv8
->armv8_mmu
.armv8_cache
.info
= -1;
913 armv8
->armv8_mmu
.armv8_cache
.flush_all_data_cache
= NULL
;
914 armv8
->armv8_mmu
.armv8_cache
.display_cache_info
= NULL
;
918 int armv8_aarch64_state(struct target
*target
)
920 struct arm
*arm
= target_to_arm(target
);
922 if (arm
->common_magic
!= ARM_COMMON_MAGIC
) {
923 LOG_ERROR("BUG: called for a non-ARM target");
927 LOG_USER("target halted in %s state due to %s, current mode: %s\n"
928 "cpsr: 0x%8.8" PRIx32
" pc: 0x%" PRIx64
"%s",
929 armv8_state_strings
[arm
->core_state
],
930 debug_reason_name(target
),
931 armv8_mode_name(arm
->core_mode
),
932 buf_get_u32(arm
->cpsr
->value
, 0, 32),
933 buf_get_u64(arm
->pc
->value
, 0, 64),
934 arm
->is_semihosting
? ", semihosting" : "");
939 int armv8_arch_state(struct target
*target
)
941 static const char * const state
[] = {
942 "disabled", "enabled"
945 struct armv8_common
*armv8
= target_to_armv8(target
);
946 struct arm
*arm
= &armv8
->arm
;
948 if (armv8
->common_magic
!= ARMV8_COMMON_MAGIC
) {
949 LOG_ERROR("BUG: called for a non-Armv8 target");
950 return ERROR_COMMAND_SYNTAX_ERROR
;
953 if (arm
->core_state
== ARM_STATE_AARCH64
)
954 armv8_aarch64_state(target
);
956 arm_arch_state(target
);
958 LOG_USER("MMU: %s, D-Cache: %s, I-Cache: %s",
959 state
[armv8
->armv8_mmu
.mmu_enabled
],
960 state
[armv8
->armv8_mmu
.armv8_cache
.d_u_cache_enabled
],
961 state
[armv8
->armv8_mmu
.armv8_cache
.i_cache_enabled
]);
963 if (arm
->core_mode
== ARM_MODE_ABT
)
964 armv8_show_fault_registers(target
);
966 if (target
->debug_reason
== DBG_REASON_WATCHPOINT
)
967 LOG_USER("Watchpoint triggered at PC %#08x",
968 (unsigned) armv8
->dpm
.wp_pc
);
973 static struct reg_data_type aarch64_vector_base_types
[] = {
974 {REG_TYPE_IEEE_DOUBLE
, "ieee_double", 0, {NULL
} },
975 {REG_TYPE_UINT64
, "uint64", 0, {NULL
} },
976 {REG_TYPE_INT64
, "int64", 0, {NULL
} },
977 {REG_TYPE_IEEE_SINGLE
, "ieee_single", 0, {NULL
} },
978 {REG_TYPE_UINT32
, "uint32", 0, {NULL
} },
979 {REG_TYPE_INT32
, "int32", 0, {NULL
} },
980 {REG_TYPE_UINT16
, "uint16", 0, {NULL
} },
981 {REG_TYPE_INT16
, "int16", 0, {NULL
} },
982 {REG_TYPE_UINT8
, "uint8", 0, {NULL
} },
983 {REG_TYPE_INT8
, "int8", 0, {NULL
} },
984 {REG_TYPE_UINT128
, "uint128", 0, {NULL
} },
985 {REG_TYPE_INT128
, "int128", 0, {NULL
} }
988 static struct reg_data_type_vector aarch64_vector_types
[] = {
989 {aarch64_vector_base_types
+ 0, 2},
990 {aarch64_vector_base_types
+ 1, 2},
991 {aarch64_vector_base_types
+ 2, 2},
992 {aarch64_vector_base_types
+ 3, 4},
993 {aarch64_vector_base_types
+ 4, 4},
994 {aarch64_vector_base_types
+ 5, 4},
995 {aarch64_vector_base_types
+ 6, 8},
996 {aarch64_vector_base_types
+ 7, 8},
997 {aarch64_vector_base_types
+ 8, 16},
998 {aarch64_vector_base_types
+ 9, 16},
999 {aarch64_vector_base_types
+ 10, 01},
1000 {aarch64_vector_base_types
+ 11, 01},
1003 static struct reg_data_type aarch64_fpu_vector
[] = {
1004 {REG_TYPE_ARCH_DEFINED
, "v2d", REG_TYPE_CLASS_VECTOR
, {aarch64_vector_types
+ 0} },
1005 {REG_TYPE_ARCH_DEFINED
, "v2u", REG_TYPE_CLASS_VECTOR
, {aarch64_vector_types
+ 1} },
1006 {REG_TYPE_ARCH_DEFINED
, "v2i", REG_TYPE_CLASS_VECTOR
, {aarch64_vector_types
+ 2} },
1007 {REG_TYPE_ARCH_DEFINED
, "v4f", REG_TYPE_CLASS_VECTOR
, {aarch64_vector_types
+ 3} },
1008 {REG_TYPE_ARCH_DEFINED
, "v4u", REG_TYPE_CLASS_VECTOR
, {aarch64_vector_types
+ 4} },
1009 {REG_TYPE_ARCH_DEFINED
, "v4i", REG_TYPE_CLASS_VECTOR
, {aarch64_vector_types
+ 5} },
1010 {REG_TYPE_ARCH_DEFINED
, "v8u", REG_TYPE_CLASS_VECTOR
, {aarch64_vector_types
+ 6} },
1011 {REG_TYPE_ARCH_DEFINED
, "v8i", REG_TYPE_CLASS_VECTOR
, {aarch64_vector_types
+ 7} },
1012 {REG_TYPE_ARCH_DEFINED
, "v16u", REG_TYPE_CLASS_VECTOR
, {aarch64_vector_types
+ 8} },
1013 {REG_TYPE_ARCH_DEFINED
, "v16i", REG_TYPE_CLASS_VECTOR
, {aarch64_vector_types
+ 9} },
1014 {REG_TYPE_ARCH_DEFINED
, "v1u", REG_TYPE_CLASS_VECTOR
, {aarch64_vector_types
+ 10} },
1015 {REG_TYPE_ARCH_DEFINED
, "v1i", REG_TYPE_CLASS_VECTOR
, {aarch64_vector_types
+ 11} },
1018 static struct reg_data_type_union_field aarch64_union_fields_vnd
[] = {
1019 {"f", aarch64_fpu_vector
+ 0, aarch64_union_fields_vnd
+ 1},
1020 {"u", aarch64_fpu_vector
+ 1, aarch64_union_fields_vnd
+ 2},
1021 {"s", aarch64_fpu_vector
+ 2, NULL
},
1024 static struct reg_data_type_union_field aarch64_union_fields_vns
[] = {
1025 {"f", aarch64_fpu_vector
+ 3, aarch64_union_fields_vns
+ 1},
1026 {"u", aarch64_fpu_vector
+ 4, aarch64_union_fields_vns
+ 2},
1027 {"s", aarch64_fpu_vector
+ 5, NULL
},
1030 static struct reg_data_type_union_field aarch64_union_fields_vnh
[] = {
1031 {"u", aarch64_fpu_vector
+ 6, aarch64_union_fields_vnh
+ 1},
1032 {"s", aarch64_fpu_vector
+ 7, NULL
},
1035 static struct reg_data_type_union_field aarch64_union_fields_vnb
[] = {
1036 {"u", aarch64_fpu_vector
+ 8, aarch64_union_fields_vnb
+ 1},
1037 {"s", aarch64_fpu_vector
+ 9, NULL
},
1040 static struct reg_data_type_union_field aarch64_union_fields_vnq
[] = {
1041 {"u", aarch64_fpu_vector
+ 10, aarch64_union_fields_vnq
+ 1},
1042 {"s", aarch64_fpu_vector
+ 11, NULL
},
1045 static struct reg_data_type_union aarch64_union_types
[] = {
1046 {aarch64_union_fields_vnd
},
1047 {aarch64_union_fields_vns
},
1048 {aarch64_union_fields_vnh
},
1049 {aarch64_union_fields_vnb
},
1050 {aarch64_union_fields_vnq
},
1053 static struct reg_data_type aarch64_fpu_union
[] = {
1054 {REG_TYPE_ARCH_DEFINED
, "vnd", REG_TYPE_CLASS_UNION
, {.reg_type_union
= aarch64_union_types
+ 0} },
1055 {REG_TYPE_ARCH_DEFINED
, "vns", REG_TYPE_CLASS_UNION
, {.reg_type_union
= aarch64_union_types
+ 1} },
1056 {REG_TYPE_ARCH_DEFINED
, "vnh", REG_TYPE_CLASS_UNION
, {.reg_type_union
= aarch64_union_types
+ 2} },
1057 {REG_TYPE_ARCH_DEFINED
, "vnb", REG_TYPE_CLASS_UNION
, {.reg_type_union
= aarch64_union_types
+ 3} },
1058 {REG_TYPE_ARCH_DEFINED
, "vnq", REG_TYPE_CLASS_UNION
, {.reg_type_union
= aarch64_union_types
+ 4} },
1061 static struct reg_data_type_union_field aarch64v_union_fields
[] = {
1062 {"d", aarch64_fpu_union
+ 0, aarch64v_union_fields
+ 1},
1063 {"s", aarch64_fpu_union
+ 1, aarch64v_union_fields
+ 2},
1064 {"h", aarch64_fpu_union
+ 2, aarch64v_union_fields
+ 3},
1065 {"b", aarch64_fpu_union
+ 3, aarch64v_union_fields
+ 4},
1066 {"q", aarch64_fpu_union
+ 4, NULL
},
1069 static struct reg_data_type_union aarch64v_union
[] = {
1070 {aarch64v_union_fields
}
1073 static struct reg_data_type aarch64v
[] = {
1074 {REG_TYPE_ARCH_DEFINED
, "aarch64v", REG_TYPE_CLASS_UNION
, {.reg_type_union
= aarch64v_union
} },
1077 static const struct {
1084 const char *feature
;
1085 struct reg_data_type
*data_type
;
1087 { ARMV8_R0
, "x0", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1088 { ARMV8_R1
, "x1", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1089 { ARMV8_R2
, "x2", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1090 { ARMV8_R3
, "x3", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1091 { ARMV8_R4
, "x4", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1092 { ARMV8_R5
, "x5", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1093 { ARMV8_R6
, "x6", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1094 { ARMV8_R7
, "x7", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1095 { ARMV8_R8
, "x8", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1096 { ARMV8_R9
, "x9", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1097 { ARMV8_R10
, "x10", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1098 { ARMV8_R11
, "x11", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1099 { ARMV8_R12
, "x12", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1100 { ARMV8_R13
, "x13", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1101 { ARMV8_R14
, "x14", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1102 { ARMV8_R15
, "x15", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1103 { ARMV8_R16
, "x16", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1104 { ARMV8_R17
, "x17", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1105 { ARMV8_R18
, "x18", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1106 { ARMV8_R19
, "x19", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1107 { ARMV8_R20
, "x20", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1108 { ARMV8_R21
, "x21", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1109 { ARMV8_R22
, "x22", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1110 { ARMV8_R23
, "x23", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1111 { ARMV8_R24
, "x24", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1112 { ARMV8_R25
, "x25", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1113 { ARMV8_R26
, "x26", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1114 { ARMV8_R27
, "x27", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1115 { ARMV8_R28
, "x28", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1116 { ARMV8_R29
, "x29", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1117 { ARMV8_R30
, "x30", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1119 { ARMV8_SP
, "sp", 64, ARM_MODE_ANY
, REG_TYPE_DATA_PTR
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1120 { ARMV8_PC
, "pc", 64, ARM_MODE_ANY
, REG_TYPE_CODE_PTR
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1122 { ARMV8_xPSR
, "CPSR", 32, ARM_MODE_ANY
, REG_TYPE_UINT32
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1124 { ARMV8_V0
, "v0", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1125 { ARMV8_V1
, "v1", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1126 { ARMV8_V2
, "v2", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1127 { ARMV8_V3
, "v3", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1128 { ARMV8_V4
, "v4", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1129 { ARMV8_V5
, "v5", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1130 { ARMV8_V6
, "v6", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1131 { ARMV8_V7
, "v7", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1132 { ARMV8_V8
, "v8", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1133 { ARMV8_V9
, "v9", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1134 { ARMV8_V10
, "v10", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1135 { ARMV8_V11
, "v11", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1136 { ARMV8_V12
, "v12", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1137 { ARMV8_V13
, "v13", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1138 { ARMV8_V14
, "v14", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1139 { ARMV8_V15
, "v15", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1140 { ARMV8_V16
, "v16", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1141 { ARMV8_V17
, "v17", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1142 { ARMV8_V18
, "v18", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1143 { ARMV8_V19
, "v19", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1144 { ARMV8_V20
, "v20", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1145 { ARMV8_V21
, "v21", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1146 { ARMV8_V22
, "v22", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1147 { ARMV8_V23
, "v23", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1148 { ARMV8_V24
, "v24", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1149 { ARMV8_V25
, "v25", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1150 { ARMV8_V26
, "v26", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1151 { ARMV8_V27
, "v27", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1152 { ARMV8_V28
, "v28", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1153 { ARMV8_V29
, "v29", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1154 { ARMV8_V30
, "v30", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1155 { ARMV8_V31
, "v31", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1156 { ARMV8_FPSR
, "fpsr", 32, ARM_MODE_ANY
, REG_TYPE_UINT32
, "simdfp", "org.gnu.gdb.aarch64.fpu", NULL
},
1157 { ARMV8_FPCR
, "fpcr", 32, ARM_MODE_ANY
, REG_TYPE_UINT32
, "simdfp", "org.gnu.gdb.aarch64.fpu", NULL
},
1159 { ARMV8_ELR_EL1
, "ELR_EL1", 64, ARMV8_64_EL1H
, REG_TYPE_CODE_PTR
, "banked", "net.sourceforge.openocd.banked",
1161 { ARMV8_ESR_EL1
, "ESR_EL1", 32, ARMV8_64_EL1H
, REG_TYPE_UINT32
, "banked", "net.sourceforge.openocd.banked",
1163 { ARMV8_SPSR_EL1
, "SPSR_EL1", 32, ARMV8_64_EL1H
, REG_TYPE_UINT32
, "banked", "net.sourceforge.openocd.banked",
1166 { ARMV8_ELR_EL2
, "ELR_EL2", 64, ARMV8_64_EL2H
, REG_TYPE_CODE_PTR
, "banked", "net.sourceforge.openocd.banked",
1168 { ARMV8_ESR_EL2
, "ESR_EL2", 32, ARMV8_64_EL2H
, REG_TYPE_UINT32
, "banked", "net.sourceforge.openocd.banked",
1170 { ARMV8_SPSR_EL2
, "SPSR_EL2", 32, ARMV8_64_EL2H
, REG_TYPE_UINT32
, "banked", "net.sourceforge.openocd.banked",
1173 { ARMV8_ELR_EL3
, "ELR_EL3", 64, ARMV8_64_EL3H
, REG_TYPE_CODE_PTR
, "banked", "net.sourceforge.openocd.banked",
1175 { ARMV8_ESR_EL3
, "ESR_EL3", 32, ARMV8_64_EL3H
, REG_TYPE_UINT32
, "banked", "net.sourceforge.openocd.banked",
1177 { ARMV8_SPSR_EL3
, "SPSR_EL3", 32, ARMV8_64_EL3H
, REG_TYPE_UINT32
, "banked", "net.sourceforge.openocd.banked",
1181 static const struct {
1188 const char *feature
;
1189 } armv8_regs32
[] = {
1190 { ARMV8_R0
, "r0", 32, ARM_MODE_ANY
, REG_TYPE_UINT32
, "general", "org.gnu.gdb.arm.core" },
1191 { ARMV8_R1
, "r1", 32, ARM_MODE_ANY
, REG_TYPE_UINT32
, "general", "org.gnu.gdb.arm.core" },
1192 { ARMV8_R2
, "r2", 32, ARM_MODE_ANY
, REG_TYPE_UINT32
, "general", "org.gnu.gdb.arm.core" },
1193 { ARMV8_R3
, "r3", 32, ARM_MODE_ANY
, REG_TYPE_UINT32
, "general", "org.gnu.gdb.arm.core" },
1194 { ARMV8_R4
, "r4", 32, ARM_MODE_ANY
, REG_TYPE_UINT32
, "general", "org.gnu.gdb.arm.core" },
1195 { ARMV8_R5
, "r5", 32, ARM_MODE_ANY
, REG_TYPE_UINT32
, "general", "org.gnu.gdb.arm.core" },
1196 { ARMV8_R6
, "r6", 32, ARM_MODE_ANY
, REG_TYPE_UINT32
, "general", "org.gnu.gdb.arm.core" },
1197 { ARMV8_R7
, "r7", 32, ARM_MODE_ANY
, REG_TYPE_UINT32
, "general", "org.gnu.gdb.arm.core" },
1198 { ARMV8_R8
, "r8", 32, ARM_MODE_ANY
, REG_TYPE_UINT32
, "general", "org.gnu.gdb.arm.core" },
1199 { ARMV8_R9
, "r9", 32, ARM_MODE_ANY
, REG_TYPE_UINT32
, "general", "org.gnu.gdb.arm.core" },
1200 { ARMV8_R10
, "r10", 32, ARM_MODE_ANY
, REG_TYPE_UINT32
, "general", "org.gnu.gdb.arm.core" },
1201 { ARMV8_R11
, "r11", 32, ARM_MODE_ANY
, REG_TYPE_UINT32
, "general", "org.gnu.gdb.arm.core" },
1202 { ARMV8_R12
, "r12", 32, ARM_MODE_ANY
, REG_TYPE_UINT32
, "general", "org.gnu.gdb.arm.core" },
1203 { ARMV8_R13
, "sp", 32, ARM_MODE_ANY
, REG_TYPE_DATA_PTR
, "general", "org.gnu.gdb.arm.core" },
1204 { ARMV8_R14
, "lr", 32, ARM_MODE_ANY
, REG_TYPE_CODE_PTR
, "general", "org.gnu.gdb.arm.core" },
1205 { ARMV8_PC
, "pc", 32, ARM_MODE_ANY
, REG_TYPE_CODE_PTR
, "general", "org.gnu.gdb.arm.core" },
1206 { ARMV8_xPSR
, "cpsr", 32, ARM_MODE_ANY
, REG_TYPE_UINT32
, "general", "org.gnu.gdb.arm.core" },
1209 #define ARMV8_NUM_REGS ARRAY_SIZE(armv8_regs)
1210 #define ARMV8_NUM_REGS32 ARRAY_SIZE(armv8_regs32)
1212 static int armv8_get_core_reg(struct reg
*reg
)
1214 struct arm_reg
*armv8_reg
= reg
->arch_info
;
1215 struct target
*target
= armv8_reg
->target
;
1216 struct arm
*arm
= target_to_arm(target
);
1218 if (target
->state
!= TARGET_HALTED
)
1219 return ERROR_TARGET_NOT_HALTED
;
1221 return arm
->read_core_reg(target
, reg
, armv8_reg
->num
, arm
->core_mode
);
1224 static int armv8_set_core_reg(struct reg
*reg
, uint8_t *buf
)
1226 struct arm_reg
*armv8_reg
= reg
->arch_info
;
1227 struct target
*target
= armv8_reg
->target
;
1228 struct arm
*arm
= target_to_arm(target
);
1229 uint64_t value
= buf_get_u64(buf
, 0, reg
->size
);
1231 if (target
->state
!= TARGET_HALTED
)
1232 return ERROR_TARGET_NOT_HALTED
;
1234 if (reg
->size
<= 64) {
1235 if (reg
== arm
->cpsr
)
1236 armv8_set_cpsr(arm
, (uint32_t)value
);
1238 buf_set_u64(reg
->value
, 0, reg
->size
, value
);
1241 } else if (reg
->size
<= 128) {
1242 uint64_t hvalue
= buf_get_u64(buf
+ 8, 0, reg
->size
- 64);
1244 buf_set_u64(reg
->value
, 0, 64, value
);
1245 buf_set_u64(reg
->value
+ 8, 0, reg
->size
- 64, hvalue
);
1254 static const struct reg_arch_type armv8_reg_type
= {
1255 .get
= armv8_get_core_reg
,
1256 .set
= armv8_set_core_reg
,
1259 static int armv8_get_core_reg32(struct reg
*reg
)
1261 struct arm_reg
*armv8_reg
= reg
->arch_info
;
1262 struct target
*target
= armv8_reg
->target
;
1263 struct arm
*arm
= target_to_arm(target
);
1264 struct reg_cache
*cache
= arm
->core_cache
;
1268 /* get the corresponding Aarch64 register */
1269 reg64
= cache
->reg_list
+ armv8_reg
->num
;
1275 retval
= arm
->read_core_reg(target
, reg64
, armv8_reg
->num
, arm
->core_mode
);
1276 if (retval
== ERROR_OK
)
1277 reg
->valid
= reg64
->valid
;
1282 static int armv8_set_core_reg32(struct reg
*reg
, uint8_t *buf
)
1284 struct arm_reg
*armv8_reg
= reg
->arch_info
;
1285 struct target
*target
= armv8_reg
->target
;
1286 struct arm
*arm
= target_to_arm(target
);
1287 struct reg_cache
*cache
= arm
->core_cache
;
1288 struct reg
*reg64
= cache
->reg_list
+ armv8_reg
->num
;
1289 uint32_t value
= buf_get_u32(buf
, 0, 32);
1291 if (reg64
== arm
->cpsr
) {
1292 armv8_set_cpsr(arm
, value
);
1294 buf_set_u32(reg
->value
, 0, 32, value
);
1304 static const struct reg_arch_type armv8_reg32_type
= {
1305 .get
= armv8_get_core_reg32
,
1306 .set
= armv8_set_core_reg32
,
1309 /** Builds cache of architecturally defined registers. */
1310 struct reg_cache
*armv8_build_reg_cache(struct target
*target
)
1312 struct armv8_common
*armv8
= target_to_armv8(target
);
1313 struct arm
*arm
= &armv8
->arm
;
1314 int num_regs
= ARMV8_NUM_REGS
;
1315 int num_regs32
= ARMV8_NUM_REGS32
;
1316 struct reg_cache
**cache_p
= register_get_last_cache_p(&target
->reg_cache
);
1317 struct reg_cache
*cache
= malloc(sizeof(struct reg_cache
));
1318 struct reg_cache
*cache32
= malloc(sizeof(struct reg_cache
));
1319 struct reg
*reg_list
= calloc(num_regs
, sizeof(struct reg
));
1320 struct reg
*reg_list32
= calloc(num_regs32
, sizeof(struct reg
));
1321 struct arm_reg
*arch_info
= calloc(num_regs
, sizeof(struct arm_reg
));
1322 struct reg_feature
*feature
;
1325 /* Build the process context cache */
1326 cache
->name
= "Aarch64 registers";
1327 cache
->next
= cache32
;
1328 cache
->reg_list
= reg_list
;
1329 cache
->num_regs
= num_regs
;
1331 for (i
= 0; i
< num_regs
; i
++) {
1332 arch_info
[i
].num
= armv8_regs
[i
].id
;
1333 arch_info
[i
].mode
= armv8_regs
[i
].mode
;
1334 arch_info
[i
].target
= target
;
1335 arch_info
[i
].arm
= arm
;
1337 reg_list
[i
].name
= armv8_regs
[i
].name
;
1338 reg_list
[i
].size
= armv8_regs
[i
].bits
;
1339 reg_list
[i
].value
= &arch_info
[i
].value
[0];
1340 reg_list
[i
].type
= &armv8_reg_type
;
1341 reg_list
[i
].arch_info
= &arch_info
[i
];
1343 reg_list
[i
].group
= armv8_regs
[i
].group
;
1344 reg_list
[i
].number
= i
;
1345 reg_list
[i
].exist
= true;
1346 reg_list
[i
].caller_save
= true; /* gdb defaults to true */
1348 feature
= calloc(1, sizeof(struct reg_feature
));
1350 feature
->name
= armv8_regs
[i
].feature
;
1351 reg_list
[i
].feature
= feature
;
1353 LOG_ERROR("unable to allocate feature list");
1355 if (armv8_regs
[i
].data_type
== NULL
) {
1356 reg_list
[i
].reg_data_type
= calloc(1, sizeof(struct reg_data_type
));
1357 if (reg_list
[i
].reg_data_type
)
1358 reg_list
[i
].reg_data_type
->type
= armv8_regs
[i
].type
;
1360 LOG_ERROR("unable to allocate reg type list");
1362 reg_list
[i
].reg_data_type
= armv8_regs
[i
].data_type
;
1366 arm
->cpsr
= reg_list
+ ARMV8_xPSR
;
1367 arm
->pc
= reg_list
+ ARMV8_PC
;
1368 arm
->core_cache
= cache
;
1370 /* shadow cache for ARM mode registers */
1371 cache32
->name
= "Aarch32 registers";
1372 cache32
->next
= NULL
;
1373 cache32
->reg_list
= reg_list32
;
1374 cache32
->num_regs
= num_regs32
;
1376 for (i
= 0; i
< num_regs32
; i
++) {
1377 reg_list32
[i
].name
= armv8_regs32
[i
].name
;
1378 reg_list32
[i
].size
= armv8_regs32
[i
].bits
;
1379 reg_list32
[i
].value
= &arch_info
[armv8_regs32
[i
].id
].value
[0];
1380 reg_list32
[i
].type
= &armv8_reg32_type
;
1381 reg_list32
[i
].arch_info
= &arch_info
[armv8_regs32
[i
].id
];
1382 reg_list32
[i
].group
= armv8_regs32
[i
].group
;
1383 reg_list32
[i
].number
= i
;
1384 reg_list32
[i
].exist
= true;
1385 reg_list32
[i
].caller_save
= true;
1387 feature
= calloc(1, sizeof(struct reg_feature
));
1389 feature
->name
= armv8_regs32
[i
].feature
;
1390 reg_list32
[i
].feature
= feature
;
1392 LOG_ERROR("unable to allocate feature list");
1394 reg_list32
[i
].reg_data_type
= calloc(1, sizeof(struct reg_data_type
));
1395 if (reg_list32
[i
].reg_data_type
)
1396 reg_list32
[i
].reg_data_type
->type
= armv8_regs32
[i
].type
;
1398 LOG_ERROR("unable to allocate reg type list");
1405 struct reg
*armv8_reg_current(struct arm
*arm
, unsigned regnum
)
1409 if (regnum
> (ARMV8_LAST_REG
- 1))
1412 r
= arm
->core_cache
->reg_list
+ regnum
;
1416 const struct command_registration armv8_command_handlers
[] = {
1418 .chain
= dap_command_handlers
,
1420 COMMAND_REGISTRATION_DONE
1424 int armv8_get_gdb_reg_list(struct target
*target
,
1425 struct reg
**reg_list
[], int *reg_list_size
,
1426 enum target_register_class reg_class
)
1428 struct arm
*arm
= target_to_arm(target
);
1431 if (arm
->core_state
== ARM_STATE_AARCH64
) {
1433 LOG_DEBUG("Creating Aarch64 register list for target %s", target_name(target
));
1435 switch (reg_class
) {
1436 case REG_CLASS_GENERAL
:
1437 *reg_list_size
= ARMV8_V0
;
1438 *reg_list
= malloc(sizeof(struct reg
*) * (*reg_list_size
));
1440 for (i
= 0; i
< *reg_list_size
; i
++)
1441 (*reg_list
)[i
] = armv8_reg_current(arm
, i
);
1445 *reg_list_size
= ARMV8_LAST_REG
;
1446 *reg_list
= malloc(sizeof(struct reg
*) * (*reg_list_size
));
1448 for (i
= 0; i
< *reg_list_size
; i
++)
1449 (*reg_list
)[i
] = armv8_reg_current(arm
, i
);
1454 LOG_ERROR("not a valid register class type in query.");
1458 struct reg_cache
*cache32
= arm
->core_cache
->next
;
1460 LOG_DEBUG("Creating Aarch32 register list for target %s", target_name(target
));
1462 switch (reg_class
) {
1463 case REG_CLASS_GENERAL
:
1465 *reg_list_size
= cache32
->num_regs
;
1466 *reg_list
= malloc(sizeof(struct reg
*) * (*reg_list_size
));
1468 for (i
= 0; i
< *reg_list_size
; i
++)
1469 (*reg_list
)[i
] = cache32
->reg_list
+ i
;
1473 LOG_ERROR("not a valid register class type in query.");
1479 int armv8_set_dbgreg_bits(struct armv8_common
*armv8
, unsigned int reg
, unsigned long mask
, unsigned long value
)
1484 int retval
= mem_ap_read_atomic_u32(armv8
->debug_ap
,
1485 armv8
->debug_base
+ reg
, &tmp
);
1486 if (ERROR_OK
!= retval
)
1489 /* clear bitfield */
1492 tmp
|= value
& mask
;
1494 /* write new value */
1495 retval
= mem_ap_write_atomic_u32(armv8
->debug_ap
,
1496 armv8
->debug_base
+ reg
, tmp
);
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)