1 /***************************************************************************
2 * Copyright (C) 2009 by David Brownell *
4 * Copyright (C) ST-Ericsson SA 2011 michel.jaouen@stericsson.com *
6 * This program is free software; you can redistribute it and/or modify *
7 * it under the terms of the GNU General Public License as published by *
8 * the Free Software Foundation; either version 2 of the License, or *
9 * (at your option) any later version. *
11 * This program is distributed in the hope that it will be useful, *
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
14 * GNU General Public License for more details. *
16 * You should have received a copy of the GNU General Public License *
17 * along with this program. If not, see <http://www.gnu.org/licenses/>. *
18 ***************************************************************************/
24 #include <helper/replacements.h>
27 #include "arm_disassembler.h"
30 #include <helper/binarybuffer.h>
31 #include <helper/command.h>
37 #include "arm_opcodes.h"
39 #include "target_type.h"
41 static void armv7a_show_fault_registers(struct target
*target
)
43 uint32_t dfsr
, ifsr
, dfar
, ifar
;
44 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
45 struct arm_dpm
*dpm
= armv7a
->arm
.dpm
;
48 retval
= dpm
->prepare(dpm
);
49 if (retval
!= ERROR_OK
)
52 /* ARMV4_5_MRC(cpnum, op1, r0, CRn, CRm, op2) */
54 /* c5/c0 - {data, instruction} fault status registers */
55 retval
= dpm
->instr_read_data_r0(dpm
,
56 ARMV4_5_MRC(15, 0, 0, 5, 0, 0),
58 if (retval
!= ERROR_OK
)
61 retval
= dpm
->instr_read_data_r0(dpm
,
62 ARMV4_5_MRC(15, 0, 0, 5, 0, 1),
64 if (retval
!= ERROR_OK
)
67 /* c6/c0 - {data, instruction} fault address registers */
68 retval
= dpm
->instr_read_data_r0(dpm
,
69 ARMV4_5_MRC(15, 0, 0, 6, 0, 0),
71 if (retval
!= ERROR_OK
)
74 retval
= dpm
->instr_read_data_r0(dpm
,
75 ARMV4_5_MRC(15, 0, 0, 6, 0, 2),
77 if (retval
!= ERROR_OK
)
80 LOG_USER("Data fault registers DFSR: %8.8" PRIx32
81 ", DFAR: %8.8" PRIx32
, dfsr
, dfar
);
82 LOG_USER("Instruction fault registers IFSR: %8.8" PRIx32
83 ", IFAR: %8.8" PRIx32
, ifsr
, ifar
);
86 /* (void) */ dpm
->finish(dpm
);
90 /* retrieve main id register */
91 static int armv7a_read_midr(struct target
*target
)
93 int retval
= ERROR_FAIL
;
94 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
95 struct arm_dpm
*dpm
= armv7a
->arm
.dpm
;
97 retval
= dpm
->prepare(dpm
);
98 if (retval
!= ERROR_OK
)
100 /* MRC p15,0,<Rd>,c0,c0,0; read main id register*/
102 retval
= dpm
->instr_read_data_r0(dpm
,
103 ARMV4_5_MRC(15, 0, 0, 0, 0, 0),
105 if (retval
!= ERROR_OK
)
108 armv7a
->rev
= (midr
& 0xf);
109 armv7a
->partnum
= (midr
>> 4) & 0xfff;
110 armv7a
->arch
= (midr
>> 16) & 0xf;
111 armv7a
->variant
= (midr
>> 20) & 0xf;
112 armv7a
->implementor
= (midr
>> 24) & 0xff;
113 LOG_INFO("%s rev %" PRIx32
", partnum %" PRIx32
", arch %" PRIx32
114 ", variant %" PRIx32
", implementor %" PRIx32
,
120 armv7a
->implementor
);
127 int armv7a_read_ttbcr(struct target
*target
)
129 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
130 struct arm_dpm
*dpm
= armv7a
->arm
.dpm
;
131 uint32_t ttbcr
, ttbcr_n
;
135 retval
= dpm
->prepare(dpm
);
136 if (retval
!= ERROR_OK
)
139 /* MRC p15,0,<Rt>,c2,c0,2 ; Read CP15 Translation Table Base Control Register*/
140 retval
= dpm
->instr_read_data_r0(dpm
,
141 ARMV4_5_MRC(15, 0, 0, 2, 0, 2),
143 if (retval
!= ERROR_OK
)
146 LOG_DEBUG("ttbcr %" PRIx32
, ttbcr
);
148 ttbcr_n
= ttbcr
& 0x7;
149 armv7a
->armv7a_mmu
.ttbcr
= ttbcr
;
150 armv7a
->armv7a_mmu
.cached
= 1;
152 for (ttbidx
= 0; ttbidx
< 2; ttbidx
++) {
153 /* MRC p15,0,<Rt>,c2,c0,ttbidx */
154 retval
= dpm
->instr_read_data_r0(dpm
,
155 ARMV4_5_MRC(15, 0, 0, 2, 0, ttbidx
),
156 &armv7a
->armv7a_mmu
.ttbr
[ttbidx
]);
157 if (retval
!= ERROR_OK
)
162 * ARM Architecture Reference Manual (ARMv7-A and ARMv7-Redition),
163 * document # ARM DDI 0406C
165 armv7a
->armv7a_mmu
.ttbr_range
[0] = 0xffffffff >> ttbcr_n
;
166 armv7a
->armv7a_mmu
.ttbr_range
[1] = 0xffffffff;
167 armv7a
->armv7a_mmu
.ttbr_mask
[0] = 0xffffffff << (14 - ttbcr_n
);
168 armv7a
->armv7a_mmu
.ttbr_mask
[1] = 0xffffffff << 14;
169 armv7a
->armv7a_mmu
.cached
= 1;
171 retval
= armv7a_read_midr(target
);
172 if (retval
!= ERROR_OK
)
175 /* FIXME: why this special case based on part number? */
176 if ((armv7a
->partnum
& 0xf) == 0) {
177 /* ARM DDI 0344H , ARM DDI 0407F */
178 armv7a
->armv7a_mmu
.ttbr_mask
[0] = 7 << (32 - ttbcr_n
);
181 LOG_DEBUG("ttbr1 %s, ttbr0_mask %" PRIx32
" ttbr1_mask %" PRIx32
,
182 (ttbcr_n
!= 0) ? "used" : "not used",
183 armv7a
->armv7a_mmu
.ttbr_mask
[0],
184 armv7a
->armv7a_mmu
.ttbr_mask
[1]);
191 /* method adapted to Cortex-A : reused ARM v4 v5 method */
192 int armv7a_mmu_translate_va(struct target
*target
, uint32_t va
, uint32_t *val
)
194 uint32_t first_lvl_descriptor
= 0x0;
195 uint32_t second_lvl_descriptor
= 0x0;
197 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
198 uint32_t ttbidx
= 0; /* default to ttbr0 */
203 if (target
->state
!= TARGET_HALTED
)
204 LOG_INFO("target not halted, using cached values for translation table!");
206 /* if va is above the range handled by ttbr0, select ttbr1 */
207 if (va
> armv7a
->armv7a_mmu
.ttbr_range
[0]) {
212 ttb
= armv7a
->armv7a_mmu
.ttbr
[ttbidx
];
213 ttb_mask
= armv7a
->armv7a_mmu
.ttbr_mask
[ttbidx
];
214 va_mask
= 0xfff00000 & armv7a
->armv7a_mmu
.ttbr_range
[ttbidx
];
216 LOG_DEBUG("ttb_mask %" PRIx32
" va_mask %" PRIx32
" ttbidx %i",
217 ttb_mask
, va_mask
, ttbidx
);
218 retval
= armv7a
->armv7a_mmu
.read_physical_memory(target
,
219 (ttb
& ttb_mask
) | ((va
& va_mask
) >> 18),
220 4, 1, (uint8_t *)&first_lvl_descriptor
);
221 if (retval
!= ERROR_OK
)
223 first_lvl_descriptor
= target_buffer_get_u32(target
, (uint8_t *)
224 &first_lvl_descriptor
);
225 /* reuse armv4_5 piece of code, specific armv7a changes may come later */
226 LOG_DEBUG("1st lvl desc: %8.8" PRIx32
"", first_lvl_descriptor
);
228 if ((first_lvl_descriptor
& 0x3) == 0) {
229 LOG_ERROR("Address translation failure");
230 return ERROR_TARGET_TRANSLATION_FAULT
;
234 if ((first_lvl_descriptor
& 0x40002) == 2) {
235 /* section descriptor */
236 *val
= (first_lvl_descriptor
& 0xfff00000) | (va
& 0x000fffff);
238 } else if ((first_lvl_descriptor
& 0x40002) == 0x40002) {
239 /* supersection descriptor */
240 if (first_lvl_descriptor
& 0x00f001e0) {
241 LOG_ERROR("Physical address does not fit into 32 bits");
242 return ERROR_TARGET_TRANSLATION_FAULT
;
244 *val
= (first_lvl_descriptor
& 0xff000000) | (va
& 0x00ffffff);
249 retval
= armv7a
->armv7a_mmu
.read_physical_memory(target
,
250 (first_lvl_descriptor
& 0xfffffc00) | ((va
& 0x000ff000) >> 10),
251 4, 1, (uint8_t *)&second_lvl_descriptor
);
252 if (retval
!= ERROR_OK
)
255 second_lvl_descriptor
= target_buffer_get_u32(target
, (uint8_t *)
256 &second_lvl_descriptor
);
258 LOG_DEBUG("2nd lvl desc: %8.8" PRIx32
"", second_lvl_descriptor
);
260 if ((second_lvl_descriptor
& 0x3) == 0) {
261 LOG_ERROR("Address translation failure");
262 return ERROR_TARGET_TRANSLATION_FAULT
;
265 if ((second_lvl_descriptor
& 0x3) == 1) {
266 /* large page descriptor */
267 *val
= (second_lvl_descriptor
& 0xffff0000) | (va
& 0x0000ffff);
269 /* small page descriptor */
270 *val
= (second_lvl_descriptor
& 0xfffff000) | (va
& 0x00000fff);
276 /* V7 method VA TO PA */
277 int armv7a_mmu_translate_va_pa(struct target
*target
, uint32_t va
,
278 uint32_t *val
, int meminfo
)
280 int retval
= ERROR_FAIL
;
281 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
282 struct arm_dpm
*dpm
= armv7a
->arm
.dpm
;
283 uint32_t virt
= va
& ~0xfff;
284 uint32_t NOS
, NS
, INNER
, OUTER
;
286 retval
= dpm
->prepare(dpm
);
287 if (retval
!= ERROR_OK
)
289 /* mmu must be enable in order to get a correct translation
290 * use VA to PA CP15 register for conversion */
291 retval
= dpm
->instr_write_data_r0(dpm
,
292 ARMV4_5_MCR(15, 0, 0, 7, 8, 0),
294 if (retval
!= ERROR_OK
)
296 retval
= dpm
->instr_read_data_r0(dpm
,
297 ARMV4_5_MRC(15, 0, 0, 7, 4, 0),
299 /* decode memory attribute */
300 NOS
= (*val
>> 10) & 1; /* Not Outer shareable */
301 NS
= (*val
>> 9) & 1; /* Non secure */
302 INNER
= (*val
>> 4) & 0x7;
303 OUTER
= (*val
>> 2) & 0x3;
305 if (retval
!= ERROR_OK
)
307 *val
= (*val
& ~0xfff) + (va
& 0xfff);
309 LOG_WARNING("virt = phys : MMU disable !!");
311 LOG_INFO("%" PRIx32
" : %" PRIx32
" %s outer shareable %s secured",
313 NOS
== 1 ? "not" : " ",
314 NS
== 1 ? "not" : "");
317 LOG_INFO("outer: Non-Cacheable");
320 LOG_INFO("outer: Write-Back, Write-Allocate");
323 LOG_INFO("outer: Write-Through, No Write-Allocate");
326 LOG_INFO("outer: Write-Back, no Write-Allocate");
331 LOG_INFO("inner: Non-Cacheable");
334 LOG_INFO("inner: Strongly-ordered");
337 LOG_INFO("inner: Device");
340 LOG_INFO("inner: Write-Back, Write-Allocate");
343 LOG_INFO("inner: Write-Through");
346 LOG_INFO("inner: Write-Back, no Write-Allocate");
349 LOG_INFO("inner: %" PRIx32
" ???", INNER
);
359 /* FIXME: remove it */
360 static int armv7a_l2x_cache_init(struct target
*target
, uint32_t base
, uint32_t way
)
362 struct armv7a_l2x_cache
*l2x_cache
;
363 struct target_list
*head
= target
->head
;
366 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
367 l2x_cache
= calloc(1, sizeof(struct armv7a_l2x_cache
));
368 l2x_cache
->base
= base
;
369 l2x_cache
->way
= way
;
370 /*LOG_INFO("cache l2 initialized base %x way %d",
371 l2x_cache->base,l2x_cache->way);*/
372 if (armv7a
->armv7a_mmu
.armv7a_cache
.outer_cache
)
373 LOG_INFO("outer cache already initialized\n");
374 armv7a
->armv7a_mmu
.armv7a_cache
.outer_cache
= l2x_cache
;
375 /* initialize all target in this cluster (smp target)
376 * l2 cache must be configured after smp declaration */
377 while (head
!= (struct target_list
*)NULL
) {
379 if (curr
!= target
) {
380 armv7a
= target_to_armv7a(curr
);
381 if (armv7a
->armv7a_mmu
.armv7a_cache
.outer_cache
)
382 LOG_ERROR("smp target : outer cache already initialized\n");
383 armv7a
->armv7a_mmu
.armv7a_cache
.outer_cache
= l2x_cache
;
390 /* FIXME: remove it */
391 COMMAND_HANDLER(handle_cache_l2x
)
393 struct target
*target
= get_current_target(CMD_CTX
);
397 return ERROR_COMMAND_SYNTAX_ERROR
;
399 /* command_print(CMD_CTX, "%s %s", CMD_ARGV[0], CMD_ARGV[1]); */
400 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[0], base
);
401 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[1], way
);
403 /* AP address is in bits 31:24 of DP_SELECT */
404 armv7a_l2x_cache_init(target
, base
, way
);
409 int armv7a_handle_cache_info_command(struct command_context
*cmd_ctx
,
410 struct armv7a_cache_common
*armv7a_cache
)
412 struct armv7a_l2x_cache
*l2x_cache
= (struct armv7a_l2x_cache
*)
413 (armv7a_cache
->outer_cache
);
417 if (armv7a_cache
->info
== -1) {
418 command_print(cmd_ctx
, "cache not yet identified");
422 for (cl
= 0; cl
< armv7a_cache
->loc
; cl
++) {
423 struct armv7a_arch_cache
*arch
= &(armv7a_cache
->arch
[cl
]);
425 if (arch
->ctype
& 1) {
426 command_print(cmd_ctx
,
427 "L%d I-Cache: linelen %" PRIi32
428 ", associativity %" PRIi32
430 ", cachesize %" PRId32
" KBytes",
432 arch
->i_size
.linelen
,
433 arch
->i_size
.associativity
,
435 arch
->i_size
.cachesize
);
438 if (arch
->ctype
>= 2) {
439 command_print(cmd_ctx
,
440 "L%d D-Cache: linelen %" PRIi32
441 ", associativity %" PRIi32
443 ", cachesize %" PRId32
" KBytes",
445 arch
->d_u_size
.linelen
,
446 arch
->d_u_size
.associativity
,
447 arch
->d_u_size
.nsets
,
448 arch
->d_u_size
.cachesize
);
452 if (l2x_cache
!= NULL
)
453 command_print(cmd_ctx
, "Outer unified cache Base Address 0x%" PRIx32
", %" PRId32
" ways",
454 l2x_cache
->base
, l2x_cache
->way
);
459 /* retrieve core id cluster id */
460 static int armv7a_read_mpidr(struct target
*target
)
462 int retval
= ERROR_FAIL
;
463 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
464 struct arm_dpm
*dpm
= armv7a
->arm
.dpm
;
466 retval
= dpm
->prepare(dpm
);
467 if (retval
!= ERROR_OK
)
469 /* MRC p15,0,<Rd>,c0,c0,5; read Multiprocessor ID register*/
471 retval
= dpm
->instr_read_data_r0(dpm
,
472 ARMV4_5_MRC(15, 0, 0, 0, 0, 5),
474 if (retval
!= ERROR_OK
)
477 /* ARMv7R uses a different format for MPIDR.
478 * When configured uniprocessor (most R cores) it reads as 0.
479 * This will need to be implemented for multiprocessor ARMv7R cores. */
480 if (armv7a
->is_armv7r
) {
482 LOG_ERROR("MPIDR nonzero in ARMv7-R target");
487 armv7a
->multi_processor_system
= (mpidr
>> 30) & 1;
488 armv7a
->cluster_id
= (mpidr
>> 8) & 0xf;
489 armv7a
->cpu_id
= mpidr
& 0x3;
490 LOG_INFO("%s cluster %x core %x %s", target_name(target
),
493 armv7a
->multi_processor_system
== 0 ? "multi core" : "mono core");
496 LOG_ERROR("MPIDR not in multiprocessor format");
505 static int get_cache_info(struct arm_dpm
*dpm
, int cl
, int ct
, uint32_t *cache_reg
)
507 int retval
= ERROR_OK
;
509 /* select cache level */
510 retval
= dpm
->instr_write_data_r0(dpm
,
511 ARMV4_5_MCR(15, 2, 0, 0, 0, 0),
512 (cl
<< 1) | (ct
== 1 ? 1 : 0));
513 if (retval
!= ERROR_OK
)
516 retval
= dpm
->instr_read_data_r0(dpm
,
517 ARMV4_5_MRC(15, 1, 0, 0, 0, 0),
523 static struct armv7a_cachesize
decode_cache_reg(uint32_t cache_reg
)
525 struct armv7a_cachesize size
;
528 size
.linelen
= 16 << (cache_reg
& 0x7);
529 size
.associativity
= ((cache_reg
>> 3) & 0x3ff) + 1;
530 size
.nsets
= ((cache_reg
>> 13) & 0x7fff) + 1;
531 size
.cachesize
= size
.linelen
* size
.associativity
* size
.nsets
/ 1024;
533 /* compute info for set way operation on cache */
534 size
.index_shift
= (cache_reg
& 0x7) + 4;
535 size
.index
= (cache_reg
>> 13) & 0x7fff;
536 size
.way
= ((cache_reg
>> 3) & 0x3ff);
538 while (((size
.way
<< i
) & 0x80000000) == 0)
545 int armv7a_identify_cache(struct target
*target
)
547 /* read cache descriptor */
548 int retval
= ERROR_FAIL
;
549 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
550 struct arm_dpm
*dpm
= armv7a
->arm
.dpm
;
551 uint32_t csselr
, clidr
, ctr
;
554 struct armv7a_cache_common
*cache
=
555 &(armv7a
->armv7a_mmu
.armv7a_cache
);
557 retval
= dpm
->prepare(dpm
);
558 if (retval
!= ERROR_OK
)
562 * mrc p15, 0, r0, c0, c0, 1 @ read ctr */
563 retval
= dpm
->instr_read_data_r0(dpm
,
564 ARMV4_5_MRC(15, 0, 0, 0, 0, 1),
566 if (retval
!= ERROR_OK
)
569 cache
->iminline
= 4UL << (ctr
& 0xf);
570 cache
->dminline
= 4UL << ((ctr
& 0xf0000) >> 16);
571 LOG_DEBUG("ctr %" PRIx32
" ctr.iminline %" PRId32
" ctr.dminline %" PRId32
,
572 ctr
, cache
->iminline
, cache
->dminline
);
575 * mrc p15, 1, r0, c0, c0, 1 @ read clidr */
576 retval
= dpm
->instr_read_data_r0(dpm
,
577 ARMV4_5_MRC(15, 1, 0, 0, 0, 1),
579 if (retval
!= ERROR_OK
)
582 cache
->loc
= (clidr
& 0x7000000) >> 24;
583 LOG_DEBUG("Number of cache levels to PoC %" PRId32
, cache
->loc
);
585 /* retrieve selected cache for later restore
586 * MRC p15, 2,<Rd>, c0, c0, 0; Read CSSELR */
587 retval
= dpm
->instr_read_data_r0(dpm
,
588 ARMV4_5_MRC(15, 2, 0, 0, 0, 0),
590 if (retval
!= ERROR_OK
)
593 /* retrieve all available inner caches */
594 for (cl
= 0; cl
< cache
->loc
; clidr
>>= 3, cl
++) {
596 /* isolate cache type at current level */
599 /* skip reserved values */
600 if (ctype
> CACHE_LEVEL_HAS_UNIFIED_CACHE
)
603 /* separate d or unified d/i cache at this level ? */
604 if (ctype
& (CACHE_LEVEL_HAS_UNIFIED_CACHE
| CACHE_LEVEL_HAS_D_CACHE
)) {
605 /* retrieve d-cache info */
606 retval
= get_cache_info(dpm
, cl
, 0, &cache_reg
);
607 if (retval
!= ERROR_OK
)
609 cache
->arch
[cl
].d_u_size
= decode_cache_reg(cache_reg
);
611 LOG_DEBUG("data/unified cache index %d << %d, way %d << %d",
612 cache
->arch
[cl
].d_u_size
.index
,
613 cache
->arch
[cl
].d_u_size
.index_shift
,
614 cache
->arch
[cl
].d_u_size
.way
,
615 cache
->arch
[cl
].d_u_size
.way_shift
);
617 LOG_DEBUG("cacheline %d bytes %d KBytes asso %d ways",
618 cache
->arch
[cl
].d_u_size
.linelen
,
619 cache
->arch
[cl
].d_u_size
.cachesize
,
620 cache
->arch
[cl
].d_u_size
.associativity
);
623 /* separate i-cache at this level ? */
624 if (ctype
& CACHE_LEVEL_HAS_I_CACHE
) {
625 /* retrieve i-cache info */
626 retval
= get_cache_info(dpm
, cl
, 1, &cache_reg
);
627 if (retval
!= ERROR_OK
)
629 cache
->arch
[cl
].i_size
= decode_cache_reg(cache_reg
);
631 LOG_DEBUG("instruction cache index %d << %d, way %d << %d",
632 cache
->arch
[cl
].i_size
.index
,
633 cache
->arch
[cl
].i_size
.index_shift
,
634 cache
->arch
[cl
].i_size
.way
,
635 cache
->arch
[cl
].i_size
.way_shift
);
637 LOG_DEBUG("cacheline %d bytes %d KBytes asso %d ways",
638 cache
->arch
[cl
].i_size
.linelen
,
639 cache
->arch
[cl
].i_size
.cachesize
,
640 cache
->arch
[cl
].i_size
.associativity
);
643 cache
->arch
[cl
].ctype
= ctype
;
646 /* restore selected cache */
647 dpm
->instr_write_data_r0(dpm
,
648 ARMV4_5_MRC(15, 2, 0, 0, 0, 0),
651 if (retval
!= ERROR_OK
)
654 /* if no l2 cache initialize l1 data cache flush function function */
655 if (armv7a
->armv7a_mmu
.armv7a_cache
.flush_all_data_cache
== NULL
) {
656 armv7a
->armv7a_mmu
.armv7a_cache
.flush_all_data_cache
=
657 armv7a_cache_auto_flush_all_data
;
660 armv7a
->armv7a_mmu
.armv7a_cache
.info
= 1;
663 armv7a_read_mpidr(target
);
668 static int armv7a_setup_semihosting(struct target
*target
, int enable
)
670 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
674 ret
= mem_ap_read_atomic_u32(armv7a
->debug_ap
,
675 armv7a
->debug_base
+ CPUDBG_VCR
,
678 LOG_ERROR("Failed to read VCR register\n");
683 vcr
|= DBG_VCR_SVC_MASK
;
685 vcr
&= ~DBG_VCR_SVC_MASK
;
687 ret
= mem_ap_write_atomic_u32(armv7a
->debug_ap
,
688 armv7a
->debug_base
+ CPUDBG_VCR
,
691 LOG_ERROR("Failed to write VCR register\n");
696 int armv7a_init_arch_info(struct target
*target
, struct armv7a_common
*armv7a
)
698 struct arm
*arm
= &armv7a
->arm
;
699 arm
->arch_info
= armv7a
;
700 target
->arch_info
= &armv7a
->arm
;
701 arm
->setup_semihosting
= armv7a_setup_semihosting
;
702 /* target is useful in all function arm v4 5 compatible */
703 armv7a
->arm
.target
= target
;
704 armv7a
->arm
.common_magic
= ARM_COMMON_MAGIC
;
705 armv7a
->common_magic
= ARMV7_COMMON_MAGIC
;
706 armv7a
->armv7a_mmu
.armv7a_cache
.info
= -1;
707 armv7a
->armv7a_mmu
.armv7a_cache
.outer_cache
= NULL
;
708 armv7a
->armv7a_mmu
.armv7a_cache
.flush_all_data_cache
= NULL
;
709 armv7a
->armv7a_mmu
.armv7a_cache
.auto_cache_enabled
= 1;
713 int armv7a_arch_state(struct target
*target
)
715 static const char *state
[] = {
716 "disabled", "enabled"
719 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
720 struct arm
*arm
= &armv7a
->arm
;
722 if (armv7a
->common_magic
!= ARMV7_COMMON_MAGIC
) {
723 LOG_ERROR("BUG: called for a non-ARMv7A target");
724 return ERROR_COMMAND_SYNTAX_ERROR
;
727 arm_arch_state(target
);
729 if (armv7a
->is_armv7r
) {
730 LOG_USER("D-Cache: %s, I-Cache: %s",
731 state
[armv7a
->armv7a_mmu
.armv7a_cache
.d_u_cache_enabled
],
732 state
[armv7a
->armv7a_mmu
.armv7a_cache
.i_cache_enabled
]);
734 LOG_USER("MMU: %s, D-Cache: %s, I-Cache: %s",
735 state
[armv7a
->armv7a_mmu
.mmu_enabled
],
736 state
[armv7a
->armv7a_mmu
.armv7a_cache
.d_u_cache_enabled
],
737 state
[armv7a
->armv7a_mmu
.armv7a_cache
.i_cache_enabled
]);
740 if (arm
->core_mode
== ARM_MODE_ABT
)
741 armv7a_show_fault_registers(target
);
742 if (target
->debug_reason
== DBG_REASON_WATCHPOINT
)
743 LOG_USER("Watchpoint triggered at PC %#08x",
744 (unsigned) armv7a
->dpm
.wp_pc
);
749 static const struct command_registration l2_cache_commands
[] = {
752 .handler
= handle_cache_l2x
,
753 .mode
= COMMAND_EXEC
,
754 .help
= "configure l2x cache "
756 .usage
= "[base_addr] [number_of_way]",
758 COMMAND_REGISTRATION_DONE
762 const struct command_registration l2x_cache_command_handlers
[] = {
764 .name
= "cache_config",
765 .mode
= COMMAND_EXEC
,
766 .help
= "cache configuration for a target",
768 .chain
= l2_cache_commands
,
770 COMMAND_REGISTRATION_DONE
773 const struct command_registration armv7a_command_handlers
[] = {
775 .chain
= l2x_cache_command_handlers
,
778 .chain
= arm7a_cache_command_handlers
,
780 COMMAND_REGISTRATION_DONE
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)