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 /* For user and system modes, these list indices for all registers.
48 * otherwise they're just indices for the shadow registers and SPSR.
50 unsigned short n_indices
;
51 const uint8_t *indices
;
52 } armv8_mode_data
[] = {
53 /* These special modes are currently only supported
54 * by ARMv6M and ARMv7M profiles */
101 .psr
= ARMV8_64_EL3T
,
105 .psr
= ARMV8_64_EL3H
,
109 /** Map PSR mode bits to the name of an ARM processor operating mode. */
110 const char *armv8_mode_name(unsigned psr_mode
)
112 for (unsigned i
= 0; i
< ARRAY_SIZE(armv8_mode_data
); i
++) {
113 if (armv8_mode_data
[i
].psr
== psr_mode
)
114 return armv8_mode_data
[i
].name
;
116 LOG_ERROR("unrecognized psr mode: %#02x", psr_mode
);
117 return "UNRECOGNIZED";
120 int armv8_mode_to_number(enum arm_mode mode
)
124 /* map MODE_ANY to user mode */
157 LOG_ERROR("invalid mode value encountered %d", mode
);
163 static int armv8_read_core_reg(struct target
*target
, struct reg
*r
,
164 int num
, enum arm_mode mode
)
168 struct arm_reg
*armv8_core_reg
;
169 struct armv8_common
*armv8
= target_to_armv8(target
);
171 assert(num
< (int)armv8
->arm
.core_cache
->num_regs
);
173 armv8_core_reg
= armv8
->arm
.core_cache
->reg_list
[num
].arch_info
;
174 retval
= armv8
->load_core_reg_u64(target
,
175 armv8_core_reg
->num
, ®_value
);
177 buf_set_u64(armv8
->arm
.core_cache
->reg_list
[num
].value
, 0, 64, reg_value
);
178 armv8
->arm
.core_cache
->reg_list
[num
].valid
= 1;
179 armv8
->arm
.core_cache
->reg_list
[num
].dirty
= 0;
185 static int armv8_write_core_reg(struct target
*target
, struct reg
*r
,
186 int num
, enum arm_mode mode
, target_addr_t value
)
189 struct arm_reg
*armv8_core_reg
;
190 struct armv8_common
*armv8
= target_to_armv8(target
);
192 assert(num
< (int)armv8
->arm
.core_cache
->num_regs
);
194 armv8_core_reg
= armv8
->arm
.core_cache
->reg_list
[num
].arch_info
;
195 retval
= armv8
->store_core_reg_u64(target
,
198 if (retval
!= ERROR_OK
) {
199 LOG_ERROR("JTAG failure");
200 armv8
->arm
.core_cache
->reg_list
[num
].dirty
= armv8
->arm
.core_cache
->reg_list
[num
].valid
;
201 return ERROR_JTAG_DEVICE_ERROR
;
204 LOG_DEBUG("write core reg %i value 0x%" PRIx64
"", num
, value
);
205 armv8
->arm
.core_cache
->reg_list
[num
].valid
= 1;
206 armv8
->arm
.core_cache
->reg_list
[num
].dirty
= 0;
212 * Configures host-side ARM records to reflect the specified CPSR.
213 * Later, code can use arm_reg_current() to map register numbers
214 * according to how they are exposed by this mode.
216 void armv8_set_cpsr(struct arm
*arm
, uint32_t cpsr
)
218 uint32_t mode
= cpsr
& 0x1F;
220 /* NOTE: this may be called very early, before the register
221 * cache is set up. We can't defend against many errors, in
222 * particular against CPSRs that aren't valid *here* ...
225 buf_set_u32(arm
->cpsr
->value
, 0, 32, cpsr
);
226 arm
->cpsr
->valid
= 1;
227 arm
->cpsr
->dirty
= 0;
230 /* Older ARMs won't have the J bit */
231 enum arm_state state
= 0xFF;
233 if (((cpsr
& 0x10) >> 4) == 0) {
234 state
= ARM_STATE_AARCH64
;
236 if (cpsr
& (1 << 5)) { /* T */
237 if (cpsr
& (1 << 24)) { /* J */
238 LOG_WARNING("ThumbEE -- incomplete support");
239 state
= ARM_STATE_THUMB_EE
;
241 state
= ARM_STATE_THUMB
;
243 if (cpsr
& (1 << 24)) { /* J */
244 LOG_ERROR("Jazelle state handling is BROKEN!");
245 state
= ARM_STATE_JAZELLE
;
247 state
= ARM_STATE_ARM
;
250 arm
->core_state
= state
;
251 if (arm
->core_state
== ARM_STATE_AARCH64
) {
253 case SYSTEM_AAR64_MODE_EL0t
:
254 arm
->core_mode
= ARMV8_64_EL0T
;
256 case SYSTEM_AAR64_MODE_EL1t
:
257 arm
->core_mode
= ARMV8_64_EL0T
;
259 case SYSTEM_AAR64_MODE_EL1h
:
260 arm
->core_mode
= ARMV8_64_EL1H
;
262 case SYSTEM_AAR64_MODE_EL2t
:
263 arm
->core_mode
= ARMV8_64_EL2T
;
265 case SYSTEM_AAR64_MODE_EL2h
:
266 arm
->core_mode
= ARMV8_64_EL2H
;
268 case SYSTEM_AAR64_MODE_EL3t
:
269 arm
->core_mode
= ARMV8_64_EL3T
;
271 case SYSTEM_AAR64_MODE_EL3h
:
272 arm
->core_mode
= ARMV8_64_EL3H
;
275 LOG_DEBUG("unknow mode 0x%x", (unsigned) (mode
));
279 arm
->core_mode
= mode
;
282 LOG_DEBUG("set CPSR %#8.8x: %s mode, %s state", (unsigned) cpsr
,
283 armv8_mode_name(arm
->core_mode
),
284 armv8_state_strings
[arm
->core_state
]);
287 static void armv8_show_fault_registers32(struct armv8_common
*armv8
)
289 uint32_t dfsr
, ifsr
, dfar
, ifar
;
290 struct arm_dpm
*dpm
= armv8
->arm
.dpm
;
293 retval
= dpm
->prepare(dpm
);
294 if (retval
!= ERROR_OK
)
297 /* ARMV4_5_MRC(cpnum, op1, r0, CRn, CRm, op2) */
299 /* c5/c0 - {data, instruction} fault status registers */
300 retval
= dpm
->instr_read_data_r0(dpm
,
301 T32_FMTITR(ARMV4_5_MRC(15, 0, 0, 5, 0, 0)),
303 if (retval
!= ERROR_OK
)
306 retval
= dpm
->instr_read_data_r0(dpm
,
307 T32_FMTITR(ARMV4_5_MRC(15, 0, 0, 5, 0, 1)),
309 if (retval
!= ERROR_OK
)
312 /* c6/c0 - {data, instruction} fault address registers */
313 retval
= dpm
->instr_read_data_r0(dpm
,
314 T32_FMTITR(ARMV4_5_MRC(15, 0, 0, 6, 0, 0)),
316 if (retval
!= ERROR_OK
)
319 retval
= dpm
->instr_read_data_r0(dpm
,
320 T32_FMTITR(ARMV4_5_MRC(15, 0, 0, 6, 0, 2)),
322 if (retval
!= ERROR_OK
)
325 LOG_USER("Data fault registers DFSR: %8.8" PRIx32
326 ", DFAR: %8.8" PRIx32
, dfsr
, dfar
);
327 LOG_USER("Instruction fault registers IFSR: %8.8" PRIx32
328 ", IFAR: %8.8" PRIx32
, ifsr
, ifar
);
331 /* (void) */ dpm
->finish(dpm
);
334 static void armv8_show_fault_registers(struct target
*target
)
336 struct armv8_common
*armv8
= target_to_armv8(target
);
338 if (armv8
->arm
.core_state
!= ARM_STATE_AARCH64
)
339 armv8_show_fault_registers32(armv8
);
342 static uint8_t armv8_pa_size(uint32_t ps
)
365 LOG_INFO("Unknow physicall address size");
371 static int armv8_read_ttbcr32(struct target
*target
)
373 struct armv8_common
*armv8
= target_to_armv8(target
);
374 struct arm_dpm
*dpm
= armv8
->arm
.dpm
;
375 uint32_t ttbcr
, ttbcr_n
;
376 int retval
= dpm
->prepare(dpm
);
377 if (retval
!= ERROR_OK
)
379 /* MRC p15,0,<Rt>,c2,c0,2 ; Read CP15 Translation Table Base Control Register*/
380 retval
= dpm
->instr_read_data_r0(dpm
,
381 T32_FMTITR(ARMV4_5_MRC(15, 0, 0, 2, 0, 2)),
383 if (retval
!= ERROR_OK
)
386 LOG_DEBUG("ttbcr %" PRIx32
, ttbcr
);
388 ttbcr_n
= ttbcr
& 0x7;
389 armv8
->armv8_mmu
.ttbcr
= ttbcr
;
392 * ARM Architecture Reference Manual (ARMv7-A and ARMv7-Redition),
393 * document # ARM DDI 0406C
395 armv8
->armv8_mmu
.ttbr_range
[0] = 0xffffffff >> ttbcr_n
;
396 armv8
->armv8_mmu
.ttbr_range
[1] = 0xffffffff;
397 armv8
->armv8_mmu
.ttbr_mask
[0] = 0xffffffff << (14 - ttbcr_n
);
398 armv8
->armv8_mmu
.ttbr_mask
[1] = 0xffffffff << 14;
400 LOG_DEBUG("ttbr1 %s, ttbr0_mask %" PRIx32
" ttbr1_mask %" PRIx32
,
401 (ttbcr_n
!= 0) ? "used" : "not used",
402 armv8
->armv8_mmu
.ttbr_mask
[0],
403 armv8
->armv8_mmu
.ttbr_mask
[1]);
410 static int armv8_read_ttbcr(struct target
*target
)
412 struct armv8_common
*armv8
= target_to_armv8(target
);
413 struct arm_dpm
*dpm
= armv8
->arm
.dpm
;
414 struct arm
*arm
= &armv8
->arm
;
418 int retval
= dpm
->prepare(dpm
);
419 if (retval
!= ERROR_OK
)
422 /* claaer ttrr1_used and ttbr0_mask */
423 memset(&armv8
->armv8_mmu
.ttbr1_used
, 0, sizeof(armv8
->armv8_mmu
.ttbr1_used
));
424 memset(&armv8
->armv8_mmu
.ttbr0_mask
, 0, sizeof(armv8
->armv8_mmu
.ttbr0_mask
));
426 switch (arm
->core_mode
) {
429 retval
= dpm
->instr_read_data_r0(dpm
,
430 ARMV8_MRS(SYSTEM_TCR_EL3
, 0),
432 retval
+= dpm
->instr_read_data_r0_64(dpm
,
433 ARMV8_MRS(SYSTEM_TTBR0_EL3
, 0),
435 if (retval
!= ERROR_OK
)
437 armv8
->va_size
= 64 - (ttbcr
& 0x3F);
438 armv8
->pa_size
= armv8_pa_size((ttbcr
>> 16) & 7);
439 armv8
->page_size
= (ttbcr
>> 14) & 3;
443 retval
= dpm
->instr_read_data_r0(dpm
,
444 ARMV8_MRS(SYSTEM_TCR_EL2
, 0),
446 retval
+= dpm
->instr_read_data_r0_64(dpm
,
447 ARMV8_MRS(SYSTEM_TTBR0_EL2
, 0),
449 if (retval
!= ERROR_OK
)
451 armv8
->va_size
= 64 - (ttbcr
& 0x3F);
452 armv8
->pa_size
= armv8_pa_size((ttbcr
>> 16) & 7);
453 armv8
->page_size
= (ttbcr
>> 14) & 3;
458 retval
= dpm
->instr_read_data_r0_64(dpm
,
459 ARMV8_MRS(SYSTEM_TCR_EL1
, 0),
461 armv8
->va_size
= 64 - (ttbcr_64
& 0x3F);
462 armv8
->pa_size
= armv8_pa_size((ttbcr_64
>> 32) & 7);
463 armv8
->page_size
= (ttbcr_64
>> 14) & 3;
464 armv8
->armv8_mmu
.ttbr1_used
= (((ttbcr_64
>> 16) & 0x3F) != 0) ? 1 : 0;
465 armv8
->armv8_mmu
.ttbr0_mask
= 0x0000FFFFFFFFFFFF;
466 retval
+= dpm
->instr_read_data_r0_64(dpm
,
467 ARMV8_MRS(SYSTEM_TTBR0_EL1
| (armv8
->armv8_mmu
.ttbr1_used
), 0),
469 if (retval
!= ERROR_OK
)
473 LOG_ERROR("unknow core state");
477 if (retval
!= ERROR_OK
)
481 LOG_INFO("ttb1 %s ,ttb0_mask %llx",
482 armv8
->armv8_mmu
.ttbr1_used
? "used" : "not used",
483 armv8
->armv8_mmu
.ttbr0_mask
);
485 if (armv8
->armv8_mmu
.ttbr1_used
== 1) {
486 LOG_INFO("TTBR0 access above %" PRIx64
,
487 (uint64_t)(armv8
->armv8_mmu
.ttbr0_mask
));
488 armv8
->armv8_mmu
.os_border
= armv8
->armv8_mmu
.ttbr0_mask
;
490 /* fix me , default is hard coded LINUX border */
491 armv8
->armv8_mmu
.os_border
= 0xc0000000;
498 static int armv8_4K_translate(struct target
*target
, target_addr_t va
, target_addr_t
*val
)
500 LOG_ERROR("4K page Address translation need to add");
505 /* method adapted to cortex A : reused arm v4 v5 method*/
506 int armv8_mmu_translate_va(struct target
*target
, target_addr_t va
, target_addr_t
*val
)
508 int retval
= ERROR_FAIL
;
509 struct armv8_common
*armv8
= target_to_armv8(target
);
510 struct arm_dpm
*dpm
= armv8
->arm
.dpm
;
512 retval
= dpm
->prepare(dpm
);
513 retval
+= armv8_read_ttbcr(target
);
514 if (retval
!= ERROR_OK
)
516 if (armv8
->page_size
== 0)
517 return armv8_4K_translate(target
, va
, val
);
524 /* V8 method VA TO PA */
525 int armv8_mmu_translate_va_pa(struct target
*target
, target_addr_t va
,
526 target_addr_t
*val
, int meminfo
)
531 static int armv8_handle_inner_cache_info_command(struct command_context
*cmd_ctx
,
532 struct armv8_cache_common
*armv8_cache
)
534 if (armv8_cache
->ctype
== -1) {
535 command_print(cmd_ctx
, "cache not yet identified");
539 command_print(cmd_ctx
,
540 "D-Cache: linelen %" PRIi32
", associativity %" PRIi32
", nsets %" PRIi32
", cachesize %" PRId32
" KBytes",
541 armv8_cache
->d_u_size
.linelen
,
542 armv8_cache
->d_u_size
.associativity
,
543 armv8_cache
->d_u_size
.nsets
,
544 armv8_cache
->d_u_size
.cachesize
);
546 command_print(cmd_ctx
,
547 "I-Cache: linelen %" PRIi32
", associativity %" PRIi32
", nsets %" PRIi32
", cachesize %" PRId32
" KBytes",
548 armv8_cache
->i_size
.linelen
,
549 armv8_cache
->i_size
.associativity
,
550 armv8_cache
->i_size
.nsets
,
551 armv8_cache
->i_size
.cachesize
);
556 static int _armv8_flush_all_data(struct target
*target
)
558 struct armv8_common
*armv8
= target_to_armv8(target
);
559 struct arm_dpm
*dpm
= armv8
->arm
.dpm
;
560 struct armv8_cachesize
*d_u_size
=
561 &(armv8
->armv8_mmu
.armv8_cache
.d_u_size
);
562 int32_t c_way
, c_index
= d_u_size
->index
;
564 /* check that cache data is on at target halt */
565 if (!armv8
->armv8_mmu
.armv8_cache
.d_u_cache_enabled
) {
566 LOG_INFO("flushed not performed :cache not on at target halt");
569 retval
= dpm
->prepare(dpm
);
570 if (retval
!= ERROR_OK
)
573 c_way
= d_u_size
->way
;
575 uint32_t value
= (c_index
<< d_u_size
->index_shift
)
576 | (c_way
<< d_u_size
->way_shift
);
578 /* LOG_INFO ("%d %d %x",c_way,c_index,value); */
579 retval
= dpm
->instr_write_data_r0(dpm
,
580 ARMV8_MSR_GP(SYSTEM_DCCISW
, 0),
582 if (retval
!= ERROR_OK
)
585 } while (c_way
>= 0);
587 } while (c_index
>= 0);
590 LOG_ERROR("flushed failed");
595 static int armv8_flush_all_data(struct target
*target
)
597 int retval
= ERROR_FAIL
;
598 /* check that armv8_cache is correctly identify */
599 struct armv8_common
*armv8
= target_to_armv8(target
);
600 if (armv8
->armv8_mmu
.armv8_cache
.ctype
== -1) {
601 LOG_ERROR("trying to flush un-identified cache");
606 /* look if all the other target have been flushed in order to flush level
608 struct target_list
*head
;
611 while (head
!= (struct target_list
*)NULL
) {
613 if (curr
->state
== TARGET_HALTED
) {
614 LOG_INFO("Wait flushing data l1 on core %" PRId32
, curr
->coreid
);
615 retval
= _armv8_flush_all_data(curr
);
620 retval
= _armv8_flush_all_data(target
);
624 int armv8_handle_cache_info_command(struct command_context
*cmd_ctx
,
625 struct armv8_cache_common
*armv8_cache
)
627 if (armv8_cache
->ctype
== -1) {
628 command_print(cmd_ctx
, "cache not yet identified");
632 if (armv8_cache
->display_cache_info
)
633 armv8_cache
->display_cache_info(cmd_ctx
, armv8_cache
);
637 /* retrieve core id cluster id */
638 static int armv8_read_mpidr(struct target
*target
)
640 int retval
= ERROR_FAIL
;
641 struct armv8_common
*armv8
= target_to_armv8(target
);
642 struct arm_dpm
*dpm
= armv8
->arm
.dpm
;
645 retval
= dpm
->prepare(dpm
);
646 if (retval
!= ERROR_OK
)
648 /* MRC p15,0,<Rd>,c0,c0,5; read Multiprocessor ID register*/
650 retval
= dpm
->instr_read_data_r0(dpm
, armv8_opcode(armv8
, READ_REG_MPIDR
), &mpidr
);
651 if (retval
!= ERROR_OK
)
654 armv8
->multi_processor_system
= (mpidr
>> 30) & 1;
655 armv8
->cluster_id
= (mpidr
>> 8) & 0xf;
656 armv8
->cpu_id
= mpidr
& 0x3;
657 LOG_INFO("%s cluster %x core %x %s", target_name(target
),
660 armv8
->multi_processor_system
== 0 ? "multi core" : "mono core");
663 LOG_ERROR("mpdir not in multiprocessor format");
672 int armv8_identify_cache(struct target
*target
)
674 /* read cache descriptor */
675 int retval
= ERROR_FAIL
;
676 struct armv8_common
*armv8
= target_to_armv8(target
);
677 struct arm_dpm
*dpm
= armv8
->arm
.dpm
;
678 uint32_t cache_selected
, clidr
;
679 uint32_t cache_i_reg
, cache_d_reg
;
680 struct armv8_cache_common
*cache
= &(armv8
->armv8_mmu
.armv8_cache
);
681 int is_aarch64
= armv8
->arm
.core_state
== ARM_STATE_AARCH64
;
683 retval
= is_aarch64
? armv8_read_ttbcr(target
) : armv8_read_ttbcr32(target
);
684 if (retval
!= ERROR_OK
)
687 retval
= dpm
->prepare(dpm
);
688 if (retval
!= ERROR_OK
)
692 retval
= dpm
->instr_read_data_r0(dpm
, armv8_opcode(armv8
, READ_REG_CLIDR
), &clidr
);
693 if (retval
!= ERROR_OK
)
696 clidr
= (clidr
& 0x7000000) >> 23;
697 LOG_INFO("number of cache level %" PRIx32
, (uint32_t)(clidr
/ 2));
698 if ((clidr
/ 2) > 1) {
699 /* FIXME not supported present in cortex A8 and later */
700 /* in cortex A7, A15 */
701 LOG_ERROR("cache l2 present :not supported");
703 /* retrieve selected cache*/
704 retval
= dpm
->instr_read_data_r0(dpm
, armv8_opcode(armv8
, READ_REG_CSSELR
), &cache_selected
);
705 if (retval
!= ERROR_OK
)
708 /* select instruction cache
709 * [0] : 1 instruction cache selection , 0 data cache selection */
710 retval
= dpm
->instr_write_data_r0(dpm
, armv8_opcode(armv8
, WRITE_REG_CSSELR
), 1);
711 if (retval
!= ERROR_OK
)
715 * MRC P15,1,<RT>,C0, C0,0 ;on cortex A9 read CCSIDR
716 * [2:0] line size 001 eight word per line
717 * [27:13] NumSet 0x7f 16KB, 0xff 32Kbytes, 0x1ff 64Kbytes */
718 retval
= dpm
->instr_read_data_r0(dpm
, armv8_opcode(armv8
, READ_REG_CCSIDR
), &cache_i_reg
);
719 if (retval
!= ERROR_OK
)
722 /* select data cache*/
723 retval
= dpm
->instr_write_data_r0(dpm
, armv8_opcode(armv8
, WRITE_REG_CSSELR
), 0);
724 if (retval
!= ERROR_OK
)
727 retval
= dpm
->instr_read_data_r0(dpm
, armv8_opcode(armv8
, READ_REG_CCSIDR
), &cache_d_reg
);
728 if (retval
!= ERROR_OK
)
731 /* restore selected cache */
732 dpm
->instr_write_data_r0(dpm
, armv8_opcode(armv8
, WRITE_REG_CSSELR
), cache_selected
);
733 if (retval
!= ERROR_OK
)
738 cache
->d_u_size
.linelen
= 16 << (cache_d_reg
& 0x7);
739 cache
->d_u_size
.cachesize
= (((cache_d_reg
>> 13) & 0x7fff)+1)/8;
740 cache
->d_u_size
.nsets
= (cache_d_reg
>> 13) & 0x7fff;
741 cache
->d_u_size
.associativity
= ((cache_d_reg
>> 3) & 0x3ff) + 1;
742 /* compute info for set way operation on cache */
743 cache
->d_u_size
.index_shift
= (cache_d_reg
& 0x7) + 4;
744 cache
->d_u_size
.index
= (cache_d_reg
>> 13) & 0x7fff;
745 cache
->d_u_size
.way
= ((cache_d_reg
>> 3) & 0x3ff);
746 cache
->d_u_size
.way_shift
= cache
->d_u_size
.way
+ 1;
749 while (((cache
->d_u_size
.way_shift
>> i
) & 1) != 1)
751 cache
->d_u_size
.way_shift
= 32-i
;
754 LOG_INFO("data cache index %d << %d, way %d << %d",
755 cache
->d_u_size
.index
, cache
->d_u_size
.index_shift
,
757 cache
->d_u_size
.way_shift
);
759 LOG_INFO("data cache %d bytes %d KBytes asso %d ways",
760 cache
->d_u_size
.linelen
,
761 cache
->d_u_size
.cachesize
,
762 cache
->d_u_size
.associativity
);
764 cache
->i_size
.linelen
= 16 << (cache_i_reg
& 0x7);
765 cache
->i_size
.associativity
= ((cache_i_reg
>> 3) & 0x3ff) + 1;
766 cache
->i_size
.nsets
= (cache_i_reg
>> 13) & 0x7fff;
767 cache
->i_size
.cachesize
= (((cache_i_reg
>> 13) & 0x7fff)+1)/8;
768 /* compute info for set way operation on cache */
769 cache
->i_size
.index_shift
= (cache_i_reg
& 0x7) + 4;
770 cache
->i_size
.index
= (cache_i_reg
>> 13) & 0x7fff;
771 cache
->i_size
.way
= ((cache_i_reg
>> 3) & 0x3ff);
772 cache
->i_size
.way_shift
= cache
->i_size
.way
+ 1;
775 while (((cache
->i_size
.way_shift
>> i
) & 1) != 1)
777 cache
->i_size
.way_shift
= 32-i
;
780 LOG_INFO("instruction cache index %d << %d, way %d << %d",
781 cache
->i_size
.index
, cache
->i_size
.index_shift
,
782 cache
->i_size
.way
, cache
->i_size
.way_shift
);
784 LOG_INFO("instruction cache %d bytes %d KBytes asso %d ways",
785 cache
->i_size
.linelen
,
786 cache
->i_size
.cachesize
,
787 cache
->i_size
.associativity
);
789 /* if no l2 cache initialize l1 data cache flush function function */
790 if (armv8
->armv8_mmu
.armv8_cache
.flush_all_data_cache
== NULL
) {
791 armv8
->armv8_mmu
.armv8_cache
.display_cache_info
=
792 armv8_handle_inner_cache_info_command
;
793 armv8
->armv8_mmu
.armv8_cache
.flush_all_data_cache
=
794 armv8_flush_all_data
;
796 armv8
->armv8_mmu
.armv8_cache
.ctype
= 0;
800 armv8_read_mpidr(target
);
805 int armv8_init_arch_info(struct target
*target
, struct armv8_common
*armv8
)
807 struct arm
*arm
= &armv8
->arm
;
808 arm
->arch_info
= armv8
;
809 target
->arch_info
= &armv8
->arm
;
810 /* target is useful in all function arm v4 5 compatible */
811 armv8
->arm
.target
= target
;
812 armv8
->arm
.common_magic
= ARM_COMMON_MAGIC
;
813 armv8
->common_magic
= ARMV8_COMMON_MAGIC
;
815 arm
->read_core_reg
= armv8_read_core_reg
;
817 arm
->write_core_reg
= armv8_write_core_reg
;
820 armv8
->armv8_mmu
.armv8_cache
.l2_cache
= NULL
;
821 armv8
->armv8_mmu
.armv8_cache
.ctype
= -1;
822 armv8
->armv8_mmu
.armv8_cache
.flush_all_data_cache
= NULL
;
823 armv8
->armv8_mmu
.armv8_cache
.display_cache_info
= NULL
;
827 int armv8_aarch64_state(struct target
*target
)
829 struct arm
*arm
= target_to_arm(target
);
831 if (arm
->common_magic
!= ARM_COMMON_MAGIC
) {
832 LOG_ERROR("BUG: called for a non-ARM target");
836 LOG_USER("target halted in %s state due to %s, current mode: %s\n"
837 "cpsr: 0x%8.8" PRIx32
" pc: 0x%" PRIx64
"%s",
838 armv8_state_strings
[arm
->core_state
],
839 debug_reason_name(target
),
840 armv8_mode_name(arm
->core_mode
),
841 buf_get_u32(arm
->cpsr
->value
, 0, 32),
842 buf_get_u64(arm
->pc
->value
, 0, 64),
843 arm
->is_semihosting
? ", semihosting" : "");
848 int armv8_arch_state(struct target
*target
)
850 static const char * const state
[] = {
851 "disabled", "enabled"
854 struct armv8_common
*armv8
= target_to_armv8(target
);
855 struct arm
*arm
= &armv8
->arm
;
857 if (armv8
->common_magic
!= ARMV8_COMMON_MAGIC
) {
858 LOG_ERROR("BUG: called for a non-Armv8 target");
859 return ERROR_COMMAND_SYNTAX_ERROR
;
862 if (arm
->core_state
== ARM_STATE_AARCH64
)
863 armv8_aarch64_state(target
);
865 arm_arch_state(target
);
867 LOG_USER("MMU: %s, D-Cache: %s, I-Cache: %s",
868 state
[armv8
->armv8_mmu
.mmu_enabled
],
869 state
[armv8
->armv8_mmu
.armv8_cache
.d_u_cache_enabled
],
870 state
[armv8
->armv8_mmu
.armv8_cache
.i_cache_enabled
]);
872 if (arm
->core_mode
== ARM_MODE_ABT
)
873 armv8_show_fault_registers(target
);
875 if (target
->debug_reason
== DBG_REASON_WATCHPOINT
)
876 LOG_USER("Watchpoint triggered at PC %#08x",
877 (unsigned) armv8
->dpm
.wp_pc
);
882 static const struct {
890 { ARMV8_R0
, "x0", 64, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core" },
891 { ARMV8_R1
, "x1", 64, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core" },
892 { ARMV8_R2
, "x2", 64, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core" },
893 { ARMV8_R3
, "x3", 64, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core" },
894 { ARMV8_R4
, "x4", 64, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core" },
895 { ARMV8_R5
, "x5", 64, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core" },
896 { ARMV8_R6
, "x6", 64, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core" },
897 { ARMV8_R7
, "x7", 64, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core" },
898 { ARMV8_R8
, "x8", 64, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core" },
899 { ARMV8_R9
, "x9", 64, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core" },
900 { ARMV8_R10
, "x10", 64, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core" },
901 { ARMV8_R11
, "x11", 64, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core" },
902 { ARMV8_R12
, "x12", 64, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core" },
903 { ARMV8_R13
, "x13", 64, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core" },
904 { ARMV8_R14
, "x14", 64, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core" },
905 { ARMV8_R15
, "x15", 64, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core" },
906 { ARMV8_R16
, "x16", 64, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core" },
907 { ARMV8_R17
, "x17", 64, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core" },
908 { ARMV8_R18
, "x18", 64, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core" },
909 { ARMV8_R19
, "x19", 64, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core" },
910 { ARMV8_R20
, "x20", 64, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core" },
911 { ARMV8_R21
, "x21", 64, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core" },
912 { ARMV8_R22
, "x22", 64, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core" },
913 { ARMV8_R23
, "x23", 64, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core" },
914 { ARMV8_R24
, "x24", 64, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core" },
915 { ARMV8_R25
, "x25", 64, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core" },
916 { ARMV8_R26
, "x26", 64, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core" },
917 { ARMV8_R27
, "x27", 64, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core" },
918 { ARMV8_R28
, "x28", 64, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core" },
919 { ARMV8_R29
, "x29", 64, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core" },
920 { ARMV8_R30
, "x30", 64, REG_TYPE_UINT64
, "general", "org.gnu.gdb.aarch64.core" },
922 { ARMV8_R31
, "sp", 64, REG_TYPE_DATA_PTR
, "general", "org.gnu.gdb.aarch64.core" },
923 { ARMV8_PC
, "pc", 64, REG_TYPE_CODE_PTR
, "general", "org.gnu.gdb.aarch64.core" },
925 { ARMV8_xPSR
, "CPSR", 32, REG_TYPE_UINT32
, "general", "org.gnu.gdb.aarch64.core" },
928 #define ARMV8_NUM_REGS ARRAY_SIZE(armv8_regs)
931 static int armv8_get_core_reg(struct reg
*reg
)
934 struct arm_reg
*armv8_reg
= reg
->arch_info
;
935 struct target
*target
= armv8_reg
->target
;
936 struct arm
*arm
= target_to_arm(target
);
938 if (target
->state
!= TARGET_HALTED
)
939 return ERROR_TARGET_NOT_HALTED
;
941 retval
= arm
->read_core_reg(target
, reg
, armv8_reg
->num
, arm
->core_mode
);
946 static int armv8_set_core_reg(struct reg
*reg
, uint8_t *buf
)
948 struct arm_reg
*armv8_reg
= reg
->arch_info
;
949 struct target
*target
= armv8_reg
->target
;
950 struct arm
*arm
= target_to_arm(target
);
951 uint64_t value
= buf_get_u64(buf
, 0, 64);
953 if (target
->state
!= TARGET_HALTED
)
954 return ERROR_TARGET_NOT_HALTED
;
956 if (reg
== arm
->cpsr
) {
957 armv8_set_cpsr(arm
, (uint32_t)value
);
959 buf_set_u64(reg
->value
, 0, 64, value
);
968 static const struct reg_arch_type armv8_reg_type
= {
969 .get
= armv8_get_core_reg
,
970 .set
= armv8_set_core_reg
,
973 /** Builds cache of architecturally defined registers. */
974 struct reg_cache
*armv8_build_reg_cache(struct target
*target
)
976 struct armv8_common
*armv8
= target_to_armv8(target
);
977 struct arm
*arm
= &armv8
->arm
;
978 int num_regs
= ARMV8_NUM_REGS
;
979 struct reg_cache
**cache_p
= register_get_last_cache_p(&target
->reg_cache
);
980 struct reg_cache
*cache
= malloc(sizeof(struct reg_cache
));
981 struct reg
*reg_list
= calloc(num_regs
, sizeof(struct reg
));
982 struct arm_reg
*arch_info
= calloc(num_regs
, sizeof(struct arm_reg
));
983 struct reg_feature
*feature
;
986 /* Build the process context cache */
987 cache
->name
= "arm v8 registers";
989 cache
->reg_list
= reg_list
;
990 cache
->num_regs
= num_regs
;
993 for (i
= 0; i
< num_regs
; i
++) {
994 arch_info
[i
].num
= armv8_regs
[i
].id
;
995 arch_info
[i
].target
= target
;
996 arch_info
[i
].arm
= arm
;
998 reg_list
[i
].name
= armv8_regs
[i
].name
;
999 reg_list
[i
].size
= armv8_regs
[i
].bits
;
1000 reg_list
[i
].value
= calloc(1, 8);
1001 reg_list
[i
].dirty
= 0;
1002 reg_list
[i
].valid
= 0;
1003 reg_list
[i
].type
= &armv8_reg_type
;
1004 reg_list
[i
].arch_info
= &arch_info
[i
];
1006 reg_list
[i
].group
= armv8_regs
[i
].group
;
1007 reg_list
[i
].number
= i
;
1008 reg_list
[i
].exist
= true;
1009 reg_list
[i
].caller_save
= true; /* gdb defaults to true */
1011 feature
= calloc(1, sizeof(struct reg_feature
));
1013 feature
->name
= armv8_regs
[i
].feature
;
1014 reg_list
[i
].feature
= feature
;
1016 LOG_ERROR("unable to allocate feature list");
1018 reg_list
[i
].reg_data_type
= calloc(1, sizeof(struct reg_data_type
));
1019 if (reg_list
[i
].reg_data_type
)
1020 reg_list
[i
].reg_data_type
->type
= armv8_regs
[i
].type
;
1022 LOG_ERROR("unable to allocate reg type list");
1025 arm
->cpsr
= reg_list
+ ARMV8_xPSR
;
1026 arm
->pc
= reg_list
+ ARMV8_PC
;
1027 arm
->core_cache
= cache
;
1032 struct reg
*armv8_reg_current(struct arm
*arm
, unsigned regnum
)
1036 if (regnum
> (ARMV8_LAST_REG
- 1))
1039 r
= arm
->core_cache
->reg_list
+ regnum
;
1043 const struct command_registration armv8_command_handlers
[] = {
1045 .chain
= dap_command_handlers
,
1047 COMMAND_REGISTRATION_DONE
1051 int armv8_get_gdb_reg_list(struct target
*target
,
1052 struct reg
**reg_list
[], int *reg_list_size
,
1053 enum target_register_class reg_class
)
1055 struct arm
*arm
= target_to_arm(target
);
1058 switch (reg_class
) {
1059 case REG_CLASS_GENERAL
:
1061 *reg_list_size
= ARMV8_LAST_REG
;
1062 *reg_list
= malloc(sizeof(struct reg
*) * (*reg_list_size
));
1064 for (i
= 0; i
< ARMV8_LAST_REG
; i
++)
1065 (*reg_list
)[i
] = armv8_reg_current(arm
, i
);
1070 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)