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 #define __unused __attribute__((unused))
42 static const char * const armv8_state_strings
[] = {
43 "AArch32", "Thumb", "Jazelle", "ThumbEE", "AArch64",
49 /* For user and system modes, these list indices for all registers.
50 * otherwise they're just indices for the shadow registers and SPSR.
52 unsigned short n_indices
;
53 const uint8_t *indices
;
54 } armv8_mode_data
[] = {
55 /* These special modes are currently only supported
56 * by ARMv6M and ARMv7M profiles */
103 .psr
= ARMV8_64_EL3T
,
107 .psr
= ARMV8_64_EL3H
,
111 /** Map PSR mode bits to the name of an ARM processor operating mode. */
112 const char *armv8_mode_name(unsigned psr_mode
)
114 for (unsigned i
= 0; i
< ARRAY_SIZE(armv8_mode_data
); i
++) {
115 if (armv8_mode_data
[i
].psr
== psr_mode
)
116 return armv8_mode_data
[i
].name
;
118 LOG_ERROR("unrecognized psr mode: %#02x", psr_mode
);
119 return "UNRECOGNIZED";
122 int armv8_mode_to_number(enum arm_mode mode
)
126 /* map MODE_ANY to user mode */
159 LOG_ERROR("invalid mode value encountered %d", mode
);
165 static int armv8_read_core_reg(struct target
*target
, struct reg
*r
,
166 int num
, enum arm_mode mode
)
170 struct arm_reg
*armv8_core_reg
;
171 struct armv8_common
*armv8
= target_to_armv8(target
);
173 assert(num
< (int)armv8
->arm
.core_cache
->num_regs
);
175 armv8_core_reg
= armv8
->arm
.core_cache
->reg_list
[num
].arch_info
;
176 retval
= armv8
->load_core_reg_u64(target
,
177 armv8_core_reg
->num
, ®_value
);
179 buf_set_u64(armv8
->arm
.core_cache
->reg_list
[num
].value
, 0, 64, reg_value
);
180 armv8
->arm
.core_cache
->reg_list
[num
].valid
= 1;
181 armv8
->arm
.core_cache
->reg_list
[num
].dirty
= 0;
187 static int armv8_write_core_reg(struct target
*target
, struct reg
*r
,
188 int num
, enum arm_mode mode
, target_addr_t value
)
191 struct arm_reg
*armv8_core_reg
;
192 struct armv8_common
*armv8
= target_to_armv8(target
);
194 assert(num
< (int)armv8
->arm
.core_cache
->num_regs
);
196 armv8_core_reg
= armv8
->arm
.core_cache
->reg_list
[num
].arch_info
;
197 retval
= armv8
->store_core_reg_u64(target
,
200 if (retval
!= ERROR_OK
) {
201 LOG_ERROR("JTAG failure");
202 armv8
->arm
.core_cache
->reg_list
[num
].dirty
= armv8
->arm
.core_cache
->reg_list
[num
].valid
;
203 return ERROR_JTAG_DEVICE_ERROR
;
206 LOG_DEBUG("write core reg %i value 0x%" PRIx64
"", num
, value
);
207 armv8
->arm
.core_cache
->reg_list
[num
].valid
= 1;
208 armv8
->arm
.core_cache
->reg_list
[num
].dirty
= 0;
214 /* retrieve core id cluster id */
215 int armv8_read_mpidr(struct armv8_common
*armv8
)
217 int retval
= ERROR_FAIL
;
218 struct arm_dpm
*dpm
= armv8
->arm
.dpm
;
221 retval
= dpm
->prepare(dpm
);
222 if (retval
!= ERROR_OK
)
225 retval
= dpm
->instr_read_data_r0(dpm
, armv8_opcode(armv8
, READ_REG_MPIDR
), &mpidr
);
226 if (retval
!= ERROR_OK
)
229 armv8
->multi_processor_system
= (mpidr
>> 30) & 1;
230 armv8
->cluster_id
= (mpidr
>> 8) & 0xf;
231 armv8
->cpu_id
= mpidr
& 0x3;
232 LOG_INFO("%s cluster %x core %x %s", target_name(armv8
->arm
.target
),
235 armv8
->multi_processor_system
== 0 ? "multi core" : "mono core");
238 LOG_ERROR("mpdir not in multiprocessor format");
246 * Configures host-side ARM records to reflect the specified CPSR.
247 * Later, code can use arm_reg_current() to map register numbers
248 * according to how they are exposed by this mode.
250 void armv8_set_cpsr(struct arm
*arm
, uint32_t cpsr
)
252 uint32_t mode
= cpsr
& 0x1F;
254 /* NOTE: this may be called very early, before the register
255 * cache is set up. We can't defend against many errors, in
256 * particular against CPSRs that aren't valid *here* ...
259 buf_set_u32(arm
->cpsr
->value
, 0, 32, cpsr
);
260 arm
->cpsr
->valid
= 1;
261 arm
->cpsr
->dirty
= 0;
264 /* Older ARMs won't have the J bit */
265 enum arm_state state
= 0xFF;
267 if (((cpsr
& 0x10) >> 4) == 0) {
268 state
= ARM_STATE_AARCH64
;
270 if (cpsr
& (1 << 5)) { /* T */
271 if (cpsr
& (1 << 24)) { /* J */
272 LOG_WARNING("ThumbEE -- incomplete support");
273 state
= ARM_STATE_THUMB_EE
;
275 state
= ARM_STATE_THUMB
;
277 if (cpsr
& (1 << 24)) { /* J */
278 LOG_ERROR("Jazelle state handling is BROKEN!");
279 state
= ARM_STATE_JAZELLE
;
281 state
= ARM_STATE_ARM
;
284 arm
->core_state
= state
;
285 if (arm
->core_state
== ARM_STATE_AARCH64
)
286 arm
->core_mode
= (mode
<< 4) | 0xf;
288 arm
->core_mode
= mode
;
290 LOG_DEBUG("set CPSR %#8.8x: %s mode, %s state", (unsigned) cpsr
,
291 armv8_mode_name(arm
->core_mode
),
292 armv8_state_strings
[arm
->core_state
]);
295 static void armv8_show_fault_registers32(struct armv8_common
*armv8
)
297 uint32_t dfsr
, ifsr
, dfar
, ifar
;
298 struct arm_dpm
*dpm
= armv8
->arm
.dpm
;
301 retval
= dpm
->prepare(dpm
);
302 if (retval
!= ERROR_OK
)
305 /* ARMV4_5_MRC(cpnum, op1, r0, CRn, CRm, op2) */
307 /* c5/c0 - {data, instruction} fault status registers */
308 retval
= dpm
->instr_read_data_r0(dpm
,
309 T32_FMTITR(ARMV4_5_MRC(15, 0, 0, 5, 0, 0)),
311 if (retval
!= ERROR_OK
)
314 retval
= dpm
->instr_read_data_r0(dpm
,
315 T32_FMTITR(ARMV4_5_MRC(15, 0, 0, 5, 0, 1)),
317 if (retval
!= ERROR_OK
)
320 /* c6/c0 - {data, instruction} fault address registers */
321 retval
= dpm
->instr_read_data_r0(dpm
,
322 T32_FMTITR(ARMV4_5_MRC(15, 0, 0, 6, 0, 0)),
324 if (retval
!= ERROR_OK
)
327 retval
= dpm
->instr_read_data_r0(dpm
,
328 T32_FMTITR(ARMV4_5_MRC(15, 0, 0, 6, 0, 2)),
330 if (retval
!= ERROR_OK
)
333 LOG_USER("Data fault registers DFSR: %8.8" PRIx32
334 ", DFAR: %8.8" PRIx32
, dfsr
, dfar
);
335 LOG_USER("Instruction fault registers IFSR: %8.8" PRIx32
336 ", IFAR: %8.8" PRIx32
, ifsr
, ifar
);
339 /* (void) */ dpm
->finish(dpm
);
342 static void armv8_show_fault_registers(struct target
*target
)
344 struct armv8_common
*armv8
= target_to_armv8(target
);
346 if (armv8
->arm
.core_state
!= ARM_STATE_AARCH64
)
347 armv8_show_fault_registers32(armv8
);
350 static uint8_t armv8_pa_size(uint32_t ps
)
373 LOG_INFO("Unknow physicall address size");
379 static __unused
int armv8_read_ttbcr32(struct target
*target
)
381 struct armv8_common
*armv8
= target_to_armv8(target
);
382 struct arm_dpm
*dpm
= armv8
->arm
.dpm
;
383 uint32_t ttbcr
, ttbcr_n
;
384 int retval
= dpm
->prepare(dpm
);
385 if (retval
!= ERROR_OK
)
387 /* MRC p15,0,<Rt>,c2,c0,2 ; Read CP15 Translation Table Base Control Register*/
388 retval
= dpm
->instr_read_data_r0(dpm
,
389 T32_FMTITR(ARMV4_5_MRC(15, 0, 0, 2, 0, 2)),
391 if (retval
!= ERROR_OK
)
394 LOG_DEBUG("ttbcr %" PRIx32
, ttbcr
);
396 ttbcr_n
= ttbcr
& 0x7;
397 armv8
->armv8_mmu
.ttbcr
= ttbcr
;
400 * ARM Architecture Reference Manual (ARMv7-A and ARMv7-Redition),
401 * document # ARM DDI 0406C
403 armv8
->armv8_mmu
.ttbr_range
[0] = 0xffffffff >> ttbcr_n
;
404 armv8
->armv8_mmu
.ttbr_range
[1] = 0xffffffff;
405 armv8
->armv8_mmu
.ttbr_mask
[0] = 0xffffffff << (14 - ttbcr_n
);
406 armv8
->armv8_mmu
.ttbr_mask
[1] = 0xffffffff << 14;
408 LOG_DEBUG("ttbr1 %s, ttbr0_mask %" PRIx32
" ttbr1_mask %" PRIx32
,
409 (ttbcr_n
!= 0) ? "used" : "not used",
410 armv8
->armv8_mmu
.ttbr_mask
[0],
411 armv8
->armv8_mmu
.ttbr_mask
[1]);
418 static __unused
int armv8_read_ttbcr(struct target
*target
)
420 struct armv8_common
*armv8
= target_to_armv8(target
);
421 struct arm_dpm
*dpm
= armv8
->arm
.dpm
;
422 struct arm
*arm
= &armv8
->arm
;
426 int retval
= dpm
->prepare(dpm
);
427 if (retval
!= ERROR_OK
)
430 /* claaer ttrr1_used and ttbr0_mask */
431 memset(&armv8
->armv8_mmu
.ttbr1_used
, 0, sizeof(armv8
->armv8_mmu
.ttbr1_used
));
432 memset(&armv8
->armv8_mmu
.ttbr0_mask
, 0, sizeof(armv8
->armv8_mmu
.ttbr0_mask
));
434 switch (armv8_curel_from_core_mode(arm
)) {
435 case SYSTEM_CUREL_EL3
:
436 retval
= dpm
->instr_read_data_r0(dpm
,
437 ARMV8_MRS(SYSTEM_TCR_EL3
, 0),
439 retval
+= dpm
->instr_read_data_r0_64(dpm
,
440 ARMV8_MRS(SYSTEM_TTBR0_EL3
, 0),
442 if (retval
!= ERROR_OK
)
444 armv8
->va_size
= 64 - (ttbcr
& 0x3F);
445 armv8
->pa_size
= armv8_pa_size((ttbcr
>> 16) & 7);
446 armv8
->page_size
= (ttbcr
>> 14) & 3;
448 case SYSTEM_CUREL_EL2
:
449 retval
= dpm
->instr_read_data_r0(dpm
,
450 ARMV8_MRS(SYSTEM_TCR_EL2
, 0),
452 retval
+= dpm
->instr_read_data_r0_64(dpm
,
453 ARMV8_MRS(SYSTEM_TTBR0_EL2
, 0),
455 if (retval
!= ERROR_OK
)
457 armv8
->va_size
= 64 - (ttbcr
& 0x3F);
458 armv8
->pa_size
= armv8_pa_size((ttbcr
>> 16) & 7);
459 armv8
->page_size
= (ttbcr
>> 14) & 3;
461 case SYSTEM_CUREL_EL0
:
462 case SYSTEM_CUREL_EL1
:
463 retval
= dpm
->instr_read_data_r0_64(dpm
,
464 ARMV8_MRS(SYSTEM_TCR_EL1
, 0),
466 armv8
->va_size
= 64 - (ttbcr_64
& 0x3F);
467 armv8
->pa_size
= armv8_pa_size((ttbcr_64
>> 32) & 7);
468 armv8
->page_size
= (ttbcr_64
>> 14) & 3;
469 armv8
->armv8_mmu
.ttbr1_used
= (((ttbcr_64
>> 16) & 0x3F) != 0) ? 1 : 0;
470 armv8
->armv8_mmu
.ttbr0_mask
= 0x0000FFFFFFFFFFFF;
471 retval
+= dpm
->instr_read_data_r0_64(dpm
,
472 ARMV8_MRS(SYSTEM_TTBR0_EL1
| (armv8
->armv8_mmu
.ttbr1_used
), 0),
474 if (retval
!= ERROR_OK
)
478 LOG_ERROR("unknow core state");
482 if (retval
!= ERROR_OK
)
485 if (armv8
->armv8_mmu
.ttbr1_used
== 1)
486 LOG_INFO("TTBR0 access above %" PRIx64
, (uint64_t)(armv8
->armv8_mmu
.ttbr0_mask
));
493 /* method adapted to cortex A : reused arm v4 v5 method*/
494 int armv8_mmu_translate_va(struct target
*target
, target_addr_t va
, target_addr_t
*val
)
499 /* V8 method VA TO PA */
500 int armv8_mmu_translate_va_pa(struct target
*target
, target_addr_t va
,
501 target_addr_t
*val
, int meminfo
)
503 struct armv8_common
*armv8
= target_to_armv8(target
);
504 struct arm
*arm
= target_to_arm(target
);
505 struct arm_dpm
*dpm
= &armv8
->dpm
;
510 static const char * const shared_name
[] = {
511 "Non-", "UNDEFINED ", "Outer ", "Inner "
514 static const char * const secure_name
[] = {
515 "Secure", "Not Secure"
518 retval
= dpm
->prepare(dpm
);
519 if (retval
!= ERROR_OK
)
522 switch (armv8_curel_from_core_mode(arm
)) {
523 case SYSTEM_CUREL_EL0
:
524 instr
= ARMV8_SYS(SYSTEM_ATS12E0R
, 0);
525 /* can only execute instruction at EL2 */
526 dpmv8_modeswitch(dpm
, ARMV8_64_EL2T
);
528 case SYSTEM_CUREL_EL1
:
529 instr
= ARMV8_SYS(SYSTEM_ATS12E1R
, 0);
530 /* can only execute instruction at EL2 */
531 dpmv8_modeswitch(dpm
, ARMV8_64_EL2T
);
533 case SYSTEM_CUREL_EL2
:
534 instr
= ARMV8_SYS(SYSTEM_ATS1E2R
, 0);
536 case SYSTEM_CUREL_EL3
:
537 instr
= ARMV8_SYS(SYSTEM_ATS1E3R
, 0);
544 /* write VA to R0 and execute translation instruction */
545 retval
= dpm
->instr_write_data_r0_64(dpm
, instr
, (uint64_t)va
);
546 /* read result from PAR_EL1 */
547 if (retval
== ERROR_OK
)
548 retval
= dpm
->instr_read_data_r0_64(dpm
, ARMV8_MRS(SYSTEM_PAR_EL1
, 0), &par
);
552 /* switch back to saved PE mode */
553 dpmv8_modeswitch(dpm
, ARM_MODE_ANY
);
555 if (retval
!= ERROR_OK
)
559 LOG_ERROR("Address translation failed at stage %i, FST=%x, PTW=%i",
560 ((int)(par
>> 9) & 1)+1, (int)(par
>> 1) & 0x3f, (int)(par
>> 8) & 1);
565 *val
= (par
& 0xFFFFFFFFF000UL
) | (va
& 0xFFF);
567 int SH
= (par
>> 7) & 3;
568 int NS
= (par
>> 9) & 1;
569 int ATTR
= (par
>> 56) & 0xFF;
571 char *memtype
= (ATTR
& 0xF0) == 0 ? "Device Memory" : "Normal Memory";
573 LOG_USER("%sshareable, %s",
574 shared_name
[SH
], secure_name
[NS
]);
575 LOG_USER("%s", memtype
);
582 int armv8_handle_cache_info_command(struct command_context
*cmd_ctx
,
583 struct armv8_cache_common
*armv8_cache
)
585 if (armv8_cache
->info
== -1) {
586 command_print(cmd_ctx
, "cache not yet identified");
590 if (armv8_cache
->display_cache_info
)
591 armv8_cache
->display_cache_info(cmd_ctx
, armv8_cache
);
595 int armv8_init_arch_info(struct target
*target
, struct armv8_common
*armv8
)
597 struct arm
*arm
= &armv8
->arm
;
598 arm
->arch_info
= armv8
;
599 target
->arch_info
= &armv8
->arm
;
600 /* target is useful in all function arm v4 5 compatible */
601 armv8
->arm
.target
= target
;
602 armv8
->arm
.common_magic
= ARM_COMMON_MAGIC
;
603 armv8
->common_magic
= ARMV8_COMMON_MAGIC
;
605 arm
->read_core_reg
= armv8_read_core_reg
;
607 arm
->write_core_reg
= armv8_write_core_reg
;
610 armv8
->armv8_mmu
.armv8_cache
.l2_cache
= NULL
;
611 armv8
->armv8_mmu
.armv8_cache
.info
= -1;
612 armv8
->armv8_mmu
.armv8_cache
.flush_all_data_cache
= NULL
;
613 armv8
->armv8_mmu
.armv8_cache
.display_cache_info
= NULL
;
617 int armv8_aarch64_state(struct target
*target
)
619 struct arm
*arm
= target_to_arm(target
);
621 if (arm
->common_magic
!= ARM_COMMON_MAGIC
) {
622 LOG_ERROR("BUG: called for a non-ARM target");
626 LOG_USER("target halted in %s state due to %s, current mode: %s\n"
627 "cpsr: 0x%8.8" PRIx32
" pc: 0x%" PRIx64
"%s",
628 armv8_state_strings
[arm
->core_state
],
629 debug_reason_name(target
),
630 armv8_mode_name(arm
->core_mode
),
631 buf_get_u32(arm
->cpsr
->value
, 0, 32),
632 buf_get_u64(arm
->pc
->value
, 0, 64),
633 arm
->is_semihosting
? ", semihosting" : "");
638 int armv8_arch_state(struct target
*target
)
640 static const char * const state
[] = {
641 "disabled", "enabled"
644 struct armv8_common
*armv8
= target_to_armv8(target
);
645 struct arm
*arm
= &armv8
->arm
;
647 if (armv8
->common_magic
!= ARMV8_COMMON_MAGIC
) {
648 LOG_ERROR("BUG: called for a non-Armv8 target");
649 return ERROR_COMMAND_SYNTAX_ERROR
;
652 if (arm
->core_state
== ARM_STATE_AARCH64
)
653 armv8_aarch64_state(target
);
655 arm_arch_state(target
);
657 LOG_USER("MMU: %s, D-Cache: %s, I-Cache: %s",
658 state
[armv8
->armv8_mmu
.mmu_enabled
],
659 state
[armv8
->armv8_mmu
.armv8_cache
.d_u_cache_enabled
],
660 state
[armv8
->armv8_mmu
.armv8_cache
.i_cache_enabled
]);
662 if (arm
->core_mode
== ARM_MODE_ABT
)
663 armv8_show_fault_registers(target
);
665 if (target
->debug_reason
== DBG_REASON_WATCHPOINT
)
666 LOG_USER("Watchpoint triggered at PC %#08x",
667 (unsigned) armv8
->dpm
.wp_pc
);
672 static const struct {
680 { ARMV8_R0
, "x0", 64, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core" },
681 { ARMV8_R1
, "x1", 64, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core" },
682 { ARMV8_R2
, "x2", 64, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core" },
683 { ARMV8_R3
, "x3", 64, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core" },
684 { ARMV8_R4
, "x4", 64, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core" },
685 { ARMV8_R5
, "x5", 64, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core" },
686 { ARMV8_R6
, "x6", 64, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core" },
687 { ARMV8_R7
, "x7", 64, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core" },
688 { ARMV8_R8
, "x8", 64, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core" },
689 { ARMV8_R9
, "x9", 64, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core" },
690 { ARMV8_R10
, "x10", 64, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core" },
691 { ARMV8_R11
, "x11", 64, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core" },
692 { ARMV8_R12
, "x12", 64, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core" },
693 { ARMV8_R13
, "x13", 64, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core" },
694 { ARMV8_R14
, "x14", 64, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core" },
695 { ARMV8_R15
, "x15", 64, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core" },
696 { ARMV8_R16
, "x16", 64, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core" },
697 { ARMV8_R17
, "x17", 64, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core" },
698 { ARMV8_R18
, "x18", 64, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core" },
699 { ARMV8_R19
, "x19", 64, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core" },
700 { ARMV8_R20
, "x20", 64, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core" },
701 { ARMV8_R21
, "x21", 64, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core" },
702 { ARMV8_R22
, "x22", 64, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core" },
703 { ARMV8_R23
, "x23", 64, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core" },
704 { ARMV8_R24
, "x24", 64, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core" },
705 { ARMV8_R25
, "x25", 64, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core" },
706 { ARMV8_R26
, "x26", 64, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core" },
707 { ARMV8_R27
, "x27", 64, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core" },
708 { ARMV8_R28
, "x28", 64, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core" },
709 { ARMV8_R29
, "x29", 64, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core" },
710 { ARMV8_R30
, "x30", 64, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core" },
712 { ARMV8_R31
, "sp", 64, REG_TYPE_DATA_PTR
, "general", "org.gnu.gdb.aarch64.core" },
713 { ARMV8_PC
, "pc", 64, REG_TYPE_CODE_PTR
, "general", "org.gnu.gdb.aarch64.core" },
715 { ARMV8_xPSR
, "CPSR", 32, REG_TYPE_UINT32
, "general", "org.gnu.gdb.aarch64.core" },
718 #define ARMV8_NUM_REGS ARRAY_SIZE(armv8_regs)
721 static int armv8_get_core_reg(struct reg
*reg
)
724 struct arm_reg
*armv8_reg
= reg
->arch_info
;
725 struct target
*target
= armv8_reg
->target
;
726 struct arm
*arm
= target_to_arm(target
);
728 if (target
->state
!= TARGET_HALTED
)
729 return ERROR_TARGET_NOT_HALTED
;
731 retval
= arm
->read_core_reg(target
, reg
, armv8_reg
->num
, arm
->core_mode
);
736 static int armv8_set_core_reg(struct reg
*reg
, uint8_t *buf
)
738 struct arm_reg
*armv8_reg
= reg
->arch_info
;
739 struct target
*target
= armv8_reg
->target
;
740 struct arm
*arm
= target_to_arm(target
);
741 uint64_t value
= buf_get_u64(buf
, 0, 64);
743 if (target
->state
!= TARGET_HALTED
)
744 return ERROR_TARGET_NOT_HALTED
;
746 if (reg
== arm
->cpsr
) {
747 armv8_set_cpsr(arm
, (uint32_t)value
);
749 buf_set_u64(reg
->value
, 0, 64, value
);
758 static const struct reg_arch_type armv8_reg_type
= {
759 .get
= armv8_get_core_reg
,
760 .set
= armv8_set_core_reg
,
763 /** Builds cache of architecturally defined registers. */
764 struct reg_cache
*armv8_build_reg_cache(struct target
*target
)
766 struct armv8_common
*armv8
= target_to_armv8(target
);
767 struct arm
*arm
= &armv8
->arm
;
768 int num_regs
= ARMV8_NUM_REGS
;
769 struct reg_cache
**cache_p
= register_get_last_cache_p(&target
->reg_cache
);
770 struct reg_cache
*cache
= malloc(sizeof(struct reg_cache
));
771 struct reg
*reg_list
= calloc(num_regs
, sizeof(struct reg
));
772 struct arm_reg
*arch_info
= calloc(num_regs
, sizeof(struct arm_reg
));
773 struct reg_feature
*feature
;
776 /* Build the process context cache */
777 cache
->name
= "arm v8 registers";
779 cache
->reg_list
= reg_list
;
780 cache
->num_regs
= num_regs
;
783 for (i
= 0; i
< num_regs
; i
++) {
784 arch_info
[i
].num
= armv8_regs
[i
].id
;
785 arch_info
[i
].target
= target
;
786 arch_info
[i
].arm
= arm
;
788 reg_list
[i
].name
= armv8_regs
[i
].name
;
789 reg_list
[i
].size
= armv8_regs
[i
].bits
;
790 reg_list
[i
].value
= calloc(1, 8);
791 reg_list
[i
].dirty
= 0;
792 reg_list
[i
].valid
= 0;
793 reg_list
[i
].type
= &armv8_reg_type
;
794 reg_list
[i
].arch_info
= &arch_info
[i
];
796 reg_list
[i
].group
= armv8_regs
[i
].group
;
797 reg_list
[i
].number
= i
;
798 reg_list
[i
].exist
= true;
799 reg_list
[i
].caller_save
= true; /* gdb defaults to true */
801 feature
= calloc(1, sizeof(struct reg_feature
));
803 feature
->name
= armv8_regs
[i
].feature
;
804 reg_list
[i
].feature
= feature
;
806 LOG_ERROR("unable to allocate feature list");
808 reg_list
[i
].reg_data_type
= calloc(1, sizeof(struct reg_data_type
));
809 if (reg_list
[i
].reg_data_type
)
810 reg_list
[i
].reg_data_type
->type
= armv8_regs
[i
].type
;
812 LOG_ERROR("unable to allocate reg type list");
815 arm
->cpsr
= reg_list
+ ARMV8_xPSR
;
816 arm
->pc
= reg_list
+ ARMV8_PC
;
817 arm
->core_cache
= cache
;
822 struct reg
*armv8_reg_current(struct arm
*arm
, unsigned regnum
)
826 if (regnum
> (ARMV8_LAST_REG
- 1))
829 r
= arm
->core_cache
->reg_list
+ regnum
;
833 const struct command_registration armv8_command_handlers
[] = {
835 .chain
= dap_command_handlers
,
837 COMMAND_REGISTRATION_DONE
841 int armv8_get_gdb_reg_list(struct target
*target
,
842 struct reg
**reg_list
[], int *reg_list_size
,
843 enum target_register_class reg_class
)
845 struct arm
*arm
= target_to_arm(target
);
849 case REG_CLASS_GENERAL
:
851 *reg_list_size
= ARMV8_LAST_REG
;
852 *reg_list
= malloc(sizeof(struct reg
*) * (*reg_list_size
));
854 for (i
= 0; i
< ARMV8_LAST_REG
; i
++)
855 (*reg_list
)[i
] = armv8_reg_current(arm
, i
);
860 LOG_ERROR("not a valid register class type in query.");
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)