1 /***************************************************************************
2 * Copyright (C) 2015 by David Ung *
4 * This program is free software; you can redistribute it and/or modify *
5 * it under the terms of the GNU General Public License as published by *
6 * the Free Software Foundation; either version 2 of the License, or *
7 * (at your option) any later version. *
9 * This program is distributed in the hope that it will be useful, *
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
12 * GNU General Public License for more details. *
14 * You should have received a copy of the GNU General Public License *
15 * along with this program; if not, write to the *
16 * Free Software Foundation, Inc., *
17 ***************************************************************************/
23 #include <helper/replacements.h>
26 #include "arm_disassembler.h"
29 #include <helper/binarybuffer.h>
30 #include <helper/command.h>
36 #include "armv8_opcodes.h"
38 #include "target_type.h"
40 static const char * const armv8_state_strings
[] = {
41 "AArch32", "Thumb", "Jazelle", "ThumbEE", "AArch64",
47 } armv8_mode_data
[] = {
102 /** Map PSR mode bits to the name of an ARM processor operating mode. */
103 const char *armv8_mode_name(unsigned psr_mode
)
105 for (unsigned i
= 0; i
< ARRAY_SIZE(armv8_mode_data
); i
++) {
106 if (armv8_mode_data
[i
].psr
== psr_mode
)
107 return armv8_mode_data
[i
].name
;
109 LOG_ERROR("unrecognized psr mode: %#02x", psr_mode
);
110 return "UNRECOGNIZED";
113 static int armv8_read_reg(struct armv8_common
*armv8
, int regnum
, uint64_t *regval
)
115 struct arm_dpm
*dpm
= &armv8
->dpm
;
122 retval
= dpm
->instr_read_data_dcc_64(dpm
,
123 ARMV8_MSR_GP(SYSTEM_DBG_DBGDTR_EL0
, regnum
), &value_64
);
126 retval
= dpm
->instr_read_data_r0_64(dpm
,
127 ARMV8_MOVFSP_64(0), &value_64
);
130 retval
= dpm
->instr_read_data_r0_64(dpm
,
131 ARMV8_MRS_DLR(0), &value_64
);
134 retval
= dpm
->instr_read_data_r0(dpm
,
135 ARMV8_MRS_DSPSR(0), &value
);
139 retval
= dpm
->instr_read_data_r0(dpm
,
140 ARMV8_MRS_FPSR(0), &value
);
144 retval
= dpm
->instr_read_data_r0(dpm
,
145 ARMV8_MRS_FPCR(0), &value
);
149 retval
= dpm
->instr_read_data_r0_64(dpm
,
150 ARMV8_MRS(SYSTEM_ELR_EL1
, 0), &value_64
);
153 retval
= dpm
->instr_read_data_r0_64(dpm
,
154 ARMV8_MRS(SYSTEM_ELR_EL2
, 0), &value_64
);
157 retval
= dpm
->instr_read_data_r0_64(dpm
,
158 ARMV8_MRS(SYSTEM_ELR_EL3
, 0), &value_64
);
161 retval
= dpm
->instr_read_data_r0(dpm
,
162 ARMV8_MRS(SYSTEM_ESR_EL1
, 0), &value
);
166 retval
= dpm
->instr_read_data_r0(dpm
,
167 ARMV8_MRS(SYSTEM_ESR_EL2
, 0), &value
);
171 retval
= dpm
->instr_read_data_r0(dpm
,
172 ARMV8_MRS(SYSTEM_ESR_EL3
, 0), &value
);
176 retval
= dpm
->instr_read_data_r0(dpm
,
177 ARMV8_MRS(SYSTEM_SPSR_EL1
, 0), &value
);
181 retval
= dpm
->instr_read_data_r0(dpm
,
182 ARMV8_MRS(SYSTEM_SPSR_EL2
, 0), &value
);
186 retval
= dpm
->instr_read_data_r0(dpm
,
187 ARMV8_MRS(SYSTEM_SPSR_EL3
, 0), &value
);
195 if (retval
== ERROR_OK
&& regval
!= NULL
)
203 static int armv8_read_reg_simdfp_aarch64(struct armv8_common
*armv8
, int regnum
, uint64_t *lvalue
, uint64_t *hvalue
)
205 int retval
= ERROR_FAIL
;
206 struct arm_dpm
*dpm
= &armv8
->dpm
;
209 case ARMV8_V0
... ARMV8_V31
:
210 retval
= dpm
->instr_read_data_r0_64(dpm
,
211 ARMV8_MOV_GPR_VFP(0, (regnum
- ARMV8_V0
), 1), hvalue
);
212 if (retval
!= ERROR_OK
)
214 retval
= dpm
->instr_read_data_r0_64(dpm
,
215 ARMV8_MOV_GPR_VFP(0, (regnum
- ARMV8_V0
), 0), lvalue
);
226 static int armv8_write_reg(struct armv8_common
*armv8
, int regnum
, uint64_t value_64
)
228 struct arm_dpm
*dpm
= &armv8
->dpm
;
234 retval
= dpm
->instr_write_data_dcc_64(dpm
,
235 ARMV8_MRS(SYSTEM_DBG_DBGDTR_EL0
, regnum
),
239 retval
= dpm
->instr_write_data_r0_64(dpm
,
244 retval
= dpm
->instr_write_data_r0_64(dpm
,
250 retval
= dpm
->instr_write_data_r0(dpm
,
256 retval
= dpm
->instr_write_data_r0(dpm
,
262 retval
= dpm
->instr_write_data_r0(dpm
,
266 /* registers clobbered by taking exception in debug state */
268 retval
= dpm
->instr_write_data_r0_64(dpm
,
269 ARMV8_MSR_GP(SYSTEM_ELR_EL1
, 0), value_64
);
272 retval
= dpm
->instr_write_data_r0_64(dpm
,
273 ARMV8_MSR_GP(SYSTEM_ELR_EL2
, 0), value_64
);
276 retval
= dpm
->instr_write_data_r0_64(dpm
,
277 ARMV8_MSR_GP(SYSTEM_ELR_EL3
, 0), value_64
);
281 retval
= dpm
->instr_write_data_r0(dpm
,
282 ARMV8_MSR_GP(SYSTEM_ESR_EL1
, 0), value
);
286 retval
= dpm
->instr_write_data_r0(dpm
,
287 ARMV8_MSR_GP(SYSTEM_ESR_EL2
, 0), value
);
291 retval
= dpm
->instr_write_data_r0(dpm
,
292 ARMV8_MSR_GP(SYSTEM_ESR_EL3
, 0), value
);
296 retval
= dpm
->instr_write_data_r0(dpm
,
297 ARMV8_MSR_GP(SYSTEM_SPSR_EL1
, 0), value
);
301 retval
= dpm
->instr_write_data_r0(dpm
,
302 ARMV8_MSR_GP(SYSTEM_SPSR_EL2
, 0), value
);
306 retval
= dpm
->instr_write_data_r0(dpm
,
307 ARMV8_MSR_GP(SYSTEM_SPSR_EL3
, 0), value
);
317 static int armv8_write_reg_simdfp_aarch64(struct armv8_common
*armv8
, int regnum
, uint64_t lvalue
, uint64_t hvalue
)
319 int retval
= ERROR_FAIL
;
320 struct arm_dpm
*dpm
= &armv8
->dpm
;
323 case ARMV8_V0
... ARMV8_V31
:
324 retval
= dpm
->instr_write_data_r0_64(dpm
,
325 ARMV8_MOV_VFP_GPR((regnum
- ARMV8_V0
), 0, 1), hvalue
);
326 if (retval
!= ERROR_OK
)
328 retval
= dpm
->instr_write_data_r0_64(dpm
,
329 ARMV8_MOV_VFP_GPR((regnum
- ARMV8_V0
), 0, 0), lvalue
);
340 static int armv8_read_reg32(struct armv8_common
*armv8
, int regnum
, uint64_t *regval
)
342 struct arm_dpm
*dpm
= &armv8
->dpm
;
347 case ARMV8_R0
... ARMV8_R14
:
348 /* return via DCC: "MCR p14, 0, Rnum, c0, c5, 0" */
349 retval
= dpm
->instr_read_data_dcc(dpm
,
350 ARMV4_5_MCR(14, 0, regnum
, 0, 5, 0),
354 retval
= dpm
->instr_read_data_dcc(dpm
,
355 ARMV4_5_MCR(14, 0, 13, 0, 5, 0),
359 retval
= dpm
->instr_read_data_r0(dpm
,
364 retval
= dpm
->instr_read_data_r0(dpm
,
368 case ARMV8_ELR_EL1
: /* mapped to LR_svc */
369 retval
= dpm
->instr_read_data_dcc(dpm
,
370 ARMV4_5_MCR(14, 0, 14, 0, 5, 0),
373 case ARMV8_ELR_EL2
: /* mapped to ELR_hyp */
374 retval
= dpm
->instr_read_data_r0(dpm
,
375 ARMV8_MRS_T1(0, 14, 0, 1),
378 case ARMV8_ELR_EL3
: /* mapped to LR_mon */
379 retval
= dpm
->instr_read_data_dcc(dpm
,
380 ARMV4_5_MCR(14, 0, 14, 0, 5, 0),
383 case ARMV8_ESR_EL1
: /* mapped to DFSR */
384 retval
= dpm
->instr_read_data_r0(dpm
,
385 ARMV4_5_MRC(15, 0, 0, 5, 0, 0),
388 case ARMV8_ESR_EL2
: /* mapped to HSR */
389 retval
= dpm
->instr_read_data_r0(dpm
,
390 ARMV4_5_MRC(15, 4, 0, 5, 2, 0),
393 case ARMV8_ESR_EL3
: /* FIXME: no equivalent in aarch32? */
396 case ARMV8_SPSR_EL1
: /* mapped to SPSR_svc */
397 retval
= dpm
->instr_read_data_r0(dpm
,
398 ARMV8_MRS_xPSR_T1(1, 0),
401 case ARMV8_SPSR_EL2
: /* mapped to SPSR_hyp */
402 retval
= dpm
->instr_read_data_r0(dpm
,
403 ARMV8_MRS_xPSR_T1(1, 0),
406 case ARMV8_SPSR_EL3
: /* mapped to SPSR_mon */
407 retval
= dpm
->instr_read_data_r0(dpm
,
408 ARMV8_MRS_xPSR_T1(1, 0),
412 /* "VMRS r0, FPSCR"; then return via DCC */
413 retval
= dpm
->instr_read_data_r0(dpm
,
414 ARMV4_5_VMRS(0), &value
);
421 if (retval
== ERROR_OK
&& regval
!= NULL
)
427 static int armv8_read_reg_simdfp_aarch32(struct armv8_common
*armv8
, int regnum
, uint64_t *lvalue
, uint64_t *hvalue
)
429 int retval
= ERROR_FAIL
;
430 struct arm_dpm
*dpm
= &armv8
->dpm
;
431 struct reg
*reg_r1
= dpm
->arm
->core_cache
->reg_list
+ ARMV8_R1
;
432 uint32_t value_r0
= 0, value_r1
= 0;
433 unsigned num
= (regnum
- ARMV8_V0
) << 1;
436 case ARMV8_V0
... ARMV8_V15
:
437 /* we are going to write R1, mark it dirty */
438 reg_r1
->dirty
= true;
439 /* move from double word register to r0:r1: "vmov r0, r1, vm"
440 * then read r0 via dcc
442 retval
= dpm
->instr_read_data_r0(dpm
,
443 ARMV4_5_VMOV(1, 1, 0, (num
>> 4), (num
& 0xf)),
445 /* read r1 via dcc */
446 retval
= dpm
->instr_read_data_dcc(dpm
,
447 ARMV4_5_MCR(14, 0, 1, 0, 5, 0),
449 if (retval
== ERROR_OK
) {
451 *lvalue
= ((*lvalue
) << 32) | value_r0
;
456 /* repeat above steps for high 64 bits of V register */
457 retval
= dpm
->instr_read_data_r0(dpm
,
458 ARMV4_5_VMOV(1, 1, 0, (num
>> 4), (num
& 0xf)),
460 retval
= dpm
->instr_read_data_dcc(dpm
,
461 ARMV4_5_MCR(14, 0, 1, 0, 5, 0),
463 if (retval
== ERROR_OK
) {
465 *hvalue
= ((*hvalue
) << 32) | value_r0
;
477 static int armv8_write_reg32(struct armv8_common
*armv8
, int regnum
, uint64_t value
)
479 struct arm_dpm
*dpm
= &armv8
->dpm
;
483 case ARMV8_R0
... ARMV8_R14
:
484 /* load register from DCC: "MRC p14, 0, Rnum, c0, c5, 0" */
485 retval
= dpm
->instr_write_data_dcc(dpm
,
486 ARMV4_5_MRC(14, 0, regnum
, 0, 5, 0), value
);
489 retval
= dpm
->instr_write_data_dcc(dpm
,
490 ARMV4_5_MRC(14, 0, 13, 0, 5, 0), value
);
493 * read r0 from DCC; then "MOV pc, r0" */
494 retval
= dpm
->instr_write_data_r0(dpm
,
495 ARMV8_MCR_DLR(0), value
);
497 case ARMV8_xPSR
: /* CPSR */
498 /* read r0 from DCC, then "MCR r0, DSPSR" */
499 retval
= dpm
->instr_write_data_r0(dpm
,
500 ARMV8_MCR_DSPSR(0), value
);
502 case ARMV8_ELR_EL1
: /* mapped to LR_svc */
503 retval
= dpm
->instr_write_data_dcc(dpm
,
504 ARMV4_5_MRC(14, 0, 14, 0, 5, 0),
507 case ARMV8_ELR_EL2
: /* mapped to ELR_hyp */
508 retval
= dpm
->instr_write_data_r0(dpm
,
509 ARMV8_MSR_GP_T1(0, 14, 0, 1),
512 case ARMV8_ELR_EL3
: /* mapped to LR_mon */
513 retval
= dpm
->instr_write_data_dcc(dpm
,
514 ARMV4_5_MRC(14, 0, 14, 0, 5, 0),
517 case ARMV8_ESR_EL1
: /* mapped to DFSR */
518 retval
= dpm
->instr_write_data_r0(dpm
,
519 ARMV4_5_MCR(15, 0, 0, 5, 0, 0),
522 case ARMV8_ESR_EL2
: /* mapped to HSR */
523 retval
= dpm
->instr_write_data_r0(dpm
,
524 ARMV4_5_MCR(15, 4, 0, 5, 2, 0),
527 case ARMV8_ESR_EL3
: /* FIXME: no equivalent in aarch32? */
530 case ARMV8_SPSR_EL1
: /* mapped to SPSR_svc */
531 retval
= dpm
->instr_write_data_r0(dpm
,
532 ARMV8_MSR_GP_xPSR_T1(1, 0, 15),
535 case ARMV8_SPSR_EL2
: /* mapped to SPSR_hyp */
536 retval
= dpm
->instr_write_data_r0(dpm
,
537 ARMV8_MSR_GP_xPSR_T1(1, 0, 15),
540 case ARMV8_SPSR_EL3
: /* mapped to SPSR_mon */
541 retval
= dpm
->instr_write_data_r0(dpm
,
542 ARMV8_MSR_GP_xPSR_T1(1, 0, 15),
546 /* move to r0 from DCC, then "VMSR FPSCR, r0" */
547 retval
= dpm
->instr_write_data_r0(dpm
,
548 ARMV4_5_VMSR(0), value
);
559 static int armv8_write_reg_simdfp_aarch32(struct armv8_common
*armv8
, int regnum
, uint64_t lvalue
, uint64_t hvalue
)
561 int retval
= ERROR_FAIL
;
562 struct arm_dpm
*dpm
= &armv8
->dpm
;
563 struct reg
*reg_r1
= dpm
->arm
->core_cache
->reg_list
+ ARMV8_R1
;
564 uint32_t value_r0
= 0, value_r1
= 0;
565 unsigned num
= (regnum
- ARMV8_V0
) << 1;
568 case ARMV8_V0
... ARMV8_V15
:
569 /* we are going to write R1, mark it dirty */
570 reg_r1
->dirty
= true;
571 value_r1
= lvalue
>> 32;
572 value_r0
= lvalue
& 0xFFFFFFFF;
573 /* write value_r1 to r1 via dcc */
574 retval
= dpm
->instr_write_data_dcc(dpm
,
575 ARMV4_5_MRC(14, 0, 1, 0, 5, 0),
577 /* write value_r0 to r0 via dcc then,
578 * move to double word register from r0:r1: "vmov vm, r0, r1"
580 retval
= dpm
->instr_write_data_r0(dpm
,
581 ARMV4_5_VMOV(0, 1, 0, (num
>> 4), (num
& 0xf)),
585 /* repeat above steps for high 64 bits of V register */
586 value_r1
= hvalue
>> 32;
587 value_r0
= hvalue
& 0xFFFFFFFF;
588 retval
= dpm
->instr_write_data_dcc(dpm
,
589 ARMV4_5_MRC(14, 0, 1, 0, 5, 0),
591 retval
= dpm
->instr_write_data_r0(dpm
,
592 ARMV4_5_VMOV(0, 1, 0, (num
>> 4), (num
& 0xf)),
603 void armv8_select_reg_access(struct armv8_common
*armv8
, bool is_aarch64
)
606 armv8
->read_reg_u64
= armv8_read_reg
;
607 armv8
->write_reg_u64
= armv8_write_reg
;
608 armv8
->read_reg_u128
= armv8_read_reg_simdfp_aarch64
;
609 armv8
->write_reg_u128
= armv8_write_reg_simdfp_aarch64
;
612 armv8
->read_reg_u64
= armv8_read_reg32
;
613 armv8
->write_reg_u64
= armv8_write_reg32
;
614 armv8
->read_reg_u128
= armv8_read_reg_simdfp_aarch32
;
615 armv8
->write_reg_u128
= armv8_write_reg_simdfp_aarch32
;
619 /* retrieve core id cluster id */
620 int armv8_read_mpidr(struct armv8_common
*armv8
)
622 int retval
= ERROR_FAIL
;
623 struct arm
*arm
= &armv8
->arm
;
624 struct arm_dpm
*dpm
= armv8
->arm
.dpm
;
627 retval
= dpm
->prepare(dpm
);
628 if (retval
!= ERROR_OK
)
631 /* check if we're in an unprivileged mode */
632 if (armv8_curel_from_core_mode(arm
->core_mode
) < SYSTEM_CUREL_EL1
) {
633 retval
= armv8_dpm_modeswitch(dpm
, ARMV8_64_EL1H
);
634 if (retval
!= ERROR_OK
)
638 retval
= dpm
->instr_read_data_r0(dpm
, armv8_opcode(armv8
, READ_REG_MPIDR
), &mpidr
);
639 if (retval
!= ERROR_OK
)
642 armv8
->multi_processor_system
= (mpidr
>> 30) & 1;
643 armv8
->cluster_id
= (mpidr
>> 8) & 0xf;
644 armv8
->cpu_id
= mpidr
& 0x3;
645 LOG_INFO("%s cluster %x core %x %s", target_name(armv8
->arm
.target
),
648 armv8
->multi_processor_system
== 0 ? "multi core" : "single core");
650 LOG_ERROR("mpidr not in multiprocessor format");
653 armv8_dpm_modeswitch(dpm
, ARM_MODE_ANY
);
659 * Configures host-side ARM records to reflect the specified CPSR.
660 * Later, code can use arm_reg_current() to map register numbers
661 * according to how they are exposed by this mode.
663 void armv8_set_cpsr(struct arm
*arm
, uint32_t cpsr
)
665 uint32_t mode
= cpsr
& 0x1F;
667 /* NOTE: this may be called very early, before the register
668 * cache is set up. We can't defend against many errors, in
669 * particular against CPSRs that aren't valid *here* ...
672 buf_set_u32(arm
->cpsr
->value
, 0, 32, cpsr
);
673 arm
->cpsr
->valid
= 1;
674 arm
->cpsr
->dirty
= 0;
677 /* Older ARMs won't have the J bit */
678 enum arm_state state
= 0xFF;
680 if ((cpsr
& 0x10) != 0) {
682 if (cpsr
& (1 << 5)) { /* T */
683 if (cpsr
& (1 << 24)) { /* J */
684 LOG_WARNING("ThumbEE -- incomplete support");
685 state
= ARM_STATE_THUMB_EE
;
687 state
= ARM_STATE_THUMB
;
689 if (cpsr
& (1 << 24)) { /* J */
690 LOG_ERROR("Jazelle state handling is BROKEN!");
691 state
= ARM_STATE_JAZELLE
;
693 state
= ARM_STATE_ARM
;
697 state
= ARM_STATE_AARCH64
;
700 arm
->core_state
= state
;
701 arm
->core_mode
= mode
;
703 LOG_DEBUG("set CPSR %#8.8x: %s mode, %s state", (unsigned) cpsr
,
704 armv8_mode_name(arm
->core_mode
),
705 armv8_state_strings
[arm
->core_state
]);
708 static void armv8_show_fault_registers32(struct armv8_common
*armv8
)
710 uint32_t dfsr
, ifsr
, dfar
, ifar
;
711 struct arm_dpm
*dpm
= armv8
->arm
.dpm
;
714 retval
= dpm
->prepare(dpm
);
715 if (retval
!= ERROR_OK
)
718 /* ARMV4_5_MRC(cpnum, op1, r0, CRn, CRm, op2) */
720 /* c5/c0 - {data, instruction} fault status registers */
721 retval
= dpm
->instr_read_data_r0(dpm
,
722 ARMV4_5_MRC(15, 0, 0, 5, 0, 0),
724 if (retval
!= ERROR_OK
)
727 retval
= dpm
->instr_read_data_r0(dpm
,
728 ARMV4_5_MRC(15, 0, 0, 5, 0, 1),
730 if (retval
!= ERROR_OK
)
733 /* c6/c0 - {data, instruction} fault address registers */
734 retval
= dpm
->instr_read_data_r0(dpm
,
735 ARMV4_5_MRC(15, 0, 0, 6, 0, 0),
737 if (retval
!= ERROR_OK
)
740 retval
= dpm
->instr_read_data_r0(dpm
,
741 ARMV4_5_MRC(15, 0, 0, 6, 0, 2),
743 if (retval
!= ERROR_OK
)
746 LOG_USER("Data fault registers DFSR: %8.8" PRIx32
747 ", DFAR: %8.8" PRIx32
, dfsr
, dfar
);
748 LOG_USER("Instruction fault registers IFSR: %8.8" PRIx32
749 ", IFAR: %8.8" PRIx32
, ifsr
, ifar
);
752 /* (void) */ dpm
->finish(dpm
);
755 static __attribute__((unused
)) void armv8_show_fault_registers(struct target
*target
)
757 struct armv8_common
*armv8
= target_to_armv8(target
);
759 if (armv8
->arm
.core_state
!= ARM_STATE_AARCH64
)
760 armv8_show_fault_registers32(armv8
);
763 static uint8_t armv8_pa_size(uint32_t ps
)
786 LOG_INFO("Unknow physicall address size");
792 static __attribute__((unused
)) int armv8_read_ttbcr32(struct target
*target
)
794 struct armv8_common
*armv8
= target_to_armv8(target
);
795 struct arm_dpm
*dpm
= armv8
->arm
.dpm
;
796 uint32_t ttbcr
, ttbcr_n
;
797 int retval
= dpm
->prepare(dpm
);
798 if (retval
!= ERROR_OK
)
800 /* MRC p15,0,<Rt>,c2,c0,2 ; Read CP15 Translation Table Base Control Register*/
801 retval
= dpm
->instr_read_data_r0(dpm
,
802 ARMV4_5_MRC(15, 0, 0, 2, 0, 2),
804 if (retval
!= ERROR_OK
)
807 LOG_DEBUG("ttbcr %" PRIx32
, ttbcr
);
809 ttbcr_n
= ttbcr
& 0x7;
810 armv8
->armv8_mmu
.ttbcr
= ttbcr
;
813 * ARM Architecture Reference Manual (ARMv7-A and ARMv7-Redition),
814 * document # ARM DDI 0406C
816 armv8
->armv8_mmu
.ttbr_range
[0] = 0xffffffff >> ttbcr_n
;
817 armv8
->armv8_mmu
.ttbr_range
[1] = 0xffffffff;
818 armv8
->armv8_mmu
.ttbr_mask
[0] = 0xffffffff << (14 - ttbcr_n
);
819 armv8
->armv8_mmu
.ttbr_mask
[1] = 0xffffffff << 14;
821 LOG_DEBUG("ttbr1 %s, ttbr0_mask %" PRIx32
" ttbr1_mask %" PRIx32
,
822 (ttbcr_n
!= 0) ? "used" : "not used",
823 armv8
->armv8_mmu
.ttbr_mask
[0],
824 armv8
->armv8_mmu
.ttbr_mask
[1]);
831 static __attribute__((unused
)) int armv8_read_ttbcr(struct target
*target
)
833 struct armv8_common
*armv8
= target_to_armv8(target
);
834 struct arm_dpm
*dpm
= armv8
->arm
.dpm
;
835 struct arm
*arm
= &armv8
->arm
;
839 int retval
= dpm
->prepare(dpm
);
840 if (retval
!= ERROR_OK
)
843 /* claaer ttrr1_used and ttbr0_mask */
844 memset(&armv8
->armv8_mmu
.ttbr1_used
, 0, sizeof(armv8
->armv8_mmu
.ttbr1_used
));
845 memset(&armv8
->armv8_mmu
.ttbr0_mask
, 0, sizeof(armv8
->armv8_mmu
.ttbr0_mask
));
847 switch (armv8_curel_from_core_mode(arm
->core_mode
)) {
848 case SYSTEM_CUREL_EL3
:
849 retval
= dpm
->instr_read_data_r0(dpm
,
850 ARMV8_MRS(SYSTEM_TCR_EL3
, 0),
852 retval
+= dpm
->instr_read_data_r0_64(dpm
,
853 ARMV8_MRS(SYSTEM_TTBR0_EL3
, 0),
855 if (retval
!= ERROR_OK
)
857 armv8
->va_size
= 64 - (ttbcr
& 0x3F);
858 armv8
->pa_size
= armv8_pa_size((ttbcr
>> 16) & 7);
859 armv8
->page_size
= (ttbcr
>> 14) & 3;
861 case SYSTEM_CUREL_EL2
:
862 retval
= dpm
->instr_read_data_r0(dpm
,
863 ARMV8_MRS(SYSTEM_TCR_EL2
, 0),
865 retval
+= dpm
->instr_read_data_r0_64(dpm
,
866 ARMV8_MRS(SYSTEM_TTBR0_EL2
, 0),
868 if (retval
!= ERROR_OK
)
870 armv8
->va_size
= 64 - (ttbcr
& 0x3F);
871 armv8
->pa_size
= armv8_pa_size((ttbcr
>> 16) & 7);
872 armv8
->page_size
= (ttbcr
>> 14) & 3;
874 case SYSTEM_CUREL_EL0
:
875 armv8_dpm_modeswitch(dpm
, ARMV8_64_EL1H
);
877 case SYSTEM_CUREL_EL1
:
878 retval
= dpm
->instr_read_data_r0_64(dpm
,
879 ARMV8_MRS(SYSTEM_TCR_EL1
, 0),
881 armv8
->va_size
= 64 - (ttbcr_64
& 0x3F);
882 armv8
->pa_size
= armv8_pa_size((ttbcr_64
>> 32) & 7);
883 armv8
->page_size
= (ttbcr_64
>> 14) & 3;
884 armv8
->armv8_mmu
.ttbr1_used
= (((ttbcr_64
>> 16) & 0x3F) != 0) ? 1 : 0;
885 armv8
->armv8_mmu
.ttbr0_mask
= 0x0000FFFFFFFFFFFF;
886 retval
+= dpm
->instr_read_data_r0_64(dpm
,
887 ARMV8_MRS(SYSTEM_TTBR0_EL1
| (armv8
->armv8_mmu
.ttbr1_used
), 0),
889 if (retval
!= ERROR_OK
)
893 LOG_ERROR("unknow core state");
897 if (retval
!= ERROR_OK
)
900 if (armv8
->armv8_mmu
.ttbr1_used
== 1)
901 LOG_INFO("TTBR0 access above %" PRIx64
, (uint64_t)(armv8
->armv8_mmu
.ttbr0_mask
));
904 armv8_dpm_modeswitch(dpm
, ARM_MODE_ANY
);
909 /* method adapted to cortex A : reused arm v4 v5 method*/
910 int armv8_mmu_translate_va(struct target
*target
, target_addr_t va
, target_addr_t
*val
)
915 /* V8 method VA TO PA */
916 int armv8_mmu_translate_va_pa(struct target
*target
, target_addr_t va
,
917 target_addr_t
*val
, int meminfo
)
919 struct armv8_common
*armv8
= target_to_armv8(target
);
920 struct arm
*arm
= target_to_arm(target
);
921 struct arm_dpm
*dpm
= &armv8
->dpm
;
922 enum arm_mode target_mode
= ARM_MODE_ANY
;
927 static const char * const shared_name
[] = {
928 "Non-", "UNDEFINED ", "Outer ", "Inner "
931 static const char * const secure_name
[] = {
932 "Secure", "Not Secure"
935 retval
= dpm
->prepare(dpm
);
936 if (retval
!= ERROR_OK
)
939 switch (armv8_curel_from_core_mode(arm
->core_mode
)) {
940 case SYSTEM_CUREL_EL0
:
941 instr
= ARMV8_SYS(SYSTEM_ATS12E0R
, 0);
942 /* can only execute instruction at EL2 */
943 target_mode
= ARMV8_64_EL2H
;
945 case SYSTEM_CUREL_EL1
:
946 instr
= ARMV8_SYS(SYSTEM_ATS12E1R
, 0);
947 /* can only execute instruction at EL2 */
948 target_mode
= ARMV8_64_EL2H
;
950 case SYSTEM_CUREL_EL2
:
951 instr
= ARMV8_SYS(SYSTEM_ATS1E2R
, 0);
953 case SYSTEM_CUREL_EL3
:
954 instr
= ARMV8_SYS(SYSTEM_ATS1E3R
, 0);
961 if (target_mode
!= ARM_MODE_ANY
)
962 armv8_dpm_modeswitch(dpm
, target_mode
);
964 /* write VA to R0 and execute translation instruction */
965 retval
= dpm
->instr_write_data_r0_64(dpm
, instr
, (uint64_t)va
);
966 /* read result from PAR_EL1 */
967 if (retval
== ERROR_OK
)
968 retval
= dpm
->instr_read_data_r0_64(dpm
, ARMV8_MRS(SYSTEM_PAR_EL1
, 0), &par
);
970 /* switch back to saved PE mode */
971 if (target_mode
!= ARM_MODE_ANY
)
972 armv8_dpm_modeswitch(dpm
, ARM_MODE_ANY
);
976 if (retval
!= ERROR_OK
)
980 LOG_ERROR("Address translation failed at stage %i, FST=%x, PTW=%i",
981 ((int)(par
>> 9) & 1)+1, (int)(par
>> 1) & 0x3f, (int)(par
>> 8) & 1);
986 *val
= (par
& 0xFFFFFFFFF000UL
) | (va
& 0xFFF);
988 int SH
= (par
>> 7) & 3;
989 int NS
= (par
>> 9) & 1;
990 int ATTR
= (par
>> 56) & 0xFF;
992 char *memtype
= (ATTR
& 0xF0) == 0 ? "Device Memory" : "Normal Memory";
994 LOG_USER("%sshareable, %s",
995 shared_name
[SH
], secure_name
[NS
]);
996 LOG_USER("%s", memtype
);
1003 int armv8_handle_cache_info_command(struct command_context
*cmd_ctx
,
1004 struct armv8_cache_common
*armv8_cache
)
1006 if (armv8_cache
->info
== -1) {
1007 command_print(cmd_ctx
, "cache not yet identified");
1011 if (armv8_cache
->display_cache_info
)
1012 armv8_cache
->display_cache_info(cmd_ctx
, armv8_cache
);
1016 int armv8_init_arch_info(struct target
*target
, struct armv8_common
*armv8
)
1018 struct arm
*arm
= &armv8
->arm
;
1019 arm
->arch_info
= armv8
;
1020 target
->arch_info
= &armv8
->arm
;
1021 /* target is useful in all function arm v4 5 compatible */
1022 armv8
->arm
.target
= target
;
1023 armv8
->arm
.common_magic
= ARM_COMMON_MAGIC
;
1024 armv8
->common_magic
= ARMV8_COMMON_MAGIC
;
1026 armv8
->armv8_mmu
.armv8_cache
.l2_cache
= NULL
;
1027 armv8
->armv8_mmu
.armv8_cache
.info
= -1;
1028 armv8
->armv8_mmu
.armv8_cache
.flush_all_data_cache
= NULL
;
1029 armv8
->armv8_mmu
.armv8_cache
.display_cache_info
= NULL
;
1033 int armv8_aarch64_state(struct target
*target
)
1035 struct arm
*arm
= target_to_arm(target
);
1037 if (arm
->common_magic
!= ARM_COMMON_MAGIC
) {
1038 LOG_ERROR("BUG: called for a non-ARM target");
1042 LOG_USER("target halted in %s state due to %s, current mode: %s\n"
1043 "cpsr: 0x%8.8" PRIx32
" pc: 0x%" PRIx64
"%s",
1044 armv8_state_strings
[arm
->core_state
],
1045 debug_reason_name(target
),
1046 armv8_mode_name(arm
->core_mode
),
1047 buf_get_u32(arm
->cpsr
->value
, 0, 32),
1048 buf_get_u64(arm
->pc
->value
, 0, 64),
1049 arm
->is_semihosting
? ", semihosting" : "");
1054 int armv8_arch_state(struct target
*target
)
1056 static const char * const state
[] = {
1057 "disabled", "enabled"
1060 struct armv8_common
*armv8
= target_to_armv8(target
);
1061 struct arm
*arm
= &armv8
->arm
;
1063 if (armv8
->common_magic
!= ARMV8_COMMON_MAGIC
) {
1064 LOG_ERROR("BUG: called for a non-Armv8 target");
1065 return ERROR_COMMAND_SYNTAX_ERROR
;
1068 if (arm
->core_state
== ARM_STATE_AARCH64
)
1069 armv8_aarch64_state(target
);
1071 arm_arch_state(target
);
1073 LOG_USER("MMU: %s, D-Cache: %s, I-Cache: %s",
1074 state
[armv8
->armv8_mmu
.mmu_enabled
],
1075 state
[armv8
->armv8_mmu
.armv8_cache
.d_u_cache_enabled
],
1076 state
[armv8
->armv8_mmu
.armv8_cache
.i_cache_enabled
]);
1078 if (arm
->core_mode
== ARM_MODE_ABT
)
1079 armv8_show_fault_registers(target
);
1081 if (target
->debug_reason
== DBG_REASON_WATCHPOINT
)
1082 LOG_USER("Watchpoint triggered at PC %#08x",
1083 (unsigned) armv8
->dpm
.wp_pc
);
1088 static struct reg_data_type aarch64_vector_base_types
[] = {
1089 {REG_TYPE_IEEE_DOUBLE
, "ieee_double", 0, {NULL
} },
1090 {REG_TYPE_UINT64
, "uint64", 0, {NULL
} },
1091 {REG_TYPE_INT64
, "int64", 0, {NULL
} },
1092 {REG_TYPE_IEEE_SINGLE
, "ieee_single", 0, {NULL
} },
1093 {REG_TYPE_UINT32
, "uint32", 0, {NULL
} },
1094 {REG_TYPE_INT32
, "int32", 0, {NULL
} },
1095 {REG_TYPE_UINT16
, "uint16", 0, {NULL
} },
1096 {REG_TYPE_INT16
, "int16", 0, {NULL
} },
1097 {REG_TYPE_UINT8
, "uint8", 0, {NULL
} },
1098 {REG_TYPE_INT8
, "int8", 0, {NULL
} },
1099 {REG_TYPE_UINT128
, "uint128", 0, {NULL
} },
1100 {REG_TYPE_INT128
, "int128", 0, {NULL
} }
1103 static struct reg_data_type_vector aarch64_vector_types
[] = {
1104 {aarch64_vector_base_types
+ 0, 2},
1105 {aarch64_vector_base_types
+ 1, 2},
1106 {aarch64_vector_base_types
+ 2, 2},
1107 {aarch64_vector_base_types
+ 3, 4},
1108 {aarch64_vector_base_types
+ 4, 4},
1109 {aarch64_vector_base_types
+ 5, 4},
1110 {aarch64_vector_base_types
+ 6, 8},
1111 {aarch64_vector_base_types
+ 7, 8},
1112 {aarch64_vector_base_types
+ 8, 16},
1113 {aarch64_vector_base_types
+ 9, 16},
1114 {aarch64_vector_base_types
+ 10, 01},
1115 {aarch64_vector_base_types
+ 11, 01},
1118 static struct reg_data_type aarch64_fpu_vector
[] = {
1119 {REG_TYPE_ARCH_DEFINED
, "v2d", REG_TYPE_CLASS_VECTOR
, {aarch64_vector_types
+ 0} },
1120 {REG_TYPE_ARCH_DEFINED
, "v2u", REG_TYPE_CLASS_VECTOR
, {aarch64_vector_types
+ 1} },
1121 {REG_TYPE_ARCH_DEFINED
, "v2i", REG_TYPE_CLASS_VECTOR
, {aarch64_vector_types
+ 2} },
1122 {REG_TYPE_ARCH_DEFINED
, "v4f", REG_TYPE_CLASS_VECTOR
, {aarch64_vector_types
+ 3} },
1123 {REG_TYPE_ARCH_DEFINED
, "v4u", REG_TYPE_CLASS_VECTOR
, {aarch64_vector_types
+ 4} },
1124 {REG_TYPE_ARCH_DEFINED
, "v4i", REG_TYPE_CLASS_VECTOR
, {aarch64_vector_types
+ 5} },
1125 {REG_TYPE_ARCH_DEFINED
, "v8u", REG_TYPE_CLASS_VECTOR
, {aarch64_vector_types
+ 6} },
1126 {REG_TYPE_ARCH_DEFINED
, "v8i", REG_TYPE_CLASS_VECTOR
, {aarch64_vector_types
+ 7} },
1127 {REG_TYPE_ARCH_DEFINED
, "v16u", REG_TYPE_CLASS_VECTOR
, {aarch64_vector_types
+ 8} },
1128 {REG_TYPE_ARCH_DEFINED
, "v16i", REG_TYPE_CLASS_VECTOR
, {aarch64_vector_types
+ 9} },
1129 {REG_TYPE_ARCH_DEFINED
, "v1u", REG_TYPE_CLASS_VECTOR
, {aarch64_vector_types
+ 10} },
1130 {REG_TYPE_ARCH_DEFINED
, "v1i", REG_TYPE_CLASS_VECTOR
, {aarch64_vector_types
+ 11} },
1133 static struct reg_data_type_union_field aarch64_union_fields_vnd
[] = {
1134 {"f", aarch64_fpu_vector
+ 0, aarch64_union_fields_vnd
+ 1},
1135 {"u", aarch64_fpu_vector
+ 1, aarch64_union_fields_vnd
+ 2},
1136 {"s", aarch64_fpu_vector
+ 2, NULL
},
1139 static struct reg_data_type_union_field aarch64_union_fields_vns
[] = {
1140 {"f", aarch64_fpu_vector
+ 3, aarch64_union_fields_vns
+ 1},
1141 {"u", aarch64_fpu_vector
+ 4, aarch64_union_fields_vns
+ 2},
1142 {"s", aarch64_fpu_vector
+ 5, NULL
},
1145 static struct reg_data_type_union_field aarch64_union_fields_vnh
[] = {
1146 {"u", aarch64_fpu_vector
+ 6, aarch64_union_fields_vnh
+ 1},
1147 {"s", aarch64_fpu_vector
+ 7, NULL
},
1150 static struct reg_data_type_union_field aarch64_union_fields_vnb
[] = {
1151 {"u", aarch64_fpu_vector
+ 8, aarch64_union_fields_vnb
+ 1},
1152 {"s", aarch64_fpu_vector
+ 9, NULL
},
1155 static struct reg_data_type_union_field aarch64_union_fields_vnq
[] = {
1156 {"u", aarch64_fpu_vector
+ 10, aarch64_union_fields_vnq
+ 1},
1157 {"s", aarch64_fpu_vector
+ 11, NULL
},
1160 static struct reg_data_type_union aarch64_union_types
[] = {
1161 {aarch64_union_fields_vnd
},
1162 {aarch64_union_fields_vns
},
1163 {aarch64_union_fields_vnh
},
1164 {aarch64_union_fields_vnb
},
1165 {aarch64_union_fields_vnq
},
1168 static struct reg_data_type aarch64_fpu_union
[] = {
1169 {REG_TYPE_ARCH_DEFINED
, "vnd", REG_TYPE_CLASS_UNION
, {.reg_type_union
= aarch64_union_types
+ 0} },
1170 {REG_TYPE_ARCH_DEFINED
, "vns", REG_TYPE_CLASS_UNION
, {.reg_type_union
= aarch64_union_types
+ 1} },
1171 {REG_TYPE_ARCH_DEFINED
, "vnh", REG_TYPE_CLASS_UNION
, {.reg_type_union
= aarch64_union_types
+ 2} },
1172 {REG_TYPE_ARCH_DEFINED
, "vnb", REG_TYPE_CLASS_UNION
, {.reg_type_union
= aarch64_union_types
+ 3} },
1173 {REG_TYPE_ARCH_DEFINED
, "vnq", REG_TYPE_CLASS_UNION
, {.reg_type_union
= aarch64_union_types
+ 4} },
1176 static struct reg_data_type_union_field aarch64v_union_fields
[] = {
1177 {"d", aarch64_fpu_union
+ 0, aarch64v_union_fields
+ 1},
1178 {"s", aarch64_fpu_union
+ 1, aarch64v_union_fields
+ 2},
1179 {"h", aarch64_fpu_union
+ 2, aarch64v_union_fields
+ 3},
1180 {"b", aarch64_fpu_union
+ 3, aarch64v_union_fields
+ 4},
1181 {"q", aarch64_fpu_union
+ 4, NULL
},
1184 static struct reg_data_type_union aarch64v_union
[] = {
1185 {aarch64v_union_fields
}
1188 static struct reg_data_type aarch64v
[] = {
1189 {REG_TYPE_ARCH_DEFINED
, "aarch64v", REG_TYPE_CLASS_UNION
,
1190 {.reg_type_union
= aarch64v_union
} },
1193 static struct reg_data_type_bitfield aarch64_cpsr_bits
[] = {
1194 { 0, 0 , REG_TYPE_UINT8
},
1195 { 2, 3, REG_TYPE_UINT8
},
1196 { 4, 4 , REG_TYPE_UINT8
},
1197 { 6, 6 , REG_TYPE_BOOL
},
1198 { 7, 7 , REG_TYPE_BOOL
},
1199 { 8, 8 , REG_TYPE_BOOL
},
1200 { 9, 9 , REG_TYPE_BOOL
},
1201 { 20, 20, REG_TYPE_BOOL
},
1202 { 21, 21, REG_TYPE_BOOL
},
1203 { 28, 28, REG_TYPE_BOOL
},
1204 { 29, 29, REG_TYPE_BOOL
},
1205 { 30, 30, REG_TYPE_BOOL
},
1206 { 31, 31, REG_TYPE_BOOL
},
1209 static struct reg_data_type_flags_field aarch64_cpsr_fields
[] = {
1210 { "SP", aarch64_cpsr_bits
+ 0, aarch64_cpsr_fields
+ 1 },
1211 { "EL", aarch64_cpsr_bits
+ 1, aarch64_cpsr_fields
+ 2 },
1212 { "nRW", aarch64_cpsr_bits
+ 2, aarch64_cpsr_fields
+ 3 },
1213 { "F" , aarch64_cpsr_bits
+ 3, aarch64_cpsr_fields
+ 4 },
1214 { "I" , aarch64_cpsr_bits
+ 4, aarch64_cpsr_fields
+ 5 },
1215 { "A" , aarch64_cpsr_bits
+ 5, aarch64_cpsr_fields
+ 6 },
1216 { "D" , aarch64_cpsr_bits
+ 6, aarch64_cpsr_fields
+ 7 },
1217 { "IL" , aarch64_cpsr_bits
+ 7, aarch64_cpsr_fields
+ 8 },
1218 { "SS" , aarch64_cpsr_bits
+ 8, aarch64_cpsr_fields
+ 9 },
1219 { "V" , aarch64_cpsr_bits
+ 9, aarch64_cpsr_fields
+ 10 },
1220 { "C" , aarch64_cpsr_bits
+ 10, aarch64_cpsr_fields
+ 11 },
1221 { "Z" , aarch64_cpsr_bits
+ 11, aarch64_cpsr_fields
+ 12 },
1222 { "N" , aarch64_cpsr_bits
+ 12, NULL
}
1225 static struct reg_data_type_flags aarch64_cpsr_flags
[] = {
1226 { 4, aarch64_cpsr_fields
}
1229 static struct reg_data_type aarch64_flags_cpsr
[] = {
1230 {REG_TYPE_ARCH_DEFINED
, "cpsr_flags", REG_TYPE_CLASS_FLAGS
,
1231 {.reg_type_flags
= aarch64_cpsr_flags
} },
1234 static const struct {
1241 const char *feature
;
1242 struct reg_data_type
*data_type
;
1244 { ARMV8_R0
, "x0", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1245 { ARMV8_R1
, "x1", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1246 { ARMV8_R2
, "x2", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1247 { ARMV8_R3
, "x3", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1248 { ARMV8_R4
, "x4", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1249 { ARMV8_R5
, "x5", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1250 { ARMV8_R6
, "x6", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1251 { ARMV8_R7
, "x7", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1252 { ARMV8_R8
, "x8", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1253 { ARMV8_R9
, "x9", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1254 { ARMV8_R10
, "x10", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1255 { ARMV8_R11
, "x11", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1256 { ARMV8_R12
, "x12", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1257 { ARMV8_R13
, "x13", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1258 { ARMV8_R14
, "x14", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1259 { ARMV8_R15
, "x15", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1260 { ARMV8_R16
, "x16", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1261 { ARMV8_R17
, "x17", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1262 { ARMV8_R18
, "x18", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1263 { ARMV8_R19
, "x19", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1264 { ARMV8_R20
, "x20", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1265 { ARMV8_R21
, "x21", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1266 { ARMV8_R22
, "x22", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1267 { ARMV8_R23
, "x23", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1268 { ARMV8_R24
, "x24", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1269 { ARMV8_R25
, "x25", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1270 { ARMV8_R26
, "x26", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1271 { ARMV8_R27
, "x27", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1272 { ARMV8_R28
, "x28", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1273 { ARMV8_R29
, "x29", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1274 { ARMV8_R30
, "x30", 64, ARM_MODE_ANY
, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1276 { ARMV8_SP
, "sp", 64, ARM_MODE_ANY
, REG_TYPE_DATA_PTR
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1277 { ARMV8_PC
, "pc", 64, ARM_MODE_ANY
, REG_TYPE_CODE_PTR
, "general", "org.gnu.gdb.aarch64.core", NULL
},
1278 { ARMV8_xPSR
, "cpsr", 32, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
,
1279 "general", "org.gnu.gdb.aarch64.core", aarch64_flags_cpsr
},
1280 { ARMV8_V0
, "v0", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1281 { ARMV8_V1
, "v1", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1282 { ARMV8_V2
, "v2", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1283 { ARMV8_V3
, "v3", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1284 { ARMV8_V4
, "v4", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1285 { ARMV8_V5
, "v5", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1286 { ARMV8_V6
, "v6", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1287 { ARMV8_V7
, "v7", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1288 { ARMV8_V8
, "v8", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1289 { ARMV8_V9
, "v9", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1290 { ARMV8_V10
, "v10", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1291 { ARMV8_V11
, "v11", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1292 { ARMV8_V12
, "v12", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1293 { ARMV8_V13
, "v13", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1294 { ARMV8_V14
, "v14", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1295 { ARMV8_V15
, "v15", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1296 { ARMV8_V16
, "v16", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1297 { ARMV8_V17
, "v17", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1298 { ARMV8_V18
, "v18", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1299 { ARMV8_V19
, "v19", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1300 { ARMV8_V20
, "v20", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1301 { ARMV8_V21
, "v21", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1302 { ARMV8_V22
, "v22", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1303 { ARMV8_V23
, "v23", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1304 { ARMV8_V24
, "v24", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1305 { ARMV8_V25
, "v25", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1306 { ARMV8_V26
, "v26", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1307 { ARMV8_V27
, "v27", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1308 { ARMV8_V28
, "v28", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1309 { ARMV8_V29
, "v29", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1310 { ARMV8_V30
, "v30", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1311 { ARMV8_V31
, "v31", 128, ARM_MODE_ANY
, REG_TYPE_ARCH_DEFINED
, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v
},
1312 { ARMV8_FPSR
, "fpsr", 32, ARM_MODE_ANY
, REG_TYPE_UINT32
, "simdfp", "org.gnu.gdb.aarch64.fpu", NULL
},
1313 { ARMV8_FPCR
, "fpcr", 32, ARM_MODE_ANY
, REG_TYPE_UINT32
, "simdfp", "org.gnu.gdb.aarch64.fpu", NULL
},
1315 { ARMV8_ELR_EL1
, "ELR_EL1", 64, ARMV8_64_EL1H
, REG_TYPE_CODE_PTR
, "banked", "net.sourceforge.openocd.banked",
1317 { ARMV8_ESR_EL1
, "ESR_EL1", 32, ARMV8_64_EL1H
, REG_TYPE_UINT32
, "banked", "net.sourceforge.openocd.banked",
1319 { ARMV8_SPSR_EL1
, "SPSR_EL1", 32, ARMV8_64_EL1H
, REG_TYPE_UINT32
, "banked", "net.sourceforge.openocd.banked",
1322 { ARMV8_ELR_EL2
, "ELR_EL2", 64, ARMV8_64_EL2H
, REG_TYPE_CODE_PTR
, "banked", "net.sourceforge.openocd.banked",
1324 { ARMV8_ESR_EL2
, "ESR_EL2", 32, ARMV8_64_EL2H
, REG_TYPE_UINT32
, "banked", "net.sourceforge.openocd.banked",
1326 { ARMV8_SPSR_EL2
, "SPSR_EL2", 32, ARMV8_64_EL2H
, REG_TYPE_UINT32
, "banked", "net.sourceforge.openocd.banked",
1329 { ARMV8_ELR_EL3
, "ELR_EL3", 64, ARMV8_64_EL3H
, REG_TYPE_CODE_PTR
, "banked", "net.sourceforge.openocd.banked",
1331 { ARMV8_ESR_EL3
, "ESR_EL3", 32, ARMV8_64_EL3H
, REG_TYPE_UINT32
, "banked", "net.sourceforge.openocd.banked",
1333 { ARMV8_SPSR_EL3
, "SPSR_EL3", 32, ARMV8_64_EL3H
, REG_TYPE_UINT32
, "banked", "net.sourceforge.openocd.banked",
1337 static const struct {
1345 const char *feature
;
1346 } armv8_regs32
[] = {
1347 { ARMV8_R0
, 0, "r0", 32, ARM_MODE_ANY
, REG_TYPE_UINT32
, "general", "org.gnu.gdb.arm.core" },
1348 { ARMV8_R1
, 0, "r1", 32, ARM_MODE_ANY
, REG_TYPE_UINT32
, "general", "org.gnu.gdb.arm.core" },
1349 { ARMV8_R2
, 0, "r2", 32, ARM_MODE_ANY
, REG_TYPE_UINT32
, "general", "org.gnu.gdb.arm.core" },
1350 { ARMV8_R3
, 0, "r3", 32, ARM_MODE_ANY
, REG_TYPE_UINT32
, "general", "org.gnu.gdb.arm.core" },
1351 { ARMV8_R4
, 0, "r4", 32, ARM_MODE_ANY
, REG_TYPE_UINT32
, "general", "org.gnu.gdb.arm.core" },
1352 { ARMV8_R5
, 0, "r5", 32, ARM_MODE_ANY
, REG_TYPE_UINT32
, "general", "org.gnu.gdb.arm.core" },
1353 { ARMV8_R6
, 0, "r6", 32, ARM_MODE_ANY
, REG_TYPE_UINT32
, "general", "org.gnu.gdb.arm.core" },
1354 { ARMV8_R7
, 0, "r7", 32, ARM_MODE_ANY
, REG_TYPE_UINT32
, "general", "org.gnu.gdb.arm.core" },
1355 { ARMV8_R8
, 0, "r8", 32, ARM_MODE_ANY
, REG_TYPE_UINT32
, "general", "org.gnu.gdb.arm.core" },
1356 { ARMV8_R9
, 0, "r9", 32, ARM_MODE_ANY
, REG_TYPE_UINT32
, "general", "org.gnu.gdb.arm.core" },
1357 { ARMV8_R10
, 0, "r10", 32, ARM_MODE_ANY
, REG_TYPE_UINT32
, "general", "org.gnu.gdb.arm.core" },
1358 { ARMV8_R11
, 0, "r11", 32, ARM_MODE_ANY
, REG_TYPE_UINT32
, "general", "org.gnu.gdb.arm.core" },
1359 { ARMV8_R12
, 0, "r12", 32, ARM_MODE_ANY
, REG_TYPE_UINT32
, "general", "org.gnu.gdb.arm.core" },
1360 { ARMV8_R13
, 0, "sp", 32, ARM_MODE_ANY
, REG_TYPE_DATA_PTR
, "general", "org.gnu.gdb.arm.core" },
1361 { ARMV8_R14
, 0, "lr", 32, ARM_MODE_ANY
, REG_TYPE_CODE_PTR
, "general", "org.gnu.gdb.arm.core" },
1362 { ARMV8_PC
, 0, "pc", 32, ARM_MODE_ANY
, REG_TYPE_CODE_PTR
, "general", "org.gnu.gdb.arm.core" },
1363 { ARMV8_xPSR
, 0, "cpsr", 32, ARM_MODE_ANY
, REG_TYPE_UINT32
, "general", "org.gnu.gdb.arm.core" },
1364 { ARMV8_V0
, 0, "d0", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1365 { ARMV8_V0
, 8, "d1", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1366 { ARMV8_V1
, 0, "d2", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1367 { ARMV8_V1
, 8, "d3", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1368 { ARMV8_V2
, 0, "d4", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1369 { ARMV8_V2
, 8, "d5", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1370 { ARMV8_V3
, 0, "d6", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1371 { ARMV8_V3
, 8, "d7", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1372 { ARMV8_V4
, 0, "d8", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1373 { ARMV8_V4
, 8, "d9", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1374 { ARMV8_V5
, 0, "d10", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1375 { ARMV8_V5
, 8, "d11", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1376 { ARMV8_V6
, 0, "d12", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1377 { ARMV8_V6
, 8, "d13", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1378 { ARMV8_V7
, 0, "d14", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1379 { ARMV8_V7
, 8, "d15", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1380 { ARMV8_V8
, 0, "d16", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1381 { ARMV8_V8
, 8, "d17", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1382 { ARMV8_V9
, 0, "d18", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1383 { ARMV8_V9
, 8, "d19", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1384 { ARMV8_V10
, 0, "d20", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1385 { ARMV8_V10
, 8, "d21", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1386 { ARMV8_V11
, 0, "d22", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1387 { ARMV8_V11
, 8, "d23", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1388 { ARMV8_V12
, 0, "d24", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1389 { ARMV8_V12
, 8, "d25", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1390 { ARMV8_V13
, 0, "d26", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1391 { ARMV8_V13
, 8, "d27", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1392 { ARMV8_V14
, 0, "d28", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1393 { ARMV8_V14
, 8, "d29", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1394 { ARMV8_V15
, 0, "d30", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1395 { ARMV8_V15
, 8, "d31", 64, ARM_MODE_ANY
, REG_TYPE_IEEE_DOUBLE
, NULL
, "org.gnu.gdb.arm.vfp"},
1396 { ARMV8_FPSR
, 0, "fpscr", 32, ARM_MODE_ANY
, REG_TYPE_UINT32
, "float", "org.gnu.gdb.arm.vfp"},
1399 #define ARMV8_NUM_REGS ARRAY_SIZE(armv8_regs)
1400 #define ARMV8_NUM_REGS32 ARRAY_SIZE(armv8_regs32)
1402 static int armv8_get_core_reg(struct reg
*reg
)
1404 struct arm_reg
*armv8_reg
= reg
->arch_info
;
1405 struct target
*target
= armv8_reg
->target
;
1406 struct arm
*arm
= target_to_arm(target
);
1408 if (target
->state
!= TARGET_HALTED
)
1409 return ERROR_TARGET_NOT_HALTED
;
1411 return arm
->read_core_reg(target
, reg
, armv8_reg
->num
, arm
->core_mode
);
1414 static int armv8_set_core_reg(struct reg
*reg
, uint8_t *buf
)
1416 struct arm_reg
*armv8_reg
= reg
->arch_info
;
1417 struct target
*target
= armv8_reg
->target
;
1418 struct arm
*arm
= target_to_arm(target
);
1419 uint64_t value
= buf_get_u64(buf
, 0, reg
->size
);
1421 if (target
->state
!= TARGET_HALTED
)
1422 return ERROR_TARGET_NOT_HALTED
;
1424 if (reg
->size
<= 64) {
1425 if (reg
== arm
->cpsr
)
1426 armv8_set_cpsr(arm
, (uint32_t)value
);
1428 buf_set_u64(reg
->value
, 0, reg
->size
, value
);
1431 } else if (reg
->size
<= 128) {
1432 uint64_t hvalue
= buf_get_u64(buf
+ 8, 0, reg
->size
- 64);
1434 buf_set_u64(reg
->value
, 0, 64, value
);
1435 buf_set_u64(reg
->value
+ 8, 0, reg
->size
- 64, hvalue
);
1444 static const struct reg_arch_type armv8_reg_type
= {
1445 .get
= armv8_get_core_reg
,
1446 .set
= armv8_set_core_reg
,
1449 static int armv8_get_core_reg32(struct reg
*reg
)
1451 struct arm_reg
*armv8_reg
= reg
->arch_info
;
1452 struct target
*target
= armv8_reg
->target
;
1453 struct arm
*arm
= target_to_arm(target
);
1454 struct reg_cache
*cache
= arm
->core_cache
;
1458 /* get the corresponding Aarch64 register */
1459 reg64
= cache
->reg_list
+ armv8_reg
->num
;
1465 retval
= arm
->read_core_reg(target
, reg64
, armv8_reg
->num
, arm
->core_mode
);
1466 if (retval
== ERROR_OK
)
1467 reg
->valid
= reg64
->valid
;
1472 static int armv8_set_core_reg32(struct reg
*reg
, uint8_t *buf
)
1474 struct arm_reg
*armv8_reg
= reg
->arch_info
;
1475 struct target
*target
= armv8_reg
->target
;
1476 struct arm
*arm
= target_to_arm(target
);
1477 struct reg_cache
*cache
= arm
->core_cache
;
1478 struct reg
*reg64
= cache
->reg_list
+ armv8_reg
->num
;
1479 uint32_t value
= buf_get_u32(buf
, 0, 32);
1481 if (reg64
== arm
->cpsr
) {
1482 armv8_set_cpsr(arm
, value
);
1484 if (reg
->size
<= 32)
1485 buf_set_u32(reg
->value
, 0, 32, value
);
1486 else if (reg
->size
<= 64) {
1487 uint64_t value64
= buf_get_u64(buf
, 0, 64);
1488 buf_set_u64(reg
->value
, 0, 64, value64
);
1499 static const struct reg_arch_type armv8_reg32_type
= {
1500 .get
= armv8_get_core_reg32
,
1501 .set
= armv8_set_core_reg32
,
1504 /** Builds cache of architecturally defined registers. */
1505 struct reg_cache
*armv8_build_reg_cache(struct target
*target
)
1507 struct armv8_common
*armv8
= target_to_armv8(target
);
1508 struct arm
*arm
= &armv8
->arm
;
1509 int num_regs
= ARMV8_NUM_REGS
;
1510 int num_regs32
= ARMV8_NUM_REGS32
;
1511 struct reg_cache
**cache_p
= register_get_last_cache_p(&target
->reg_cache
);
1512 struct reg_cache
*cache
= malloc(sizeof(struct reg_cache
));
1513 struct reg_cache
*cache32
= malloc(sizeof(struct reg_cache
));
1514 struct reg
*reg_list
= calloc(num_regs
, sizeof(struct reg
));
1515 struct reg
*reg_list32
= calloc(num_regs32
, sizeof(struct reg
));
1516 struct arm_reg
*arch_info
= calloc(num_regs
, sizeof(struct arm_reg
));
1517 struct reg_feature
*feature
;
1520 /* Build the process context cache */
1521 cache
->name
= "Aarch64 registers";
1522 cache
->next
= cache32
;
1523 cache
->reg_list
= reg_list
;
1524 cache
->num_regs
= num_regs
;
1526 for (i
= 0; i
< num_regs
; i
++) {
1527 arch_info
[i
].num
= armv8_regs
[i
].id
;
1528 arch_info
[i
].mode
= armv8_regs
[i
].mode
;
1529 arch_info
[i
].target
= target
;
1530 arch_info
[i
].arm
= arm
;
1532 reg_list
[i
].name
= armv8_regs
[i
].name
;
1533 reg_list
[i
].size
= armv8_regs
[i
].bits
;
1534 reg_list
[i
].value
= &arch_info
[i
].value
[0];
1535 reg_list
[i
].type
= &armv8_reg_type
;
1536 reg_list
[i
].arch_info
= &arch_info
[i
];
1538 reg_list
[i
].group
= armv8_regs
[i
].group
;
1539 reg_list
[i
].number
= i
;
1540 reg_list
[i
].exist
= true;
1541 reg_list
[i
].caller_save
= true; /* gdb defaults to true */
1543 feature
= calloc(1, sizeof(struct reg_feature
));
1545 feature
->name
= armv8_regs
[i
].feature
;
1546 reg_list
[i
].feature
= feature
;
1548 LOG_ERROR("unable to allocate feature list");
1550 if (armv8_regs
[i
].data_type
== NULL
) {
1551 reg_list
[i
].reg_data_type
= calloc(1, sizeof(struct reg_data_type
));
1552 if (reg_list
[i
].reg_data_type
)
1553 reg_list
[i
].reg_data_type
->type
= armv8_regs
[i
].type
;
1555 LOG_ERROR("unable to allocate reg type list");
1557 reg_list
[i
].reg_data_type
= armv8_regs
[i
].data_type
;
1561 arm
->cpsr
= reg_list
+ ARMV8_xPSR
;
1562 arm
->pc
= reg_list
+ ARMV8_PC
;
1563 arm
->core_cache
= cache
;
1565 /* shadow cache for ARM mode registers */
1566 cache32
->name
= "Aarch32 registers";
1567 cache32
->next
= NULL
;
1568 cache32
->reg_list
= reg_list32
;
1569 cache32
->num_regs
= num_regs32
;
1571 for (i
= 0; i
< num_regs32
; i
++) {
1572 reg_list32
[i
].name
= armv8_regs32
[i
].name
;
1573 reg_list32
[i
].size
= armv8_regs32
[i
].bits
;
1574 reg_list32
[i
].value
= &arch_info
[armv8_regs32
[i
].id
].value
[armv8_regs32
[i
].mapping
];
1575 reg_list32
[i
].type
= &armv8_reg32_type
;
1576 reg_list32
[i
].arch_info
= &arch_info
[armv8_regs32
[i
].id
];
1577 reg_list32
[i
].group
= armv8_regs32
[i
].group
;
1578 reg_list32
[i
].number
= i
;
1579 reg_list32
[i
].exist
= true;
1580 reg_list32
[i
].caller_save
= true;
1582 feature
= calloc(1, sizeof(struct reg_feature
));
1584 feature
->name
= armv8_regs32
[i
].feature
;
1585 reg_list32
[i
].feature
= feature
;
1587 LOG_ERROR("unable to allocate feature list");
1589 reg_list32
[i
].reg_data_type
= calloc(1, sizeof(struct reg_data_type
));
1590 if (reg_list32
[i
].reg_data_type
)
1591 reg_list32
[i
].reg_data_type
->type
= armv8_regs32
[i
].type
;
1593 LOG_ERROR("unable to allocate reg type list");
1600 struct reg
*armv8_reg_current(struct arm
*arm
, unsigned regnum
)
1604 if (regnum
> (ARMV8_LAST_REG
- 1))
1607 r
= arm
->core_cache
->reg_list
+ regnum
;
1611 const struct command_registration armv8_command_handlers
[] = {
1612 COMMAND_REGISTRATION_DONE
1615 int armv8_get_gdb_reg_list(struct target
*target
,
1616 struct reg
**reg_list
[], int *reg_list_size
,
1617 enum target_register_class reg_class
)
1619 struct arm
*arm
= target_to_arm(target
);
1622 if (arm
->core_state
== ARM_STATE_AARCH64
) {
1624 LOG_DEBUG("Creating Aarch64 register list for target %s", target_name(target
));
1626 switch (reg_class
) {
1627 case REG_CLASS_GENERAL
:
1628 *reg_list_size
= ARMV8_V0
;
1629 *reg_list
= malloc(sizeof(struct reg
*) * (*reg_list_size
));
1631 for (i
= 0; i
< *reg_list_size
; i
++)
1632 (*reg_list
)[i
] = armv8_reg_current(arm
, i
);
1636 *reg_list_size
= ARMV8_LAST_REG
;
1637 *reg_list
= malloc(sizeof(struct reg
*) * (*reg_list_size
));
1639 for (i
= 0; i
< *reg_list_size
; i
++)
1640 (*reg_list
)[i
] = armv8_reg_current(arm
, i
);
1645 LOG_ERROR("not a valid register class type in query.");
1649 struct reg_cache
*cache32
= arm
->core_cache
->next
;
1651 LOG_DEBUG("Creating Aarch32 register list for target %s", target_name(target
));
1653 switch (reg_class
) {
1654 case REG_CLASS_GENERAL
:
1655 *reg_list_size
= ARMV8_R14
+ 3;
1656 *reg_list
= malloc(sizeof(struct reg
*) * (*reg_list_size
));
1658 for (i
= 0; i
< *reg_list_size
; i
++)
1659 (*reg_list
)[i
] = cache32
->reg_list
+ i
;
1663 *reg_list_size
= cache32
->num_regs
;
1664 *reg_list
= malloc(sizeof(struct reg
*) * (*reg_list_size
));
1666 for (i
= 0; i
< *reg_list_size
; i
++)
1667 (*reg_list
)[i
] = cache32
->reg_list
+ i
;
1671 LOG_ERROR("not a valid register class type in query.");
1677 int armv8_set_dbgreg_bits(struct armv8_common
*armv8
, unsigned int reg
, unsigned long mask
, unsigned long value
)
1682 int retval
= mem_ap_read_atomic_u32(armv8
->debug_ap
,
1683 armv8
->debug_base
+ reg
, &tmp
);
1684 if (ERROR_OK
!= retval
)
1687 /* clear bitfield */
1690 tmp
|= value
& mask
;
1692 /* write new value */
1693 retval
= mem_ap_write_atomic_u32(armv8
->debug_ap
,
1694 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)