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
) {
287 case SYSTEM_AAR64_MODE_EL0t
:
288 arm
->core_mode
= ARMV8_64_EL0T
;
290 case SYSTEM_AAR64_MODE_EL1t
:
291 arm
->core_mode
= ARMV8_64_EL0T
;
293 case SYSTEM_AAR64_MODE_EL1h
:
294 arm
->core_mode
= ARMV8_64_EL1H
;
296 case SYSTEM_AAR64_MODE_EL2t
:
297 arm
->core_mode
= ARMV8_64_EL2T
;
299 case SYSTEM_AAR64_MODE_EL2h
:
300 arm
->core_mode
= ARMV8_64_EL2H
;
302 case SYSTEM_AAR64_MODE_EL3t
:
303 arm
->core_mode
= ARMV8_64_EL3T
;
305 case SYSTEM_AAR64_MODE_EL3h
:
306 arm
->core_mode
= ARMV8_64_EL3H
;
309 LOG_DEBUG("unknow mode 0x%x", (unsigned) (mode
));
313 arm
->core_mode
= mode
;
316 LOG_DEBUG("set CPSR %#8.8x: %s mode, %s state", (unsigned) cpsr
,
317 armv8_mode_name(arm
->core_mode
),
318 armv8_state_strings
[arm
->core_state
]);
321 static void armv8_show_fault_registers32(struct armv8_common
*armv8
)
323 uint32_t dfsr
, ifsr
, dfar
, ifar
;
324 struct arm_dpm
*dpm
= armv8
->arm
.dpm
;
327 retval
= dpm
->prepare(dpm
);
328 if (retval
!= ERROR_OK
)
331 /* ARMV4_5_MRC(cpnum, op1, r0, CRn, CRm, op2) */
333 /* c5/c0 - {data, instruction} fault status registers */
334 retval
= dpm
->instr_read_data_r0(dpm
,
335 T32_FMTITR(ARMV4_5_MRC(15, 0, 0, 5, 0, 0)),
337 if (retval
!= ERROR_OK
)
340 retval
= dpm
->instr_read_data_r0(dpm
,
341 T32_FMTITR(ARMV4_5_MRC(15, 0, 0, 5, 0, 1)),
343 if (retval
!= ERROR_OK
)
346 /* c6/c0 - {data, instruction} fault address registers */
347 retval
= dpm
->instr_read_data_r0(dpm
,
348 T32_FMTITR(ARMV4_5_MRC(15, 0, 0, 6, 0, 0)),
350 if (retval
!= ERROR_OK
)
353 retval
= dpm
->instr_read_data_r0(dpm
,
354 T32_FMTITR(ARMV4_5_MRC(15, 0, 0, 6, 0, 2)),
356 if (retval
!= ERROR_OK
)
359 LOG_USER("Data fault registers DFSR: %8.8" PRIx32
360 ", DFAR: %8.8" PRIx32
, dfsr
, dfar
);
361 LOG_USER("Instruction fault registers IFSR: %8.8" PRIx32
362 ", IFAR: %8.8" PRIx32
, ifsr
, ifar
);
365 /* (void) */ dpm
->finish(dpm
);
368 static void armv8_show_fault_registers(struct target
*target
)
370 struct armv8_common
*armv8
= target_to_armv8(target
);
372 if (armv8
->arm
.core_state
!= ARM_STATE_AARCH64
)
373 armv8_show_fault_registers32(armv8
);
376 static uint8_t armv8_pa_size(uint32_t ps
)
399 LOG_INFO("Unknow physicall address size");
405 static __unused
int armv8_read_ttbcr32(struct target
*target
)
407 struct armv8_common
*armv8
= target_to_armv8(target
);
408 struct arm_dpm
*dpm
= armv8
->arm
.dpm
;
409 uint32_t ttbcr
, ttbcr_n
;
410 int retval
= dpm
->prepare(dpm
);
411 if (retval
!= ERROR_OK
)
413 /* MRC p15,0,<Rt>,c2,c0,2 ; Read CP15 Translation Table Base Control Register*/
414 retval
= dpm
->instr_read_data_r0(dpm
,
415 T32_FMTITR(ARMV4_5_MRC(15, 0, 0, 2, 0, 2)),
417 if (retval
!= ERROR_OK
)
420 LOG_DEBUG("ttbcr %" PRIx32
, ttbcr
);
422 ttbcr_n
= ttbcr
& 0x7;
423 armv8
->armv8_mmu
.ttbcr
= ttbcr
;
426 * ARM Architecture Reference Manual (ARMv7-A and ARMv7-Redition),
427 * document # ARM DDI 0406C
429 armv8
->armv8_mmu
.ttbr_range
[0] = 0xffffffff >> ttbcr_n
;
430 armv8
->armv8_mmu
.ttbr_range
[1] = 0xffffffff;
431 armv8
->armv8_mmu
.ttbr_mask
[0] = 0xffffffff << (14 - ttbcr_n
);
432 armv8
->armv8_mmu
.ttbr_mask
[1] = 0xffffffff << 14;
434 LOG_DEBUG("ttbr1 %s, ttbr0_mask %" PRIx32
" ttbr1_mask %" PRIx32
,
435 (ttbcr_n
!= 0) ? "used" : "not used",
436 armv8
->armv8_mmu
.ttbr_mask
[0],
437 armv8
->armv8_mmu
.ttbr_mask
[1]);
444 static int armv8_read_ttbcr(struct target
*target
)
446 struct armv8_common
*armv8
= target_to_armv8(target
);
447 struct arm_dpm
*dpm
= armv8
->arm
.dpm
;
448 struct arm
*arm
= &armv8
->arm
;
452 int retval
= dpm
->prepare(dpm
);
453 if (retval
!= ERROR_OK
)
456 /* claaer ttrr1_used and ttbr0_mask */
457 memset(&armv8
->armv8_mmu
.ttbr1_used
, 0, sizeof(armv8
->armv8_mmu
.ttbr1_used
));
458 memset(&armv8
->armv8_mmu
.ttbr0_mask
, 0, sizeof(armv8
->armv8_mmu
.ttbr0_mask
));
460 switch (arm
->core_mode
) {
463 retval
= dpm
->instr_read_data_r0(dpm
,
464 ARMV8_MRS(SYSTEM_TCR_EL3
, 0),
466 retval
+= dpm
->instr_read_data_r0_64(dpm
,
467 ARMV8_MRS(SYSTEM_TTBR0_EL3
, 0),
469 if (retval
!= ERROR_OK
)
471 armv8
->va_size
= 64 - (ttbcr
& 0x3F);
472 armv8
->pa_size
= armv8_pa_size((ttbcr
>> 16) & 7);
473 armv8
->page_size
= (ttbcr
>> 14) & 3;
477 retval
= dpm
->instr_read_data_r0(dpm
,
478 ARMV8_MRS(SYSTEM_TCR_EL2
, 0),
480 retval
+= dpm
->instr_read_data_r0_64(dpm
,
481 ARMV8_MRS(SYSTEM_TTBR0_EL2
, 0),
483 if (retval
!= ERROR_OK
)
485 armv8
->va_size
= 64 - (ttbcr
& 0x3F);
486 armv8
->pa_size
= armv8_pa_size((ttbcr
>> 16) & 7);
487 armv8
->page_size
= (ttbcr
>> 14) & 3;
492 retval
= dpm
->instr_read_data_r0_64(dpm
,
493 ARMV8_MRS(SYSTEM_TCR_EL1
, 0),
495 armv8
->va_size
= 64 - (ttbcr_64
& 0x3F);
496 armv8
->pa_size
= armv8_pa_size((ttbcr_64
>> 32) & 7);
497 armv8
->page_size
= (ttbcr_64
>> 14) & 3;
498 armv8
->armv8_mmu
.ttbr1_used
= (((ttbcr_64
>> 16) & 0x3F) != 0) ? 1 : 0;
499 armv8
->armv8_mmu
.ttbr0_mask
= 0x0000FFFFFFFFFFFF;
500 retval
+= dpm
->instr_read_data_r0_64(dpm
,
501 ARMV8_MRS(SYSTEM_TTBR0_EL1
| (armv8
->armv8_mmu
.ttbr1_used
), 0),
503 if (retval
!= ERROR_OK
)
507 LOG_ERROR("unknow core state");
511 if (retval
!= ERROR_OK
)
515 LOG_INFO("ttb1 %s ,ttb0_mask %llx",
516 armv8
->armv8_mmu
.ttbr1_used
? "used" : "not used",
517 armv8
->armv8_mmu
.ttbr0_mask
);
519 if (armv8
->armv8_mmu
.ttbr1_used
== 1) {
520 LOG_INFO("TTBR0 access above %" PRIx64
,
521 (uint64_t)(armv8
->armv8_mmu
.ttbr0_mask
));
522 armv8
->armv8_mmu
.os_border
= armv8
->armv8_mmu
.ttbr0_mask
;
524 /* fix me , default is hard coded LINUX border */
525 armv8
->armv8_mmu
.os_border
= 0xc0000000;
532 static int armv8_4K_translate(struct target
*target
, target_addr_t va
, target_addr_t
*val
)
534 LOG_ERROR("4K page Address translation need to add");
539 /* method adapted to cortex A : reused arm v4 v5 method*/
540 int armv8_mmu_translate_va(struct target
*target
, target_addr_t va
, target_addr_t
*val
)
542 int retval
= ERROR_FAIL
;
543 struct armv8_common
*armv8
= target_to_armv8(target
);
544 struct arm_dpm
*dpm
= armv8
->arm
.dpm
;
546 retval
= dpm
->prepare(dpm
);
547 retval
+= armv8_read_ttbcr(target
);
548 if (retval
!= ERROR_OK
)
550 if (armv8
->page_size
== 0)
551 return armv8_4K_translate(target
, va
, val
);
558 /* V8 method VA TO PA */
559 int armv8_mmu_translate_va_pa(struct target
*target
, target_addr_t va
,
560 target_addr_t
*val
, int meminfo
)
565 int armv8_handle_cache_info_command(struct command_context
*cmd_ctx
,
566 struct armv8_cache_common
*armv8_cache
)
568 if (armv8_cache
->info
== -1) {
569 command_print(cmd_ctx
, "cache not yet identified");
573 if (armv8_cache
->display_cache_info
)
574 armv8_cache
->display_cache_info(cmd_ctx
, armv8_cache
);
578 int armv8_init_arch_info(struct target
*target
, struct armv8_common
*armv8
)
580 struct arm
*arm
= &armv8
->arm
;
581 arm
->arch_info
= armv8
;
582 target
->arch_info
= &armv8
->arm
;
583 /* target is useful in all function arm v4 5 compatible */
584 armv8
->arm
.target
= target
;
585 armv8
->arm
.common_magic
= ARM_COMMON_MAGIC
;
586 armv8
->common_magic
= ARMV8_COMMON_MAGIC
;
588 arm
->read_core_reg
= armv8_read_core_reg
;
590 arm
->write_core_reg
= armv8_write_core_reg
;
593 armv8
->armv8_mmu
.armv8_cache
.l2_cache
= NULL
;
594 armv8
->armv8_mmu
.armv8_cache
.info
= -1;
595 armv8
->armv8_mmu
.armv8_cache
.flush_all_data_cache
= NULL
;
596 armv8
->armv8_mmu
.armv8_cache
.display_cache_info
= NULL
;
600 int armv8_aarch64_state(struct target
*target
)
602 struct arm
*arm
= target_to_arm(target
);
604 if (arm
->common_magic
!= ARM_COMMON_MAGIC
) {
605 LOG_ERROR("BUG: called for a non-ARM target");
609 LOG_USER("target halted in %s state due to %s, current mode: %s\n"
610 "cpsr: 0x%8.8" PRIx32
" pc: 0x%" PRIx64
"%s",
611 armv8_state_strings
[arm
->core_state
],
612 debug_reason_name(target
),
613 armv8_mode_name(arm
->core_mode
),
614 buf_get_u32(arm
->cpsr
->value
, 0, 32),
615 buf_get_u64(arm
->pc
->value
, 0, 64),
616 arm
->is_semihosting
? ", semihosting" : "");
621 int armv8_arch_state(struct target
*target
)
623 static const char * const state
[] = {
624 "disabled", "enabled"
627 struct armv8_common
*armv8
= target_to_armv8(target
);
628 struct arm
*arm
= &armv8
->arm
;
630 if (armv8
->common_magic
!= ARMV8_COMMON_MAGIC
) {
631 LOG_ERROR("BUG: called for a non-Armv8 target");
632 return ERROR_COMMAND_SYNTAX_ERROR
;
635 if (arm
->core_state
== ARM_STATE_AARCH64
)
636 armv8_aarch64_state(target
);
638 arm_arch_state(target
);
640 LOG_USER("MMU: %s, D-Cache: %s, I-Cache: %s",
641 state
[armv8
->armv8_mmu
.mmu_enabled
],
642 state
[armv8
->armv8_mmu
.armv8_cache
.d_u_cache_enabled
],
643 state
[armv8
->armv8_mmu
.armv8_cache
.i_cache_enabled
]);
645 if (arm
->core_mode
== ARM_MODE_ABT
)
646 armv8_show_fault_registers(target
);
648 if (target
->debug_reason
== DBG_REASON_WATCHPOINT
)
649 LOG_USER("Watchpoint triggered at PC %#08x",
650 (unsigned) armv8
->dpm
.wp_pc
);
655 static const struct {
663 { ARMV8_R0
, "x0", 64, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core" },
664 { ARMV8_R1
, "x1", 64, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core" },
665 { ARMV8_R2
, "x2", 64, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core" },
666 { ARMV8_R3
, "x3", 64, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core" },
667 { ARMV8_R4
, "x4", 64, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core" },
668 { ARMV8_R5
, "x5", 64, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core" },
669 { ARMV8_R6
, "x6", 64, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core" },
670 { ARMV8_R7
, "x7", 64, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core" },
671 { ARMV8_R8
, "x8", 64, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core" },
672 { ARMV8_R9
, "x9", 64, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core" },
673 { ARMV8_R10
, "x10", 64, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core" },
674 { ARMV8_R11
, "x11", 64, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core" },
675 { ARMV8_R12
, "x12", 64, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core" },
676 { ARMV8_R13
, "x13", 64, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core" },
677 { ARMV8_R14
, "x14", 64, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core" },
678 { ARMV8_R15
, "x15", 64, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core" },
679 { ARMV8_R16
, "x16", 64, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core" },
680 { ARMV8_R17
, "x17", 64, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core" },
681 { ARMV8_R18
, "x18", 64, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core" },
682 { ARMV8_R19
, "x19", 64, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core" },
683 { ARMV8_R20
, "x20", 64, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core" },
684 { ARMV8_R21
, "x21", 64, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core" },
685 { ARMV8_R22
, "x22", 64, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core" },
686 { ARMV8_R23
, "x23", 64, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core" },
687 { ARMV8_R24
, "x24", 64, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core" },
688 { ARMV8_R25
, "x25", 64, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core" },
689 { ARMV8_R26
, "x26", 64, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core" },
690 { ARMV8_R27
, "x27", 64, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core" },
691 { ARMV8_R28
, "x28", 64, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core" },
692 { ARMV8_R29
, "x29", 64, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core" },
693 { ARMV8_R30
, "x30", 64, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core" },
695 { ARMV8_R31
, "sp", 64, REG_TYPE_DATA_PTR
, "general", "org.gnu.gdb.aarch64.core" },
696 { ARMV8_PC
, "pc", 64, REG_TYPE_CODE_PTR
, "general", "org.gnu.gdb.aarch64.core" },
698 { ARMV8_xPSR
, "CPSR", 32, REG_TYPE_UINT32
, "general", "org.gnu.gdb.aarch64.core" },
701 #define ARMV8_NUM_REGS ARRAY_SIZE(armv8_regs)
704 static int armv8_get_core_reg(struct reg
*reg
)
707 struct arm_reg
*armv8_reg
= reg
->arch_info
;
708 struct target
*target
= armv8_reg
->target
;
709 struct arm
*arm
= target_to_arm(target
);
711 if (target
->state
!= TARGET_HALTED
)
712 return ERROR_TARGET_NOT_HALTED
;
714 retval
= arm
->read_core_reg(target
, reg
, armv8_reg
->num
, arm
->core_mode
);
719 static int armv8_set_core_reg(struct reg
*reg
, uint8_t *buf
)
721 struct arm_reg
*armv8_reg
= reg
->arch_info
;
722 struct target
*target
= armv8_reg
->target
;
723 struct arm
*arm
= target_to_arm(target
);
724 uint64_t value
= buf_get_u64(buf
, 0, 64);
726 if (target
->state
!= TARGET_HALTED
)
727 return ERROR_TARGET_NOT_HALTED
;
729 if (reg
== arm
->cpsr
) {
730 armv8_set_cpsr(arm
, (uint32_t)value
);
732 buf_set_u64(reg
->value
, 0, 64, value
);
741 static const struct reg_arch_type armv8_reg_type
= {
742 .get
= armv8_get_core_reg
,
743 .set
= armv8_set_core_reg
,
746 /** Builds cache of architecturally defined registers. */
747 struct reg_cache
*armv8_build_reg_cache(struct target
*target
)
749 struct armv8_common
*armv8
= target_to_armv8(target
);
750 struct arm
*arm
= &armv8
->arm
;
751 int num_regs
= ARMV8_NUM_REGS
;
752 struct reg_cache
**cache_p
= register_get_last_cache_p(&target
->reg_cache
);
753 struct reg_cache
*cache
= malloc(sizeof(struct reg_cache
));
754 struct reg
*reg_list
= calloc(num_regs
, sizeof(struct reg
));
755 struct arm_reg
*arch_info
= calloc(num_regs
, sizeof(struct arm_reg
));
756 struct reg_feature
*feature
;
759 /* Build the process context cache */
760 cache
->name
= "arm v8 registers";
762 cache
->reg_list
= reg_list
;
763 cache
->num_regs
= num_regs
;
766 for (i
= 0; i
< num_regs
; i
++) {
767 arch_info
[i
].num
= armv8_regs
[i
].id
;
768 arch_info
[i
].target
= target
;
769 arch_info
[i
].arm
= arm
;
771 reg_list
[i
].name
= armv8_regs
[i
].name
;
772 reg_list
[i
].size
= armv8_regs
[i
].bits
;
773 reg_list
[i
].value
= calloc(1, 8);
774 reg_list
[i
].dirty
= 0;
775 reg_list
[i
].valid
= 0;
776 reg_list
[i
].type
= &armv8_reg_type
;
777 reg_list
[i
].arch_info
= &arch_info
[i
];
779 reg_list
[i
].group
= armv8_regs
[i
].group
;
780 reg_list
[i
].number
= i
;
781 reg_list
[i
].exist
= true;
782 reg_list
[i
].caller_save
= true; /* gdb defaults to true */
784 feature
= calloc(1, sizeof(struct reg_feature
));
786 feature
->name
= armv8_regs
[i
].feature
;
787 reg_list
[i
].feature
= feature
;
789 LOG_ERROR("unable to allocate feature list");
791 reg_list
[i
].reg_data_type
= calloc(1, sizeof(struct reg_data_type
));
792 if (reg_list
[i
].reg_data_type
)
793 reg_list
[i
].reg_data_type
->type
= armv8_regs
[i
].type
;
795 LOG_ERROR("unable to allocate reg type list");
798 arm
->cpsr
= reg_list
+ ARMV8_xPSR
;
799 arm
->pc
= reg_list
+ ARMV8_PC
;
800 arm
->core_cache
= cache
;
805 struct reg
*armv8_reg_current(struct arm
*arm
, unsigned regnum
)
809 if (regnum
> (ARMV8_LAST_REG
- 1))
812 r
= arm
->core_cache
->reg_list
+ regnum
;
816 const struct command_registration armv8_command_handlers
[] = {
818 .chain
= dap_command_handlers
,
820 COMMAND_REGISTRATION_DONE
824 int armv8_get_gdb_reg_list(struct target
*target
,
825 struct reg
**reg_list
[], int *reg_list_size
,
826 enum target_register_class reg_class
)
828 struct arm
*arm
= target_to_arm(target
);
832 case REG_CLASS_GENERAL
:
834 *reg_list_size
= ARMV8_LAST_REG
;
835 *reg_list
= malloc(sizeof(struct reg
*) * (*reg_list_size
));
837 for (i
= 0; i
< ARMV8_LAST_REG
; i
++)
838 (*reg_list
)[i
] = armv8_reg_current(arm
, i
);
843 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)