1 // SPDX-License-Identifier: GPL-2.0-or-later
3 /***************************************************************************
4 * Copyright (C) 2015 by David Ung *
6 * Copyright (C) 2018 by Liviu Ionescu *
8 ***************************************************************************/
14 #include <helper/replacements.h>
17 #include "arm_disassembler.h"
20 #include <helper/binarybuffer.h>
21 #include <helper/command.h>
27 #include "armv8_opcodes.h"
29 #include "target_type.h"
30 #include "semihosting_common.h"
32 static const char * const armv8_state_strings
[] = {
33 "AArch32", "Thumb", "Jazelle", "ThumbEE", "AArch64",
39 } armv8_mode_data
[] = {
102 .psr
= ARMV8_64_EL3H
,
106 /** Map PSR mode bits to the name of an ARM processor operating mode. */
107 const char *armv8_mode_name(unsigned psr_mode
)
109 for (unsigned i
= 0; i
< ARRAY_SIZE(armv8_mode_data
); i
++) {
110 if (armv8_mode_data
[i
].psr
== psr_mode
)
111 return armv8_mode_data
[i
].name
;
113 LOG_ERROR("unrecognized psr mode: %#02x", psr_mode
);
114 return "UNRECOGNIZED";
117 static uint8_t armv8_pa_size(uint32_t ps
)
140 LOG_INFO("Unknown physical address size");
146 static __attribute__((unused
)) int armv8_read_ttbcr32(struct target
*target
)
148 struct armv8_common
*armv8
= target_to_armv8(target
);
149 struct arm_dpm
*dpm
= armv8
->arm
.dpm
;
150 uint32_t ttbcr
, ttbcr_n
;
151 int retval
= dpm
->prepare(dpm
);
152 if (retval
!= ERROR_OK
)
154 /* MRC p15,0,<Rt>,c2,c0,2 ; Read CP15 Translation Table Base Control Register*/
155 retval
= dpm
->instr_read_data_r0(dpm
,
156 ARMV4_5_MRC(15, 0, 0, 2, 0, 2),
158 if (retval
!= ERROR_OK
)
161 LOG_DEBUG("ttbcr %" PRIx32
, ttbcr
);
163 ttbcr_n
= ttbcr
& 0x7;
164 armv8
->armv8_mmu
.ttbcr
= ttbcr
;
167 * ARM Architecture Reference Manual (ARMv7-A and ARMv7-R edition),
168 * document # ARM DDI 0406C
170 armv8
->armv8_mmu
.ttbr_range
[0] = 0xffffffff >> ttbcr_n
;
171 armv8
->armv8_mmu
.ttbr_range
[1] = 0xffffffff;
172 armv8
->armv8_mmu
.ttbr_mask
[0] = 0xffffffff << (14 - ttbcr_n
);
173 armv8
->armv8_mmu
.ttbr_mask
[1] = 0xffffffff << 14;
175 LOG_DEBUG("ttbr1 %s, ttbr0_mask %" PRIx32
" ttbr1_mask %" PRIx32
,
176 (ttbcr_n
!= 0) ? "used" : "not used",
177 armv8
->armv8_mmu
.ttbr_mask
[0],
178 armv8
->armv8_mmu
.ttbr_mask
[1]);
185 static int armv8_read_ttbcr(struct target
*target
)
187 struct armv8_common
*armv8
= target_to_armv8(target
);
188 struct arm_dpm
*dpm
= armv8
->arm
.dpm
;
189 struct arm
*arm
= &armv8
->arm
;
193 int retval
= dpm
->prepare(dpm
);
194 if (retval
!= ERROR_OK
)
197 /* clear ttrr1_used and ttbr0_mask */
198 memset(&armv8
->armv8_mmu
.ttbr1_used
, 0, sizeof(armv8
->armv8_mmu
.ttbr1_used
));
199 memset(&armv8
->armv8_mmu
.ttbr0_mask
, 0, sizeof(armv8
->armv8_mmu
.ttbr0_mask
));
201 switch (armv8_curel_from_core_mode(arm
->core_mode
)) {
202 case SYSTEM_CUREL_EL3
:
203 retval
= dpm
->instr_read_data_r0(dpm
,
204 ARMV8_MRS(SYSTEM_TCR_EL3
, 0),
206 retval
+= dpm
->instr_read_data_r0_64(dpm
,
207 ARMV8_MRS(SYSTEM_TTBR0_EL3
, 0),
209 if (retval
!= ERROR_OK
)
211 armv8
->va_size
= 64 - (ttbcr
& 0x3F);
212 armv8
->pa_size
= armv8_pa_size((ttbcr
>> 16) & 7);
213 armv8
->page_size
= (ttbcr
>> 14) & 3;
215 case SYSTEM_CUREL_EL2
:
216 retval
= dpm
->instr_read_data_r0(dpm
,
217 ARMV8_MRS(SYSTEM_TCR_EL2
, 0),
219 retval
+= dpm
->instr_read_data_r0_64(dpm
,
220 ARMV8_MRS(SYSTEM_TTBR0_EL2
, 0),
222 if (retval
!= ERROR_OK
)
224 armv8
->va_size
= 64 - (ttbcr
& 0x3F);
225 armv8
->pa_size
= armv8_pa_size((ttbcr
>> 16) & 7);
226 armv8
->page_size
= (ttbcr
>> 14) & 3;
228 case SYSTEM_CUREL_EL0
:
229 armv8_dpm_modeswitch(dpm
, ARMV8_64_EL1H
);
231 case SYSTEM_CUREL_EL1
:
232 retval
= dpm
->instr_read_data_r0_64(dpm
,
233 ARMV8_MRS(SYSTEM_TCR_EL1
, 0),
235 armv8
->va_size
= 64 - (ttbcr_64
& 0x3F);
236 armv8
->pa_size
= armv8_pa_size((ttbcr_64
>> 32) & 7);
237 armv8
->page_size
= (ttbcr_64
>> 14) & 3;
238 armv8
->armv8_mmu
.ttbr1_used
= (((ttbcr_64
>> 16) & 0x3F) != 0) ? 1 : 0;
239 armv8
->armv8_mmu
.ttbr0_mask
= 0x0000FFFFFFFFFFFF;
240 retval
+= dpm
->instr_read_data_r0_64(dpm
,
241 ARMV8_MRS(SYSTEM_TTBR0_EL1
| (armv8
->armv8_mmu
.ttbr1_used
), 0),
243 if (retval
!= ERROR_OK
)
247 LOG_ERROR("unknown core state");
251 if (retval
!= ERROR_OK
)
254 if (armv8
->armv8_mmu
.ttbr1_used
== 1)
255 LOG_INFO("TTBR0 access above %" PRIx64
, (uint64_t)(armv8
->armv8_mmu
.ttbr0_mask
));
258 armv8_dpm_modeswitch(dpm
, ARM_MODE_ANY
);
263 static int armv8_get_pauth_mask(struct armv8_common
*armv8
, uint64_t *mask
)
265 struct arm
*arm
= &armv8
->arm
;
266 int retval
= ERROR_OK
;
267 if (armv8
->va_size
== 0)
268 retval
= armv8_read_ttbcr(arm
->target
);
269 if (retval
!= ERROR_OK
)
272 *mask
= ~(((uint64_t)1 << armv8
->va_size
) - 1);
277 static int armv8_read_reg(struct armv8_common
*armv8
, int regnum
, uint64_t *regval
)
279 struct arm_dpm
*dpm
= &armv8
->dpm
;
286 retval
= dpm
->instr_read_data_dcc_64(dpm
,
287 ARMV8_MSR_GP(SYSTEM_DBG_DBGDTR_EL0
, regnum
), &value_64
);
290 retval
= dpm
->instr_read_data_r0_64(dpm
,
291 ARMV8_MOVFSP_64(0), &value_64
);
294 retval
= dpm
->instr_read_data_r0_64(dpm
,
295 ARMV8_MRS_DLR(0), &value_64
);
298 retval
= dpm
->instr_read_data_r0(dpm
,
299 ARMV8_MRS_DSPSR(0), &value
);
303 retval
= dpm
->instr_read_data_r0(dpm
,
304 ARMV8_MRS_FPSR(0), &value
);
308 retval
= dpm
->instr_read_data_r0(dpm
,
309 ARMV8_MRS_FPCR(0), &value
);
313 retval
= dpm
->instr_read_data_r0_64(dpm
,
314 ARMV8_MRS(SYSTEM_ELR_EL1
, 0), &value_64
);
317 retval
= dpm
->instr_read_data_r0_64(dpm
,
318 ARMV8_MRS(SYSTEM_ELR_EL2
, 0), &value_64
);
321 retval
= dpm
->instr_read_data_r0_64(dpm
,
322 ARMV8_MRS(SYSTEM_ELR_EL3
, 0), &value_64
);
325 retval
= dpm
->instr_read_data_r0(dpm
,
326 ARMV8_MRS(SYSTEM_ESR_EL1
, 0), &value
);
330 retval
= dpm
->instr_read_data_r0(dpm
,
331 ARMV8_MRS(SYSTEM_ESR_EL2
, 0), &value
);
335 retval
= dpm
->instr_read_data_r0(dpm
,
336 ARMV8_MRS(SYSTEM_ESR_EL3
, 0), &value
);
340 retval
= dpm
->instr_read_data_r0(dpm
,
341 ARMV8_MRS(SYSTEM_SPSR_EL1
, 0), &value
);
345 retval
= dpm
->instr_read_data_r0(dpm
,
346 ARMV8_MRS(SYSTEM_SPSR_EL2
, 0), &value
);
350 retval
= dpm
->instr_read_data_r0(dpm
,
351 ARMV8_MRS(SYSTEM_SPSR_EL3
, 0), &value
);
354 case ARMV8_PAUTH_CMASK
:
355 case ARMV8_PAUTH_DMASK
:
356 retval
= armv8_get_pauth_mask(armv8
, &value_64
);
363 if (retval
== ERROR_OK
&& regval
)
371 static int armv8_read_reg_simdfp_aarch64(struct armv8_common
*armv8
, int regnum
, uint64_t *lvalue
, uint64_t *hvalue
)
373 int retval
= ERROR_FAIL
;
374 struct arm_dpm
*dpm
= &armv8
->dpm
;
377 case ARMV8_V0
... ARMV8_V31
:
378 retval
= dpm
->instr_read_data_r0_64(dpm
,
379 ARMV8_MOV_GPR_VFP(0, (regnum
- ARMV8_V0
), 1), hvalue
);
380 if (retval
!= ERROR_OK
)
382 retval
= dpm
->instr_read_data_r0_64(dpm
,
383 ARMV8_MOV_GPR_VFP(0, (regnum
- ARMV8_V0
), 0), lvalue
);
394 static int armv8_write_reg(struct armv8_common
*armv8
, int regnum
, uint64_t value_64
)
396 struct arm_dpm
*dpm
= &armv8
->dpm
;
402 retval
= dpm
->instr_write_data_dcc_64(dpm
,
403 ARMV8_MRS(SYSTEM_DBG_DBGDTR_EL0
, regnum
),
407 retval
= dpm
->instr_write_data_r0_64(dpm
,
412 retval
= dpm
->instr_write_data_r0_64(dpm
,
418 retval
= dpm
->instr_write_data_r0(dpm
,
424 retval
= dpm
->instr_write_data_r0(dpm
,
430 retval
= dpm
->instr_write_data_r0(dpm
,
434 /* registers clobbered by taking exception in debug state */
436 retval
= dpm
->instr_write_data_r0_64(dpm
,
437 ARMV8_MSR_GP(SYSTEM_ELR_EL1
, 0), value_64
);
440 retval
= dpm
->instr_write_data_r0_64(dpm
,
441 ARMV8_MSR_GP(SYSTEM_ELR_EL2
, 0), value_64
);
444 retval
= dpm
->instr_write_data_r0_64(dpm
,
445 ARMV8_MSR_GP(SYSTEM_ELR_EL3
, 0), value_64
);
449 retval
= dpm
->instr_write_data_r0(dpm
,
450 ARMV8_MSR_GP(SYSTEM_ESR_EL1
, 0), value
);
454 retval
= dpm
->instr_write_data_r0(dpm
,
455 ARMV8_MSR_GP(SYSTEM_ESR_EL2
, 0), value
);
459 retval
= dpm
->instr_write_data_r0(dpm
,
460 ARMV8_MSR_GP(SYSTEM_ESR_EL3
, 0), value
);
464 retval
= dpm
->instr_write_data_r0(dpm
,
465 ARMV8_MSR_GP(SYSTEM_SPSR_EL1
, 0), value
);
469 retval
= dpm
->instr_write_data_r0(dpm
,
470 ARMV8_MSR_GP(SYSTEM_SPSR_EL2
, 0), value
);
474 retval
= dpm
->instr_write_data_r0(dpm
,
475 ARMV8_MSR_GP(SYSTEM_SPSR_EL3
, 0), value
);
485 static int armv8_write_reg_simdfp_aarch64(struct armv8_common
*armv8
, int regnum
, uint64_t lvalue
, uint64_t hvalue
)
487 int retval
= ERROR_FAIL
;
488 struct arm_dpm
*dpm
= &armv8
->dpm
;
491 case ARMV8_V0
... ARMV8_V31
:
492 retval
= dpm
->instr_write_data_r0_64(dpm
,
493 ARMV8_MOV_VFP_GPR((regnum
- ARMV8_V0
), 0, 1), hvalue
);
494 if (retval
!= ERROR_OK
)
496 retval
= dpm
->instr_write_data_r0_64(dpm
,
497 ARMV8_MOV_VFP_GPR((regnum
- ARMV8_V0
), 0, 0), lvalue
);
508 static int armv8_read_reg32(struct armv8_common
*armv8
, int regnum
, uint64_t *regval
)
510 struct arm_dpm
*dpm
= &armv8
->dpm
;
515 case ARMV8_R0
... ARMV8_R14
:
516 /* return via DCC: "MCR p14, 0, Rnum, c0, c5, 0" */
517 retval
= dpm
->instr_read_data_dcc(dpm
,
518 ARMV4_5_MCR(14, 0, regnum
, 0, 5, 0),
522 retval
= dpm
->instr_read_data_dcc(dpm
,
523 ARMV4_5_MCR(14, 0, 13, 0, 5, 0),
527 retval
= dpm
->instr_read_data_r0(dpm
,
532 retval
= dpm
->instr_read_data_r0(dpm
,
536 case ARMV8_ELR_EL1
: /* mapped to LR_svc */
537 retval
= dpm
->instr_read_data_dcc(dpm
,
538 ARMV4_5_MCR(14, 0, 14, 0, 5, 0),
541 case ARMV8_ELR_EL2
: /* mapped to ELR_hyp */
542 retval
= dpm
->instr_read_data_r0(dpm
,
543 ARMV8_MRS_T1(0, 14, 0, 1),
546 case ARMV8_ELR_EL3
: /* mapped to LR_mon */
547 retval
= dpm
->instr_read_data_dcc(dpm
,
548 ARMV4_5_MCR(14, 0, 14, 0, 5, 0),
551 case ARMV8_ESR_EL1
: /* mapped to DFSR */
552 retval
= dpm
->instr_read_data_r0(dpm
,
553 ARMV4_5_MRC(15, 0, 0, 5, 0, 0),
556 case ARMV8_ESR_EL2
: /* mapped to HSR */
557 retval
= dpm
->instr_read_data_r0(dpm
,
558 ARMV4_5_MRC(15, 4, 0, 5, 2, 0),
561 case ARMV8_ESR_EL3
: /* FIXME: no equivalent in aarch32? */
564 case ARMV8_SPSR_EL1
: /* mapped to SPSR_svc */
565 retval
= dpm
->instr_read_data_r0(dpm
,
566 ARMV8_MRS_XPSR_T1(1, 0),
569 case ARMV8_SPSR_EL2
: /* mapped to SPSR_hyp */
570 retval
= dpm
->instr_read_data_r0(dpm
,
571 ARMV8_MRS_XPSR_T1(1, 0),
574 case ARMV8_SPSR_EL3
: /* mapped to SPSR_mon */
575 retval
= dpm
->instr_read_data_r0(dpm
,
576 ARMV8_MRS_XPSR_T1(1, 0),
580 /* "VMRS r0, FPSCR"; then return via DCC */
581 retval
= dpm
->instr_read_data_r0(dpm
,
582 ARMV4_5_VMRS(0), &value
);
589 if (retval
== ERROR_OK
&& regval
)
595 static int armv8_read_reg_simdfp_aarch32(struct armv8_common
*armv8
, int regnum
, uint64_t *lvalue
, uint64_t *hvalue
)
597 int retval
= ERROR_FAIL
;
598 struct arm_dpm
*dpm
= &armv8
->dpm
;
599 struct reg
*reg_r1
= dpm
->arm
->core_cache
->reg_list
+ ARMV8_R1
;
600 uint32_t value_r0
= 0, value_r1
= 0;
601 unsigned num
= (regnum
- ARMV8_V0
) << 1;
604 case ARMV8_V0
... ARMV8_V15
:
605 /* we are going to write R1, mark it dirty */
606 reg_r1
->dirty
= true;
607 /* move from double word register to r0:r1: "vmov r0, r1, vm"
608 * then read r0 via dcc
610 retval
= dpm
->instr_read_data_r0(dpm
,
611 ARMV4_5_VMOV(1, 1, 0, (num
>> 4), (num
& 0xf)),
613 if (retval
!= ERROR_OK
)
615 /* read r1 via dcc */
616 retval
= dpm
->instr_read_data_dcc(dpm
,
617 ARMV4_5_MCR(14, 0, 1, 0, 5, 0),
619 if (retval
!= ERROR_OK
)
622 *lvalue
= ((*lvalue
) << 32) | value_r0
;
625 /* repeat above steps for high 64 bits of V register */
626 retval
= dpm
->instr_read_data_r0(dpm
,
627 ARMV4_5_VMOV(1, 1, 0, (num
>> 4), (num
& 0xf)),
629 if (retval
!= ERROR_OK
)
631 retval
= dpm
->instr_read_data_dcc(dpm
,
632 ARMV4_5_MCR(14, 0, 1, 0, 5, 0),
634 if (retval
!= ERROR_OK
)
637 *hvalue
= ((*hvalue
) << 32) | value_r0
;
647 static int armv8_write_reg32(struct armv8_common
*armv8
, int regnum
, uint64_t value
)
649 struct arm_dpm
*dpm
= &armv8
->dpm
;
653 case ARMV8_R0
... ARMV8_R14
:
654 /* load register from DCC: "MRC p14, 0, Rnum, c0, c5, 0" */
655 retval
= dpm
->instr_write_data_dcc(dpm
,
656 ARMV4_5_MRC(14, 0, regnum
, 0, 5, 0), value
);
659 retval
= dpm
->instr_write_data_dcc(dpm
,
660 ARMV4_5_MRC(14, 0, 13, 0, 5, 0), value
);
663 * read r0 from DCC; then "MOV pc, r0" */
664 retval
= dpm
->instr_write_data_r0(dpm
,
665 ARMV8_MCR_DLR(0), value
);
667 case ARMV8_XPSR
: /* CPSR */
668 /* read r0 from DCC, then "MCR r0, DSPSR" */
669 retval
= dpm
->instr_write_data_r0(dpm
,
670 ARMV8_MCR_DSPSR(0), value
);
672 case ARMV8_ELR_EL1
: /* mapped to LR_svc */
673 retval
= dpm
->instr_write_data_dcc(dpm
,
674 ARMV4_5_MRC(14, 0, 14, 0, 5, 0),
677 case ARMV8_ELR_EL2
: /* mapped to ELR_hyp */
678 retval
= dpm
->instr_write_data_r0(dpm
,
679 ARMV8_MSR_GP_T1(0, 14, 0, 1),
682 case ARMV8_ELR_EL3
: /* mapped to LR_mon */
683 retval
= dpm
->instr_write_data_dcc(dpm
,
684 ARMV4_5_MRC(14, 0, 14, 0, 5, 0),
687 case ARMV8_ESR_EL1
: /* mapped to DFSR */
688 retval
= dpm
->instr_write_data_r0(dpm
,
689 ARMV4_5_MCR(15, 0, 0, 5, 0, 0),
692 case ARMV8_ESR_EL2
: /* mapped to HSR */
693 retval
= dpm
->instr_write_data_r0(dpm
,
694 ARMV4_5_MCR(15, 4, 0, 5, 2, 0),
697 case ARMV8_ESR_EL3
: /* FIXME: no equivalent in aarch32? */
700 case ARMV8_SPSR_EL1
: /* mapped to SPSR_svc */
701 retval
= dpm
->instr_write_data_r0(dpm
,
702 ARMV8_MSR_GP_XPSR_T1(1, 0, 15),
705 case ARMV8_SPSR_EL2
: /* mapped to SPSR_hyp */
706 retval
= dpm
->instr_write_data_r0(dpm
,
707 ARMV8_MSR_GP_XPSR_T1(1, 0, 15),
710 case ARMV8_SPSR_EL3
: /* mapped to SPSR_mon */
711 retval
= dpm
->instr_write_data_r0(dpm
,
712 ARMV8_MSR_GP_XPSR_T1(1, 0, 15),
716 /* move to r0 from DCC, then "VMSR FPSCR, r0" */
717 retval
= dpm
->instr_write_data_r0(dpm
,
718 ARMV4_5_VMSR(0), value
);
729 static int armv8_write_reg_simdfp_aarch32(struct armv8_common
*armv8
, int regnum
, uint64_t lvalue
, uint64_t hvalue
)
731 int retval
= ERROR_FAIL
;
732 struct arm_dpm
*dpm
= &armv8
->dpm
;
733 struct reg
*reg_r1
= dpm
->arm
->core_cache
->reg_list
+ ARMV8_R1
;
734 uint32_t value_r0
= 0, value_r1
= 0;
735 unsigned num
= (regnum
- ARMV8_V0
) << 1;
738 case ARMV8_V0
... ARMV8_V15
:
739 /* we are going to write R1, mark it dirty */
740 reg_r1
->dirty
= true;
741 value_r1
= lvalue
>> 32;
742 value_r0
= lvalue
& 0xFFFFFFFF;
743 /* write value_r1 to r1 via dcc */
744 retval
= dpm
->instr_write_data_dcc(dpm
,
745 ARMV4_5_MRC(14, 0, 1, 0, 5, 0),
747 if (retval
!= ERROR_OK
)
749 /* write value_r0 to r0 via dcc then,
750 * move to double word register from r0:r1: "vmov vm, r0, r1"
752 retval
= dpm
->instr_write_data_r0(dpm
,
753 ARMV4_5_VMOV(0, 1, 0, (num
>> 4), (num
& 0xf)),
755 if (retval
!= ERROR_OK
)
759 /* repeat above steps for high 64 bits of V register */
760 value_r1
= hvalue
>> 32;
761 value_r0
= hvalue
& 0xFFFFFFFF;
762 retval
= dpm
->instr_write_data_dcc(dpm
,
763 ARMV4_5_MRC(14, 0, 1, 0, 5, 0),
765 if (retval
!= ERROR_OK
)
767 retval
= dpm
->instr_write_data_r0(dpm
,
768 ARMV4_5_VMOV(0, 1, 0, (num
>> 4), (num
& 0xf)),
779 void armv8_select_reg_access(struct armv8_common
*armv8
, bool is_aarch64
)
782 armv8
->read_reg_u64
= armv8_read_reg
;
783 armv8
->write_reg_u64
= armv8_write_reg
;
784 armv8
->read_reg_u128
= armv8_read_reg_simdfp_aarch64
;
785 armv8
->write_reg_u128
= armv8_write_reg_simdfp_aarch64
;
788 armv8
->read_reg_u64
= armv8_read_reg32
;
789 armv8
->write_reg_u64
= armv8_write_reg32
;
790 armv8
->read_reg_u128
= armv8_read_reg_simdfp_aarch32
;
791 armv8
->write_reg_u128
= armv8_write_reg_simdfp_aarch32
;
795 /* retrieve core id cluster id */
796 int armv8_read_mpidr(struct armv8_common
*armv8
)
798 int retval
= ERROR_FAIL
;
799 struct arm
*arm
= &armv8
->arm
;
800 struct arm_dpm
*dpm
= armv8
->arm
.dpm
;
803 retval
= dpm
->prepare(dpm
);
804 if (retval
!= ERROR_OK
)
807 /* check if we're in an unprivileged mode */
808 if (armv8_curel_from_core_mode(arm
->core_mode
) < SYSTEM_CUREL_EL1
) {
809 retval
= armv8_dpm_modeswitch(dpm
, ARMV8_64_EL1H
);
810 if (retval
!= ERROR_OK
)
814 retval
= dpm
->instr_read_data_r0(dpm
, armv8_opcode(armv8
, READ_REG_MPIDR
), &mpidr
);
815 if (retval
!= ERROR_OK
)
817 if (mpidr
& 1U<<31) {
818 armv8
->multi_processor_system
= (mpidr
>> 30) & 1;
819 armv8
->cluster_id
= (mpidr
>> 8) & 0xf;
820 armv8
->cpu_id
= mpidr
& 0x3;
821 LOG_INFO("%s cluster %x core %x %s", target_name(armv8
->arm
.target
),
824 armv8
->multi_processor_system
== 0 ? "multi core" : "single core");
826 LOG_ERROR("mpidr not in multiprocessor format");
829 armv8_dpm_modeswitch(dpm
, ARM_MODE_ANY
);
835 * Configures host-side ARM records to reflect the specified CPSR.
836 * Later, code can use arm_reg_current() to map register numbers
837 * according to how they are exposed by this mode.
839 void armv8_set_cpsr(struct arm
*arm
, uint32_t cpsr
)
841 uint32_t mode
= cpsr
& 0x1F;
843 /* NOTE: this may be called very early, before the register
844 * cache is set up. We can't defend against many errors, in
845 * particular against CPSRs that aren't valid *here* ...
848 buf_set_u32(arm
->cpsr
->value
, 0, 32, cpsr
);
849 arm
->cpsr
->valid
= true;
850 arm
->cpsr
->dirty
= false;
853 /* Older ARMs won't have the J bit */
854 enum arm_state state
= 0xFF;
856 if ((cpsr
& 0x10) != 0) {
858 if (cpsr
& (1 << 5)) { /* T */
859 if (cpsr
& (1 << 24)) { /* J */
860 LOG_WARNING("ThumbEE -- incomplete support");
861 state
= ARM_STATE_THUMB_EE
;
863 state
= ARM_STATE_THUMB
;
865 if (cpsr
& (1 << 24)) { /* J */
866 LOG_ERROR("Jazelle state handling is BROKEN!");
867 state
= ARM_STATE_JAZELLE
;
869 state
= ARM_STATE_ARM
;
873 state
= ARM_STATE_AARCH64
;
876 arm
->core_state
= state
;
877 arm
->core_mode
= mode
;
879 LOG_DEBUG("set CPSR %#8.8x: %s mode, %s state", (unsigned) cpsr
,
880 armv8_mode_name(arm
->core_mode
),
881 armv8_state_strings
[arm
->core_state
]);
884 static void armv8_show_fault_registers32(struct armv8_common
*armv8
)
886 uint32_t dfsr
, ifsr
, dfar
, ifar
;
887 struct arm_dpm
*dpm
= armv8
->arm
.dpm
;
890 retval
= dpm
->prepare(dpm
);
891 if (retval
!= ERROR_OK
)
894 /* ARMV4_5_MRC(cpnum, op1, r0, crn, crm, op2) */
896 /* c5/c0 - {data, instruction} fault status registers */
897 retval
= dpm
->instr_read_data_r0(dpm
,
898 ARMV4_5_MRC(15, 0, 0, 5, 0, 0),
900 if (retval
!= ERROR_OK
)
903 retval
= dpm
->instr_read_data_r0(dpm
,
904 ARMV4_5_MRC(15, 0, 0, 5, 0, 1),
906 if (retval
!= ERROR_OK
)
909 /* c6/c0 - {data, instruction} fault address registers */
910 retval
= dpm
->instr_read_data_r0(dpm
,
911 ARMV4_5_MRC(15, 0, 0, 6, 0, 0),
913 if (retval
!= ERROR_OK
)
916 retval
= dpm
->instr_read_data_r0(dpm
,
917 ARMV4_5_MRC(15, 0, 0, 6, 0, 2),
919 if (retval
!= ERROR_OK
)
922 LOG_USER("Data fault registers DFSR: %8.8" PRIx32
923 ", DFAR: %8.8" PRIx32
, dfsr
, dfar
);
924 LOG_USER("Instruction fault registers IFSR: %8.8" PRIx32
925 ", IFAR: %8.8" PRIx32
, ifsr
, ifar
);
928 /* (void) */ dpm
->finish(dpm
);
931 static __attribute__((unused
)) void armv8_show_fault_registers(struct target
*target
)
933 struct armv8_common
*armv8
= target_to_armv8(target
);
935 if (armv8
->arm
.core_state
!= ARM_STATE_AARCH64
)
936 armv8_show_fault_registers32(armv8
);
939 /* method adapted to cortex A : reused arm v4 v5 method*/
940 int armv8_mmu_translate_va(struct target
*target
, target_addr_t va
, target_addr_t
*val
)
945 /* V8 method VA TO PA */
946 int armv8_mmu_translate_va_pa(struct target
*target
, target_addr_t va
,
947 target_addr_t
*val
, int meminfo
)
949 struct armv8_common
*armv8
= target_to_armv8(target
);
950 struct arm
*arm
= target_to_arm(target
);
951 struct arm_dpm
*dpm
= &armv8
->dpm
;
952 enum arm_mode target_mode
= ARM_MODE_ANY
;
957 static const char * const shared_name
[] = {
958 "Non-", "UNDEFINED ", "Outer ", "Inner "
961 static const char * const secure_name
[] = {
962 "Secure", "Not Secure"
965 if (target
->state
!= TARGET_HALTED
) {
966 LOG_WARNING("target %s not halted", target_name(target
));
967 return ERROR_TARGET_NOT_HALTED
;
970 retval
= dpm
->prepare(dpm
);
971 if (retval
!= ERROR_OK
)
974 switch (armv8_curel_from_core_mode(arm
->core_mode
)) {
975 case SYSTEM_CUREL_EL0
:
976 instr
= ARMV8_SYS(SYSTEM_ATS12E0R
, 0);
977 /* can only execute instruction at EL2 */
978 target_mode
= ARMV8_64_EL2H
;
980 case SYSTEM_CUREL_EL1
:
981 instr
= ARMV8_SYS(SYSTEM_ATS12E1R
, 0);
982 /* can only execute instruction at EL2 */
983 target_mode
= ARMV8_64_EL2H
;
985 case SYSTEM_CUREL_EL2
:
986 instr
= ARMV8_SYS(SYSTEM_ATS1E2R
, 0);
988 case SYSTEM_CUREL_EL3
:
989 instr
= ARMV8_SYS(SYSTEM_ATS1E3R
, 0);
996 if (target_mode
!= ARM_MODE_ANY
)
997 armv8_dpm_modeswitch(dpm
, target_mode
);
999 /* write VA to R0 and execute translation instruction */
1000 retval
= dpm
->instr_write_data_r0_64(dpm
, instr
, (uint64_t)va
);
1001 /* read result from PAR_EL1 */
1002 if (retval
== ERROR_OK
)
1003 retval
= dpm
->instr_read_data_r0_64(dpm
, ARMV8_MRS(SYSTEM_PAR_EL1
, 0), &par
);
1005 /* switch back to saved PE mode */
1006 if (target_mode
!= ARM_MODE_ANY
)
1007 armv8_dpm_modeswitch(dpm
, ARM_MODE_ANY
);
1011 if (retval
!= ERROR_OK
)
1015 LOG_ERROR("Address translation failed at stage %i, FST=%x, PTW=%i",
1016 ((int)(par
>> 9) & 1)+1, (int)(par
>> 1) & 0x3f, (int)(par
>> 8) & 1);
1019 retval
= ERROR_FAIL
;
1021 *val
= (par
& 0xFFFFFFFFF000UL
) | (va
& 0xFFF);
1023 int SH
= (par
>> 7) & 3;
1024 int NS
= (par
>> 9) & 1;
1025 int ATTR
= (par
>> 56) & 0xFF;
1027 char *memtype
= (ATTR
& 0xF0) == 0 ? "Device Memory" : "Normal Memory";
1029 LOG_USER("%sshareable, %s",
1030 shared_name
[SH
], secure_name
[NS
]);
1031 LOG_USER("%s", memtype
);
1038 COMMAND_HANDLER(armv8_handle_exception_catch_command
)
1040 struct target
*target
= get_current_target(CMD_CTX
);
1041 struct armv8_common
*armv8
= target_to_armv8(target
);
1042 uint32_t edeccr
= 0;
1043 unsigned int argp
= 0;
1046 static const struct jim_nvp nvp_ecatch_modes
[] = {
1047 { .name
= "off", .value
= 0 },
1048 { .name
= "nsec_el1", .value
= (1 << 5) },
1049 { .name
= "nsec_el2", .value
= (2 << 5) },
1050 { .name
= "nsec_el12", .value
= (3 << 5) },
1051 { .name
= "sec_el1", .value
= (1 << 1) },
1052 { .name
= "sec_el3", .value
= (4 << 1) },
1053 { .name
= "sec_el13", .value
= (5 << 1) },
1054 { .name
= NULL
, .value
= -1 },
1056 const struct jim_nvp
*n
;
1058 if (CMD_ARGC
== 0) {
1059 const char *sec
= NULL
, *nsec
= NULL
;
1061 retval
= mem_ap_read_atomic_u32(armv8
->debug_ap
,
1062 armv8
->debug_base
+ CPUV8_DBG_ECCR
, &edeccr
);
1063 if (retval
!= ERROR_OK
)
1066 n
= jim_nvp_value2name_simple(nvp_ecatch_modes
, edeccr
& 0x0f);
1070 n
= jim_nvp_value2name_simple(nvp_ecatch_modes
, edeccr
& 0xf0);
1074 if (!sec
|| !nsec
) {
1075 LOG_WARNING("Exception Catch: unknown exception catch configuration: EDECCR = %02" PRIx32
, edeccr
& 0xff);
1079 command_print(CMD
, "Exception Catch: Secure: %s, Non-Secure: %s", sec
, nsec
);
1083 while (argp
< CMD_ARGC
) {
1084 n
= jim_nvp_name2value_simple(nvp_ecatch_modes
, CMD_ARGV
[argp
]);
1086 LOG_ERROR("Unknown option: %s", CMD_ARGV
[argp
]);
1090 LOG_DEBUG("found: %s", n
->name
);
1096 retval
= mem_ap_write_atomic_u32(armv8
->debug_ap
,
1097 armv8
->debug_base
+ CPUV8_DBG_ECCR
, edeccr
);
1098 if (retval
!= ERROR_OK
)
1104 COMMAND_HANDLER(armv8_pauth_command
)
1106 struct target
*target
= get_current_target(CMD_CTX
);
1107 struct armv8_common
*armv8
= target_to_armv8(target
);
1108 return CALL_COMMAND_HANDLER(handle_command_parse_bool
,
1109 &armv8
->enable_pauth
,
1113 int armv8_handle_cache_info_command(struct command_invocation
*cmd
,
1114 struct armv8_cache_common
*armv8_cache
)
1116 if (armv8_cache
->info
== -1) {
1117 command_print(cmd
, "cache not yet identified");
1121 if (armv8_cache
->display_cache_info
)
1122 armv8_cache
->display_cache_info(cmd
, armv8_cache
);
1126 static int armv8_setup_semihosting(struct target
*target
, int enable
)
1131 int armv8_init_arch_info(struct target
*target
, struct armv8_common
*armv8
)
1133 struct arm
*arm
= &armv8
->arm
;
1134 arm
->arch_info
= armv8
;
1135 target
->arch_info
= &armv8
->arm
;
1136 arm
->setup_semihosting
= armv8_setup_semihosting
;
1137 /* target is useful in all function arm v4 5 compatible */
1138 armv8
->arm
.target
= target
;
1139 armv8
->arm
.common_magic
= ARM_COMMON_MAGIC
;
1140 armv8
->common_magic
= ARMV8_COMMON_MAGIC
;
1142 armv8
->armv8_mmu
.armv8_cache
.l2_cache
= NULL
;
1143 armv8
->armv8_mmu
.armv8_cache
.info
= -1;
1144 armv8
->armv8_mmu
.armv8_cache
.flush_all_data_cache
= NULL
;
1145 armv8
->armv8_mmu
.armv8_cache
.display_cache_info
= NULL
;
1149 static int armv8_aarch64_state(struct target
*target
)
1151 struct arm
*arm
= target_to_arm(target
);
1153 if (arm
->common_magic
!= ARM_COMMON_MAGIC
) {
1154 LOG_ERROR("BUG: called for a non-ARM target");
1158 LOG_USER("%s halted in %s state due to %s, current mode: %s\n"
1159 "cpsr: 0x%8.8" PRIx32
" pc: 0x%" PRIx64
"%s",
1160 target_name(target
),
1161 armv8_state_strings
[arm
->core_state
],
1162 debug_reason_name(target
),
1163 armv8_mode_name(arm
->core_mode
),
1164 buf_get_u32(arm
->cpsr
->value
, 0, 32),
1165 buf_get_u64(arm
->pc
->value
, 0, 64),
1166 (target
->semihosting
&& target
->semihosting
->is_active
) ? ", semihosting" : "");
1171 int armv8_arch_state(struct target
*target
)
1173 static const char * const state
[] = {
1174 "disabled", "enabled"
1177 struct armv8_common
*armv8
= target_to_armv8(target
);
1178 struct arm
*arm
= &armv8
->arm
;
1180 if (armv8
->common_magic
!= ARMV8_COMMON_MAGIC
) {
1181 LOG_ERROR("BUG: called for a non-Armv8 target");
1182 return ERROR_COMMAND_SYNTAX_ERROR
;
1185 if (arm
->core_state
== ARM_STATE_AARCH64
)
1186 armv8_aarch64_state(target
);
1188 arm_arch_state(target
);
1190 LOG_USER("MMU: %s, D-Cache: %s, I-Cache: %s",
1191 state
[armv8
->armv8_mmu
.mmu_enabled
],
1192 state
[armv8
->armv8_mmu
.armv8_cache
.d_u_cache_enabled
],
1193 state
[armv8
->armv8_mmu
.armv8_cache
.i_cache_enabled
]);
1195 if (arm
->core_mode
== ARM_MODE_ABT
)
1196 armv8_show_fault_registers(target
);
1198 if (target
->debug_reason
== DBG_REASON_WATCHPOINT
)
1199 LOG_USER("Watchpoint triggered at " TARGET_ADDR_FMT
, armv8
->dpm
.wp_addr
);
1204 static struct reg_data_type aarch64_vector_base_types
[] = {
1205 {REG_TYPE_IEEE_DOUBLE
, "ieee_double", 0, {NULL
} },
1206 {REG_TYPE_UINT64
, "uint64", 0, {NULL
} },
1207 {REG_TYPE_INT64
, "int64", 0, {NULL
} },
1208 {REG_TYPE_IEEE_SINGLE
, "ieee_single", 0, {NULL
} },
1209 {REG_TYPE_UINT32
, "uint32", 0, {NULL
} },
1210 {REG_TYPE_INT32
, "int32", 0, {NULL
} },
1211 {REG_TYPE_UINT16
, "uint16", 0, {NULL
} },
1212 {REG_TYPE_INT16
, "int16", 0, {NULL
} },
1213 {REG_TYPE_UINT8
, "uint8", 0, {NULL
} },
1214 {REG_TYPE_INT8
, "int8", 0, {NULL
} },
1215 {REG_TYPE_UINT128
, "uint128", 0, {NULL
} },
1216 {REG_TYPE_INT128
, "int128", 0, {NULL
} }
1219 static struct reg_data_type_vector aarch64_vector_types
[] = {
1220 {aarch64_vector_base_types
+ 0, 2},
1221 {aarch64_vector_base_types
+ 1, 2},
1222 {aarch64_vector_base_types
+ 2, 2},
1223 {aarch64_vector_base_types
+ 3, 4},
1224 {aarch64_vector_base_types
+ 4, 4},
1225 {aarch64_vector_base_types
+ 5, 4},
1226 {aarch64_vector_base_types
+ 6, 8},
1227 {aarch64_vector_base_types
+ 7, 8},
1228 {aarch64_vector_base_types
+ 8, 16},
1229 {aarch64_vector_base_types
+ 9, 16},
1230 {aarch64_vector_base_types
+ 10, 01},
1231 {aarch64_vector_base_types
+ 11, 01},
1234 static struct reg_data_type aarch64_fpu_vector
[] = {
1235 {REG_TYPE_ARCH_DEFINED
, "v2d", REG_TYPE_CLASS_VECTOR
, {aarch64_vector_types
+ 0} },
1236 {REG_TYPE_ARCH_DEFINED
, "v2u", REG_TYPE_CLASS_VECTOR
, {aarch64_vector_types
+ 1} },
1237 {REG_TYPE_ARCH_DEFINED
, "v2i", REG_TYPE_CLASS_VECTOR
, {aarch64_vector_types
+ 2} },
1238 {REG_TYPE_ARCH_DEFINED
, "v4f", REG_TYPE_CLASS_VECTOR
, {aarch64_vector_types
+ 3} },
1239 {REG_TYPE_ARCH_DEFINED
, "v4u", REG_TYPE_CLASS_VECTOR
, {aarch64_vector_types
+ 4} },
1240 {REG_TYPE_ARCH_DEFINED
, "v4i", REG_TYPE_CLASS_VECTOR
, {aarch64_vector_types
+ 5} },
1241 {REG_TYPE_ARCH_DEFINED
, "v8u", REG_TYPE_CLASS_VECTOR
, {aarch64_vector_types
+ 6} },
1242 {REG_TYPE_ARCH_DEFINED
, "v8i", REG_TYPE_CLASS_VECTOR
, {aarch64_vector_types
+ 7} },
1243 {REG_TYPE_ARCH_DEFINED
, "v16u", REG_TYPE_CLASS_VECTOR
, {aarch64_vector_types
+ 8} },
1244 {REG_TYPE_ARCH_DEFINED
, "v16i", REG_TYPE_CLASS_VECTOR
, {aarch64_vector_types
+ 9} },
1245 {REG_TYPE_ARCH_DEFINED
, "v1u", REG_TYPE_CLASS_VECTOR
, {aarch64_vector_types
+ 10} },
1246 {REG_TYPE_ARCH_DEFINED
, "v1i", REG_TYPE_CLASS_VECTOR
, {aarch64_vector_types
+ 11} },
1249 static struct reg_data_type_union_field aarch64_union_fields_vnd
[] = {
1250 {"f", aarch64_fpu_vector
+ 0, aarch64_union_fields_vnd
+ 1},
1251 {"u", aarch64_fpu_vector
+ 1, aarch64_union_fields_vnd
+ 2},
1252 {"s", aarch64_fpu_vector
+ 2, NULL
},
1255 static struct reg_data_type_union_field aarch64_union_fields_vns
[] = {
1256 {"f", aarch64_fpu_vector
+ 3, aarch64_union_fields_vns
+ 1},
1257 {"u", aarch64_fpu_vector
+ 4, aarch64_union_fields_vns
+ 2},
1258 {"s", aarch64_fpu_vector
+ 5, NULL
},
1261 static struct reg_data_type_union_field aarch64_union_fields_vnh
[] = {
1262 {"u", aarch64_fpu_vector
+ 6, aarch64_union_fields_vnh
+ 1},
1263 {"s", aarch64_fpu_vector
+ 7, NULL
},
1266 static struct reg_data_type_union_field aarch64_union_fields_vnb
[] = {
1267 {"u", aarch64_fpu_vector
+ 8, aarch64_union_fields_vnb
+ 1},
1268 {"s", aarch64_fpu_vector
+ 9, NULL
},
1271 static struct reg_data_type_union_field aarch64_union_fields_vnq
[] = {
1272 {"u", aarch64_fpu_vector
+ 10, aarch64_union_fields_vnq
+ 1},
1273 {"s", aarch64_fpu_vector
+ 11, NULL
},
1276 static struct reg_data_type_union aarch64_union_types
[] = {
1277 {aarch64_union_fields_vnd
},
1278 {aarch64_union_fields_vns
},
1279 {aarch64_union_fields_vnh
},
1280 {aarch64_union_fields_vnb
},
1281 {aarch64_union_fields_vnq
},
1284 static struct reg_data_type aarch64_fpu_union
[] = {
1285 {REG_TYPE_ARCH_DEFINED
, "vnd", REG_TYPE_CLASS_UNION
, {.reg_type_union
= aarch64_union_types
+ 0} },
1286 {REG_TYPE_ARCH_DEFINED
, "vns", REG_TYPE_CLASS_UNION
, {.reg_type_union
= aarch64_union_types
+ 1} },
1287 {REG_TYPE_ARCH_DEFINED
, "vnh", REG_TYPE_CLASS_UNION
, {.reg_type_union
= aarch64_union_types
+ 2} },
1288 {REG_TYPE_ARCH_DEFINED
, "vnb", REG_TYPE_CLASS_UNION
, {.reg_type_union
= aarch64_union_types
+ 3} },
1289 {REG_TYPE_ARCH_DEFINED
, "vnq", REG_TYPE_CLASS_UNION
, {.reg_type_union
= aarch64_union_types
+ 4} },
1292 static struct reg_data_type_union_field aarch64v_union_fields
[] = {
1293 {"d", aarch64_fpu_union
+ 0, aarch64v_union_fields
+ 1},
1294 {"s", aarch64_fpu_union
+ 1, aarch64v_union_fields
+ 2},
1295 {"h", aarch64_fpu_union
+ 2, aarch64v_union_fields
+ 3},
1296 {"b", aarch64_fpu_union
+ 3, aarch64v_union_fields
+ 4},
1297 {"q", aarch64_fpu_union
+ 4, NULL
},
1300 static struct reg_data_type_union aarch64v_union
[] = {
1301 {aarch64v_union_fields
}
1304 static struct reg_data_type aarch64v
[] = {
1305 {REG_TYPE_ARCH_DEFINED
, "aarch64v", REG_TYPE_CLASS_UNION
,
1306 {.reg_type_union
= aarch64v_union
} },
1309 static struct reg_data_type_bitfield aarch64_cpsr_bits
[] = {
1310 { 0, 0, REG_TYPE_UINT8
},
1311 { 2, 3, REG_TYPE_UINT8
},
1312 { 4, 4, REG_TYPE_UINT8
},
1313 { 6, 6, REG_TYPE_BOOL
},
1314 { 7, 7, REG_TYPE_BOOL
},
1315 { 8, 8, REG_TYPE_BOOL
},
1316 { 9, 9, REG_TYPE_BOOL
},
1317 { 20, 20, REG_TYPE_BOOL
},
1318 { 21, 21, REG_TYPE_BOOL
},
1319 { 28, 28, REG_TYPE_BOOL
},
1320 { 29, 29, REG_TYPE_BOOL
},
1321 { 30, 30, REG_TYPE_BOOL
},
1322 { 31, 31, REG_TYPE_BOOL
},
1325 static struct reg_data_type_flags_field aarch64_cpsr_fields
[] = {
1326 { "SP", aarch64_cpsr_bits
+ 0, aarch64_cpsr_fields
+ 1 },
1327 { "EL", aarch64_cpsr_bits
+ 1, aarch64_cpsr_fields
+ 2 },
1328 { "nRW", aarch64_cpsr_bits
+ 2, aarch64_cpsr_fields
+ 3 },
1329 { "F", aarch64_cpsr_bits
+ 3, aarch64_cpsr_fields
+ 4 },
1330 { "I", aarch64_cpsr_bits
+ 4, aarch64_cpsr_fields
+ 5 },
1331 { "A", aarch64_cpsr_bits
+ 5, aarch64_cpsr_fields
+ 6 },
1332 { "D", aarch64_cpsr_bits
+ 6, aarch64_cpsr_fields
+ 7 },
1333 { "IL", aarch64_cpsr_bits
+ 7, aarch64_cpsr_fields
+ 8 },
1334 { "SS", aarch64_cpsr_bits
+ 8, aarch64_cpsr_fields
+ 9 },
1335 { "V", aarch64_cpsr_bits
+ 9, aarch64_cpsr_fields
+ 10 },
1336 { "C", aarch64_cpsr_bits
+ 10, aarch64_cpsr_fields
+ 11 },
1337 { "Z", aarch64_cpsr_bits
+ 11, aarch64_cpsr_fields
+ 12 },
1338 { "N", aarch64_cpsr_bits
+ 12, NULL
}
1341 static struct reg_data_type_flags aarch64_cpsr_flags
[] = {
1342 { 4, aarch64_cpsr_fields
}
1345 static struct reg_data_type aarch64_flags_cpsr
[] = {
1346 {REG_TYPE_ARCH_DEFINED
, "cpsr_flags", REG_TYPE_CLASS_FLAGS
,
1347 {.reg_type_flags
= aarch64_cpsr_flags
} },
1350 static const struct {
1357 const char *feature
;
1358 struct reg_data_type
*data_type
;
1360 { ARMV8_R0
, "x0", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1361 { ARMV8_R1
, "x1", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1362 { ARMV8_R2
, "x2", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1363 { ARMV8_R3
, "x3", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1364 { ARMV8_R4
, "x4", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1365 { ARMV8_R5
, "x5", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1366 { ARMV8_R6
, "x6", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1367 { ARMV8_R7
, "x7", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1368 { ARMV8_R8
, "x8", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1369 { ARMV8_R9
, "x9", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1370 { ARMV8_R10
, "x10", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1371 { ARMV8_R11
, "x11", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1372 { ARMV8_R12
, "x12", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1373 { ARMV8_R13
, "x13", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1374 { ARMV8_R14
, "x14", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1375 { ARMV8_R15
, "x15", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1376 { ARMV8_R16
, "x16", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1377 { ARMV8_R17
, "x17", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1378 { ARMV8_R18
, "x18", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1379 { ARMV8_R19
, "x19", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1380 { ARMV8_R20
, "x20", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1381 { ARMV8_R21
, "x21", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1382 { ARMV8_R22
, "x22", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1383 { ARMV8_R23
, "x23", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1384 { ARMV8_R24
, "x24", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1385 { ARMV8_R25
, "x25", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1386 { ARMV8_R26
, "x26", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1387 { ARMV8_R27
, "x27", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1388 { ARMV8_R28
, "x28", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1389 { ARMV8_R29
, "x29", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1390 { ARMV8_R30
, "x30", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1392 { ARMV8_SP
, "sp", 64, ARM_MODE_ANY
, REG_TYPE_DATA_PTR
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1393 { ARMV8_PC
, "pc", 64, ARM_MODE_ANY
, REG_TYPE_CODE_PTR
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1394 { ARMV8_XPSR
, "cpsr", 32, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
,
1395 "general", "org.gnu.gdb.aarch64.core", aarch64_flags_cpsr
},
1396 { ARMV8_V0
, "v0", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1397 { ARMV8_V1
, "v1", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1398 { ARMV8_V2
, "v2", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1399 { ARMV8_V3
, "v3", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1400 { ARMV8_V4
, "v4", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1401 { ARMV8_V5
, "v5", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1402 { ARMV8_V6
, "v6", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1403 { ARMV8_V7
, "v7", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1404 { ARMV8_V8
, "v8", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1405 { ARMV8_V9
, "v9", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1406 { ARMV8_V10
, "v10", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1407 { ARMV8_V11
, "v11", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1408 { ARMV8_V12
, "v12", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1409 { ARMV8_V13
, "v13", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1410 { ARMV8_V14
, "v14", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1411 { ARMV8_V15
, "v15", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1412 { ARMV8_V16
, "v16", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1413 { ARMV8_V17
, "v17", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1414 { ARMV8_V18
, "v18", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1415 { ARMV8_V19
, "v19", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1416 { ARMV8_V20
, "v20", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1417 { ARMV8_V21
, "v21", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1418 { ARMV8_V22
, "v22", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1419 { ARMV8_V23
, "v23", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1420 { ARMV8_V24
, "v24", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1421 { ARMV8_V25
, "v25", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1422 { ARMV8_V26
, "v26", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1423 { ARMV8_V27
, "v27", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1424 { ARMV8_V28
, "v28", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1425 { ARMV8_V29
, "v29", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1426 { ARMV8_V30
, "v30", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1427 { ARMV8_V31
, "v31", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1428 { ARMV8_FPSR
, "fpsr", 32, ARM_MODE_ANY
, REG_TYPE_UINT32
, "simdfp", "org.gnu.gdb.aarch64.fpu", NULL
},
1429 { ARMV8_FPCR
, "fpcr", 32, ARM_MODE_ANY
, REG_TYPE_UINT32
, "simdfp", "org.gnu.gdb.aarch64.fpu", NULL
},
1431 { ARMV8_ELR_EL1
, "ELR_EL1", 64, ARMV8_64_EL1H
, REG_TYPE_CODE_PTR
, "banked", "net.sourceforge.openocd.banked",
1433 { ARMV8_ESR_EL1
, "ESR_EL1", 32, ARMV8_64_EL1H
, REG_TYPE_UINT32
, "banked", "net.sourceforge.openocd.banked",
1435 { ARMV8_SPSR_EL1
, "SPSR_EL1", 32, ARMV8_64_EL1H
, REG_TYPE_UINT32
, "banked", "net.sourceforge.openocd.banked",
1438 { ARMV8_ELR_EL2
, "ELR_EL2", 64, ARMV8_64_EL2H
, REG_TYPE_CODE_PTR
, "banked", "net.sourceforge.openocd.banked",
1440 { ARMV8_ESR_EL2
, "ESR_EL2", 32, ARMV8_64_EL2H
, REG_TYPE_UINT32
, "banked", "net.sourceforge.openocd.banked",
1442 { ARMV8_SPSR_EL2
, "SPSR_EL2", 32, ARMV8_64_EL2H
, REG_TYPE_UINT32
, "banked", "net.sourceforge.openocd.banked",
1445 { ARMV8_ELR_EL3
, "ELR_EL3", 64, ARMV8_64_EL3H
, REG_TYPE_CODE_PTR
, "banked", "net.sourceforge.openocd.banked",
1447 { ARMV8_ESR_EL3
, "ESR_EL3", 32, ARMV8_64_EL3H
, REG_TYPE_UINT32
, "banked", "net.sourceforge.openocd.banked",
1449 { ARMV8_SPSR_EL3
, "SPSR_EL3", 32, ARMV8_64_EL3H
, REG_TYPE_UINT32
, "banked", "net.sourceforge.openocd.banked",
1451 { ARMV8_PAUTH_DMASK
, "pauth_dmask", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, NULL
, "org.gnu.gdb.aarch64.pauth", NULL
},
1452 { ARMV8_PAUTH_CMASK
, "pauth_cmask", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, NULL
, "org.gnu.gdb.aarch64.pauth", NULL
},
1455 static const struct {
1463 const char *feature
;
1464 } armv8_regs32
[] = {
1465 { ARMV8_R0
, 0, "r0", 32, ARM_MODE_ANY
, REG_TYPE_UINT32
, "general", "org.gnu.gdb.arm.core" },
1466 { ARMV8_R1
, 0, "r1", 32, ARM_MODE_ANY
, REG_TYPE_UINT32
, "general", "org.gnu.gdb.arm.core" },
1467 { ARMV8_R2
, 0, "r2", 32, ARM_MODE_ANY
, REG_TYPE_UINT32
, "general", "org.gnu.gdb.arm.core" },
1468 { ARMV8_R3
, 0, "r3", 32, ARM_MODE_ANY
, REG_TYPE_UINT32
, "general", "org.gnu.gdb.arm.core" },
1469 { ARMV8_R4
, 0, "r4", 32, ARM_MODE_ANY
, REG_TYPE_UINT32
, "general", "org.gnu.gdb.arm.core" },
1470 { ARMV8_R5
, 0, "r5", 32, ARM_MODE_ANY
, REG_TYPE_UINT32
, "general", "org.gnu.gdb.arm.core" },
1471 { ARMV8_R6
, 0, "r6", 32, ARM_MODE_ANY
, REG_TYPE_UINT32
, "general", "org.gnu.gdb.arm.core" },
1472 { ARMV8_R7
, 0, "r7", 32, ARM_MODE_ANY
, REG_TYPE_UINT32
, "general", "org.gnu.gdb.arm.core" },
1473 { ARMV8_R8
, 0, "r8", 32, ARM_MODE_ANY
, REG_TYPE_UINT32
, "general", "org.gnu.gdb.arm.core" },
1474 { ARMV8_R9
, 0, "r9", 32, ARM_MODE_ANY
, REG_TYPE_UINT32
, "general", "org.gnu.gdb.arm.core" },
1475 { ARMV8_R10
, 0, "r10", 32, ARM_MODE_ANY
, REG_TYPE_UINT32
, "general", "org.gnu.gdb.arm.core" },
1476 { ARMV8_R11
, 0, "r11", 32, ARM_MODE_ANY
, REG_TYPE_UINT32
, "general", "org.gnu.gdb.arm.core" },
1477 { ARMV8_R12
, 0, "r12", 32, ARM_MODE_ANY
, REG_TYPE_UINT32
, "general", "org.gnu.gdb.arm.core" },
1478 { ARMV8_R13
, 0, "sp", 32, ARM_MODE_ANY
, REG_TYPE_DATA_PTR
, "general", "org.gnu.gdb.arm.core" },
1479 { ARMV8_R14
, 0, "lr", 32, ARM_MODE_ANY
, REG_TYPE_CODE_PTR
, "general", "org.gnu.gdb.arm.core" },
1480 { ARMV8_PC
, 0, "pc", 32, ARM_MODE_ANY
, REG_TYPE_CODE_PTR
, "general", "org.gnu.gdb.arm.core" },
1481 { ARMV8_XPSR
, 0, "cpsr", 32, ARM_MODE_ANY
, REG_TYPE_UINT32
, "general", "org.gnu.gdb.arm.core" },
1482 { ARMV8_V0
, 0, "d0", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1483 { ARMV8_V0
, 8, "d1", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1484 { ARMV8_V1
, 0, "d2", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1485 { ARMV8_V1
, 8, "d3", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1486 { ARMV8_V2
, 0, "d4", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1487 { ARMV8_V2
, 8, "d5", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1488 { ARMV8_V3
, 0, "d6", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1489 { ARMV8_V3
, 8, "d7", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1490 { ARMV8_V4
, 0, "d8", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1491 { ARMV8_V4
, 8, "d9", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1492 { ARMV8_V5
, 0, "d10", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1493 { ARMV8_V5
, 8, "d11", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1494 { ARMV8_V6
, 0, "d12", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1495 { ARMV8_V6
, 8, "d13", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1496 { ARMV8_V7
, 0, "d14", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1497 { ARMV8_V7
, 8, "d15", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1498 { ARMV8_V8
, 0, "d16", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1499 { ARMV8_V8
, 8, "d17", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1500 { ARMV8_V9
, 0, "d18", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1501 { ARMV8_V9
, 8, "d19", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1502 { ARMV8_V10
, 0, "d20", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1503 { ARMV8_V10
, 8, "d21", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1504 { ARMV8_V11
, 0, "d22", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1505 { ARMV8_V11
, 8, "d23", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1506 { ARMV8_V12
, 0, "d24", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1507 { ARMV8_V12
, 8, "d25", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1508 { ARMV8_V13
, 0, "d26", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1509 { ARMV8_V13
, 8, "d27", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1510 { ARMV8_V14
, 0, "d28", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1511 { ARMV8_V14
, 8, "d29", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1512 { ARMV8_V15
, 0, "d30", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1513 { ARMV8_V15
, 8, "d31", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1514 { ARMV8_FPSR
, 0, "fpscr", 32, ARM_MODE_ANY
, REG_TYPE_UINT32
, "float", "org.gnu.gdb.arm.vfp"},
1517 #define ARMV8_NUM_REGS ARRAY_SIZE(armv8_regs)
1518 #define ARMV8_NUM_REGS32 ARRAY_SIZE(armv8_regs32)
1520 static int armv8_get_core_reg(struct reg
*reg
)
1522 struct arm_reg
*armv8_reg
= reg
->arch_info
;
1523 struct target
*target
= armv8_reg
->target
;
1524 struct arm
*arm
= target_to_arm(target
);
1526 if (target
->state
!= TARGET_HALTED
)
1527 return ERROR_TARGET_NOT_HALTED
;
1529 return arm
->read_core_reg(target
, reg
, armv8_reg
->num
, arm
->core_mode
);
1532 static int armv8_set_core_reg(struct reg
*reg
, uint8_t *buf
)
1534 struct arm_reg
*armv8_reg
= reg
->arch_info
;
1535 struct target
*target
= armv8_reg
->target
;
1536 struct arm
*arm
= target_to_arm(target
);
1537 uint64_t value
= buf_get_u64(buf
, 0, reg
->size
);
1539 if (target
->state
!= TARGET_HALTED
)
1540 return ERROR_TARGET_NOT_HALTED
;
1542 if (reg
->size
<= 64) {
1543 if (reg
== arm
->cpsr
)
1544 armv8_set_cpsr(arm
, (uint32_t)value
);
1546 buf_set_u64(reg
->value
, 0, reg
->size
, value
);
1549 } else if (reg
->size
<= 128) {
1550 uint64_t hvalue
= buf_get_u64(buf
+ 8, 0, reg
->size
- 64);
1552 buf_set_u64(reg
->value
, 0, 64, value
);
1553 buf_set_u64(reg
->value
+ 8, 0, reg
->size
- 64, hvalue
);
1562 static const struct reg_arch_type armv8_reg_type
= {
1563 .get
= armv8_get_core_reg
,
1564 .set
= armv8_set_core_reg
,
1567 static int armv8_get_core_reg32(struct reg
*reg
)
1569 struct arm_reg
*armv8_reg
= reg
->arch_info
;
1570 struct target
*target
= armv8_reg
->target
;
1571 struct arm
*arm
= target_to_arm(target
);
1572 struct reg_cache
*cache
= arm
->core_cache
;
1576 if (target
->state
!= TARGET_HALTED
)
1577 return ERROR_TARGET_NOT_HALTED
;
1579 /* get the corresponding Aarch64 register */
1580 reg64
= cache
->reg_list
+ armv8_reg
->num
;
1586 retval
= arm
->read_core_reg(target
, reg64
, armv8_reg
->num
, arm
->core_mode
);
1587 if (retval
== ERROR_OK
)
1588 reg
->valid
= reg64
->valid
;
1593 static int armv8_set_core_reg32(struct reg
*reg
, uint8_t *buf
)
1595 struct arm_reg
*armv8_reg
= reg
->arch_info
;
1596 struct target
*target
= armv8_reg
->target
;
1597 struct arm
*arm
= target_to_arm(target
);
1598 struct reg_cache
*cache
= arm
->core_cache
;
1599 struct reg
*reg64
= cache
->reg_list
+ armv8_reg
->num
;
1600 uint32_t value
= buf_get_u32(buf
, 0, 32);
1602 if (target
->state
!= TARGET_HALTED
)
1603 return ERROR_TARGET_NOT_HALTED
;
1605 if (reg64
== arm
->cpsr
) {
1606 armv8_set_cpsr(arm
, value
);
1608 if (reg
->size
<= 32)
1609 buf_set_u32(reg
->value
, 0, 32, value
);
1610 else if (reg
->size
<= 64) {
1611 uint64_t value64
= buf_get_u64(buf
, 0, 64);
1612 buf_set_u64(reg
->value
, 0, 64, value64
);
1615 reg64
->valid
= true;
1618 reg64
->dirty
= true;
1623 static const struct reg_arch_type armv8_reg32_type
= {
1624 .get
= armv8_get_core_reg32
,
1625 .set
= armv8_set_core_reg32
,
1628 /** Builds cache of architecturally defined registers. */
1629 struct reg_cache
*armv8_build_reg_cache(struct target
*target
)
1631 struct armv8_common
*armv8
= target_to_armv8(target
);
1632 struct arm
*arm
= &armv8
->arm
;
1633 int num_regs
= ARMV8_NUM_REGS
;
1634 int num_regs32
= ARMV8_NUM_REGS32
;
1635 struct reg_cache
**cache_p
= register_get_last_cache_p(&target
->reg_cache
);
1636 struct reg_cache
*cache
= malloc(sizeof(struct reg_cache
));
1637 struct reg_cache
*cache32
= malloc(sizeof(struct reg_cache
));
1638 struct reg
*reg_list
= calloc(num_regs
, sizeof(struct reg
));
1639 struct reg
*reg_list32
= calloc(num_regs32
, sizeof(struct reg
));
1640 struct arm_reg
*arch_info
= calloc(num_regs
, sizeof(struct arm_reg
));
1641 struct reg_feature
*feature
;
1644 /* Build the process context cache */
1645 cache
->name
= "Aarch64 registers";
1646 cache
->next
= cache32
;
1647 cache
->reg_list
= reg_list
;
1648 cache
->num_regs
= num_regs
;
1650 for (i
= 0; i
< num_regs
; i
++) {
1651 arch_info
[i
].num
= armv8_regs
[i
].id
;
1652 arch_info
[i
].mode
= armv8_regs
[i
].mode
;
1653 arch_info
[i
].target
= target
;
1654 arch_info
[i
].arm
= arm
;
1656 reg_list
[i
].name
= armv8_regs
[i
].name
;
1657 reg_list
[i
].size
= armv8_regs
[i
].bits
;
1658 reg_list
[i
].value
= &arch_info
[i
].value
[0];
1659 reg_list
[i
].type
= &armv8_reg_type
;
1660 reg_list
[i
].arch_info
= &arch_info
[i
];
1662 reg_list
[i
].group
= armv8_regs
[i
].group
;
1663 reg_list
[i
].number
= i
;
1664 reg_list
[i
].exist
= true;
1665 reg_list
[i
].caller_save
= true; /* gdb defaults to true */
1667 feature
= calloc(1, sizeof(struct reg_feature
));
1669 feature
->name
= armv8_regs
[i
].feature
;
1670 reg_list
[i
].feature
= feature
;
1672 LOG_ERROR("unable to allocate feature list");
1674 reg_list
[i
].reg_data_type
= calloc(1, sizeof(struct reg_data_type
));
1675 if (reg_list
[i
].reg_data_type
) {
1676 if (!armv8_regs
[i
].data_type
)
1677 reg_list
[i
].reg_data_type
->type
= armv8_regs
[i
].type
;
1679 *reg_list
[i
].reg_data_type
= *armv8_regs
[i
].data_type
;
1681 LOG_ERROR("unable to allocate reg type list");
1683 if (i
== ARMV8_PAUTH_CMASK
|| i
== ARMV8_PAUTH_DMASK
)
1684 reg_list
[i
].hidden
= !armv8
->enable_pauth
;
1687 arm
->cpsr
= reg_list
+ ARMV8_XPSR
;
1688 arm
->pc
= reg_list
+ ARMV8_PC
;
1689 arm
->core_cache
= cache
;
1691 /* shadow cache for ARM mode registers */
1692 cache32
->name
= "Aarch32 registers";
1693 cache32
->next
= NULL
;
1694 cache32
->reg_list
= reg_list32
;
1695 cache32
->num_regs
= num_regs32
;
1697 for (i
= 0; i
< num_regs32
; i
++) {
1698 reg_list32
[i
].name
= armv8_regs32
[i
].name
;
1699 reg_list32
[i
].size
= armv8_regs32
[i
].bits
;
1700 reg_list32
[i
].value
= &arch_info
[armv8_regs32
[i
].id
].value
[armv8_regs32
[i
].mapping
];
1701 reg_list32
[i
].type
= &armv8_reg32_type
;
1702 reg_list32
[i
].arch_info
= &arch_info
[armv8_regs32
[i
].id
];
1703 reg_list32
[i
].group
= armv8_regs32
[i
].group
;
1704 reg_list32
[i
].number
= i
;
1705 reg_list32
[i
].exist
= true;
1706 reg_list32
[i
].caller_save
= true;
1708 feature
= calloc(1, sizeof(struct reg_feature
));
1710 feature
->name
= armv8_regs32
[i
].feature
;
1711 reg_list32
[i
].feature
= feature
;
1713 LOG_ERROR("unable to allocate feature list");
1715 reg_list32
[i
].reg_data_type
= calloc(1, sizeof(struct reg_data_type
));
1716 if (reg_list32
[i
].reg_data_type
)
1717 reg_list32
[i
].reg_data_type
->type
= armv8_regs32
[i
].type
;
1719 LOG_ERROR("unable to allocate reg type list");
1726 struct reg
*armv8_reg_current(struct arm
*arm
, unsigned regnum
)
1730 if (regnum
> (ARMV8_LAST_REG
- 1))
1733 r
= arm
->core_cache
->reg_list
+ regnum
;
1737 static void armv8_free_cache(struct reg_cache
*cache
, bool regs32
)
1745 for (i
= 0; i
< cache
->num_regs
; i
++) {
1746 reg
= &cache
->reg_list
[i
];
1749 free(reg
->reg_data_type
);
1753 free(cache
->reg_list
[0].arch_info
);
1754 free(cache
->reg_list
);
1758 void armv8_free_reg_cache(struct target
*target
)
1760 struct armv8_common
*armv8
= target_to_armv8(target
);
1761 struct arm
*arm
= &armv8
->arm
;
1762 struct reg_cache
*cache
= NULL
, *cache32
= NULL
;
1764 cache
= arm
->core_cache
;
1766 cache32
= cache
->next
;
1767 armv8_free_cache(cache32
, true);
1768 armv8_free_cache(cache
, false);
1769 arm
->core_cache
= NULL
;
1772 const struct command_registration armv8_command_handlers
[] = {
1774 .name
= "catch_exc",
1775 .handler
= armv8_handle_exception_catch_command
,
1776 .mode
= COMMAND_EXEC
,
1777 .help
= "configure exception catch",
1778 .usage
= "[(nsec_el1,nsec_el2,sec_el1,sec_el3)+,off]",
1782 .handler
= armv8_pauth_command
,
1783 .mode
= COMMAND_CONFIG
,
1784 .help
= "enable or disable providing GDB with an 8-bytes mask to "
1785 "remove signature bits added by pointer authentication."
1786 "Pointer authentication feature is broken until gdb 12.1, going to be fixed. "
1787 "Consider using a newer version of gdb if you want enable "
1789 .usage
= "[on|off]",
1791 COMMAND_REGISTRATION_DONE
1794 const char *armv8_get_gdb_arch(struct target
*target
)
1796 struct arm
*arm
= target_to_arm(target
);
1797 return arm
->core_state
== ARM_STATE_AARCH64
? "aarch64" : "arm";
1800 int armv8_get_gdb_reg_list(struct target
*target
,
1801 struct reg
**reg_list
[], int *reg_list_size
,
1802 enum target_register_class reg_class
)
1804 struct arm
*arm
= target_to_arm(target
);
1807 if (arm
->core_state
== ARM_STATE_AARCH64
) {
1809 LOG_DEBUG("Creating Aarch64 register list for target %s", target_name(target
));
1811 switch (reg_class
) {
1812 case REG_CLASS_GENERAL
:
1813 *reg_list_size
= ARMV8_V0
;
1814 *reg_list
= malloc(sizeof(struct reg
*) * (*reg_list_size
));
1816 for (i
= 0; i
< *reg_list_size
; i
++)
1817 (*reg_list
)[i
] = armv8_reg_current(arm
, i
);
1821 *reg_list_size
= ARMV8_LAST_REG
;
1822 *reg_list
= malloc(sizeof(struct reg
*) * (*reg_list_size
));
1824 for (i
= 0; i
< *reg_list_size
; i
++)
1825 (*reg_list
)[i
] = armv8_reg_current(arm
, i
);
1830 LOG_ERROR("not a valid register class type in query.");
1834 struct reg_cache
*cache32
= arm
->core_cache
->next
;
1836 LOG_DEBUG("Creating Aarch32 register list for target %s", target_name(target
));
1838 switch (reg_class
) {
1839 case REG_CLASS_GENERAL
:
1840 *reg_list_size
= ARMV8_R14
+ 3;
1841 *reg_list
= malloc(sizeof(struct reg
*) * (*reg_list_size
));
1843 for (i
= 0; i
< *reg_list_size
; i
++)
1844 (*reg_list
)[i
] = cache32
->reg_list
+ i
;
1848 *reg_list_size
= cache32
->num_regs
;
1849 *reg_list
= malloc(sizeof(struct reg
*) * (*reg_list_size
));
1851 for (i
= 0; i
< *reg_list_size
; i
++)
1852 (*reg_list
)[i
] = cache32
->reg_list
+ i
;
1856 LOG_ERROR("not a valid register class type in query.");
1862 int armv8_set_dbgreg_bits(struct armv8_common
*armv8
, unsigned int reg
, unsigned long mask
, unsigned long value
)
1867 int retval
= mem_ap_read_atomic_u32(armv8
->debug_ap
,
1868 armv8
->debug_base
+ reg
, &tmp
);
1869 if (retval
!= ERROR_OK
)
1872 /* clear bitfield */
1875 tmp
|= value
& mask
;
1877 /* write new value */
1878 retval
= mem_ap_write_atomic_u32(armv8
->debug_ap
,
1879 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)