1 /***************************************************************************
2 * Copyright (C) 2015 by David Ung *
4 * Copyright (C) 2018 by Liviu Ionescu *
7 * This program is free software; you can redistribute it and/or modify *
8 * it under the terms of the GNU General Public License as published by *
9 * the Free Software Foundation; either version 2 of the License, or *
10 * (at your option) any later version. *
12 * This program is distributed in the hope that it will be useful, *
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
15 * GNU General Public License for more details. *
17 * You should have received a copy of the GNU General Public License *
18 * along with this program; if not, write to the *
19 * Free Software Foundation, Inc., *
20 ***************************************************************************/
26 #include <helper/replacements.h>
29 #include "arm_disassembler.h"
32 #include <helper/binarybuffer.h>
33 #include <helper/command.h>
39 #include "armv8_opcodes.h"
41 #include "target_type.h"
42 #include "semihosting_common.h"
44 static const char * const armv8_state_strings
[] = {
45 "AArch32", "Thumb", "Jazelle", "ThumbEE", "AArch64",
51 } armv8_mode_data
[] = {
102 .psr
= ARMV8_64_EL2T
,
106 .psr
= ARMV8_64_EL2H
,
110 .psr
= ARMV8_64_EL3T
,
114 .psr
= ARMV8_64_EL3H
,
118 /** Map PSR mode bits to the name of an ARM processor operating mode. */
119 const char *armv8_mode_name(unsigned psr_mode
)
121 for (unsigned i
= 0; i
< ARRAY_SIZE(armv8_mode_data
); i
++) {
122 if (armv8_mode_data
[i
].psr
== psr_mode
)
123 return armv8_mode_data
[i
].name
;
125 LOG_ERROR("unrecognized psr mode: %#02x", psr_mode
);
126 return "UNRECOGNIZED";
129 static int armv8_read_reg(struct armv8_common
*armv8
, int regnum
, uint64_t *regval
)
131 struct arm_dpm
*dpm
= &armv8
->dpm
;
138 retval
= dpm
->instr_read_data_dcc_64(dpm
,
139 ARMV8_MSR_GP(SYSTEM_DBG_DBGDTR_EL0
, regnum
), &value_64
);
142 retval
= dpm
->instr_read_data_r0_64(dpm
,
143 ARMV8_MOVFSP_64(0), &value_64
);
146 retval
= dpm
->instr_read_data_r0_64(dpm
,
147 ARMV8_MRS_DLR(0), &value_64
);
150 retval
= dpm
->instr_read_data_r0(dpm
,
151 ARMV8_MRS_DSPSR(0), &value
);
155 retval
= dpm
->instr_read_data_r0(dpm
,
156 ARMV8_MRS_FPSR(0), &value
);
160 retval
= dpm
->instr_read_data_r0(dpm
,
161 ARMV8_MRS_FPCR(0), &value
);
165 retval
= dpm
->instr_read_data_r0_64(dpm
,
166 ARMV8_MRS(SYSTEM_ELR_EL1
, 0), &value_64
);
169 retval
= dpm
->instr_read_data_r0_64(dpm
,
170 ARMV8_MRS(SYSTEM_ELR_EL2
, 0), &value_64
);
173 retval
= dpm
->instr_read_data_r0_64(dpm
,
174 ARMV8_MRS(SYSTEM_ELR_EL3
, 0), &value_64
);
177 retval
= dpm
->instr_read_data_r0(dpm
,
178 ARMV8_MRS(SYSTEM_ESR_EL1
, 0), &value
);
182 retval
= dpm
->instr_read_data_r0(dpm
,
183 ARMV8_MRS(SYSTEM_ESR_EL2
, 0), &value
);
187 retval
= dpm
->instr_read_data_r0(dpm
,
188 ARMV8_MRS(SYSTEM_ESR_EL3
, 0), &value
);
192 retval
= dpm
->instr_read_data_r0(dpm
,
193 ARMV8_MRS(SYSTEM_SPSR_EL1
, 0), &value
);
197 retval
= dpm
->instr_read_data_r0(dpm
,
198 ARMV8_MRS(SYSTEM_SPSR_EL2
, 0), &value
);
202 retval
= dpm
->instr_read_data_r0(dpm
,
203 ARMV8_MRS(SYSTEM_SPSR_EL3
, 0), &value
);
211 if (retval
== ERROR_OK
&& regval
)
219 static int armv8_read_reg_simdfp_aarch64(struct armv8_common
*armv8
, int regnum
, uint64_t *lvalue
, uint64_t *hvalue
)
221 int retval
= ERROR_FAIL
;
222 struct arm_dpm
*dpm
= &armv8
->dpm
;
225 case ARMV8_V0
... ARMV8_V31
:
226 retval
= dpm
->instr_read_data_r0_64(dpm
,
227 ARMV8_MOV_GPR_VFP(0, (regnum
- ARMV8_V0
), 1), hvalue
);
228 if (retval
!= ERROR_OK
)
230 retval
= dpm
->instr_read_data_r0_64(dpm
,
231 ARMV8_MOV_GPR_VFP(0, (regnum
- ARMV8_V0
), 0), lvalue
);
242 static int armv8_write_reg(struct armv8_common
*armv8
, int regnum
, uint64_t value_64
)
244 struct arm_dpm
*dpm
= &armv8
->dpm
;
250 retval
= dpm
->instr_write_data_dcc_64(dpm
,
251 ARMV8_MRS(SYSTEM_DBG_DBGDTR_EL0
, regnum
),
255 retval
= dpm
->instr_write_data_r0_64(dpm
,
260 retval
= dpm
->instr_write_data_r0_64(dpm
,
266 retval
= dpm
->instr_write_data_r0(dpm
,
272 retval
= dpm
->instr_write_data_r0(dpm
,
278 retval
= dpm
->instr_write_data_r0(dpm
,
282 /* registers clobbered by taking exception in debug state */
284 retval
= dpm
->instr_write_data_r0_64(dpm
,
285 ARMV8_MSR_GP(SYSTEM_ELR_EL1
, 0), value_64
);
288 retval
= dpm
->instr_write_data_r0_64(dpm
,
289 ARMV8_MSR_GP(SYSTEM_ELR_EL2
, 0), value_64
);
292 retval
= dpm
->instr_write_data_r0_64(dpm
,
293 ARMV8_MSR_GP(SYSTEM_ELR_EL3
, 0), value_64
);
297 retval
= dpm
->instr_write_data_r0(dpm
,
298 ARMV8_MSR_GP(SYSTEM_ESR_EL1
, 0), value
);
302 retval
= dpm
->instr_write_data_r0(dpm
,
303 ARMV8_MSR_GP(SYSTEM_ESR_EL2
, 0), value
);
307 retval
= dpm
->instr_write_data_r0(dpm
,
308 ARMV8_MSR_GP(SYSTEM_ESR_EL3
, 0), value
);
312 retval
= dpm
->instr_write_data_r0(dpm
,
313 ARMV8_MSR_GP(SYSTEM_SPSR_EL1
, 0), value
);
317 retval
= dpm
->instr_write_data_r0(dpm
,
318 ARMV8_MSR_GP(SYSTEM_SPSR_EL2
, 0), value
);
322 retval
= dpm
->instr_write_data_r0(dpm
,
323 ARMV8_MSR_GP(SYSTEM_SPSR_EL3
, 0), value
);
333 static int armv8_write_reg_simdfp_aarch64(struct armv8_common
*armv8
, int regnum
, uint64_t lvalue
, uint64_t hvalue
)
335 int retval
= ERROR_FAIL
;
336 struct arm_dpm
*dpm
= &armv8
->dpm
;
339 case ARMV8_V0
... ARMV8_V31
:
340 retval
= dpm
->instr_write_data_r0_64(dpm
,
341 ARMV8_MOV_VFP_GPR((regnum
- ARMV8_V0
), 0, 1), hvalue
);
342 if (retval
!= ERROR_OK
)
344 retval
= dpm
->instr_write_data_r0_64(dpm
,
345 ARMV8_MOV_VFP_GPR((regnum
- ARMV8_V0
), 0, 0), lvalue
);
356 static int armv8_read_reg32(struct armv8_common
*armv8
, int regnum
, uint64_t *regval
)
358 struct arm_dpm
*dpm
= &armv8
->dpm
;
363 case ARMV8_R0
... ARMV8_R14
:
364 /* return via DCC: "MCR p14, 0, Rnum, c0, c5, 0" */
365 retval
= dpm
->instr_read_data_dcc(dpm
,
366 ARMV4_5_MCR(14, 0, regnum
, 0, 5, 0),
370 retval
= dpm
->instr_read_data_dcc(dpm
,
371 ARMV4_5_MCR(14, 0, 13, 0, 5, 0),
375 retval
= dpm
->instr_read_data_r0(dpm
,
380 retval
= dpm
->instr_read_data_r0(dpm
,
384 case ARMV8_ELR_EL1
: /* mapped to LR_svc */
385 retval
= dpm
->instr_read_data_dcc(dpm
,
386 ARMV4_5_MCR(14, 0, 14, 0, 5, 0),
389 case ARMV8_ELR_EL2
: /* mapped to ELR_hyp */
390 retval
= dpm
->instr_read_data_r0(dpm
,
391 ARMV8_MRS_T1(0, 14, 0, 1),
394 case ARMV8_ELR_EL3
: /* mapped to LR_mon */
395 retval
= dpm
->instr_read_data_dcc(dpm
,
396 ARMV4_5_MCR(14, 0, 14, 0, 5, 0),
399 case ARMV8_ESR_EL1
: /* mapped to DFSR */
400 retval
= dpm
->instr_read_data_r0(dpm
,
401 ARMV4_5_MRC(15, 0, 0, 5, 0, 0),
404 case ARMV8_ESR_EL2
: /* mapped to HSR */
405 retval
= dpm
->instr_read_data_r0(dpm
,
406 ARMV4_5_MRC(15, 4, 0, 5, 2, 0),
409 case ARMV8_ESR_EL3
: /* FIXME: no equivalent in aarch32? */
412 case ARMV8_SPSR_EL1
: /* mapped to SPSR_svc */
413 retval
= dpm
->instr_read_data_r0(dpm
,
414 ARMV8_MRS_xPSR_T1(1, 0),
417 case ARMV8_SPSR_EL2
: /* mapped to SPSR_hyp */
418 retval
= dpm
->instr_read_data_r0(dpm
,
419 ARMV8_MRS_xPSR_T1(1, 0),
422 case ARMV8_SPSR_EL3
: /* mapped to SPSR_mon */
423 retval
= dpm
->instr_read_data_r0(dpm
,
424 ARMV8_MRS_xPSR_T1(1, 0),
428 /* "VMRS r0, FPSCR"; then return via DCC */
429 retval
= dpm
->instr_read_data_r0(dpm
,
430 ARMV4_5_VMRS(0), &value
);
437 if (retval
== ERROR_OK
&& regval
)
443 static int armv8_read_reg_simdfp_aarch32(struct armv8_common
*armv8
, int regnum
, uint64_t *lvalue
, uint64_t *hvalue
)
445 int retval
= ERROR_FAIL
;
446 struct arm_dpm
*dpm
= &armv8
->dpm
;
447 struct reg
*reg_r1
= dpm
->arm
->core_cache
->reg_list
+ ARMV8_R1
;
448 uint32_t value_r0
= 0, value_r1
= 0;
449 unsigned num
= (regnum
- ARMV8_V0
) << 1;
452 case ARMV8_V0
... ARMV8_V15
:
453 /* we are going to write R1, mark it dirty */
454 reg_r1
->dirty
= true;
455 /* move from double word register to r0:r1: "vmov r0, r1, vm"
456 * then read r0 via dcc
458 retval
= dpm
->instr_read_data_r0(dpm
,
459 ARMV4_5_VMOV(1, 1, 0, (num
>> 4), (num
& 0xf)),
461 if (retval
!= ERROR_OK
)
463 /* read r1 via dcc */
464 retval
= dpm
->instr_read_data_dcc(dpm
,
465 ARMV4_5_MCR(14, 0, 1, 0, 5, 0),
467 if (retval
!= ERROR_OK
)
470 *lvalue
= ((*lvalue
) << 32) | value_r0
;
473 /* repeat above steps for high 64 bits of V register */
474 retval
= dpm
->instr_read_data_r0(dpm
,
475 ARMV4_5_VMOV(1, 1, 0, (num
>> 4), (num
& 0xf)),
477 if (retval
!= ERROR_OK
)
479 retval
= dpm
->instr_read_data_dcc(dpm
,
480 ARMV4_5_MCR(14, 0, 1, 0, 5, 0),
482 if (retval
!= ERROR_OK
)
485 *hvalue
= ((*hvalue
) << 32) | value_r0
;
495 static int armv8_write_reg32(struct armv8_common
*armv8
, int regnum
, uint64_t value
)
497 struct arm_dpm
*dpm
= &armv8
->dpm
;
501 case ARMV8_R0
... ARMV8_R14
:
502 /* load register from DCC: "MRC p14, 0, Rnum, c0, c5, 0" */
503 retval
= dpm
->instr_write_data_dcc(dpm
,
504 ARMV4_5_MRC(14, 0, regnum
, 0, 5, 0), value
);
507 retval
= dpm
->instr_write_data_dcc(dpm
,
508 ARMV4_5_MRC(14, 0, 13, 0, 5, 0), value
);
511 * read r0 from DCC; then "MOV pc, r0" */
512 retval
= dpm
->instr_write_data_r0(dpm
,
513 ARMV8_MCR_DLR(0), value
);
515 case ARMV8_xPSR
: /* CPSR */
516 /* read r0 from DCC, then "MCR r0, DSPSR" */
517 retval
= dpm
->instr_write_data_r0(dpm
,
518 ARMV8_MCR_DSPSR(0), value
);
520 case ARMV8_ELR_EL1
: /* mapped to LR_svc */
521 retval
= dpm
->instr_write_data_dcc(dpm
,
522 ARMV4_5_MRC(14, 0, 14, 0, 5, 0),
525 case ARMV8_ELR_EL2
: /* mapped to ELR_hyp */
526 retval
= dpm
->instr_write_data_r0(dpm
,
527 ARMV8_MSR_GP_T1(0, 14, 0, 1),
530 case ARMV8_ELR_EL3
: /* mapped to LR_mon */
531 retval
= dpm
->instr_write_data_dcc(dpm
,
532 ARMV4_5_MRC(14, 0, 14, 0, 5, 0),
535 case ARMV8_ESR_EL1
: /* mapped to DFSR */
536 retval
= dpm
->instr_write_data_r0(dpm
,
537 ARMV4_5_MCR(15, 0, 0, 5, 0, 0),
540 case ARMV8_ESR_EL2
: /* mapped to HSR */
541 retval
= dpm
->instr_write_data_r0(dpm
,
542 ARMV4_5_MCR(15, 4, 0, 5, 2, 0),
545 case ARMV8_ESR_EL3
: /* FIXME: no equivalent in aarch32? */
548 case ARMV8_SPSR_EL1
: /* mapped to SPSR_svc */
549 retval
= dpm
->instr_write_data_r0(dpm
,
550 ARMV8_MSR_GP_xPSR_T1(1, 0, 15),
553 case ARMV8_SPSR_EL2
: /* mapped to SPSR_hyp */
554 retval
= dpm
->instr_write_data_r0(dpm
,
555 ARMV8_MSR_GP_xPSR_T1(1, 0, 15),
558 case ARMV8_SPSR_EL3
: /* mapped to SPSR_mon */
559 retval
= dpm
->instr_write_data_r0(dpm
,
560 ARMV8_MSR_GP_xPSR_T1(1, 0, 15),
564 /* move to r0 from DCC, then "VMSR FPSCR, r0" */
565 retval
= dpm
->instr_write_data_r0(dpm
,
566 ARMV4_5_VMSR(0), value
);
577 static int armv8_write_reg_simdfp_aarch32(struct armv8_common
*armv8
, int regnum
, uint64_t lvalue
, uint64_t hvalue
)
579 int retval
= ERROR_FAIL
;
580 struct arm_dpm
*dpm
= &armv8
->dpm
;
581 struct reg
*reg_r1
= dpm
->arm
->core_cache
->reg_list
+ ARMV8_R1
;
582 uint32_t value_r0
= 0, value_r1
= 0;
583 unsigned num
= (regnum
- ARMV8_V0
) << 1;
586 case ARMV8_V0
... ARMV8_V15
:
587 /* we are going to write R1, mark it dirty */
588 reg_r1
->dirty
= true;
589 value_r1
= lvalue
>> 32;
590 value_r0
= lvalue
& 0xFFFFFFFF;
591 /* write value_r1 to r1 via dcc */
592 retval
= dpm
->instr_write_data_dcc(dpm
,
593 ARMV4_5_MRC(14, 0, 1, 0, 5, 0),
595 if (retval
!= ERROR_OK
)
597 /* write value_r0 to r0 via dcc then,
598 * move to double word register from r0:r1: "vmov vm, r0, r1"
600 retval
= dpm
->instr_write_data_r0(dpm
,
601 ARMV4_5_VMOV(0, 1, 0, (num
>> 4), (num
& 0xf)),
603 if (retval
!= ERROR_OK
)
607 /* repeat above steps for high 64 bits of V register */
608 value_r1
= hvalue
>> 32;
609 value_r0
= hvalue
& 0xFFFFFFFF;
610 retval
= dpm
->instr_write_data_dcc(dpm
,
611 ARMV4_5_MRC(14, 0, 1, 0, 5, 0),
613 if (retval
!= ERROR_OK
)
615 retval
= dpm
->instr_write_data_r0(dpm
,
616 ARMV4_5_VMOV(0, 1, 0, (num
>> 4), (num
& 0xf)),
627 void armv8_select_reg_access(struct armv8_common
*armv8
, bool is_aarch64
)
630 armv8
->read_reg_u64
= armv8_read_reg
;
631 armv8
->write_reg_u64
= armv8_write_reg
;
632 armv8
->read_reg_u128
= armv8_read_reg_simdfp_aarch64
;
633 armv8
->write_reg_u128
= armv8_write_reg_simdfp_aarch64
;
636 armv8
->read_reg_u64
= armv8_read_reg32
;
637 armv8
->write_reg_u64
= armv8_write_reg32
;
638 armv8
->read_reg_u128
= armv8_read_reg_simdfp_aarch32
;
639 armv8
->write_reg_u128
= armv8_write_reg_simdfp_aarch32
;
643 /* retrieve core id cluster id */
644 int armv8_read_mpidr(struct armv8_common
*armv8
)
646 int retval
= ERROR_FAIL
;
647 struct arm
*arm
= &armv8
->arm
;
648 struct arm_dpm
*dpm
= armv8
->arm
.dpm
;
651 retval
= dpm
->prepare(dpm
);
652 if (retval
!= ERROR_OK
)
655 /* check if we're in an unprivileged mode */
656 if (armv8_curel_from_core_mode(arm
->core_mode
) < SYSTEM_CUREL_EL1
) {
657 retval
= armv8_dpm_modeswitch(dpm
, ARMV8_64_EL1H
);
658 if (retval
!= ERROR_OK
)
662 retval
= dpm
->instr_read_data_r0(dpm
, armv8_opcode(armv8
, READ_REG_MPIDR
), &mpidr
);
663 if (retval
!= ERROR_OK
)
665 if (mpidr
& 1U<<31) {
666 armv8
->multi_processor_system
= (mpidr
>> 30) & 1;
667 armv8
->cluster_id
= (mpidr
>> 8) & 0xf;
668 armv8
->cpu_id
= mpidr
& 0x3;
669 LOG_INFO("%s cluster %x core %x %s", target_name(armv8
->arm
.target
),
672 armv8
->multi_processor_system
== 0 ? "multi core" : "single core");
674 LOG_ERROR("mpidr not in multiprocessor format");
677 armv8_dpm_modeswitch(dpm
, ARM_MODE_ANY
);
683 * Configures host-side ARM records to reflect the specified CPSR.
684 * Later, code can use arm_reg_current() to map register numbers
685 * according to how they are exposed by this mode.
687 void armv8_set_cpsr(struct arm
*arm
, uint32_t cpsr
)
689 uint32_t mode
= cpsr
& 0x1F;
691 /* NOTE: this may be called very early, before the register
692 * cache is set up. We can't defend against many errors, in
693 * particular against CPSRs that aren't valid *here* ...
696 buf_set_u32(arm
->cpsr
->value
, 0, 32, cpsr
);
697 arm
->cpsr
->valid
= true;
698 arm
->cpsr
->dirty
= false;
701 /* Older ARMs won't have the J bit */
702 enum arm_state state
= 0xFF;
704 if ((cpsr
& 0x10) != 0) {
706 if (cpsr
& (1 << 5)) { /* T */
707 if (cpsr
& (1 << 24)) { /* J */
708 LOG_WARNING("ThumbEE -- incomplete support");
709 state
= ARM_STATE_THUMB_EE
;
711 state
= ARM_STATE_THUMB
;
713 if (cpsr
& (1 << 24)) { /* J */
714 LOG_ERROR("Jazelle state handling is BROKEN!");
715 state
= ARM_STATE_JAZELLE
;
717 state
= ARM_STATE_ARM
;
721 state
= ARM_STATE_AARCH64
;
724 arm
->core_state
= state
;
725 arm
->core_mode
= mode
;
727 LOG_DEBUG("set CPSR %#8.8x: %s mode, %s state", (unsigned) cpsr
,
728 armv8_mode_name(arm
->core_mode
),
729 armv8_state_strings
[arm
->core_state
]);
732 static void armv8_show_fault_registers32(struct armv8_common
*armv8
)
734 uint32_t dfsr
, ifsr
, dfar
, ifar
;
735 struct arm_dpm
*dpm
= armv8
->arm
.dpm
;
738 retval
= dpm
->prepare(dpm
);
739 if (retval
!= ERROR_OK
)
742 /* ARMV4_5_MRC(cpnum, op1, r0, crn, crm, op2) */
744 /* c5/c0 - {data, instruction} fault status registers */
745 retval
= dpm
->instr_read_data_r0(dpm
,
746 ARMV4_5_MRC(15, 0, 0, 5, 0, 0),
748 if (retval
!= ERROR_OK
)
751 retval
= dpm
->instr_read_data_r0(dpm
,
752 ARMV4_5_MRC(15, 0, 0, 5, 0, 1),
754 if (retval
!= ERROR_OK
)
757 /* c6/c0 - {data, instruction} fault address registers */
758 retval
= dpm
->instr_read_data_r0(dpm
,
759 ARMV4_5_MRC(15, 0, 0, 6, 0, 0),
761 if (retval
!= ERROR_OK
)
764 retval
= dpm
->instr_read_data_r0(dpm
,
765 ARMV4_5_MRC(15, 0, 0, 6, 0, 2),
767 if (retval
!= ERROR_OK
)
770 LOG_USER("Data fault registers DFSR: %8.8" PRIx32
771 ", DFAR: %8.8" PRIx32
, dfsr
, dfar
);
772 LOG_USER("Instruction fault registers IFSR: %8.8" PRIx32
773 ", IFAR: %8.8" PRIx32
, ifsr
, ifar
);
776 /* (void) */ dpm
->finish(dpm
);
779 static __attribute__((unused
)) void armv8_show_fault_registers(struct target
*target
)
781 struct armv8_common
*armv8
= target_to_armv8(target
);
783 if (armv8
->arm
.core_state
!= ARM_STATE_AARCH64
)
784 armv8_show_fault_registers32(armv8
);
787 static uint8_t armv8_pa_size(uint32_t ps
)
810 LOG_INFO("Unknown physical address size");
816 static __attribute__((unused
)) int armv8_read_ttbcr32(struct target
*target
)
818 struct armv8_common
*armv8
= target_to_armv8(target
);
819 struct arm_dpm
*dpm
= armv8
->arm
.dpm
;
820 uint32_t ttbcr
, ttbcr_n
;
821 int retval
= dpm
->prepare(dpm
);
822 if (retval
!= ERROR_OK
)
824 /* MRC p15,0,<Rt>,c2,c0,2 ; Read CP15 Translation Table Base Control Register*/
825 retval
= dpm
->instr_read_data_r0(dpm
,
826 ARMV4_5_MRC(15, 0, 0, 2, 0, 2),
828 if (retval
!= ERROR_OK
)
831 LOG_DEBUG("ttbcr %" PRIx32
, ttbcr
);
833 ttbcr_n
= ttbcr
& 0x7;
834 armv8
->armv8_mmu
.ttbcr
= ttbcr
;
837 * ARM Architecture Reference Manual (ARMv7-A and ARMv7-R edition),
838 * document # ARM DDI 0406C
840 armv8
->armv8_mmu
.ttbr_range
[0] = 0xffffffff >> ttbcr_n
;
841 armv8
->armv8_mmu
.ttbr_range
[1] = 0xffffffff;
842 armv8
->armv8_mmu
.ttbr_mask
[0] = 0xffffffff << (14 - ttbcr_n
);
843 armv8
->armv8_mmu
.ttbr_mask
[1] = 0xffffffff << 14;
845 LOG_DEBUG("ttbr1 %s, ttbr0_mask %" PRIx32
" ttbr1_mask %" PRIx32
,
846 (ttbcr_n
!= 0) ? "used" : "not used",
847 armv8
->armv8_mmu
.ttbr_mask
[0],
848 armv8
->armv8_mmu
.ttbr_mask
[1]);
855 static __attribute__((unused
)) int armv8_read_ttbcr(struct target
*target
)
857 struct armv8_common
*armv8
= target_to_armv8(target
);
858 struct arm_dpm
*dpm
= armv8
->arm
.dpm
;
859 struct arm
*arm
= &armv8
->arm
;
863 int retval
= dpm
->prepare(dpm
);
864 if (retval
!= ERROR_OK
)
867 /* clear ttrr1_used and ttbr0_mask */
868 memset(&armv8
->armv8_mmu
.ttbr1_used
, 0, sizeof(armv8
->armv8_mmu
.ttbr1_used
));
869 memset(&armv8
->armv8_mmu
.ttbr0_mask
, 0, sizeof(armv8
->armv8_mmu
.ttbr0_mask
));
871 switch (armv8_curel_from_core_mode(arm
->core_mode
)) {
872 case SYSTEM_CUREL_EL3
:
873 retval
= dpm
->instr_read_data_r0(dpm
,
874 ARMV8_MRS(SYSTEM_TCR_EL3
, 0),
876 retval
+= dpm
->instr_read_data_r0_64(dpm
,
877 ARMV8_MRS(SYSTEM_TTBR0_EL3
, 0),
879 if (retval
!= ERROR_OK
)
881 armv8
->va_size
= 64 - (ttbcr
& 0x3F);
882 armv8
->pa_size
= armv8_pa_size((ttbcr
>> 16) & 7);
883 armv8
->page_size
= (ttbcr
>> 14) & 3;
885 case SYSTEM_CUREL_EL2
:
886 retval
= dpm
->instr_read_data_r0(dpm
,
887 ARMV8_MRS(SYSTEM_TCR_EL2
, 0),
889 retval
+= dpm
->instr_read_data_r0_64(dpm
,
890 ARMV8_MRS(SYSTEM_TTBR0_EL2
, 0),
892 if (retval
!= ERROR_OK
)
894 armv8
->va_size
= 64 - (ttbcr
& 0x3F);
895 armv8
->pa_size
= armv8_pa_size((ttbcr
>> 16) & 7);
896 armv8
->page_size
= (ttbcr
>> 14) & 3;
898 case SYSTEM_CUREL_EL0
:
899 armv8_dpm_modeswitch(dpm
, ARMV8_64_EL1H
);
901 case SYSTEM_CUREL_EL1
:
902 retval
= dpm
->instr_read_data_r0_64(dpm
,
903 ARMV8_MRS(SYSTEM_TCR_EL1
, 0),
905 armv8
->va_size
= 64 - (ttbcr_64
& 0x3F);
906 armv8
->pa_size
= armv8_pa_size((ttbcr_64
>> 32) & 7);
907 armv8
->page_size
= (ttbcr_64
>> 14) & 3;
908 armv8
->armv8_mmu
.ttbr1_used
= (((ttbcr_64
>> 16) & 0x3F) != 0) ? 1 : 0;
909 armv8
->armv8_mmu
.ttbr0_mask
= 0x0000FFFFFFFFFFFF;
910 retval
+= dpm
->instr_read_data_r0_64(dpm
,
911 ARMV8_MRS(SYSTEM_TTBR0_EL1
| (armv8
->armv8_mmu
.ttbr1_used
), 0),
913 if (retval
!= ERROR_OK
)
917 LOG_ERROR("unknown core state");
921 if (retval
!= ERROR_OK
)
924 if (armv8
->armv8_mmu
.ttbr1_used
== 1)
925 LOG_INFO("TTBR0 access above %" PRIx64
, (uint64_t)(armv8
->armv8_mmu
.ttbr0_mask
));
928 armv8_dpm_modeswitch(dpm
, ARM_MODE_ANY
);
933 /* method adapted to cortex A : reused arm v4 v5 method*/
934 int armv8_mmu_translate_va(struct target
*target
, target_addr_t va
, target_addr_t
*val
)
939 /* V8 method VA TO PA */
940 int armv8_mmu_translate_va_pa(struct target
*target
, target_addr_t va
,
941 target_addr_t
*val
, int meminfo
)
943 struct armv8_common
*armv8
= target_to_armv8(target
);
944 struct arm
*arm
= target_to_arm(target
);
945 struct arm_dpm
*dpm
= &armv8
->dpm
;
946 enum arm_mode target_mode
= ARM_MODE_ANY
;
951 static const char * const shared_name
[] = {
952 "Non-", "UNDEFINED ", "Outer ", "Inner "
955 static const char * const secure_name
[] = {
956 "Secure", "Not Secure"
959 if (target
->state
!= TARGET_HALTED
) {
960 LOG_WARNING("target %s not halted", target_name(target
));
961 return ERROR_TARGET_NOT_HALTED
;
964 retval
= dpm
->prepare(dpm
);
965 if (retval
!= ERROR_OK
)
968 switch (armv8_curel_from_core_mode(arm
->core_mode
)) {
969 case SYSTEM_CUREL_EL0
:
970 instr
= ARMV8_SYS(SYSTEM_ATS12E0R
, 0);
971 /* can only execute instruction at EL2 */
972 target_mode
= ARMV8_64_EL2H
;
974 case SYSTEM_CUREL_EL1
:
975 instr
= ARMV8_SYS(SYSTEM_ATS12E1R
, 0);
976 /* can only execute instruction at EL2 */
977 target_mode
= ARMV8_64_EL2H
;
979 case SYSTEM_CUREL_EL2
:
980 instr
= ARMV8_SYS(SYSTEM_ATS1E2R
, 0);
982 case SYSTEM_CUREL_EL3
:
983 instr
= ARMV8_SYS(SYSTEM_ATS1E3R
, 0);
990 if (target_mode
!= ARM_MODE_ANY
)
991 armv8_dpm_modeswitch(dpm
, target_mode
);
993 /* write VA to R0 and execute translation instruction */
994 retval
= dpm
->instr_write_data_r0_64(dpm
, instr
, (uint64_t)va
);
995 /* read result from PAR_EL1 */
996 if (retval
== ERROR_OK
)
997 retval
= dpm
->instr_read_data_r0_64(dpm
, ARMV8_MRS(SYSTEM_PAR_EL1
, 0), &par
);
999 /* switch back to saved PE mode */
1000 if (target_mode
!= ARM_MODE_ANY
)
1001 armv8_dpm_modeswitch(dpm
, ARM_MODE_ANY
);
1005 if (retval
!= ERROR_OK
)
1009 LOG_ERROR("Address translation failed at stage %i, FST=%x, PTW=%i",
1010 ((int)(par
>> 9) & 1)+1, (int)(par
>> 1) & 0x3f, (int)(par
>> 8) & 1);
1013 retval
= ERROR_FAIL
;
1015 *val
= (par
& 0xFFFFFFFFF000UL
) | (va
& 0xFFF);
1017 int SH
= (par
>> 7) & 3;
1018 int NS
= (par
>> 9) & 1;
1019 int ATTR
= (par
>> 56) & 0xFF;
1021 char *memtype
= (ATTR
& 0xF0) == 0 ? "Device Memory" : "Normal Memory";
1023 LOG_USER("%sshareable, %s",
1024 shared_name
[SH
], secure_name
[NS
]);
1025 LOG_USER("%s", memtype
);
1032 COMMAND_HANDLER(armv8_handle_exception_catch_command
)
1034 struct target
*target
= get_current_target(CMD_CTX
);
1035 struct armv8_common
*armv8
= target_to_armv8(target
);
1036 uint32_t edeccr
= 0;
1037 unsigned int argp
= 0;
1040 static const struct jim_nvp nvp_ecatch_modes
[] = {
1041 { .name
= "off", .value
= 0 },
1042 { .name
= "nsec_el1", .value
= (1 << 5) },
1043 { .name
= "nsec_el2", .value
= (2 << 5) },
1044 { .name
= "nsec_el12", .value
= (3 << 5) },
1045 { .name
= "sec_el1", .value
= (1 << 1) },
1046 { .name
= "sec_el3", .value
= (4 << 1) },
1047 { .name
= "sec_el13", .value
= (5 << 1) },
1048 { .name
= NULL
, .value
= -1 },
1050 const struct jim_nvp
*n
;
1052 if (CMD_ARGC
== 0) {
1053 const char *sec
= NULL
, *nsec
= NULL
;
1055 retval
= mem_ap_read_atomic_u32(armv8
->debug_ap
,
1056 armv8
->debug_base
+ CPUV8_DBG_ECCR
, &edeccr
);
1057 if (retval
!= ERROR_OK
)
1060 n
= jim_nvp_value2name_simple(nvp_ecatch_modes
, edeccr
& 0x0f);
1064 n
= jim_nvp_value2name_simple(nvp_ecatch_modes
, edeccr
& 0xf0);
1068 if (!sec
|| !nsec
) {
1069 LOG_WARNING("Exception Catch: unknown exception catch configuration: EDECCR = %02" PRIx32
, edeccr
& 0xff);
1073 command_print(CMD
, "Exception Catch: Secure: %s, Non-Secure: %s", sec
, nsec
);
1077 while (argp
< CMD_ARGC
) {
1078 n
= jim_nvp_name2value_simple(nvp_ecatch_modes
, CMD_ARGV
[argp
]);
1080 LOG_ERROR("Unknown option: %s", CMD_ARGV
[argp
]);
1084 LOG_DEBUG("found: %s", n
->name
);
1090 retval
= mem_ap_write_atomic_u32(armv8
->debug_ap
,
1091 armv8
->debug_base
+ CPUV8_DBG_ECCR
, edeccr
);
1092 if (retval
!= ERROR_OK
)
1098 int armv8_handle_cache_info_command(struct command_invocation
*cmd
,
1099 struct armv8_cache_common
*armv8_cache
)
1101 if (armv8_cache
->info
== -1) {
1102 command_print(cmd
, "cache not yet identified");
1106 if (armv8_cache
->display_cache_info
)
1107 armv8_cache
->display_cache_info(cmd
, armv8_cache
);
1111 static int armv8_setup_semihosting(struct target
*target
, int enable
)
1116 int armv8_init_arch_info(struct target
*target
, struct armv8_common
*armv8
)
1118 struct arm
*arm
= &armv8
->arm
;
1119 arm
->arch_info
= armv8
;
1120 target
->arch_info
= &armv8
->arm
;
1121 arm
->setup_semihosting
= armv8_setup_semihosting
;
1122 /* target is useful in all function arm v4 5 compatible */
1123 armv8
->arm
.target
= target
;
1124 armv8
->arm
.common_magic
= ARM_COMMON_MAGIC
;
1125 armv8
->common_magic
= ARMV8_COMMON_MAGIC
;
1127 armv8
->armv8_mmu
.armv8_cache
.l2_cache
= NULL
;
1128 armv8
->armv8_mmu
.armv8_cache
.info
= -1;
1129 armv8
->armv8_mmu
.armv8_cache
.flush_all_data_cache
= NULL
;
1130 armv8
->armv8_mmu
.armv8_cache
.display_cache_info
= NULL
;
1134 static int armv8_aarch64_state(struct target
*target
)
1136 struct arm
*arm
= target_to_arm(target
);
1138 if (arm
->common_magic
!= ARM_COMMON_MAGIC
) {
1139 LOG_ERROR("BUG: called for a non-ARM target");
1143 LOG_USER("%s halted in %s state due to %s, current mode: %s\n"
1144 "cpsr: 0x%8.8" PRIx32
" pc: 0x%" PRIx64
"%s",
1145 target_name(target
),
1146 armv8_state_strings
[arm
->core_state
],
1147 debug_reason_name(target
),
1148 armv8_mode_name(arm
->core_mode
),
1149 buf_get_u32(arm
->cpsr
->value
, 0, 32),
1150 buf_get_u64(arm
->pc
->value
, 0, 64),
1151 (target
->semihosting
&& target
->semihosting
->is_active
) ? ", semihosting" : "");
1156 int armv8_arch_state(struct target
*target
)
1158 static const char * const state
[] = {
1159 "disabled", "enabled"
1162 struct armv8_common
*armv8
= target_to_armv8(target
);
1163 struct arm
*arm
= &armv8
->arm
;
1165 if (armv8
->common_magic
!= ARMV8_COMMON_MAGIC
) {
1166 LOG_ERROR("BUG: called for a non-Armv8 target");
1167 return ERROR_COMMAND_SYNTAX_ERROR
;
1170 if (arm
->core_state
== ARM_STATE_AARCH64
)
1171 armv8_aarch64_state(target
);
1173 arm_arch_state(target
);
1175 LOG_USER("MMU: %s, D-Cache: %s, I-Cache: %s",
1176 state
[armv8
->armv8_mmu
.mmu_enabled
],
1177 state
[armv8
->armv8_mmu
.armv8_cache
.d_u_cache_enabled
],
1178 state
[armv8
->armv8_mmu
.armv8_cache
.i_cache_enabled
]);
1180 if (arm
->core_mode
== ARM_MODE_ABT
)
1181 armv8_show_fault_registers(target
);
1183 if (target
->debug_reason
== DBG_REASON_WATCHPOINT
)
1184 LOG_USER("Watchpoint triggered at " TARGET_ADDR_FMT
, armv8
->dpm
.wp_addr
);
1189 static struct reg_data_type aarch64_vector_base_types
[] = {
1190 {REG_TYPE_IEEE_DOUBLE
, "ieee_double", 0, {NULL
} },
1191 {REG_TYPE_UINT64
, "uint64", 0, {NULL
} },
1192 {REG_TYPE_INT64
, "int64", 0, {NULL
} },
1193 {REG_TYPE_IEEE_SINGLE
, "ieee_single", 0, {NULL
} },
1194 {REG_TYPE_UINT32
, "uint32", 0, {NULL
} },
1195 {REG_TYPE_INT32
, "int32", 0, {NULL
} },
1196 {REG_TYPE_UINT16
, "uint16", 0, {NULL
} },
1197 {REG_TYPE_INT16
, "int16", 0, {NULL
} },
1198 {REG_TYPE_UINT8
, "uint8", 0, {NULL
} },
1199 {REG_TYPE_INT8
, "int8", 0, {NULL
} },
1200 {REG_TYPE_UINT128
, "uint128", 0, {NULL
} },
1201 {REG_TYPE_INT128
, "int128", 0, {NULL
} }
1204 static struct reg_data_type_vector aarch64_vector_types
[] = {
1205 {aarch64_vector_base_types
+ 0, 2},
1206 {aarch64_vector_base_types
+ 1, 2},
1207 {aarch64_vector_base_types
+ 2, 2},
1208 {aarch64_vector_base_types
+ 3, 4},
1209 {aarch64_vector_base_types
+ 4, 4},
1210 {aarch64_vector_base_types
+ 5, 4},
1211 {aarch64_vector_base_types
+ 6, 8},
1212 {aarch64_vector_base_types
+ 7, 8},
1213 {aarch64_vector_base_types
+ 8, 16},
1214 {aarch64_vector_base_types
+ 9, 16},
1215 {aarch64_vector_base_types
+ 10, 01},
1216 {aarch64_vector_base_types
+ 11, 01},
1219 static struct reg_data_type aarch64_fpu_vector
[] = {
1220 {REG_TYPE_ARCH_DEFINED
, "v2d", REG_TYPE_CLASS_VECTOR
, {aarch64_vector_types
+ 0} },
1221 {REG_TYPE_ARCH_DEFINED
, "v2u", REG_TYPE_CLASS_VECTOR
, {aarch64_vector_types
+ 1} },
1222 {REG_TYPE_ARCH_DEFINED
, "v2i", REG_TYPE_CLASS_VECTOR
, {aarch64_vector_types
+ 2} },
1223 {REG_TYPE_ARCH_DEFINED
, "v4f", REG_TYPE_CLASS_VECTOR
, {aarch64_vector_types
+ 3} },
1224 {REG_TYPE_ARCH_DEFINED
, "v4u", REG_TYPE_CLASS_VECTOR
, {aarch64_vector_types
+ 4} },
1225 {REG_TYPE_ARCH_DEFINED
, "v4i", REG_TYPE_CLASS_VECTOR
, {aarch64_vector_types
+ 5} },
1226 {REG_TYPE_ARCH_DEFINED
, "v8u", REG_TYPE_CLASS_VECTOR
, {aarch64_vector_types
+ 6} },
1227 {REG_TYPE_ARCH_DEFINED
, "v8i", REG_TYPE_CLASS_VECTOR
, {aarch64_vector_types
+ 7} },
1228 {REG_TYPE_ARCH_DEFINED
, "v16u", REG_TYPE_CLASS_VECTOR
, {aarch64_vector_types
+ 8} },
1229 {REG_TYPE_ARCH_DEFINED
, "v16i", REG_TYPE_CLASS_VECTOR
, {aarch64_vector_types
+ 9} },
1230 {REG_TYPE_ARCH_DEFINED
, "v1u", REG_TYPE_CLASS_VECTOR
, {aarch64_vector_types
+ 10} },
1231 {REG_TYPE_ARCH_DEFINED
, "v1i", REG_TYPE_CLASS_VECTOR
, {aarch64_vector_types
+ 11} },
1234 static struct reg_data_type_union_field aarch64_union_fields_vnd
[] = {
1235 {"f", aarch64_fpu_vector
+ 0, aarch64_union_fields_vnd
+ 1},
1236 {"u", aarch64_fpu_vector
+ 1, aarch64_union_fields_vnd
+ 2},
1237 {"s", aarch64_fpu_vector
+ 2, NULL
},
1240 static struct reg_data_type_union_field aarch64_union_fields_vns
[] = {
1241 {"f", aarch64_fpu_vector
+ 3, aarch64_union_fields_vns
+ 1},
1242 {"u", aarch64_fpu_vector
+ 4, aarch64_union_fields_vns
+ 2},
1243 {"s", aarch64_fpu_vector
+ 5, NULL
},
1246 static struct reg_data_type_union_field aarch64_union_fields_vnh
[] = {
1247 {"u", aarch64_fpu_vector
+ 6, aarch64_union_fields_vnh
+ 1},
1248 {"s", aarch64_fpu_vector
+ 7, NULL
},
1251 static struct reg_data_type_union_field aarch64_union_fields_vnb
[] = {
1252 {"u", aarch64_fpu_vector
+ 8, aarch64_union_fields_vnb
+ 1},
1253 {"s", aarch64_fpu_vector
+ 9, NULL
},
1256 static struct reg_data_type_union_field aarch64_union_fields_vnq
[] = {
1257 {"u", aarch64_fpu_vector
+ 10, aarch64_union_fields_vnq
+ 1},
1258 {"s", aarch64_fpu_vector
+ 11, NULL
},
1261 static struct reg_data_type_union aarch64_union_types
[] = {
1262 {aarch64_union_fields_vnd
},
1263 {aarch64_union_fields_vns
},
1264 {aarch64_union_fields_vnh
},
1265 {aarch64_union_fields_vnb
},
1266 {aarch64_union_fields_vnq
},
1269 static struct reg_data_type aarch64_fpu_union
[] = {
1270 {REG_TYPE_ARCH_DEFINED
, "vnd", REG_TYPE_CLASS_UNION
, {.reg_type_union
= aarch64_union_types
+ 0} },
1271 {REG_TYPE_ARCH_DEFINED
, "vns", REG_TYPE_CLASS_UNION
, {.reg_type_union
= aarch64_union_types
+ 1} },
1272 {REG_TYPE_ARCH_DEFINED
, "vnh", REG_TYPE_CLASS_UNION
, {.reg_type_union
= aarch64_union_types
+ 2} },
1273 {REG_TYPE_ARCH_DEFINED
, "vnb", REG_TYPE_CLASS_UNION
, {.reg_type_union
= aarch64_union_types
+ 3} },
1274 {REG_TYPE_ARCH_DEFINED
, "vnq", REG_TYPE_CLASS_UNION
, {.reg_type_union
= aarch64_union_types
+ 4} },
1277 static struct reg_data_type_union_field aarch64v_union_fields
[] = {
1278 {"d", aarch64_fpu_union
+ 0, aarch64v_union_fields
+ 1},
1279 {"s", aarch64_fpu_union
+ 1, aarch64v_union_fields
+ 2},
1280 {"h", aarch64_fpu_union
+ 2, aarch64v_union_fields
+ 3},
1281 {"b", aarch64_fpu_union
+ 3, aarch64v_union_fields
+ 4},
1282 {"q", aarch64_fpu_union
+ 4, NULL
},
1285 static struct reg_data_type_union aarch64v_union
[] = {
1286 {aarch64v_union_fields
}
1289 static struct reg_data_type aarch64v
[] = {
1290 {REG_TYPE_ARCH_DEFINED
, "aarch64v", REG_TYPE_CLASS_UNION
,
1291 {.reg_type_union
= aarch64v_union
} },
1294 static struct reg_data_type_bitfield aarch64_cpsr_bits
[] = {
1295 { 0, 0, REG_TYPE_UINT8
},
1296 { 2, 3, REG_TYPE_UINT8
},
1297 { 4, 4, REG_TYPE_UINT8
},
1298 { 6, 6, REG_TYPE_BOOL
},
1299 { 7, 7, REG_TYPE_BOOL
},
1300 { 8, 8, REG_TYPE_BOOL
},
1301 { 9, 9, REG_TYPE_BOOL
},
1302 { 20, 20, REG_TYPE_BOOL
},
1303 { 21, 21, REG_TYPE_BOOL
},
1304 { 28, 28, REG_TYPE_BOOL
},
1305 { 29, 29, REG_TYPE_BOOL
},
1306 { 30, 30, REG_TYPE_BOOL
},
1307 { 31, 31, REG_TYPE_BOOL
},
1310 static struct reg_data_type_flags_field aarch64_cpsr_fields
[] = {
1311 { "SP", aarch64_cpsr_bits
+ 0, aarch64_cpsr_fields
+ 1 },
1312 { "EL", aarch64_cpsr_bits
+ 1, aarch64_cpsr_fields
+ 2 },
1313 { "nRW", aarch64_cpsr_bits
+ 2, aarch64_cpsr_fields
+ 3 },
1314 { "F", aarch64_cpsr_bits
+ 3, aarch64_cpsr_fields
+ 4 },
1315 { "I", aarch64_cpsr_bits
+ 4, aarch64_cpsr_fields
+ 5 },
1316 { "A", aarch64_cpsr_bits
+ 5, aarch64_cpsr_fields
+ 6 },
1317 { "D", aarch64_cpsr_bits
+ 6, aarch64_cpsr_fields
+ 7 },
1318 { "IL", aarch64_cpsr_bits
+ 7, aarch64_cpsr_fields
+ 8 },
1319 { "SS", aarch64_cpsr_bits
+ 8, aarch64_cpsr_fields
+ 9 },
1320 { "V", aarch64_cpsr_bits
+ 9, aarch64_cpsr_fields
+ 10 },
1321 { "C", aarch64_cpsr_bits
+ 10, aarch64_cpsr_fields
+ 11 },
1322 { "Z", aarch64_cpsr_bits
+ 11, aarch64_cpsr_fields
+ 12 },
1323 { "N", aarch64_cpsr_bits
+ 12, NULL
}
1326 static struct reg_data_type_flags aarch64_cpsr_flags
[] = {
1327 { 4, aarch64_cpsr_fields
}
1330 static struct reg_data_type aarch64_flags_cpsr
[] = {
1331 {REG_TYPE_ARCH_DEFINED
, "cpsr_flags", REG_TYPE_CLASS_FLAGS
,
1332 {.reg_type_flags
= aarch64_cpsr_flags
} },
1335 static const struct {
1342 const char *feature
;
1343 struct reg_data_type
*data_type
;
1345 { ARMV8_R0
, "x0", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1346 { ARMV8_R1
, "x1", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1347 { ARMV8_R2
, "x2", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1348 { ARMV8_R3
, "x3", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1349 { ARMV8_R4
, "x4", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1350 { ARMV8_R5
, "x5", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1351 { ARMV8_R6
, "x6", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1352 { ARMV8_R7
, "x7", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1353 { ARMV8_R8
, "x8", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1354 { ARMV8_R9
, "x9", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1355 { ARMV8_R10
, "x10", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1356 { ARMV8_R11
, "x11", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1357 { ARMV8_R12
, "x12", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1358 { ARMV8_R13
, "x13", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1359 { ARMV8_R14
, "x14", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1360 { ARMV8_R15
, "x15", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1361 { ARMV8_R16
, "x16", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1362 { ARMV8_R17
, "x17", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1363 { ARMV8_R18
, "x18", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1364 { ARMV8_R19
, "x19", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1365 { ARMV8_R20
, "x20", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1366 { ARMV8_R21
, "x21", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1367 { ARMV8_R22
, "x22", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1368 { ARMV8_R23
, "x23", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1369 { ARMV8_R24
, "x24", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1370 { ARMV8_R25
, "x25", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1371 { ARMV8_R26
, "x26", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1372 { ARMV8_R27
, "x27", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1373 { ARMV8_R28
, "x28", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1374 { ARMV8_R29
, "x29", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1375 { ARMV8_R30
, "x30", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1377 { ARMV8_SP
, "sp", 64, ARM_MODE_ANY
, REG_TYPE_DATA_PTR
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1378 { ARMV8_PC
, "pc", 64, ARM_MODE_ANY
, REG_TYPE_CODE_PTR
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1379 { ARMV8_xPSR
, "cpsr", 32, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
,
1380 "general", "org.gnu.gdb.aarch64.core", aarch64_flags_cpsr
},
1381 { ARMV8_V0
, "v0", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1382 { ARMV8_V1
, "v1", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1383 { ARMV8_V2
, "v2", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1384 { ARMV8_V3
, "v3", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1385 { ARMV8_V4
, "v4", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1386 { ARMV8_V5
, "v5", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1387 { ARMV8_V6
, "v6", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1388 { ARMV8_V7
, "v7", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1389 { ARMV8_V8
, "v8", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1390 { ARMV8_V9
, "v9", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1391 { ARMV8_V10
, "v10", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1392 { ARMV8_V11
, "v11", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1393 { ARMV8_V12
, "v12", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1394 { ARMV8_V13
, "v13", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1395 { ARMV8_V14
, "v14", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1396 { ARMV8_V15
, "v15", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1397 { ARMV8_V16
, "v16", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1398 { ARMV8_V17
, "v17", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1399 { ARMV8_V18
, "v18", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1400 { ARMV8_V19
, "v19", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1401 { ARMV8_V20
, "v20", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1402 { ARMV8_V21
, "v21", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1403 { ARMV8_V22
, "v22", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1404 { ARMV8_V23
, "v23", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1405 { ARMV8_V24
, "v24", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1406 { ARMV8_V25
, "v25", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1407 { ARMV8_V26
, "v26", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1408 { ARMV8_V27
, "v27", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1409 { ARMV8_V28
, "v28", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1410 { ARMV8_V29
, "v29", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1411 { ARMV8_V30
, "v30", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1412 { ARMV8_V31
, "v31", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1413 { ARMV8_FPSR
, "fpsr", 32, ARM_MODE_ANY
, REG_TYPE_UINT32
, "simdfp", "org.gnu.gdb.aarch64.fpu", NULL
},
1414 { ARMV8_FPCR
, "fpcr", 32, ARM_MODE_ANY
, REG_TYPE_UINT32
, "simdfp", "org.gnu.gdb.aarch64.fpu", NULL
},
1416 { ARMV8_ELR_EL1
, "ELR_EL1", 64, ARMV8_64_EL1H
, REG_TYPE_CODE_PTR
, "banked", "net.sourceforge.openocd.banked",
1418 { ARMV8_ESR_EL1
, "ESR_EL1", 32, ARMV8_64_EL1H
, REG_TYPE_UINT32
, "banked", "net.sourceforge.openocd.banked",
1420 { ARMV8_SPSR_EL1
, "SPSR_EL1", 32, ARMV8_64_EL1H
, REG_TYPE_UINT32
, "banked", "net.sourceforge.openocd.banked",
1423 { ARMV8_ELR_EL2
, "ELR_EL2", 64, ARMV8_64_EL2H
, REG_TYPE_CODE_PTR
, "banked", "net.sourceforge.openocd.banked",
1425 { ARMV8_ESR_EL2
, "ESR_EL2", 32, ARMV8_64_EL2H
, REG_TYPE_UINT32
, "banked", "net.sourceforge.openocd.banked",
1427 { ARMV8_SPSR_EL2
, "SPSR_EL2", 32, ARMV8_64_EL2H
, REG_TYPE_UINT32
, "banked", "net.sourceforge.openocd.banked",
1430 { ARMV8_ELR_EL3
, "ELR_EL3", 64, ARMV8_64_EL3H
, REG_TYPE_CODE_PTR
, "banked", "net.sourceforge.openocd.banked",
1432 { ARMV8_ESR_EL3
, "ESR_EL3", 32, ARMV8_64_EL3H
, REG_TYPE_UINT32
, "banked", "net.sourceforge.openocd.banked",
1434 { ARMV8_SPSR_EL3
, "SPSR_EL3", 32, ARMV8_64_EL3H
, REG_TYPE_UINT32
, "banked", "net.sourceforge.openocd.banked",
1438 static const struct {
1446 const char *feature
;
1447 } armv8_regs32
[] = {
1448 { ARMV8_R0
, 0, "r0", 32, ARM_MODE_ANY
, REG_TYPE_UINT32
, "general", "org.gnu.gdb.arm.core" },
1449 { ARMV8_R1
, 0, "r1", 32, ARM_MODE_ANY
, REG_TYPE_UINT32
, "general", "org.gnu.gdb.arm.core" },
1450 { ARMV8_R2
, 0, "r2", 32, ARM_MODE_ANY
, REG_TYPE_UINT32
, "general", "org.gnu.gdb.arm.core" },
1451 { ARMV8_R3
, 0, "r3", 32, ARM_MODE_ANY
, REG_TYPE_UINT32
, "general", "org.gnu.gdb.arm.core" },
1452 { ARMV8_R4
, 0, "r4", 32, ARM_MODE_ANY
, REG_TYPE_UINT32
, "general", "org.gnu.gdb.arm.core" },
1453 { ARMV8_R5
, 0, "r5", 32, ARM_MODE_ANY
, REG_TYPE_UINT32
, "general", "org.gnu.gdb.arm.core" },
1454 { ARMV8_R6
, 0, "r6", 32, ARM_MODE_ANY
, REG_TYPE_UINT32
, "general", "org.gnu.gdb.arm.core" },
1455 { ARMV8_R7
, 0, "r7", 32, ARM_MODE_ANY
, REG_TYPE_UINT32
, "general", "org.gnu.gdb.arm.core" },
1456 { ARMV8_R8
, 0, "r8", 32, ARM_MODE_ANY
, REG_TYPE_UINT32
, "general", "org.gnu.gdb.arm.core" },
1457 { ARMV8_R9
, 0, "r9", 32, ARM_MODE_ANY
, REG_TYPE_UINT32
, "general", "org.gnu.gdb.arm.core" },
1458 { ARMV8_R10
, 0, "r10", 32, ARM_MODE_ANY
, REG_TYPE_UINT32
, "general", "org.gnu.gdb.arm.core" },
1459 { ARMV8_R11
, 0, "r11", 32, ARM_MODE_ANY
, REG_TYPE_UINT32
, "general", "org.gnu.gdb.arm.core" },
1460 { ARMV8_R12
, 0, "r12", 32, ARM_MODE_ANY
, REG_TYPE_UINT32
, "general", "org.gnu.gdb.arm.core" },
1461 { ARMV8_R13
, 0, "sp", 32, ARM_MODE_ANY
, REG_TYPE_DATA_PTR
, "general", "org.gnu.gdb.arm.core" },
1462 { ARMV8_R14
, 0, "lr", 32, ARM_MODE_ANY
, REG_TYPE_CODE_PTR
, "general", "org.gnu.gdb.arm.core" },
1463 { ARMV8_PC
, 0, "pc", 32, ARM_MODE_ANY
, REG_TYPE_CODE_PTR
, "general", "org.gnu.gdb.arm.core" },
1464 { ARMV8_xPSR
, 0, "cpsr", 32, ARM_MODE_ANY
, REG_TYPE_UINT32
, "general", "org.gnu.gdb.arm.core" },
1465 { ARMV8_V0
, 0, "d0", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1466 { ARMV8_V0
, 8, "d1", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1467 { ARMV8_V1
, 0, "d2", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1468 { ARMV8_V1
, 8, "d3", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1469 { ARMV8_V2
, 0, "d4", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1470 { ARMV8_V2
, 8, "d5", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1471 { ARMV8_V3
, 0, "d6", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1472 { ARMV8_V3
, 8, "d7", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1473 { ARMV8_V4
, 0, "d8", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1474 { ARMV8_V4
, 8, "d9", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1475 { ARMV8_V5
, 0, "d10", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1476 { ARMV8_V5
, 8, "d11", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1477 { ARMV8_V6
, 0, "d12", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1478 { ARMV8_V6
, 8, "d13", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1479 { ARMV8_V7
, 0, "d14", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1480 { ARMV8_V7
, 8, "d15", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1481 { ARMV8_V8
, 0, "d16", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1482 { ARMV8_V8
, 8, "d17", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1483 { ARMV8_V9
, 0, "d18", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1484 { ARMV8_V9
, 8, "d19", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1485 { ARMV8_V10
, 0, "d20", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1486 { ARMV8_V10
, 8, "d21", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1487 { ARMV8_V11
, 0, "d22", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1488 { ARMV8_V11
, 8, "d23", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1489 { ARMV8_V12
, 0, "d24", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1490 { ARMV8_V12
, 8, "d25", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1491 { ARMV8_V13
, 0, "d26", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1492 { ARMV8_V13
, 8, "d27", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1493 { ARMV8_V14
, 0, "d28", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1494 { ARMV8_V14
, 8, "d29", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1495 { ARMV8_V15
, 0, "d30", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1496 { ARMV8_V15
, 8, "d31", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1497 { ARMV8_FPSR
, 0, "fpscr", 32, ARM_MODE_ANY
, REG_TYPE_UINT32
, "float", "org.gnu.gdb.arm.vfp"},
1500 #define ARMV8_NUM_REGS ARRAY_SIZE(armv8_regs)
1501 #define ARMV8_NUM_REGS32 ARRAY_SIZE(armv8_regs32)
1503 static int armv8_get_core_reg(struct reg
*reg
)
1505 struct arm_reg
*armv8_reg
= reg
->arch_info
;
1506 struct target
*target
= armv8_reg
->target
;
1507 struct arm
*arm
= target_to_arm(target
);
1509 if (target
->state
!= TARGET_HALTED
)
1510 return ERROR_TARGET_NOT_HALTED
;
1512 return arm
->read_core_reg(target
, reg
, armv8_reg
->num
, arm
->core_mode
);
1515 static int armv8_set_core_reg(struct reg
*reg
, uint8_t *buf
)
1517 struct arm_reg
*armv8_reg
= reg
->arch_info
;
1518 struct target
*target
= armv8_reg
->target
;
1519 struct arm
*arm
= target_to_arm(target
);
1520 uint64_t value
= buf_get_u64(buf
, 0, reg
->size
);
1522 if (target
->state
!= TARGET_HALTED
)
1523 return ERROR_TARGET_NOT_HALTED
;
1525 if (reg
->size
<= 64) {
1526 if (reg
== arm
->cpsr
)
1527 armv8_set_cpsr(arm
, (uint32_t)value
);
1529 buf_set_u64(reg
->value
, 0, reg
->size
, value
);
1532 } else if (reg
->size
<= 128) {
1533 uint64_t hvalue
= buf_get_u64(buf
+ 8, 0, reg
->size
- 64);
1535 buf_set_u64(reg
->value
, 0, 64, value
);
1536 buf_set_u64(reg
->value
+ 8, 0, reg
->size
- 64, hvalue
);
1545 static const struct reg_arch_type armv8_reg_type
= {
1546 .get
= armv8_get_core_reg
,
1547 .set
= armv8_set_core_reg
,
1550 static int armv8_get_core_reg32(struct reg
*reg
)
1552 struct arm_reg
*armv8_reg
= reg
->arch_info
;
1553 struct target
*target
= armv8_reg
->target
;
1554 struct arm
*arm
= target_to_arm(target
);
1555 struct reg_cache
*cache
= arm
->core_cache
;
1559 if (target
->state
!= TARGET_HALTED
)
1560 return ERROR_TARGET_NOT_HALTED
;
1562 /* get the corresponding Aarch64 register */
1563 reg64
= cache
->reg_list
+ armv8_reg
->num
;
1569 retval
= arm
->read_core_reg(target
, reg64
, armv8_reg
->num
, arm
->core_mode
);
1570 if (retval
== ERROR_OK
)
1571 reg
->valid
= reg64
->valid
;
1576 static int armv8_set_core_reg32(struct reg
*reg
, uint8_t *buf
)
1578 struct arm_reg
*armv8_reg
= reg
->arch_info
;
1579 struct target
*target
= armv8_reg
->target
;
1580 struct arm
*arm
= target_to_arm(target
);
1581 struct reg_cache
*cache
= arm
->core_cache
;
1582 struct reg
*reg64
= cache
->reg_list
+ armv8_reg
->num
;
1583 uint32_t value
= buf_get_u32(buf
, 0, 32);
1585 if (target
->state
!= TARGET_HALTED
)
1586 return ERROR_TARGET_NOT_HALTED
;
1588 if (reg64
== arm
->cpsr
) {
1589 armv8_set_cpsr(arm
, value
);
1591 if (reg
->size
<= 32)
1592 buf_set_u32(reg
->value
, 0, 32, value
);
1593 else if (reg
->size
<= 64) {
1594 uint64_t value64
= buf_get_u64(buf
, 0, 64);
1595 buf_set_u64(reg
->value
, 0, 64, value64
);
1598 reg64
->valid
= true;
1601 reg64
->dirty
= true;
1606 static const struct reg_arch_type armv8_reg32_type
= {
1607 .get
= armv8_get_core_reg32
,
1608 .set
= armv8_set_core_reg32
,
1611 /** Builds cache of architecturally defined registers. */
1612 struct reg_cache
*armv8_build_reg_cache(struct target
*target
)
1614 struct armv8_common
*armv8
= target_to_armv8(target
);
1615 struct arm
*arm
= &armv8
->arm
;
1616 int num_regs
= ARMV8_NUM_REGS
;
1617 int num_regs32
= ARMV8_NUM_REGS32
;
1618 struct reg_cache
**cache_p
= register_get_last_cache_p(&target
->reg_cache
);
1619 struct reg_cache
*cache
= malloc(sizeof(struct reg_cache
));
1620 struct reg_cache
*cache32
= malloc(sizeof(struct reg_cache
));
1621 struct reg
*reg_list
= calloc(num_regs
, sizeof(struct reg
));
1622 struct reg
*reg_list32
= calloc(num_regs32
, sizeof(struct reg
));
1623 struct arm_reg
*arch_info
= calloc(num_regs
, sizeof(struct arm_reg
));
1624 struct reg_feature
*feature
;
1627 /* Build the process context cache */
1628 cache
->name
= "Aarch64 registers";
1629 cache
->next
= cache32
;
1630 cache
->reg_list
= reg_list
;
1631 cache
->num_regs
= num_regs
;
1633 for (i
= 0; i
< num_regs
; i
++) {
1634 arch_info
[i
].num
= armv8_regs
[i
].id
;
1635 arch_info
[i
].mode
= armv8_regs
[i
].mode
;
1636 arch_info
[i
].target
= target
;
1637 arch_info
[i
].arm
= arm
;
1639 reg_list
[i
].name
= armv8_regs
[i
].name
;
1640 reg_list
[i
].size
= armv8_regs
[i
].bits
;
1641 reg_list
[i
].value
= &arch_info
[i
].value
[0];
1642 reg_list
[i
].type
= &armv8_reg_type
;
1643 reg_list
[i
].arch_info
= &arch_info
[i
];
1645 reg_list
[i
].group
= armv8_regs
[i
].group
;
1646 reg_list
[i
].number
= i
;
1647 reg_list
[i
].exist
= true;
1648 reg_list
[i
].caller_save
= true; /* gdb defaults to true */
1650 feature
= calloc(1, sizeof(struct reg_feature
));
1652 feature
->name
= armv8_regs
[i
].feature
;
1653 reg_list
[i
].feature
= feature
;
1655 LOG_ERROR("unable to allocate feature list");
1657 reg_list
[i
].reg_data_type
= calloc(1, sizeof(struct reg_data_type
));
1658 if (reg_list
[i
].reg_data_type
) {
1659 if (!armv8_regs
[i
].data_type
)
1660 reg_list
[i
].reg_data_type
->type
= armv8_regs
[i
].type
;
1662 *reg_list
[i
].reg_data_type
= *armv8_regs
[i
].data_type
;
1664 LOG_ERROR("unable to allocate reg type list");
1667 arm
->cpsr
= reg_list
+ ARMV8_xPSR
;
1668 arm
->pc
= reg_list
+ ARMV8_PC
;
1669 arm
->core_cache
= cache
;
1671 /* shadow cache for ARM mode registers */
1672 cache32
->name
= "Aarch32 registers";
1673 cache32
->next
= NULL
;
1674 cache32
->reg_list
= reg_list32
;
1675 cache32
->num_regs
= num_regs32
;
1677 for (i
= 0; i
< num_regs32
; i
++) {
1678 reg_list32
[i
].name
= armv8_regs32
[i
].name
;
1679 reg_list32
[i
].size
= armv8_regs32
[i
].bits
;
1680 reg_list32
[i
].value
= &arch_info
[armv8_regs32
[i
].id
].value
[armv8_regs32
[i
].mapping
];
1681 reg_list32
[i
].type
= &armv8_reg32_type
;
1682 reg_list32
[i
].arch_info
= &arch_info
[armv8_regs32
[i
].id
];
1683 reg_list32
[i
].group
= armv8_regs32
[i
].group
;
1684 reg_list32
[i
].number
= i
;
1685 reg_list32
[i
].exist
= true;
1686 reg_list32
[i
].caller_save
= true;
1688 feature
= calloc(1, sizeof(struct reg_feature
));
1690 feature
->name
= armv8_regs32
[i
].feature
;
1691 reg_list32
[i
].feature
= feature
;
1693 LOG_ERROR("unable to allocate feature list");
1695 reg_list32
[i
].reg_data_type
= calloc(1, sizeof(struct reg_data_type
));
1696 if (reg_list32
[i
].reg_data_type
)
1697 reg_list32
[i
].reg_data_type
->type
= armv8_regs32
[i
].type
;
1699 LOG_ERROR("unable to allocate reg type list");
1706 struct reg
*armv8_reg_current(struct arm
*arm
, unsigned regnum
)
1710 if (regnum
> (ARMV8_LAST_REG
- 1))
1713 r
= arm
->core_cache
->reg_list
+ regnum
;
1717 static void armv8_free_cache(struct reg_cache
*cache
, bool regs32
)
1725 for (i
= 0; i
< cache
->num_regs
; i
++) {
1726 reg
= &cache
->reg_list
[i
];
1729 free(reg
->reg_data_type
);
1733 free(cache
->reg_list
[0].arch_info
);
1734 free(cache
->reg_list
);
1738 void armv8_free_reg_cache(struct target
*target
)
1740 struct armv8_common
*armv8
= target_to_armv8(target
);
1741 struct arm
*arm
= &armv8
->arm
;
1742 struct reg_cache
*cache
= NULL
, *cache32
= NULL
;
1744 cache
= arm
->core_cache
;
1746 cache32
= cache
->next
;
1747 armv8_free_cache(cache32
, true);
1748 armv8_free_cache(cache
, false);
1749 arm
->core_cache
= NULL
;
1752 const struct command_registration armv8_command_handlers
[] = {
1754 .name
= "catch_exc",
1755 .handler
= armv8_handle_exception_catch_command
,
1756 .mode
= COMMAND_EXEC
,
1757 .help
= "configure exception catch",
1758 .usage
= "[(nsec_el1,nsec_el2,sec_el1,sec_el3)+,off]",
1760 COMMAND_REGISTRATION_DONE
1763 const char *armv8_get_gdb_arch(struct target
*target
)
1765 struct arm
*arm
= target_to_arm(target
);
1766 return arm
->core_state
== ARM_STATE_AARCH64
? "aarch64" : "arm";
1769 int armv8_get_gdb_reg_list(struct target
*target
,
1770 struct reg
**reg_list
[], int *reg_list_size
,
1771 enum target_register_class reg_class
)
1773 struct arm
*arm
= target_to_arm(target
);
1776 if (arm
->core_state
== ARM_STATE_AARCH64
) {
1778 LOG_DEBUG("Creating Aarch64 register list for target %s", target_name(target
));
1780 switch (reg_class
) {
1781 case REG_CLASS_GENERAL
:
1782 *reg_list_size
= ARMV8_V0
;
1783 *reg_list
= malloc(sizeof(struct reg
*) * (*reg_list_size
));
1785 for (i
= 0; i
< *reg_list_size
; i
++)
1786 (*reg_list
)[i
] = armv8_reg_current(arm
, i
);
1790 *reg_list_size
= ARMV8_LAST_REG
;
1791 *reg_list
= malloc(sizeof(struct reg
*) * (*reg_list_size
));
1793 for (i
= 0; i
< *reg_list_size
; i
++)
1794 (*reg_list
)[i
] = armv8_reg_current(arm
, i
);
1799 LOG_ERROR("not a valid register class type in query.");
1803 struct reg_cache
*cache32
= arm
->core_cache
->next
;
1805 LOG_DEBUG("Creating Aarch32 register list for target %s", target_name(target
));
1807 switch (reg_class
) {
1808 case REG_CLASS_GENERAL
:
1809 *reg_list_size
= ARMV8_R14
+ 3;
1810 *reg_list
= malloc(sizeof(struct reg
*) * (*reg_list_size
));
1812 for (i
= 0; i
< *reg_list_size
; i
++)
1813 (*reg_list
)[i
] = cache32
->reg_list
+ i
;
1817 *reg_list_size
= cache32
->num_regs
;
1818 *reg_list
= malloc(sizeof(struct reg
*) * (*reg_list_size
));
1820 for (i
= 0; i
< *reg_list_size
; i
++)
1821 (*reg_list
)[i
] = cache32
->reg_list
+ i
;
1825 LOG_ERROR("not a valid register class type in query.");
1831 int armv8_set_dbgreg_bits(struct armv8_common
*armv8
, unsigned int reg
, unsigned long mask
, unsigned long value
)
1836 int retval
= mem_ap_read_atomic_u32(armv8
->debug_ap
,
1837 armv8
->debug_base
+ reg
, &tmp
);
1838 if (retval
!= ERROR_OK
)
1841 /* clear bitfield */
1844 tmp
|= value
& mask
;
1846 /* write new value */
1847 retval
= mem_ap_write_atomic_u32(armv8
->debug_ap
,
1848 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)