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_EL2H
,
106 .psr
= ARMV8_64_EL3T
,
110 .psr
= ARMV8_64_EL3H
,
114 /** Map PSR mode bits to the name of an ARM processor operating mode. */
115 const char *armv8_mode_name(unsigned psr_mode
)
117 for (unsigned i
= 0; i
< ARRAY_SIZE(armv8_mode_data
); i
++) {
118 if (armv8_mode_data
[i
].psr
== psr_mode
)
119 return armv8_mode_data
[i
].name
;
121 LOG_ERROR("unrecognized psr mode: %#02x", psr_mode
);
122 return "UNRECOGNIZED";
125 static int armv8_read_reg(struct armv8_common
*armv8
, int regnum
, uint64_t *regval
)
127 struct arm_dpm
*dpm
= &armv8
->dpm
;
134 retval
= dpm
->instr_read_data_dcc_64(dpm
,
135 ARMV8_MSR_GP(SYSTEM_DBG_DBGDTR_EL0
, regnum
), &value_64
);
138 retval
= dpm
->instr_read_data_r0_64(dpm
,
139 ARMV8_MOVFSP_64(0), &value_64
);
142 retval
= dpm
->instr_read_data_r0_64(dpm
,
143 ARMV8_MRS_DLR(0), &value_64
);
146 retval
= dpm
->instr_read_data_r0(dpm
,
147 ARMV8_MRS_DSPSR(0), &value
);
151 retval
= dpm
->instr_read_data_r0(dpm
,
152 ARMV8_MRS_FPSR(0), &value
);
156 retval
= dpm
->instr_read_data_r0(dpm
,
157 ARMV8_MRS_FPCR(0), &value
);
161 retval
= dpm
->instr_read_data_r0_64(dpm
,
162 ARMV8_MRS(SYSTEM_ELR_EL1
, 0), &value_64
);
165 retval
= dpm
->instr_read_data_r0_64(dpm
,
166 ARMV8_MRS(SYSTEM_ELR_EL2
, 0), &value_64
);
169 retval
= dpm
->instr_read_data_r0_64(dpm
,
170 ARMV8_MRS(SYSTEM_ELR_EL3
, 0), &value_64
);
173 retval
= dpm
->instr_read_data_r0(dpm
,
174 ARMV8_MRS(SYSTEM_ESR_EL1
, 0), &value
);
178 retval
= dpm
->instr_read_data_r0(dpm
,
179 ARMV8_MRS(SYSTEM_ESR_EL2
, 0), &value
);
183 retval
= dpm
->instr_read_data_r0(dpm
,
184 ARMV8_MRS(SYSTEM_ESR_EL3
, 0), &value
);
188 retval
= dpm
->instr_read_data_r0(dpm
,
189 ARMV8_MRS(SYSTEM_SPSR_EL1
, 0), &value
);
193 retval
= dpm
->instr_read_data_r0(dpm
,
194 ARMV8_MRS(SYSTEM_SPSR_EL2
, 0), &value
);
198 retval
= dpm
->instr_read_data_r0(dpm
,
199 ARMV8_MRS(SYSTEM_SPSR_EL3
, 0), &value
);
207 if (retval
== ERROR_OK
&& regval
!= NULL
)
215 static int armv8_read_reg_simdfp_aarch64(struct armv8_common
*armv8
, int regnum
, uint64_t *lvalue
, uint64_t *hvalue
)
217 int retval
= ERROR_FAIL
;
218 struct arm_dpm
*dpm
= &armv8
->dpm
;
221 case ARMV8_V0
... ARMV8_V31
:
222 retval
= dpm
->instr_read_data_r0_64(dpm
,
223 ARMV8_MOV_GPR_VFP(0, (regnum
- ARMV8_V0
), 1), hvalue
);
224 if (retval
!= ERROR_OK
)
226 retval
= dpm
->instr_read_data_r0_64(dpm
,
227 ARMV8_MOV_GPR_VFP(0, (regnum
- ARMV8_V0
), 0), lvalue
);
238 static int armv8_write_reg(struct armv8_common
*armv8
, int regnum
, uint64_t value_64
)
240 struct arm_dpm
*dpm
= &armv8
->dpm
;
246 retval
= dpm
->instr_write_data_dcc_64(dpm
,
247 ARMV8_MRS(SYSTEM_DBG_DBGDTR_EL0
, regnum
),
251 retval
= dpm
->instr_write_data_r0_64(dpm
,
256 retval
= dpm
->instr_write_data_r0_64(dpm
,
262 retval
= dpm
->instr_write_data_r0(dpm
,
268 retval
= dpm
->instr_write_data_r0(dpm
,
274 retval
= dpm
->instr_write_data_r0(dpm
,
278 /* registers clobbered by taking exception in debug state */
280 retval
= dpm
->instr_write_data_r0_64(dpm
,
281 ARMV8_MSR_GP(SYSTEM_ELR_EL1
, 0), value_64
);
284 retval
= dpm
->instr_write_data_r0_64(dpm
,
285 ARMV8_MSR_GP(SYSTEM_ELR_EL2
, 0), value_64
);
288 retval
= dpm
->instr_write_data_r0_64(dpm
,
289 ARMV8_MSR_GP(SYSTEM_ELR_EL3
, 0), value_64
);
293 retval
= dpm
->instr_write_data_r0(dpm
,
294 ARMV8_MSR_GP(SYSTEM_ESR_EL1
, 0), value
);
298 retval
= dpm
->instr_write_data_r0(dpm
,
299 ARMV8_MSR_GP(SYSTEM_ESR_EL2
, 0), value
);
303 retval
= dpm
->instr_write_data_r0(dpm
,
304 ARMV8_MSR_GP(SYSTEM_ESR_EL3
, 0), value
);
308 retval
= dpm
->instr_write_data_r0(dpm
,
309 ARMV8_MSR_GP(SYSTEM_SPSR_EL1
, 0), value
);
313 retval
= dpm
->instr_write_data_r0(dpm
,
314 ARMV8_MSR_GP(SYSTEM_SPSR_EL2
, 0), value
);
318 retval
= dpm
->instr_write_data_r0(dpm
,
319 ARMV8_MSR_GP(SYSTEM_SPSR_EL3
, 0), value
);
329 static int armv8_write_reg_simdfp_aarch64(struct armv8_common
*armv8
, int regnum
, uint64_t lvalue
, uint64_t hvalue
)
331 int retval
= ERROR_FAIL
;
332 struct arm_dpm
*dpm
= &armv8
->dpm
;
335 case ARMV8_V0
... ARMV8_V31
:
336 retval
= dpm
->instr_write_data_r0_64(dpm
,
337 ARMV8_MOV_VFP_GPR((regnum
- ARMV8_V0
), 0, 1), hvalue
);
338 if (retval
!= ERROR_OK
)
340 retval
= dpm
->instr_write_data_r0_64(dpm
,
341 ARMV8_MOV_VFP_GPR((regnum
- ARMV8_V0
), 0, 0), lvalue
);
352 static int armv8_read_reg32(struct armv8_common
*armv8
, int regnum
, uint64_t *regval
)
354 struct arm_dpm
*dpm
= &armv8
->dpm
;
359 case ARMV8_R0
... ARMV8_R14
:
360 /* return via DCC: "MCR p14, 0, Rnum, c0, c5, 0" */
361 retval
= dpm
->instr_read_data_dcc(dpm
,
362 ARMV4_5_MCR(14, 0, regnum
, 0, 5, 0),
366 retval
= dpm
->instr_read_data_dcc(dpm
,
367 ARMV4_5_MCR(14, 0, 13, 0, 5, 0),
371 retval
= dpm
->instr_read_data_r0(dpm
,
376 retval
= dpm
->instr_read_data_r0(dpm
,
380 case ARMV8_ELR_EL1
: /* mapped to LR_svc */
381 retval
= dpm
->instr_read_data_dcc(dpm
,
382 ARMV4_5_MCR(14, 0, 14, 0, 5, 0),
385 case ARMV8_ELR_EL2
: /* mapped to ELR_hyp */
386 retval
= dpm
->instr_read_data_r0(dpm
,
387 ARMV8_MRS_T1(0, 14, 0, 1),
390 case ARMV8_ELR_EL3
: /* mapped to LR_mon */
391 retval
= dpm
->instr_read_data_dcc(dpm
,
392 ARMV4_5_MCR(14, 0, 14, 0, 5, 0),
395 case ARMV8_ESR_EL1
: /* mapped to DFSR */
396 retval
= dpm
->instr_read_data_r0(dpm
,
397 ARMV4_5_MRC(15, 0, 0, 5, 0, 0),
400 case ARMV8_ESR_EL2
: /* mapped to HSR */
401 retval
= dpm
->instr_read_data_r0(dpm
,
402 ARMV4_5_MRC(15, 4, 0, 5, 2, 0),
405 case ARMV8_ESR_EL3
: /* FIXME: no equivalent in aarch32? */
408 case ARMV8_SPSR_EL1
: /* mapped to SPSR_svc */
409 retval
= dpm
->instr_read_data_r0(dpm
,
410 ARMV8_MRS_xPSR_T1(1, 0),
413 case ARMV8_SPSR_EL2
: /* mapped to SPSR_hyp */
414 retval
= dpm
->instr_read_data_r0(dpm
,
415 ARMV8_MRS_xPSR_T1(1, 0),
418 case ARMV8_SPSR_EL3
: /* mapped to SPSR_mon */
419 retval
= dpm
->instr_read_data_r0(dpm
,
420 ARMV8_MRS_xPSR_T1(1, 0),
424 /* "VMRS r0, FPSCR"; then return via DCC */
425 retval
= dpm
->instr_read_data_r0(dpm
,
426 ARMV4_5_VMRS(0), &value
);
433 if (retval
== ERROR_OK
&& regval
!= NULL
)
439 static int armv8_read_reg_simdfp_aarch32(struct armv8_common
*armv8
, int regnum
, uint64_t *lvalue
, uint64_t *hvalue
)
441 int retval
= ERROR_FAIL
;
442 struct arm_dpm
*dpm
= &armv8
->dpm
;
443 struct reg
*reg_r1
= dpm
->arm
->core_cache
->reg_list
+ ARMV8_R1
;
444 uint32_t value_r0
= 0, value_r1
= 0;
445 unsigned num
= (regnum
- ARMV8_V0
) << 1;
448 case ARMV8_V0
... ARMV8_V15
:
449 /* we are going to write R1, mark it dirty */
450 reg_r1
->dirty
= true;
451 /* move from double word register to r0:r1: "vmov r0, r1, vm"
452 * then read r0 via dcc
454 retval
= dpm
->instr_read_data_r0(dpm
,
455 ARMV4_5_VMOV(1, 1, 0, (num
>> 4), (num
& 0xf)),
457 /* read r1 via dcc */
458 retval
= dpm
->instr_read_data_dcc(dpm
,
459 ARMV4_5_MCR(14, 0, 1, 0, 5, 0),
461 if (retval
== ERROR_OK
) {
463 *lvalue
= ((*lvalue
) << 32) | value_r0
;
468 /* repeat above steps for high 64 bits of V register */
469 retval
= dpm
->instr_read_data_r0(dpm
,
470 ARMV4_5_VMOV(1, 1, 0, (num
>> 4), (num
& 0xf)),
472 retval
= dpm
->instr_read_data_dcc(dpm
,
473 ARMV4_5_MCR(14, 0, 1, 0, 5, 0),
475 if (retval
== ERROR_OK
) {
477 *hvalue
= ((*hvalue
) << 32) | value_r0
;
489 static int armv8_write_reg32(struct armv8_common
*armv8
, int regnum
, uint64_t value
)
491 struct arm_dpm
*dpm
= &armv8
->dpm
;
495 case ARMV8_R0
... ARMV8_R14
:
496 /* load register from DCC: "MRC p14, 0, Rnum, c0, c5, 0" */
497 retval
= dpm
->instr_write_data_dcc(dpm
,
498 ARMV4_5_MRC(14, 0, regnum
, 0, 5, 0), value
);
501 retval
= dpm
->instr_write_data_dcc(dpm
,
502 ARMV4_5_MRC(14, 0, 13, 0, 5, 0), value
);
505 * read r0 from DCC; then "MOV pc, r0" */
506 retval
= dpm
->instr_write_data_r0(dpm
,
507 ARMV8_MCR_DLR(0), value
);
509 case ARMV8_xPSR
: /* CPSR */
510 /* read r0 from DCC, then "MCR r0, DSPSR" */
511 retval
= dpm
->instr_write_data_r0(dpm
,
512 ARMV8_MCR_DSPSR(0), value
);
514 case ARMV8_ELR_EL1
: /* mapped to LR_svc */
515 retval
= dpm
->instr_write_data_dcc(dpm
,
516 ARMV4_5_MRC(14, 0, 14, 0, 5, 0),
519 case ARMV8_ELR_EL2
: /* mapped to ELR_hyp */
520 retval
= dpm
->instr_write_data_r0(dpm
,
521 ARMV8_MSR_GP_T1(0, 14, 0, 1),
524 case ARMV8_ELR_EL3
: /* mapped to LR_mon */
525 retval
= dpm
->instr_write_data_dcc(dpm
,
526 ARMV4_5_MRC(14, 0, 14, 0, 5, 0),
529 case ARMV8_ESR_EL1
: /* mapped to DFSR */
530 retval
= dpm
->instr_write_data_r0(dpm
,
531 ARMV4_5_MCR(15, 0, 0, 5, 0, 0),
534 case ARMV8_ESR_EL2
: /* mapped to HSR */
535 retval
= dpm
->instr_write_data_r0(dpm
,
536 ARMV4_5_MCR(15, 4, 0, 5, 2, 0),
539 case ARMV8_ESR_EL3
: /* FIXME: no equivalent in aarch32? */
542 case ARMV8_SPSR_EL1
: /* mapped to SPSR_svc */
543 retval
= dpm
->instr_write_data_r0(dpm
,
544 ARMV8_MSR_GP_xPSR_T1(1, 0, 15),
547 case ARMV8_SPSR_EL2
: /* mapped to SPSR_hyp */
548 retval
= dpm
->instr_write_data_r0(dpm
,
549 ARMV8_MSR_GP_xPSR_T1(1, 0, 15),
552 case ARMV8_SPSR_EL3
: /* mapped to SPSR_mon */
553 retval
= dpm
->instr_write_data_r0(dpm
,
554 ARMV8_MSR_GP_xPSR_T1(1, 0, 15),
558 /* move to r0 from DCC, then "VMSR FPSCR, r0" */
559 retval
= dpm
->instr_write_data_r0(dpm
,
560 ARMV4_5_VMSR(0), value
);
571 static int armv8_write_reg_simdfp_aarch32(struct armv8_common
*armv8
, int regnum
, uint64_t lvalue
, uint64_t hvalue
)
573 int retval
= ERROR_FAIL
;
574 struct arm_dpm
*dpm
= &armv8
->dpm
;
575 struct reg
*reg_r1
= dpm
->arm
->core_cache
->reg_list
+ ARMV8_R1
;
576 uint32_t value_r0
= 0, value_r1
= 0;
577 unsigned num
= (regnum
- ARMV8_V0
) << 1;
580 case ARMV8_V0
... ARMV8_V15
:
581 /* we are going to write R1, mark it dirty */
582 reg_r1
->dirty
= true;
583 value_r1
= lvalue
>> 32;
584 value_r0
= lvalue
& 0xFFFFFFFF;
585 /* write value_r1 to r1 via dcc */
586 retval
= dpm
->instr_write_data_dcc(dpm
,
587 ARMV4_5_MRC(14, 0, 1, 0, 5, 0),
589 /* write value_r0 to r0 via dcc then,
590 * move to double word register from r0:r1: "vmov vm, r0, r1"
592 retval
= dpm
->instr_write_data_r0(dpm
,
593 ARMV4_5_VMOV(0, 1, 0, (num
>> 4), (num
& 0xf)),
597 /* repeat above steps for high 64 bits of V register */
598 value_r1
= hvalue
>> 32;
599 value_r0
= hvalue
& 0xFFFFFFFF;
600 retval
= dpm
->instr_write_data_dcc(dpm
,
601 ARMV4_5_MRC(14, 0, 1, 0, 5, 0),
603 retval
= dpm
->instr_write_data_r0(dpm
,
604 ARMV4_5_VMOV(0, 1, 0, (num
>> 4), (num
& 0xf)),
615 void armv8_select_reg_access(struct armv8_common
*armv8
, bool is_aarch64
)
618 armv8
->read_reg_u64
= armv8_read_reg
;
619 armv8
->write_reg_u64
= armv8_write_reg
;
620 armv8
->read_reg_u128
= armv8_read_reg_simdfp_aarch64
;
621 armv8
->write_reg_u128
= armv8_write_reg_simdfp_aarch64
;
624 armv8
->read_reg_u64
= armv8_read_reg32
;
625 armv8
->write_reg_u64
= armv8_write_reg32
;
626 armv8
->read_reg_u128
= armv8_read_reg_simdfp_aarch32
;
627 armv8
->write_reg_u128
= armv8_write_reg_simdfp_aarch32
;
631 /* retrieve core id cluster id */
632 int armv8_read_mpidr(struct armv8_common
*armv8
)
634 int retval
= ERROR_FAIL
;
635 struct arm
*arm
= &armv8
->arm
;
636 struct arm_dpm
*dpm
= armv8
->arm
.dpm
;
639 retval
= dpm
->prepare(dpm
);
640 if (retval
!= ERROR_OK
)
643 /* check if we're in an unprivileged mode */
644 if (armv8_curel_from_core_mode(arm
->core_mode
) < SYSTEM_CUREL_EL1
) {
645 retval
= armv8_dpm_modeswitch(dpm
, ARMV8_64_EL1H
);
646 if (retval
!= ERROR_OK
)
650 retval
= dpm
->instr_read_data_r0(dpm
, armv8_opcode(armv8
, READ_REG_MPIDR
), &mpidr
);
651 if (retval
!= ERROR_OK
)
653 if (mpidr
& 1U<<31) {
654 armv8
->multi_processor_system
= (mpidr
>> 30) & 1;
655 armv8
->cluster_id
= (mpidr
>> 8) & 0xf;
656 armv8
->cpu_id
= mpidr
& 0x3;
657 LOG_INFO("%s cluster %x core %x %s", target_name(armv8
->arm
.target
),
660 armv8
->multi_processor_system
== 0 ? "multi core" : "single core");
662 LOG_ERROR("mpidr not in multiprocessor format");
665 armv8_dpm_modeswitch(dpm
, ARM_MODE_ANY
);
671 * Configures host-side ARM records to reflect the specified CPSR.
672 * Later, code can use arm_reg_current() to map register numbers
673 * according to how they are exposed by this mode.
675 void armv8_set_cpsr(struct arm
*arm
, uint32_t cpsr
)
677 uint32_t mode
= cpsr
& 0x1F;
679 /* NOTE: this may be called very early, before the register
680 * cache is set up. We can't defend against many errors, in
681 * particular against CPSRs that aren't valid *here* ...
684 buf_set_u32(arm
->cpsr
->value
, 0, 32, cpsr
);
685 arm
->cpsr
->valid
= true;
686 arm
->cpsr
->dirty
= false;
689 /* Older ARMs won't have the J bit */
690 enum arm_state state
= 0xFF;
692 if ((cpsr
& 0x10) != 0) {
694 if (cpsr
& (1 << 5)) { /* T */
695 if (cpsr
& (1 << 24)) { /* J */
696 LOG_WARNING("ThumbEE -- incomplete support");
697 state
= ARM_STATE_THUMB_EE
;
699 state
= ARM_STATE_THUMB
;
701 if (cpsr
& (1 << 24)) { /* J */
702 LOG_ERROR("Jazelle state handling is BROKEN!");
703 state
= ARM_STATE_JAZELLE
;
705 state
= ARM_STATE_ARM
;
709 state
= ARM_STATE_AARCH64
;
712 arm
->core_state
= state
;
713 arm
->core_mode
= mode
;
715 LOG_DEBUG("set CPSR %#8.8x: %s mode, %s state", (unsigned) cpsr
,
716 armv8_mode_name(arm
->core_mode
),
717 armv8_state_strings
[arm
->core_state
]);
720 static void armv8_show_fault_registers32(struct armv8_common
*armv8
)
722 uint32_t dfsr
, ifsr
, dfar
, ifar
;
723 struct arm_dpm
*dpm
= armv8
->arm
.dpm
;
726 retval
= dpm
->prepare(dpm
);
727 if (retval
!= ERROR_OK
)
730 /* ARMV4_5_MRC(cpnum, op1, r0, CRn, CRm, op2) */
732 /* c5/c0 - {data, instruction} fault status registers */
733 retval
= dpm
->instr_read_data_r0(dpm
,
734 ARMV4_5_MRC(15, 0, 0, 5, 0, 0),
736 if (retval
!= ERROR_OK
)
739 retval
= dpm
->instr_read_data_r0(dpm
,
740 ARMV4_5_MRC(15, 0, 0, 5, 0, 1),
742 if (retval
!= ERROR_OK
)
745 /* c6/c0 - {data, instruction} fault address registers */
746 retval
= dpm
->instr_read_data_r0(dpm
,
747 ARMV4_5_MRC(15, 0, 0, 6, 0, 0),
749 if (retval
!= ERROR_OK
)
752 retval
= dpm
->instr_read_data_r0(dpm
,
753 ARMV4_5_MRC(15, 0, 0, 6, 0, 2),
755 if (retval
!= ERROR_OK
)
758 LOG_USER("Data fault registers DFSR: %8.8" PRIx32
759 ", DFAR: %8.8" PRIx32
, dfsr
, dfar
);
760 LOG_USER("Instruction fault registers IFSR: %8.8" PRIx32
761 ", IFAR: %8.8" PRIx32
, ifsr
, ifar
);
764 /* (void) */ dpm
->finish(dpm
);
767 static __attribute__((unused
)) void armv8_show_fault_registers(struct target
*target
)
769 struct armv8_common
*armv8
= target_to_armv8(target
);
771 if (armv8
->arm
.core_state
!= ARM_STATE_AARCH64
)
772 armv8_show_fault_registers32(armv8
);
775 static uint8_t armv8_pa_size(uint32_t ps
)
798 LOG_INFO("Unknown physical address size");
804 static __attribute__((unused
)) int armv8_read_ttbcr32(struct target
*target
)
806 struct armv8_common
*armv8
= target_to_armv8(target
);
807 struct arm_dpm
*dpm
= armv8
->arm
.dpm
;
808 uint32_t ttbcr
, ttbcr_n
;
809 int retval
= dpm
->prepare(dpm
);
810 if (retval
!= ERROR_OK
)
812 /* MRC p15,0,<Rt>,c2,c0,2 ; Read CP15 Translation Table Base Control Register*/
813 retval
= dpm
->instr_read_data_r0(dpm
,
814 ARMV4_5_MRC(15, 0, 0, 2, 0, 2),
816 if (retval
!= ERROR_OK
)
819 LOG_DEBUG("ttbcr %" PRIx32
, ttbcr
);
821 ttbcr_n
= ttbcr
& 0x7;
822 armv8
->armv8_mmu
.ttbcr
= ttbcr
;
825 * ARM Architecture Reference Manual (ARMv7-A and ARMv7-R edition),
826 * document # ARM DDI 0406C
828 armv8
->armv8_mmu
.ttbr_range
[0] = 0xffffffff >> ttbcr_n
;
829 armv8
->armv8_mmu
.ttbr_range
[1] = 0xffffffff;
830 armv8
->armv8_mmu
.ttbr_mask
[0] = 0xffffffff << (14 - ttbcr_n
);
831 armv8
->armv8_mmu
.ttbr_mask
[1] = 0xffffffff << 14;
833 LOG_DEBUG("ttbr1 %s, ttbr0_mask %" PRIx32
" ttbr1_mask %" PRIx32
,
834 (ttbcr_n
!= 0) ? "used" : "not used",
835 armv8
->armv8_mmu
.ttbr_mask
[0],
836 armv8
->armv8_mmu
.ttbr_mask
[1]);
843 static __attribute__((unused
)) int armv8_read_ttbcr(struct target
*target
)
845 struct armv8_common
*armv8
= target_to_armv8(target
);
846 struct arm_dpm
*dpm
= armv8
->arm
.dpm
;
847 struct arm
*arm
= &armv8
->arm
;
851 int retval
= dpm
->prepare(dpm
);
852 if (retval
!= ERROR_OK
)
855 /* clear ttrr1_used and ttbr0_mask */
856 memset(&armv8
->armv8_mmu
.ttbr1_used
, 0, sizeof(armv8
->armv8_mmu
.ttbr1_used
));
857 memset(&armv8
->armv8_mmu
.ttbr0_mask
, 0, sizeof(armv8
->armv8_mmu
.ttbr0_mask
));
859 switch (armv8_curel_from_core_mode(arm
->core_mode
)) {
860 case SYSTEM_CUREL_EL3
:
861 retval
= dpm
->instr_read_data_r0(dpm
,
862 ARMV8_MRS(SYSTEM_TCR_EL3
, 0),
864 retval
+= dpm
->instr_read_data_r0_64(dpm
,
865 ARMV8_MRS(SYSTEM_TTBR0_EL3
, 0),
867 if (retval
!= ERROR_OK
)
869 armv8
->va_size
= 64 - (ttbcr
& 0x3F);
870 armv8
->pa_size
= armv8_pa_size((ttbcr
>> 16) & 7);
871 armv8
->page_size
= (ttbcr
>> 14) & 3;
873 case SYSTEM_CUREL_EL2
:
874 retval
= dpm
->instr_read_data_r0(dpm
,
875 ARMV8_MRS(SYSTEM_TCR_EL2
, 0),
877 retval
+= dpm
->instr_read_data_r0_64(dpm
,
878 ARMV8_MRS(SYSTEM_TTBR0_EL2
, 0),
880 if (retval
!= ERROR_OK
)
882 armv8
->va_size
= 64 - (ttbcr
& 0x3F);
883 armv8
->pa_size
= armv8_pa_size((ttbcr
>> 16) & 7);
884 armv8
->page_size
= (ttbcr
>> 14) & 3;
886 case SYSTEM_CUREL_EL0
:
887 armv8_dpm_modeswitch(dpm
, ARMV8_64_EL1H
);
889 case SYSTEM_CUREL_EL1
:
890 retval
= dpm
->instr_read_data_r0_64(dpm
,
891 ARMV8_MRS(SYSTEM_TCR_EL1
, 0),
893 armv8
->va_size
= 64 - (ttbcr_64
& 0x3F);
894 armv8
->pa_size
= armv8_pa_size((ttbcr_64
>> 32) & 7);
895 armv8
->page_size
= (ttbcr_64
>> 14) & 3;
896 armv8
->armv8_mmu
.ttbr1_used
= (((ttbcr_64
>> 16) & 0x3F) != 0) ? 1 : 0;
897 armv8
->armv8_mmu
.ttbr0_mask
= 0x0000FFFFFFFFFFFF;
898 retval
+= dpm
->instr_read_data_r0_64(dpm
,
899 ARMV8_MRS(SYSTEM_TTBR0_EL1
| (armv8
->armv8_mmu
.ttbr1_used
), 0),
901 if (retval
!= ERROR_OK
)
905 LOG_ERROR("unknown core state");
909 if (retval
!= ERROR_OK
)
912 if (armv8
->armv8_mmu
.ttbr1_used
== 1)
913 LOG_INFO("TTBR0 access above %" PRIx64
, (uint64_t)(armv8
->armv8_mmu
.ttbr0_mask
));
916 armv8_dpm_modeswitch(dpm
, ARM_MODE_ANY
);
921 /* method adapted to cortex A : reused arm v4 v5 method*/
922 int armv8_mmu_translate_va(struct target
*target
, target_addr_t va
, target_addr_t
*val
)
927 /* V8 method VA TO PA */
928 int armv8_mmu_translate_va_pa(struct target
*target
, target_addr_t va
,
929 target_addr_t
*val
, int meminfo
)
931 struct armv8_common
*armv8
= target_to_armv8(target
);
932 struct arm
*arm
= target_to_arm(target
);
933 struct arm_dpm
*dpm
= &armv8
->dpm
;
934 enum arm_mode target_mode
= ARM_MODE_ANY
;
939 static const char * const shared_name
[] = {
940 "Non-", "UNDEFINED ", "Outer ", "Inner "
943 static const char * const secure_name
[] = {
944 "Secure", "Not Secure"
947 if (target
->state
!= TARGET_HALTED
) {
948 LOG_WARNING("target %s not halted", target_name(target
));
949 return ERROR_TARGET_NOT_HALTED
;
952 retval
= dpm
->prepare(dpm
);
953 if (retval
!= ERROR_OK
)
956 switch (armv8_curel_from_core_mode(arm
->core_mode
)) {
957 case SYSTEM_CUREL_EL0
:
958 instr
= ARMV8_SYS(SYSTEM_ATS12E0R
, 0);
959 /* can only execute instruction at EL2 */
960 target_mode
= ARMV8_64_EL2H
;
962 case SYSTEM_CUREL_EL1
:
963 instr
= ARMV8_SYS(SYSTEM_ATS12E1R
, 0);
964 /* can only execute instruction at EL2 */
965 target_mode
= ARMV8_64_EL2H
;
967 case SYSTEM_CUREL_EL2
:
968 instr
= ARMV8_SYS(SYSTEM_ATS1E2R
, 0);
970 case SYSTEM_CUREL_EL3
:
971 instr
= ARMV8_SYS(SYSTEM_ATS1E3R
, 0);
978 if (target_mode
!= ARM_MODE_ANY
)
979 armv8_dpm_modeswitch(dpm
, target_mode
);
981 /* write VA to R0 and execute translation instruction */
982 retval
= dpm
->instr_write_data_r0_64(dpm
, instr
, (uint64_t)va
);
983 /* read result from PAR_EL1 */
984 if (retval
== ERROR_OK
)
985 retval
= dpm
->instr_read_data_r0_64(dpm
, ARMV8_MRS(SYSTEM_PAR_EL1
, 0), &par
);
987 /* switch back to saved PE mode */
988 if (target_mode
!= ARM_MODE_ANY
)
989 armv8_dpm_modeswitch(dpm
, ARM_MODE_ANY
);
993 if (retval
!= ERROR_OK
)
997 LOG_ERROR("Address translation failed at stage %i, FST=%x, PTW=%i",
998 ((int)(par
>> 9) & 1)+1, (int)(par
>> 1) & 0x3f, (int)(par
>> 8) & 1);
1001 retval
= ERROR_FAIL
;
1003 *val
= (par
& 0xFFFFFFFFF000UL
) | (va
& 0xFFF);
1005 int SH
= (par
>> 7) & 3;
1006 int NS
= (par
>> 9) & 1;
1007 int ATTR
= (par
>> 56) & 0xFF;
1009 char *memtype
= (ATTR
& 0xF0) == 0 ? "Device Memory" : "Normal Memory";
1011 LOG_USER("%sshareable, %s",
1012 shared_name
[SH
], secure_name
[NS
]);
1013 LOG_USER("%s", memtype
);
1020 COMMAND_HANDLER(armv8_handle_exception_catch_command
)
1022 struct target
*target
= get_current_target(CMD_CTX
);
1023 struct armv8_common
*armv8
= target_to_armv8(target
);
1024 uint32_t edeccr
= 0;
1025 unsigned int argp
= 0;
1028 static const Jim_Nvp nvp_ecatch_modes
[] = {
1029 { .name
= "off", .value
= 0 },
1030 { .name
= "nsec_el1", .value
= (1 << 5) },
1031 { .name
= "nsec_el2", .value
= (2 << 5) },
1032 { .name
= "nsec_el12", .value
= (3 << 5) },
1033 { .name
= "sec_el1", .value
= (1 << 1) },
1034 { .name
= "sec_el3", .value
= (4 << 1) },
1035 { .name
= "sec_el13", .value
= (5 << 1) },
1036 { .name
= NULL
, .value
= -1 },
1040 if (CMD_ARGC
== 0) {
1041 const char *sec
= NULL
, *nsec
= NULL
;
1043 retval
= mem_ap_read_atomic_u32(armv8
->debug_ap
,
1044 armv8
->debug_base
+ CPUV8_DBG_ECCR
, &edeccr
);
1045 if (retval
!= ERROR_OK
)
1048 n
= Jim_Nvp_value2name_simple(nvp_ecatch_modes
, edeccr
& 0x0f);
1049 if (n
->name
!= NULL
)
1052 n
= Jim_Nvp_value2name_simple(nvp_ecatch_modes
, edeccr
& 0xf0);
1053 if (n
->name
!= NULL
)
1056 if (sec
== NULL
|| nsec
== NULL
) {
1057 LOG_WARNING("Exception Catch: unknown exception catch configuration: EDECCR = %02" PRIx32
, edeccr
& 0xff);
1061 command_print(CMD
, "Exception Catch: Secure: %s, Non-Secure: %s", sec
, nsec
);
1065 while (CMD_ARGC
> argp
) {
1066 n
= Jim_Nvp_name2value_simple(nvp_ecatch_modes
, CMD_ARGV
[argp
]);
1067 if (n
->name
== NULL
) {
1068 LOG_ERROR("Unknown option: %s", CMD_ARGV
[argp
]);
1072 LOG_DEBUG("found: %s", n
->name
);
1078 retval
= mem_ap_write_atomic_u32(armv8
->debug_ap
,
1079 armv8
->debug_base
+ CPUV8_DBG_ECCR
, edeccr
);
1080 if (retval
!= ERROR_OK
)
1086 int armv8_handle_cache_info_command(struct command_invocation
*cmd
,
1087 struct armv8_cache_common
*armv8_cache
)
1089 if (armv8_cache
->info
== -1) {
1090 command_print(cmd
, "cache not yet identified");
1094 if (armv8_cache
->display_cache_info
)
1095 armv8_cache
->display_cache_info(cmd
, armv8_cache
);
1099 static int armv8_setup_semihosting(struct target
*target
, int enable
)
1101 struct arm
*arm
= target_to_arm(target
);
1103 if (arm
->core_state
!= ARM_STATE_AARCH64
) {
1104 LOG_ERROR("semihosting only supported in AArch64 state\n");
1111 int armv8_init_arch_info(struct target
*target
, struct armv8_common
*armv8
)
1113 struct arm
*arm
= &armv8
->arm
;
1114 arm
->arch_info
= armv8
;
1115 target
->arch_info
= &armv8
->arm
;
1116 arm
->setup_semihosting
= armv8_setup_semihosting
;
1117 /* target is useful in all function arm v4 5 compatible */
1118 armv8
->arm
.target
= target
;
1119 armv8
->arm
.common_magic
= ARM_COMMON_MAGIC
;
1120 armv8
->common_magic
= ARMV8_COMMON_MAGIC
;
1122 armv8
->armv8_mmu
.armv8_cache
.l2_cache
= NULL
;
1123 armv8
->armv8_mmu
.armv8_cache
.info
= -1;
1124 armv8
->armv8_mmu
.armv8_cache
.flush_all_data_cache
= NULL
;
1125 armv8
->armv8_mmu
.armv8_cache
.display_cache_info
= NULL
;
1129 int armv8_aarch64_state(struct target
*target
)
1131 struct arm
*arm
= target_to_arm(target
);
1133 if (arm
->common_magic
!= ARM_COMMON_MAGIC
) {
1134 LOG_ERROR("BUG: called for a non-ARM target");
1138 LOG_USER("%s halted in %s state due to %s, current mode: %s\n"
1139 "cpsr: 0x%8.8" PRIx32
" pc: 0x%" PRIx64
"%s",
1140 target_name(target
),
1141 armv8_state_strings
[arm
->core_state
],
1142 debug_reason_name(target
),
1143 armv8_mode_name(arm
->core_mode
),
1144 buf_get_u32(arm
->cpsr
->value
, 0, 32),
1145 buf_get_u64(arm
->pc
->value
, 0, 64),
1146 (target
->semihosting
&& target
->semihosting
->is_active
) ? ", semihosting" : "");
1151 int armv8_arch_state(struct target
*target
)
1153 static const char * const state
[] = {
1154 "disabled", "enabled"
1157 struct armv8_common
*armv8
= target_to_armv8(target
);
1158 struct arm
*arm
= &armv8
->arm
;
1160 if (armv8
->common_magic
!= ARMV8_COMMON_MAGIC
) {
1161 LOG_ERROR("BUG: called for a non-Armv8 target");
1162 return ERROR_COMMAND_SYNTAX_ERROR
;
1165 if (arm
->core_state
== ARM_STATE_AARCH64
)
1166 armv8_aarch64_state(target
);
1168 arm_arch_state(target
);
1170 LOG_USER("MMU: %s, D-Cache: %s, I-Cache: %s",
1171 state
[armv8
->armv8_mmu
.mmu_enabled
],
1172 state
[armv8
->armv8_mmu
.armv8_cache
.d_u_cache_enabled
],
1173 state
[armv8
->armv8_mmu
.armv8_cache
.i_cache_enabled
]);
1175 if (arm
->core_mode
== ARM_MODE_ABT
)
1176 armv8_show_fault_registers(target
);
1178 if (target
->debug_reason
== DBG_REASON_WATCHPOINT
)
1179 LOG_USER("Watchpoint triggered at PC %#08x",
1180 (unsigned) armv8
->dpm
.wp_pc
);
1185 static struct reg_data_type aarch64_vector_base_types
[] = {
1186 {REG_TYPE_IEEE_DOUBLE
, "ieee_double", 0, {NULL
} },
1187 {REG_TYPE_UINT64
, "uint64", 0, {NULL
} },
1188 {REG_TYPE_INT64
, "int64", 0, {NULL
} },
1189 {REG_TYPE_IEEE_SINGLE
, "ieee_single", 0, {NULL
} },
1190 {REG_TYPE_UINT32
, "uint32", 0, {NULL
} },
1191 {REG_TYPE_INT32
, "int32", 0, {NULL
} },
1192 {REG_TYPE_UINT16
, "uint16", 0, {NULL
} },
1193 {REG_TYPE_INT16
, "int16", 0, {NULL
} },
1194 {REG_TYPE_UINT8
, "uint8", 0, {NULL
} },
1195 {REG_TYPE_INT8
, "int8", 0, {NULL
} },
1196 {REG_TYPE_UINT128
, "uint128", 0, {NULL
} },
1197 {REG_TYPE_INT128
, "int128", 0, {NULL
} }
1200 static struct reg_data_type_vector aarch64_vector_types
[] = {
1201 {aarch64_vector_base_types
+ 0, 2},
1202 {aarch64_vector_base_types
+ 1, 2},
1203 {aarch64_vector_base_types
+ 2, 2},
1204 {aarch64_vector_base_types
+ 3, 4},
1205 {aarch64_vector_base_types
+ 4, 4},
1206 {aarch64_vector_base_types
+ 5, 4},
1207 {aarch64_vector_base_types
+ 6, 8},
1208 {aarch64_vector_base_types
+ 7, 8},
1209 {aarch64_vector_base_types
+ 8, 16},
1210 {aarch64_vector_base_types
+ 9, 16},
1211 {aarch64_vector_base_types
+ 10, 01},
1212 {aarch64_vector_base_types
+ 11, 01},
1215 static struct reg_data_type aarch64_fpu_vector
[] = {
1216 {REG_TYPE_ARCH_DEFINED
, "v2d", REG_TYPE_CLASS_VECTOR
, {aarch64_vector_types
+ 0} },
1217 {REG_TYPE_ARCH_DEFINED
, "v2u", REG_TYPE_CLASS_VECTOR
, {aarch64_vector_types
+ 1} },
1218 {REG_TYPE_ARCH_DEFINED
, "v2i", REG_TYPE_CLASS_VECTOR
, {aarch64_vector_types
+ 2} },
1219 {REG_TYPE_ARCH_DEFINED
, "v4f", REG_TYPE_CLASS_VECTOR
, {aarch64_vector_types
+ 3} },
1220 {REG_TYPE_ARCH_DEFINED
, "v4u", REG_TYPE_CLASS_VECTOR
, {aarch64_vector_types
+ 4} },
1221 {REG_TYPE_ARCH_DEFINED
, "v4i", REG_TYPE_CLASS_VECTOR
, {aarch64_vector_types
+ 5} },
1222 {REG_TYPE_ARCH_DEFINED
, "v8u", REG_TYPE_CLASS_VECTOR
, {aarch64_vector_types
+ 6} },
1223 {REG_TYPE_ARCH_DEFINED
, "v8i", REG_TYPE_CLASS_VECTOR
, {aarch64_vector_types
+ 7} },
1224 {REG_TYPE_ARCH_DEFINED
, "v16u", REG_TYPE_CLASS_VECTOR
, {aarch64_vector_types
+ 8} },
1225 {REG_TYPE_ARCH_DEFINED
, "v16i", REG_TYPE_CLASS_VECTOR
, {aarch64_vector_types
+ 9} },
1226 {REG_TYPE_ARCH_DEFINED
, "v1u", REG_TYPE_CLASS_VECTOR
, {aarch64_vector_types
+ 10} },
1227 {REG_TYPE_ARCH_DEFINED
, "v1i", REG_TYPE_CLASS_VECTOR
, {aarch64_vector_types
+ 11} },
1230 static struct reg_data_type_union_field aarch64_union_fields_vnd
[] = {
1231 {"f", aarch64_fpu_vector
+ 0, aarch64_union_fields_vnd
+ 1},
1232 {"u", aarch64_fpu_vector
+ 1, aarch64_union_fields_vnd
+ 2},
1233 {"s", aarch64_fpu_vector
+ 2, NULL
},
1236 static struct reg_data_type_union_field aarch64_union_fields_vns
[] = {
1237 {"f", aarch64_fpu_vector
+ 3, aarch64_union_fields_vns
+ 1},
1238 {"u", aarch64_fpu_vector
+ 4, aarch64_union_fields_vns
+ 2},
1239 {"s", aarch64_fpu_vector
+ 5, NULL
},
1242 static struct reg_data_type_union_field aarch64_union_fields_vnh
[] = {
1243 {"u", aarch64_fpu_vector
+ 6, aarch64_union_fields_vnh
+ 1},
1244 {"s", aarch64_fpu_vector
+ 7, NULL
},
1247 static struct reg_data_type_union_field aarch64_union_fields_vnb
[] = {
1248 {"u", aarch64_fpu_vector
+ 8, aarch64_union_fields_vnb
+ 1},
1249 {"s", aarch64_fpu_vector
+ 9, NULL
},
1252 static struct reg_data_type_union_field aarch64_union_fields_vnq
[] = {
1253 {"u", aarch64_fpu_vector
+ 10, aarch64_union_fields_vnq
+ 1},
1254 {"s", aarch64_fpu_vector
+ 11, NULL
},
1257 static struct reg_data_type_union aarch64_union_types
[] = {
1258 {aarch64_union_fields_vnd
},
1259 {aarch64_union_fields_vns
},
1260 {aarch64_union_fields_vnh
},
1261 {aarch64_union_fields_vnb
},
1262 {aarch64_union_fields_vnq
},
1265 static struct reg_data_type aarch64_fpu_union
[] = {
1266 {REG_TYPE_ARCH_DEFINED
, "vnd", REG_TYPE_CLASS_UNION
, {.reg_type_union
= aarch64_union_types
+ 0} },
1267 {REG_TYPE_ARCH_DEFINED
, "vns", REG_TYPE_CLASS_UNION
, {.reg_type_union
= aarch64_union_types
+ 1} },
1268 {REG_TYPE_ARCH_DEFINED
, "vnh", REG_TYPE_CLASS_UNION
, {.reg_type_union
= aarch64_union_types
+ 2} },
1269 {REG_TYPE_ARCH_DEFINED
, "vnb", REG_TYPE_CLASS_UNION
, {.reg_type_union
= aarch64_union_types
+ 3} },
1270 {REG_TYPE_ARCH_DEFINED
, "vnq", REG_TYPE_CLASS_UNION
, {.reg_type_union
= aarch64_union_types
+ 4} },
1273 static struct reg_data_type_union_field aarch64v_union_fields
[] = {
1274 {"d", aarch64_fpu_union
+ 0, aarch64v_union_fields
+ 1},
1275 {"s", aarch64_fpu_union
+ 1, aarch64v_union_fields
+ 2},
1276 {"h", aarch64_fpu_union
+ 2, aarch64v_union_fields
+ 3},
1277 {"b", aarch64_fpu_union
+ 3, aarch64v_union_fields
+ 4},
1278 {"q", aarch64_fpu_union
+ 4, NULL
},
1281 static struct reg_data_type_union aarch64v_union
[] = {
1282 {aarch64v_union_fields
}
1285 static struct reg_data_type aarch64v
[] = {
1286 {REG_TYPE_ARCH_DEFINED
, "aarch64v", REG_TYPE_CLASS_UNION
,
1287 {.reg_type_union
= aarch64v_union
} },
1290 static struct reg_data_type_bitfield aarch64_cpsr_bits
[] = {
1291 { 0, 0, REG_TYPE_UINT8
},
1292 { 2, 3, REG_TYPE_UINT8
},
1293 { 4, 4, REG_TYPE_UINT8
},
1294 { 6, 6, REG_TYPE_BOOL
},
1295 { 7, 7, REG_TYPE_BOOL
},
1296 { 8, 8, REG_TYPE_BOOL
},
1297 { 9, 9, REG_TYPE_BOOL
},
1298 { 20, 20, REG_TYPE_BOOL
},
1299 { 21, 21, REG_TYPE_BOOL
},
1300 { 28, 28, REG_TYPE_BOOL
},
1301 { 29, 29, REG_TYPE_BOOL
},
1302 { 30, 30, REG_TYPE_BOOL
},
1303 { 31, 31, REG_TYPE_BOOL
},
1306 static struct reg_data_type_flags_field aarch64_cpsr_fields
[] = {
1307 { "SP", aarch64_cpsr_bits
+ 0, aarch64_cpsr_fields
+ 1 },
1308 { "EL", aarch64_cpsr_bits
+ 1, aarch64_cpsr_fields
+ 2 },
1309 { "nRW", aarch64_cpsr_bits
+ 2, aarch64_cpsr_fields
+ 3 },
1310 { "F", aarch64_cpsr_bits
+ 3, aarch64_cpsr_fields
+ 4 },
1311 { "I", aarch64_cpsr_bits
+ 4, aarch64_cpsr_fields
+ 5 },
1312 { "A", aarch64_cpsr_bits
+ 5, aarch64_cpsr_fields
+ 6 },
1313 { "D", aarch64_cpsr_bits
+ 6, aarch64_cpsr_fields
+ 7 },
1314 { "IL", aarch64_cpsr_bits
+ 7, aarch64_cpsr_fields
+ 8 },
1315 { "SS", aarch64_cpsr_bits
+ 8, aarch64_cpsr_fields
+ 9 },
1316 { "V", aarch64_cpsr_bits
+ 9, aarch64_cpsr_fields
+ 10 },
1317 { "C", aarch64_cpsr_bits
+ 10, aarch64_cpsr_fields
+ 11 },
1318 { "Z", aarch64_cpsr_bits
+ 11, aarch64_cpsr_fields
+ 12 },
1319 { "N", aarch64_cpsr_bits
+ 12, NULL
}
1322 static struct reg_data_type_flags aarch64_cpsr_flags
[] = {
1323 { 4, aarch64_cpsr_fields
}
1326 static struct reg_data_type aarch64_flags_cpsr
[] = {
1327 {REG_TYPE_ARCH_DEFINED
, "cpsr_flags", REG_TYPE_CLASS_FLAGS
,
1328 {.reg_type_flags
= aarch64_cpsr_flags
} },
1331 static const struct {
1338 const char *feature
;
1339 struct reg_data_type
*data_type
;
1341 { ARMV8_R0
, "x0", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1342 { ARMV8_R1
, "x1", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1343 { ARMV8_R2
, "x2", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1344 { ARMV8_R3
, "x3", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1345 { ARMV8_R4
, "x4", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1346 { ARMV8_R5
, "x5", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1347 { ARMV8_R6
, "x6", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1348 { ARMV8_R7
, "x7", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1349 { ARMV8_R8
, "x8", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1350 { ARMV8_R9
, "x9", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1351 { ARMV8_R10
, "x10", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1352 { ARMV8_R11
, "x11", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1353 { ARMV8_R12
, "x12", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1354 { ARMV8_R13
, "x13", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1355 { ARMV8_R14
, "x14", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1356 { ARMV8_R15
, "x15", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1357 { ARMV8_R16
, "x16", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1358 { ARMV8_R17
, "x17", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1359 { ARMV8_R18
, "x18", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1360 { ARMV8_R19
, "x19", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1361 { ARMV8_R20
, "x20", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1362 { ARMV8_R21
, "x21", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1363 { ARMV8_R22
, "x22", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1364 { ARMV8_R23
, "x23", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1365 { ARMV8_R24
, "x24", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1366 { ARMV8_R25
, "x25", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1367 { ARMV8_R26
, "x26", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1368 { ARMV8_R27
, "x27", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1369 { ARMV8_R28
, "x28", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1370 { ARMV8_R29
, "x29", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1371 { ARMV8_R30
, "x30", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1373 { ARMV8_SP
, "sp", 64, ARM_MODE_ANY
, REG_TYPE_DATA_PTR
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1374 { ARMV8_PC
, "pc", 64, ARM_MODE_ANY
, REG_TYPE_CODE_PTR
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1375 { ARMV8_xPSR
, "cpsr", 32, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
,
1376 "general", "org.gnu.gdb.aarch64.core", aarch64_flags_cpsr
},
1377 { ARMV8_V0
, "v0", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1378 { ARMV8_V1
, "v1", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1379 { ARMV8_V2
, "v2", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1380 { ARMV8_V3
, "v3", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1381 { ARMV8_V4
, "v4", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1382 { ARMV8_V5
, "v5", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1383 { ARMV8_V6
, "v6", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1384 { ARMV8_V7
, "v7", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1385 { ARMV8_V8
, "v8", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1386 { ARMV8_V9
, "v9", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1387 { ARMV8_V10
, "v10", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1388 { ARMV8_V11
, "v11", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1389 { ARMV8_V12
, "v12", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1390 { ARMV8_V13
, "v13", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1391 { ARMV8_V14
, "v14", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1392 { ARMV8_V15
, "v15", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1393 { ARMV8_V16
, "v16", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1394 { ARMV8_V17
, "v17", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1395 { ARMV8_V18
, "v18", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1396 { ARMV8_V19
, "v19", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1397 { ARMV8_V20
, "v20", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1398 { ARMV8_V21
, "v21", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1399 { ARMV8_V22
, "v22", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1400 { ARMV8_V23
, "v23", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1401 { ARMV8_V24
, "v24", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1402 { ARMV8_V25
, "v25", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1403 { ARMV8_V26
, "v26", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1404 { ARMV8_V27
, "v27", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1405 { ARMV8_V28
, "v28", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1406 { ARMV8_V29
, "v29", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1407 { ARMV8_V30
, "v30", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1408 { ARMV8_V31
, "v31", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1409 { ARMV8_FPSR
, "fpsr", 32, ARM_MODE_ANY
, REG_TYPE_UINT32
, "simdfp", "org.gnu.gdb.aarch64.fpu", NULL
},
1410 { ARMV8_FPCR
, "fpcr", 32, ARM_MODE_ANY
, REG_TYPE_UINT32
, "simdfp", "org.gnu.gdb.aarch64.fpu", NULL
},
1412 { ARMV8_ELR_EL1
, "ELR_EL1", 64, ARMV8_64_EL1H
, REG_TYPE_CODE_PTR
, "banked", "net.sourceforge.openocd.banked",
1414 { ARMV8_ESR_EL1
, "ESR_EL1", 32, ARMV8_64_EL1H
, REG_TYPE_UINT32
, "banked", "net.sourceforge.openocd.banked",
1416 { ARMV8_SPSR_EL1
, "SPSR_EL1", 32, ARMV8_64_EL1H
, REG_TYPE_UINT32
, "banked", "net.sourceforge.openocd.banked",
1419 { ARMV8_ELR_EL2
, "ELR_EL2", 64, ARMV8_64_EL2H
, REG_TYPE_CODE_PTR
, "banked", "net.sourceforge.openocd.banked",
1421 { ARMV8_ESR_EL2
, "ESR_EL2", 32, ARMV8_64_EL2H
, REG_TYPE_UINT32
, "banked", "net.sourceforge.openocd.banked",
1423 { ARMV8_SPSR_EL2
, "SPSR_EL2", 32, ARMV8_64_EL2H
, REG_TYPE_UINT32
, "banked", "net.sourceforge.openocd.banked",
1426 { ARMV8_ELR_EL3
, "ELR_EL3", 64, ARMV8_64_EL3H
, REG_TYPE_CODE_PTR
, "banked", "net.sourceforge.openocd.banked",
1428 { ARMV8_ESR_EL3
, "ESR_EL3", 32, ARMV8_64_EL3H
, REG_TYPE_UINT32
, "banked", "net.sourceforge.openocd.banked",
1430 { ARMV8_SPSR_EL3
, "SPSR_EL3", 32, ARMV8_64_EL3H
, REG_TYPE_UINT32
, "banked", "net.sourceforge.openocd.banked",
1434 static const struct {
1442 const char *feature
;
1443 } armv8_regs32
[] = {
1444 { ARMV8_R0
, 0, "r0", 32, ARM_MODE_ANY
, REG_TYPE_UINT32
, "general", "org.gnu.gdb.arm.core" },
1445 { ARMV8_R1
, 0, "r1", 32, ARM_MODE_ANY
, REG_TYPE_UINT32
, "general", "org.gnu.gdb.arm.core" },
1446 { ARMV8_R2
, 0, "r2", 32, ARM_MODE_ANY
, REG_TYPE_UINT32
, "general", "org.gnu.gdb.arm.core" },
1447 { ARMV8_R3
, 0, "r3", 32, ARM_MODE_ANY
, REG_TYPE_UINT32
, "general", "org.gnu.gdb.arm.core" },
1448 { ARMV8_R4
, 0, "r4", 32, ARM_MODE_ANY
, REG_TYPE_UINT32
, "general", "org.gnu.gdb.arm.core" },
1449 { ARMV8_R5
, 0, "r5", 32, ARM_MODE_ANY
, REG_TYPE_UINT32
, "general", "org.gnu.gdb.arm.core" },
1450 { ARMV8_R6
, 0, "r6", 32, ARM_MODE_ANY
, REG_TYPE_UINT32
, "general", "org.gnu.gdb.arm.core" },
1451 { ARMV8_R7
, 0, "r7", 32, ARM_MODE_ANY
, REG_TYPE_UINT32
, "general", "org.gnu.gdb.arm.core" },
1452 { ARMV8_R8
, 0, "r8", 32, ARM_MODE_ANY
, REG_TYPE_UINT32
, "general", "org.gnu.gdb.arm.core" },
1453 { ARMV8_R9
, 0, "r9", 32, ARM_MODE_ANY
, REG_TYPE_UINT32
, "general", "org.gnu.gdb.arm.core" },
1454 { ARMV8_R10
, 0, "r10", 32, ARM_MODE_ANY
, REG_TYPE_UINT32
, "general", "org.gnu.gdb.arm.core" },
1455 { ARMV8_R11
, 0, "r11", 32, ARM_MODE_ANY
, REG_TYPE_UINT32
, "general", "org.gnu.gdb.arm.core" },
1456 { ARMV8_R12
, 0, "r12", 32, ARM_MODE_ANY
, REG_TYPE_UINT32
, "general", "org.gnu.gdb.arm.core" },
1457 { ARMV8_R13
, 0, "sp", 32, ARM_MODE_ANY
, REG_TYPE_DATA_PTR
, "general", "org.gnu.gdb.arm.core" },
1458 { ARMV8_R14
, 0, "lr", 32, ARM_MODE_ANY
, REG_TYPE_CODE_PTR
, "general", "org.gnu.gdb.arm.core" },
1459 { ARMV8_PC
, 0, "pc", 32, ARM_MODE_ANY
, REG_TYPE_CODE_PTR
, "general", "org.gnu.gdb.arm.core" },
1460 { ARMV8_xPSR
, 0, "cpsr", 32, ARM_MODE_ANY
, REG_TYPE_UINT32
, "general", "org.gnu.gdb.arm.core" },
1461 { ARMV8_V0
, 0, "d0", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1462 { ARMV8_V0
, 8, "d1", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1463 { ARMV8_V1
, 0, "d2", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1464 { ARMV8_V1
, 8, "d3", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1465 { ARMV8_V2
, 0, "d4", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1466 { ARMV8_V2
, 8, "d5", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1467 { ARMV8_V3
, 0, "d6", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1468 { ARMV8_V3
, 8, "d7", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1469 { ARMV8_V4
, 0, "d8", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1470 { ARMV8_V4
, 8, "d9", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1471 { ARMV8_V5
, 0, "d10", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1472 { ARMV8_V5
, 8, "d11", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1473 { ARMV8_V6
, 0, "d12", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1474 { ARMV8_V6
, 8, "d13", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1475 { ARMV8_V7
, 0, "d14", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1476 { ARMV8_V7
, 8, "d15", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1477 { ARMV8_V8
, 0, "d16", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1478 { ARMV8_V8
, 8, "d17", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1479 { ARMV8_V9
, 0, "d18", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1480 { ARMV8_V9
, 8, "d19", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1481 { ARMV8_V10
, 0, "d20", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1482 { ARMV8_V10
, 8, "d21", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1483 { ARMV8_V11
, 0, "d22", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1484 { ARMV8_V11
, 8, "d23", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1485 { ARMV8_V12
, 0, "d24", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1486 { ARMV8_V12
, 8, "d25", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1487 { ARMV8_V13
, 0, "d26", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1488 { ARMV8_V13
, 8, "d27", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1489 { ARMV8_V14
, 0, "d28", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1490 { ARMV8_V14
, 8, "d29", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1491 { ARMV8_V15
, 0, "d30", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1492 { ARMV8_V15
, 8, "d31", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1493 { ARMV8_FPSR
, 0, "fpscr", 32, ARM_MODE_ANY
, REG_TYPE_UINT32
, "float", "org.gnu.gdb.arm.vfp"},
1496 #define ARMV8_NUM_REGS ARRAY_SIZE(armv8_regs)
1497 #define ARMV8_NUM_REGS32 ARRAY_SIZE(armv8_regs32)
1499 static int armv8_get_core_reg(struct reg
*reg
)
1501 struct arm_reg
*armv8_reg
= reg
->arch_info
;
1502 struct target
*target
= armv8_reg
->target
;
1503 struct arm
*arm
= target_to_arm(target
);
1505 if (target
->state
!= TARGET_HALTED
)
1506 return ERROR_TARGET_NOT_HALTED
;
1508 return arm
->read_core_reg(target
, reg
, armv8_reg
->num
, arm
->core_mode
);
1511 static int armv8_set_core_reg(struct reg
*reg
, uint8_t *buf
)
1513 struct arm_reg
*armv8_reg
= reg
->arch_info
;
1514 struct target
*target
= armv8_reg
->target
;
1515 struct arm
*arm
= target_to_arm(target
);
1516 uint64_t value
= buf_get_u64(buf
, 0, reg
->size
);
1518 if (target
->state
!= TARGET_HALTED
)
1519 return ERROR_TARGET_NOT_HALTED
;
1521 if (reg
->size
<= 64) {
1522 if (reg
== arm
->cpsr
)
1523 armv8_set_cpsr(arm
, (uint32_t)value
);
1525 buf_set_u64(reg
->value
, 0, reg
->size
, value
);
1528 } else if (reg
->size
<= 128) {
1529 uint64_t hvalue
= buf_get_u64(buf
+ 8, 0, reg
->size
- 64);
1531 buf_set_u64(reg
->value
, 0, 64, value
);
1532 buf_set_u64(reg
->value
+ 8, 0, reg
->size
- 64, hvalue
);
1541 static const struct reg_arch_type armv8_reg_type
= {
1542 .get
= armv8_get_core_reg
,
1543 .set
= armv8_set_core_reg
,
1546 static int armv8_get_core_reg32(struct reg
*reg
)
1548 struct arm_reg
*armv8_reg
= reg
->arch_info
;
1549 struct target
*target
= armv8_reg
->target
;
1550 struct arm
*arm
= target_to_arm(target
);
1551 struct reg_cache
*cache
= arm
->core_cache
;
1555 if (target
->state
!= TARGET_HALTED
)
1556 return ERROR_TARGET_NOT_HALTED
;
1558 /* get the corresponding Aarch64 register */
1559 reg64
= cache
->reg_list
+ armv8_reg
->num
;
1565 retval
= arm
->read_core_reg(target
, reg64
, armv8_reg
->num
, arm
->core_mode
);
1566 if (retval
== ERROR_OK
)
1567 reg
->valid
= reg64
->valid
;
1572 static int armv8_set_core_reg32(struct reg
*reg
, uint8_t *buf
)
1574 struct arm_reg
*armv8_reg
= reg
->arch_info
;
1575 struct target
*target
= armv8_reg
->target
;
1576 struct arm
*arm
= target_to_arm(target
);
1577 struct reg_cache
*cache
= arm
->core_cache
;
1578 struct reg
*reg64
= cache
->reg_list
+ armv8_reg
->num
;
1579 uint32_t value
= buf_get_u32(buf
, 0, 32);
1581 if (target
->state
!= TARGET_HALTED
)
1582 return ERROR_TARGET_NOT_HALTED
;
1584 if (reg64
== arm
->cpsr
) {
1585 armv8_set_cpsr(arm
, value
);
1587 if (reg
->size
<= 32)
1588 buf_set_u32(reg
->value
, 0, 32, value
);
1589 else if (reg
->size
<= 64) {
1590 uint64_t value64
= buf_get_u64(buf
, 0, 64);
1591 buf_set_u64(reg
->value
, 0, 64, value64
);
1594 reg64
->valid
= true;
1597 reg64
->dirty
= true;
1602 static const struct reg_arch_type armv8_reg32_type
= {
1603 .get
= armv8_get_core_reg32
,
1604 .set
= armv8_set_core_reg32
,
1607 /** Builds cache of architecturally defined registers. */
1608 struct reg_cache
*armv8_build_reg_cache(struct target
*target
)
1610 struct armv8_common
*armv8
= target_to_armv8(target
);
1611 struct arm
*arm
= &armv8
->arm
;
1612 int num_regs
= ARMV8_NUM_REGS
;
1613 int num_regs32
= ARMV8_NUM_REGS32
;
1614 struct reg_cache
**cache_p
= register_get_last_cache_p(&target
->reg_cache
);
1615 struct reg_cache
*cache
= malloc(sizeof(struct reg_cache
));
1616 struct reg_cache
*cache32
= malloc(sizeof(struct reg_cache
));
1617 struct reg
*reg_list
= calloc(num_regs
, sizeof(struct reg
));
1618 struct reg
*reg_list32
= calloc(num_regs32
, sizeof(struct reg
));
1619 struct arm_reg
*arch_info
= calloc(num_regs
, sizeof(struct arm_reg
));
1620 struct reg_feature
*feature
;
1623 /* Build the process context cache */
1624 cache
->name
= "Aarch64 registers";
1625 cache
->next
= cache32
;
1626 cache
->reg_list
= reg_list
;
1627 cache
->num_regs
= num_regs
;
1629 for (i
= 0; i
< num_regs
; i
++) {
1630 arch_info
[i
].num
= armv8_regs
[i
].id
;
1631 arch_info
[i
].mode
= armv8_regs
[i
].mode
;
1632 arch_info
[i
].target
= target
;
1633 arch_info
[i
].arm
= arm
;
1635 reg_list
[i
].name
= armv8_regs
[i
].name
;
1636 reg_list
[i
].size
= armv8_regs
[i
].bits
;
1637 reg_list
[i
].value
= &arch_info
[i
].value
[0];
1638 reg_list
[i
].type
= &armv8_reg_type
;
1639 reg_list
[i
].arch_info
= &arch_info
[i
];
1641 reg_list
[i
].group
= armv8_regs
[i
].group
;
1642 reg_list
[i
].number
= i
;
1643 reg_list
[i
].exist
= true;
1644 reg_list
[i
].caller_save
= true; /* gdb defaults to true */
1646 feature
= calloc(1, sizeof(struct reg_feature
));
1648 feature
->name
= armv8_regs
[i
].feature
;
1649 reg_list
[i
].feature
= feature
;
1651 LOG_ERROR("unable to allocate feature list");
1653 reg_list
[i
].reg_data_type
= calloc(1, sizeof(struct reg_data_type
));
1654 if (reg_list
[i
].reg_data_type
) {
1655 if (armv8_regs
[i
].data_type
== NULL
)
1656 reg_list
[i
].reg_data_type
->type
= armv8_regs
[i
].type
;
1658 *reg_list
[i
].reg_data_type
= *armv8_regs
[i
].data_type
;
1660 LOG_ERROR("unable to allocate reg type list");
1663 arm
->cpsr
= reg_list
+ ARMV8_xPSR
;
1664 arm
->pc
= reg_list
+ ARMV8_PC
;
1665 arm
->core_cache
= cache
;
1667 /* shadow cache for ARM mode registers */
1668 cache32
->name
= "Aarch32 registers";
1669 cache32
->next
= NULL
;
1670 cache32
->reg_list
= reg_list32
;
1671 cache32
->num_regs
= num_regs32
;
1673 for (i
= 0; i
< num_regs32
; i
++) {
1674 reg_list32
[i
].name
= armv8_regs32
[i
].name
;
1675 reg_list32
[i
].size
= armv8_regs32
[i
].bits
;
1676 reg_list32
[i
].value
= &arch_info
[armv8_regs32
[i
].id
].value
[armv8_regs32
[i
].mapping
];
1677 reg_list32
[i
].type
= &armv8_reg32_type
;
1678 reg_list32
[i
].arch_info
= &arch_info
[armv8_regs32
[i
].id
];
1679 reg_list32
[i
].group
= armv8_regs32
[i
].group
;
1680 reg_list32
[i
].number
= i
;
1681 reg_list32
[i
].exist
= true;
1682 reg_list32
[i
].caller_save
= true;
1684 feature
= calloc(1, sizeof(struct reg_feature
));
1686 feature
->name
= armv8_regs32
[i
].feature
;
1687 reg_list32
[i
].feature
= feature
;
1689 LOG_ERROR("unable to allocate feature list");
1691 reg_list32
[i
].reg_data_type
= calloc(1, sizeof(struct reg_data_type
));
1692 if (reg_list32
[i
].reg_data_type
)
1693 reg_list32
[i
].reg_data_type
->type
= armv8_regs32
[i
].type
;
1695 LOG_ERROR("unable to allocate reg type list");
1702 struct reg
*armv8_reg_current(struct arm
*arm
, unsigned regnum
)
1706 if (regnum
> (ARMV8_LAST_REG
- 1))
1709 r
= arm
->core_cache
->reg_list
+ regnum
;
1713 static void armv8_free_cache(struct reg_cache
*cache
, bool regs32
)
1721 for (i
= 0; i
< cache
->num_regs
; i
++) {
1722 reg
= &cache
->reg_list
[i
];
1725 free(reg
->reg_data_type
);
1729 free(cache
->reg_list
[0].arch_info
);
1730 free(cache
->reg_list
);
1734 void armv8_free_reg_cache(struct target
*target
)
1736 struct armv8_common
*armv8
= target_to_armv8(target
);
1737 struct arm
*arm
= &armv8
->arm
;
1738 struct reg_cache
*cache
= NULL
, *cache32
= NULL
;
1740 cache
= arm
->core_cache
;
1742 cache32
= cache
->next
;
1743 armv8_free_cache(cache32
, true);
1744 armv8_free_cache(cache
, false);
1745 arm
->core_cache
= NULL
;
1748 const struct command_registration armv8_command_handlers
[] = {
1750 .name
= "catch_exc",
1751 .handler
= armv8_handle_exception_catch_command
,
1752 .mode
= COMMAND_EXEC
,
1753 .help
= "configure exception catch",
1754 .usage
= "[(nsec_el1,nsec_el2,sec_el1,sec_el3)+,off]",
1756 COMMAND_REGISTRATION_DONE
1759 const char *armv8_get_gdb_arch(struct target
*target
)
1761 struct arm
*arm
= target_to_arm(target
);
1762 return arm
->core_state
== ARM_STATE_AARCH64
? "aarch64" : "arm";
1765 int armv8_get_gdb_reg_list(struct target
*target
,
1766 struct reg
**reg_list
[], int *reg_list_size
,
1767 enum target_register_class reg_class
)
1769 struct arm
*arm
= target_to_arm(target
);
1772 if (arm
->core_state
== ARM_STATE_AARCH64
) {
1774 LOG_DEBUG("Creating Aarch64 register list for target %s", target_name(target
));
1776 switch (reg_class
) {
1777 case REG_CLASS_GENERAL
:
1778 *reg_list_size
= ARMV8_V0
;
1779 *reg_list
= malloc(sizeof(struct reg
*) * (*reg_list_size
));
1781 for (i
= 0; i
< *reg_list_size
; i
++)
1782 (*reg_list
)[i
] = armv8_reg_current(arm
, i
);
1786 *reg_list_size
= ARMV8_LAST_REG
;
1787 *reg_list
= malloc(sizeof(struct reg
*) * (*reg_list_size
));
1789 for (i
= 0; i
< *reg_list_size
; i
++)
1790 (*reg_list
)[i
] = armv8_reg_current(arm
, i
);
1795 LOG_ERROR("not a valid register class type in query.");
1799 struct reg_cache
*cache32
= arm
->core_cache
->next
;
1801 LOG_DEBUG("Creating Aarch32 register list for target %s", target_name(target
));
1803 switch (reg_class
) {
1804 case REG_CLASS_GENERAL
:
1805 *reg_list_size
= ARMV8_R14
+ 3;
1806 *reg_list
= malloc(sizeof(struct reg
*) * (*reg_list_size
));
1808 for (i
= 0; i
< *reg_list_size
; i
++)
1809 (*reg_list
)[i
] = cache32
->reg_list
+ i
;
1813 *reg_list_size
= cache32
->num_regs
;
1814 *reg_list
= malloc(sizeof(struct reg
*) * (*reg_list_size
));
1816 for (i
= 0; i
< *reg_list_size
; i
++)
1817 (*reg_list
)[i
] = cache32
->reg_list
+ i
;
1821 LOG_ERROR("not a valid register class type in query.");
1827 int armv8_set_dbgreg_bits(struct armv8_common
*armv8
, unsigned int reg
, unsigned long mask
, unsigned long value
)
1832 int retval
= mem_ap_read_atomic_u32(armv8
->debug_ap
,
1833 armv8
->debug_base
+ reg
, &tmp
);
1834 if (ERROR_OK
!= retval
)
1837 /* clear bitfield */
1840 tmp
|= value
& mask
;
1842 /* write new value */
1843 retval
= mem_ap_write_atomic_u32(armv8
->debug_ap
,
1844 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)