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 static void armv8_decode_cacheability(int attr
)
949 LOG_USER_N("UNPREDICTABLE");
953 LOG_USER_N("Non-cacheable");
956 switch (attr
& 0xC) {
958 LOG_USER_N("Write-Through Transient");
961 LOG_USER_N("Write-Back Transient");
964 LOG_USER_N("Write-Through Non-transient");
967 LOG_USER_N("Write-Back Non-transient");
971 LOG_USER_N(" Read-Allocate");
973 LOG_USER_N(" No-Read Allocate");
975 LOG_USER_N(" Write-Allocate");
977 LOG_USER_N(" No-Write Allocate");
980 static void armv8_decode_memory_attr(int attr
)
983 LOG_USER("Normal Memory, Inner Non-cacheable, "
984 "Outer Non-cacheable, XS=0");
985 } else if (attr
== 0xA0) {
986 LOG_USER("Normal Memory, Inner Write-through Cacheable, "
987 "Outer Write-through Cacheable, Read-Allocate, "
988 "No-Write Allocate, Non-transient, XS=0");
989 } else if (attr
== 0xF0) {
990 LOG_USER("Tagged Normal Memory, Inner Write-Back, "
991 "Outer Write-Back, Read-Allocate, Write-Allocate, "
993 } else if ((attr
& 0xF0) == 0) {
994 switch (attr
& 0xC) {
996 LOG_USER_N("Device-nGnRnE Memory");
999 LOG_USER_N("Device-nGnRE Memory");
1002 LOG_USER_N("Device-nGRE Memory");
1005 LOG_USER_N("Device-GRE Memory");
1013 LOG_USER_N("Normal Memory, Inner ");
1014 armv8_decode_cacheability(attr
& 0xF);
1015 LOG_USER_N(", Outer ");
1016 armv8_decode_cacheability(attr
>> 4);
1021 /* V8 method VA TO PA */
1022 int armv8_mmu_translate_va_pa(struct target
*target
, target_addr_t va
,
1023 target_addr_t
*val
, int meminfo
)
1025 struct armv8_common
*armv8
= target_to_armv8(target
);
1026 struct arm
*arm
= target_to_arm(target
);
1027 struct arm_dpm
*dpm
= &armv8
->dpm
;
1028 enum arm_mode target_mode
= ARM_MODE_ANY
;
1033 static const char * const shared_name
[] = {
1034 "Non-", "UNDEFINED ", "Outer ", "Inner "
1037 static const char * const secure_name
[] = {
1038 "Secure", "Not Secure"
1041 if (target
->state
!= TARGET_HALTED
) {
1042 LOG_TARGET_ERROR(target
, "not halted");
1043 return ERROR_TARGET_NOT_HALTED
;
1046 retval
= dpm
->prepare(dpm
);
1047 if (retval
!= ERROR_OK
)
1050 switch (armv8_curel_from_core_mode(arm
->core_mode
)) {
1051 case SYSTEM_CUREL_EL0
:
1052 instr
= ARMV8_SYS(SYSTEM_ATS12E0R
, 0);
1053 /* can only execute instruction at EL2 */
1054 target_mode
= ARMV8_64_EL2H
;
1056 case SYSTEM_CUREL_EL1
:
1057 instr
= ARMV8_SYS(SYSTEM_ATS12E1R
, 0);
1058 /* can only execute instruction at EL2 */
1059 target_mode
= ARMV8_64_EL2H
;
1061 case SYSTEM_CUREL_EL2
:
1062 instr
= ARMV8_SYS(SYSTEM_ATS1E2R
, 0);
1064 case SYSTEM_CUREL_EL3
:
1065 instr
= ARMV8_SYS(SYSTEM_ATS1E3R
, 0);
1072 if (target_mode
!= ARM_MODE_ANY
)
1073 armv8_dpm_modeswitch(dpm
, target_mode
);
1075 /* write VA to R0 and execute translation instruction */
1076 retval
= dpm
->instr_write_data_r0_64(dpm
, instr
, (uint64_t)va
);
1077 /* read result from PAR_EL1 */
1078 if (retval
== ERROR_OK
)
1079 retval
= dpm
->instr_read_data_r0_64(dpm
, ARMV8_MRS(SYSTEM_PAR_EL1
, 0), &par
);
1081 /* switch back to saved PE mode */
1082 if (target_mode
!= ARM_MODE_ANY
)
1083 armv8_dpm_modeswitch(dpm
, ARM_MODE_ANY
);
1087 if (retval
!= ERROR_OK
)
1091 LOG_ERROR("Address translation failed at stage %i, FST=%x, PTW=%i",
1092 ((int)(par
>> 9) & 1)+1, (int)(par
>> 1) & 0x3f, (int)(par
>> 8) & 1);
1095 retval
= ERROR_FAIL
;
1097 *val
= (par
& 0xFFFFFFFFF000UL
) | (va
& 0xFFF);
1099 int SH
= (par
>> 7) & 3;
1100 int NS
= (par
>> 9) & 1;
1101 int ATTR
= (par
>> 56) & 0xFF;
1103 LOG_USER("%sshareable, %s",
1104 shared_name
[SH
], secure_name
[NS
]);
1105 armv8_decode_memory_attr(ATTR
);
1112 COMMAND_HANDLER(armv8_handle_exception_catch_command
)
1114 struct target
*target
= get_current_target(CMD_CTX
);
1115 struct armv8_common
*armv8
= target_to_armv8(target
);
1116 uint32_t edeccr
= 0;
1117 unsigned int argp
= 0;
1120 static const struct nvp nvp_ecatch_modes
[] = {
1121 { .name
= "off", .value
= 0 },
1122 { .name
= "nsec_el1", .value
= (1 << 5) },
1123 { .name
= "nsec_el2", .value
= (2 << 5) },
1124 { .name
= "nsec_el12", .value
= (3 << 5) },
1125 { .name
= "sec_el1", .value
= (1 << 1) },
1126 { .name
= "sec_el3", .value
= (4 << 1) },
1127 { .name
= "sec_el13", .value
= (5 << 1) },
1128 { .name
= NULL
, .value
= -1 },
1130 const struct nvp
*n
;
1132 if (CMD_ARGC
== 0) {
1133 const char *sec
= NULL
, *nsec
= NULL
;
1135 retval
= mem_ap_read_atomic_u32(armv8
->debug_ap
,
1136 armv8
->debug_base
+ CPUV8_DBG_ECCR
, &edeccr
);
1137 if (retval
!= ERROR_OK
)
1140 n
= nvp_value2name(nvp_ecatch_modes
, edeccr
& 0x0f);
1144 n
= nvp_value2name(nvp_ecatch_modes
, edeccr
& 0xf0);
1148 if (!sec
|| !nsec
) {
1149 LOG_WARNING("Exception Catch: unknown exception catch configuration: EDECCR = %02" PRIx32
, edeccr
& 0xff);
1153 command_print(CMD
, "Exception Catch: Secure: %s, Non-Secure: %s", sec
, nsec
);
1157 while (argp
< CMD_ARGC
) {
1158 n
= nvp_name2value(nvp_ecatch_modes
, CMD_ARGV
[argp
]);
1160 LOG_ERROR("Unknown option: %s", CMD_ARGV
[argp
]);
1164 LOG_DEBUG("found: %s", n
->name
);
1170 retval
= mem_ap_write_atomic_u32(armv8
->debug_ap
,
1171 armv8
->debug_base
+ CPUV8_DBG_ECCR
, edeccr
);
1172 if (retval
!= ERROR_OK
)
1178 COMMAND_HANDLER(armv8_pauth_command
)
1180 struct target
*target
= get_current_target(CMD_CTX
);
1181 struct armv8_common
*armv8
= target_to_armv8(target
);
1182 return CALL_COMMAND_HANDLER(handle_command_parse_bool
,
1183 &armv8
->enable_pauth
,
1187 int armv8_handle_cache_info_command(struct command_invocation
*cmd
,
1188 struct armv8_cache_common
*armv8_cache
)
1190 if (armv8_cache
->info
== -1) {
1191 command_print(cmd
, "cache not yet identified");
1195 if (armv8_cache
->display_cache_info
)
1196 armv8_cache
->display_cache_info(cmd
, armv8_cache
);
1200 static int armv8_setup_semihosting(struct target
*target
, int enable
)
1205 int armv8_init_arch_info(struct target
*target
, struct armv8_common
*armv8
)
1207 struct arm
*arm
= &armv8
->arm
;
1208 arm
->arch_info
= armv8
;
1209 target
->arch_info
= &armv8
->arm
;
1210 arm
->setup_semihosting
= armv8_setup_semihosting
;
1211 /* target is useful in all function arm v4 5 compatible */
1212 armv8
->arm
.target
= target
;
1213 armv8
->arm
.common_magic
= ARM_COMMON_MAGIC
;
1214 armv8
->common_magic
= ARMV8_COMMON_MAGIC
;
1216 armv8
->armv8_mmu
.armv8_cache
.l2_cache
= NULL
;
1217 armv8
->armv8_mmu
.armv8_cache
.info
= -1;
1218 armv8
->armv8_mmu
.armv8_cache
.flush_all_data_cache
= NULL
;
1219 armv8
->armv8_mmu
.armv8_cache
.display_cache_info
= NULL
;
1223 static int armv8_aarch64_state(struct target
*target
)
1225 struct arm
*arm
= target_to_arm(target
);
1227 if (arm
->common_magic
!= ARM_COMMON_MAGIC
) {
1228 LOG_ERROR("BUG: called for a non-ARM target");
1232 LOG_USER("%s halted in %s state due to %s, current mode: %s\n"
1233 "cpsr: 0x%8.8" PRIx32
" pc: 0x%" PRIx64
"%s",
1234 target_name(target
),
1235 armv8_state_strings
[arm
->core_state
],
1236 debug_reason_name(target
),
1237 armv8_mode_name(arm
->core_mode
),
1238 buf_get_u32(arm
->cpsr
->value
, 0, 32),
1239 buf_get_u64(arm
->pc
->value
, 0, 64),
1240 (target
->semihosting
&& target
->semihosting
->is_active
) ? ", semihosting" : "");
1245 int armv8_arch_state(struct target
*target
)
1247 static const char * const state
[] = {
1248 "disabled", "enabled"
1251 struct armv8_common
*armv8
= target_to_armv8(target
);
1252 struct arm
*arm
= &armv8
->arm
;
1254 if (armv8
->common_magic
!= ARMV8_COMMON_MAGIC
) {
1255 LOG_ERROR("BUG: called for a non-Armv8 target");
1256 return ERROR_COMMAND_SYNTAX_ERROR
;
1259 if (arm
->core_state
== ARM_STATE_AARCH64
)
1260 armv8_aarch64_state(target
);
1262 arm_arch_state(target
);
1264 LOG_USER("MMU: %s, D-Cache: %s, I-Cache: %s",
1265 state
[armv8
->armv8_mmu
.mmu_enabled
],
1266 state
[armv8
->armv8_mmu
.armv8_cache
.d_u_cache_enabled
],
1267 state
[armv8
->armv8_mmu
.armv8_cache
.i_cache_enabled
]);
1269 if (arm
->core_mode
== ARM_MODE_ABT
)
1270 armv8_show_fault_registers(target
);
1272 if (target
->debug_reason
== DBG_REASON_WATCHPOINT
)
1273 LOG_USER("Watchpoint triggered at " TARGET_ADDR_FMT
, armv8
->dpm
.wp_addr
);
1278 static struct reg_data_type aarch64_vector_base_types
[] = {
1279 {REG_TYPE_IEEE_DOUBLE
, "ieee_double", 0, {NULL
} },
1280 {REG_TYPE_UINT64
, "uint64", 0, {NULL
} },
1281 {REG_TYPE_INT64
, "int64", 0, {NULL
} },
1282 {REG_TYPE_IEEE_SINGLE
, "ieee_single", 0, {NULL
} },
1283 {REG_TYPE_UINT32
, "uint32", 0, {NULL
} },
1284 {REG_TYPE_INT32
, "int32", 0, {NULL
} },
1285 {REG_TYPE_UINT16
, "uint16", 0, {NULL
} },
1286 {REG_TYPE_INT16
, "int16", 0, {NULL
} },
1287 {REG_TYPE_UINT8
, "uint8", 0, {NULL
} },
1288 {REG_TYPE_INT8
, "int8", 0, {NULL
} },
1289 {REG_TYPE_UINT128
, "uint128", 0, {NULL
} },
1290 {REG_TYPE_INT128
, "int128", 0, {NULL
} }
1293 static struct reg_data_type_vector aarch64_vector_types
[] = {
1294 {aarch64_vector_base_types
+ 0, 2},
1295 {aarch64_vector_base_types
+ 1, 2},
1296 {aarch64_vector_base_types
+ 2, 2},
1297 {aarch64_vector_base_types
+ 3, 4},
1298 {aarch64_vector_base_types
+ 4, 4},
1299 {aarch64_vector_base_types
+ 5, 4},
1300 {aarch64_vector_base_types
+ 6, 8},
1301 {aarch64_vector_base_types
+ 7, 8},
1302 {aarch64_vector_base_types
+ 8, 16},
1303 {aarch64_vector_base_types
+ 9, 16},
1304 {aarch64_vector_base_types
+ 10, 01},
1305 {aarch64_vector_base_types
+ 11, 01},
1308 static struct reg_data_type aarch64_fpu_vector
[] = {
1309 {REG_TYPE_ARCH_DEFINED
, "v2d", REG_TYPE_CLASS_VECTOR
, {aarch64_vector_types
+ 0} },
1310 {REG_TYPE_ARCH_DEFINED
, "v2u", REG_TYPE_CLASS_VECTOR
, {aarch64_vector_types
+ 1} },
1311 {REG_TYPE_ARCH_DEFINED
, "v2i", REG_TYPE_CLASS_VECTOR
, {aarch64_vector_types
+ 2} },
1312 {REG_TYPE_ARCH_DEFINED
, "v4f", REG_TYPE_CLASS_VECTOR
, {aarch64_vector_types
+ 3} },
1313 {REG_TYPE_ARCH_DEFINED
, "v4u", REG_TYPE_CLASS_VECTOR
, {aarch64_vector_types
+ 4} },
1314 {REG_TYPE_ARCH_DEFINED
, "v4i", REG_TYPE_CLASS_VECTOR
, {aarch64_vector_types
+ 5} },
1315 {REG_TYPE_ARCH_DEFINED
, "v8u", REG_TYPE_CLASS_VECTOR
, {aarch64_vector_types
+ 6} },
1316 {REG_TYPE_ARCH_DEFINED
, "v8i", REG_TYPE_CLASS_VECTOR
, {aarch64_vector_types
+ 7} },
1317 {REG_TYPE_ARCH_DEFINED
, "v16u", REG_TYPE_CLASS_VECTOR
, {aarch64_vector_types
+ 8} },
1318 {REG_TYPE_ARCH_DEFINED
, "v16i", REG_TYPE_CLASS_VECTOR
, {aarch64_vector_types
+ 9} },
1319 {REG_TYPE_ARCH_DEFINED
, "v1u", REG_TYPE_CLASS_VECTOR
, {aarch64_vector_types
+ 10} },
1320 {REG_TYPE_ARCH_DEFINED
, "v1i", REG_TYPE_CLASS_VECTOR
, {aarch64_vector_types
+ 11} },
1323 static struct reg_data_type_union_field aarch64_union_fields_vnd
[] = {
1324 {"f", aarch64_fpu_vector
+ 0, aarch64_union_fields_vnd
+ 1},
1325 {"u", aarch64_fpu_vector
+ 1, aarch64_union_fields_vnd
+ 2},
1326 {"s", aarch64_fpu_vector
+ 2, NULL
},
1329 static struct reg_data_type_union_field aarch64_union_fields_vns
[] = {
1330 {"f", aarch64_fpu_vector
+ 3, aarch64_union_fields_vns
+ 1},
1331 {"u", aarch64_fpu_vector
+ 4, aarch64_union_fields_vns
+ 2},
1332 {"s", aarch64_fpu_vector
+ 5, NULL
},
1335 static struct reg_data_type_union_field aarch64_union_fields_vnh
[] = {
1336 {"u", aarch64_fpu_vector
+ 6, aarch64_union_fields_vnh
+ 1},
1337 {"s", aarch64_fpu_vector
+ 7, NULL
},
1340 static struct reg_data_type_union_field aarch64_union_fields_vnb
[] = {
1341 {"u", aarch64_fpu_vector
+ 8, aarch64_union_fields_vnb
+ 1},
1342 {"s", aarch64_fpu_vector
+ 9, NULL
},
1345 static struct reg_data_type_union_field aarch64_union_fields_vnq
[] = {
1346 {"u", aarch64_fpu_vector
+ 10, aarch64_union_fields_vnq
+ 1},
1347 {"s", aarch64_fpu_vector
+ 11, NULL
},
1350 static struct reg_data_type_union aarch64_union_types
[] = {
1351 {aarch64_union_fields_vnd
},
1352 {aarch64_union_fields_vns
},
1353 {aarch64_union_fields_vnh
},
1354 {aarch64_union_fields_vnb
},
1355 {aarch64_union_fields_vnq
},
1358 static struct reg_data_type aarch64_fpu_union
[] = {
1359 {REG_TYPE_ARCH_DEFINED
, "vnd", REG_TYPE_CLASS_UNION
, {.reg_type_union
= aarch64_union_types
+ 0} },
1360 {REG_TYPE_ARCH_DEFINED
, "vns", REG_TYPE_CLASS_UNION
, {.reg_type_union
= aarch64_union_types
+ 1} },
1361 {REG_TYPE_ARCH_DEFINED
, "vnh", REG_TYPE_CLASS_UNION
, {.reg_type_union
= aarch64_union_types
+ 2} },
1362 {REG_TYPE_ARCH_DEFINED
, "vnb", REG_TYPE_CLASS_UNION
, {.reg_type_union
= aarch64_union_types
+ 3} },
1363 {REG_TYPE_ARCH_DEFINED
, "vnq", REG_TYPE_CLASS_UNION
, {.reg_type_union
= aarch64_union_types
+ 4} },
1366 static struct reg_data_type_union_field aarch64v_union_fields
[] = {
1367 {"d", aarch64_fpu_union
+ 0, aarch64v_union_fields
+ 1},
1368 {"s", aarch64_fpu_union
+ 1, aarch64v_union_fields
+ 2},
1369 {"h", aarch64_fpu_union
+ 2, aarch64v_union_fields
+ 3},
1370 {"b", aarch64_fpu_union
+ 3, aarch64v_union_fields
+ 4},
1371 {"q", aarch64_fpu_union
+ 4, NULL
},
1374 static struct reg_data_type_union aarch64v_union
[] = {
1375 {aarch64v_union_fields
}
1378 static struct reg_data_type aarch64v
[] = {
1379 {REG_TYPE_ARCH_DEFINED
, "aarch64v", REG_TYPE_CLASS_UNION
,
1380 {.reg_type_union
= aarch64v_union
} },
1383 static struct reg_data_type_bitfield aarch64_cpsr_bits
[] = {
1384 { 0, 0, REG_TYPE_UINT8
},
1385 { 2, 3, REG_TYPE_UINT8
},
1386 { 4, 4, REG_TYPE_UINT8
},
1387 { 6, 6, REG_TYPE_BOOL
},
1388 { 7, 7, REG_TYPE_BOOL
},
1389 { 8, 8, REG_TYPE_BOOL
},
1390 { 9, 9, REG_TYPE_BOOL
},
1391 { 20, 20, REG_TYPE_BOOL
},
1392 { 21, 21, REG_TYPE_BOOL
},
1393 { 28, 28, REG_TYPE_BOOL
},
1394 { 29, 29, REG_TYPE_BOOL
},
1395 { 30, 30, REG_TYPE_BOOL
},
1396 { 31, 31, REG_TYPE_BOOL
},
1399 static struct reg_data_type_flags_field aarch64_cpsr_fields
[] = {
1400 { "SP", aarch64_cpsr_bits
+ 0, aarch64_cpsr_fields
+ 1 },
1401 { "EL", aarch64_cpsr_bits
+ 1, aarch64_cpsr_fields
+ 2 },
1402 { "nRW", aarch64_cpsr_bits
+ 2, aarch64_cpsr_fields
+ 3 },
1403 { "F", aarch64_cpsr_bits
+ 3, aarch64_cpsr_fields
+ 4 },
1404 { "I", aarch64_cpsr_bits
+ 4, aarch64_cpsr_fields
+ 5 },
1405 { "A", aarch64_cpsr_bits
+ 5, aarch64_cpsr_fields
+ 6 },
1406 { "D", aarch64_cpsr_bits
+ 6, aarch64_cpsr_fields
+ 7 },
1407 { "IL", aarch64_cpsr_bits
+ 7, aarch64_cpsr_fields
+ 8 },
1408 { "SS", aarch64_cpsr_bits
+ 8, aarch64_cpsr_fields
+ 9 },
1409 { "V", aarch64_cpsr_bits
+ 9, aarch64_cpsr_fields
+ 10 },
1410 { "C", aarch64_cpsr_bits
+ 10, aarch64_cpsr_fields
+ 11 },
1411 { "Z", aarch64_cpsr_bits
+ 11, aarch64_cpsr_fields
+ 12 },
1412 { "N", aarch64_cpsr_bits
+ 12, NULL
}
1415 static struct reg_data_type_flags aarch64_cpsr_flags
[] = {
1416 { 4, aarch64_cpsr_fields
}
1419 static struct reg_data_type aarch64_flags_cpsr
[] = {
1420 {REG_TYPE_ARCH_DEFINED
, "cpsr_flags", REG_TYPE_CLASS_FLAGS
,
1421 {.reg_type_flags
= aarch64_cpsr_flags
} },
1424 static const struct {
1431 const char *feature
;
1432 struct reg_data_type
*data_type
;
1434 { ARMV8_R0
, "x0", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1435 { ARMV8_R1
, "x1", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1436 { ARMV8_R2
, "x2", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1437 { ARMV8_R3
, "x3", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1438 { ARMV8_R4
, "x4", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1439 { ARMV8_R5
, "x5", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1440 { ARMV8_R6
, "x6", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1441 { ARMV8_R7
, "x7", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1442 { ARMV8_R8
, "x8", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1443 { ARMV8_R9
, "x9", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1444 { ARMV8_R10
, "x10", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1445 { ARMV8_R11
, "x11", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1446 { ARMV8_R12
, "x12", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1447 { ARMV8_R13
, "x13", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1448 { ARMV8_R14
, "x14", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1449 { ARMV8_R15
, "x15", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1450 { ARMV8_R16
, "x16", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1451 { ARMV8_R17
, "x17", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1452 { ARMV8_R18
, "x18", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1453 { ARMV8_R19
, "x19", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1454 { ARMV8_R20
, "x20", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1455 { ARMV8_R21
, "x21", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1456 { ARMV8_R22
, "x22", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1457 { ARMV8_R23
, "x23", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1458 { ARMV8_R24
, "x24", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1459 { ARMV8_R25
, "x25", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1460 { ARMV8_R26
, "x26", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1461 { ARMV8_R27
, "x27", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1462 { ARMV8_R28
, "x28", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1463 { ARMV8_R29
, "x29", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1464 { ARMV8_R30
, "x30", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1466 { ARMV8_SP
, "sp", 64, ARM_MODE_ANY
, REG_TYPE_DATA_PTR
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1467 { ARMV8_PC
, "pc", 64, ARM_MODE_ANY
, REG_TYPE_CODE_PTR
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1468 { ARMV8_XPSR
, "cpsr", 32, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
,
1469 "general", "org.gnu.gdb.aarch64.core", aarch64_flags_cpsr
},
1470 { ARMV8_V0
, "v0", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1471 { ARMV8_V1
, "v1", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1472 { ARMV8_V2
, "v2", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1473 { ARMV8_V3
, "v3", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1474 { ARMV8_V4
, "v4", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1475 { ARMV8_V5
, "v5", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1476 { ARMV8_V6
, "v6", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1477 { ARMV8_V7
, "v7", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1478 { ARMV8_V8
, "v8", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1479 { ARMV8_V9
, "v9", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1480 { ARMV8_V10
, "v10", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1481 { ARMV8_V11
, "v11", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1482 { ARMV8_V12
, "v12", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1483 { ARMV8_V13
, "v13", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1484 { ARMV8_V14
, "v14", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1485 { ARMV8_V15
, "v15", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1486 { ARMV8_V16
, "v16", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1487 { ARMV8_V17
, "v17", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1488 { ARMV8_V18
, "v18", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1489 { ARMV8_V19
, "v19", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1490 { ARMV8_V20
, "v20", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1491 { ARMV8_V21
, "v21", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1492 { ARMV8_V22
, "v22", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1493 { ARMV8_V23
, "v23", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1494 { ARMV8_V24
, "v24", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1495 { ARMV8_V25
, "v25", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1496 { ARMV8_V26
, "v26", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1497 { ARMV8_V27
, "v27", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1498 { ARMV8_V28
, "v28", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1499 { ARMV8_V29
, "v29", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1500 { ARMV8_V30
, "v30", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1501 { ARMV8_V31
, "v31", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1502 { ARMV8_FPSR
, "fpsr", 32, ARM_MODE_ANY
, REG_TYPE_UINT32
, "simdfp", "org.gnu.gdb.aarch64.fpu", NULL
},
1503 { ARMV8_FPCR
, "fpcr", 32, ARM_MODE_ANY
, REG_TYPE_UINT32
, "simdfp", "org.gnu.gdb.aarch64.fpu", NULL
},
1505 { ARMV8_ELR_EL1
, "ELR_EL1", 64, ARMV8_64_EL1H
, REG_TYPE_CODE_PTR
, "banked", "net.sourceforge.openocd.banked",
1507 { ARMV8_ESR_EL1
, "ESR_EL1", 32, ARMV8_64_EL1H
, REG_TYPE_UINT32
, "banked", "net.sourceforge.openocd.banked",
1509 { ARMV8_SPSR_EL1
, "SPSR_EL1", 32, ARMV8_64_EL1H
, REG_TYPE_UINT32
, "banked", "net.sourceforge.openocd.banked",
1512 { ARMV8_ELR_EL2
, "ELR_EL2", 64, ARMV8_64_EL2H
, REG_TYPE_CODE_PTR
, "banked", "net.sourceforge.openocd.banked",
1514 { ARMV8_ESR_EL2
, "ESR_EL2", 32, ARMV8_64_EL2H
, REG_TYPE_UINT32
, "banked", "net.sourceforge.openocd.banked",
1516 { ARMV8_SPSR_EL2
, "SPSR_EL2", 32, ARMV8_64_EL2H
, REG_TYPE_UINT32
, "banked", "net.sourceforge.openocd.banked",
1519 { ARMV8_ELR_EL3
, "ELR_EL3", 64, ARMV8_64_EL3H
, REG_TYPE_CODE_PTR
, "banked", "net.sourceforge.openocd.banked",
1521 { ARMV8_ESR_EL3
, "ESR_EL3", 32, ARMV8_64_EL3H
, REG_TYPE_UINT32
, "banked", "net.sourceforge.openocd.banked",
1523 { ARMV8_SPSR_EL3
, "SPSR_EL3", 32, ARMV8_64_EL3H
, REG_TYPE_UINT32
, "banked", "net.sourceforge.openocd.banked",
1525 { ARMV8_PAUTH_DMASK
, "pauth_dmask", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, NULL
, "org.gnu.gdb.aarch64.pauth", NULL
},
1526 { ARMV8_PAUTH_CMASK
, "pauth_cmask", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, NULL
, "org.gnu.gdb.aarch64.pauth", NULL
},
1529 static const struct {
1537 const char *feature
;
1538 } armv8_regs32
[] = {
1539 { ARMV8_R0
, 0, "r0", 32, ARM_MODE_ANY
, REG_TYPE_UINT32
, "general", "org.gnu.gdb.arm.core" },
1540 { ARMV8_R1
, 0, "r1", 32, ARM_MODE_ANY
, REG_TYPE_UINT32
, "general", "org.gnu.gdb.arm.core" },
1541 { ARMV8_R2
, 0, "r2", 32, ARM_MODE_ANY
, REG_TYPE_UINT32
, "general", "org.gnu.gdb.arm.core" },
1542 { ARMV8_R3
, 0, "r3", 32, ARM_MODE_ANY
, REG_TYPE_UINT32
, "general", "org.gnu.gdb.arm.core" },
1543 { ARMV8_R4
, 0, "r4", 32, ARM_MODE_ANY
, REG_TYPE_UINT32
, "general", "org.gnu.gdb.arm.core" },
1544 { ARMV8_R5
, 0, "r5", 32, ARM_MODE_ANY
, REG_TYPE_UINT32
, "general", "org.gnu.gdb.arm.core" },
1545 { ARMV8_R6
, 0, "r6", 32, ARM_MODE_ANY
, REG_TYPE_UINT32
, "general", "org.gnu.gdb.arm.core" },
1546 { ARMV8_R7
, 0, "r7", 32, ARM_MODE_ANY
, REG_TYPE_UINT32
, "general", "org.gnu.gdb.arm.core" },
1547 { ARMV8_R8
, 0, "r8", 32, ARM_MODE_ANY
, REG_TYPE_UINT32
, "general", "org.gnu.gdb.arm.core" },
1548 { ARMV8_R9
, 0, "r9", 32, ARM_MODE_ANY
, REG_TYPE_UINT32
, "general", "org.gnu.gdb.arm.core" },
1549 { ARMV8_R10
, 0, "r10", 32, ARM_MODE_ANY
, REG_TYPE_UINT32
, "general", "org.gnu.gdb.arm.core" },
1550 { ARMV8_R11
, 0, "r11", 32, ARM_MODE_ANY
, REG_TYPE_UINT32
, "general", "org.gnu.gdb.arm.core" },
1551 { ARMV8_R12
, 0, "r12", 32, ARM_MODE_ANY
, REG_TYPE_UINT32
, "general", "org.gnu.gdb.arm.core" },
1552 { ARMV8_R13
, 0, "sp", 32, ARM_MODE_ANY
, REG_TYPE_DATA_PTR
, "general", "org.gnu.gdb.arm.core" },
1553 { ARMV8_R14
, 0, "lr", 32, ARM_MODE_ANY
, REG_TYPE_CODE_PTR
, "general", "org.gnu.gdb.arm.core" },
1554 { ARMV8_PC
, 0, "pc", 32, ARM_MODE_ANY
, REG_TYPE_CODE_PTR
, "general", "org.gnu.gdb.arm.core" },
1555 { ARMV8_XPSR
, 0, "cpsr", 32, ARM_MODE_ANY
, REG_TYPE_UINT32
, "general", "org.gnu.gdb.arm.core" },
1556 { ARMV8_V0
, 0, "d0", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1557 { ARMV8_V0
, 8, "d1", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1558 { ARMV8_V1
, 0, "d2", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1559 { ARMV8_V1
, 8, "d3", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1560 { ARMV8_V2
, 0, "d4", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1561 { ARMV8_V2
, 8, "d5", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1562 { ARMV8_V3
, 0, "d6", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1563 { ARMV8_V3
, 8, "d7", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1564 { ARMV8_V4
, 0, "d8", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1565 { ARMV8_V4
, 8, "d9", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1566 { ARMV8_V5
, 0, "d10", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1567 { ARMV8_V5
, 8, "d11", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1568 { ARMV8_V6
, 0, "d12", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1569 { ARMV8_V6
, 8, "d13", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1570 { ARMV8_V7
, 0, "d14", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1571 { ARMV8_V7
, 8, "d15", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1572 { ARMV8_V8
, 0, "d16", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1573 { ARMV8_V8
, 8, "d17", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1574 { ARMV8_V9
, 0, "d18", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1575 { ARMV8_V9
, 8, "d19", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1576 { ARMV8_V10
, 0, "d20", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1577 { ARMV8_V10
, 8, "d21", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1578 { ARMV8_V11
, 0, "d22", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1579 { ARMV8_V11
, 8, "d23", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1580 { ARMV8_V12
, 0, "d24", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1581 { ARMV8_V12
, 8, "d25", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1582 { ARMV8_V13
, 0, "d26", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1583 { ARMV8_V13
, 8, "d27", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1584 { ARMV8_V14
, 0, "d28", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1585 { ARMV8_V14
, 8, "d29", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1586 { ARMV8_V15
, 0, "d30", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1587 { ARMV8_V15
, 8, "d31", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1588 { ARMV8_FPSR
, 0, "fpscr", 32, ARM_MODE_ANY
, REG_TYPE_UINT32
, "float", "org.gnu.gdb.arm.vfp"},
1591 #define ARMV8_NUM_REGS ARRAY_SIZE(armv8_regs)
1592 #define ARMV8_NUM_REGS32 ARRAY_SIZE(armv8_regs32)
1594 static int armv8_get_core_reg(struct reg
*reg
)
1596 struct arm_reg
*armv8_reg
= reg
->arch_info
;
1597 struct target
*target
= armv8_reg
->target
;
1598 struct arm
*arm
= target_to_arm(target
);
1600 if (target
->state
!= TARGET_HALTED
)
1601 return ERROR_TARGET_NOT_HALTED
;
1603 return arm
->read_core_reg(target
, reg
, armv8_reg
->num
, arm
->core_mode
);
1606 static int armv8_set_core_reg(struct reg
*reg
, uint8_t *buf
)
1608 struct arm_reg
*armv8_reg
= reg
->arch_info
;
1609 struct target
*target
= armv8_reg
->target
;
1610 struct arm
*arm
= target_to_arm(target
);
1611 uint64_t value
= buf_get_u64(buf
, 0, reg
->size
);
1613 if (target
->state
!= TARGET_HALTED
)
1614 return ERROR_TARGET_NOT_HALTED
;
1616 if (reg
->size
<= 64) {
1617 if (reg
== arm
->cpsr
)
1618 armv8_set_cpsr(arm
, (uint32_t)value
);
1620 buf_set_u64(reg
->value
, 0, reg
->size
, value
);
1623 } else if (reg
->size
<= 128) {
1624 uint64_t hvalue
= buf_get_u64(buf
+ 8, 0, reg
->size
- 64);
1626 buf_set_u64(reg
->value
, 0, 64, value
);
1627 buf_set_u64(reg
->value
+ 8, 0, reg
->size
- 64, hvalue
);
1636 static const struct reg_arch_type armv8_reg_type
= {
1637 .get
= armv8_get_core_reg
,
1638 .set
= armv8_set_core_reg
,
1641 static int armv8_get_core_reg32(struct reg
*reg
)
1643 struct arm_reg
*armv8_reg
= reg
->arch_info
;
1644 struct target
*target
= armv8_reg
->target
;
1645 struct arm
*arm
= target_to_arm(target
);
1646 struct reg_cache
*cache
= arm
->core_cache
;
1650 if (target
->state
!= TARGET_HALTED
)
1651 return ERROR_TARGET_NOT_HALTED
;
1653 /* get the corresponding Aarch64 register */
1654 reg64
= cache
->reg_list
+ armv8_reg
->num
;
1660 retval
= arm
->read_core_reg(target
, reg64
, armv8_reg
->num
, arm
->core_mode
);
1661 if (retval
== ERROR_OK
)
1662 reg
->valid
= reg64
->valid
;
1667 static int armv8_set_core_reg32(struct reg
*reg
, uint8_t *buf
)
1669 struct arm_reg
*armv8_reg
= reg
->arch_info
;
1670 struct target
*target
= armv8_reg
->target
;
1671 struct arm
*arm
= target_to_arm(target
);
1672 struct reg_cache
*cache
= arm
->core_cache
;
1673 struct reg
*reg64
= cache
->reg_list
+ armv8_reg
->num
;
1674 uint32_t value
= buf_get_u32(buf
, 0, 32);
1676 if (target
->state
!= TARGET_HALTED
)
1677 return ERROR_TARGET_NOT_HALTED
;
1679 if (reg64
== arm
->cpsr
) {
1680 armv8_set_cpsr(arm
, value
);
1682 if (reg
->size
<= 32)
1683 buf_set_u32(reg
->value
, 0, 32, value
);
1684 else if (reg
->size
<= 64) {
1685 uint64_t value64
= buf_get_u64(buf
, 0, 64);
1686 buf_set_u64(reg
->value
, 0, 64, value64
);
1689 reg64
->valid
= true;
1692 reg64
->dirty
= true;
1697 static const struct reg_arch_type armv8_reg32_type
= {
1698 .get
= armv8_get_core_reg32
,
1699 .set
= armv8_set_core_reg32
,
1702 /** Builds cache of architecturally defined registers. */
1703 struct reg_cache
*armv8_build_reg_cache(struct target
*target
)
1705 struct armv8_common
*armv8
= target_to_armv8(target
);
1706 struct arm
*arm
= &armv8
->arm
;
1707 int num_regs
= ARMV8_NUM_REGS
;
1708 int num_regs32
= ARMV8_NUM_REGS32
;
1709 struct reg_cache
**cache_p
= register_get_last_cache_p(&target
->reg_cache
);
1710 struct reg_cache
*cache
= malloc(sizeof(struct reg_cache
));
1711 struct reg_cache
*cache32
= malloc(sizeof(struct reg_cache
));
1712 struct reg
*reg_list
= calloc(num_regs
, sizeof(struct reg
));
1713 struct reg
*reg_list32
= calloc(num_regs32
, sizeof(struct reg
));
1714 struct arm_reg
*arch_info
= calloc(num_regs
, sizeof(struct arm_reg
));
1715 struct reg_feature
*feature
;
1718 /* Build the process context cache */
1719 cache
->name
= "Aarch64 registers";
1720 cache
->next
= cache32
;
1721 cache
->reg_list
= reg_list
;
1722 cache
->num_regs
= num_regs
;
1724 for (i
= 0; i
< num_regs
; i
++) {
1725 arch_info
[i
].num
= armv8_regs
[i
].id
;
1726 arch_info
[i
].mode
= armv8_regs
[i
].mode
;
1727 arch_info
[i
].target
= target
;
1728 arch_info
[i
].arm
= arm
;
1730 reg_list
[i
].name
= armv8_regs
[i
].name
;
1731 reg_list
[i
].size
= armv8_regs
[i
].bits
;
1732 reg_list
[i
].value
= &arch_info
[i
].value
[0];
1733 reg_list
[i
].type
= &armv8_reg_type
;
1734 reg_list
[i
].arch_info
= &arch_info
[i
];
1736 reg_list
[i
].group
= armv8_regs
[i
].group
;
1737 reg_list
[i
].number
= i
;
1738 reg_list
[i
].exist
= true;
1739 reg_list
[i
].caller_save
= true; /* gdb defaults to true */
1741 feature
= calloc(1, sizeof(struct reg_feature
));
1743 feature
->name
= armv8_regs
[i
].feature
;
1744 reg_list
[i
].feature
= feature
;
1746 LOG_ERROR("unable to allocate feature list");
1748 reg_list
[i
].reg_data_type
= calloc(1, sizeof(struct reg_data_type
));
1749 if (reg_list
[i
].reg_data_type
) {
1750 if (!armv8_regs
[i
].data_type
)
1751 reg_list
[i
].reg_data_type
->type
= armv8_regs
[i
].type
;
1753 *reg_list
[i
].reg_data_type
= *armv8_regs
[i
].data_type
;
1755 LOG_ERROR("unable to allocate reg type list");
1757 if (i
== ARMV8_PAUTH_CMASK
|| i
== ARMV8_PAUTH_DMASK
)
1758 reg_list
[i
].exist
= armv8
->enable_pauth
;
1761 arm
->cpsr
= reg_list
+ ARMV8_XPSR
;
1762 arm
->pc
= reg_list
+ ARMV8_PC
;
1763 arm
->core_cache
= cache
;
1765 /* shadow cache for ARM mode registers */
1766 cache32
->name
= "Aarch32 registers";
1767 cache32
->next
= NULL
;
1768 cache32
->reg_list
= reg_list32
;
1769 cache32
->num_regs
= num_regs32
;
1771 for (i
= 0; i
< num_regs32
; i
++) {
1772 reg_list32
[i
].name
= armv8_regs32
[i
].name
;
1773 reg_list32
[i
].size
= armv8_regs32
[i
].bits
;
1774 reg_list32
[i
].value
= &arch_info
[armv8_regs32
[i
].id
].value
[armv8_regs32
[i
].mapping
];
1775 reg_list32
[i
].type
= &armv8_reg32_type
;
1776 reg_list32
[i
].arch_info
= &arch_info
[armv8_regs32
[i
].id
];
1777 reg_list32
[i
].group
= armv8_regs32
[i
].group
;
1778 reg_list32
[i
].number
= i
;
1779 reg_list32
[i
].exist
= true;
1780 reg_list32
[i
].caller_save
= true;
1782 feature
= calloc(1, sizeof(struct reg_feature
));
1784 feature
->name
= armv8_regs32
[i
].feature
;
1785 reg_list32
[i
].feature
= feature
;
1787 LOG_ERROR("unable to allocate feature list");
1789 reg_list32
[i
].reg_data_type
= calloc(1, sizeof(struct reg_data_type
));
1790 if (reg_list32
[i
].reg_data_type
)
1791 reg_list32
[i
].reg_data_type
->type
= armv8_regs32
[i
].type
;
1793 LOG_ERROR("unable to allocate reg type list");
1800 struct reg
*armv8_reg_current(struct arm
*arm
, unsigned regnum
)
1804 if (regnum
> (ARMV8_LAST_REG
- 1))
1807 r
= arm
->core_cache
->reg_list
+ regnum
;
1811 static void armv8_free_cache(struct reg_cache
*cache
, bool regs32
)
1819 for (i
= 0; i
< cache
->num_regs
; i
++) {
1820 reg
= &cache
->reg_list
[i
];
1823 free(reg
->reg_data_type
);
1827 free(cache
->reg_list
[0].arch_info
);
1828 free(cache
->reg_list
);
1832 void armv8_free_reg_cache(struct target
*target
)
1834 struct armv8_common
*armv8
= target_to_armv8(target
);
1835 struct arm
*arm
= &armv8
->arm
;
1836 struct reg_cache
*cache
= NULL
, *cache32
= NULL
;
1838 cache
= arm
->core_cache
;
1840 cache32
= cache
->next
;
1841 armv8_free_cache(cache32
, true);
1842 armv8_free_cache(cache
, false);
1843 arm
->core_cache
= NULL
;
1846 const struct command_registration armv8_command_handlers
[] = {
1848 .name
= "catch_exc",
1849 .handler
= armv8_handle_exception_catch_command
,
1850 .mode
= COMMAND_EXEC
,
1851 .help
= "configure exception catch",
1852 .usage
= "[(nsec_el1,nsec_el2,sec_el1,sec_el3)+,off]",
1856 .handler
= armv8_pauth_command
,
1857 .mode
= COMMAND_CONFIG
,
1858 .help
= "enable or disable providing GDB with an 8-bytes mask to "
1859 "remove signature bits added by pointer authentication."
1860 "Pointer authentication feature is broken until gdb 12.1, going to be fixed. "
1861 "Consider using a newer version of gdb if you want enable "
1863 .usage
= "[on|off]",
1865 COMMAND_REGISTRATION_DONE
1868 const char *armv8_get_gdb_arch(const struct target
*target
)
1870 struct arm
*arm
= target_to_arm(target
);
1871 return arm
->core_state
== ARM_STATE_AARCH64
? "aarch64" : "arm";
1874 int armv8_get_gdb_reg_list(struct target
*target
,
1875 struct reg
**reg_list
[], int *reg_list_size
,
1876 enum target_register_class reg_class
)
1878 struct arm
*arm
= target_to_arm(target
);
1881 if (arm
->core_state
== ARM_STATE_AARCH64
) {
1883 LOG_DEBUG("Creating Aarch64 register list for target %s", target_name(target
));
1885 switch (reg_class
) {
1886 case REG_CLASS_GENERAL
:
1887 *reg_list_size
= ARMV8_V0
;
1888 *reg_list
= malloc(sizeof(struct reg
*) * (*reg_list_size
));
1890 for (i
= 0; i
< *reg_list_size
; i
++)
1891 (*reg_list
)[i
] = armv8_reg_current(arm
, i
);
1895 *reg_list_size
= ARMV8_LAST_REG
;
1896 *reg_list
= malloc(sizeof(struct reg
*) * (*reg_list_size
));
1898 for (i
= 0; i
< *reg_list_size
; i
++)
1899 (*reg_list
)[i
] = armv8_reg_current(arm
, i
);
1904 LOG_ERROR("not a valid register class type in query.");
1908 struct reg_cache
*cache32
= arm
->core_cache
->next
;
1910 LOG_DEBUG("Creating Aarch32 register list for target %s", target_name(target
));
1912 switch (reg_class
) {
1913 case REG_CLASS_GENERAL
:
1914 *reg_list_size
= ARMV8_R14
+ 3;
1915 *reg_list
= malloc(sizeof(struct reg
*) * (*reg_list_size
));
1917 for (i
= 0; i
< *reg_list_size
; i
++)
1918 (*reg_list
)[i
] = cache32
->reg_list
+ i
;
1922 *reg_list_size
= cache32
->num_regs
;
1923 *reg_list
= malloc(sizeof(struct reg
*) * (*reg_list_size
));
1925 for (i
= 0; i
< *reg_list_size
; i
++)
1926 (*reg_list
)[i
] = cache32
->reg_list
+ i
;
1930 LOG_ERROR("not a valid register class type in query.");
1936 int armv8_set_dbgreg_bits(struct armv8_common
*armv8
, unsigned int reg
, unsigned long mask
, unsigned long value
)
1941 int retval
= mem_ap_read_atomic_u32(armv8
->debug_ap
,
1942 armv8
->debug_base
+ reg
, &tmp
);
1943 if (retval
!= ERROR_OK
)
1946 /* clear bitfield */
1949 tmp
|= value
& mask
;
1951 /* write new value */
1952 retval
= mem_ap_write_atomic_u32(armv8
->debug_ap
,
1953 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)