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>
22 #include <helper/nvp.h>
28 #include "armv8_opcodes.h"
30 #include "target_type.h"
31 #include "semihosting_common.h"
33 static const char * const armv8_state_strings
[] = {
34 "AArch32", "Thumb", "Jazelle", "ThumbEE", "AArch64",
40 } armv8_mode_data
[] = {
103 .psr
= ARMV8_64_EL3H
,
107 /** Map PSR mode bits to the name of an ARM processor operating mode. */
108 const char *armv8_mode_name(unsigned psr_mode
)
110 for (unsigned i
= 0; i
< ARRAY_SIZE(armv8_mode_data
); i
++) {
111 if (armv8_mode_data
[i
].psr
== psr_mode
)
112 return armv8_mode_data
[i
].name
;
114 LOG_ERROR("unrecognized psr mode: %#02x", psr_mode
);
115 return "UNRECOGNIZED";
118 static uint8_t armv8_pa_size(uint32_t ps
)
141 LOG_INFO("Unknown physical address size");
147 static __attribute__((unused
)) int armv8_read_ttbcr32(struct target
*target
)
149 struct armv8_common
*armv8
= target_to_armv8(target
);
150 struct arm_dpm
*dpm
= armv8
->arm
.dpm
;
151 uint32_t ttbcr
, ttbcr_n
;
152 int retval
= dpm
->prepare(dpm
);
153 if (retval
!= ERROR_OK
)
155 /* MRC p15,0,<Rt>,c2,c0,2 ; Read CP15 Translation Table Base Control Register*/
156 retval
= dpm
->instr_read_data_r0(dpm
,
157 ARMV4_5_MRC(15, 0, 0, 2, 0, 2),
159 if (retval
!= ERROR_OK
)
162 LOG_DEBUG("ttbcr %" PRIx32
, ttbcr
);
164 ttbcr_n
= ttbcr
& 0x7;
165 armv8
->armv8_mmu
.ttbcr
= ttbcr
;
168 * ARM Architecture Reference Manual (ARMv7-A and ARMv7-R edition),
169 * document # ARM DDI 0406C
171 armv8
->armv8_mmu
.ttbr_range
[0] = 0xffffffff >> ttbcr_n
;
172 armv8
->armv8_mmu
.ttbr_range
[1] = 0xffffffff;
173 armv8
->armv8_mmu
.ttbr_mask
[0] = 0xffffffff << (14 - ttbcr_n
);
174 armv8
->armv8_mmu
.ttbr_mask
[1] = 0xffffffff << 14;
176 LOG_DEBUG("ttbr1 %s, ttbr0_mask %" PRIx32
" ttbr1_mask %" PRIx32
,
177 (ttbcr_n
!= 0) ? "used" : "not used",
178 armv8
->armv8_mmu
.ttbr_mask
[0],
179 armv8
->armv8_mmu
.ttbr_mask
[1]);
186 static int armv8_read_ttbcr(struct target
*target
)
188 struct armv8_common
*armv8
= target_to_armv8(target
);
189 struct arm_dpm
*dpm
= armv8
->arm
.dpm
;
190 struct arm
*arm
= &armv8
->arm
;
194 int retval
= dpm
->prepare(dpm
);
195 if (retval
!= ERROR_OK
)
198 /* clear ttrr1_used and ttbr0_mask */
199 memset(&armv8
->armv8_mmu
.ttbr1_used
, 0, sizeof(armv8
->armv8_mmu
.ttbr1_used
));
200 memset(&armv8
->armv8_mmu
.ttbr0_mask
, 0, sizeof(armv8
->armv8_mmu
.ttbr0_mask
));
202 switch (armv8_curel_from_core_mode(arm
->core_mode
)) {
203 case SYSTEM_CUREL_EL3
:
204 retval
= dpm
->instr_read_data_r0(dpm
,
205 ARMV8_MRS(SYSTEM_TCR_EL3
, 0),
207 retval
+= dpm
->instr_read_data_r0_64(dpm
,
208 ARMV8_MRS(SYSTEM_TTBR0_EL3
, 0),
210 if (retval
!= ERROR_OK
)
212 armv8
->va_size
= 64 - (ttbcr
& 0x3F);
213 armv8
->pa_size
= armv8_pa_size((ttbcr
>> 16) & 7);
214 armv8
->page_size
= (ttbcr
>> 14) & 3;
216 case SYSTEM_CUREL_EL2
:
217 retval
= dpm
->instr_read_data_r0(dpm
,
218 ARMV8_MRS(SYSTEM_TCR_EL2
, 0),
220 retval
+= dpm
->instr_read_data_r0_64(dpm
,
221 ARMV8_MRS(SYSTEM_TTBR0_EL2
, 0),
223 if (retval
!= ERROR_OK
)
225 armv8
->va_size
= 64 - (ttbcr
& 0x3F);
226 armv8
->pa_size
= armv8_pa_size((ttbcr
>> 16) & 7);
227 armv8
->page_size
= (ttbcr
>> 14) & 3;
229 case SYSTEM_CUREL_EL0
:
230 armv8_dpm_modeswitch(dpm
, ARMV8_64_EL1H
);
232 case SYSTEM_CUREL_EL1
:
233 retval
= dpm
->instr_read_data_r0_64(dpm
,
234 ARMV8_MRS(SYSTEM_TCR_EL1
, 0),
236 armv8
->va_size
= 64 - (ttbcr_64
& 0x3F);
237 armv8
->pa_size
= armv8_pa_size((ttbcr_64
>> 32) & 7);
238 armv8
->page_size
= (ttbcr_64
>> 14) & 3;
239 armv8
->armv8_mmu
.ttbr1_used
= (((ttbcr_64
>> 16) & 0x3F) != 0) ? 1 : 0;
240 armv8
->armv8_mmu
.ttbr0_mask
= 0x0000FFFFFFFFFFFFULL
;
241 retval
+= dpm
->instr_read_data_r0_64(dpm
,
242 ARMV8_MRS(SYSTEM_TTBR0_EL1
| (armv8
->armv8_mmu
.ttbr1_used
), 0),
244 if (retval
!= ERROR_OK
)
248 LOG_ERROR("unknown core state");
252 if (retval
!= ERROR_OK
)
255 if (armv8
->armv8_mmu
.ttbr1_used
== 1)
256 LOG_INFO("TTBR0 access above %" PRIx64
, (uint64_t)(armv8
->armv8_mmu
.ttbr0_mask
));
259 armv8_dpm_modeswitch(dpm
, ARM_MODE_ANY
);
264 static int armv8_get_pauth_mask(struct armv8_common
*armv8
, uint64_t *mask
)
266 struct arm
*arm
= &armv8
->arm
;
267 int retval
= ERROR_OK
;
268 if (armv8
->va_size
== 0)
269 retval
= armv8_read_ttbcr(arm
->target
);
270 if (retval
!= ERROR_OK
)
273 *mask
= ~(((uint64_t)1 << armv8
->va_size
) - 1);
278 static int armv8_read_reg(struct armv8_common
*armv8
, int regnum
, uint64_t *regval
)
280 struct arm_dpm
*dpm
= &armv8
->dpm
;
287 retval
= dpm
->instr_read_data_dcc_64(dpm
,
288 ARMV8_MSR_GP(SYSTEM_DBG_DBGDTR_EL0
, regnum
), &value_64
);
291 retval
= dpm
->instr_read_data_r0_64(dpm
,
292 ARMV8_MOVFSP_64(0), &value_64
);
295 retval
= dpm
->instr_read_data_r0_64(dpm
,
296 ARMV8_MRS_DLR(0), &value_64
);
299 retval
= dpm
->instr_read_data_r0(dpm
,
300 ARMV8_MRS_DSPSR(0), &value
);
304 retval
= dpm
->instr_read_data_r0(dpm
,
305 ARMV8_MRS_FPSR(0), &value
);
309 retval
= dpm
->instr_read_data_r0(dpm
,
310 ARMV8_MRS_FPCR(0), &value
);
314 retval
= dpm
->instr_read_data_r0_64(dpm
,
315 ARMV8_MRS(SYSTEM_ELR_EL1
, 0), &value_64
);
318 retval
= dpm
->instr_read_data_r0_64(dpm
,
319 ARMV8_MRS(SYSTEM_ELR_EL2
, 0), &value_64
);
322 retval
= dpm
->instr_read_data_r0_64(dpm
,
323 ARMV8_MRS(SYSTEM_ELR_EL3
, 0), &value_64
);
326 retval
= dpm
->instr_read_data_r0(dpm
,
327 ARMV8_MRS(SYSTEM_ESR_EL1
, 0), &value
);
331 retval
= dpm
->instr_read_data_r0(dpm
,
332 ARMV8_MRS(SYSTEM_ESR_EL2
, 0), &value
);
336 retval
= dpm
->instr_read_data_r0(dpm
,
337 ARMV8_MRS(SYSTEM_ESR_EL3
, 0), &value
);
341 retval
= dpm
->instr_read_data_r0(dpm
,
342 ARMV8_MRS(SYSTEM_SPSR_EL1
, 0), &value
);
346 retval
= dpm
->instr_read_data_r0(dpm
,
347 ARMV8_MRS(SYSTEM_SPSR_EL2
, 0), &value
);
351 retval
= dpm
->instr_read_data_r0(dpm
,
352 ARMV8_MRS(SYSTEM_SPSR_EL3
, 0), &value
);
355 case ARMV8_PAUTH_CMASK
:
356 case ARMV8_PAUTH_DMASK
:
357 retval
= armv8_get_pauth_mask(armv8
, &value_64
);
364 if (retval
== ERROR_OK
&& regval
)
372 static int armv8_read_reg_simdfp_aarch64(struct armv8_common
*armv8
, int regnum
, uint64_t *lvalue
, uint64_t *hvalue
)
374 int retval
= ERROR_FAIL
;
375 struct arm_dpm
*dpm
= &armv8
->dpm
;
378 case ARMV8_V0
... ARMV8_V31
:
379 retval
= dpm
->instr_read_data_r0_64(dpm
,
380 ARMV8_MOV_GPR_VFP(0, (regnum
- ARMV8_V0
), 1), hvalue
);
381 if (retval
!= ERROR_OK
)
383 retval
= dpm
->instr_read_data_r0_64(dpm
,
384 ARMV8_MOV_GPR_VFP(0, (regnum
- ARMV8_V0
), 0), lvalue
);
395 static int armv8_write_reg(struct armv8_common
*armv8
, int regnum
, uint64_t value_64
)
397 struct arm_dpm
*dpm
= &armv8
->dpm
;
403 retval
= dpm
->instr_write_data_dcc_64(dpm
,
404 ARMV8_MRS(SYSTEM_DBG_DBGDTR_EL0
, regnum
),
408 retval
= dpm
->instr_write_data_r0_64(dpm
,
413 retval
= dpm
->instr_write_data_r0_64(dpm
,
419 retval
= dpm
->instr_write_data_r0(dpm
,
425 retval
= dpm
->instr_write_data_r0(dpm
,
431 retval
= dpm
->instr_write_data_r0(dpm
,
435 /* registers clobbered by taking exception in debug state */
437 retval
= dpm
->instr_write_data_r0_64(dpm
,
438 ARMV8_MSR_GP(SYSTEM_ELR_EL1
, 0), value_64
);
441 retval
= dpm
->instr_write_data_r0_64(dpm
,
442 ARMV8_MSR_GP(SYSTEM_ELR_EL2
, 0), value_64
);
445 retval
= dpm
->instr_write_data_r0_64(dpm
,
446 ARMV8_MSR_GP(SYSTEM_ELR_EL3
, 0), value_64
);
450 retval
= dpm
->instr_write_data_r0(dpm
,
451 ARMV8_MSR_GP(SYSTEM_ESR_EL1
, 0), value
);
455 retval
= dpm
->instr_write_data_r0(dpm
,
456 ARMV8_MSR_GP(SYSTEM_ESR_EL2
, 0), value
);
460 retval
= dpm
->instr_write_data_r0(dpm
,
461 ARMV8_MSR_GP(SYSTEM_ESR_EL3
, 0), value
);
465 retval
= dpm
->instr_write_data_r0(dpm
,
466 ARMV8_MSR_GP(SYSTEM_SPSR_EL1
, 0), value
);
470 retval
= dpm
->instr_write_data_r0(dpm
,
471 ARMV8_MSR_GP(SYSTEM_SPSR_EL2
, 0), value
);
475 retval
= dpm
->instr_write_data_r0(dpm
,
476 ARMV8_MSR_GP(SYSTEM_SPSR_EL3
, 0), value
);
486 static int armv8_write_reg_simdfp_aarch64(struct armv8_common
*armv8
, int regnum
, uint64_t lvalue
, uint64_t hvalue
)
488 int retval
= ERROR_FAIL
;
489 struct arm_dpm
*dpm
= &armv8
->dpm
;
492 case ARMV8_V0
... ARMV8_V31
:
493 retval
= dpm
->instr_write_data_r0_64(dpm
,
494 ARMV8_MOV_VFP_GPR((regnum
- ARMV8_V0
), 0, 1), hvalue
);
495 if (retval
!= ERROR_OK
)
497 retval
= dpm
->instr_write_data_r0_64(dpm
,
498 ARMV8_MOV_VFP_GPR((regnum
- ARMV8_V0
), 0, 0), lvalue
);
509 static int armv8_read_reg32(struct armv8_common
*armv8
, int regnum
, uint64_t *regval
)
511 struct arm_dpm
*dpm
= &armv8
->dpm
;
516 case ARMV8_R0
... ARMV8_R14
:
517 /* return via DCC: "MCR p14, 0, Rnum, c0, c5, 0" */
518 retval
= dpm
->instr_read_data_dcc(dpm
,
519 ARMV4_5_MCR(14, 0, regnum
, 0, 5, 0),
523 retval
= dpm
->instr_read_data_dcc(dpm
,
524 ARMV4_5_MCR(14, 0, 13, 0, 5, 0),
528 retval
= dpm
->instr_read_data_r0(dpm
,
533 retval
= dpm
->instr_read_data_r0(dpm
,
537 case ARMV8_ELR_EL1
: /* mapped to LR_svc */
538 retval
= dpm
->instr_read_data_dcc(dpm
,
539 ARMV4_5_MCR(14, 0, 14, 0, 5, 0),
542 case ARMV8_ELR_EL2
: /* mapped to ELR_hyp */
543 retval
= dpm
->instr_read_data_r0(dpm
,
544 ARMV8_MRS_T1(0, 14, 0, 1),
547 case ARMV8_ELR_EL3
: /* mapped to LR_mon */
548 retval
= dpm
->instr_read_data_dcc(dpm
,
549 ARMV4_5_MCR(14, 0, 14, 0, 5, 0),
552 case ARMV8_ESR_EL1
: /* mapped to DFSR */
553 retval
= dpm
->instr_read_data_r0(dpm
,
554 ARMV4_5_MRC(15, 0, 0, 5, 0, 0),
557 case ARMV8_ESR_EL2
: /* mapped to HSR */
558 retval
= dpm
->instr_read_data_r0(dpm
,
559 ARMV4_5_MRC(15, 4, 0, 5, 2, 0),
562 case ARMV8_ESR_EL3
: /* FIXME: no equivalent in aarch32? */
565 case ARMV8_SPSR_EL1
: /* mapped to SPSR_svc */
566 retval
= dpm
->instr_read_data_r0(dpm
,
567 ARMV8_MRS_XPSR_T1(1, 0),
570 case ARMV8_SPSR_EL2
: /* mapped to SPSR_hyp */
571 retval
= dpm
->instr_read_data_r0(dpm
,
572 ARMV8_MRS_XPSR_T1(1, 0),
575 case ARMV8_SPSR_EL3
: /* mapped to SPSR_mon */
576 retval
= dpm
->instr_read_data_r0(dpm
,
577 ARMV8_MRS_XPSR_T1(1, 0),
581 /* "VMRS r0, FPSCR"; then return via DCC */
582 retval
= dpm
->instr_read_data_r0(dpm
,
583 ARMV4_5_VMRS(0), &value
);
590 if (retval
== ERROR_OK
&& regval
)
596 static int armv8_read_reg_simdfp_aarch32(struct armv8_common
*armv8
, int regnum
, uint64_t *lvalue
, uint64_t *hvalue
)
598 int retval
= ERROR_FAIL
;
599 struct arm_dpm
*dpm
= &armv8
->dpm
;
600 struct reg
*reg_r1
= dpm
->arm
->core_cache
->reg_list
+ ARMV8_R1
;
601 uint32_t value_r0
= 0, value_r1
= 0;
602 unsigned num
= (regnum
- ARMV8_V0
) << 1;
605 case ARMV8_V0
... ARMV8_V15
:
606 /* we are going to write R1, mark it dirty */
607 reg_r1
->dirty
= true;
608 /* move from double word register to r0:r1: "vmov r0, r1, vm"
609 * then read r0 via dcc
611 retval
= dpm
->instr_read_data_r0(dpm
,
612 ARMV4_5_VMOV(1, 1, 0, (num
>> 4), (num
& 0xf)),
614 if (retval
!= ERROR_OK
)
616 /* read r1 via dcc */
617 retval
= dpm
->instr_read_data_dcc(dpm
,
618 ARMV4_5_MCR(14, 0, 1, 0, 5, 0),
620 if (retval
!= ERROR_OK
)
623 *lvalue
= ((*lvalue
) << 32) | value_r0
;
626 /* repeat above steps for high 64 bits of V register */
627 retval
= dpm
->instr_read_data_r0(dpm
,
628 ARMV4_5_VMOV(1, 1, 0, (num
>> 4), (num
& 0xf)),
630 if (retval
!= ERROR_OK
)
632 retval
= dpm
->instr_read_data_dcc(dpm
,
633 ARMV4_5_MCR(14, 0, 1, 0, 5, 0),
635 if (retval
!= ERROR_OK
)
638 *hvalue
= ((*hvalue
) << 32) | value_r0
;
648 static int armv8_write_reg32(struct armv8_common
*armv8
, int regnum
, uint64_t value
)
650 struct arm_dpm
*dpm
= &armv8
->dpm
;
654 case ARMV8_R0
... ARMV8_R14
:
655 /* load register from DCC: "MRC p14, 0, Rnum, c0, c5, 0" */
656 retval
= dpm
->instr_write_data_dcc(dpm
,
657 ARMV4_5_MRC(14, 0, regnum
, 0, 5, 0), value
);
660 retval
= dpm
->instr_write_data_dcc(dpm
,
661 ARMV4_5_MRC(14, 0, 13, 0, 5, 0), value
);
664 * read r0 from DCC; then "MOV pc, r0" */
665 retval
= dpm
->instr_write_data_r0(dpm
,
666 ARMV8_MCR_DLR(0), value
);
668 case ARMV8_XPSR
: /* CPSR */
669 /* read r0 from DCC, then "MCR r0, DSPSR" */
670 retval
= dpm
->instr_write_data_r0(dpm
,
671 ARMV8_MCR_DSPSR(0), value
);
673 case ARMV8_ELR_EL1
: /* mapped to LR_svc */
674 retval
= dpm
->instr_write_data_dcc(dpm
,
675 ARMV4_5_MRC(14, 0, 14, 0, 5, 0),
678 case ARMV8_ELR_EL2
: /* mapped to ELR_hyp */
679 retval
= dpm
->instr_write_data_r0(dpm
,
680 ARMV8_MSR_GP_T1(0, 14, 0, 1),
683 case ARMV8_ELR_EL3
: /* mapped to LR_mon */
684 retval
= dpm
->instr_write_data_dcc(dpm
,
685 ARMV4_5_MRC(14, 0, 14, 0, 5, 0),
688 case ARMV8_ESR_EL1
: /* mapped to DFSR */
689 retval
= dpm
->instr_write_data_r0(dpm
,
690 ARMV4_5_MCR(15, 0, 0, 5, 0, 0),
693 case ARMV8_ESR_EL2
: /* mapped to HSR */
694 retval
= dpm
->instr_write_data_r0(dpm
,
695 ARMV4_5_MCR(15, 4, 0, 5, 2, 0),
698 case ARMV8_ESR_EL3
: /* FIXME: no equivalent in aarch32? */
701 case ARMV8_SPSR_EL1
: /* mapped to SPSR_svc */
702 retval
= dpm
->instr_write_data_r0(dpm
,
703 ARMV8_MSR_GP_XPSR_T1(1, 0, 15),
706 case ARMV8_SPSR_EL2
: /* mapped to SPSR_hyp */
707 retval
= dpm
->instr_write_data_r0(dpm
,
708 ARMV8_MSR_GP_XPSR_T1(1, 0, 15),
711 case ARMV8_SPSR_EL3
: /* mapped to SPSR_mon */
712 retval
= dpm
->instr_write_data_r0(dpm
,
713 ARMV8_MSR_GP_XPSR_T1(1, 0, 15),
717 /* move to r0 from DCC, then "VMSR FPSCR, r0" */
718 retval
= dpm
->instr_write_data_r0(dpm
,
719 ARMV4_5_VMSR(0), value
);
730 static int armv8_write_reg_simdfp_aarch32(struct armv8_common
*armv8
, int regnum
, uint64_t lvalue
, uint64_t hvalue
)
732 int retval
= ERROR_FAIL
;
733 struct arm_dpm
*dpm
= &armv8
->dpm
;
734 struct reg
*reg_r1
= dpm
->arm
->core_cache
->reg_list
+ ARMV8_R1
;
735 uint32_t value_r0
= 0, value_r1
= 0;
736 unsigned num
= (regnum
- ARMV8_V0
) << 1;
739 case ARMV8_V0
... ARMV8_V15
:
740 /* we are going to write R1, mark it dirty */
741 reg_r1
->dirty
= true;
742 value_r1
= lvalue
>> 32;
743 value_r0
= lvalue
& 0xFFFFFFFF;
744 /* write value_r1 to r1 via dcc */
745 retval
= dpm
->instr_write_data_dcc(dpm
,
746 ARMV4_5_MRC(14, 0, 1, 0, 5, 0),
748 if (retval
!= ERROR_OK
)
750 /* write value_r0 to r0 via dcc then,
751 * move to double word register from r0:r1: "vmov vm, r0, r1"
753 retval
= dpm
->instr_write_data_r0(dpm
,
754 ARMV4_5_VMOV(0, 1, 0, (num
>> 4), (num
& 0xf)),
756 if (retval
!= ERROR_OK
)
760 /* repeat above steps for high 64 bits of V register */
761 value_r1
= hvalue
>> 32;
762 value_r0
= hvalue
& 0xFFFFFFFF;
763 retval
= dpm
->instr_write_data_dcc(dpm
,
764 ARMV4_5_MRC(14, 0, 1, 0, 5, 0),
766 if (retval
!= ERROR_OK
)
768 retval
= dpm
->instr_write_data_r0(dpm
,
769 ARMV4_5_VMOV(0, 1, 0, (num
>> 4), (num
& 0xf)),
780 void armv8_select_reg_access(struct armv8_common
*armv8
, bool is_aarch64
)
783 armv8
->read_reg_u64
= armv8_read_reg
;
784 armv8
->write_reg_u64
= armv8_write_reg
;
785 armv8
->read_reg_u128
= armv8_read_reg_simdfp_aarch64
;
786 armv8
->write_reg_u128
= armv8_write_reg_simdfp_aarch64
;
789 armv8
->read_reg_u64
= armv8_read_reg32
;
790 armv8
->write_reg_u64
= armv8_write_reg32
;
791 armv8
->read_reg_u128
= armv8_read_reg_simdfp_aarch32
;
792 armv8
->write_reg_u128
= armv8_write_reg_simdfp_aarch32
;
796 /* retrieve core id cluster id */
797 int armv8_read_mpidr(struct armv8_common
*armv8
)
799 int retval
= ERROR_FAIL
;
800 struct arm
*arm
= &armv8
->arm
;
801 struct arm_dpm
*dpm
= armv8
->arm
.dpm
;
804 retval
= dpm
->prepare(dpm
);
805 if (retval
!= ERROR_OK
)
808 /* check if we're in an unprivileged mode */
809 if (armv8_curel_from_core_mode(arm
->core_mode
) < SYSTEM_CUREL_EL1
) {
810 retval
= armv8_dpm_modeswitch(dpm
, ARMV8_64_EL1H
);
811 if (retval
!= ERROR_OK
)
815 retval
= dpm
->instr_read_data_r0(dpm
, armv8_opcode(armv8
, READ_REG_MPIDR
), &mpidr
);
816 if (retval
!= ERROR_OK
)
818 if (mpidr
& 1U<<31) {
819 armv8
->multi_processor_system
= (mpidr
>> 30) & 1;
820 armv8
->cluster_id
= (mpidr
>> 8) & 0xf;
821 armv8
->cpu_id
= mpidr
& 0x3;
822 LOG_INFO("%s cluster %x core %x %s", target_name(armv8
->arm
.target
),
825 armv8
->multi_processor_system
== 0 ? "multi core" : "single core");
827 LOG_ERROR("mpidr not in multiprocessor format");
830 armv8_dpm_modeswitch(dpm
, ARM_MODE_ANY
);
836 * Configures host-side ARM records to reflect the specified CPSR.
837 * Later, code can use arm_reg_current() to map register numbers
838 * according to how they are exposed by this mode.
840 void armv8_set_cpsr(struct arm
*arm
, uint32_t cpsr
)
842 uint32_t mode
= cpsr
& 0x1F;
844 /* NOTE: this may be called very early, before the register
845 * cache is set up. We can't defend against many errors, in
846 * particular against CPSRs that aren't valid *here* ...
849 buf_set_u32(arm
->cpsr
->value
, 0, 32, cpsr
);
850 arm
->cpsr
->valid
= true;
851 arm
->cpsr
->dirty
= false;
854 /* Older ARMs won't have the J bit */
855 enum arm_state state
= 0xFF;
857 if ((cpsr
& 0x10) != 0) {
859 if (cpsr
& (1 << 5)) { /* T */
860 if (cpsr
& (1 << 24)) { /* J */
861 LOG_WARNING("ThumbEE -- incomplete support");
862 state
= ARM_STATE_THUMB_EE
;
864 state
= ARM_STATE_THUMB
;
866 if (cpsr
& (1 << 24)) { /* J */
867 LOG_ERROR("Jazelle state handling is BROKEN!");
868 state
= ARM_STATE_JAZELLE
;
870 state
= ARM_STATE_ARM
;
874 state
= ARM_STATE_AARCH64
;
877 arm
->core_state
= state
;
878 arm
->core_mode
= mode
;
880 LOG_DEBUG("set CPSR %#8.8x: %s mode, %s state", (unsigned) cpsr
,
881 armv8_mode_name(arm
->core_mode
),
882 armv8_state_strings
[arm
->core_state
]);
885 static void armv8_show_fault_registers32(struct armv8_common
*armv8
)
887 uint32_t dfsr
, ifsr
, dfar
, ifar
;
888 struct arm_dpm
*dpm
= armv8
->arm
.dpm
;
891 retval
= dpm
->prepare(dpm
);
892 if (retval
!= ERROR_OK
)
895 /* ARMV4_5_MRC(cpnum, op1, r0, crn, crm, op2) */
897 /* c5/c0 - {data, instruction} fault status registers */
898 retval
= dpm
->instr_read_data_r0(dpm
,
899 ARMV4_5_MRC(15, 0, 0, 5, 0, 0),
901 if (retval
!= ERROR_OK
)
904 retval
= dpm
->instr_read_data_r0(dpm
,
905 ARMV4_5_MRC(15, 0, 0, 5, 0, 1),
907 if (retval
!= ERROR_OK
)
910 /* c6/c0 - {data, instruction} fault address registers */
911 retval
= dpm
->instr_read_data_r0(dpm
,
912 ARMV4_5_MRC(15, 0, 0, 6, 0, 0),
914 if (retval
!= ERROR_OK
)
917 retval
= dpm
->instr_read_data_r0(dpm
,
918 ARMV4_5_MRC(15, 0, 0, 6, 0, 2),
920 if (retval
!= ERROR_OK
)
923 LOG_USER("Data fault registers DFSR: %8.8" PRIx32
924 ", DFAR: %8.8" PRIx32
, dfsr
, dfar
);
925 LOG_USER("Instruction fault registers IFSR: %8.8" PRIx32
926 ", IFAR: %8.8" PRIx32
, ifsr
, ifar
);
929 /* (void) */ dpm
->finish(dpm
);
932 static __attribute__((unused
)) void armv8_show_fault_registers(struct target
*target
)
934 struct armv8_common
*armv8
= target_to_armv8(target
);
936 if (armv8
->arm
.core_state
!= ARM_STATE_AARCH64
)
937 armv8_show_fault_registers32(armv8
);
940 /* method adapted to cortex A : reused arm v4 v5 method*/
941 int armv8_mmu_translate_va(struct target
*target
, target_addr_t va
, target_addr_t
*val
)
946 /* V8 method VA TO PA */
947 int armv8_mmu_translate_va_pa(struct target
*target
, target_addr_t va
,
948 target_addr_t
*val
, int meminfo
)
950 struct armv8_common
*armv8
= target_to_armv8(target
);
951 struct arm
*arm
= target_to_arm(target
);
952 struct arm_dpm
*dpm
= &armv8
->dpm
;
953 enum arm_mode target_mode
= ARM_MODE_ANY
;
958 static const char * const shared_name
[] = {
959 "Non-", "UNDEFINED ", "Outer ", "Inner "
962 static const char * const secure_name
[] = {
963 "Secure", "Not Secure"
966 if (target
->state
!= TARGET_HALTED
) {
967 LOG_TARGET_ERROR(target
, "not halted");
968 return ERROR_TARGET_NOT_HALTED
;
971 retval
= dpm
->prepare(dpm
);
972 if (retval
!= ERROR_OK
)
975 switch (armv8_curel_from_core_mode(arm
->core_mode
)) {
976 case SYSTEM_CUREL_EL0
:
977 instr
= ARMV8_SYS(SYSTEM_ATS12E0R
, 0);
978 /* can only execute instruction at EL2 */
979 target_mode
= ARMV8_64_EL2H
;
981 case SYSTEM_CUREL_EL1
:
982 instr
= ARMV8_SYS(SYSTEM_ATS12E1R
, 0);
983 /* can only execute instruction at EL2 */
984 target_mode
= ARMV8_64_EL2H
;
986 case SYSTEM_CUREL_EL2
:
987 instr
= ARMV8_SYS(SYSTEM_ATS1E2R
, 0);
989 case SYSTEM_CUREL_EL3
:
990 instr
= ARMV8_SYS(SYSTEM_ATS1E3R
, 0);
997 if (target_mode
!= ARM_MODE_ANY
)
998 armv8_dpm_modeswitch(dpm
, target_mode
);
1000 /* write VA to R0 and execute translation instruction */
1001 retval
= dpm
->instr_write_data_r0_64(dpm
, instr
, (uint64_t)va
);
1002 /* read result from PAR_EL1 */
1003 if (retval
== ERROR_OK
)
1004 retval
= dpm
->instr_read_data_r0_64(dpm
, ARMV8_MRS(SYSTEM_PAR_EL1
, 0), &par
);
1006 /* switch back to saved PE mode */
1007 if (target_mode
!= ARM_MODE_ANY
)
1008 armv8_dpm_modeswitch(dpm
, ARM_MODE_ANY
);
1012 if (retval
!= ERROR_OK
)
1016 LOG_ERROR("Address translation failed at stage %i, FST=%x, PTW=%i",
1017 ((int)(par
>> 9) & 1)+1, (int)(par
>> 1) & 0x3f, (int)(par
>> 8) & 1);
1020 retval
= ERROR_FAIL
;
1022 *val
= (par
& 0xFFFFFFFFF000UL
) | (va
& 0xFFF);
1024 int SH
= (par
>> 7) & 3;
1025 int NS
= (par
>> 9) & 1;
1026 int ATTR
= (par
>> 56) & 0xFF;
1028 char *memtype
= (ATTR
& 0xF0) == 0 ? "Device Memory" : "Normal Memory";
1030 LOG_USER("%sshareable, %s",
1031 shared_name
[SH
], secure_name
[NS
]);
1032 LOG_USER("%s", memtype
);
1039 COMMAND_HANDLER(armv8_handle_exception_catch_command
)
1041 struct target
*target
= get_current_target(CMD_CTX
);
1042 struct armv8_common
*armv8
= target_to_armv8(target
);
1043 uint32_t edeccr
= 0;
1044 unsigned int argp
= 0;
1047 static const struct nvp nvp_ecatch_modes
[] = {
1048 { .name
= "off", .value
= 0 },
1049 { .name
= "nsec_el1", .value
= (1 << 5) },
1050 { .name
= "nsec_el2", .value
= (2 << 5) },
1051 { .name
= "nsec_el12", .value
= (3 << 5) },
1052 { .name
= "sec_el1", .value
= (1 << 1) },
1053 { .name
= "sec_el3", .value
= (4 << 1) },
1054 { .name
= "sec_el13", .value
= (5 << 1) },
1055 { .name
= NULL
, .value
= -1 },
1057 const struct nvp
*n
;
1059 if (CMD_ARGC
== 0) {
1060 const char *sec
= NULL
, *nsec
= NULL
;
1062 retval
= mem_ap_read_atomic_u32(armv8
->debug_ap
,
1063 armv8
->debug_base
+ CPUV8_DBG_ECCR
, &edeccr
);
1064 if (retval
!= ERROR_OK
)
1067 n
= nvp_value2name(nvp_ecatch_modes
, edeccr
& 0x0f);
1071 n
= nvp_value2name(nvp_ecatch_modes
, edeccr
& 0xf0);
1075 if (!sec
|| !nsec
) {
1076 LOG_WARNING("Exception Catch: unknown exception catch configuration: EDECCR = %02" PRIx32
, edeccr
& 0xff);
1080 command_print(CMD
, "Exception Catch: Secure: %s, Non-Secure: %s", sec
, nsec
);
1084 while (argp
< CMD_ARGC
) {
1085 n
= nvp_name2value(nvp_ecatch_modes
, CMD_ARGV
[argp
]);
1087 LOG_ERROR("Unknown option: %s", CMD_ARGV
[argp
]);
1091 LOG_DEBUG("found: %s", n
->name
);
1097 retval
= mem_ap_write_atomic_u32(armv8
->debug_ap
,
1098 armv8
->debug_base
+ CPUV8_DBG_ECCR
, edeccr
);
1099 if (retval
!= ERROR_OK
)
1105 COMMAND_HANDLER(armv8_pauth_command
)
1107 struct target
*target
= get_current_target(CMD_CTX
);
1108 struct armv8_common
*armv8
= target_to_armv8(target
);
1109 return CALL_COMMAND_HANDLER(handle_command_parse_bool
,
1110 &armv8
->enable_pauth
,
1114 int armv8_handle_cache_info_command(struct command_invocation
*cmd
,
1115 struct armv8_cache_common
*armv8_cache
)
1117 if (armv8_cache
->info
== -1) {
1118 command_print(cmd
, "cache not yet identified");
1122 if (armv8_cache
->display_cache_info
)
1123 armv8_cache
->display_cache_info(cmd
, armv8_cache
);
1127 static int armv8_setup_semihosting(struct target
*target
, int enable
)
1132 int armv8_init_arch_info(struct target
*target
, struct armv8_common
*armv8
)
1134 struct arm
*arm
= &armv8
->arm
;
1135 arm
->arch_info
= armv8
;
1136 target
->arch_info
= &armv8
->arm
;
1137 arm
->setup_semihosting
= armv8_setup_semihosting
;
1138 /* target is useful in all function arm v4 5 compatible */
1139 armv8
->arm
.target
= target
;
1140 armv8
->arm
.common_magic
= ARM_COMMON_MAGIC
;
1141 armv8
->common_magic
= ARMV8_COMMON_MAGIC
;
1143 armv8
->armv8_mmu
.armv8_cache
.l2_cache
= NULL
;
1144 armv8
->armv8_mmu
.armv8_cache
.info
= -1;
1145 armv8
->armv8_mmu
.armv8_cache
.flush_all_data_cache
= NULL
;
1146 armv8
->armv8_mmu
.armv8_cache
.display_cache_info
= NULL
;
1150 static int armv8_aarch64_state(struct target
*target
)
1152 struct arm
*arm
= target_to_arm(target
);
1154 if (arm
->common_magic
!= ARM_COMMON_MAGIC
) {
1155 LOG_ERROR("BUG: called for a non-ARM target");
1159 LOG_USER("%s halted in %s state due to %s, current mode: %s\n"
1160 "cpsr: 0x%8.8" PRIx32
" pc: 0x%" PRIx64
"%s",
1161 target_name(target
),
1162 armv8_state_strings
[arm
->core_state
],
1163 debug_reason_name(target
),
1164 armv8_mode_name(arm
->core_mode
),
1165 buf_get_u32(arm
->cpsr
->value
, 0, 32),
1166 buf_get_u64(arm
->pc
->value
, 0, 64),
1167 (target
->semihosting
&& target
->semihosting
->is_active
) ? ", semihosting" : "");
1172 int armv8_arch_state(struct target
*target
)
1174 static const char * const state
[] = {
1175 "disabled", "enabled"
1178 struct armv8_common
*armv8
= target_to_armv8(target
);
1179 struct arm
*arm
= &armv8
->arm
;
1181 if (armv8
->common_magic
!= ARMV8_COMMON_MAGIC
) {
1182 LOG_ERROR("BUG: called for a non-Armv8 target");
1183 return ERROR_COMMAND_SYNTAX_ERROR
;
1186 if (arm
->core_state
== ARM_STATE_AARCH64
)
1187 armv8_aarch64_state(target
);
1189 arm_arch_state(target
);
1191 LOG_USER("MMU: %s, D-Cache: %s, I-Cache: %s",
1192 state
[armv8
->armv8_mmu
.mmu_enabled
],
1193 state
[armv8
->armv8_mmu
.armv8_cache
.d_u_cache_enabled
],
1194 state
[armv8
->armv8_mmu
.armv8_cache
.i_cache_enabled
]);
1196 if (arm
->core_mode
== ARM_MODE_ABT
)
1197 armv8_show_fault_registers(target
);
1199 if (target
->debug_reason
== DBG_REASON_WATCHPOINT
)
1200 LOG_USER("Watchpoint triggered at " TARGET_ADDR_FMT
, armv8
->dpm
.wp_addr
);
1205 static struct reg_data_type aarch64_vector_base_types
[] = {
1206 {REG_TYPE_IEEE_DOUBLE
, "ieee_double", 0, {NULL
} },
1207 {REG_TYPE_UINT64
, "uint64", 0, {NULL
} },
1208 {REG_TYPE_INT64
, "int64", 0, {NULL
} },
1209 {REG_TYPE_IEEE_SINGLE
, "ieee_single", 0, {NULL
} },
1210 {REG_TYPE_UINT32
, "uint32", 0, {NULL
} },
1211 {REG_TYPE_INT32
, "int32", 0, {NULL
} },
1212 {REG_TYPE_UINT16
, "uint16", 0, {NULL
} },
1213 {REG_TYPE_INT16
, "int16", 0, {NULL
} },
1214 {REG_TYPE_UINT8
, "uint8", 0, {NULL
} },
1215 {REG_TYPE_INT8
, "int8", 0, {NULL
} },
1216 {REG_TYPE_UINT128
, "uint128", 0, {NULL
} },
1217 {REG_TYPE_INT128
, "int128", 0, {NULL
} }
1220 static struct reg_data_type_vector aarch64_vector_types
[] = {
1221 {aarch64_vector_base_types
+ 0, 2},
1222 {aarch64_vector_base_types
+ 1, 2},
1223 {aarch64_vector_base_types
+ 2, 2},
1224 {aarch64_vector_base_types
+ 3, 4},
1225 {aarch64_vector_base_types
+ 4, 4},
1226 {aarch64_vector_base_types
+ 5, 4},
1227 {aarch64_vector_base_types
+ 6, 8},
1228 {aarch64_vector_base_types
+ 7, 8},
1229 {aarch64_vector_base_types
+ 8, 16},
1230 {aarch64_vector_base_types
+ 9, 16},
1231 {aarch64_vector_base_types
+ 10, 01},
1232 {aarch64_vector_base_types
+ 11, 01},
1235 static struct reg_data_type aarch64_fpu_vector
[] = {
1236 {REG_TYPE_ARCH_DEFINED
, "v2d", REG_TYPE_CLASS_VECTOR
, {aarch64_vector_types
+ 0} },
1237 {REG_TYPE_ARCH_DEFINED
, "v2u", REG_TYPE_CLASS_VECTOR
, {aarch64_vector_types
+ 1} },
1238 {REG_TYPE_ARCH_DEFINED
, "v2i", REG_TYPE_CLASS_VECTOR
, {aarch64_vector_types
+ 2} },
1239 {REG_TYPE_ARCH_DEFINED
, "v4f", REG_TYPE_CLASS_VECTOR
, {aarch64_vector_types
+ 3} },
1240 {REG_TYPE_ARCH_DEFINED
, "v4u", REG_TYPE_CLASS_VECTOR
, {aarch64_vector_types
+ 4} },
1241 {REG_TYPE_ARCH_DEFINED
, "v4i", REG_TYPE_CLASS_VECTOR
, {aarch64_vector_types
+ 5} },
1242 {REG_TYPE_ARCH_DEFINED
, "v8u", REG_TYPE_CLASS_VECTOR
, {aarch64_vector_types
+ 6} },
1243 {REG_TYPE_ARCH_DEFINED
, "v8i", REG_TYPE_CLASS_VECTOR
, {aarch64_vector_types
+ 7} },
1244 {REG_TYPE_ARCH_DEFINED
, "v16u", REG_TYPE_CLASS_VECTOR
, {aarch64_vector_types
+ 8} },
1245 {REG_TYPE_ARCH_DEFINED
, "v16i", REG_TYPE_CLASS_VECTOR
, {aarch64_vector_types
+ 9} },
1246 {REG_TYPE_ARCH_DEFINED
, "v1u", REG_TYPE_CLASS_VECTOR
, {aarch64_vector_types
+ 10} },
1247 {REG_TYPE_ARCH_DEFINED
, "v1i", REG_TYPE_CLASS_VECTOR
, {aarch64_vector_types
+ 11} },
1250 static struct reg_data_type_union_field aarch64_union_fields_vnd
[] = {
1251 {"f", aarch64_fpu_vector
+ 0, aarch64_union_fields_vnd
+ 1},
1252 {"u", aarch64_fpu_vector
+ 1, aarch64_union_fields_vnd
+ 2},
1253 {"s", aarch64_fpu_vector
+ 2, NULL
},
1256 static struct reg_data_type_union_field aarch64_union_fields_vns
[] = {
1257 {"f", aarch64_fpu_vector
+ 3, aarch64_union_fields_vns
+ 1},
1258 {"u", aarch64_fpu_vector
+ 4, aarch64_union_fields_vns
+ 2},
1259 {"s", aarch64_fpu_vector
+ 5, NULL
},
1262 static struct reg_data_type_union_field aarch64_union_fields_vnh
[] = {
1263 {"u", aarch64_fpu_vector
+ 6, aarch64_union_fields_vnh
+ 1},
1264 {"s", aarch64_fpu_vector
+ 7, NULL
},
1267 static struct reg_data_type_union_field aarch64_union_fields_vnb
[] = {
1268 {"u", aarch64_fpu_vector
+ 8, aarch64_union_fields_vnb
+ 1},
1269 {"s", aarch64_fpu_vector
+ 9, NULL
},
1272 static struct reg_data_type_union_field aarch64_union_fields_vnq
[] = {
1273 {"u", aarch64_fpu_vector
+ 10, aarch64_union_fields_vnq
+ 1},
1274 {"s", aarch64_fpu_vector
+ 11, NULL
},
1277 static struct reg_data_type_union aarch64_union_types
[] = {
1278 {aarch64_union_fields_vnd
},
1279 {aarch64_union_fields_vns
},
1280 {aarch64_union_fields_vnh
},
1281 {aarch64_union_fields_vnb
},
1282 {aarch64_union_fields_vnq
},
1285 static struct reg_data_type aarch64_fpu_union
[] = {
1286 {REG_TYPE_ARCH_DEFINED
, "vnd", REG_TYPE_CLASS_UNION
, {.reg_type_union
= aarch64_union_types
+ 0} },
1287 {REG_TYPE_ARCH_DEFINED
, "vns", REG_TYPE_CLASS_UNION
, {.reg_type_union
= aarch64_union_types
+ 1} },
1288 {REG_TYPE_ARCH_DEFINED
, "vnh", REG_TYPE_CLASS_UNION
, {.reg_type_union
= aarch64_union_types
+ 2} },
1289 {REG_TYPE_ARCH_DEFINED
, "vnb", REG_TYPE_CLASS_UNION
, {.reg_type_union
= aarch64_union_types
+ 3} },
1290 {REG_TYPE_ARCH_DEFINED
, "vnq", REG_TYPE_CLASS_UNION
, {.reg_type_union
= aarch64_union_types
+ 4} },
1293 static struct reg_data_type_union_field aarch64v_union_fields
[] = {
1294 {"d", aarch64_fpu_union
+ 0, aarch64v_union_fields
+ 1},
1295 {"s", aarch64_fpu_union
+ 1, aarch64v_union_fields
+ 2},
1296 {"h", aarch64_fpu_union
+ 2, aarch64v_union_fields
+ 3},
1297 {"b", aarch64_fpu_union
+ 3, aarch64v_union_fields
+ 4},
1298 {"q", aarch64_fpu_union
+ 4, NULL
},
1301 static struct reg_data_type_union aarch64v_union
[] = {
1302 {aarch64v_union_fields
}
1305 static struct reg_data_type aarch64v
[] = {
1306 {REG_TYPE_ARCH_DEFINED
, "aarch64v", REG_TYPE_CLASS_UNION
,
1307 {.reg_type_union
= aarch64v_union
} },
1310 static struct reg_data_type_bitfield aarch64_cpsr_bits
[] = {
1311 { 0, 0, REG_TYPE_UINT8
},
1312 { 2, 3, REG_TYPE_UINT8
},
1313 { 4, 4, REG_TYPE_UINT8
},
1314 { 6, 6, REG_TYPE_BOOL
},
1315 { 7, 7, REG_TYPE_BOOL
},
1316 { 8, 8, REG_TYPE_BOOL
},
1317 { 9, 9, REG_TYPE_BOOL
},
1318 { 20, 20, REG_TYPE_BOOL
},
1319 { 21, 21, REG_TYPE_BOOL
},
1320 { 28, 28, REG_TYPE_BOOL
},
1321 { 29, 29, REG_TYPE_BOOL
},
1322 { 30, 30, REG_TYPE_BOOL
},
1323 { 31, 31, REG_TYPE_BOOL
},
1326 static struct reg_data_type_flags_field aarch64_cpsr_fields
[] = {
1327 { "SP", aarch64_cpsr_bits
+ 0, aarch64_cpsr_fields
+ 1 },
1328 { "EL", aarch64_cpsr_bits
+ 1, aarch64_cpsr_fields
+ 2 },
1329 { "nRW", aarch64_cpsr_bits
+ 2, aarch64_cpsr_fields
+ 3 },
1330 { "F", aarch64_cpsr_bits
+ 3, aarch64_cpsr_fields
+ 4 },
1331 { "I", aarch64_cpsr_bits
+ 4, aarch64_cpsr_fields
+ 5 },
1332 { "A", aarch64_cpsr_bits
+ 5, aarch64_cpsr_fields
+ 6 },
1333 { "D", aarch64_cpsr_bits
+ 6, aarch64_cpsr_fields
+ 7 },
1334 { "IL", aarch64_cpsr_bits
+ 7, aarch64_cpsr_fields
+ 8 },
1335 { "SS", aarch64_cpsr_bits
+ 8, aarch64_cpsr_fields
+ 9 },
1336 { "V", aarch64_cpsr_bits
+ 9, aarch64_cpsr_fields
+ 10 },
1337 { "C", aarch64_cpsr_bits
+ 10, aarch64_cpsr_fields
+ 11 },
1338 { "Z", aarch64_cpsr_bits
+ 11, aarch64_cpsr_fields
+ 12 },
1339 { "N", aarch64_cpsr_bits
+ 12, NULL
}
1342 static struct reg_data_type_flags aarch64_cpsr_flags
[] = {
1343 { 4, aarch64_cpsr_fields
}
1346 static struct reg_data_type aarch64_flags_cpsr
[] = {
1347 {REG_TYPE_ARCH_DEFINED
, "cpsr_flags", REG_TYPE_CLASS_FLAGS
,
1348 {.reg_type_flags
= aarch64_cpsr_flags
} },
1351 static const struct {
1358 const char *feature
;
1359 struct reg_data_type
*data_type
;
1361 { ARMV8_R0
, "x0", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1362 { ARMV8_R1
, "x1", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1363 { ARMV8_R2
, "x2", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1364 { ARMV8_R3
, "x3", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1365 { ARMV8_R4
, "x4", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1366 { ARMV8_R5
, "x5", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1367 { ARMV8_R6
, "x6", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1368 { ARMV8_R7
, "x7", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1369 { ARMV8_R8
, "x8", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1370 { ARMV8_R9
, "x9", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1371 { ARMV8_R10
, "x10", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1372 { ARMV8_R11
, "x11", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1373 { ARMV8_R12
, "x12", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1374 { ARMV8_R13
, "x13", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1375 { ARMV8_R14
, "x14", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1376 { ARMV8_R15
, "x15", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1377 { ARMV8_R16
, "x16", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1378 { ARMV8_R17
, "x17", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1379 { ARMV8_R18
, "x18", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1380 { ARMV8_R19
, "x19", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1381 { ARMV8_R20
, "x20", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1382 { ARMV8_R21
, "x21", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1383 { ARMV8_R22
, "x22", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1384 { ARMV8_R23
, "x23", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1385 { ARMV8_R24
, "x24", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1386 { ARMV8_R25
, "x25", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1387 { ARMV8_R26
, "x26", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1388 { ARMV8_R27
, "x27", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1389 { ARMV8_R28
, "x28", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1390 { ARMV8_R29
, "x29", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1391 { ARMV8_R30
, "x30", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1393 { ARMV8_SP
, "sp", 64, ARM_MODE_ANY
, REG_TYPE_DATA_PTR
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1394 { ARMV8_PC
, "pc", 64, ARM_MODE_ANY
, REG_TYPE_CODE_PTR
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1395 { ARMV8_XPSR
, "cpsr", 32, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
,
1396 "general", "org.gnu.gdb.aarch64.core", aarch64_flags_cpsr
},
1397 { ARMV8_V0
, "v0", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1398 { ARMV8_V1
, "v1", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1399 { ARMV8_V2
, "v2", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1400 { ARMV8_V3
, "v3", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1401 { ARMV8_V4
, "v4", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1402 { ARMV8_V5
, "v5", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1403 { ARMV8_V6
, "v6", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1404 { ARMV8_V7
, "v7", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1405 { ARMV8_V8
, "v8", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1406 { ARMV8_V9
, "v9", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1407 { ARMV8_V10
, "v10", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1408 { ARMV8_V11
, "v11", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1409 { ARMV8_V12
, "v12", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1410 { ARMV8_V13
, "v13", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1411 { ARMV8_V14
, "v14", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1412 { ARMV8_V15
, "v15", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1413 { ARMV8_V16
, "v16", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1414 { ARMV8_V17
, "v17", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1415 { ARMV8_V18
, "v18", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1416 { ARMV8_V19
, "v19", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1417 { ARMV8_V20
, "v20", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1418 { ARMV8_V21
, "v21", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1419 { ARMV8_V22
, "v22", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1420 { ARMV8_V23
, "v23", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1421 { ARMV8_V24
, "v24", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1422 { ARMV8_V25
, "v25", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1423 { ARMV8_V26
, "v26", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1424 { ARMV8_V27
, "v27", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1425 { ARMV8_V28
, "v28", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1426 { ARMV8_V29
, "v29", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1427 { ARMV8_V30
, "v30", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1428 { ARMV8_V31
, "v31", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1429 { ARMV8_FPSR
, "fpsr", 32, ARM_MODE_ANY
, REG_TYPE_UINT32
, "simdfp", "org.gnu.gdb.aarch64.fpu", NULL
},
1430 { ARMV8_FPCR
, "fpcr", 32, ARM_MODE_ANY
, REG_TYPE_UINT32
, "simdfp", "org.gnu.gdb.aarch64.fpu", NULL
},
1432 { ARMV8_ELR_EL1
, "ELR_EL1", 64, ARMV8_64_EL1H
, REG_TYPE_CODE_PTR
, "banked", "net.sourceforge.openocd.banked",
1434 { ARMV8_ESR_EL1
, "ESR_EL1", 32, ARMV8_64_EL1H
, REG_TYPE_UINT32
, "banked", "net.sourceforge.openocd.banked",
1436 { ARMV8_SPSR_EL1
, "SPSR_EL1", 32, ARMV8_64_EL1H
, REG_TYPE_UINT32
, "banked", "net.sourceforge.openocd.banked",
1439 { ARMV8_ELR_EL2
, "ELR_EL2", 64, ARMV8_64_EL2H
, REG_TYPE_CODE_PTR
, "banked", "net.sourceforge.openocd.banked",
1441 { ARMV8_ESR_EL2
, "ESR_EL2", 32, ARMV8_64_EL2H
, REG_TYPE_UINT32
, "banked", "net.sourceforge.openocd.banked",
1443 { ARMV8_SPSR_EL2
, "SPSR_EL2", 32, ARMV8_64_EL2H
, REG_TYPE_UINT32
, "banked", "net.sourceforge.openocd.banked",
1446 { ARMV8_ELR_EL3
, "ELR_EL3", 64, ARMV8_64_EL3H
, REG_TYPE_CODE_PTR
, "banked", "net.sourceforge.openocd.banked",
1448 { ARMV8_ESR_EL3
, "ESR_EL3", 32, ARMV8_64_EL3H
, REG_TYPE_UINT32
, "banked", "net.sourceforge.openocd.banked",
1450 { ARMV8_SPSR_EL3
, "SPSR_EL3", 32, ARMV8_64_EL3H
, REG_TYPE_UINT32
, "banked", "net.sourceforge.openocd.banked",
1452 { ARMV8_PAUTH_DMASK
, "pauth_dmask", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, NULL
, "org.gnu.gdb.aarch64.pauth", NULL
},
1453 { ARMV8_PAUTH_CMASK
, "pauth_cmask", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, NULL
, "org.gnu.gdb.aarch64.pauth", NULL
},
1456 static const struct {
1464 const char *feature
;
1465 } armv8_regs32
[] = {
1466 { ARMV8_R0
, 0, "r0", 32, ARM_MODE_ANY
, REG_TYPE_UINT32
, "general", "org.gnu.gdb.arm.core" },
1467 { ARMV8_R1
, 0, "r1", 32, ARM_MODE_ANY
, REG_TYPE_UINT32
, "general", "org.gnu.gdb.arm.core" },
1468 { ARMV8_R2
, 0, "r2", 32, ARM_MODE_ANY
, REG_TYPE_UINT32
, "general", "org.gnu.gdb.arm.core" },
1469 { ARMV8_R3
, 0, "r3", 32, ARM_MODE_ANY
, REG_TYPE_UINT32
, "general", "org.gnu.gdb.arm.core" },
1470 { ARMV8_R4
, 0, "r4", 32, ARM_MODE_ANY
, REG_TYPE_UINT32
, "general", "org.gnu.gdb.arm.core" },
1471 { ARMV8_R5
, 0, "r5", 32, ARM_MODE_ANY
, REG_TYPE_UINT32
, "general", "org.gnu.gdb.arm.core" },
1472 { ARMV8_R6
, 0, "r6", 32, ARM_MODE_ANY
, REG_TYPE_UINT32
, "general", "org.gnu.gdb.arm.core" },
1473 { ARMV8_R7
, 0, "r7", 32, ARM_MODE_ANY
, REG_TYPE_UINT32
, "general", "org.gnu.gdb.arm.core" },
1474 { ARMV8_R8
, 0, "r8", 32, ARM_MODE_ANY
, REG_TYPE_UINT32
, "general", "org.gnu.gdb.arm.core" },
1475 { ARMV8_R9
, 0, "r9", 32, ARM_MODE_ANY
, REG_TYPE_UINT32
, "general", "org.gnu.gdb.arm.core" },
1476 { ARMV8_R10
, 0, "r10", 32, ARM_MODE_ANY
, REG_TYPE_UINT32
, "general", "org.gnu.gdb.arm.core" },
1477 { ARMV8_R11
, 0, "r11", 32, ARM_MODE_ANY
, REG_TYPE_UINT32
, "general", "org.gnu.gdb.arm.core" },
1478 { ARMV8_R12
, 0, "r12", 32, ARM_MODE_ANY
, REG_TYPE_UINT32
, "general", "org.gnu.gdb.arm.core" },
1479 { ARMV8_R13
, 0, "sp", 32, ARM_MODE_ANY
, REG_TYPE_DATA_PTR
, "general", "org.gnu.gdb.arm.core" },
1480 { ARMV8_R14
, 0, "lr", 32, ARM_MODE_ANY
, REG_TYPE_CODE_PTR
, "general", "org.gnu.gdb.arm.core" },
1481 { ARMV8_PC
, 0, "pc", 32, ARM_MODE_ANY
, REG_TYPE_CODE_PTR
, "general", "org.gnu.gdb.arm.core" },
1482 { ARMV8_XPSR
, 0, "cpsr", 32, ARM_MODE_ANY
, REG_TYPE_UINT32
, "general", "org.gnu.gdb.arm.core" },
1483 { ARMV8_V0
, 0, "d0", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1484 { ARMV8_V0
, 8, "d1", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1485 { ARMV8_V1
, 0, "d2", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1486 { ARMV8_V1
, 8, "d3", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1487 { ARMV8_V2
, 0, "d4", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1488 { ARMV8_V2
, 8, "d5", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1489 { ARMV8_V3
, 0, "d6", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1490 { ARMV8_V3
, 8, "d7", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1491 { ARMV8_V4
, 0, "d8", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1492 { ARMV8_V4
, 8, "d9", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1493 { ARMV8_V5
, 0, "d10", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1494 { ARMV8_V5
, 8, "d11", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1495 { ARMV8_V6
, 0, "d12", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1496 { ARMV8_V6
, 8, "d13", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1497 { ARMV8_V7
, 0, "d14", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1498 { ARMV8_V7
, 8, "d15", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1499 { ARMV8_V8
, 0, "d16", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1500 { ARMV8_V8
, 8, "d17", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1501 { ARMV8_V9
, 0, "d18", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1502 { ARMV8_V9
, 8, "d19", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1503 { ARMV8_V10
, 0, "d20", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1504 { ARMV8_V10
, 8, "d21", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1505 { ARMV8_V11
, 0, "d22", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1506 { ARMV8_V11
, 8, "d23", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1507 { ARMV8_V12
, 0, "d24", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1508 { ARMV8_V12
, 8, "d25", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1509 { ARMV8_V13
, 0, "d26", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1510 { ARMV8_V13
, 8, "d27", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1511 { ARMV8_V14
, 0, "d28", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1512 { ARMV8_V14
, 8, "d29", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1513 { ARMV8_V15
, 0, "d30", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1514 { ARMV8_V15
, 8, "d31", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1515 { ARMV8_FPSR
, 0, "fpscr", 32, ARM_MODE_ANY
, REG_TYPE_UINT32
, "float", "org.gnu.gdb.arm.vfp"},
1518 #define ARMV8_NUM_REGS ARRAY_SIZE(armv8_regs)
1519 #define ARMV8_NUM_REGS32 ARRAY_SIZE(armv8_regs32)
1521 static int armv8_get_core_reg(struct reg
*reg
)
1523 struct arm_reg
*armv8_reg
= reg
->arch_info
;
1524 struct target
*target
= armv8_reg
->target
;
1525 struct arm
*arm
= target_to_arm(target
);
1527 if (target
->state
!= TARGET_HALTED
)
1528 return ERROR_TARGET_NOT_HALTED
;
1530 return arm
->read_core_reg(target
, reg
, armv8_reg
->num
, arm
->core_mode
);
1533 static int armv8_set_core_reg(struct reg
*reg
, uint8_t *buf
)
1535 struct arm_reg
*armv8_reg
= reg
->arch_info
;
1536 struct target
*target
= armv8_reg
->target
;
1537 struct arm
*arm
= target_to_arm(target
);
1538 uint64_t value
= buf_get_u64(buf
, 0, reg
->size
);
1540 if (target
->state
!= TARGET_HALTED
)
1541 return ERROR_TARGET_NOT_HALTED
;
1543 if (reg
->size
<= 64) {
1544 if (reg
== arm
->cpsr
)
1545 armv8_set_cpsr(arm
, (uint32_t)value
);
1547 buf_set_u64(reg
->value
, 0, reg
->size
, value
);
1550 } else if (reg
->size
<= 128) {
1551 uint64_t hvalue
= buf_get_u64(buf
+ 8, 0, reg
->size
- 64);
1553 buf_set_u64(reg
->value
, 0, 64, value
);
1554 buf_set_u64(reg
->value
+ 8, 0, reg
->size
- 64, hvalue
);
1563 static const struct reg_arch_type armv8_reg_type
= {
1564 .get
= armv8_get_core_reg
,
1565 .set
= armv8_set_core_reg
,
1568 static int armv8_get_core_reg32(struct reg
*reg
)
1570 struct arm_reg
*armv8_reg
= reg
->arch_info
;
1571 struct target
*target
= armv8_reg
->target
;
1572 struct arm
*arm
= target_to_arm(target
);
1573 struct reg_cache
*cache
= arm
->core_cache
;
1577 if (target
->state
!= TARGET_HALTED
)
1578 return ERROR_TARGET_NOT_HALTED
;
1580 /* get the corresponding Aarch64 register */
1581 reg64
= cache
->reg_list
+ armv8_reg
->num
;
1587 retval
= arm
->read_core_reg(target
, reg64
, armv8_reg
->num
, arm
->core_mode
);
1588 if (retval
== ERROR_OK
)
1589 reg
->valid
= reg64
->valid
;
1594 static int armv8_set_core_reg32(struct reg
*reg
, uint8_t *buf
)
1596 struct arm_reg
*armv8_reg
= reg
->arch_info
;
1597 struct target
*target
= armv8_reg
->target
;
1598 struct arm
*arm
= target_to_arm(target
);
1599 struct reg_cache
*cache
= arm
->core_cache
;
1600 struct reg
*reg64
= cache
->reg_list
+ armv8_reg
->num
;
1601 uint32_t value
= buf_get_u32(buf
, 0, 32);
1603 if (target
->state
!= TARGET_HALTED
)
1604 return ERROR_TARGET_NOT_HALTED
;
1606 if (reg64
== arm
->cpsr
) {
1607 armv8_set_cpsr(arm
, value
);
1609 if (reg
->size
<= 32)
1610 buf_set_u32(reg
->value
, 0, 32, value
);
1611 else if (reg
->size
<= 64) {
1612 uint64_t value64
= buf_get_u64(buf
, 0, 64);
1613 buf_set_u64(reg
->value
, 0, 64, value64
);
1616 reg64
->valid
= true;
1619 reg64
->dirty
= true;
1624 static const struct reg_arch_type armv8_reg32_type
= {
1625 .get
= armv8_get_core_reg32
,
1626 .set
= armv8_set_core_reg32
,
1629 /** Builds cache of architecturally defined registers. */
1630 struct reg_cache
*armv8_build_reg_cache(struct target
*target
)
1632 struct armv8_common
*armv8
= target_to_armv8(target
);
1633 struct arm
*arm
= &armv8
->arm
;
1634 int num_regs
= ARMV8_NUM_REGS
;
1635 int num_regs32
= ARMV8_NUM_REGS32
;
1636 struct reg_cache
**cache_p
= register_get_last_cache_p(&target
->reg_cache
);
1637 struct reg_cache
*cache
= malloc(sizeof(struct reg_cache
));
1638 struct reg_cache
*cache32
= malloc(sizeof(struct reg_cache
));
1639 struct reg
*reg_list
= calloc(num_regs
, sizeof(struct reg
));
1640 struct reg
*reg_list32
= calloc(num_regs32
, sizeof(struct reg
));
1641 struct arm_reg
*arch_info
= calloc(num_regs
, sizeof(struct arm_reg
));
1642 struct reg_feature
*feature
;
1645 /* Build the process context cache */
1646 cache
->name
= "Aarch64 registers";
1647 cache
->next
= cache32
;
1648 cache
->reg_list
= reg_list
;
1649 cache
->num_regs
= num_regs
;
1651 for (i
= 0; i
< num_regs
; i
++) {
1652 arch_info
[i
].num
= armv8_regs
[i
].id
;
1653 arch_info
[i
].mode
= armv8_regs
[i
].mode
;
1654 arch_info
[i
].target
= target
;
1655 arch_info
[i
].arm
= arm
;
1657 reg_list
[i
].name
= armv8_regs
[i
].name
;
1658 reg_list
[i
].size
= armv8_regs
[i
].bits
;
1659 reg_list
[i
].value
= &arch_info
[i
].value
[0];
1660 reg_list
[i
].type
= &armv8_reg_type
;
1661 reg_list
[i
].arch_info
= &arch_info
[i
];
1663 reg_list
[i
].group
= armv8_regs
[i
].group
;
1664 reg_list
[i
].number
= i
;
1665 reg_list
[i
].exist
= true;
1666 reg_list
[i
].caller_save
= true; /* gdb defaults to true */
1668 feature
= calloc(1, sizeof(struct reg_feature
));
1670 feature
->name
= armv8_regs
[i
].feature
;
1671 reg_list
[i
].feature
= feature
;
1673 LOG_ERROR("unable to allocate feature list");
1675 reg_list
[i
].reg_data_type
= calloc(1, sizeof(struct reg_data_type
));
1676 if (reg_list
[i
].reg_data_type
) {
1677 if (!armv8_regs
[i
].data_type
)
1678 reg_list
[i
].reg_data_type
->type
= armv8_regs
[i
].type
;
1680 *reg_list
[i
].reg_data_type
= *armv8_regs
[i
].data_type
;
1682 LOG_ERROR("unable to allocate reg type list");
1684 if (i
== ARMV8_PAUTH_CMASK
|| i
== ARMV8_PAUTH_DMASK
)
1685 reg_list
[i
].exist
= armv8
->enable_pauth
;
1688 arm
->cpsr
= reg_list
+ ARMV8_XPSR
;
1689 arm
->pc
= reg_list
+ ARMV8_PC
;
1690 arm
->core_cache
= cache
;
1692 /* shadow cache for ARM mode registers */
1693 cache32
->name
= "Aarch32 registers";
1694 cache32
->next
= NULL
;
1695 cache32
->reg_list
= reg_list32
;
1696 cache32
->num_regs
= num_regs32
;
1698 for (i
= 0; i
< num_regs32
; i
++) {
1699 reg_list32
[i
].name
= armv8_regs32
[i
].name
;
1700 reg_list32
[i
].size
= armv8_regs32
[i
].bits
;
1701 reg_list32
[i
].value
= &arch_info
[armv8_regs32
[i
].id
].value
[armv8_regs32
[i
].mapping
];
1702 reg_list32
[i
].type
= &armv8_reg32_type
;
1703 reg_list32
[i
].arch_info
= &arch_info
[armv8_regs32
[i
].id
];
1704 reg_list32
[i
].group
= armv8_regs32
[i
].group
;
1705 reg_list32
[i
].number
= i
;
1706 reg_list32
[i
].exist
= true;
1707 reg_list32
[i
].caller_save
= true;
1709 feature
= calloc(1, sizeof(struct reg_feature
));
1711 feature
->name
= armv8_regs32
[i
].feature
;
1712 reg_list32
[i
].feature
= feature
;
1714 LOG_ERROR("unable to allocate feature list");
1716 reg_list32
[i
].reg_data_type
= calloc(1, sizeof(struct reg_data_type
));
1717 if (reg_list32
[i
].reg_data_type
)
1718 reg_list32
[i
].reg_data_type
->type
= armv8_regs32
[i
].type
;
1720 LOG_ERROR("unable to allocate reg type list");
1727 struct reg
*armv8_reg_current(struct arm
*arm
, unsigned regnum
)
1731 if (regnum
> (ARMV8_LAST_REG
- 1))
1734 r
= arm
->core_cache
->reg_list
+ regnum
;
1738 static void armv8_free_cache(struct reg_cache
*cache
, bool regs32
)
1746 for (i
= 0; i
< cache
->num_regs
; i
++) {
1747 reg
= &cache
->reg_list
[i
];
1750 free(reg
->reg_data_type
);
1754 free(cache
->reg_list
[0].arch_info
);
1755 free(cache
->reg_list
);
1759 void armv8_free_reg_cache(struct target
*target
)
1761 struct armv8_common
*armv8
= target_to_armv8(target
);
1762 struct arm
*arm
= &armv8
->arm
;
1763 struct reg_cache
*cache
= NULL
, *cache32
= NULL
;
1765 cache
= arm
->core_cache
;
1767 cache32
= cache
->next
;
1768 armv8_free_cache(cache32
, true);
1769 armv8_free_cache(cache
, false);
1770 arm
->core_cache
= NULL
;
1773 const struct command_registration armv8_command_handlers
[] = {
1775 .name
= "catch_exc",
1776 .handler
= armv8_handle_exception_catch_command
,
1777 .mode
= COMMAND_EXEC
,
1778 .help
= "configure exception catch",
1779 .usage
= "[(nsec_el1,nsec_el2,sec_el1,sec_el3)+,off]",
1783 .handler
= armv8_pauth_command
,
1784 .mode
= COMMAND_CONFIG
,
1785 .help
= "enable or disable providing GDB with an 8-bytes mask to "
1786 "remove signature bits added by pointer authentication."
1787 "Pointer authentication feature is broken until gdb 12.1, going to be fixed. "
1788 "Consider using a newer version of gdb if you want enable "
1790 .usage
= "[on|off]",
1792 COMMAND_REGISTRATION_DONE
1795 const char *armv8_get_gdb_arch(struct target
*target
)
1797 struct arm
*arm
= target_to_arm(target
);
1798 return arm
->core_state
== ARM_STATE_AARCH64
? "aarch64" : "arm";
1801 int armv8_get_gdb_reg_list(struct target
*target
,
1802 struct reg
**reg_list
[], int *reg_list_size
,
1803 enum target_register_class reg_class
)
1805 struct arm
*arm
= target_to_arm(target
);
1808 if (arm
->core_state
== ARM_STATE_AARCH64
) {
1810 LOG_DEBUG("Creating Aarch64 register list for target %s", target_name(target
));
1812 switch (reg_class
) {
1813 case REG_CLASS_GENERAL
:
1814 *reg_list_size
= ARMV8_V0
;
1815 *reg_list
= malloc(sizeof(struct reg
*) * (*reg_list_size
));
1817 for (i
= 0; i
< *reg_list_size
; i
++)
1818 (*reg_list
)[i
] = armv8_reg_current(arm
, i
);
1822 *reg_list_size
= ARMV8_LAST_REG
;
1823 *reg_list
= malloc(sizeof(struct reg
*) * (*reg_list_size
));
1825 for (i
= 0; i
< *reg_list_size
; i
++)
1826 (*reg_list
)[i
] = armv8_reg_current(arm
, i
);
1831 LOG_ERROR("not a valid register class type in query.");
1835 struct reg_cache
*cache32
= arm
->core_cache
->next
;
1837 LOG_DEBUG("Creating Aarch32 register list for target %s", target_name(target
));
1839 switch (reg_class
) {
1840 case REG_CLASS_GENERAL
:
1841 *reg_list_size
= ARMV8_R14
+ 3;
1842 *reg_list
= malloc(sizeof(struct reg
*) * (*reg_list_size
));
1844 for (i
= 0; i
< *reg_list_size
; i
++)
1845 (*reg_list
)[i
] = cache32
->reg_list
+ i
;
1849 *reg_list_size
= cache32
->num_regs
;
1850 *reg_list
= malloc(sizeof(struct reg
*) * (*reg_list_size
));
1852 for (i
= 0; i
< *reg_list_size
; i
++)
1853 (*reg_list
)[i
] = cache32
->reg_list
+ i
;
1857 LOG_ERROR("not a valid register class type in query.");
1863 int armv8_set_dbgreg_bits(struct armv8_common
*armv8
, unsigned int reg
, unsigned long mask
, unsigned long value
)
1868 int retval
= mem_ap_read_atomic_u32(armv8
->debug_ap
,
1869 armv8
->debug_base
+ reg
, &tmp
);
1870 if (retval
!= ERROR_OK
)
1873 /* clear bitfield */
1876 tmp
|= value
& mask
;
1878 /* write new value */
1879 retval
= mem_ap_write_atomic_u32(armv8
->debug_ap
,
1880 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)