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_EL3T
,
106 .psr
= ARMV8_64_EL3H
,
110 /** Map PSR mode bits to the name of an ARM processor operating mode. */
111 const char *armv8_mode_name(unsigned psr_mode
)
113 for (unsigned i
= 0; i
< ARRAY_SIZE(armv8_mode_data
); i
++) {
114 if (armv8_mode_data
[i
].psr
== psr_mode
)
115 return armv8_mode_data
[i
].name
;
117 LOG_ERROR("unrecognized psr mode: %#02x", psr_mode
);
118 return "UNRECOGNIZED";
121 static int armv8_read_reg(struct armv8_common
*armv8
, int regnum
, uint64_t *regval
)
123 struct arm_dpm
*dpm
= &armv8
->dpm
;
130 retval
= dpm
->instr_read_data_dcc_64(dpm
,
131 ARMV8_MSR_GP(SYSTEM_DBG_DBGDTR_EL0
, regnum
), &value_64
);
134 retval
= dpm
->instr_read_data_r0_64(dpm
,
135 ARMV8_MOVFSP_64(0), &value_64
);
138 retval
= dpm
->instr_read_data_r0_64(dpm
,
139 ARMV8_MRS_DLR(0), &value_64
);
142 retval
= dpm
->instr_read_data_r0(dpm
,
143 ARMV8_MRS_DSPSR(0), &value
);
147 retval
= dpm
->instr_read_data_r0(dpm
,
148 ARMV8_MRS_FPSR(0), &value
);
152 retval
= dpm
->instr_read_data_r0(dpm
,
153 ARMV8_MRS_FPCR(0), &value
);
157 retval
= dpm
->instr_read_data_r0_64(dpm
,
158 ARMV8_MRS(SYSTEM_ELR_EL1
, 0), &value_64
);
161 retval
= dpm
->instr_read_data_r0_64(dpm
,
162 ARMV8_MRS(SYSTEM_ELR_EL2
, 0), &value_64
);
165 retval
= dpm
->instr_read_data_r0_64(dpm
,
166 ARMV8_MRS(SYSTEM_ELR_EL3
, 0), &value_64
);
169 retval
= dpm
->instr_read_data_r0(dpm
,
170 ARMV8_MRS(SYSTEM_ESR_EL1
, 0), &value
);
174 retval
= dpm
->instr_read_data_r0(dpm
,
175 ARMV8_MRS(SYSTEM_ESR_EL2
, 0), &value
);
179 retval
= dpm
->instr_read_data_r0(dpm
,
180 ARMV8_MRS(SYSTEM_ESR_EL3
, 0), &value
);
184 retval
= dpm
->instr_read_data_r0(dpm
,
185 ARMV8_MRS(SYSTEM_SPSR_EL1
, 0), &value
);
189 retval
= dpm
->instr_read_data_r0(dpm
,
190 ARMV8_MRS(SYSTEM_SPSR_EL2
, 0), &value
);
194 retval
= dpm
->instr_read_data_r0(dpm
,
195 ARMV8_MRS(SYSTEM_SPSR_EL3
, 0), &value
);
203 if (retval
== ERROR_OK
&& regval
!= NULL
)
211 static int armv8_read_reg_simdfp_aarch64(struct armv8_common
*armv8
, int regnum
, uint64_t *lvalue
, uint64_t *hvalue
)
213 int retval
= ERROR_FAIL
;
214 struct arm_dpm
*dpm
= &armv8
->dpm
;
217 case ARMV8_V0
... ARMV8_V31
:
218 retval
= dpm
->instr_read_data_r0_64(dpm
,
219 ARMV8_MOV_GPR_VFP(0, (regnum
- ARMV8_V0
), 1), hvalue
);
220 if (retval
!= ERROR_OK
)
222 retval
= dpm
->instr_read_data_r0_64(dpm
,
223 ARMV8_MOV_GPR_VFP(0, (regnum
- ARMV8_V0
), 0), lvalue
);
234 static int armv8_write_reg(struct armv8_common
*armv8
, int regnum
, uint64_t value_64
)
236 struct arm_dpm
*dpm
= &armv8
->dpm
;
242 retval
= dpm
->instr_write_data_dcc_64(dpm
,
243 ARMV8_MRS(SYSTEM_DBG_DBGDTR_EL0
, regnum
),
247 retval
= dpm
->instr_write_data_r0_64(dpm
,
252 retval
= dpm
->instr_write_data_r0_64(dpm
,
258 retval
= dpm
->instr_write_data_r0(dpm
,
264 retval
= dpm
->instr_write_data_r0(dpm
,
270 retval
= dpm
->instr_write_data_r0(dpm
,
274 /* registers clobbered by taking exception in debug state */
276 retval
= dpm
->instr_write_data_r0_64(dpm
,
277 ARMV8_MSR_GP(SYSTEM_ELR_EL1
, 0), value_64
);
280 retval
= dpm
->instr_write_data_r0_64(dpm
,
281 ARMV8_MSR_GP(SYSTEM_ELR_EL2
, 0), value_64
);
284 retval
= dpm
->instr_write_data_r0_64(dpm
,
285 ARMV8_MSR_GP(SYSTEM_ELR_EL3
, 0), value_64
);
289 retval
= dpm
->instr_write_data_r0(dpm
,
290 ARMV8_MSR_GP(SYSTEM_ESR_EL1
, 0), value
);
294 retval
= dpm
->instr_write_data_r0(dpm
,
295 ARMV8_MSR_GP(SYSTEM_ESR_EL2
, 0), value
);
299 retval
= dpm
->instr_write_data_r0(dpm
,
300 ARMV8_MSR_GP(SYSTEM_ESR_EL3
, 0), value
);
304 retval
= dpm
->instr_write_data_r0(dpm
,
305 ARMV8_MSR_GP(SYSTEM_SPSR_EL1
, 0), value
);
309 retval
= dpm
->instr_write_data_r0(dpm
,
310 ARMV8_MSR_GP(SYSTEM_SPSR_EL2
, 0), value
);
314 retval
= dpm
->instr_write_data_r0(dpm
,
315 ARMV8_MSR_GP(SYSTEM_SPSR_EL3
, 0), value
);
325 static int armv8_write_reg_simdfp_aarch64(struct armv8_common
*armv8
, int regnum
, uint64_t lvalue
, uint64_t hvalue
)
327 int retval
= ERROR_FAIL
;
328 struct arm_dpm
*dpm
= &armv8
->dpm
;
331 case ARMV8_V0
... ARMV8_V31
:
332 retval
= dpm
->instr_write_data_r0_64(dpm
,
333 ARMV8_MOV_VFP_GPR((regnum
- ARMV8_V0
), 0, 1), hvalue
);
334 if (retval
!= ERROR_OK
)
336 retval
= dpm
->instr_write_data_r0_64(dpm
,
337 ARMV8_MOV_VFP_GPR((regnum
- ARMV8_V0
), 0, 0), lvalue
);
348 static int armv8_read_reg32(struct armv8_common
*armv8
, int regnum
, uint64_t *regval
)
350 struct arm_dpm
*dpm
= &armv8
->dpm
;
355 case ARMV8_R0
... ARMV8_R14
:
356 /* return via DCC: "MCR p14, 0, Rnum, c0, c5, 0" */
357 retval
= dpm
->instr_read_data_dcc(dpm
,
358 ARMV4_5_MCR(14, 0, regnum
, 0, 5, 0),
362 retval
= dpm
->instr_read_data_dcc(dpm
,
363 ARMV4_5_MCR(14, 0, 13, 0, 5, 0),
367 retval
= dpm
->instr_read_data_r0(dpm
,
372 retval
= dpm
->instr_read_data_r0(dpm
,
376 case ARMV8_ELR_EL1
: /* mapped to LR_svc */
377 retval
= dpm
->instr_read_data_dcc(dpm
,
378 ARMV4_5_MCR(14, 0, 14, 0, 5, 0),
381 case ARMV8_ELR_EL2
: /* mapped to ELR_hyp */
382 retval
= dpm
->instr_read_data_r0(dpm
,
383 ARMV8_MRS_T1(0, 14, 0, 1),
386 case ARMV8_ELR_EL3
: /* mapped to LR_mon */
387 retval
= dpm
->instr_read_data_dcc(dpm
,
388 ARMV4_5_MCR(14, 0, 14, 0, 5, 0),
391 case ARMV8_ESR_EL1
: /* mapped to DFSR */
392 retval
= dpm
->instr_read_data_r0(dpm
,
393 ARMV4_5_MRC(15, 0, 0, 5, 0, 0),
396 case ARMV8_ESR_EL2
: /* mapped to HSR */
397 retval
= dpm
->instr_read_data_r0(dpm
,
398 ARMV4_5_MRC(15, 4, 0, 5, 2, 0),
401 case ARMV8_ESR_EL3
: /* FIXME: no equivalent in aarch32? */
404 case ARMV8_SPSR_EL1
: /* mapped to SPSR_svc */
405 retval
= dpm
->instr_read_data_r0(dpm
,
406 ARMV8_MRS_xPSR_T1(1, 0),
409 case ARMV8_SPSR_EL2
: /* mapped to SPSR_hyp */
410 retval
= dpm
->instr_read_data_r0(dpm
,
411 ARMV8_MRS_xPSR_T1(1, 0),
414 case ARMV8_SPSR_EL3
: /* mapped to SPSR_mon */
415 retval
= dpm
->instr_read_data_r0(dpm
,
416 ARMV8_MRS_xPSR_T1(1, 0),
420 /* "VMRS r0, FPSCR"; then return via DCC */
421 retval
= dpm
->instr_read_data_r0(dpm
,
422 ARMV4_5_VMRS(0), &value
);
429 if (retval
== ERROR_OK
&& regval
!= NULL
)
435 static int armv8_read_reg_simdfp_aarch32(struct armv8_common
*armv8
, int regnum
, uint64_t *lvalue
, uint64_t *hvalue
)
437 int retval
= ERROR_FAIL
;
438 struct arm_dpm
*dpm
= &armv8
->dpm
;
439 struct reg
*reg_r1
= dpm
->arm
->core_cache
->reg_list
+ ARMV8_R1
;
440 uint32_t value_r0
= 0, value_r1
= 0;
441 unsigned num
= (regnum
- ARMV8_V0
) << 1;
444 case ARMV8_V0
... ARMV8_V15
:
445 /* we are going to write R1, mark it dirty */
446 reg_r1
->dirty
= true;
447 /* move from double word register to r0:r1: "vmov r0, r1, vm"
448 * then read r0 via dcc
450 retval
= dpm
->instr_read_data_r0(dpm
,
451 ARMV4_5_VMOV(1, 1, 0, (num
>> 4), (num
& 0xf)),
453 /* read r1 via dcc */
454 retval
= dpm
->instr_read_data_dcc(dpm
,
455 ARMV4_5_MCR(14, 0, 1, 0, 5, 0),
457 if (retval
== ERROR_OK
) {
459 *lvalue
= ((*lvalue
) << 32) | value_r0
;
464 /* repeat above steps for high 64 bits of V register */
465 retval
= dpm
->instr_read_data_r0(dpm
,
466 ARMV4_5_VMOV(1, 1, 0, (num
>> 4), (num
& 0xf)),
468 retval
= dpm
->instr_read_data_dcc(dpm
,
469 ARMV4_5_MCR(14, 0, 1, 0, 5, 0),
471 if (retval
== ERROR_OK
) {
473 *hvalue
= ((*hvalue
) << 32) | value_r0
;
485 static int armv8_write_reg32(struct armv8_common
*armv8
, int regnum
, uint64_t value
)
487 struct arm_dpm
*dpm
= &armv8
->dpm
;
491 case ARMV8_R0
... ARMV8_R14
:
492 /* load register from DCC: "MRC p14, 0, Rnum, c0, c5, 0" */
493 retval
= dpm
->instr_write_data_dcc(dpm
,
494 ARMV4_5_MRC(14, 0, regnum
, 0, 5, 0), value
);
497 retval
= dpm
->instr_write_data_dcc(dpm
,
498 ARMV4_5_MRC(14, 0, 13, 0, 5, 0), value
);
501 * read r0 from DCC; then "MOV pc, r0" */
502 retval
= dpm
->instr_write_data_r0(dpm
,
503 ARMV8_MCR_DLR(0), value
);
505 case ARMV8_xPSR
: /* CPSR */
506 /* read r0 from DCC, then "MCR r0, DSPSR" */
507 retval
= dpm
->instr_write_data_r0(dpm
,
508 ARMV8_MCR_DSPSR(0), value
);
510 case ARMV8_ELR_EL1
: /* mapped to LR_svc */
511 retval
= dpm
->instr_write_data_dcc(dpm
,
512 ARMV4_5_MRC(14, 0, 14, 0, 5, 0),
515 case ARMV8_ELR_EL2
: /* mapped to ELR_hyp */
516 retval
= dpm
->instr_write_data_r0(dpm
,
517 ARMV8_MSR_GP_T1(0, 14, 0, 1),
520 case ARMV8_ELR_EL3
: /* mapped to LR_mon */
521 retval
= dpm
->instr_write_data_dcc(dpm
,
522 ARMV4_5_MRC(14, 0, 14, 0, 5, 0),
525 case ARMV8_ESR_EL1
: /* mapped to DFSR */
526 retval
= dpm
->instr_write_data_r0(dpm
,
527 ARMV4_5_MCR(15, 0, 0, 5, 0, 0),
530 case ARMV8_ESR_EL2
: /* mapped to HSR */
531 retval
= dpm
->instr_write_data_r0(dpm
,
532 ARMV4_5_MCR(15, 4, 0, 5, 2, 0),
535 case ARMV8_ESR_EL3
: /* FIXME: no equivalent in aarch32? */
538 case ARMV8_SPSR_EL1
: /* mapped to SPSR_svc */
539 retval
= dpm
->instr_write_data_r0(dpm
,
540 ARMV8_MSR_GP_xPSR_T1(1, 0, 15),
543 case ARMV8_SPSR_EL2
: /* mapped to SPSR_hyp */
544 retval
= dpm
->instr_write_data_r0(dpm
,
545 ARMV8_MSR_GP_xPSR_T1(1, 0, 15),
548 case ARMV8_SPSR_EL3
: /* mapped to SPSR_mon */
549 retval
= dpm
->instr_write_data_r0(dpm
,
550 ARMV8_MSR_GP_xPSR_T1(1, 0, 15),
554 /* move to r0 from DCC, then "VMSR FPSCR, r0" */
555 retval
= dpm
->instr_write_data_r0(dpm
,
556 ARMV4_5_VMSR(0), value
);
567 static int armv8_write_reg_simdfp_aarch32(struct armv8_common
*armv8
, int regnum
, uint64_t lvalue
, uint64_t hvalue
)
569 int retval
= ERROR_FAIL
;
570 struct arm_dpm
*dpm
= &armv8
->dpm
;
571 struct reg
*reg_r1
= dpm
->arm
->core_cache
->reg_list
+ ARMV8_R1
;
572 uint32_t value_r0
= 0, value_r1
= 0;
573 unsigned num
= (regnum
- ARMV8_V0
) << 1;
576 case ARMV8_V0
... ARMV8_V15
:
577 /* we are going to write R1, mark it dirty */
578 reg_r1
->dirty
= true;
579 value_r1
= lvalue
>> 32;
580 value_r0
= lvalue
& 0xFFFFFFFF;
581 /* write value_r1 to r1 via dcc */
582 retval
= dpm
->instr_write_data_dcc(dpm
,
583 ARMV4_5_MRC(14, 0, 1, 0, 5, 0),
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)),
593 /* repeat above steps for high 64 bits of V register */
594 value_r1
= hvalue
>> 32;
595 value_r0
= hvalue
& 0xFFFFFFFF;
596 retval
= dpm
->instr_write_data_dcc(dpm
,
597 ARMV4_5_MRC(14, 0, 1, 0, 5, 0),
599 retval
= dpm
->instr_write_data_r0(dpm
,
600 ARMV4_5_VMOV(0, 1, 0, (num
>> 4), (num
& 0xf)),
611 void armv8_select_reg_access(struct armv8_common
*armv8
, bool is_aarch64
)
614 armv8
->read_reg_u64
= armv8_read_reg
;
615 armv8
->write_reg_u64
= armv8_write_reg
;
616 armv8
->read_reg_u128
= armv8_read_reg_simdfp_aarch64
;
617 armv8
->write_reg_u128
= armv8_write_reg_simdfp_aarch64
;
620 armv8
->read_reg_u64
= armv8_read_reg32
;
621 armv8
->write_reg_u64
= armv8_write_reg32
;
622 armv8
->read_reg_u128
= armv8_read_reg_simdfp_aarch32
;
623 armv8
->write_reg_u128
= armv8_write_reg_simdfp_aarch32
;
627 /* retrieve core id cluster id */
628 int armv8_read_mpidr(struct armv8_common
*armv8
)
630 int retval
= ERROR_FAIL
;
631 struct arm
*arm
= &armv8
->arm
;
632 struct arm_dpm
*dpm
= armv8
->arm
.dpm
;
635 retval
= dpm
->prepare(dpm
);
636 if (retval
!= ERROR_OK
)
639 /* check if we're in an unprivileged mode */
640 if (armv8_curel_from_core_mode(arm
->core_mode
) < SYSTEM_CUREL_EL1
) {
641 retval
= armv8_dpm_modeswitch(dpm
, ARMV8_64_EL1H
);
642 if (retval
!= ERROR_OK
)
646 retval
= dpm
->instr_read_data_r0(dpm
, armv8_opcode(armv8
, READ_REG_MPIDR
), &mpidr
);
647 if (retval
!= ERROR_OK
)
650 armv8
->multi_processor_system
= (mpidr
>> 30) & 1;
651 armv8
->cluster_id
= (mpidr
>> 8) & 0xf;
652 armv8
->cpu_id
= mpidr
& 0x3;
653 LOG_INFO("%s cluster %x core %x %s", target_name(armv8
->arm
.target
),
656 armv8
->multi_processor_system
== 0 ? "multi core" : "single core");
658 LOG_ERROR("mpidr not in multiprocessor format");
661 armv8_dpm_modeswitch(dpm
, ARM_MODE_ANY
);
667 * Configures host-side ARM records to reflect the specified CPSR.
668 * Later, code can use arm_reg_current() to map register numbers
669 * according to how they are exposed by this mode.
671 void armv8_set_cpsr(struct arm
*arm
, uint32_t cpsr
)
673 uint32_t mode
= cpsr
& 0x1F;
675 /* NOTE: this may be called very early, before the register
676 * cache is set up. We can't defend against many errors, in
677 * particular against CPSRs that aren't valid *here* ...
680 buf_set_u32(arm
->cpsr
->value
, 0, 32, cpsr
);
681 arm
->cpsr
->valid
= 1;
682 arm
->cpsr
->dirty
= 0;
685 /* Older ARMs won't have the J bit */
686 enum arm_state state
= 0xFF;
688 if ((cpsr
& 0x10) != 0) {
690 if (cpsr
& (1 << 5)) { /* T */
691 if (cpsr
& (1 << 24)) { /* J */
692 LOG_WARNING("ThumbEE -- incomplete support");
693 state
= ARM_STATE_THUMB_EE
;
695 state
= ARM_STATE_THUMB
;
697 if (cpsr
& (1 << 24)) { /* J */
698 LOG_ERROR("Jazelle state handling is BROKEN!");
699 state
= ARM_STATE_JAZELLE
;
701 state
= ARM_STATE_ARM
;
705 state
= ARM_STATE_AARCH64
;
708 arm
->core_state
= state
;
709 arm
->core_mode
= mode
;
711 LOG_DEBUG("set CPSR %#8.8x: %s mode, %s state", (unsigned) cpsr
,
712 armv8_mode_name(arm
->core_mode
),
713 armv8_state_strings
[arm
->core_state
]);
716 static void armv8_show_fault_registers32(struct armv8_common
*armv8
)
718 uint32_t dfsr
, ifsr
, dfar
, ifar
;
719 struct arm_dpm
*dpm
= armv8
->arm
.dpm
;
722 retval
= dpm
->prepare(dpm
);
723 if (retval
!= ERROR_OK
)
726 /* ARMV4_5_MRC(cpnum, op1, r0, CRn, CRm, op2) */
728 /* c5/c0 - {data, instruction} fault status registers */
729 retval
= dpm
->instr_read_data_r0(dpm
,
730 ARMV4_5_MRC(15, 0, 0, 5, 0, 0),
732 if (retval
!= ERROR_OK
)
735 retval
= dpm
->instr_read_data_r0(dpm
,
736 ARMV4_5_MRC(15, 0, 0, 5, 0, 1),
738 if (retval
!= ERROR_OK
)
741 /* c6/c0 - {data, instruction} fault address registers */
742 retval
= dpm
->instr_read_data_r0(dpm
,
743 ARMV4_5_MRC(15, 0, 0, 6, 0, 0),
745 if (retval
!= ERROR_OK
)
748 retval
= dpm
->instr_read_data_r0(dpm
,
749 ARMV4_5_MRC(15, 0, 0, 6, 0, 2),
751 if (retval
!= ERROR_OK
)
754 LOG_USER("Data fault registers DFSR: %8.8" PRIx32
755 ", DFAR: %8.8" PRIx32
, dfsr
, dfar
);
756 LOG_USER("Instruction fault registers IFSR: %8.8" PRIx32
757 ", IFAR: %8.8" PRIx32
, ifsr
, ifar
);
760 /* (void) */ dpm
->finish(dpm
);
763 static __attribute__((unused
)) void armv8_show_fault_registers(struct target
*target
)
765 struct armv8_common
*armv8
= target_to_armv8(target
);
767 if (armv8
->arm
.core_state
!= ARM_STATE_AARCH64
)
768 armv8_show_fault_registers32(armv8
);
771 static uint8_t armv8_pa_size(uint32_t ps
)
794 LOG_INFO("Unknow physicall address size");
800 static __attribute__((unused
)) int armv8_read_ttbcr32(struct target
*target
)
802 struct armv8_common
*armv8
= target_to_armv8(target
);
803 struct arm_dpm
*dpm
= armv8
->arm
.dpm
;
804 uint32_t ttbcr
, ttbcr_n
;
805 int retval
= dpm
->prepare(dpm
);
806 if (retval
!= ERROR_OK
)
808 /* MRC p15,0,<Rt>,c2,c0,2 ; Read CP15 Translation Table Base Control Register*/
809 retval
= dpm
->instr_read_data_r0(dpm
,
810 ARMV4_5_MRC(15, 0, 0, 2, 0, 2),
812 if (retval
!= ERROR_OK
)
815 LOG_DEBUG("ttbcr %" PRIx32
, ttbcr
);
817 ttbcr_n
= ttbcr
& 0x7;
818 armv8
->armv8_mmu
.ttbcr
= ttbcr
;
821 * ARM Architecture Reference Manual (ARMv7-A and ARMv7-Redition),
822 * document # ARM DDI 0406C
824 armv8
->armv8_mmu
.ttbr_range
[0] = 0xffffffff >> ttbcr_n
;
825 armv8
->armv8_mmu
.ttbr_range
[1] = 0xffffffff;
826 armv8
->armv8_mmu
.ttbr_mask
[0] = 0xffffffff << (14 - ttbcr_n
);
827 armv8
->armv8_mmu
.ttbr_mask
[1] = 0xffffffff << 14;
829 LOG_DEBUG("ttbr1 %s, ttbr0_mask %" PRIx32
" ttbr1_mask %" PRIx32
,
830 (ttbcr_n
!= 0) ? "used" : "not used",
831 armv8
->armv8_mmu
.ttbr_mask
[0],
832 armv8
->armv8_mmu
.ttbr_mask
[1]);
839 static __attribute__((unused
)) int armv8_read_ttbcr(struct target
*target
)
841 struct armv8_common
*armv8
= target_to_armv8(target
);
842 struct arm_dpm
*dpm
= armv8
->arm
.dpm
;
843 struct arm
*arm
= &armv8
->arm
;
847 int retval
= dpm
->prepare(dpm
);
848 if (retval
!= ERROR_OK
)
851 /* claaer ttrr1_used and ttbr0_mask */
852 memset(&armv8
->armv8_mmu
.ttbr1_used
, 0, sizeof(armv8
->armv8_mmu
.ttbr1_used
));
853 memset(&armv8
->armv8_mmu
.ttbr0_mask
, 0, sizeof(armv8
->armv8_mmu
.ttbr0_mask
));
855 switch (armv8_curel_from_core_mode(arm
->core_mode
)) {
856 case SYSTEM_CUREL_EL3
:
857 retval
= dpm
->instr_read_data_r0(dpm
,
858 ARMV8_MRS(SYSTEM_TCR_EL3
, 0),
860 retval
+= dpm
->instr_read_data_r0_64(dpm
,
861 ARMV8_MRS(SYSTEM_TTBR0_EL3
, 0),
863 if (retval
!= ERROR_OK
)
865 armv8
->va_size
= 64 - (ttbcr
& 0x3F);
866 armv8
->pa_size
= armv8_pa_size((ttbcr
>> 16) & 7);
867 armv8
->page_size
= (ttbcr
>> 14) & 3;
869 case SYSTEM_CUREL_EL2
:
870 retval
= dpm
->instr_read_data_r0(dpm
,
871 ARMV8_MRS(SYSTEM_TCR_EL2
, 0),
873 retval
+= dpm
->instr_read_data_r0_64(dpm
,
874 ARMV8_MRS(SYSTEM_TTBR0_EL2
, 0),
876 if (retval
!= ERROR_OK
)
878 armv8
->va_size
= 64 - (ttbcr
& 0x3F);
879 armv8
->pa_size
= armv8_pa_size((ttbcr
>> 16) & 7);
880 armv8
->page_size
= (ttbcr
>> 14) & 3;
882 case SYSTEM_CUREL_EL0
:
883 armv8_dpm_modeswitch(dpm
, ARMV8_64_EL1H
);
885 case SYSTEM_CUREL_EL1
:
886 retval
= dpm
->instr_read_data_r0_64(dpm
,
887 ARMV8_MRS(SYSTEM_TCR_EL1
, 0),
889 armv8
->va_size
= 64 - (ttbcr_64
& 0x3F);
890 armv8
->pa_size
= armv8_pa_size((ttbcr_64
>> 32) & 7);
891 armv8
->page_size
= (ttbcr_64
>> 14) & 3;
892 armv8
->armv8_mmu
.ttbr1_used
= (((ttbcr_64
>> 16) & 0x3F) != 0) ? 1 : 0;
893 armv8
->armv8_mmu
.ttbr0_mask
= 0x0000FFFFFFFFFFFF;
894 retval
+= dpm
->instr_read_data_r0_64(dpm
,
895 ARMV8_MRS(SYSTEM_TTBR0_EL1
| (armv8
->armv8_mmu
.ttbr1_used
), 0),
897 if (retval
!= ERROR_OK
)
901 LOG_ERROR("unknow core state");
905 if (retval
!= ERROR_OK
)
908 if (armv8
->armv8_mmu
.ttbr1_used
== 1)
909 LOG_INFO("TTBR0 access above %" PRIx64
, (uint64_t)(armv8
->armv8_mmu
.ttbr0_mask
));
912 armv8_dpm_modeswitch(dpm
, ARM_MODE_ANY
);
917 /* method adapted to cortex A : reused arm v4 v5 method*/
918 int armv8_mmu_translate_va(struct target
*target
, target_addr_t va
, target_addr_t
*val
)
923 /* V8 method VA TO PA */
924 int armv8_mmu_translate_va_pa(struct target
*target
, target_addr_t va
,
925 target_addr_t
*val
, int meminfo
)
927 struct armv8_common
*armv8
= target_to_armv8(target
);
928 struct arm
*arm
= target_to_arm(target
);
929 struct arm_dpm
*dpm
= &armv8
->dpm
;
930 enum arm_mode target_mode
= ARM_MODE_ANY
;
935 static const char * const shared_name
[] = {
936 "Non-", "UNDEFINED ", "Outer ", "Inner "
939 static const char * const secure_name
[] = {
940 "Secure", "Not Secure"
943 if (target
->state
!= TARGET_HALTED
) {
944 LOG_WARNING("target %s not halted", target_name(target
));
945 return ERROR_TARGET_NOT_HALTED
;
948 retval
= dpm
->prepare(dpm
);
949 if (retval
!= ERROR_OK
)
952 switch (armv8_curel_from_core_mode(arm
->core_mode
)) {
953 case SYSTEM_CUREL_EL0
:
954 instr
= ARMV8_SYS(SYSTEM_ATS12E0R
, 0);
955 /* can only execute instruction at EL2 */
956 target_mode
= ARMV8_64_EL2H
;
958 case SYSTEM_CUREL_EL1
:
959 instr
= ARMV8_SYS(SYSTEM_ATS12E1R
, 0);
960 /* can only execute instruction at EL2 */
961 target_mode
= ARMV8_64_EL2H
;
963 case SYSTEM_CUREL_EL2
:
964 instr
= ARMV8_SYS(SYSTEM_ATS1E2R
, 0);
966 case SYSTEM_CUREL_EL3
:
967 instr
= ARMV8_SYS(SYSTEM_ATS1E3R
, 0);
974 if (target_mode
!= ARM_MODE_ANY
)
975 armv8_dpm_modeswitch(dpm
, target_mode
);
977 /* write VA to R0 and execute translation instruction */
978 retval
= dpm
->instr_write_data_r0_64(dpm
, instr
, (uint64_t)va
);
979 /* read result from PAR_EL1 */
980 if (retval
== ERROR_OK
)
981 retval
= dpm
->instr_read_data_r0_64(dpm
, ARMV8_MRS(SYSTEM_PAR_EL1
, 0), &par
);
983 /* switch back to saved PE mode */
984 if (target_mode
!= ARM_MODE_ANY
)
985 armv8_dpm_modeswitch(dpm
, ARM_MODE_ANY
);
989 if (retval
!= ERROR_OK
)
993 LOG_ERROR("Address translation failed at stage %i, FST=%x, PTW=%i",
994 ((int)(par
>> 9) & 1)+1, (int)(par
>> 1) & 0x3f, (int)(par
>> 8) & 1);
999 *val
= (par
& 0xFFFFFFFFF000UL
) | (va
& 0xFFF);
1001 int SH
= (par
>> 7) & 3;
1002 int NS
= (par
>> 9) & 1;
1003 int ATTR
= (par
>> 56) & 0xFF;
1005 char *memtype
= (ATTR
& 0xF0) == 0 ? "Device Memory" : "Normal Memory";
1007 LOG_USER("%sshareable, %s",
1008 shared_name
[SH
], secure_name
[NS
]);
1009 LOG_USER("%s", memtype
);
1016 int armv8_handle_cache_info_command(struct command_context
*cmd_ctx
,
1017 struct armv8_cache_common
*armv8_cache
)
1019 if (armv8_cache
->info
== -1) {
1020 command_print(cmd_ctx
, "cache not yet identified");
1024 if (armv8_cache
->display_cache_info
)
1025 armv8_cache
->display_cache_info(cmd_ctx
, armv8_cache
);
1029 static int armv8_setup_semihosting(struct target
*target
, int enable
)
1031 struct arm
*arm
= target_to_arm(target
);
1033 if (arm
->core_state
!= ARM_STATE_AARCH64
) {
1034 LOG_ERROR("semihosting only supported in AArch64 state\n");
1041 int armv8_init_arch_info(struct target
*target
, struct armv8_common
*armv8
)
1043 struct arm
*arm
= &armv8
->arm
;
1044 arm
->arch_info
= armv8
;
1045 target
->arch_info
= &armv8
->arm
;
1046 arm
->setup_semihosting
= armv8_setup_semihosting
;
1047 /* target is useful in all function arm v4 5 compatible */
1048 armv8
->arm
.target
= target
;
1049 armv8
->arm
.common_magic
= ARM_COMMON_MAGIC
;
1050 armv8
->common_magic
= ARMV8_COMMON_MAGIC
;
1052 armv8
->armv8_mmu
.armv8_cache
.l2_cache
= NULL
;
1053 armv8
->armv8_mmu
.armv8_cache
.info
= -1;
1054 armv8
->armv8_mmu
.armv8_cache
.flush_all_data_cache
= NULL
;
1055 armv8
->armv8_mmu
.armv8_cache
.display_cache_info
= NULL
;
1059 int armv8_aarch64_state(struct target
*target
)
1061 struct arm
*arm
= target_to_arm(target
);
1063 if (arm
->common_magic
!= ARM_COMMON_MAGIC
) {
1064 LOG_ERROR("BUG: called for a non-ARM target");
1068 LOG_USER("target halted in %s state due to %s, current mode: %s\n"
1069 "cpsr: 0x%8.8" PRIx32
" pc: 0x%" PRIx64
"%s",
1070 armv8_state_strings
[arm
->core_state
],
1071 debug_reason_name(target
),
1072 armv8_mode_name(arm
->core_mode
),
1073 buf_get_u32(arm
->cpsr
->value
, 0, 32),
1074 buf_get_u64(arm
->pc
->value
, 0, 64),
1075 (target
->semihosting
&& target
->semihosting
->is_active
) ? ", semihosting" : "");
1080 int armv8_arch_state(struct target
*target
)
1082 static const char * const state
[] = {
1083 "disabled", "enabled"
1086 struct armv8_common
*armv8
= target_to_armv8(target
);
1087 struct arm
*arm
= &armv8
->arm
;
1089 if (armv8
->common_magic
!= ARMV8_COMMON_MAGIC
) {
1090 LOG_ERROR("BUG: called for a non-Armv8 target");
1091 return ERROR_COMMAND_SYNTAX_ERROR
;
1094 if (arm
->core_state
== ARM_STATE_AARCH64
)
1095 armv8_aarch64_state(target
);
1097 arm_arch_state(target
);
1099 LOG_USER("MMU: %s, D-Cache: %s, I-Cache: %s",
1100 state
[armv8
->armv8_mmu
.mmu_enabled
],
1101 state
[armv8
->armv8_mmu
.armv8_cache
.d_u_cache_enabled
],
1102 state
[armv8
->armv8_mmu
.armv8_cache
.i_cache_enabled
]);
1104 if (arm
->core_mode
== ARM_MODE_ABT
)
1105 armv8_show_fault_registers(target
);
1107 if (target
->debug_reason
== DBG_REASON_WATCHPOINT
)
1108 LOG_USER("Watchpoint triggered at PC %#08x",
1109 (unsigned) armv8
->dpm
.wp_pc
);
1114 static struct reg_data_type aarch64_vector_base_types
[] = {
1115 {REG_TYPE_IEEE_DOUBLE
, "ieee_double", 0, {NULL
} },
1116 {REG_TYPE_UINT64
, "uint64", 0, {NULL
} },
1117 {REG_TYPE_INT64
, "int64", 0, {NULL
} },
1118 {REG_TYPE_IEEE_SINGLE
, "ieee_single", 0, {NULL
} },
1119 {REG_TYPE_UINT32
, "uint32", 0, {NULL
} },
1120 {REG_TYPE_INT32
, "int32", 0, {NULL
} },
1121 {REG_TYPE_UINT16
, "uint16", 0, {NULL
} },
1122 {REG_TYPE_INT16
, "int16", 0, {NULL
} },
1123 {REG_TYPE_UINT8
, "uint8", 0, {NULL
} },
1124 {REG_TYPE_INT8
, "int8", 0, {NULL
} },
1125 {REG_TYPE_UINT128
, "uint128", 0, {NULL
} },
1126 {REG_TYPE_INT128
, "int128", 0, {NULL
} }
1129 static struct reg_data_type_vector aarch64_vector_types
[] = {
1130 {aarch64_vector_base_types
+ 0, 2},
1131 {aarch64_vector_base_types
+ 1, 2},
1132 {aarch64_vector_base_types
+ 2, 2},
1133 {aarch64_vector_base_types
+ 3, 4},
1134 {aarch64_vector_base_types
+ 4, 4},
1135 {aarch64_vector_base_types
+ 5, 4},
1136 {aarch64_vector_base_types
+ 6, 8},
1137 {aarch64_vector_base_types
+ 7, 8},
1138 {aarch64_vector_base_types
+ 8, 16},
1139 {aarch64_vector_base_types
+ 9, 16},
1140 {aarch64_vector_base_types
+ 10, 01},
1141 {aarch64_vector_base_types
+ 11, 01},
1144 static struct reg_data_type aarch64_fpu_vector
[] = {
1145 {REG_TYPE_ARCH_DEFINED
, "v2d", REG_TYPE_CLASS_VECTOR
, {aarch64_vector_types
+ 0} },
1146 {REG_TYPE_ARCH_DEFINED
, "v2u", REG_TYPE_CLASS_VECTOR
, {aarch64_vector_types
+ 1} },
1147 {REG_TYPE_ARCH_DEFINED
, "v2i", REG_TYPE_CLASS_VECTOR
, {aarch64_vector_types
+ 2} },
1148 {REG_TYPE_ARCH_DEFINED
, "v4f", REG_TYPE_CLASS_VECTOR
, {aarch64_vector_types
+ 3} },
1149 {REG_TYPE_ARCH_DEFINED
, "v4u", REG_TYPE_CLASS_VECTOR
, {aarch64_vector_types
+ 4} },
1150 {REG_TYPE_ARCH_DEFINED
, "v4i", REG_TYPE_CLASS_VECTOR
, {aarch64_vector_types
+ 5} },
1151 {REG_TYPE_ARCH_DEFINED
, "v8u", REG_TYPE_CLASS_VECTOR
, {aarch64_vector_types
+ 6} },
1152 {REG_TYPE_ARCH_DEFINED
, "v8i", REG_TYPE_CLASS_VECTOR
, {aarch64_vector_types
+ 7} },
1153 {REG_TYPE_ARCH_DEFINED
, "v16u", REG_TYPE_CLASS_VECTOR
, {aarch64_vector_types
+ 8} },
1154 {REG_TYPE_ARCH_DEFINED
, "v16i", REG_TYPE_CLASS_VECTOR
, {aarch64_vector_types
+ 9} },
1155 {REG_TYPE_ARCH_DEFINED
, "v1u", REG_TYPE_CLASS_VECTOR
, {aarch64_vector_types
+ 10} },
1156 {REG_TYPE_ARCH_DEFINED
, "v1i", REG_TYPE_CLASS_VECTOR
, {aarch64_vector_types
+ 11} },
1159 static struct reg_data_type_union_field aarch64_union_fields_vnd
[] = {
1160 {"f", aarch64_fpu_vector
+ 0, aarch64_union_fields_vnd
+ 1},
1161 {"u", aarch64_fpu_vector
+ 1, aarch64_union_fields_vnd
+ 2},
1162 {"s", aarch64_fpu_vector
+ 2, NULL
},
1165 static struct reg_data_type_union_field aarch64_union_fields_vns
[] = {
1166 {"f", aarch64_fpu_vector
+ 3, aarch64_union_fields_vns
+ 1},
1167 {"u", aarch64_fpu_vector
+ 4, aarch64_union_fields_vns
+ 2},
1168 {"s", aarch64_fpu_vector
+ 5, NULL
},
1171 static struct reg_data_type_union_field aarch64_union_fields_vnh
[] = {
1172 {"u", aarch64_fpu_vector
+ 6, aarch64_union_fields_vnh
+ 1},
1173 {"s", aarch64_fpu_vector
+ 7, NULL
},
1176 static struct reg_data_type_union_field aarch64_union_fields_vnb
[] = {
1177 {"u", aarch64_fpu_vector
+ 8, aarch64_union_fields_vnb
+ 1},
1178 {"s", aarch64_fpu_vector
+ 9, NULL
},
1181 static struct reg_data_type_union_field aarch64_union_fields_vnq
[] = {
1182 {"u", aarch64_fpu_vector
+ 10, aarch64_union_fields_vnq
+ 1},
1183 {"s", aarch64_fpu_vector
+ 11, NULL
},
1186 static struct reg_data_type_union aarch64_union_types
[] = {
1187 {aarch64_union_fields_vnd
},
1188 {aarch64_union_fields_vns
},
1189 {aarch64_union_fields_vnh
},
1190 {aarch64_union_fields_vnb
},
1191 {aarch64_union_fields_vnq
},
1194 static struct reg_data_type aarch64_fpu_union
[] = {
1195 {REG_TYPE_ARCH_DEFINED
, "vnd", REG_TYPE_CLASS_UNION
, {.reg_type_union
= aarch64_union_types
+ 0} },
1196 {REG_TYPE_ARCH_DEFINED
, "vns", REG_TYPE_CLASS_UNION
, {.reg_type_union
= aarch64_union_types
+ 1} },
1197 {REG_TYPE_ARCH_DEFINED
, "vnh", REG_TYPE_CLASS_UNION
, {.reg_type_union
= aarch64_union_types
+ 2} },
1198 {REG_TYPE_ARCH_DEFINED
, "vnb", REG_TYPE_CLASS_UNION
, {.reg_type_union
= aarch64_union_types
+ 3} },
1199 {REG_TYPE_ARCH_DEFINED
, "vnq", REG_TYPE_CLASS_UNION
, {.reg_type_union
= aarch64_union_types
+ 4} },
1202 static struct reg_data_type_union_field aarch64v_union_fields
[] = {
1203 {"d", aarch64_fpu_union
+ 0, aarch64v_union_fields
+ 1},
1204 {"s", aarch64_fpu_union
+ 1, aarch64v_union_fields
+ 2},
1205 {"h", aarch64_fpu_union
+ 2, aarch64v_union_fields
+ 3},
1206 {"b", aarch64_fpu_union
+ 3, aarch64v_union_fields
+ 4},
1207 {"q", aarch64_fpu_union
+ 4, NULL
},
1210 static struct reg_data_type_union aarch64v_union
[] = {
1211 {aarch64v_union_fields
}
1214 static struct reg_data_type aarch64v
[] = {
1215 {REG_TYPE_ARCH_DEFINED
, "aarch64v", REG_TYPE_CLASS_UNION
,
1216 {.reg_type_union
= aarch64v_union
} },
1219 static struct reg_data_type_bitfield aarch64_cpsr_bits
[] = {
1220 { 0, 0 , REG_TYPE_UINT8
},
1221 { 2, 3, REG_TYPE_UINT8
},
1222 { 4, 4 , REG_TYPE_UINT8
},
1223 { 6, 6 , REG_TYPE_BOOL
},
1224 { 7, 7 , REG_TYPE_BOOL
},
1225 { 8, 8 , REG_TYPE_BOOL
},
1226 { 9, 9 , REG_TYPE_BOOL
},
1227 { 20, 20, REG_TYPE_BOOL
},
1228 { 21, 21, REG_TYPE_BOOL
},
1229 { 28, 28, REG_TYPE_BOOL
},
1230 { 29, 29, REG_TYPE_BOOL
},
1231 { 30, 30, REG_TYPE_BOOL
},
1232 { 31, 31, REG_TYPE_BOOL
},
1235 static struct reg_data_type_flags_field aarch64_cpsr_fields
[] = {
1236 { "SP", aarch64_cpsr_bits
+ 0, aarch64_cpsr_fields
+ 1 },
1237 { "EL", aarch64_cpsr_bits
+ 1, aarch64_cpsr_fields
+ 2 },
1238 { "nRW", aarch64_cpsr_bits
+ 2, aarch64_cpsr_fields
+ 3 },
1239 { "F" , aarch64_cpsr_bits
+ 3, aarch64_cpsr_fields
+ 4 },
1240 { "I" , aarch64_cpsr_bits
+ 4, aarch64_cpsr_fields
+ 5 },
1241 { "A" , aarch64_cpsr_bits
+ 5, aarch64_cpsr_fields
+ 6 },
1242 { "D" , aarch64_cpsr_bits
+ 6, aarch64_cpsr_fields
+ 7 },
1243 { "IL" , aarch64_cpsr_bits
+ 7, aarch64_cpsr_fields
+ 8 },
1244 { "SS" , aarch64_cpsr_bits
+ 8, aarch64_cpsr_fields
+ 9 },
1245 { "V" , aarch64_cpsr_bits
+ 9, aarch64_cpsr_fields
+ 10 },
1246 { "C" , aarch64_cpsr_bits
+ 10, aarch64_cpsr_fields
+ 11 },
1247 { "Z" , aarch64_cpsr_bits
+ 11, aarch64_cpsr_fields
+ 12 },
1248 { "N" , aarch64_cpsr_bits
+ 12, NULL
}
1251 static struct reg_data_type_flags aarch64_cpsr_flags
[] = {
1252 { 4, aarch64_cpsr_fields
}
1255 static struct reg_data_type aarch64_flags_cpsr
[] = {
1256 {REG_TYPE_ARCH_DEFINED
, "cpsr_flags", REG_TYPE_CLASS_FLAGS
,
1257 {.reg_type_flags
= aarch64_cpsr_flags
} },
1260 static const struct {
1267 const char *feature
;
1268 struct reg_data_type
*data_type
;
1270 { ARMV8_R0
, "x0", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1271 { ARMV8_R1
, "x1", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1272 { ARMV8_R2
, "x2", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1273 { ARMV8_R3
, "x3", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1274 { ARMV8_R4
, "x4", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1275 { ARMV8_R5
, "x5", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1276 { ARMV8_R6
, "x6", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1277 { ARMV8_R7
, "x7", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1278 { ARMV8_R8
, "x8", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1279 { ARMV8_R9
, "x9", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1280 { ARMV8_R10
, "x10", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1281 { ARMV8_R11
, "x11", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1282 { ARMV8_R12
, "x12", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1283 { ARMV8_R13
, "x13", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1284 { ARMV8_R14
, "x14", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1285 { ARMV8_R15
, "x15", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1286 { ARMV8_R16
, "x16", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1287 { ARMV8_R17
, "x17", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1288 { ARMV8_R18
, "x18", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1289 { ARMV8_R19
, "x19", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1290 { ARMV8_R20
, "x20", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1291 { ARMV8_R21
, "x21", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1292 { ARMV8_R22
, "x22", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1293 { ARMV8_R23
, "x23", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1294 { ARMV8_R24
, "x24", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1295 { ARMV8_R25
, "x25", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1296 { ARMV8_R26
, "x26", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1297 { ARMV8_R27
, "x27", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1298 { ARMV8_R28
, "x28", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1299 { ARMV8_R29
, "x29", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1300 { ARMV8_R30
, "x30", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1302 { ARMV8_SP
, "sp", 64, ARM_MODE_ANY
, REG_TYPE_DATA_PTR
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1303 { ARMV8_PC
, "pc", 64, ARM_MODE_ANY
, REG_TYPE_CODE_PTR
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1304 { ARMV8_xPSR
, "cpsr", 32, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
,
1305 "general", "org.gnu.gdb.aarch64.core", aarch64_flags_cpsr
},
1306 { ARMV8_V0
, "v0", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1307 { ARMV8_V1
, "v1", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1308 { ARMV8_V2
, "v2", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1309 { ARMV8_V3
, "v3", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1310 { ARMV8_V4
, "v4", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1311 { ARMV8_V5
, "v5", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1312 { ARMV8_V6
, "v6", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1313 { ARMV8_V7
, "v7", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1314 { ARMV8_V8
, "v8", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1315 { ARMV8_V9
, "v9", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1316 { ARMV8_V10
, "v10", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1317 { ARMV8_V11
, "v11", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1318 { ARMV8_V12
, "v12", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1319 { ARMV8_V13
, "v13", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1320 { ARMV8_V14
, "v14", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1321 { ARMV8_V15
, "v15", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1322 { ARMV8_V16
, "v16", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1323 { ARMV8_V17
, "v17", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1324 { ARMV8_V18
, "v18", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1325 { ARMV8_V19
, "v19", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1326 { ARMV8_V20
, "v20", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1327 { ARMV8_V21
, "v21", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1328 { ARMV8_V22
, "v22", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1329 { ARMV8_V23
, "v23", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1330 { ARMV8_V24
, "v24", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1331 { ARMV8_V25
, "v25", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1332 { ARMV8_V26
, "v26", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1333 { ARMV8_V27
, "v27", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1334 { ARMV8_V28
, "v28", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1335 { ARMV8_V29
, "v29", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1336 { ARMV8_V30
, "v30", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1337 { ARMV8_V31
, "v31", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1338 { ARMV8_FPSR
, "fpsr", 32, ARM_MODE_ANY
, REG_TYPE_UINT32
, "simdfp", "org.gnu.gdb.aarch64.fpu", NULL
},
1339 { ARMV8_FPCR
, "fpcr", 32, ARM_MODE_ANY
, REG_TYPE_UINT32
, "simdfp", "org.gnu.gdb.aarch64.fpu", NULL
},
1341 { ARMV8_ELR_EL1
, "ELR_EL1", 64, ARMV8_64_EL1H
, REG_TYPE_CODE_PTR
, "banked", "net.sourceforge.openocd.banked",
1343 { ARMV8_ESR_EL1
, "ESR_EL1", 32, ARMV8_64_EL1H
, REG_TYPE_UINT32
, "banked", "net.sourceforge.openocd.banked",
1345 { ARMV8_SPSR_EL1
, "SPSR_EL1", 32, ARMV8_64_EL1H
, REG_TYPE_UINT32
, "banked", "net.sourceforge.openocd.banked",
1348 { ARMV8_ELR_EL2
, "ELR_EL2", 64, ARMV8_64_EL2H
, REG_TYPE_CODE_PTR
, "banked", "net.sourceforge.openocd.banked",
1350 { ARMV8_ESR_EL2
, "ESR_EL2", 32, ARMV8_64_EL2H
, REG_TYPE_UINT32
, "banked", "net.sourceforge.openocd.banked",
1352 { ARMV8_SPSR_EL2
, "SPSR_EL2", 32, ARMV8_64_EL2H
, REG_TYPE_UINT32
, "banked", "net.sourceforge.openocd.banked",
1355 { ARMV8_ELR_EL3
, "ELR_EL3", 64, ARMV8_64_EL3H
, REG_TYPE_CODE_PTR
, "banked", "net.sourceforge.openocd.banked",
1357 { ARMV8_ESR_EL3
, "ESR_EL3", 32, ARMV8_64_EL3H
, REG_TYPE_UINT32
, "banked", "net.sourceforge.openocd.banked",
1359 { ARMV8_SPSR_EL3
, "SPSR_EL3", 32, ARMV8_64_EL3H
, REG_TYPE_UINT32
, "banked", "net.sourceforge.openocd.banked",
1363 static const struct {
1371 const char *feature
;
1372 } armv8_regs32
[] = {
1373 { ARMV8_R0
, 0, "r0", 32, ARM_MODE_ANY
, REG_TYPE_UINT32
, "general", "org.gnu.gdb.arm.core" },
1374 { ARMV8_R1
, 0, "r1", 32, ARM_MODE_ANY
, REG_TYPE_UINT32
, "general", "org.gnu.gdb.arm.core" },
1375 { ARMV8_R2
, 0, "r2", 32, ARM_MODE_ANY
, REG_TYPE_UINT32
, "general", "org.gnu.gdb.arm.core" },
1376 { ARMV8_R3
, 0, "r3", 32, ARM_MODE_ANY
, REG_TYPE_UINT32
, "general", "org.gnu.gdb.arm.core" },
1377 { ARMV8_R4
, 0, "r4", 32, ARM_MODE_ANY
, REG_TYPE_UINT32
, "general", "org.gnu.gdb.arm.core" },
1378 { ARMV8_R5
, 0, "r5", 32, ARM_MODE_ANY
, REG_TYPE_UINT32
, "general", "org.gnu.gdb.arm.core" },
1379 { ARMV8_R6
, 0, "r6", 32, ARM_MODE_ANY
, REG_TYPE_UINT32
, "general", "org.gnu.gdb.arm.core" },
1380 { ARMV8_R7
, 0, "r7", 32, ARM_MODE_ANY
, REG_TYPE_UINT32
, "general", "org.gnu.gdb.arm.core" },
1381 { ARMV8_R8
, 0, "r8", 32, ARM_MODE_ANY
, REG_TYPE_UINT32
, "general", "org.gnu.gdb.arm.core" },
1382 { ARMV8_R9
, 0, "r9", 32, ARM_MODE_ANY
, REG_TYPE_UINT32
, "general", "org.gnu.gdb.arm.core" },
1383 { ARMV8_R10
, 0, "r10", 32, ARM_MODE_ANY
, REG_TYPE_UINT32
, "general", "org.gnu.gdb.arm.core" },
1384 { ARMV8_R11
, 0, "r11", 32, ARM_MODE_ANY
, REG_TYPE_UINT32
, "general", "org.gnu.gdb.arm.core" },
1385 { ARMV8_R12
, 0, "r12", 32, ARM_MODE_ANY
, REG_TYPE_UINT32
, "general", "org.gnu.gdb.arm.core" },
1386 { ARMV8_R13
, 0, "sp", 32, ARM_MODE_ANY
, REG_TYPE_DATA_PTR
, "general", "org.gnu.gdb.arm.core" },
1387 { ARMV8_R14
, 0, "lr", 32, ARM_MODE_ANY
, REG_TYPE_CODE_PTR
, "general", "org.gnu.gdb.arm.core" },
1388 { ARMV8_PC
, 0, "pc", 32, ARM_MODE_ANY
, REG_TYPE_CODE_PTR
, "general", "org.gnu.gdb.arm.core" },
1389 { ARMV8_xPSR
, 0, "cpsr", 32, ARM_MODE_ANY
, REG_TYPE_UINT32
, "general", "org.gnu.gdb.arm.core" },
1390 { ARMV8_V0
, 0, "d0", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1391 { ARMV8_V0
, 8, "d1", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1392 { ARMV8_V1
, 0, "d2", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1393 { ARMV8_V1
, 8, "d3", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1394 { ARMV8_V2
, 0, "d4", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1395 { ARMV8_V2
, 8, "d5", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1396 { ARMV8_V3
, 0, "d6", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1397 { ARMV8_V3
, 8, "d7", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1398 { ARMV8_V4
, 0, "d8", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1399 { ARMV8_V4
, 8, "d9", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1400 { ARMV8_V5
, 0, "d10", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1401 { ARMV8_V5
, 8, "d11", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1402 { ARMV8_V6
, 0, "d12", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1403 { ARMV8_V6
, 8, "d13", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1404 { ARMV8_V7
, 0, "d14", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1405 { ARMV8_V7
, 8, "d15", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1406 { ARMV8_V8
, 0, "d16", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1407 { ARMV8_V8
, 8, "d17", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1408 { ARMV8_V9
, 0, "d18", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1409 { ARMV8_V9
, 8, "d19", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1410 { ARMV8_V10
, 0, "d20", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1411 { ARMV8_V10
, 8, "d21", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1412 { ARMV8_V11
, 0, "d22", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1413 { ARMV8_V11
, 8, "d23", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1414 { ARMV8_V12
, 0, "d24", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1415 { ARMV8_V12
, 8, "d25", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1416 { ARMV8_V13
, 0, "d26", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1417 { ARMV8_V13
, 8, "d27", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1418 { ARMV8_V14
, 0, "d28", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1419 { ARMV8_V14
, 8, "d29", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1420 { ARMV8_V15
, 0, "d30", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1421 { ARMV8_V15
, 8, "d31", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1422 { ARMV8_FPSR
, 0, "fpscr", 32, ARM_MODE_ANY
, REG_TYPE_UINT32
, "float", "org.gnu.gdb.arm.vfp"},
1425 #define ARMV8_NUM_REGS ARRAY_SIZE(armv8_regs)
1426 #define ARMV8_NUM_REGS32 ARRAY_SIZE(armv8_regs32)
1428 static int armv8_get_core_reg(struct reg
*reg
)
1430 struct arm_reg
*armv8_reg
= reg
->arch_info
;
1431 struct target
*target
= armv8_reg
->target
;
1432 struct arm
*arm
= target_to_arm(target
);
1434 if (target
->state
!= TARGET_HALTED
)
1435 return ERROR_TARGET_NOT_HALTED
;
1437 return arm
->read_core_reg(target
, reg
, armv8_reg
->num
, arm
->core_mode
);
1440 static int armv8_set_core_reg(struct reg
*reg
, uint8_t *buf
)
1442 struct arm_reg
*armv8_reg
= reg
->arch_info
;
1443 struct target
*target
= armv8_reg
->target
;
1444 struct arm
*arm
= target_to_arm(target
);
1445 uint64_t value
= buf_get_u64(buf
, 0, reg
->size
);
1447 if (target
->state
!= TARGET_HALTED
)
1448 return ERROR_TARGET_NOT_HALTED
;
1450 if (reg
->size
<= 64) {
1451 if (reg
== arm
->cpsr
)
1452 armv8_set_cpsr(arm
, (uint32_t)value
);
1454 buf_set_u64(reg
->value
, 0, reg
->size
, value
);
1457 } else if (reg
->size
<= 128) {
1458 uint64_t hvalue
= buf_get_u64(buf
+ 8, 0, reg
->size
- 64);
1460 buf_set_u64(reg
->value
, 0, 64, value
);
1461 buf_set_u64(reg
->value
+ 8, 0, reg
->size
- 64, hvalue
);
1470 static const struct reg_arch_type armv8_reg_type
= {
1471 .get
= armv8_get_core_reg
,
1472 .set
= armv8_set_core_reg
,
1475 static int armv8_get_core_reg32(struct reg
*reg
)
1477 struct arm_reg
*armv8_reg
= reg
->arch_info
;
1478 struct target
*target
= armv8_reg
->target
;
1479 struct arm
*arm
= target_to_arm(target
);
1480 struct reg_cache
*cache
= arm
->core_cache
;
1484 if (target
->state
!= TARGET_HALTED
)
1485 return ERROR_TARGET_NOT_HALTED
;
1487 /* get the corresponding Aarch64 register */
1488 reg64
= cache
->reg_list
+ armv8_reg
->num
;
1494 retval
= arm
->read_core_reg(target
, reg64
, armv8_reg
->num
, arm
->core_mode
);
1495 if (retval
== ERROR_OK
)
1496 reg
->valid
= reg64
->valid
;
1501 static int armv8_set_core_reg32(struct reg
*reg
, uint8_t *buf
)
1503 struct arm_reg
*armv8_reg
= reg
->arch_info
;
1504 struct target
*target
= armv8_reg
->target
;
1505 struct arm
*arm
= target_to_arm(target
);
1506 struct reg_cache
*cache
= arm
->core_cache
;
1507 struct reg
*reg64
= cache
->reg_list
+ armv8_reg
->num
;
1508 uint32_t value
= buf_get_u32(buf
, 0, 32);
1510 if (target
->state
!= TARGET_HALTED
)
1511 return ERROR_TARGET_NOT_HALTED
;
1513 if (reg64
== arm
->cpsr
) {
1514 armv8_set_cpsr(arm
, value
);
1516 if (reg
->size
<= 32)
1517 buf_set_u32(reg
->value
, 0, 32, value
);
1518 else if (reg
->size
<= 64) {
1519 uint64_t value64
= buf_get_u64(buf
, 0, 64);
1520 buf_set_u64(reg
->value
, 0, 64, value64
);
1531 static const struct reg_arch_type armv8_reg32_type
= {
1532 .get
= armv8_get_core_reg32
,
1533 .set
= armv8_set_core_reg32
,
1536 /** Builds cache of architecturally defined registers. */
1537 struct reg_cache
*armv8_build_reg_cache(struct target
*target
)
1539 struct armv8_common
*armv8
= target_to_armv8(target
);
1540 struct arm
*arm
= &armv8
->arm
;
1541 int num_regs
= ARMV8_NUM_REGS
;
1542 int num_regs32
= ARMV8_NUM_REGS32
;
1543 struct reg_cache
**cache_p
= register_get_last_cache_p(&target
->reg_cache
);
1544 struct reg_cache
*cache
= malloc(sizeof(struct reg_cache
));
1545 struct reg_cache
*cache32
= malloc(sizeof(struct reg_cache
));
1546 struct reg
*reg_list
= calloc(num_regs
, sizeof(struct reg
));
1547 struct reg
*reg_list32
= calloc(num_regs32
, sizeof(struct reg
));
1548 struct arm_reg
*arch_info
= calloc(num_regs
, sizeof(struct arm_reg
));
1549 struct reg_feature
*feature
;
1552 /* Build the process context cache */
1553 cache
->name
= "Aarch64 registers";
1554 cache
->next
= cache32
;
1555 cache
->reg_list
= reg_list
;
1556 cache
->num_regs
= num_regs
;
1558 for (i
= 0; i
< num_regs
; i
++) {
1559 arch_info
[i
].num
= armv8_regs
[i
].id
;
1560 arch_info
[i
].mode
= armv8_regs
[i
].mode
;
1561 arch_info
[i
].target
= target
;
1562 arch_info
[i
].arm
= arm
;
1564 reg_list
[i
].name
= armv8_regs
[i
].name
;
1565 reg_list
[i
].size
= armv8_regs
[i
].bits
;
1566 reg_list
[i
].value
= &arch_info
[i
].value
[0];
1567 reg_list
[i
].type
= &armv8_reg_type
;
1568 reg_list
[i
].arch_info
= &arch_info
[i
];
1570 reg_list
[i
].group
= armv8_regs
[i
].group
;
1571 reg_list
[i
].number
= i
;
1572 reg_list
[i
].exist
= true;
1573 reg_list
[i
].caller_save
= true; /* gdb defaults to true */
1575 feature
= calloc(1, sizeof(struct reg_feature
));
1577 feature
->name
= armv8_regs
[i
].feature
;
1578 reg_list
[i
].feature
= feature
;
1580 LOG_ERROR("unable to allocate feature list");
1582 reg_list
[i
].reg_data_type
= calloc(1, sizeof(struct reg_data_type
));
1583 if (reg_list
[i
].reg_data_type
) {
1584 if (armv8_regs
[i
].data_type
== NULL
)
1585 reg_list
[i
].reg_data_type
->type
= armv8_regs
[i
].type
;
1587 *reg_list
[i
].reg_data_type
= *armv8_regs
[i
].data_type
;
1589 LOG_ERROR("unable to allocate reg type list");
1592 arm
->cpsr
= reg_list
+ ARMV8_xPSR
;
1593 arm
->pc
= reg_list
+ ARMV8_PC
;
1594 arm
->core_cache
= cache
;
1596 /* shadow cache for ARM mode registers */
1597 cache32
->name
= "Aarch32 registers";
1598 cache32
->next
= NULL
;
1599 cache32
->reg_list
= reg_list32
;
1600 cache32
->num_regs
= num_regs32
;
1602 for (i
= 0; i
< num_regs32
; i
++) {
1603 reg_list32
[i
].name
= armv8_regs32
[i
].name
;
1604 reg_list32
[i
].size
= armv8_regs32
[i
].bits
;
1605 reg_list32
[i
].value
= &arch_info
[armv8_regs32
[i
].id
].value
[armv8_regs32
[i
].mapping
];
1606 reg_list32
[i
].type
= &armv8_reg32_type
;
1607 reg_list32
[i
].arch_info
= &arch_info
[armv8_regs32
[i
].id
];
1608 reg_list32
[i
].group
= armv8_regs32
[i
].group
;
1609 reg_list32
[i
].number
= i
;
1610 reg_list32
[i
].exist
= true;
1611 reg_list32
[i
].caller_save
= true;
1613 feature
= calloc(1, sizeof(struct reg_feature
));
1615 feature
->name
= armv8_regs32
[i
].feature
;
1616 reg_list32
[i
].feature
= feature
;
1618 LOG_ERROR("unable to allocate feature list");
1620 reg_list32
[i
].reg_data_type
= calloc(1, sizeof(struct reg_data_type
));
1621 if (reg_list32
[i
].reg_data_type
)
1622 reg_list32
[i
].reg_data_type
->type
= armv8_regs32
[i
].type
;
1624 LOG_ERROR("unable to allocate reg type list");
1631 struct reg
*armv8_reg_current(struct arm
*arm
, unsigned regnum
)
1635 if (regnum
> (ARMV8_LAST_REG
- 1))
1638 r
= arm
->core_cache
->reg_list
+ regnum
;
1642 static void armv8_free_cache(struct reg_cache
*cache
, bool regs32
)
1650 for (i
= 0; i
< cache
->num_regs
; i
++) {
1651 reg
= &cache
->reg_list
[i
];
1654 free(reg
->reg_data_type
);
1658 free(cache
->reg_list
[0].arch_info
);
1659 free(cache
->reg_list
);
1663 void armv8_free_reg_cache(struct target
*target
)
1665 struct armv8_common
*armv8
= target_to_armv8(target
);
1666 struct arm
*arm
= &armv8
->arm
;
1667 struct reg_cache
*cache
= NULL
, *cache32
= NULL
;
1669 cache
= arm
->core_cache
;
1671 cache32
= cache
->next
;
1672 armv8_free_cache(cache32
, true);
1673 armv8_free_cache(cache
, false);
1674 arm
->core_cache
= NULL
;
1677 const struct command_registration armv8_command_handlers
[] = {
1678 COMMAND_REGISTRATION_DONE
1681 const char *armv8_get_gdb_arch(struct target
*target
)
1686 int armv8_get_gdb_reg_list(struct target
*target
,
1687 struct reg
**reg_list
[], int *reg_list_size
,
1688 enum target_register_class reg_class
)
1690 struct arm
*arm
= target_to_arm(target
);
1693 if (arm
->core_state
== ARM_STATE_AARCH64
) {
1695 LOG_DEBUG("Creating Aarch64 register list for target %s", target_name(target
));
1697 switch (reg_class
) {
1698 case REG_CLASS_GENERAL
:
1699 *reg_list_size
= ARMV8_V0
;
1700 *reg_list
= malloc(sizeof(struct reg
*) * (*reg_list_size
));
1702 for (i
= 0; i
< *reg_list_size
; i
++)
1703 (*reg_list
)[i
] = armv8_reg_current(arm
, i
);
1707 *reg_list_size
= ARMV8_LAST_REG
;
1708 *reg_list
= malloc(sizeof(struct reg
*) * (*reg_list_size
));
1710 for (i
= 0; i
< *reg_list_size
; i
++)
1711 (*reg_list
)[i
] = armv8_reg_current(arm
, i
);
1716 LOG_ERROR("not a valid register class type in query.");
1720 struct reg_cache
*cache32
= arm
->core_cache
->next
;
1722 LOG_DEBUG("Creating Aarch32 register list for target %s", target_name(target
));
1724 switch (reg_class
) {
1725 case REG_CLASS_GENERAL
:
1726 *reg_list_size
= ARMV8_R14
+ 3;
1727 *reg_list
= malloc(sizeof(struct reg
*) * (*reg_list_size
));
1729 for (i
= 0; i
< *reg_list_size
; i
++)
1730 (*reg_list
)[i
] = cache32
->reg_list
+ i
;
1734 *reg_list_size
= cache32
->num_regs
;
1735 *reg_list
= malloc(sizeof(struct reg
*) * (*reg_list_size
));
1737 for (i
= 0; i
< *reg_list_size
; i
++)
1738 (*reg_list
)[i
] = cache32
->reg_list
+ i
;
1742 LOG_ERROR("not a valid register class type in query.");
1748 int armv8_set_dbgreg_bits(struct armv8_common
*armv8
, unsigned int reg
, unsigned long mask
, unsigned long value
)
1753 int retval
= mem_ap_read_atomic_u32(armv8
->debug_ap
,
1754 armv8
->debug_base
+ reg
, &tmp
);
1755 if (ERROR_OK
!= retval
)
1758 /* clear bitfield */
1761 tmp
|= value
& mask
;
1763 /* write new value */
1764 retval
= mem_ap_write_atomic_u32(armv8
->debug_ap
,
1765 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)