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_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
!= NULL
)
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
!= NULL
)
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 /* read r1 via dcc */
450 retval
= dpm
->instr_read_data_dcc(dpm
,
451 ARMV4_5_MCR(14, 0, 1, 0, 5, 0),
453 if (retval
== ERROR_OK
) {
455 *lvalue
= ((*lvalue
) << 32) | value_r0
;
460 /* repeat above steps for high 64 bits of V register */
461 retval
= dpm
->instr_read_data_r0(dpm
,
462 ARMV4_5_VMOV(1, 1, 0, (num
>> 4), (num
& 0xf)),
464 retval
= dpm
->instr_read_data_dcc(dpm
,
465 ARMV4_5_MCR(14, 0, 1, 0, 5, 0),
467 if (retval
== ERROR_OK
) {
469 *hvalue
= ((*hvalue
) << 32) | value_r0
;
481 static int armv8_write_reg32(struct armv8_common
*armv8
, int regnum
, uint64_t value
)
483 struct arm_dpm
*dpm
= &armv8
->dpm
;
487 case ARMV8_R0
... ARMV8_R14
:
488 /* load register from DCC: "MRC p14, 0, Rnum, c0, c5, 0" */
489 retval
= dpm
->instr_write_data_dcc(dpm
,
490 ARMV4_5_MRC(14, 0, regnum
, 0, 5, 0), value
);
493 retval
= dpm
->instr_write_data_dcc(dpm
,
494 ARMV4_5_MRC(14, 0, 13, 0, 5, 0), value
);
497 * read r0 from DCC; then "MOV pc, r0" */
498 retval
= dpm
->instr_write_data_r0(dpm
,
499 ARMV8_MCR_DLR(0), value
);
501 case ARMV8_xPSR
: /* CPSR */
502 /* read r0 from DCC, then "MCR r0, DSPSR" */
503 retval
= dpm
->instr_write_data_r0(dpm
,
504 ARMV8_MCR_DSPSR(0), value
);
506 case ARMV8_ELR_EL1
: /* mapped to LR_svc */
507 retval
= dpm
->instr_write_data_dcc(dpm
,
508 ARMV4_5_MRC(14, 0, 14, 0, 5, 0),
511 case ARMV8_ELR_EL2
: /* mapped to ELR_hyp */
512 retval
= dpm
->instr_write_data_r0(dpm
,
513 ARMV8_MSR_GP_T1(0, 14, 0, 1),
516 case ARMV8_ELR_EL3
: /* mapped to LR_mon */
517 retval
= dpm
->instr_write_data_dcc(dpm
,
518 ARMV4_5_MRC(14, 0, 14, 0, 5, 0),
521 case ARMV8_ESR_EL1
: /* mapped to DFSR */
522 retval
= dpm
->instr_write_data_r0(dpm
,
523 ARMV4_5_MCR(15, 0, 0, 5, 0, 0),
526 case ARMV8_ESR_EL2
: /* mapped to HSR */
527 retval
= dpm
->instr_write_data_r0(dpm
,
528 ARMV4_5_MCR(15, 4, 0, 5, 2, 0),
531 case ARMV8_ESR_EL3
: /* FIXME: no equivalent in aarch32? */
534 case ARMV8_SPSR_EL1
: /* mapped to SPSR_svc */
535 retval
= dpm
->instr_write_data_r0(dpm
,
536 ARMV8_MSR_GP_xPSR_T1(1, 0, 15),
539 case ARMV8_SPSR_EL2
: /* mapped to SPSR_hyp */
540 retval
= dpm
->instr_write_data_r0(dpm
,
541 ARMV8_MSR_GP_xPSR_T1(1, 0, 15),
544 case ARMV8_SPSR_EL3
: /* mapped to SPSR_mon */
545 retval
= dpm
->instr_write_data_r0(dpm
,
546 ARMV8_MSR_GP_xPSR_T1(1, 0, 15),
550 /* move to r0 from DCC, then "VMSR FPSCR, r0" */
551 retval
= dpm
->instr_write_data_r0(dpm
,
552 ARMV4_5_VMSR(0), value
);
563 static int armv8_write_reg_simdfp_aarch32(struct armv8_common
*armv8
, int regnum
, uint64_t lvalue
, uint64_t hvalue
)
565 int retval
= ERROR_FAIL
;
566 struct arm_dpm
*dpm
= &armv8
->dpm
;
567 struct reg
*reg_r1
= dpm
->arm
->core_cache
->reg_list
+ ARMV8_R1
;
568 uint32_t value_r0
= 0, value_r1
= 0;
569 unsigned num
= (regnum
- ARMV8_V0
) << 1;
572 case ARMV8_V0
... ARMV8_V15
:
573 /* we are going to write R1, mark it dirty */
574 reg_r1
->dirty
= true;
575 value_r1
= lvalue
>> 32;
576 value_r0
= lvalue
& 0xFFFFFFFF;
577 /* write value_r1 to r1 via dcc */
578 retval
= dpm
->instr_write_data_dcc(dpm
,
579 ARMV4_5_MRC(14, 0, 1, 0, 5, 0),
581 /* write value_r0 to r0 via dcc then,
582 * move to double word register from r0:r1: "vmov vm, r0, r1"
584 retval
= dpm
->instr_write_data_r0(dpm
,
585 ARMV4_5_VMOV(0, 1, 0, (num
>> 4), (num
& 0xf)),
589 /* repeat above steps for high 64 bits of V register */
590 value_r1
= hvalue
>> 32;
591 value_r0
= hvalue
& 0xFFFFFFFF;
592 retval
= dpm
->instr_write_data_dcc(dpm
,
593 ARMV4_5_MRC(14, 0, 1, 0, 5, 0),
595 retval
= dpm
->instr_write_data_r0(dpm
,
596 ARMV4_5_VMOV(0, 1, 0, (num
>> 4), (num
& 0xf)),
607 void armv8_select_reg_access(struct armv8_common
*armv8
, bool is_aarch64
)
610 armv8
->read_reg_u64
= armv8_read_reg
;
611 armv8
->write_reg_u64
= armv8_write_reg
;
612 armv8
->read_reg_u128
= armv8_read_reg_simdfp_aarch64
;
613 armv8
->write_reg_u128
= armv8_write_reg_simdfp_aarch64
;
616 armv8
->read_reg_u64
= armv8_read_reg32
;
617 armv8
->write_reg_u64
= armv8_write_reg32
;
618 armv8
->read_reg_u128
= armv8_read_reg_simdfp_aarch32
;
619 armv8
->write_reg_u128
= armv8_write_reg_simdfp_aarch32
;
623 /* retrieve core id cluster id */
624 int armv8_read_mpidr(struct armv8_common
*armv8
)
626 int retval
= ERROR_FAIL
;
627 struct arm
*arm
= &armv8
->arm
;
628 struct arm_dpm
*dpm
= armv8
->arm
.dpm
;
631 retval
= dpm
->prepare(dpm
);
632 if (retval
!= ERROR_OK
)
635 /* check if we're in an unprivileged mode */
636 if (armv8_curel_from_core_mode(arm
->core_mode
) < SYSTEM_CUREL_EL1
) {
637 retval
= armv8_dpm_modeswitch(dpm
, ARMV8_64_EL1H
);
638 if (retval
!= ERROR_OK
)
642 retval
= dpm
->instr_read_data_r0(dpm
, armv8_opcode(armv8
, READ_REG_MPIDR
), &mpidr
);
643 if (retval
!= ERROR_OK
)
646 armv8
->multi_processor_system
= (mpidr
>> 30) & 1;
647 armv8
->cluster_id
= (mpidr
>> 8) & 0xf;
648 armv8
->cpu_id
= mpidr
& 0x3;
649 LOG_INFO("%s cluster %x core %x %s", target_name(armv8
->arm
.target
),
652 armv8
->multi_processor_system
== 0 ? "multi core" : "single core");
654 LOG_ERROR("mpidr not in multiprocessor format");
657 armv8_dpm_modeswitch(dpm
, ARM_MODE_ANY
);
663 * Configures host-side ARM records to reflect the specified CPSR.
664 * Later, code can use arm_reg_current() to map register numbers
665 * according to how they are exposed by this mode.
667 void armv8_set_cpsr(struct arm
*arm
, uint32_t cpsr
)
669 uint32_t mode
= cpsr
& 0x1F;
671 /* NOTE: this may be called very early, before the register
672 * cache is set up. We can't defend against many errors, in
673 * particular against CPSRs that aren't valid *here* ...
676 buf_set_u32(arm
->cpsr
->value
, 0, 32, cpsr
);
677 arm
->cpsr
->valid
= 1;
678 arm
->cpsr
->dirty
= 0;
681 /* Older ARMs won't have the J bit */
682 enum arm_state state
= 0xFF;
684 if ((cpsr
& 0x10) != 0) {
686 if (cpsr
& (1 << 5)) { /* T */
687 if (cpsr
& (1 << 24)) { /* J */
688 LOG_WARNING("ThumbEE -- incomplete support");
689 state
= ARM_STATE_THUMB_EE
;
691 state
= ARM_STATE_THUMB
;
693 if (cpsr
& (1 << 24)) { /* J */
694 LOG_ERROR("Jazelle state handling is BROKEN!");
695 state
= ARM_STATE_JAZELLE
;
697 state
= ARM_STATE_ARM
;
701 state
= ARM_STATE_AARCH64
;
704 arm
->core_state
= state
;
705 arm
->core_mode
= mode
;
707 LOG_DEBUG("set CPSR %#8.8x: %s mode, %s state", (unsigned) cpsr
,
708 armv8_mode_name(arm
->core_mode
),
709 armv8_state_strings
[arm
->core_state
]);
712 static void armv8_show_fault_registers32(struct armv8_common
*armv8
)
714 uint32_t dfsr
, ifsr
, dfar
, ifar
;
715 struct arm_dpm
*dpm
= armv8
->arm
.dpm
;
718 retval
= dpm
->prepare(dpm
);
719 if (retval
!= ERROR_OK
)
722 /* ARMV4_5_MRC(cpnum, op1, r0, CRn, CRm, op2) */
724 /* c5/c0 - {data, instruction} fault status registers */
725 retval
= dpm
->instr_read_data_r0(dpm
,
726 ARMV4_5_MRC(15, 0, 0, 5, 0, 0),
728 if (retval
!= ERROR_OK
)
731 retval
= dpm
->instr_read_data_r0(dpm
,
732 ARMV4_5_MRC(15, 0, 0, 5, 0, 1),
734 if (retval
!= ERROR_OK
)
737 /* c6/c0 - {data, instruction} fault address registers */
738 retval
= dpm
->instr_read_data_r0(dpm
,
739 ARMV4_5_MRC(15, 0, 0, 6, 0, 0),
741 if (retval
!= ERROR_OK
)
744 retval
= dpm
->instr_read_data_r0(dpm
,
745 ARMV4_5_MRC(15, 0, 0, 6, 0, 2),
747 if (retval
!= ERROR_OK
)
750 LOG_USER("Data fault registers DFSR: %8.8" PRIx32
751 ", DFAR: %8.8" PRIx32
, dfsr
, dfar
);
752 LOG_USER("Instruction fault registers IFSR: %8.8" PRIx32
753 ", IFAR: %8.8" PRIx32
, ifsr
, ifar
);
756 /* (void) */ dpm
->finish(dpm
);
759 static __attribute__((unused
)) void armv8_show_fault_registers(struct target
*target
)
761 struct armv8_common
*armv8
= target_to_armv8(target
);
763 if (armv8
->arm
.core_state
!= ARM_STATE_AARCH64
)
764 armv8_show_fault_registers32(armv8
);
767 static uint8_t armv8_pa_size(uint32_t ps
)
790 LOG_INFO("Unknow physicall address size");
796 static __attribute__((unused
)) int armv8_read_ttbcr32(struct target
*target
)
798 struct armv8_common
*armv8
= target_to_armv8(target
);
799 struct arm_dpm
*dpm
= armv8
->arm
.dpm
;
800 uint32_t ttbcr
, ttbcr_n
;
801 int retval
= dpm
->prepare(dpm
);
802 if (retval
!= ERROR_OK
)
804 /* MRC p15,0,<Rt>,c2,c0,2 ; Read CP15 Translation Table Base Control Register*/
805 retval
= dpm
->instr_read_data_r0(dpm
,
806 ARMV4_5_MRC(15, 0, 0, 2, 0, 2),
808 if (retval
!= ERROR_OK
)
811 LOG_DEBUG("ttbcr %" PRIx32
, ttbcr
);
813 ttbcr_n
= ttbcr
& 0x7;
814 armv8
->armv8_mmu
.ttbcr
= ttbcr
;
817 * ARM Architecture Reference Manual (ARMv7-A and ARMv7-Redition),
818 * document # ARM DDI 0406C
820 armv8
->armv8_mmu
.ttbr_range
[0] = 0xffffffff >> ttbcr_n
;
821 armv8
->armv8_mmu
.ttbr_range
[1] = 0xffffffff;
822 armv8
->armv8_mmu
.ttbr_mask
[0] = 0xffffffff << (14 - ttbcr_n
);
823 armv8
->armv8_mmu
.ttbr_mask
[1] = 0xffffffff << 14;
825 LOG_DEBUG("ttbr1 %s, ttbr0_mask %" PRIx32
" ttbr1_mask %" PRIx32
,
826 (ttbcr_n
!= 0) ? "used" : "not used",
827 armv8
->armv8_mmu
.ttbr_mask
[0],
828 armv8
->armv8_mmu
.ttbr_mask
[1]);
835 static __attribute__((unused
)) int armv8_read_ttbcr(struct target
*target
)
837 struct armv8_common
*armv8
= target_to_armv8(target
);
838 struct arm_dpm
*dpm
= armv8
->arm
.dpm
;
839 struct arm
*arm
= &armv8
->arm
;
843 int retval
= dpm
->prepare(dpm
);
844 if (retval
!= ERROR_OK
)
847 /* claaer ttrr1_used and ttbr0_mask */
848 memset(&armv8
->armv8_mmu
.ttbr1_used
, 0, sizeof(armv8
->armv8_mmu
.ttbr1_used
));
849 memset(&armv8
->armv8_mmu
.ttbr0_mask
, 0, sizeof(armv8
->armv8_mmu
.ttbr0_mask
));
851 switch (armv8_curel_from_core_mode(arm
->core_mode
)) {
852 case SYSTEM_CUREL_EL3
:
853 retval
= dpm
->instr_read_data_r0(dpm
,
854 ARMV8_MRS(SYSTEM_TCR_EL3
, 0),
856 retval
+= dpm
->instr_read_data_r0_64(dpm
,
857 ARMV8_MRS(SYSTEM_TTBR0_EL3
, 0),
859 if (retval
!= ERROR_OK
)
861 armv8
->va_size
= 64 - (ttbcr
& 0x3F);
862 armv8
->pa_size
= armv8_pa_size((ttbcr
>> 16) & 7);
863 armv8
->page_size
= (ttbcr
>> 14) & 3;
865 case SYSTEM_CUREL_EL2
:
866 retval
= dpm
->instr_read_data_r0(dpm
,
867 ARMV8_MRS(SYSTEM_TCR_EL2
, 0),
869 retval
+= dpm
->instr_read_data_r0_64(dpm
,
870 ARMV8_MRS(SYSTEM_TTBR0_EL2
, 0),
872 if (retval
!= ERROR_OK
)
874 armv8
->va_size
= 64 - (ttbcr
& 0x3F);
875 armv8
->pa_size
= armv8_pa_size((ttbcr
>> 16) & 7);
876 armv8
->page_size
= (ttbcr
>> 14) & 3;
878 case SYSTEM_CUREL_EL0
:
879 armv8_dpm_modeswitch(dpm
, ARMV8_64_EL1H
);
881 case SYSTEM_CUREL_EL1
:
882 retval
= dpm
->instr_read_data_r0_64(dpm
,
883 ARMV8_MRS(SYSTEM_TCR_EL1
, 0),
885 armv8
->va_size
= 64 - (ttbcr_64
& 0x3F);
886 armv8
->pa_size
= armv8_pa_size((ttbcr_64
>> 32) & 7);
887 armv8
->page_size
= (ttbcr_64
>> 14) & 3;
888 armv8
->armv8_mmu
.ttbr1_used
= (((ttbcr_64
>> 16) & 0x3F) != 0) ? 1 : 0;
889 armv8
->armv8_mmu
.ttbr0_mask
= 0x0000FFFFFFFFFFFF;
890 retval
+= dpm
->instr_read_data_r0_64(dpm
,
891 ARMV8_MRS(SYSTEM_TTBR0_EL1
| (armv8
->armv8_mmu
.ttbr1_used
), 0),
893 if (retval
!= ERROR_OK
)
897 LOG_ERROR("unknow core state");
901 if (retval
!= ERROR_OK
)
904 if (armv8
->armv8_mmu
.ttbr1_used
== 1)
905 LOG_INFO("TTBR0 access above %" PRIx64
, (uint64_t)(armv8
->armv8_mmu
.ttbr0_mask
));
908 armv8_dpm_modeswitch(dpm
, ARM_MODE_ANY
);
913 /* method adapted to cortex A : reused arm v4 v5 method*/
914 int armv8_mmu_translate_va(struct target
*target
, target_addr_t va
, target_addr_t
*val
)
919 /* V8 method VA TO PA */
920 int armv8_mmu_translate_va_pa(struct target
*target
, target_addr_t va
,
921 target_addr_t
*val
, int meminfo
)
923 struct armv8_common
*armv8
= target_to_armv8(target
);
924 struct arm
*arm
= target_to_arm(target
);
925 struct arm_dpm
*dpm
= &armv8
->dpm
;
926 enum arm_mode target_mode
= ARM_MODE_ANY
;
931 static const char * const shared_name
[] = {
932 "Non-", "UNDEFINED ", "Outer ", "Inner "
935 static const char * const secure_name
[] = {
936 "Secure", "Not Secure"
939 retval
= dpm
->prepare(dpm
);
940 if (retval
!= ERROR_OK
)
943 switch (armv8_curel_from_core_mode(arm
->core_mode
)) {
944 case SYSTEM_CUREL_EL0
:
945 instr
= ARMV8_SYS(SYSTEM_ATS12E0R
, 0);
946 /* can only execute instruction at EL2 */
947 target_mode
= ARMV8_64_EL2H
;
949 case SYSTEM_CUREL_EL1
:
950 instr
= ARMV8_SYS(SYSTEM_ATS12E1R
, 0);
951 /* can only execute instruction at EL2 */
952 target_mode
= ARMV8_64_EL2H
;
954 case SYSTEM_CUREL_EL2
:
955 instr
= ARMV8_SYS(SYSTEM_ATS1E2R
, 0);
957 case SYSTEM_CUREL_EL3
:
958 instr
= ARMV8_SYS(SYSTEM_ATS1E3R
, 0);
965 if (target_mode
!= ARM_MODE_ANY
)
966 armv8_dpm_modeswitch(dpm
, target_mode
);
968 /* write VA to R0 and execute translation instruction */
969 retval
= dpm
->instr_write_data_r0_64(dpm
, instr
, (uint64_t)va
);
970 /* read result from PAR_EL1 */
971 if (retval
== ERROR_OK
)
972 retval
= dpm
->instr_read_data_r0_64(dpm
, ARMV8_MRS(SYSTEM_PAR_EL1
, 0), &par
);
974 /* switch back to saved PE mode */
975 if (target_mode
!= ARM_MODE_ANY
)
976 armv8_dpm_modeswitch(dpm
, ARM_MODE_ANY
);
980 if (retval
!= ERROR_OK
)
984 LOG_ERROR("Address translation failed at stage %i, FST=%x, PTW=%i",
985 ((int)(par
>> 9) & 1)+1, (int)(par
>> 1) & 0x3f, (int)(par
>> 8) & 1);
990 *val
= (par
& 0xFFFFFFFFF000UL
) | (va
& 0xFFF);
992 int SH
= (par
>> 7) & 3;
993 int NS
= (par
>> 9) & 1;
994 int ATTR
= (par
>> 56) & 0xFF;
996 char *memtype
= (ATTR
& 0xF0) == 0 ? "Device Memory" : "Normal Memory";
998 LOG_USER("%sshareable, %s",
999 shared_name
[SH
], secure_name
[NS
]);
1000 LOG_USER("%s", memtype
);
1007 int armv8_handle_cache_info_command(struct command_context
*cmd_ctx
,
1008 struct armv8_cache_common
*armv8_cache
)
1010 if (armv8_cache
->info
== -1) {
1011 command_print(cmd_ctx
, "cache not yet identified");
1015 if (armv8_cache
->display_cache_info
)
1016 armv8_cache
->display_cache_info(cmd_ctx
, armv8_cache
);
1020 static int armv8_setup_semihosting(struct target
*target
, int enable
)
1022 struct arm
*arm
= target_to_arm(target
);
1024 if (arm
->core_state
!= ARM_STATE_AARCH64
) {
1025 LOG_ERROR("semihosting only supported in AArch64 state\n");
1032 int armv8_init_arch_info(struct target
*target
, struct armv8_common
*armv8
)
1034 struct arm
*arm
= &armv8
->arm
;
1035 arm
->arch_info
= armv8
;
1036 target
->arch_info
= &armv8
->arm
;
1037 arm
->setup_semihosting
= armv8_setup_semihosting
;
1038 /* target is useful in all function arm v4 5 compatible */
1039 armv8
->arm
.target
= target
;
1040 armv8
->arm
.common_magic
= ARM_COMMON_MAGIC
;
1041 armv8
->common_magic
= ARMV8_COMMON_MAGIC
;
1043 armv8
->armv8_mmu
.armv8_cache
.l2_cache
= NULL
;
1044 armv8
->armv8_mmu
.armv8_cache
.info
= -1;
1045 armv8
->armv8_mmu
.armv8_cache
.flush_all_data_cache
= NULL
;
1046 armv8
->armv8_mmu
.armv8_cache
.display_cache_info
= NULL
;
1050 int armv8_aarch64_state(struct target
*target
)
1052 struct arm
*arm
= target_to_arm(target
);
1054 if (arm
->common_magic
!= ARM_COMMON_MAGIC
) {
1055 LOG_ERROR("BUG: called for a non-ARM target");
1059 LOG_USER("target halted in %s state due to %s, current mode: %s\n"
1060 "cpsr: 0x%8.8" PRIx32
" pc: 0x%" PRIx64
"%s",
1061 armv8_state_strings
[arm
->core_state
],
1062 debug_reason_name(target
),
1063 armv8_mode_name(arm
->core_mode
),
1064 buf_get_u32(arm
->cpsr
->value
, 0, 32),
1065 buf_get_u64(arm
->pc
->value
, 0, 64),
1066 (target
->semihosting
&& target
->semihosting
->is_active
) ? ", semihosting" : "");
1071 int armv8_arch_state(struct target
*target
)
1073 static const char * const state
[] = {
1074 "disabled", "enabled"
1077 struct armv8_common
*armv8
= target_to_armv8(target
);
1078 struct arm
*arm
= &armv8
->arm
;
1080 if (armv8
->common_magic
!= ARMV8_COMMON_MAGIC
) {
1081 LOG_ERROR("BUG: called for a non-Armv8 target");
1082 return ERROR_COMMAND_SYNTAX_ERROR
;
1085 if (arm
->core_state
== ARM_STATE_AARCH64
)
1086 armv8_aarch64_state(target
);
1088 arm_arch_state(target
);
1090 LOG_USER("MMU: %s, D-Cache: %s, I-Cache: %s",
1091 state
[armv8
->armv8_mmu
.mmu_enabled
],
1092 state
[armv8
->armv8_mmu
.armv8_cache
.d_u_cache_enabled
],
1093 state
[armv8
->armv8_mmu
.armv8_cache
.i_cache_enabled
]);
1095 if (arm
->core_mode
== ARM_MODE_ABT
)
1096 armv8_show_fault_registers(target
);
1098 if (target
->debug_reason
== DBG_REASON_WATCHPOINT
)
1099 LOG_USER("Watchpoint triggered at PC %#08x",
1100 (unsigned) armv8
->dpm
.wp_pc
);
1105 static struct reg_data_type aarch64_vector_base_types
[] = {
1106 {REG_TYPE_IEEE_DOUBLE
, "ieee_double", 0, {NULL
} },
1107 {REG_TYPE_UINT64
, "uint64", 0, {NULL
} },
1108 {REG_TYPE_INT64
, "int64", 0, {NULL
} },
1109 {REG_TYPE_IEEE_SINGLE
, "ieee_single", 0, {NULL
} },
1110 {REG_TYPE_UINT32
, "uint32", 0, {NULL
} },
1111 {REG_TYPE_INT32
, "int32", 0, {NULL
} },
1112 {REG_TYPE_UINT16
, "uint16", 0, {NULL
} },
1113 {REG_TYPE_INT16
, "int16", 0, {NULL
} },
1114 {REG_TYPE_UINT8
, "uint8", 0, {NULL
} },
1115 {REG_TYPE_INT8
, "int8", 0, {NULL
} },
1116 {REG_TYPE_UINT128
, "uint128", 0, {NULL
} },
1117 {REG_TYPE_INT128
, "int128", 0, {NULL
} }
1120 static struct reg_data_type_vector aarch64_vector_types
[] = {
1121 {aarch64_vector_base_types
+ 0, 2},
1122 {aarch64_vector_base_types
+ 1, 2},
1123 {aarch64_vector_base_types
+ 2, 2},
1124 {aarch64_vector_base_types
+ 3, 4},
1125 {aarch64_vector_base_types
+ 4, 4},
1126 {aarch64_vector_base_types
+ 5, 4},
1127 {aarch64_vector_base_types
+ 6, 8},
1128 {aarch64_vector_base_types
+ 7, 8},
1129 {aarch64_vector_base_types
+ 8, 16},
1130 {aarch64_vector_base_types
+ 9, 16},
1131 {aarch64_vector_base_types
+ 10, 01},
1132 {aarch64_vector_base_types
+ 11, 01},
1135 static struct reg_data_type aarch64_fpu_vector
[] = {
1136 {REG_TYPE_ARCH_DEFINED
, "v2d", REG_TYPE_CLASS_VECTOR
, {aarch64_vector_types
+ 0} },
1137 {REG_TYPE_ARCH_DEFINED
, "v2u", REG_TYPE_CLASS_VECTOR
, {aarch64_vector_types
+ 1} },
1138 {REG_TYPE_ARCH_DEFINED
, "v2i", REG_TYPE_CLASS_VECTOR
, {aarch64_vector_types
+ 2} },
1139 {REG_TYPE_ARCH_DEFINED
, "v4f", REG_TYPE_CLASS_VECTOR
, {aarch64_vector_types
+ 3} },
1140 {REG_TYPE_ARCH_DEFINED
, "v4u", REG_TYPE_CLASS_VECTOR
, {aarch64_vector_types
+ 4} },
1141 {REG_TYPE_ARCH_DEFINED
, "v4i", REG_TYPE_CLASS_VECTOR
, {aarch64_vector_types
+ 5} },
1142 {REG_TYPE_ARCH_DEFINED
, "v8u", REG_TYPE_CLASS_VECTOR
, {aarch64_vector_types
+ 6} },
1143 {REG_TYPE_ARCH_DEFINED
, "v8i", REG_TYPE_CLASS_VECTOR
, {aarch64_vector_types
+ 7} },
1144 {REG_TYPE_ARCH_DEFINED
, "v16u", REG_TYPE_CLASS_VECTOR
, {aarch64_vector_types
+ 8} },
1145 {REG_TYPE_ARCH_DEFINED
, "v16i", REG_TYPE_CLASS_VECTOR
, {aarch64_vector_types
+ 9} },
1146 {REG_TYPE_ARCH_DEFINED
, "v1u", REG_TYPE_CLASS_VECTOR
, {aarch64_vector_types
+ 10} },
1147 {REG_TYPE_ARCH_DEFINED
, "v1i", REG_TYPE_CLASS_VECTOR
, {aarch64_vector_types
+ 11} },
1150 static struct reg_data_type_union_field aarch64_union_fields_vnd
[] = {
1151 {"f", aarch64_fpu_vector
+ 0, aarch64_union_fields_vnd
+ 1},
1152 {"u", aarch64_fpu_vector
+ 1, aarch64_union_fields_vnd
+ 2},
1153 {"s", aarch64_fpu_vector
+ 2, NULL
},
1156 static struct reg_data_type_union_field aarch64_union_fields_vns
[] = {
1157 {"f", aarch64_fpu_vector
+ 3, aarch64_union_fields_vns
+ 1},
1158 {"u", aarch64_fpu_vector
+ 4, aarch64_union_fields_vns
+ 2},
1159 {"s", aarch64_fpu_vector
+ 5, NULL
},
1162 static struct reg_data_type_union_field aarch64_union_fields_vnh
[] = {
1163 {"u", aarch64_fpu_vector
+ 6, aarch64_union_fields_vnh
+ 1},
1164 {"s", aarch64_fpu_vector
+ 7, NULL
},
1167 static struct reg_data_type_union_field aarch64_union_fields_vnb
[] = {
1168 {"u", aarch64_fpu_vector
+ 8, aarch64_union_fields_vnb
+ 1},
1169 {"s", aarch64_fpu_vector
+ 9, NULL
},
1172 static struct reg_data_type_union_field aarch64_union_fields_vnq
[] = {
1173 {"u", aarch64_fpu_vector
+ 10, aarch64_union_fields_vnq
+ 1},
1174 {"s", aarch64_fpu_vector
+ 11, NULL
},
1177 static struct reg_data_type_union aarch64_union_types
[] = {
1178 {aarch64_union_fields_vnd
},
1179 {aarch64_union_fields_vns
},
1180 {aarch64_union_fields_vnh
},
1181 {aarch64_union_fields_vnb
},
1182 {aarch64_union_fields_vnq
},
1185 static struct reg_data_type aarch64_fpu_union
[] = {
1186 {REG_TYPE_ARCH_DEFINED
, "vnd", REG_TYPE_CLASS_UNION
, {.reg_type_union
= aarch64_union_types
+ 0} },
1187 {REG_TYPE_ARCH_DEFINED
, "vns", REG_TYPE_CLASS_UNION
, {.reg_type_union
= aarch64_union_types
+ 1} },
1188 {REG_TYPE_ARCH_DEFINED
, "vnh", REG_TYPE_CLASS_UNION
, {.reg_type_union
= aarch64_union_types
+ 2} },
1189 {REG_TYPE_ARCH_DEFINED
, "vnb", REG_TYPE_CLASS_UNION
, {.reg_type_union
= aarch64_union_types
+ 3} },
1190 {REG_TYPE_ARCH_DEFINED
, "vnq", REG_TYPE_CLASS_UNION
, {.reg_type_union
= aarch64_union_types
+ 4} },
1193 static struct reg_data_type_union_field aarch64v_union_fields
[] = {
1194 {"d", aarch64_fpu_union
+ 0, aarch64v_union_fields
+ 1},
1195 {"s", aarch64_fpu_union
+ 1, aarch64v_union_fields
+ 2},
1196 {"h", aarch64_fpu_union
+ 2, aarch64v_union_fields
+ 3},
1197 {"b", aarch64_fpu_union
+ 3, aarch64v_union_fields
+ 4},
1198 {"q", aarch64_fpu_union
+ 4, NULL
},
1201 static struct reg_data_type_union aarch64v_union
[] = {
1202 {aarch64v_union_fields
}
1205 static struct reg_data_type aarch64v
[] = {
1206 {REG_TYPE_ARCH_DEFINED
, "aarch64v", REG_TYPE_CLASS_UNION
,
1207 {.reg_type_union
= aarch64v_union
} },
1210 static struct reg_data_type_bitfield aarch64_cpsr_bits
[] = {
1211 { 0, 0 , REG_TYPE_UINT8
},
1212 { 2, 3, REG_TYPE_UINT8
},
1213 { 4, 4 , REG_TYPE_UINT8
},
1214 { 6, 6 , REG_TYPE_BOOL
},
1215 { 7, 7 , REG_TYPE_BOOL
},
1216 { 8, 8 , REG_TYPE_BOOL
},
1217 { 9, 9 , REG_TYPE_BOOL
},
1218 { 20, 20, REG_TYPE_BOOL
},
1219 { 21, 21, REG_TYPE_BOOL
},
1220 { 28, 28, REG_TYPE_BOOL
},
1221 { 29, 29, REG_TYPE_BOOL
},
1222 { 30, 30, REG_TYPE_BOOL
},
1223 { 31, 31, REG_TYPE_BOOL
},
1226 static struct reg_data_type_flags_field aarch64_cpsr_fields
[] = {
1227 { "SP", aarch64_cpsr_bits
+ 0, aarch64_cpsr_fields
+ 1 },
1228 { "EL", aarch64_cpsr_bits
+ 1, aarch64_cpsr_fields
+ 2 },
1229 { "nRW", aarch64_cpsr_bits
+ 2, aarch64_cpsr_fields
+ 3 },
1230 { "F" , aarch64_cpsr_bits
+ 3, aarch64_cpsr_fields
+ 4 },
1231 { "I" , aarch64_cpsr_bits
+ 4, aarch64_cpsr_fields
+ 5 },
1232 { "A" , aarch64_cpsr_bits
+ 5, aarch64_cpsr_fields
+ 6 },
1233 { "D" , aarch64_cpsr_bits
+ 6, aarch64_cpsr_fields
+ 7 },
1234 { "IL" , aarch64_cpsr_bits
+ 7, aarch64_cpsr_fields
+ 8 },
1235 { "SS" , aarch64_cpsr_bits
+ 8, aarch64_cpsr_fields
+ 9 },
1236 { "V" , aarch64_cpsr_bits
+ 9, aarch64_cpsr_fields
+ 10 },
1237 { "C" , aarch64_cpsr_bits
+ 10, aarch64_cpsr_fields
+ 11 },
1238 { "Z" , aarch64_cpsr_bits
+ 11, aarch64_cpsr_fields
+ 12 },
1239 { "N" , aarch64_cpsr_bits
+ 12, NULL
}
1242 static struct reg_data_type_flags aarch64_cpsr_flags
[] = {
1243 { 4, aarch64_cpsr_fields
}
1246 static struct reg_data_type aarch64_flags_cpsr
[] = {
1247 {REG_TYPE_ARCH_DEFINED
, "cpsr_flags", REG_TYPE_CLASS_FLAGS
,
1248 {.reg_type_flags
= aarch64_cpsr_flags
} },
1251 static const struct {
1258 const char *feature
;
1259 struct reg_data_type
*data_type
;
1261 { ARMV8_R0
, "x0", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1262 { ARMV8_R1
, "x1", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1263 { ARMV8_R2
, "x2", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1264 { ARMV8_R3
, "x3", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1265 { ARMV8_R4
, "x4", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1266 { ARMV8_R5
, "x5", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1267 { ARMV8_R6
, "x6", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1268 { ARMV8_R7
, "x7", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1269 { ARMV8_R8
, "x8", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1270 { ARMV8_R9
, "x9", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1271 { ARMV8_R10
, "x10", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1272 { ARMV8_R11
, "x11", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1273 { ARMV8_R12
, "x12", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1274 { ARMV8_R13
, "x13", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1275 { ARMV8_R14
, "x14", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1276 { ARMV8_R15
, "x15", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1277 { ARMV8_R16
, "x16", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1278 { ARMV8_R17
, "x17", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1279 { ARMV8_R18
, "x18", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1280 { ARMV8_R19
, "x19", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1281 { ARMV8_R20
, "x20", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1282 { ARMV8_R21
, "x21", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1283 { ARMV8_R22
, "x22", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1284 { ARMV8_R23
, "x23", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1285 { ARMV8_R24
, "x24", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1286 { ARMV8_R25
, "x25", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1287 { ARMV8_R26
, "x26", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1288 { ARMV8_R27
, "x27", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1289 { ARMV8_R28
, "x28", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1290 { ARMV8_R29
, "x29", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1291 { ARMV8_R30
, "x30", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1293 { ARMV8_SP
, "sp", 64, ARM_MODE_ANY
, REG_TYPE_DATA_PTR
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1294 { ARMV8_PC
, "pc", 64, ARM_MODE_ANY
, REG_TYPE_CODE_PTR
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1295 { ARMV8_xPSR
, "cpsr", 32, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
,
1296 "general", "org.gnu.gdb.aarch64.core", aarch64_flags_cpsr
},
1297 { ARMV8_V0
, "v0", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1298 { ARMV8_V1
, "v1", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1299 { ARMV8_V2
, "v2", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1300 { ARMV8_V3
, "v3", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1301 { ARMV8_V4
, "v4", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1302 { ARMV8_V5
, "v5", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1303 { ARMV8_V6
, "v6", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1304 { ARMV8_V7
, "v7", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1305 { ARMV8_V8
, "v8", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1306 { ARMV8_V9
, "v9", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1307 { ARMV8_V10
, "v10", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1308 { ARMV8_V11
, "v11", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1309 { ARMV8_V12
, "v12", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1310 { ARMV8_V13
, "v13", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1311 { ARMV8_V14
, "v14", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1312 { ARMV8_V15
, "v15", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1313 { ARMV8_V16
, "v16", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1314 { ARMV8_V17
, "v17", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1315 { ARMV8_V18
, "v18", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1316 { ARMV8_V19
, "v19", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1317 { ARMV8_V20
, "v20", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1318 { ARMV8_V21
, "v21", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1319 { ARMV8_V22
, "v22", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1320 { ARMV8_V23
, "v23", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1321 { ARMV8_V24
, "v24", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1322 { ARMV8_V25
, "v25", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1323 { ARMV8_V26
, "v26", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1324 { ARMV8_V27
, "v27", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1325 { ARMV8_V28
, "v28", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1326 { ARMV8_V29
, "v29", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1327 { ARMV8_V30
, "v30", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1328 { ARMV8_V31
, "v31", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1329 { ARMV8_FPSR
, "fpsr", 32, ARM_MODE_ANY
, REG_TYPE_UINT32
, "simdfp", "org.gnu.gdb.aarch64.fpu", NULL
},
1330 { ARMV8_FPCR
, "fpcr", 32, ARM_MODE_ANY
, REG_TYPE_UINT32
, "simdfp", "org.gnu.gdb.aarch64.fpu", NULL
},
1332 { ARMV8_ELR_EL1
, "ELR_EL1", 64, ARMV8_64_EL1H
, REG_TYPE_CODE_PTR
, "banked", "net.sourceforge.openocd.banked",
1334 { ARMV8_ESR_EL1
, "ESR_EL1", 32, ARMV8_64_EL1H
, REG_TYPE_UINT32
, "banked", "net.sourceforge.openocd.banked",
1336 { ARMV8_SPSR_EL1
, "SPSR_EL1", 32, ARMV8_64_EL1H
, REG_TYPE_UINT32
, "banked", "net.sourceforge.openocd.banked",
1339 { ARMV8_ELR_EL2
, "ELR_EL2", 64, ARMV8_64_EL2H
, REG_TYPE_CODE_PTR
, "banked", "net.sourceforge.openocd.banked",
1341 { ARMV8_ESR_EL2
, "ESR_EL2", 32, ARMV8_64_EL2H
, REG_TYPE_UINT32
, "banked", "net.sourceforge.openocd.banked",
1343 { ARMV8_SPSR_EL2
, "SPSR_EL2", 32, ARMV8_64_EL2H
, REG_TYPE_UINT32
, "banked", "net.sourceforge.openocd.banked",
1346 { ARMV8_ELR_EL3
, "ELR_EL3", 64, ARMV8_64_EL3H
, REG_TYPE_CODE_PTR
, "banked", "net.sourceforge.openocd.banked",
1348 { ARMV8_ESR_EL3
, "ESR_EL3", 32, ARMV8_64_EL3H
, REG_TYPE_UINT32
, "banked", "net.sourceforge.openocd.banked",
1350 { ARMV8_SPSR_EL3
, "SPSR_EL3", 32, ARMV8_64_EL3H
, REG_TYPE_UINT32
, "banked", "net.sourceforge.openocd.banked",
1354 static const struct {
1362 const char *feature
;
1363 } armv8_regs32
[] = {
1364 { ARMV8_R0
, 0, "r0", 32, ARM_MODE_ANY
, REG_TYPE_UINT32
, "general", "org.gnu.gdb.arm.core" },
1365 { ARMV8_R1
, 0, "r1", 32, ARM_MODE_ANY
, REG_TYPE_UINT32
, "general", "org.gnu.gdb.arm.core" },
1366 { ARMV8_R2
, 0, "r2", 32, ARM_MODE_ANY
, REG_TYPE_UINT32
, "general", "org.gnu.gdb.arm.core" },
1367 { ARMV8_R3
, 0, "r3", 32, ARM_MODE_ANY
, REG_TYPE_UINT32
, "general", "org.gnu.gdb.arm.core" },
1368 { ARMV8_R4
, 0, "r4", 32, ARM_MODE_ANY
, REG_TYPE_UINT32
, "general", "org.gnu.gdb.arm.core" },
1369 { ARMV8_R5
, 0, "r5", 32, ARM_MODE_ANY
, REG_TYPE_UINT32
, "general", "org.gnu.gdb.arm.core" },
1370 { ARMV8_R6
, 0, "r6", 32, ARM_MODE_ANY
, REG_TYPE_UINT32
, "general", "org.gnu.gdb.arm.core" },
1371 { ARMV8_R7
, 0, "r7", 32, ARM_MODE_ANY
, REG_TYPE_UINT32
, "general", "org.gnu.gdb.arm.core" },
1372 { ARMV8_R8
, 0, "r8", 32, ARM_MODE_ANY
, REG_TYPE_UINT32
, "general", "org.gnu.gdb.arm.core" },
1373 { ARMV8_R9
, 0, "r9", 32, ARM_MODE_ANY
, REG_TYPE_UINT32
, "general", "org.gnu.gdb.arm.core" },
1374 { ARMV8_R10
, 0, "r10", 32, ARM_MODE_ANY
, REG_TYPE_UINT32
, "general", "org.gnu.gdb.arm.core" },
1375 { ARMV8_R11
, 0, "r11", 32, ARM_MODE_ANY
, REG_TYPE_UINT32
, "general", "org.gnu.gdb.arm.core" },
1376 { ARMV8_R12
, 0, "r12", 32, ARM_MODE_ANY
, REG_TYPE_UINT32
, "general", "org.gnu.gdb.arm.core" },
1377 { ARMV8_R13
, 0, "sp", 32, ARM_MODE_ANY
, REG_TYPE_DATA_PTR
, "general", "org.gnu.gdb.arm.core" },
1378 { ARMV8_R14
, 0, "lr", 32, ARM_MODE_ANY
, REG_TYPE_CODE_PTR
, "general", "org.gnu.gdb.arm.core" },
1379 { ARMV8_PC
, 0, "pc", 32, ARM_MODE_ANY
, REG_TYPE_CODE_PTR
, "general", "org.gnu.gdb.arm.core" },
1380 { ARMV8_xPSR
, 0, "cpsr", 32, ARM_MODE_ANY
, REG_TYPE_UINT32
, "general", "org.gnu.gdb.arm.core" },
1381 { ARMV8_V0
, 0, "d0", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1382 { ARMV8_V0
, 8, "d1", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1383 { ARMV8_V1
, 0, "d2", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1384 { ARMV8_V1
, 8, "d3", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1385 { ARMV8_V2
, 0, "d4", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1386 { ARMV8_V2
, 8, "d5", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1387 { ARMV8_V3
, 0, "d6", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1388 { ARMV8_V3
, 8, "d7", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1389 { ARMV8_V4
, 0, "d8", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1390 { ARMV8_V4
, 8, "d9", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1391 { ARMV8_V5
, 0, "d10", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1392 { ARMV8_V5
, 8, "d11", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1393 { ARMV8_V6
, 0, "d12", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1394 { ARMV8_V6
, 8, "d13", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1395 { ARMV8_V7
, 0, "d14", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1396 { ARMV8_V7
, 8, "d15", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1397 { ARMV8_V8
, 0, "d16", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1398 { ARMV8_V8
, 8, "d17", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1399 { ARMV8_V9
, 0, "d18", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1400 { ARMV8_V9
, 8, "d19", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1401 { ARMV8_V10
, 0, "d20", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1402 { ARMV8_V10
, 8, "d21", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1403 { ARMV8_V11
, 0, "d22", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1404 { ARMV8_V11
, 8, "d23", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1405 { ARMV8_V12
, 0, "d24", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1406 { ARMV8_V12
, 8, "d25", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1407 { ARMV8_V13
, 0, "d26", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1408 { ARMV8_V13
, 8, "d27", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1409 { ARMV8_V14
, 0, "d28", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1410 { ARMV8_V14
, 8, "d29", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1411 { ARMV8_V15
, 0, "d30", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1412 { ARMV8_V15
, 8, "d31", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1413 { ARMV8_FPSR
, 0, "fpscr", 32, ARM_MODE_ANY
, REG_TYPE_UINT32
, "float", "org.gnu.gdb.arm.vfp"},
1416 #define ARMV8_NUM_REGS ARRAY_SIZE(armv8_regs)
1417 #define ARMV8_NUM_REGS32 ARRAY_SIZE(armv8_regs32)
1419 static int armv8_get_core_reg(struct reg
*reg
)
1421 struct arm_reg
*armv8_reg
= reg
->arch_info
;
1422 struct target
*target
= armv8_reg
->target
;
1423 struct arm
*arm
= target_to_arm(target
);
1425 if (target
->state
!= TARGET_HALTED
)
1426 return ERROR_TARGET_NOT_HALTED
;
1428 return arm
->read_core_reg(target
, reg
, armv8_reg
->num
, arm
->core_mode
);
1431 static int armv8_set_core_reg(struct reg
*reg
, uint8_t *buf
)
1433 struct arm_reg
*armv8_reg
= reg
->arch_info
;
1434 struct target
*target
= armv8_reg
->target
;
1435 struct arm
*arm
= target_to_arm(target
);
1436 uint64_t value
= buf_get_u64(buf
, 0, reg
->size
);
1438 if (target
->state
!= TARGET_HALTED
)
1439 return ERROR_TARGET_NOT_HALTED
;
1441 if (reg
->size
<= 64) {
1442 if (reg
== arm
->cpsr
)
1443 armv8_set_cpsr(arm
, (uint32_t)value
);
1445 buf_set_u64(reg
->value
, 0, reg
->size
, value
);
1448 } else if (reg
->size
<= 128) {
1449 uint64_t hvalue
= buf_get_u64(buf
+ 8, 0, reg
->size
- 64);
1451 buf_set_u64(reg
->value
, 0, 64, value
);
1452 buf_set_u64(reg
->value
+ 8, 0, reg
->size
- 64, hvalue
);
1461 static const struct reg_arch_type armv8_reg_type
= {
1462 .get
= armv8_get_core_reg
,
1463 .set
= armv8_set_core_reg
,
1466 static int armv8_get_core_reg32(struct reg
*reg
)
1468 struct arm_reg
*armv8_reg
= reg
->arch_info
;
1469 struct target
*target
= armv8_reg
->target
;
1470 struct arm
*arm
= target_to_arm(target
);
1471 struct reg_cache
*cache
= arm
->core_cache
;
1475 /* get the corresponding Aarch64 register */
1476 reg64
= cache
->reg_list
+ armv8_reg
->num
;
1482 retval
= arm
->read_core_reg(target
, reg64
, armv8_reg
->num
, arm
->core_mode
);
1483 if (retval
== ERROR_OK
)
1484 reg
->valid
= reg64
->valid
;
1489 static int armv8_set_core_reg32(struct reg
*reg
, uint8_t *buf
)
1491 struct arm_reg
*armv8_reg
= reg
->arch_info
;
1492 struct target
*target
= armv8_reg
->target
;
1493 struct arm
*arm
= target_to_arm(target
);
1494 struct reg_cache
*cache
= arm
->core_cache
;
1495 struct reg
*reg64
= cache
->reg_list
+ armv8_reg
->num
;
1496 uint32_t value
= buf_get_u32(buf
, 0, 32);
1498 if (reg64
== arm
->cpsr
) {
1499 armv8_set_cpsr(arm
, value
);
1501 if (reg
->size
<= 32)
1502 buf_set_u32(reg
->value
, 0, 32, value
);
1503 else if (reg
->size
<= 64) {
1504 uint64_t value64
= buf_get_u64(buf
, 0, 64);
1505 buf_set_u64(reg
->value
, 0, 64, value64
);
1516 static const struct reg_arch_type armv8_reg32_type
= {
1517 .get
= armv8_get_core_reg32
,
1518 .set
= armv8_set_core_reg32
,
1521 /** Builds cache of architecturally defined registers. */
1522 struct reg_cache
*armv8_build_reg_cache(struct target
*target
)
1524 struct armv8_common
*armv8
= target_to_armv8(target
);
1525 struct arm
*arm
= &armv8
->arm
;
1526 int num_regs
= ARMV8_NUM_REGS
;
1527 int num_regs32
= ARMV8_NUM_REGS32
;
1528 struct reg_cache
**cache_p
= register_get_last_cache_p(&target
->reg_cache
);
1529 struct reg_cache
*cache
= malloc(sizeof(struct reg_cache
));
1530 struct reg_cache
*cache32
= malloc(sizeof(struct reg_cache
));
1531 struct reg
*reg_list
= calloc(num_regs
, sizeof(struct reg
));
1532 struct reg
*reg_list32
= calloc(num_regs32
, sizeof(struct reg
));
1533 struct arm_reg
*arch_info
= calloc(num_regs
, sizeof(struct arm_reg
));
1534 struct reg_feature
*feature
;
1537 /* Build the process context cache */
1538 cache
->name
= "Aarch64 registers";
1539 cache
->next
= cache32
;
1540 cache
->reg_list
= reg_list
;
1541 cache
->num_regs
= num_regs
;
1543 for (i
= 0; i
< num_regs
; i
++) {
1544 arch_info
[i
].num
= armv8_regs
[i
].id
;
1545 arch_info
[i
].mode
= armv8_regs
[i
].mode
;
1546 arch_info
[i
].target
= target
;
1547 arch_info
[i
].arm
= arm
;
1549 reg_list
[i
].name
= armv8_regs
[i
].name
;
1550 reg_list
[i
].size
= armv8_regs
[i
].bits
;
1551 reg_list
[i
].value
= &arch_info
[i
].value
[0];
1552 reg_list
[i
].type
= &armv8_reg_type
;
1553 reg_list
[i
].arch_info
= &arch_info
[i
];
1555 reg_list
[i
].group
= armv8_regs
[i
].group
;
1556 reg_list
[i
].number
= i
;
1557 reg_list
[i
].exist
= true;
1558 reg_list
[i
].caller_save
= true; /* gdb defaults to true */
1560 feature
= calloc(1, sizeof(struct reg_feature
));
1562 feature
->name
= armv8_regs
[i
].feature
;
1563 reg_list
[i
].feature
= feature
;
1565 LOG_ERROR("unable to allocate feature list");
1567 reg_list
[i
].reg_data_type
= calloc(1, sizeof(struct reg_data_type
));
1568 if (reg_list
[i
].reg_data_type
) {
1569 if (armv8_regs
[i
].data_type
== NULL
)
1570 reg_list
[i
].reg_data_type
->type
= armv8_regs
[i
].type
;
1572 *reg_list
[i
].reg_data_type
= *armv8_regs
[i
].data_type
;
1574 LOG_ERROR("unable to allocate reg type list");
1577 arm
->cpsr
= reg_list
+ ARMV8_xPSR
;
1578 arm
->pc
= reg_list
+ ARMV8_PC
;
1579 arm
->core_cache
= cache
;
1581 /* shadow cache for ARM mode registers */
1582 cache32
->name
= "Aarch32 registers";
1583 cache32
->next
= NULL
;
1584 cache32
->reg_list
= reg_list32
;
1585 cache32
->num_regs
= num_regs32
;
1587 for (i
= 0; i
< num_regs32
; i
++) {
1588 reg_list32
[i
].name
= armv8_regs32
[i
].name
;
1589 reg_list32
[i
].size
= armv8_regs32
[i
].bits
;
1590 reg_list32
[i
].value
= &arch_info
[armv8_regs32
[i
].id
].value
[armv8_regs32
[i
].mapping
];
1591 reg_list32
[i
].type
= &armv8_reg32_type
;
1592 reg_list32
[i
].arch_info
= &arch_info
[armv8_regs32
[i
].id
];
1593 reg_list32
[i
].group
= armv8_regs32
[i
].group
;
1594 reg_list32
[i
].number
= i
;
1595 reg_list32
[i
].exist
= true;
1596 reg_list32
[i
].caller_save
= true;
1598 feature
= calloc(1, sizeof(struct reg_feature
));
1600 feature
->name
= armv8_regs32
[i
].feature
;
1601 reg_list32
[i
].feature
= feature
;
1603 LOG_ERROR("unable to allocate feature list");
1605 reg_list32
[i
].reg_data_type
= calloc(1, sizeof(struct reg_data_type
));
1606 if (reg_list32
[i
].reg_data_type
)
1607 reg_list32
[i
].reg_data_type
->type
= armv8_regs32
[i
].type
;
1609 LOG_ERROR("unable to allocate reg type list");
1616 struct reg
*armv8_reg_current(struct arm
*arm
, unsigned regnum
)
1620 if (regnum
> (ARMV8_LAST_REG
- 1))
1623 r
= arm
->core_cache
->reg_list
+ regnum
;
1627 static void armv8_free_cache(struct reg_cache
*cache
, bool regs32
)
1635 for (i
= 0; i
< cache
->num_regs
; i
++) {
1636 reg
= &cache
->reg_list
[i
];
1639 free(reg
->reg_data_type
);
1643 free(cache
->reg_list
[0].arch_info
);
1644 free(cache
->reg_list
);
1648 void armv8_free_reg_cache(struct target
*target
)
1650 struct armv8_common
*armv8
= target_to_armv8(target
);
1651 struct arm
*arm
= &armv8
->arm
;
1652 struct reg_cache
*cache
= NULL
, *cache32
= NULL
;
1654 cache
= arm
->core_cache
;
1656 cache32
= cache
->next
;
1657 armv8_free_cache(cache32
, true);
1658 armv8_free_cache(cache
, false);
1659 arm
->core_cache
= NULL
;
1662 const struct command_registration armv8_command_handlers
[] = {
1663 COMMAND_REGISTRATION_DONE
1666 int armv8_get_gdb_reg_list(struct target
*target
,
1667 struct reg
**reg_list
[], int *reg_list_size
,
1668 enum target_register_class reg_class
)
1670 struct arm
*arm
= target_to_arm(target
);
1673 if (arm
->core_state
== ARM_STATE_AARCH64
) {
1675 LOG_DEBUG("Creating Aarch64 register list for target %s", target_name(target
));
1677 switch (reg_class
) {
1678 case REG_CLASS_GENERAL
:
1679 *reg_list_size
= ARMV8_V0
;
1680 *reg_list
= malloc(sizeof(struct reg
*) * (*reg_list_size
));
1682 for (i
= 0; i
< *reg_list_size
; i
++)
1683 (*reg_list
)[i
] = armv8_reg_current(arm
, i
);
1687 *reg_list_size
= ARMV8_LAST_REG
;
1688 *reg_list
= malloc(sizeof(struct reg
*) * (*reg_list_size
));
1690 for (i
= 0; i
< *reg_list_size
; i
++)
1691 (*reg_list
)[i
] = armv8_reg_current(arm
, i
);
1696 LOG_ERROR("not a valid register class type in query.");
1700 struct reg_cache
*cache32
= arm
->core_cache
->next
;
1702 LOG_DEBUG("Creating Aarch32 register list for target %s", target_name(target
));
1704 switch (reg_class
) {
1705 case REG_CLASS_GENERAL
:
1706 *reg_list_size
= ARMV8_R14
+ 3;
1707 *reg_list
= malloc(sizeof(struct reg
*) * (*reg_list_size
));
1709 for (i
= 0; i
< *reg_list_size
; i
++)
1710 (*reg_list
)[i
] = cache32
->reg_list
+ i
;
1714 *reg_list_size
= cache32
->num_regs
;
1715 *reg_list
= malloc(sizeof(struct reg
*) * (*reg_list_size
));
1717 for (i
= 0; i
< *reg_list_size
; i
++)
1718 (*reg_list
)[i
] = cache32
->reg_list
+ i
;
1722 LOG_ERROR("not a valid register class type in query.");
1728 int armv8_set_dbgreg_bits(struct armv8_common
*armv8
, unsigned int reg
, unsigned long mask
, unsigned long value
)
1733 int retval
= mem_ap_read_atomic_u32(armv8
->debug_ap
,
1734 armv8
->debug_base
+ reg
, &tmp
);
1735 if (ERROR_OK
!= retval
)
1738 /* clear bitfield */
1741 tmp
|= value
& mask
;
1743 /* write new value */
1744 retval
= mem_ap_write_atomic_u32(armv8
->debug_ap
,
1745 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)