aarch64: provide virt2phys command
[openocd.git] / src / target / armv8.c
1 /***************************************************************************
2 * Copyright (C) 2015 by David Ung *
3 * *
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. *
8 * *
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. *
13 * *
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 ***************************************************************************/
18
19 #ifdef HAVE_CONFIG_H
20 #include "config.h"
21 #endif
22
23 #include <helper/replacements.h>
24
25 #include "armv8.h"
26 #include "arm_disassembler.h"
27
28 #include "register.h"
29 #include <helper/binarybuffer.h>
30 #include <helper/command.h>
31
32 #include <stdlib.h>
33 #include <string.h>
34 #include <unistd.h>
35
36 #include "armv8_opcodes.h"
37 #include "target.h"
38 #include "target_type.h"
39
40 #define __unused __attribute__((unused))
41
42 static const char * const armv8_state_strings[] = {
43 "AArch32", "Thumb", "Jazelle", "ThumbEE", "AArch64",
44 };
45
46 static const struct {
47 const char *name;
48 unsigned psr;
49 /* For user and system modes, these list indices for all registers.
50 * otherwise they're just indices for the shadow registers and SPSR.
51 */
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 */
57 {
58 .name = "USR",
59 .psr = ARM_MODE_USR,
60 },
61 {
62 .name = "FIQ",
63 .psr = ARM_MODE_FIQ,
64 },
65 {
66 .name = "IRQ",
67 .psr = ARM_MODE_IRQ,
68 },
69 {
70 .name = "SVC",
71 .psr = ARM_MODE_SVC,
72 },
73 {
74 .name = "MON",
75 .psr = ARM_MODE_MON,
76 },
77 {
78 .name = "ABT",
79 .psr = ARM_MODE_ABT,
80 },
81 {
82 .name = "EL0T",
83 .psr = ARMV8_64_EL0T,
84 },
85 {
86 .name = "EL1T",
87 .psr = ARMV8_64_EL1T,
88 },
89 {
90 .name = "EL1H",
91 .psr = ARMV8_64_EL1H,
92 },
93 {
94 .name = "EL2T",
95 .psr = ARMV8_64_EL2T,
96 },
97 {
98 .name = "EL2H",
99 .psr = ARMV8_64_EL2H,
100 },
101 {
102 .name = "EL3T",
103 .psr = ARMV8_64_EL3T,
104 },
105 {
106 .name = "EL3H",
107 .psr = ARMV8_64_EL3H,
108 },
109 };
110
111 /** Map PSR mode bits to the name of an ARM processor operating mode. */
112 const char *armv8_mode_name(unsigned psr_mode)
113 {
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;
117 }
118 LOG_ERROR("unrecognized psr mode: %#02x", psr_mode);
119 return "UNRECOGNIZED";
120 }
121
122 int armv8_mode_to_number(enum arm_mode mode)
123 {
124 switch (mode) {
125 case ARM_MODE_ANY:
126 /* map MODE_ANY to user mode */
127 case ARM_MODE_USR:
128 return 0;
129 case ARM_MODE_FIQ:
130 return 1;
131 case ARM_MODE_IRQ:
132 return 2;
133 case ARM_MODE_SVC:
134 return 3;
135 case ARM_MODE_ABT:
136 return 4;
137 case ARM_MODE_UND:
138 return 5;
139 case ARM_MODE_SYS:
140 return 6;
141 case ARM_MODE_MON:
142 return 7;
143 case ARMV8_64_EL0T:
144 return 8;
145 case ARMV8_64_EL1T:
146 return 9;
147 case ARMV8_64_EL1H:
148 return 10;
149 case ARMV8_64_EL2T:
150 return 11;
151 case ARMV8_64_EL2H:
152 return 12;
153 case ARMV8_64_EL3T:
154 return 13;
155 case ARMV8_64_EL3H:
156 return 14;
157
158 default:
159 LOG_ERROR("invalid mode value encountered %d", mode);
160 return -1;
161 }
162 }
163
164
165 static int armv8_read_core_reg(struct target *target, struct reg *r,
166 int num, enum arm_mode mode)
167 {
168 uint64_t reg_value;
169 int retval;
170 struct arm_reg *armv8_core_reg;
171 struct armv8_common *armv8 = target_to_armv8(target);
172
173 assert(num < (int)armv8->arm.core_cache->num_regs);
174
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, &reg_value);
178
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;
182
183 return retval;
184 }
185
186 #if 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)
189 {
190 int retval;
191 struct arm_reg *armv8_core_reg;
192 struct armv8_common *armv8 = target_to_armv8(target);
193
194 assert(num < (int)armv8->arm.core_cache->num_regs);
195
196 armv8_core_reg = armv8->arm.core_cache->reg_list[num].arch_info;
197 retval = armv8->store_core_reg_u64(target,
198 armv8_core_reg->num,
199 value);
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;
204 }
205
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;
209
210 return ERROR_OK;
211 }
212 #endif
213
214 /* retrieve core id cluster id */
215 int armv8_read_mpidr(struct armv8_common *armv8)
216 {
217 int retval = ERROR_FAIL;
218 struct arm_dpm *dpm = armv8->arm.dpm;
219 uint32_t mpidr;
220
221 retval = dpm->prepare(dpm);
222 if (retval != ERROR_OK)
223 goto done;
224
225 retval = dpm->instr_read_data_r0(dpm, armv8_opcode(armv8, READ_REG_MPIDR), &mpidr);
226 if (retval != ERROR_OK)
227 goto done;
228 if (mpidr & 1<<31) {
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),
233 armv8->cluster_id,
234 armv8->cpu_id,
235 armv8->multi_processor_system == 0 ? "multi core" : "mono core");
236
237 } else
238 LOG_ERROR("mpdir not in multiprocessor format");
239
240 done:
241 dpm->finish(dpm);
242 return retval;
243 }
244
245 /**
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.
249 */
250 void armv8_set_cpsr(struct arm *arm, uint32_t cpsr)
251 {
252 uint32_t mode = cpsr & 0x1F;
253
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* ...
257 */
258 if (arm->cpsr) {
259 buf_set_u32(arm->cpsr->value, 0, 32, cpsr);
260 arm->cpsr->valid = 1;
261 arm->cpsr->dirty = 0;
262 }
263
264 /* Older ARMs won't have the J bit */
265 enum arm_state state = 0xFF;
266
267 if (((cpsr & 0x10) >> 4) == 0) {
268 state = ARM_STATE_AARCH64;
269 } else {
270 if (cpsr & (1 << 5)) { /* T */
271 if (cpsr & (1 << 24)) { /* J */
272 LOG_WARNING("ThumbEE -- incomplete support");
273 state = ARM_STATE_THUMB_EE;
274 } else
275 state = ARM_STATE_THUMB;
276 } else {
277 if (cpsr & (1 << 24)) { /* J */
278 LOG_ERROR("Jazelle state handling is BROKEN!");
279 state = ARM_STATE_JAZELLE;
280 } else
281 state = ARM_STATE_ARM;
282 }
283 }
284 arm->core_state = state;
285 if (arm->core_state == ARM_STATE_AARCH64) {
286 switch (mode) {
287 case SYSTEM_AAR64_MODE_EL0t:
288 arm->core_mode = ARMV8_64_EL0T;
289 break;
290 case SYSTEM_AAR64_MODE_EL1t:
291 arm->core_mode = ARMV8_64_EL0T;
292 break;
293 case SYSTEM_AAR64_MODE_EL1h:
294 arm->core_mode = ARMV8_64_EL1H;
295 break;
296 case SYSTEM_AAR64_MODE_EL2t:
297 arm->core_mode = ARMV8_64_EL2T;
298 break;
299 case SYSTEM_AAR64_MODE_EL2h:
300 arm->core_mode = ARMV8_64_EL2H;
301 break;
302 case SYSTEM_AAR64_MODE_EL3t:
303 arm->core_mode = ARMV8_64_EL3T;
304 break;
305 case SYSTEM_AAR64_MODE_EL3h:
306 arm->core_mode = ARMV8_64_EL3H;
307 break;
308 default:
309 LOG_DEBUG("unknow mode 0x%x", (unsigned) (mode));
310 break;
311 }
312 } else {
313 arm->core_mode = mode;
314 }
315
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]);
319 }
320
321 static void armv8_show_fault_registers32(struct armv8_common *armv8)
322 {
323 uint32_t dfsr, ifsr, dfar, ifar;
324 struct arm_dpm *dpm = armv8->arm.dpm;
325 int retval;
326
327 retval = dpm->prepare(dpm);
328 if (retval != ERROR_OK)
329 return;
330
331 /* ARMV4_5_MRC(cpnum, op1, r0, CRn, CRm, op2) */
332
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)),
336 &dfsr);
337 if (retval != ERROR_OK)
338 goto done;
339
340 retval = dpm->instr_read_data_r0(dpm,
341 T32_FMTITR(ARMV4_5_MRC(15, 0, 0, 5, 0, 1)),
342 &ifsr);
343 if (retval != ERROR_OK)
344 goto done;
345
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)),
349 &dfar);
350 if (retval != ERROR_OK)
351 goto done;
352
353 retval = dpm->instr_read_data_r0(dpm,
354 T32_FMTITR(ARMV4_5_MRC(15, 0, 0, 6, 0, 2)),
355 &ifar);
356 if (retval != ERROR_OK)
357 goto done;
358
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);
363
364 done:
365 /* (void) */ dpm->finish(dpm);
366 }
367
368 static void armv8_show_fault_registers(struct target *target)
369 {
370 struct armv8_common *armv8 = target_to_armv8(target);
371
372 if (armv8->arm.core_state != ARM_STATE_AARCH64)
373 armv8_show_fault_registers32(armv8);
374 }
375
376 static uint8_t armv8_pa_size(uint32_t ps)
377 {
378 uint8_t ret = 0;
379 switch (ps) {
380 case 0:
381 ret = 32;
382 break;
383 case 1:
384 ret = 36;
385 break;
386 case 2:
387 ret = 40;
388 break;
389 case 3:
390 ret = 42;
391 break;
392 case 4:
393 ret = 44;
394 break;
395 case 5:
396 ret = 48;
397 break;
398 default:
399 LOG_INFO("Unknow physicall address size");
400 break;
401 }
402 return ret;
403 }
404
405 static __unused int armv8_read_ttbcr32(struct target *target)
406 {
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)
412 goto done;
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)),
416 &ttbcr);
417 if (retval != ERROR_OK)
418 goto done;
419
420 LOG_DEBUG("ttbcr %" PRIx32, ttbcr);
421
422 ttbcr_n = ttbcr & 0x7;
423 armv8->armv8_mmu.ttbcr = ttbcr;
424
425 /*
426 * ARM Architecture Reference Manual (ARMv7-A and ARMv7-Redition),
427 * document # ARM DDI 0406C
428 */
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;
433
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]);
438
439 done:
440 dpm->finish(dpm);
441 return retval;
442 }
443
444 static __unused int armv8_read_ttbcr(struct target *target)
445 {
446 struct armv8_common *armv8 = target_to_armv8(target);
447 struct arm_dpm *dpm = armv8->arm.dpm;
448 struct arm *arm = &armv8->arm;
449 uint32_t ttbcr;
450 uint64_t ttbcr_64;
451
452 int retval = dpm->prepare(dpm);
453 if (retval != ERROR_OK)
454 goto done;
455
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));
459
460 switch (arm->core_mode) {
461 case ARMV8_64_EL3H:
462 case ARMV8_64_EL3T:
463 retval = dpm->instr_read_data_r0(dpm,
464 ARMV8_MRS(SYSTEM_TCR_EL3, 0),
465 &ttbcr);
466 retval += dpm->instr_read_data_r0_64(dpm,
467 ARMV8_MRS(SYSTEM_TTBR0_EL3, 0),
468 &armv8->ttbr_base);
469 if (retval != ERROR_OK)
470 goto done;
471 armv8->va_size = 64 - (ttbcr & 0x3F);
472 armv8->pa_size = armv8_pa_size((ttbcr >> 16) & 7);
473 armv8->page_size = (ttbcr >> 14) & 3;
474 break;
475 case ARMV8_64_EL2T:
476 case ARMV8_64_EL2H:
477 retval = dpm->instr_read_data_r0(dpm,
478 ARMV8_MRS(SYSTEM_TCR_EL2, 0),
479 &ttbcr);
480 retval += dpm->instr_read_data_r0_64(dpm,
481 ARMV8_MRS(SYSTEM_TTBR0_EL2, 0),
482 &armv8->ttbr_base);
483 if (retval != ERROR_OK)
484 goto done;
485 armv8->va_size = 64 - (ttbcr & 0x3F);
486 armv8->pa_size = armv8_pa_size((ttbcr >> 16) & 7);
487 armv8->page_size = (ttbcr >> 14) & 3;
488 break;
489 case ARMV8_64_EL0T:
490 case ARMV8_64_EL1T:
491 case ARMV8_64_EL1H:
492 retval = dpm->instr_read_data_r0_64(dpm,
493 ARMV8_MRS(SYSTEM_TCR_EL1, 0),
494 &ttbcr_64);
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),
502 &armv8->ttbr_base);
503 if (retval != ERROR_OK)
504 goto done;
505 break;
506 default:
507 LOG_ERROR("unknow core state");
508 retval = ERROR_FAIL;
509 break;
510 }
511 if (retval != ERROR_OK)
512 goto done;
513
514 if (armv8->armv8_mmu.ttbr1_used == 1)
515 LOG_INFO("TTBR0 access above %" PRIx64, (uint64_t)(armv8->armv8_mmu.ttbr0_mask));
516
517 done:
518 dpm->finish(dpm);
519 return retval;
520 }
521
522 /* method adapted to cortex A : reused arm v4 v5 method*/
523 int armv8_mmu_translate_va(struct target *target, target_addr_t va, target_addr_t *val)
524 {
525 return ERROR_OK;
526 }
527
528 /* V8 method VA TO PA */
529 int armv8_mmu_translate_va_pa(struct target *target, target_addr_t va,
530 target_addr_t *val, int meminfo)
531 {
532 struct armv8_common *armv8 = target_to_armv8(target);
533 struct arm *arm = target_to_arm(target);
534 struct arm_dpm *dpm = &armv8->dpm;
535 uint32_t retval;
536 uint32_t instr = 0;
537 uint64_t par;
538
539 static const char * const shared_name[] = {
540 "Non-", "UNDEFINED ", "Outer ", "Inner "
541 };
542
543 static const char * const secure_name[] = {
544 "Secure", "Not Secure"
545 };
546
547 retval = dpm->prepare(dpm);
548 if (retval != ERROR_OK)
549 return retval;
550
551 switch (armv8_curel_from_core_mode(arm)) {
552 case SYSTEM_CUREL_EL0:
553 instr = ARMV8_SYS(SYSTEM_ATS12E0R, 0);
554 /* can only execute instruction at EL2 */
555 dpmv8_modeswitch(dpm, ARMV8_64_EL2T);
556 break;
557 case SYSTEM_CUREL_EL1:
558 instr = ARMV8_SYS(SYSTEM_ATS12E1R, 0);
559 /* can only execute instruction at EL2 */
560 dpmv8_modeswitch(dpm, ARMV8_64_EL2T);
561 break;
562 case SYSTEM_CUREL_EL2:
563 instr = ARMV8_SYS(SYSTEM_ATS1E2R, 0);
564 break;
565 case SYSTEM_CUREL_EL3:
566 instr = ARMV8_SYS(SYSTEM_ATS1E3R, 0);
567 break;
568
569 default:
570 break;
571 };
572
573 /* write VA to R0 and execute translation instruction */
574 retval = dpm->instr_write_data_r0_64(dpm, instr, (uint64_t)va);
575 /* read result from PAR_EL1 */
576 if (retval == ERROR_OK)
577 retval = dpm->instr_read_data_r0_64(dpm, ARMV8_MRS(SYSTEM_PAR_EL1, 0), &par);
578
579 dpm->finish(dpm);
580
581 /* switch back to saved PE mode */
582 dpmv8_modeswitch(dpm, ARM_MODE_ANY);
583
584 if (retval != ERROR_OK)
585 return retval;
586
587 if (par & 1) {
588 LOG_ERROR("Address translation failed at stage %i, FST=%x, PTW=%i",
589 ((int)(par >> 9) & 1)+1, (int)(par >> 1) & 0x3f, (int)(par >> 8) & 1);
590
591 *val = 0;
592 retval = ERROR_FAIL;
593 } else {
594 *val = (par & 0xFFFFFFFFF000UL) | (va & 0xFFF);
595 if (meminfo) {
596 int SH = (par >> 7) & 3;
597 int NS = (par >> 9) & 1;
598 int ATTR = (par >> 56) & 0xFF;
599
600 char *memtype = (ATTR & 0xF0) == 0 ? "Device Memory" : "Normal Memory";
601
602 LOG_USER("%sshareable, %s",
603 shared_name[SH], secure_name[NS]);
604 LOG_USER("%s", memtype);
605 }
606 }
607
608 return retval;
609 }
610
611 int armv8_handle_cache_info_command(struct command_context *cmd_ctx,
612 struct armv8_cache_common *armv8_cache)
613 {
614 if (armv8_cache->info == -1) {
615 command_print(cmd_ctx, "cache not yet identified");
616 return ERROR_OK;
617 }
618
619 if (armv8_cache->display_cache_info)
620 armv8_cache->display_cache_info(cmd_ctx, armv8_cache);
621 return ERROR_OK;
622 }
623
624 int armv8_init_arch_info(struct target *target, struct armv8_common *armv8)
625 {
626 struct arm *arm = &armv8->arm;
627 arm->arch_info = armv8;
628 target->arch_info = &armv8->arm;
629 /* target is useful in all function arm v4 5 compatible */
630 armv8->arm.target = target;
631 armv8->arm.common_magic = ARM_COMMON_MAGIC;
632 armv8->common_magic = ARMV8_COMMON_MAGIC;
633
634 arm->read_core_reg = armv8_read_core_reg;
635 #if 0
636 arm->write_core_reg = armv8_write_core_reg;
637 #endif
638
639 armv8->armv8_mmu.armv8_cache.l2_cache = NULL;
640 armv8->armv8_mmu.armv8_cache.info = -1;
641 armv8->armv8_mmu.armv8_cache.flush_all_data_cache = NULL;
642 armv8->armv8_mmu.armv8_cache.display_cache_info = NULL;
643 return ERROR_OK;
644 }
645
646 int armv8_aarch64_state(struct target *target)
647 {
648 struct arm *arm = target_to_arm(target);
649
650 if (arm->common_magic != ARM_COMMON_MAGIC) {
651 LOG_ERROR("BUG: called for a non-ARM target");
652 return ERROR_FAIL;
653 }
654
655 LOG_USER("target halted in %s state due to %s, current mode: %s\n"
656 "cpsr: 0x%8.8" PRIx32 " pc: 0x%" PRIx64 "%s",
657 armv8_state_strings[arm->core_state],
658 debug_reason_name(target),
659 armv8_mode_name(arm->core_mode),
660 buf_get_u32(arm->cpsr->value, 0, 32),
661 buf_get_u64(arm->pc->value, 0, 64),
662 arm->is_semihosting ? ", semihosting" : "");
663
664 return ERROR_OK;
665 }
666
667 int armv8_arch_state(struct target *target)
668 {
669 static const char * const state[] = {
670 "disabled", "enabled"
671 };
672
673 struct armv8_common *armv8 = target_to_armv8(target);
674 struct arm *arm = &armv8->arm;
675
676 if (armv8->common_magic != ARMV8_COMMON_MAGIC) {
677 LOG_ERROR("BUG: called for a non-Armv8 target");
678 return ERROR_COMMAND_SYNTAX_ERROR;
679 }
680
681 if (arm->core_state == ARM_STATE_AARCH64)
682 armv8_aarch64_state(target);
683 else
684 arm_arch_state(target);
685
686 LOG_USER("MMU: %s, D-Cache: %s, I-Cache: %s",
687 state[armv8->armv8_mmu.mmu_enabled],
688 state[armv8->armv8_mmu.armv8_cache.d_u_cache_enabled],
689 state[armv8->armv8_mmu.armv8_cache.i_cache_enabled]);
690
691 if (arm->core_mode == ARM_MODE_ABT)
692 armv8_show_fault_registers(target);
693
694 if (target->debug_reason == DBG_REASON_WATCHPOINT)
695 LOG_USER("Watchpoint triggered at PC %#08x",
696 (unsigned) armv8->dpm.wp_pc);
697
698 return ERROR_OK;
699 }
700
701 static const struct {
702 unsigned id;
703 const char *name;
704 unsigned bits;
705 enum reg_type type;
706 const char *group;
707 const char *feature;
708 } armv8_regs[] = {
709 { ARMV8_R0, "x0", 64, REG_TYPE_UINT64, "general", "org.gnu.gdb.aarch64.core" },
710 { ARMV8_R1, "x1", 64, REG_TYPE_UINT64, "general", "org.gnu.gdb.aarch64.core" },
711 { ARMV8_R2, "x2", 64, REG_TYPE_UINT64, "general", "org.gnu.gdb.aarch64.core" },
712 { ARMV8_R3, "x3", 64, REG_TYPE_UINT64, "general", "org.gnu.gdb.aarch64.core" },
713 { ARMV8_R4, "x4", 64, REG_TYPE_UINT64, "general", "org.gnu.gdb.aarch64.core" },
714 { ARMV8_R5, "x5", 64, REG_TYPE_UINT64, "general", "org.gnu.gdb.aarch64.core" },
715 { ARMV8_R6, "x6", 64, REG_TYPE_UINT64, "general", "org.gnu.gdb.aarch64.core" },
716 { ARMV8_R7, "x7", 64, REG_TYPE_UINT64, "general", "org.gnu.gdb.aarch64.core" },
717 { ARMV8_R8, "x8", 64, REG_TYPE_UINT64, "general", "org.gnu.gdb.aarch64.core" },
718 { ARMV8_R9, "x9", 64, REG_TYPE_UINT64, "general", "org.gnu.gdb.aarch64.core" },
719 { ARMV8_R10, "x10", 64, REG_TYPE_UINT64, "general", "org.gnu.gdb.aarch64.core" },
720 { ARMV8_R11, "x11", 64, REG_TYPE_UINT64, "general", "org.gnu.gdb.aarch64.core" },
721 { ARMV8_R12, "x12", 64, REG_TYPE_UINT64, "general", "org.gnu.gdb.aarch64.core" },
722 { ARMV8_R13, "x13", 64, REG_TYPE_UINT64, "general", "org.gnu.gdb.aarch64.core" },
723 { ARMV8_R14, "x14", 64, REG_TYPE_UINT64, "general", "org.gnu.gdb.aarch64.core" },
724 { ARMV8_R15, "x15", 64, REG_TYPE_UINT64, "general", "org.gnu.gdb.aarch64.core" },
725 { ARMV8_R16, "x16", 64, REG_TYPE_UINT64, "general", "org.gnu.gdb.aarch64.core" },
726 { ARMV8_R17, "x17", 64, REG_TYPE_UINT64, "general", "org.gnu.gdb.aarch64.core" },
727 { ARMV8_R18, "x18", 64, REG_TYPE_UINT64, "general", "org.gnu.gdb.aarch64.core" },
728 { ARMV8_R19, "x19", 64, REG_TYPE_UINT64, "general", "org.gnu.gdb.aarch64.core" },
729 { ARMV8_R20, "x20", 64, REG_TYPE_UINT64, "general", "org.gnu.gdb.aarch64.core" },
730 { ARMV8_R21, "x21", 64, REG_TYPE_UINT64, "general", "org.gnu.gdb.aarch64.core" },
731 { ARMV8_R22, "x22", 64, REG_TYPE_UINT64, "general", "org.gnu.gdb.aarch64.core" },
732 { ARMV8_R23, "x23", 64, REG_TYPE_UINT64, "general", "org.gnu.gdb.aarch64.core" },
733 { ARMV8_R24, "x24", 64, REG_TYPE_UINT64, "general", "org.gnu.gdb.aarch64.core" },
734 { ARMV8_R25, "x25", 64, REG_TYPE_UINT64, "general", "org.gnu.gdb.aarch64.core" },
735 { ARMV8_R26, "x26", 64, REG_TYPE_UINT64, "general", "org.gnu.gdb.aarch64.core" },
736 { ARMV8_R27, "x27", 64, REG_TYPE_UINT64, "general", "org.gnu.gdb.aarch64.core" },
737 { ARMV8_R28, "x28", 64, REG_TYPE_UINT64, "general", "org.gnu.gdb.aarch64.core" },
738 { ARMV8_R29, "x29", 64, REG_TYPE_UINT64, "general", "org.gnu.gdb.aarch64.core" },
739 { ARMV8_R30, "x30", 64, REG_TYPE_UINT64, "general", "org.gnu.gdb.aarch64.core" },
740
741 { ARMV8_R31, "sp", 64, REG_TYPE_DATA_PTR, "general", "org.gnu.gdb.aarch64.core" },
742 { ARMV8_PC, "pc", 64, REG_TYPE_CODE_PTR, "general", "org.gnu.gdb.aarch64.core" },
743
744 { ARMV8_xPSR, "CPSR", 32, REG_TYPE_UINT32, "general", "org.gnu.gdb.aarch64.core" },
745 };
746
747 #define ARMV8_NUM_REGS ARRAY_SIZE(armv8_regs)
748
749
750 static int armv8_get_core_reg(struct reg *reg)
751 {
752 int retval;
753 struct arm_reg *armv8_reg = reg->arch_info;
754 struct target *target = armv8_reg->target;
755 struct arm *arm = target_to_arm(target);
756
757 if (target->state != TARGET_HALTED)
758 return ERROR_TARGET_NOT_HALTED;
759
760 retval = arm->read_core_reg(target, reg, armv8_reg->num, arm->core_mode);
761
762 return retval;
763 }
764
765 static int armv8_set_core_reg(struct reg *reg, uint8_t *buf)
766 {
767 struct arm_reg *armv8_reg = reg->arch_info;
768 struct target *target = armv8_reg->target;
769 struct arm *arm = target_to_arm(target);
770 uint64_t value = buf_get_u64(buf, 0, 64);
771
772 if (target->state != TARGET_HALTED)
773 return ERROR_TARGET_NOT_HALTED;
774
775 if (reg == arm->cpsr) {
776 armv8_set_cpsr(arm, (uint32_t)value);
777 } else {
778 buf_set_u64(reg->value, 0, 64, value);
779 reg->valid = 1;
780 }
781
782 reg->dirty = 1;
783
784 return ERROR_OK;
785 }
786
787 static const struct reg_arch_type armv8_reg_type = {
788 .get = armv8_get_core_reg,
789 .set = armv8_set_core_reg,
790 };
791
792 /** Builds cache of architecturally defined registers. */
793 struct reg_cache *armv8_build_reg_cache(struct target *target)
794 {
795 struct armv8_common *armv8 = target_to_armv8(target);
796 struct arm *arm = &armv8->arm;
797 int num_regs = ARMV8_NUM_REGS;
798 struct reg_cache **cache_p = register_get_last_cache_p(&target->reg_cache);
799 struct reg_cache *cache = malloc(sizeof(struct reg_cache));
800 struct reg *reg_list = calloc(num_regs, sizeof(struct reg));
801 struct arm_reg *arch_info = calloc(num_regs, sizeof(struct arm_reg));
802 struct reg_feature *feature;
803 int i;
804
805 /* Build the process context cache */
806 cache->name = "arm v8 registers";
807 cache->next = NULL;
808 cache->reg_list = reg_list;
809 cache->num_regs = num_regs;
810 (*cache_p) = cache;
811
812 for (i = 0; i < num_regs; i++) {
813 arch_info[i].num = armv8_regs[i].id;
814 arch_info[i].target = target;
815 arch_info[i].arm = arm;
816
817 reg_list[i].name = armv8_regs[i].name;
818 reg_list[i].size = armv8_regs[i].bits;
819 reg_list[i].value = calloc(1, 8);
820 reg_list[i].dirty = 0;
821 reg_list[i].valid = 0;
822 reg_list[i].type = &armv8_reg_type;
823 reg_list[i].arch_info = &arch_info[i];
824
825 reg_list[i].group = armv8_regs[i].group;
826 reg_list[i].number = i;
827 reg_list[i].exist = true;
828 reg_list[i].caller_save = true; /* gdb defaults to true */
829
830 feature = calloc(1, sizeof(struct reg_feature));
831 if (feature) {
832 feature->name = armv8_regs[i].feature;
833 reg_list[i].feature = feature;
834 } else
835 LOG_ERROR("unable to allocate feature list");
836
837 reg_list[i].reg_data_type = calloc(1, sizeof(struct reg_data_type));
838 if (reg_list[i].reg_data_type)
839 reg_list[i].reg_data_type->type = armv8_regs[i].type;
840 else
841 LOG_ERROR("unable to allocate reg type list");
842 }
843
844 arm->cpsr = reg_list + ARMV8_xPSR;
845 arm->pc = reg_list + ARMV8_PC;
846 arm->core_cache = cache;
847
848 return cache;
849 }
850
851 struct reg *armv8_reg_current(struct arm *arm, unsigned regnum)
852 {
853 struct reg *r;
854
855 if (regnum > (ARMV8_LAST_REG - 1))
856 return NULL;
857
858 r = arm->core_cache->reg_list + regnum;
859 return r;
860 }
861
862 const struct command_registration armv8_command_handlers[] = {
863 {
864 .chain = dap_command_handlers,
865 },
866 COMMAND_REGISTRATION_DONE
867 };
868
869
870 int armv8_get_gdb_reg_list(struct target *target,
871 struct reg **reg_list[], int *reg_list_size,
872 enum target_register_class reg_class)
873 {
874 struct arm *arm = target_to_arm(target);
875 int i;
876
877 switch (reg_class) {
878 case REG_CLASS_GENERAL:
879 case REG_CLASS_ALL:
880 *reg_list_size = ARMV8_LAST_REG;
881 *reg_list = malloc(sizeof(struct reg *) * (*reg_list_size));
882
883 for (i = 0; i < ARMV8_LAST_REG; i++)
884 (*reg_list)[i] = armv8_reg_current(arm, i);
885
886 return ERROR_OK;
887
888 default:
889 LOG_ERROR("not a valid register class type in query.");
890 return ERROR_FAIL;
891 break;
892 }
893 }

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)