1 // SPDX-License-Identifier: GPL-2.0-or-later
3 /***************************************************************************
4 * Copyright (C) 2015 by David Ung *
6 * Copyright (C) 2018 by Liviu Ionescu *
8 ***************************************************************************/
14 #include <helper/replacements.h>
17 #include "arm_disassembler.h"
20 #include <helper/binarybuffer.h>
21 #include <helper/command.h>
27 #include "armv8_opcodes.h"
29 #include "target_type.h"
30 #include "semihosting_common.h"
32 static const char * const armv8_state_strings
[] = {
33 "AArch32", "Thumb", "Jazelle", "ThumbEE", "AArch64",
39 } armv8_mode_data
[] = {
102 .psr
= ARMV8_64_EL3H
,
106 /** Map PSR mode bits to the name of an ARM processor operating mode. */
107 const char *armv8_mode_name(unsigned psr_mode
)
109 for (unsigned i
= 0; i
< ARRAY_SIZE(armv8_mode_data
); i
++) {
110 if (armv8_mode_data
[i
].psr
== psr_mode
)
111 return armv8_mode_data
[i
].name
;
113 LOG_ERROR("unrecognized psr mode: %#02x", psr_mode
);
114 return "UNRECOGNIZED";
117 static int armv8_read_reg(struct armv8_common
*armv8
, int regnum
, uint64_t *regval
)
119 struct arm_dpm
*dpm
= &armv8
->dpm
;
126 retval
= dpm
->instr_read_data_dcc_64(dpm
,
127 ARMV8_MSR_GP(SYSTEM_DBG_DBGDTR_EL0
, regnum
), &value_64
);
130 retval
= dpm
->instr_read_data_r0_64(dpm
,
131 ARMV8_MOVFSP_64(0), &value_64
);
134 retval
= dpm
->instr_read_data_r0_64(dpm
,
135 ARMV8_MRS_DLR(0), &value_64
);
138 retval
= dpm
->instr_read_data_r0(dpm
,
139 ARMV8_MRS_DSPSR(0), &value
);
143 retval
= dpm
->instr_read_data_r0(dpm
,
144 ARMV8_MRS_FPSR(0), &value
);
148 retval
= dpm
->instr_read_data_r0(dpm
,
149 ARMV8_MRS_FPCR(0), &value
);
153 retval
= dpm
->instr_read_data_r0_64(dpm
,
154 ARMV8_MRS(SYSTEM_ELR_EL1
, 0), &value_64
);
157 retval
= dpm
->instr_read_data_r0_64(dpm
,
158 ARMV8_MRS(SYSTEM_ELR_EL2
, 0), &value_64
);
161 retval
= dpm
->instr_read_data_r0_64(dpm
,
162 ARMV8_MRS(SYSTEM_ELR_EL3
, 0), &value_64
);
165 retval
= dpm
->instr_read_data_r0(dpm
,
166 ARMV8_MRS(SYSTEM_ESR_EL1
, 0), &value
);
170 retval
= dpm
->instr_read_data_r0(dpm
,
171 ARMV8_MRS(SYSTEM_ESR_EL2
, 0), &value
);
175 retval
= dpm
->instr_read_data_r0(dpm
,
176 ARMV8_MRS(SYSTEM_ESR_EL3
, 0), &value
);
180 retval
= dpm
->instr_read_data_r0(dpm
,
181 ARMV8_MRS(SYSTEM_SPSR_EL1
, 0), &value
);
185 retval
= dpm
->instr_read_data_r0(dpm
,
186 ARMV8_MRS(SYSTEM_SPSR_EL2
, 0), &value
);
190 retval
= dpm
->instr_read_data_r0(dpm
,
191 ARMV8_MRS(SYSTEM_SPSR_EL3
, 0), &value
);
199 if (retval
== ERROR_OK
&& regval
)
207 static int armv8_read_reg_simdfp_aarch64(struct armv8_common
*armv8
, int regnum
, uint64_t *lvalue
, uint64_t *hvalue
)
209 int retval
= ERROR_FAIL
;
210 struct arm_dpm
*dpm
= &armv8
->dpm
;
213 case ARMV8_V0
... ARMV8_V31
:
214 retval
= dpm
->instr_read_data_r0_64(dpm
,
215 ARMV8_MOV_GPR_VFP(0, (regnum
- ARMV8_V0
), 1), hvalue
);
216 if (retval
!= ERROR_OK
)
218 retval
= dpm
->instr_read_data_r0_64(dpm
,
219 ARMV8_MOV_GPR_VFP(0, (regnum
- ARMV8_V0
), 0), lvalue
);
230 static int armv8_write_reg(struct armv8_common
*armv8
, int regnum
, uint64_t value_64
)
232 struct arm_dpm
*dpm
= &armv8
->dpm
;
238 retval
= dpm
->instr_write_data_dcc_64(dpm
,
239 ARMV8_MRS(SYSTEM_DBG_DBGDTR_EL0
, regnum
),
243 retval
= dpm
->instr_write_data_r0_64(dpm
,
248 retval
= dpm
->instr_write_data_r0_64(dpm
,
254 retval
= dpm
->instr_write_data_r0(dpm
,
260 retval
= dpm
->instr_write_data_r0(dpm
,
266 retval
= dpm
->instr_write_data_r0(dpm
,
270 /* registers clobbered by taking exception in debug state */
272 retval
= dpm
->instr_write_data_r0_64(dpm
,
273 ARMV8_MSR_GP(SYSTEM_ELR_EL1
, 0), value_64
);
276 retval
= dpm
->instr_write_data_r0_64(dpm
,
277 ARMV8_MSR_GP(SYSTEM_ELR_EL2
, 0), value_64
);
280 retval
= dpm
->instr_write_data_r0_64(dpm
,
281 ARMV8_MSR_GP(SYSTEM_ELR_EL3
, 0), value_64
);
285 retval
= dpm
->instr_write_data_r0(dpm
,
286 ARMV8_MSR_GP(SYSTEM_ESR_EL1
, 0), value
);
290 retval
= dpm
->instr_write_data_r0(dpm
,
291 ARMV8_MSR_GP(SYSTEM_ESR_EL2
, 0), value
);
295 retval
= dpm
->instr_write_data_r0(dpm
,
296 ARMV8_MSR_GP(SYSTEM_ESR_EL3
, 0), value
);
300 retval
= dpm
->instr_write_data_r0(dpm
,
301 ARMV8_MSR_GP(SYSTEM_SPSR_EL1
, 0), value
);
305 retval
= dpm
->instr_write_data_r0(dpm
,
306 ARMV8_MSR_GP(SYSTEM_SPSR_EL2
, 0), value
);
310 retval
= dpm
->instr_write_data_r0(dpm
,
311 ARMV8_MSR_GP(SYSTEM_SPSR_EL3
, 0), value
);
321 static int armv8_write_reg_simdfp_aarch64(struct armv8_common
*armv8
, int regnum
, uint64_t lvalue
, uint64_t hvalue
)
323 int retval
= ERROR_FAIL
;
324 struct arm_dpm
*dpm
= &armv8
->dpm
;
327 case ARMV8_V0
... ARMV8_V31
:
328 retval
= dpm
->instr_write_data_r0_64(dpm
,
329 ARMV8_MOV_VFP_GPR((regnum
- ARMV8_V0
), 0, 1), hvalue
);
330 if (retval
!= ERROR_OK
)
332 retval
= dpm
->instr_write_data_r0_64(dpm
,
333 ARMV8_MOV_VFP_GPR((regnum
- ARMV8_V0
), 0, 0), lvalue
);
344 static int armv8_read_reg32(struct armv8_common
*armv8
, int regnum
, uint64_t *regval
)
346 struct arm_dpm
*dpm
= &armv8
->dpm
;
351 case ARMV8_R0
... ARMV8_R14
:
352 /* return via DCC: "MCR p14, 0, Rnum, c0, c5, 0" */
353 retval
= dpm
->instr_read_data_dcc(dpm
,
354 ARMV4_5_MCR(14, 0, regnum
, 0, 5, 0),
358 retval
= dpm
->instr_read_data_dcc(dpm
,
359 ARMV4_5_MCR(14, 0, 13, 0, 5, 0),
363 retval
= dpm
->instr_read_data_r0(dpm
,
368 retval
= dpm
->instr_read_data_r0(dpm
,
372 case ARMV8_ELR_EL1
: /* mapped to LR_svc */
373 retval
= dpm
->instr_read_data_dcc(dpm
,
374 ARMV4_5_MCR(14, 0, 14, 0, 5, 0),
377 case ARMV8_ELR_EL2
: /* mapped to ELR_hyp */
378 retval
= dpm
->instr_read_data_r0(dpm
,
379 ARMV8_MRS_T1(0, 14, 0, 1),
382 case ARMV8_ELR_EL3
: /* mapped to LR_mon */
383 retval
= dpm
->instr_read_data_dcc(dpm
,
384 ARMV4_5_MCR(14, 0, 14, 0, 5, 0),
387 case ARMV8_ESR_EL1
: /* mapped to DFSR */
388 retval
= dpm
->instr_read_data_r0(dpm
,
389 ARMV4_5_MRC(15, 0, 0, 5, 0, 0),
392 case ARMV8_ESR_EL2
: /* mapped to HSR */
393 retval
= dpm
->instr_read_data_r0(dpm
,
394 ARMV4_5_MRC(15, 4, 0, 5, 2, 0),
397 case ARMV8_ESR_EL3
: /* FIXME: no equivalent in aarch32? */
400 case ARMV8_SPSR_EL1
: /* mapped to SPSR_svc */
401 retval
= dpm
->instr_read_data_r0(dpm
,
402 ARMV8_MRS_XPSR_T1(1, 0),
405 case ARMV8_SPSR_EL2
: /* mapped to SPSR_hyp */
406 retval
= dpm
->instr_read_data_r0(dpm
,
407 ARMV8_MRS_XPSR_T1(1, 0),
410 case ARMV8_SPSR_EL3
: /* mapped to SPSR_mon */
411 retval
= dpm
->instr_read_data_r0(dpm
,
412 ARMV8_MRS_XPSR_T1(1, 0),
416 /* "VMRS r0, FPSCR"; then return via DCC */
417 retval
= dpm
->instr_read_data_r0(dpm
,
418 ARMV4_5_VMRS(0), &value
);
425 if (retval
== ERROR_OK
&& regval
)
431 static int armv8_read_reg_simdfp_aarch32(struct armv8_common
*armv8
, int regnum
, uint64_t *lvalue
, uint64_t *hvalue
)
433 int retval
= ERROR_FAIL
;
434 struct arm_dpm
*dpm
= &armv8
->dpm
;
435 struct reg
*reg_r1
= dpm
->arm
->core_cache
->reg_list
+ ARMV8_R1
;
436 uint32_t value_r0
= 0, value_r1
= 0;
437 unsigned num
= (regnum
- ARMV8_V0
) << 1;
440 case ARMV8_V0
... ARMV8_V15
:
441 /* we are going to write R1, mark it dirty */
442 reg_r1
->dirty
= true;
443 /* move from double word register to r0:r1: "vmov r0, r1, vm"
444 * then read r0 via dcc
446 retval
= dpm
->instr_read_data_r0(dpm
,
447 ARMV4_5_VMOV(1, 1, 0, (num
>> 4), (num
& 0xf)),
449 if (retval
!= ERROR_OK
)
451 /* read r1 via dcc */
452 retval
= dpm
->instr_read_data_dcc(dpm
,
453 ARMV4_5_MCR(14, 0, 1, 0, 5, 0),
455 if (retval
!= ERROR_OK
)
458 *lvalue
= ((*lvalue
) << 32) | value_r0
;
461 /* repeat above steps for high 64 bits of V register */
462 retval
= dpm
->instr_read_data_r0(dpm
,
463 ARMV4_5_VMOV(1, 1, 0, (num
>> 4), (num
& 0xf)),
465 if (retval
!= ERROR_OK
)
467 retval
= dpm
->instr_read_data_dcc(dpm
,
468 ARMV4_5_MCR(14, 0, 1, 0, 5, 0),
470 if (retval
!= ERROR_OK
)
473 *hvalue
= ((*hvalue
) << 32) | value_r0
;
483 static int armv8_write_reg32(struct armv8_common
*armv8
, int regnum
, uint64_t value
)
485 struct arm_dpm
*dpm
= &armv8
->dpm
;
489 case ARMV8_R0
... ARMV8_R14
:
490 /* load register from DCC: "MRC p14, 0, Rnum, c0, c5, 0" */
491 retval
= dpm
->instr_write_data_dcc(dpm
,
492 ARMV4_5_MRC(14, 0, regnum
, 0, 5, 0), value
);
495 retval
= dpm
->instr_write_data_dcc(dpm
,
496 ARMV4_5_MRC(14, 0, 13, 0, 5, 0), value
);
499 * read r0 from DCC; then "MOV pc, r0" */
500 retval
= dpm
->instr_write_data_r0(dpm
,
501 ARMV8_MCR_DLR(0), value
);
503 case ARMV8_XPSR
: /* CPSR */
504 /* read r0 from DCC, then "MCR r0, DSPSR" */
505 retval
= dpm
->instr_write_data_r0(dpm
,
506 ARMV8_MCR_DSPSR(0), value
);
508 case ARMV8_ELR_EL1
: /* mapped to LR_svc */
509 retval
= dpm
->instr_write_data_dcc(dpm
,
510 ARMV4_5_MRC(14, 0, 14, 0, 5, 0),
513 case ARMV8_ELR_EL2
: /* mapped to ELR_hyp */
514 retval
= dpm
->instr_write_data_r0(dpm
,
515 ARMV8_MSR_GP_T1(0, 14, 0, 1),
518 case ARMV8_ELR_EL3
: /* mapped to LR_mon */
519 retval
= dpm
->instr_write_data_dcc(dpm
,
520 ARMV4_5_MRC(14, 0, 14, 0, 5, 0),
523 case ARMV8_ESR_EL1
: /* mapped to DFSR */
524 retval
= dpm
->instr_write_data_r0(dpm
,
525 ARMV4_5_MCR(15, 0, 0, 5, 0, 0),
528 case ARMV8_ESR_EL2
: /* mapped to HSR */
529 retval
= dpm
->instr_write_data_r0(dpm
,
530 ARMV4_5_MCR(15, 4, 0, 5, 2, 0),
533 case ARMV8_ESR_EL3
: /* FIXME: no equivalent in aarch32? */
536 case ARMV8_SPSR_EL1
: /* mapped to SPSR_svc */
537 retval
= dpm
->instr_write_data_r0(dpm
,
538 ARMV8_MSR_GP_XPSR_T1(1, 0, 15),
541 case ARMV8_SPSR_EL2
: /* mapped to SPSR_hyp */
542 retval
= dpm
->instr_write_data_r0(dpm
,
543 ARMV8_MSR_GP_XPSR_T1(1, 0, 15),
546 case ARMV8_SPSR_EL3
: /* mapped to SPSR_mon */
547 retval
= dpm
->instr_write_data_r0(dpm
,
548 ARMV8_MSR_GP_XPSR_T1(1, 0, 15),
552 /* move to r0 from DCC, then "VMSR FPSCR, r0" */
553 retval
= dpm
->instr_write_data_r0(dpm
,
554 ARMV4_5_VMSR(0), value
);
565 static int armv8_write_reg_simdfp_aarch32(struct armv8_common
*armv8
, int regnum
, uint64_t lvalue
, uint64_t hvalue
)
567 int retval
= ERROR_FAIL
;
568 struct arm_dpm
*dpm
= &armv8
->dpm
;
569 struct reg
*reg_r1
= dpm
->arm
->core_cache
->reg_list
+ ARMV8_R1
;
570 uint32_t value_r0
= 0, value_r1
= 0;
571 unsigned num
= (regnum
- ARMV8_V0
) << 1;
574 case ARMV8_V0
... ARMV8_V15
:
575 /* we are going to write R1, mark it dirty */
576 reg_r1
->dirty
= true;
577 value_r1
= lvalue
>> 32;
578 value_r0
= lvalue
& 0xFFFFFFFF;
579 /* write value_r1 to r1 via dcc */
580 retval
= dpm
->instr_write_data_dcc(dpm
,
581 ARMV4_5_MRC(14, 0, 1, 0, 5, 0),
583 if (retval
!= ERROR_OK
)
585 /* write value_r0 to r0 via dcc then,
586 * move to double word register from r0:r1: "vmov vm, r0, r1"
588 retval
= dpm
->instr_write_data_r0(dpm
,
589 ARMV4_5_VMOV(0, 1, 0, (num
>> 4), (num
& 0xf)),
591 if (retval
!= ERROR_OK
)
595 /* repeat above steps for high 64 bits of V register */
596 value_r1
= hvalue
>> 32;
597 value_r0
= hvalue
& 0xFFFFFFFF;
598 retval
= dpm
->instr_write_data_dcc(dpm
,
599 ARMV4_5_MRC(14, 0, 1, 0, 5, 0),
601 if (retval
!= ERROR_OK
)
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 struct 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 },
1038 const struct jim_nvp
*n
;
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);
1052 n
= jim_nvp_value2name_simple(nvp_ecatch_modes
, edeccr
& 0xf0);
1056 if (!sec
|| !nsec
) {
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 (argp
< CMD_ARGC
) {
1066 n
= jim_nvp_name2value_simple(nvp_ecatch_modes
, CMD_ARGV
[argp
]);
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
)
1104 int armv8_init_arch_info(struct target
*target
, struct armv8_common
*armv8
)
1106 struct arm
*arm
= &armv8
->arm
;
1107 arm
->arch_info
= armv8
;
1108 target
->arch_info
= &armv8
->arm
;
1109 arm
->setup_semihosting
= armv8_setup_semihosting
;
1110 /* target is useful in all function arm v4 5 compatible */
1111 armv8
->arm
.target
= target
;
1112 armv8
->arm
.common_magic
= ARM_COMMON_MAGIC
;
1113 armv8
->common_magic
= ARMV8_COMMON_MAGIC
;
1115 armv8
->armv8_mmu
.armv8_cache
.l2_cache
= NULL
;
1116 armv8
->armv8_mmu
.armv8_cache
.info
= -1;
1117 armv8
->armv8_mmu
.armv8_cache
.flush_all_data_cache
= NULL
;
1118 armv8
->armv8_mmu
.armv8_cache
.display_cache_info
= NULL
;
1122 static int armv8_aarch64_state(struct target
*target
)
1124 struct arm
*arm
= target_to_arm(target
);
1126 if (arm
->common_magic
!= ARM_COMMON_MAGIC
) {
1127 LOG_ERROR("BUG: called for a non-ARM target");
1131 LOG_USER("%s halted in %s state due to %s, current mode: %s\n"
1132 "cpsr: 0x%8.8" PRIx32
" pc: 0x%" PRIx64
"%s",
1133 target_name(target
),
1134 armv8_state_strings
[arm
->core_state
],
1135 debug_reason_name(target
),
1136 armv8_mode_name(arm
->core_mode
),
1137 buf_get_u32(arm
->cpsr
->value
, 0, 32),
1138 buf_get_u64(arm
->pc
->value
, 0, 64),
1139 (target
->semihosting
&& target
->semihosting
->is_active
) ? ", semihosting" : "");
1144 int armv8_arch_state(struct target
*target
)
1146 static const char * const state
[] = {
1147 "disabled", "enabled"
1150 struct armv8_common
*armv8
= target_to_armv8(target
);
1151 struct arm
*arm
= &armv8
->arm
;
1153 if (armv8
->common_magic
!= ARMV8_COMMON_MAGIC
) {
1154 LOG_ERROR("BUG: called for a non-Armv8 target");
1155 return ERROR_COMMAND_SYNTAX_ERROR
;
1158 if (arm
->core_state
== ARM_STATE_AARCH64
)
1159 armv8_aarch64_state(target
);
1161 arm_arch_state(target
);
1163 LOG_USER("MMU: %s, D-Cache: %s, I-Cache: %s",
1164 state
[armv8
->armv8_mmu
.mmu_enabled
],
1165 state
[armv8
->armv8_mmu
.armv8_cache
.d_u_cache_enabled
],
1166 state
[armv8
->armv8_mmu
.armv8_cache
.i_cache_enabled
]);
1168 if (arm
->core_mode
== ARM_MODE_ABT
)
1169 armv8_show_fault_registers(target
);
1171 if (target
->debug_reason
== DBG_REASON_WATCHPOINT
)
1172 LOG_USER("Watchpoint triggered at " TARGET_ADDR_FMT
, armv8
->dpm
.wp_addr
);
1177 static struct reg_data_type aarch64_vector_base_types
[] = {
1178 {REG_TYPE_IEEE_DOUBLE
, "ieee_double", 0, {NULL
} },
1179 {REG_TYPE_UINT64
, "uint64", 0, {NULL
} },
1180 {REG_TYPE_INT64
, "int64", 0, {NULL
} },
1181 {REG_TYPE_IEEE_SINGLE
, "ieee_single", 0, {NULL
} },
1182 {REG_TYPE_UINT32
, "uint32", 0, {NULL
} },
1183 {REG_TYPE_INT32
, "int32", 0, {NULL
} },
1184 {REG_TYPE_UINT16
, "uint16", 0, {NULL
} },
1185 {REG_TYPE_INT16
, "int16", 0, {NULL
} },
1186 {REG_TYPE_UINT8
, "uint8", 0, {NULL
} },
1187 {REG_TYPE_INT8
, "int8", 0, {NULL
} },
1188 {REG_TYPE_UINT128
, "uint128", 0, {NULL
} },
1189 {REG_TYPE_INT128
, "int128", 0, {NULL
} }
1192 static struct reg_data_type_vector aarch64_vector_types
[] = {
1193 {aarch64_vector_base_types
+ 0, 2},
1194 {aarch64_vector_base_types
+ 1, 2},
1195 {aarch64_vector_base_types
+ 2, 2},
1196 {aarch64_vector_base_types
+ 3, 4},
1197 {aarch64_vector_base_types
+ 4, 4},
1198 {aarch64_vector_base_types
+ 5, 4},
1199 {aarch64_vector_base_types
+ 6, 8},
1200 {aarch64_vector_base_types
+ 7, 8},
1201 {aarch64_vector_base_types
+ 8, 16},
1202 {aarch64_vector_base_types
+ 9, 16},
1203 {aarch64_vector_base_types
+ 10, 01},
1204 {aarch64_vector_base_types
+ 11, 01},
1207 static struct reg_data_type aarch64_fpu_vector
[] = {
1208 {REG_TYPE_ARCH_DEFINED
, "v2d", REG_TYPE_CLASS_VECTOR
, {aarch64_vector_types
+ 0} },
1209 {REG_TYPE_ARCH_DEFINED
, "v2u", REG_TYPE_CLASS_VECTOR
, {aarch64_vector_types
+ 1} },
1210 {REG_TYPE_ARCH_DEFINED
, "v2i", REG_TYPE_CLASS_VECTOR
, {aarch64_vector_types
+ 2} },
1211 {REG_TYPE_ARCH_DEFINED
, "v4f", REG_TYPE_CLASS_VECTOR
, {aarch64_vector_types
+ 3} },
1212 {REG_TYPE_ARCH_DEFINED
, "v4u", REG_TYPE_CLASS_VECTOR
, {aarch64_vector_types
+ 4} },
1213 {REG_TYPE_ARCH_DEFINED
, "v4i", REG_TYPE_CLASS_VECTOR
, {aarch64_vector_types
+ 5} },
1214 {REG_TYPE_ARCH_DEFINED
, "v8u", REG_TYPE_CLASS_VECTOR
, {aarch64_vector_types
+ 6} },
1215 {REG_TYPE_ARCH_DEFINED
, "v8i", REG_TYPE_CLASS_VECTOR
, {aarch64_vector_types
+ 7} },
1216 {REG_TYPE_ARCH_DEFINED
, "v16u", REG_TYPE_CLASS_VECTOR
, {aarch64_vector_types
+ 8} },
1217 {REG_TYPE_ARCH_DEFINED
, "v16i", REG_TYPE_CLASS_VECTOR
, {aarch64_vector_types
+ 9} },
1218 {REG_TYPE_ARCH_DEFINED
, "v1u", REG_TYPE_CLASS_VECTOR
, {aarch64_vector_types
+ 10} },
1219 {REG_TYPE_ARCH_DEFINED
, "v1i", REG_TYPE_CLASS_VECTOR
, {aarch64_vector_types
+ 11} },
1222 static struct reg_data_type_union_field aarch64_union_fields_vnd
[] = {
1223 {"f", aarch64_fpu_vector
+ 0, aarch64_union_fields_vnd
+ 1},
1224 {"u", aarch64_fpu_vector
+ 1, aarch64_union_fields_vnd
+ 2},
1225 {"s", aarch64_fpu_vector
+ 2, NULL
},
1228 static struct reg_data_type_union_field aarch64_union_fields_vns
[] = {
1229 {"f", aarch64_fpu_vector
+ 3, aarch64_union_fields_vns
+ 1},
1230 {"u", aarch64_fpu_vector
+ 4, aarch64_union_fields_vns
+ 2},
1231 {"s", aarch64_fpu_vector
+ 5, NULL
},
1234 static struct reg_data_type_union_field aarch64_union_fields_vnh
[] = {
1235 {"u", aarch64_fpu_vector
+ 6, aarch64_union_fields_vnh
+ 1},
1236 {"s", aarch64_fpu_vector
+ 7, NULL
},
1239 static struct reg_data_type_union_field aarch64_union_fields_vnb
[] = {
1240 {"u", aarch64_fpu_vector
+ 8, aarch64_union_fields_vnb
+ 1},
1241 {"s", aarch64_fpu_vector
+ 9, NULL
},
1244 static struct reg_data_type_union_field aarch64_union_fields_vnq
[] = {
1245 {"u", aarch64_fpu_vector
+ 10, aarch64_union_fields_vnq
+ 1},
1246 {"s", aarch64_fpu_vector
+ 11, NULL
},
1249 static struct reg_data_type_union aarch64_union_types
[] = {
1250 {aarch64_union_fields_vnd
},
1251 {aarch64_union_fields_vns
},
1252 {aarch64_union_fields_vnh
},
1253 {aarch64_union_fields_vnb
},
1254 {aarch64_union_fields_vnq
},
1257 static struct reg_data_type aarch64_fpu_union
[] = {
1258 {REG_TYPE_ARCH_DEFINED
, "vnd", REG_TYPE_CLASS_UNION
, {.reg_type_union
= aarch64_union_types
+ 0} },
1259 {REG_TYPE_ARCH_DEFINED
, "vns", REG_TYPE_CLASS_UNION
, {.reg_type_union
= aarch64_union_types
+ 1} },
1260 {REG_TYPE_ARCH_DEFINED
, "vnh", REG_TYPE_CLASS_UNION
, {.reg_type_union
= aarch64_union_types
+ 2} },
1261 {REG_TYPE_ARCH_DEFINED
, "vnb", REG_TYPE_CLASS_UNION
, {.reg_type_union
= aarch64_union_types
+ 3} },
1262 {REG_TYPE_ARCH_DEFINED
, "vnq", REG_TYPE_CLASS_UNION
, {.reg_type_union
= aarch64_union_types
+ 4} },
1265 static struct reg_data_type_union_field aarch64v_union_fields
[] = {
1266 {"d", aarch64_fpu_union
+ 0, aarch64v_union_fields
+ 1},
1267 {"s", aarch64_fpu_union
+ 1, aarch64v_union_fields
+ 2},
1268 {"h", aarch64_fpu_union
+ 2, aarch64v_union_fields
+ 3},
1269 {"b", aarch64_fpu_union
+ 3, aarch64v_union_fields
+ 4},
1270 {"q", aarch64_fpu_union
+ 4, NULL
},
1273 static struct reg_data_type_union aarch64v_union
[] = {
1274 {aarch64v_union_fields
}
1277 static struct reg_data_type aarch64v
[] = {
1278 {REG_TYPE_ARCH_DEFINED
, "aarch64v", REG_TYPE_CLASS_UNION
,
1279 {.reg_type_union
= aarch64v_union
} },
1282 static struct reg_data_type_bitfield aarch64_cpsr_bits
[] = {
1283 { 0, 0, REG_TYPE_UINT8
},
1284 { 2, 3, REG_TYPE_UINT8
},
1285 { 4, 4, REG_TYPE_UINT8
},
1286 { 6, 6, REG_TYPE_BOOL
},
1287 { 7, 7, REG_TYPE_BOOL
},
1288 { 8, 8, REG_TYPE_BOOL
},
1289 { 9, 9, REG_TYPE_BOOL
},
1290 { 20, 20, REG_TYPE_BOOL
},
1291 { 21, 21, REG_TYPE_BOOL
},
1292 { 28, 28, REG_TYPE_BOOL
},
1293 { 29, 29, REG_TYPE_BOOL
},
1294 { 30, 30, REG_TYPE_BOOL
},
1295 { 31, 31, REG_TYPE_BOOL
},
1298 static struct reg_data_type_flags_field aarch64_cpsr_fields
[] = {
1299 { "SP", aarch64_cpsr_bits
+ 0, aarch64_cpsr_fields
+ 1 },
1300 { "EL", aarch64_cpsr_bits
+ 1, aarch64_cpsr_fields
+ 2 },
1301 { "nRW", aarch64_cpsr_bits
+ 2, aarch64_cpsr_fields
+ 3 },
1302 { "F", aarch64_cpsr_bits
+ 3, aarch64_cpsr_fields
+ 4 },
1303 { "I", aarch64_cpsr_bits
+ 4, aarch64_cpsr_fields
+ 5 },
1304 { "A", aarch64_cpsr_bits
+ 5, aarch64_cpsr_fields
+ 6 },
1305 { "D", aarch64_cpsr_bits
+ 6, aarch64_cpsr_fields
+ 7 },
1306 { "IL", aarch64_cpsr_bits
+ 7, aarch64_cpsr_fields
+ 8 },
1307 { "SS", aarch64_cpsr_bits
+ 8, aarch64_cpsr_fields
+ 9 },
1308 { "V", aarch64_cpsr_bits
+ 9, aarch64_cpsr_fields
+ 10 },
1309 { "C", aarch64_cpsr_bits
+ 10, aarch64_cpsr_fields
+ 11 },
1310 { "Z", aarch64_cpsr_bits
+ 11, aarch64_cpsr_fields
+ 12 },
1311 { "N", aarch64_cpsr_bits
+ 12, NULL
}
1314 static struct reg_data_type_flags aarch64_cpsr_flags
[] = {
1315 { 4, aarch64_cpsr_fields
}
1318 static struct reg_data_type aarch64_flags_cpsr
[] = {
1319 {REG_TYPE_ARCH_DEFINED
, "cpsr_flags", REG_TYPE_CLASS_FLAGS
,
1320 {.reg_type_flags
= aarch64_cpsr_flags
} },
1323 static const struct {
1330 const char *feature
;
1331 struct reg_data_type
*data_type
;
1333 { ARMV8_R0
, "x0", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1334 { ARMV8_R1
, "x1", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1335 { ARMV8_R2
, "x2", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1336 { ARMV8_R3
, "x3", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1337 { ARMV8_R4
, "x4", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1338 { ARMV8_R5
, "x5", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1339 { ARMV8_R6
, "x6", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1340 { ARMV8_R7
, "x7", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1341 { ARMV8_R8
, "x8", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1342 { ARMV8_R9
, "x9", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1343 { ARMV8_R10
, "x10", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1344 { ARMV8_R11
, "x11", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1345 { ARMV8_R12
, "x12", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1346 { ARMV8_R13
, "x13", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1347 { ARMV8_R14
, "x14", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1348 { ARMV8_R15
, "x15", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1349 { ARMV8_R16
, "x16", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1350 { ARMV8_R17
, "x17", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1351 { ARMV8_R18
, "x18", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1352 { ARMV8_R19
, "x19", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1353 { ARMV8_R20
, "x20", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1354 { ARMV8_R21
, "x21", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1355 { ARMV8_R22
, "x22", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1356 { ARMV8_R23
, "x23", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1357 { ARMV8_R24
, "x24", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1358 { ARMV8_R25
, "x25", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1359 { ARMV8_R26
, "x26", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1360 { ARMV8_R27
, "x27", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1361 { ARMV8_R28
, "x28", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1362 { ARMV8_R29
, "x29", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1363 { ARMV8_R30
, "x30", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1365 { ARMV8_SP
, "sp", 64, ARM_MODE_ANY
, REG_TYPE_DATA_PTR
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1366 { ARMV8_PC
, "pc", 64, ARM_MODE_ANY
, REG_TYPE_CODE_PTR
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1367 { ARMV8_XPSR
, "cpsr", 32, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
,
1368 "general", "org.gnu.gdb.aarch64.core", aarch64_flags_cpsr
},
1369 { ARMV8_V0
, "v0", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1370 { ARMV8_V1
, "v1", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1371 { ARMV8_V2
, "v2", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1372 { ARMV8_V3
, "v3", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1373 { ARMV8_V4
, "v4", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1374 { ARMV8_V5
, "v5", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1375 { ARMV8_V6
, "v6", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1376 { ARMV8_V7
, "v7", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1377 { ARMV8_V8
, "v8", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1378 { ARMV8_V9
, "v9", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1379 { ARMV8_V10
, "v10", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1380 { ARMV8_V11
, "v11", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1381 { ARMV8_V12
, "v12", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1382 { ARMV8_V13
, "v13", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1383 { ARMV8_V14
, "v14", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1384 { ARMV8_V15
, "v15", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1385 { ARMV8_V16
, "v16", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1386 { ARMV8_V17
, "v17", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1387 { ARMV8_V18
, "v18", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1388 { ARMV8_V19
, "v19", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1389 { ARMV8_V20
, "v20", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1390 { ARMV8_V21
, "v21", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1391 { ARMV8_V22
, "v22", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1392 { ARMV8_V23
, "v23", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1393 { ARMV8_V24
, "v24", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1394 { ARMV8_V25
, "v25", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1395 { ARMV8_V26
, "v26", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1396 { ARMV8_V27
, "v27", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1397 { ARMV8_V28
, "v28", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1398 { ARMV8_V29
, "v29", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1399 { ARMV8_V30
, "v30", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1400 { ARMV8_V31
, "v31", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1401 { ARMV8_FPSR
, "fpsr", 32, ARM_MODE_ANY
, REG_TYPE_UINT32
, "simdfp", "org.gnu.gdb.aarch64.fpu", NULL
},
1402 { ARMV8_FPCR
, "fpcr", 32, ARM_MODE_ANY
, REG_TYPE_UINT32
, "simdfp", "org.gnu.gdb.aarch64.fpu", NULL
},
1404 { ARMV8_ELR_EL1
, "ELR_EL1", 64, ARMV8_64_EL1H
, REG_TYPE_CODE_PTR
, "banked", "net.sourceforge.openocd.banked",
1406 { ARMV8_ESR_EL1
, "ESR_EL1", 32, ARMV8_64_EL1H
, REG_TYPE_UINT32
, "banked", "net.sourceforge.openocd.banked",
1408 { ARMV8_SPSR_EL1
, "SPSR_EL1", 32, ARMV8_64_EL1H
, REG_TYPE_UINT32
, "banked", "net.sourceforge.openocd.banked",
1411 { ARMV8_ELR_EL2
, "ELR_EL2", 64, ARMV8_64_EL2H
, REG_TYPE_CODE_PTR
, "banked", "net.sourceforge.openocd.banked",
1413 { ARMV8_ESR_EL2
, "ESR_EL2", 32, ARMV8_64_EL2H
, REG_TYPE_UINT32
, "banked", "net.sourceforge.openocd.banked",
1415 { ARMV8_SPSR_EL2
, "SPSR_EL2", 32, ARMV8_64_EL2H
, REG_TYPE_UINT32
, "banked", "net.sourceforge.openocd.banked",
1418 { ARMV8_ELR_EL3
, "ELR_EL3", 64, ARMV8_64_EL3H
, REG_TYPE_CODE_PTR
, "banked", "net.sourceforge.openocd.banked",
1420 { ARMV8_ESR_EL3
, "ESR_EL3", 32, ARMV8_64_EL3H
, REG_TYPE_UINT32
, "banked", "net.sourceforge.openocd.banked",
1422 { ARMV8_SPSR_EL3
, "SPSR_EL3", 32, ARMV8_64_EL3H
, REG_TYPE_UINT32
, "banked", "net.sourceforge.openocd.banked",
1426 static const struct {
1434 const char *feature
;
1435 } armv8_regs32
[] = {
1436 { ARMV8_R0
, 0, "r0", 32, ARM_MODE_ANY
, REG_TYPE_UINT32
, "general", "org.gnu.gdb.arm.core" },
1437 { ARMV8_R1
, 0, "r1", 32, ARM_MODE_ANY
, REG_TYPE_UINT32
, "general", "org.gnu.gdb.arm.core" },
1438 { ARMV8_R2
, 0, "r2", 32, ARM_MODE_ANY
, REG_TYPE_UINT32
, "general", "org.gnu.gdb.arm.core" },
1439 { ARMV8_R3
, 0, "r3", 32, ARM_MODE_ANY
, REG_TYPE_UINT32
, "general", "org.gnu.gdb.arm.core" },
1440 { ARMV8_R4
, 0, "r4", 32, ARM_MODE_ANY
, REG_TYPE_UINT32
, "general", "org.gnu.gdb.arm.core" },
1441 { ARMV8_R5
, 0, "r5", 32, ARM_MODE_ANY
, REG_TYPE_UINT32
, "general", "org.gnu.gdb.arm.core" },
1442 { ARMV8_R6
, 0, "r6", 32, ARM_MODE_ANY
, REG_TYPE_UINT32
, "general", "org.gnu.gdb.arm.core" },
1443 { ARMV8_R7
, 0, "r7", 32, ARM_MODE_ANY
, REG_TYPE_UINT32
, "general", "org.gnu.gdb.arm.core" },
1444 { ARMV8_R8
, 0, "r8", 32, ARM_MODE_ANY
, REG_TYPE_UINT32
, "general", "org.gnu.gdb.arm.core" },
1445 { ARMV8_R9
, 0, "r9", 32, ARM_MODE_ANY
, REG_TYPE_UINT32
, "general", "org.gnu.gdb.arm.core" },
1446 { ARMV8_R10
, 0, "r10", 32, ARM_MODE_ANY
, REG_TYPE_UINT32
, "general", "org.gnu.gdb.arm.core" },
1447 { ARMV8_R11
, 0, "r11", 32, ARM_MODE_ANY
, REG_TYPE_UINT32
, "general", "org.gnu.gdb.arm.core" },
1448 { ARMV8_R12
, 0, "r12", 32, ARM_MODE_ANY
, REG_TYPE_UINT32
, "general", "org.gnu.gdb.arm.core" },
1449 { ARMV8_R13
, 0, "sp", 32, ARM_MODE_ANY
, REG_TYPE_DATA_PTR
, "general", "org.gnu.gdb.arm.core" },
1450 { ARMV8_R14
, 0, "lr", 32, ARM_MODE_ANY
, REG_TYPE_CODE_PTR
, "general", "org.gnu.gdb.arm.core" },
1451 { ARMV8_PC
, 0, "pc", 32, ARM_MODE_ANY
, REG_TYPE_CODE_PTR
, "general", "org.gnu.gdb.arm.core" },
1452 { ARMV8_XPSR
, 0, "cpsr", 32, ARM_MODE_ANY
, REG_TYPE_UINT32
, "general", "org.gnu.gdb.arm.core" },
1453 { ARMV8_V0
, 0, "d0", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1454 { ARMV8_V0
, 8, "d1", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1455 { ARMV8_V1
, 0, "d2", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1456 { ARMV8_V1
, 8, "d3", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1457 { ARMV8_V2
, 0, "d4", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1458 { ARMV8_V2
, 8, "d5", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1459 { ARMV8_V3
, 0, "d6", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1460 { ARMV8_V3
, 8, "d7", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1461 { ARMV8_V4
, 0, "d8", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1462 { ARMV8_V4
, 8, "d9", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1463 { ARMV8_V5
, 0, "d10", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1464 { ARMV8_V5
, 8, "d11", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1465 { ARMV8_V6
, 0, "d12", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1466 { ARMV8_V6
, 8, "d13", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1467 { ARMV8_V7
, 0, "d14", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1468 { ARMV8_V7
, 8, "d15", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1469 { ARMV8_V8
, 0, "d16", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1470 { ARMV8_V8
, 8, "d17", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1471 { ARMV8_V9
, 0, "d18", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1472 { ARMV8_V9
, 8, "d19", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1473 { ARMV8_V10
, 0, "d20", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1474 { ARMV8_V10
, 8, "d21", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1475 { ARMV8_V11
, 0, "d22", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1476 { ARMV8_V11
, 8, "d23", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1477 { ARMV8_V12
, 0, "d24", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1478 { ARMV8_V12
, 8, "d25", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1479 { ARMV8_V13
, 0, "d26", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1480 { ARMV8_V13
, 8, "d27", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1481 { ARMV8_V14
, 0, "d28", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1482 { ARMV8_V14
, 8, "d29", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1483 { ARMV8_V15
, 0, "d30", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1484 { ARMV8_V15
, 8, "d31", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1485 { ARMV8_FPSR
, 0, "fpscr", 32, ARM_MODE_ANY
, REG_TYPE_UINT32
, "float", "org.gnu.gdb.arm.vfp"},
1488 #define ARMV8_NUM_REGS ARRAY_SIZE(armv8_regs)
1489 #define ARMV8_NUM_REGS32 ARRAY_SIZE(armv8_regs32)
1491 static int armv8_get_core_reg(struct reg
*reg
)
1493 struct arm_reg
*armv8_reg
= reg
->arch_info
;
1494 struct target
*target
= armv8_reg
->target
;
1495 struct arm
*arm
= target_to_arm(target
);
1497 if (target
->state
!= TARGET_HALTED
)
1498 return ERROR_TARGET_NOT_HALTED
;
1500 return arm
->read_core_reg(target
, reg
, armv8_reg
->num
, arm
->core_mode
);
1503 static int armv8_set_core_reg(struct reg
*reg
, uint8_t *buf
)
1505 struct arm_reg
*armv8_reg
= reg
->arch_info
;
1506 struct target
*target
= armv8_reg
->target
;
1507 struct arm
*arm
= target_to_arm(target
);
1508 uint64_t value
= buf_get_u64(buf
, 0, reg
->size
);
1510 if (target
->state
!= TARGET_HALTED
)
1511 return ERROR_TARGET_NOT_HALTED
;
1513 if (reg
->size
<= 64) {
1514 if (reg
== arm
->cpsr
)
1515 armv8_set_cpsr(arm
, (uint32_t)value
);
1517 buf_set_u64(reg
->value
, 0, reg
->size
, value
);
1520 } else if (reg
->size
<= 128) {
1521 uint64_t hvalue
= buf_get_u64(buf
+ 8, 0, reg
->size
- 64);
1523 buf_set_u64(reg
->value
, 0, 64, value
);
1524 buf_set_u64(reg
->value
+ 8, 0, reg
->size
- 64, hvalue
);
1533 static const struct reg_arch_type armv8_reg_type
= {
1534 .get
= armv8_get_core_reg
,
1535 .set
= armv8_set_core_reg
,
1538 static int armv8_get_core_reg32(struct reg
*reg
)
1540 struct arm_reg
*armv8_reg
= reg
->arch_info
;
1541 struct target
*target
= armv8_reg
->target
;
1542 struct arm
*arm
= target_to_arm(target
);
1543 struct reg_cache
*cache
= arm
->core_cache
;
1547 if (target
->state
!= TARGET_HALTED
)
1548 return ERROR_TARGET_NOT_HALTED
;
1550 /* get the corresponding Aarch64 register */
1551 reg64
= cache
->reg_list
+ armv8_reg
->num
;
1557 retval
= arm
->read_core_reg(target
, reg64
, armv8_reg
->num
, arm
->core_mode
);
1558 if (retval
== ERROR_OK
)
1559 reg
->valid
= reg64
->valid
;
1564 static int armv8_set_core_reg32(struct reg
*reg
, uint8_t *buf
)
1566 struct arm_reg
*armv8_reg
= reg
->arch_info
;
1567 struct target
*target
= armv8_reg
->target
;
1568 struct arm
*arm
= target_to_arm(target
);
1569 struct reg_cache
*cache
= arm
->core_cache
;
1570 struct reg
*reg64
= cache
->reg_list
+ armv8_reg
->num
;
1571 uint32_t value
= buf_get_u32(buf
, 0, 32);
1573 if (target
->state
!= TARGET_HALTED
)
1574 return ERROR_TARGET_NOT_HALTED
;
1576 if (reg64
== arm
->cpsr
) {
1577 armv8_set_cpsr(arm
, value
);
1579 if (reg
->size
<= 32)
1580 buf_set_u32(reg
->value
, 0, 32, value
);
1581 else if (reg
->size
<= 64) {
1582 uint64_t value64
= buf_get_u64(buf
, 0, 64);
1583 buf_set_u64(reg
->value
, 0, 64, value64
);
1586 reg64
->valid
= true;
1589 reg64
->dirty
= true;
1594 static const struct reg_arch_type armv8_reg32_type
= {
1595 .get
= armv8_get_core_reg32
,
1596 .set
= armv8_set_core_reg32
,
1599 /** Builds cache of architecturally defined registers. */
1600 struct reg_cache
*armv8_build_reg_cache(struct target
*target
)
1602 struct armv8_common
*armv8
= target_to_armv8(target
);
1603 struct arm
*arm
= &armv8
->arm
;
1604 int num_regs
= ARMV8_NUM_REGS
;
1605 int num_regs32
= ARMV8_NUM_REGS32
;
1606 struct reg_cache
**cache_p
= register_get_last_cache_p(&target
->reg_cache
);
1607 struct reg_cache
*cache
= malloc(sizeof(struct reg_cache
));
1608 struct reg_cache
*cache32
= malloc(sizeof(struct reg_cache
));
1609 struct reg
*reg_list
= calloc(num_regs
, sizeof(struct reg
));
1610 struct reg
*reg_list32
= calloc(num_regs32
, sizeof(struct reg
));
1611 struct arm_reg
*arch_info
= calloc(num_regs
, sizeof(struct arm_reg
));
1612 struct reg_feature
*feature
;
1615 /* Build the process context cache */
1616 cache
->name
= "Aarch64 registers";
1617 cache
->next
= cache32
;
1618 cache
->reg_list
= reg_list
;
1619 cache
->num_regs
= num_regs
;
1621 for (i
= 0; i
< num_regs
; i
++) {
1622 arch_info
[i
].num
= armv8_regs
[i
].id
;
1623 arch_info
[i
].mode
= armv8_regs
[i
].mode
;
1624 arch_info
[i
].target
= target
;
1625 arch_info
[i
].arm
= arm
;
1627 reg_list
[i
].name
= armv8_regs
[i
].name
;
1628 reg_list
[i
].size
= armv8_regs
[i
].bits
;
1629 reg_list
[i
].value
= &arch_info
[i
].value
[0];
1630 reg_list
[i
].type
= &armv8_reg_type
;
1631 reg_list
[i
].arch_info
= &arch_info
[i
];
1633 reg_list
[i
].group
= armv8_regs
[i
].group
;
1634 reg_list
[i
].number
= i
;
1635 reg_list
[i
].exist
= true;
1636 reg_list
[i
].caller_save
= true; /* gdb defaults to true */
1638 feature
= calloc(1, sizeof(struct reg_feature
));
1640 feature
->name
= armv8_regs
[i
].feature
;
1641 reg_list
[i
].feature
= feature
;
1643 LOG_ERROR("unable to allocate feature list");
1645 reg_list
[i
].reg_data_type
= calloc(1, sizeof(struct reg_data_type
));
1646 if (reg_list
[i
].reg_data_type
) {
1647 if (!armv8_regs
[i
].data_type
)
1648 reg_list
[i
].reg_data_type
->type
= armv8_regs
[i
].type
;
1650 *reg_list
[i
].reg_data_type
= *armv8_regs
[i
].data_type
;
1652 LOG_ERROR("unable to allocate reg type list");
1655 arm
->cpsr
= reg_list
+ ARMV8_XPSR
;
1656 arm
->pc
= reg_list
+ ARMV8_PC
;
1657 arm
->core_cache
= cache
;
1659 /* shadow cache for ARM mode registers */
1660 cache32
->name
= "Aarch32 registers";
1661 cache32
->next
= NULL
;
1662 cache32
->reg_list
= reg_list32
;
1663 cache32
->num_regs
= num_regs32
;
1665 for (i
= 0; i
< num_regs32
; i
++) {
1666 reg_list32
[i
].name
= armv8_regs32
[i
].name
;
1667 reg_list32
[i
].size
= armv8_regs32
[i
].bits
;
1668 reg_list32
[i
].value
= &arch_info
[armv8_regs32
[i
].id
].value
[armv8_regs32
[i
].mapping
];
1669 reg_list32
[i
].type
= &armv8_reg32_type
;
1670 reg_list32
[i
].arch_info
= &arch_info
[armv8_regs32
[i
].id
];
1671 reg_list32
[i
].group
= armv8_regs32
[i
].group
;
1672 reg_list32
[i
].number
= i
;
1673 reg_list32
[i
].exist
= true;
1674 reg_list32
[i
].caller_save
= true;
1676 feature
= calloc(1, sizeof(struct reg_feature
));
1678 feature
->name
= armv8_regs32
[i
].feature
;
1679 reg_list32
[i
].feature
= feature
;
1681 LOG_ERROR("unable to allocate feature list");
1683 reg_list32
[i
].reg_data_type
= calloc(1, sizeof(struct reg_data_type
));
1684 if (reg_list32
[i
].reg_data_type
)
1685 reg_list32
[i
].reg_data_type
->type
= armv8_regs32
[i
].type
;
1687 LOG_ERROR("unable to allocate reg type list");
1694 struct reg
*armv8_reg_current(struct arm
*arm
, unsigned regnum
)
1698 if (regnum
> (ARMV8_LAST_REG
- 1))
1701 r
= arm
->core_cache
->reg_list
+ regnum
;
1705 static void armv8_free_cache(struct reg_cache
*cache
, bool regs32
)
1713 for (i
= 0; i
< cache
->num_regs
; i
++) {
1714 reg
= &cache
->reg_list
[i
];
1717 free(reg
->reg_data_type
);
1721 free(cache
->reg_list
[0].arch_info
);
1722 free(cache
->reg_list
);
1726 void armv8_free_reg_cache(struct target
*target
)
1728 struct armv8_common
*armv8
= target_to_armv8(target
);
1729 struct arm
*arm
= &armv8
->arm
;
1730 struct reg_cache
*cache
= NULL
, *cache32
= NULL
;
1732 cache
= arm
->core_cache
;
1734 cache32
= cache
->next
;
1735 armv8_free_cache(cache32
, true);
1736 armv8_free_cache(cache
, false);
1737 arm
->core_cache
= NULL
;
1740 const struct command_registration armv8_command_handlers
[] = {
1742 .name
= "catch_exc",
1743 .handler
= armv8_handle_exception_catch_command
,
1744 .mode
= COMMAND_EXEC
,
1745 .help
= "configure exception catch",
1746 .usage
= "[(nsec_el1,nsec_el2,sec_el1,sec_el3)+,off]",
1748 COMMAND_REGISTRATION_DONE
1751 const char *armv8_get_gdb_arch(struct target
*target
)
1753 struct arm
*arm
= target_to_arm(target
);
1754 return arm
->core_state
== ARM_STATE_AARCH64
? "aarch64" : "arm";
1757 int armv8_get_gdb_reg_list(struct target
*target
,
1758 struct reg
**reg_list
[], int *reg_list_size
,
1759 enum target_register_class reg_class
)
1761 struct arm
*arm
= target_to_arm(target
);
1764 if (arm
->core_state
== ARM_STATE_AARCH64
) {
1766 LOG_DEBUG("Creating Aarch64 register list for target %s", target_name(target
));
1768 switch (reg_class
) {
1769 case REG_CLASS_GENERAL
:
1770 *reg_list_size
= ARMV8_V0
;
1771 *reg_list
= malloc(sizeof(struct reg
*) * (*reg_list_size
));
1773 for (i
= 0; i
< *reg_list_size
; i
++)
1774 (*reg_list
)[i
] = armv8_reg_current(arm
, i
);
1778 *reg_list_size
= ARMV8_LAST_REG
;
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
);
1787 LOG_ERROR("not a valid register class type in query.");
1791 struct reg_cache
*cache32
= arm
->core_cache
->next
;
1793 LOG_DEBUG("Creating Aarch32 register list for target %s", target_name(target
));
1795 switch (reg_class
) {
1796 case REG_CLASS_GENERAL
:
1797 *reg_list_size
= ARMV8_R14
+ 3;
1798 *reg_list
= malloc(sizeof(struct reg
*) * (*reg_list_size
));
1800 for (i
= 0; i
< *reg_list_size
; i
++)
1801 (*reg_list
)[i
] = cache32
->reg_list
+ i
;
1805 *reg_list_size
= cache32
->num_regs
;
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 LOG_ERROR("not a valid register class type in query.");
1819 int armv8_set_dbgreg_bits(struct armv8_common
*armv8
, unsigned int reg
, unsigned long mask
, unsigned long value
)
1824 int retval
= mem_ap_read_atomic_u32(armv8
->debug_ap
,
1825 armv8
->debug_base
+ reg
, &tmp
);
1826 if (retval
!= ERROR_OK
)
1829 /* clear bitfield */
1832 tmp
|= value
& mask
;
1834 /* write new value */
1835 retval
= mem_ap_write_atomic_u32(armv8
->debug_ap
,
1836 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)