jtag: linuxgpiod: drop extra parenthesis
[openocd.git] / src / target / armv8.c
1 // SPDX-License-Identifier: GPL-2.0-or-later
2
3 /***************************************************************************
4 * Copyright (C) 2015 by David Ung *
5 * *
6 * Copyright (C) 2018 by Liviu Ionescu *
7 * <ilg@livius.net> *
8 ***************************************************************************/
9
10 #ifdef HAVE_CONFIG_H
11 #include "config.h"
12 #endif
13
14 #include <helper/replacements.h>
15
16 #include "armv8.h"
17 #include "arm_disassembler.h"
18
19 #include "register.h"
20 #include <helper/binarybuffer.h>
21 #include <helper/command.h>
22 #include <helper/nvp.h>
23
24 #include <stdlib.h>
25 #include <string.h>
26 #include <unistd.h>
27
28 #include "armv8_opcodes.h"
29 #include "target.h"
30 #include "target_type.h"
31 #include "semihosting_common.h"
32
33 static const char * const armv8_state_strings[] = {
34 "AArch32", "Thumb", "Jazelle", "ThumbEE", "AArch64",
35 };
36
37 static const struct {
38 const char *name;
39 unsigned psr;
40 } armv8_mode_data[] = {
41 {
42 .name = "USR",
43 .psr = ARM_MODE_USR,
44 },
45 {
46 .name = "FIQ",
47 .psr = ARM_MODE_FIQ,
48 },
49 {
50 .name = "IRQ",
51 .psr = ARM_MODE_IRQ,
52 },
53 {
54 .name = "SVC",
55 .psr = ARM_MODE_SVC,
56 },
57 {
58 .name = "MON",
59 .psr = ARM_MODE_MON,
60 },
61 {
62 .name = "ABT",
63 .psr = ARM_MODE_ABT,
64 },
65 {
66 .name = "HYP",
67 .psr = ARM_MODE_HYP,
68 },
69 {
70 .name = "UND",
71 .psr = ARM_MODE_UND,
72 },
73 {
74 .name = "SYS",
75 .psr = ARM_MODE_SYS,
76 },
77 {
78 .name = "EL0T",
79 .psr = ARMV8_64_EL0T,
80 },
81 {
82 .name = "EL1T",
83 .psr = ARMV8_64_EL1T,
84 },
85 {
86 .name = "EL1H",
87 .psr = ARMV8_64_EL1H,
88 },
89 {
90 .name = "EL2T",
91 .psr = ARMV8_64_EL2T,
92 },
93 {
94 .name = "EL2H",
95 .psr = ARMV8_64_EL2H,
96 },
97 {
98 .name = "EL3T",
99 .psr = ARMV8_64_EL3T,
100 },
101 {
102 .name = "EL3H",
103 .psr = ARMV8_64_EL3H,
104 },
105 };
106
107 /** Map PSR mode bits to the name of an ARM processor operating mode. */
108 const char *armv8_mode_name(unsigned psr_mode)
109 {
110 for (unsigned i = 0; i < ARRAY_SIZE(armv8_mode_data); i++) {
111 if (armv8_mode_data[i].psr == psr_mode)
112 return armv8_mode_data[i].name;
113 }
114 LOG_ERROR("unrecognized psr mode: %#02x", psr_mode);
115 return "UNRECOGNIZED";
116 }
117
118 static uint8_t armv8_pa_size(uint32_t ps)
119 {
120 uint8_t ret = 0;
121 switch (ps) {
122 case 0:
123 ret = 32;
124 break;
125 case 1:
126 ret = 36;
127 break;
128 case 2:
129 ret = 40;
130 break;
131 case 3:
132 ret = 42;
133 break;
134 case 4:
135 ret = 44;
136 break;
137 case 5:
138 ret = 48;
139 break;
140 default:
141 LOG_INFO("Unknown physical address size");
142 break;
143 }
144 return ret;
145 }
146
147 static __attribute__((unused)) int armv8_read_ttbcr32(struct target *target)
148 {
149 struct armv8_common *armv8 = target_to_armv8(target);
150 struct arm_dpm *dpm = armv8->arm.dpm;
151 uint32_t ttbcr, ttbcr_n;
152 int retval = dpm->prepare(dpm);
153 if (retval != ERROR_OK)
154 goto done;
155 /* MRC p15,0,<Rt>,c2,c0,2 ; Read CP15 Translation Table Base Control Register*/
156 retval = dpm->instr_read_data_r0(dpm,
157 ARMV4_5_MRC(15, 0, 0, 2, 0, 2),
158 &ttbcr);
159 if (retval != ERROR_OK)
160 goto done;
161
162 LOG_DEBUG("ttbcr %" PRIx32, ttbcr);
163
164 ttbcr_n = ttbcr & 0x7;
165 armv8->armv8_mmu.ttbcr = ttbcr;
166
167 /*
168 * ARM Architecture Reference Manual (ARMv7-A and ARMv7-R edition),
169 * document # ARM DDI 0406C
170 */
171 armv8->armv8_mmu.ttbr_range[0] = 0xffffffff >> ttbcr_n;
172 armv8->armv8_mmu.ttbr_range[1] = 0xffffffff;
173 armv8->armv8_mmu.ttbr_mask[0] = 0xffffffff << (14 - ttbcr_n);
174 armv8->armv8_mmu.ttbr_mask[1] = 0xffffffff << 14;
175
176 LOG_DEBUG("ttbr1 %s, ttbr0_mask %" PRIx32 " ttbr1_mask %" PRIx32,
177 (ttbcr_n != 0) ? "used" : "not used",
178 armv8->armv8_mmu.ttbr_mask[0],
179 armv8->armv8_mmu.ttbr_mask[1]);
180
181 done:
182 dpm->finish(dpm);
183 return retval;
184 }
185
186 static int armv8_read_ttbcr(struct target *target)
187 {
188 struct armv8_common *armv8 = target_to_armv8(target);
189 struct arm_dpm *dpm = armv8->arm.dpm;
190 struct arm *arm = &armv8->arm;
191 uint32_t ttbcr;
192 uint64_t ttbcr_64;
193
194 int retval = dpm->prepare(dpm);
195 if (retval != ERROR_OK)
196 goto done;
197
198 /* clear ttrr1_used and ttbr0_mask */
199 memset(&armv8->armv8_mmu.ttbr1_used, 0, sizeof(armv8->armv8_mmu.ttbr1_used));
200 memset(&armv8->armv8_mmu.ttbr0_mask, 0, sizeof(armv8->armv8_mmu.ttbr0_mask));
201
202 switch (armv8_curel_from_core_mode(arm->core_mode)) {
203 case SYSTEM_CUREL_EL3:
204 retval = dpm->instr_read_data_r0(dpm,
205 ARMV8_MRS(SYSTEM_TCR_EL3, 0),
206 &ttbcr);
207 retval += dpm->instr_read_data_r0_64(dpm,
208 ARMV8_MRS(SYSTEM_TTBR0_EL3, 0),
209 &armv8->ttbr_base);
210 if (retval != ERROR_OK)
211 goto done;
212 armv8->va_size = 64 - (ttbcr & 0x3F);
213 armv8->pa_size = armv8_pa_size((ttbcr >> 16) & 7);
214 armv8->page_size = (ttbcr >> 14) & 3;
215 break;
216 case SYSTEM_CUREL_EL2:
217 retval = dpm->instr_read_data_r0(dpm,
218 ARMV8_MRS(SYSTEM_TCR_EL2, 0),
219 &ttbcr);
220 retval += dpm->instr_read_data_r0_64(dpm,
221 ARMV8_MRS(SYSTEM_TTBR0_EL2, 0),
222 &armv8->ttbr_base);
223 if (retval != ERROR_OK)
224 goto done;
225 armv8->va_size = 64 - (ttbcr & 0x3F);
226 armv8->pa_size = armv8_pa_size((ttbcr >> 16) & 7);
227 armv8->page_size = (ttbcr >> 14) & 3;
228 break;
229 case SYSTEM_CUREL_EL0:
230 armv8_dpm_modeswitch(dpm, ARMV8_64_EL1H);
231 /* fall through */
232 case SYSTEM_CUREL_EL1:
233 retval = dpm->instr_read_data_r0_64(dpm,
234 ARMV8_MRS(SYSTEM_TCR_EL1, 0),
235 &ttbcr_64);
236 armv8->va_size = 64 - (ttbcr_64 & 0x3F);
237 armv8->pa_size = armv8_pa_size((ttbcr_64 >> 32) & 7);
238 armv8->page_size = (ttbcr_64 >> 14) & 3;
239 armv8->armv8_mmu.ttbr1_used = (((ttbcr_64 >> 16) & 0x3F) != 0) ? 1 : 0;
240 armv8->armv8_mmu.ttbr0_mask = 0x0000FFFFFFFFFFFFULL;
241 retval += dpm->instr_read_data_r0_64(dpm,
242 ARMV8_MRS(SYSTEM_TTBR0_EL1 | (armv8->armv8_mmu.ttbr1_used), 0),
243 &armv8->ttbr_base);
244 if (retval != ERROR_OK)
245 goto done;
246 break;
247 default:
248 LOG_ERROR("unknown core state");
249 retval = ERROR_FAIL;
250 break;
251 }
252 if (retval != ERROR_OK)
253 goto done;
254
255 if (armv8->armv8_mmu.ttbr1_used == 1)
256 LOG_INFO("TTBR0 access above %" PRIx64, (uint64_t)(armv8->armv8_mmu.ttbr0_mask));
257
258 done:
259 armv8_dpm_modeswitch(dpm, ARM_MODE_ANY);
260 dpm->finish(dpm);
261 return retval;
262 }
263
264 static int armv8_get_pauth_mask(struct armv8_common *armv8, uint64_t *mask)
265 {
266 struct arm *arm = &armv8->arm;
267 int retval = ERROR_OK;
268 if (armv8->va_size == 0)
269 retval = armv8_read_ttbcr(arm->target);
270 if (retval != ERROR_OK)
271 return retval;
272
273 *mask = ~(((uint64_t)1 << armv8->va_size) - 1);
274
275 return retval;
276 }
277
278 static int armv8_read_reg(struct armv8_common *armv8, int regnum, uint64_t *regval)
279 {
280 struct arm_dpm *dpm = &armv8->dpm;
281 int retval;
282 uint32_t value;
283 uint64_t value_64;
284
285 switch (regnum) {
286 case 0 ... 30:
287 retval = dpm->instr_read_data_dcc_64(dpm,
288 ARMV8_MSR_GP(SYSTEM_DBG_DBGDTR_EL0, regnum), &value_64);
289 break;
290 case ARMV8_SP:
291 retval = dpm->instr_read_data_r0_64(dpm,
292 ARMV8_MOVFSP_64(0), &value_64);
293 break;
294 case ARMV8_PC:
295 retval = dpm->instr_read_data_r0_64(dpm,
296 ARMV8_MRS_DLR(0), &value_64);
297 break;
298 case ARMV8_XPSR:
299 retval = dpm->instr_read_data_r0(dpm,
300 ARMV8_MRS_DSPSR(0), &value);
301 value_64 = value;
302 break;
303 case ARMV8_FPSR:
304 retval = dpm->instr_read_data_r0(dpm,
305 ARMV8_MRS_FPSR(0), &value);
306 value_64 = value;
307 break;
308 case ARMV8_FPCR:
309 retval = dpm->instr_read_data_r0(dpm,
310 ARMV8_MRS_FPCR(0), &value);
311 value_64 = value;
312 break;
313 case ARMV8_ELR_EL1:
314 retval = dpm->instr_read_data_r0_64(dpm,
315 ARMV8_MRS(SYSTEM_ELR_EL1, 0), &value_64);
316 break;
317 case ARMV8_ELR_EL2:
318 retval = dpm->instr_read_data_r0_64(dpm,
319 ARMV8_MRS(SYSTEM_ELR_EL2, 0), &value_64);
320 break;
321 case ARMV8_ELR_EL3:
322 retval = dpm->instr_read_data_r0_64(dpm,
323 ARMV8_MRS(SYSTEM_ELR_EL3, 0), &value_64);
324 break;
325 case ARMV8_ESR_EL1:
326 retval = dpm->instr_read_data_r0(dpm,
327 ARMV8_MRS(SYSTEM_ESR_EL1, 0), &value);
328 value_64 = value;
329 break;
330 case ARMV8_ESR_EL2:
331 retval = dpm->instr_read_data_r0(dpm,
332 ARMV8_MRS(SYSTEM_ESR_EL2, 0), &value);
333 value_64 = value;
334 break;
335 case ARMV8_ESR_EL3:
336 retval = dpm->instr_read_data_r0(dpm,
337 ARMV8_MRS(SYSTEM_ESR_EL3, 0), &value);
338 value_64 = value;
339 break;
340 case ARMV8_SPSR_EL1:
341 retval = dpm->instr_read_data_r0(dpm,
342 ARMV8_MRS(SYSTEM_SPSR_EL1, 0), &value);
343 value_64 = value;
344 break;
345 case ARMV8_SPSR_EL2:
346 retval = dpm->instr_read_data_r0(dpm,
347 ARMV8_MRS(SYSTEM_SPSR_EL2, 0), &value);
348 value_64 = value;
349 break;
350 case ARMV8_SPSR_EL3:
351 retval = dpm->instr_read_data_r0(dpm,
352 ARMV8_MRS(SYSTEM_SPSR_EL3, 0), &value);
353 value_64 = value;
354 break;
355 case ARMV8_PAUTH_CMASK:
356 case ARMV8_PAUTH_DMASK:
357 retval = armv8_get_pauth_mask(armv8, &value_64);
358 break;
359 default:
360 retval = ERROR_FAIL;
361 break;
362 }
363
364 if (retval == ERROR_OK && regval)
365 *regval = value_64;
366 else
367 retval = ERROR_FAIL;
368
369 return retval;
370 }
371
372 static int armv8_read_reg_simdfp_aarch64(struct armv8_common *armv8, int regnum, uint64_t *lvalue, uint64_t *hvalue)
373 {
374 int retval = ERROR_FAIL;
375 struct arm_dpm *dpm = &armv8->dpm;
376
377 switch (regnum) {
378 case ARMV8_V0 ... ARMV8_V31:
379 retval = dpm->instr_read_data_r0_64(dpm,
380 ARMV8_MOV_GPR_VFP(0, (regnum - ARMV8_V0), 1), hvalue);
381 if (retval != ERROR_OK)
382 return retval;
383 retval = dpm->instr_read_data_r0_64(dpm,
384 ARMV8_MOV_GPR_VFP(0, (regnum - ARMV8_V0), 0), lvalue);
385 break;
386
387 default:
388 retval = ERROR_FAIL;
389 break;
390 }
391
392 return retval;
393 }
394
395 static int armv8_write_reg(struct armv8_common *armv8, int regnum, uint64_t value_64)
396 {
397 struct arm_dpm *dpm = &armv8->dpm;
398 int retval;
399 uint32_t value;
400
401 switch (regnum) {
402 case 0 ... 30:
403 retval = dpm->instr_write_data_dcc_64(dpm,
404 ARMV8_MRS(SYSTEM_DBG_DBGDTR_EL0, regnum),
405 value_64);
406 break;
407 case ARMV8_SP:
408 retval = dpm->instr_write_data_r0_64(dpm,
409 ARMV8_MOVTSP_64(0),
410 value_64);
411 break;
412 case ARMV8_PC:
413 retval = dpm->instr_write_data_r0_64(dpm,
414 ARMV8_MSR_DLR(0),
415 value_64);
416 break;
417 case ARMV8_XPSR:
418 value = value_64;
419 retval = dpm->instr_write_data_r0(dpm,
420 ARMV8_MSR_DSPSR(0),
421 value);
422 break;
423 case ARMV8_FPSR:
424 value = value_64;
425 retval = dpm->instr_write_data_r0(dpm,
426 ARMV8_MSR_FPSR(0),
427 value);
428 break;
429 case ARMV8_FPCR:
430 value = value_64;
431 retval = dpm->instr_write_data_r0(dpm,
432 ARMV8_MSR_FPCR(0),
433 value);
434 break;
435 /* registers clobbered by taking exception in debug state */
436 case ARMV8_ELR_EL1:
437 retval = dpm->instr_write_data_r0_64(dpm,
438 ARMV8_MSR_GP(SYSTEM_ELR_EL1, 0), value_64);
439 break;
440 case ARMV8_ELR_EL2:
441 retval = dpm->instr_write_data_r0_64(dpm,
442 ARMV8_MSR_GP(SYSTEM_ELR_EL2, 0), value_64);
443 break;
444 case ARMV8_ELR_EL3:
445 retval = dpm->instr_write_data_r0_64(dpm,
446 ARMV8_MSR_GP(SYSTEM_ELR_EL3, 0), value_64);
447 break;
448 case ARMV8_ESR_EL1:
449 value = value_64;
450 retval = dpm->instr_write_data_r0(dpm,
451 ARMV8_MSR_GP(SYSTEM_ESR_EL1, 0), value);
452 break;
453 case ARMV8_ESR_EL2:
454 value = value_64;
455 retval = dpm->instr_write_data_r0(dpm,
456 ARMV8_MSR_GP(SYSTEM_ESR_EL2, 0), value);
457 break;
458 case ARMV8_ESR_EL3:
459 value = value_64;
460 retval = dpm->instr_write_data_r0(dpm,
461 ARMV8_MSR_GP(SYSTEM_ESR_EL3, 0), value);
462 break;
463 case ARMV8_SPSR_EL1:
464 value = value_64;
465 retval = dpm->instr_write_data_r0(dpm,
466 ARMV8_MSR_GP(SYSTEM_SPSR_EL1, 0), value);
467 break;
468 case ARMV8_SPSR_EL2:
469 value = value_64;
470 retval = dpm->instr_write_data_r0(dpm,
471 ARMV8_MSR_GP(SYSTEM_SPSR_EL2, 0), value);
472 break;
473 case ARMV8_SPSR_EL3:
474 value = value_64;
475 retval = dpm->instr_write_data_r0(dpm,
476 ARMV8_MSR_GP(SYSTEM_SPSR_EL3, 0), value);
477 break;
478 default:
479 retval = ERROR_FAIL;
480 break;
481 }
482
483 return retval;
484 }
485
486 static int armv8_write_reg_simdfp_aarch64(struct armv8_common *armv8, int regnum, uint64_t lvalue, uint64_t hvalue)
487 {
488 int retval = ERROR_FAIL;
489 struct arm_dpm *dpm = &armv8->dpm;
490
491 switch (regnum) {
492 case ARMV8_V0 ... ARMV8_V31:
493 retval = dpm->instr_write_data_r0_64(dpm,
494 ARMV8_MOV_VFP_GPR((regnum - ARMV8_V0), 0, 1), hvalue);
495 if (retval != ERROR_OK)
496 return retval;
497 retval = dpm->instr_write_data_r0_64(dpm,
498 ARMV8_MOV_VFP_GPR((regnum - ARMV8_V0), 0, 0), lvalue);
499 break;
500
501 default:
502 retval = ERROR_FAIL;
503 break;
504 }
505
506 return retval;
507 }
508
509 static int armv8_read_reg32(struct armv8_common *armv8, int regnum, uint64_t *regval)
510 {
511 struct arm_dpm *dpm = &armv8->dpm;
512 uint32_t value = 0;
513 int retval;
514
515 switch (regnum) {
516 case ARMV8_R0 ... ARMV8_R14:
517 /* return via DCC: "MCR p14, 0, Rnum, c0, c5, 0" */
518 retval = dpm->instr_read_data_dcc(dpm,
519 ARMV4_5_MCR(14, 0, regnum, 0, 5, 0),
520 &value);
521 break;
522 case ARMV8_SP:
523 retval = dpm->instr_read_data_dcc(dpm,
524 ARMV4_5_MCR(14, 0, 13, 0, 5, 0),
525 &value);
526 break;
527 case ARMV8_PC:
528 retval = dpm->instr_read_data_r0(dpm,
529 ARMV8_MRC_DLR(0),
530 &value);
531 break;
532 case ARMV8_XPSR:
533 retval = dpm->instr_read_data_r0(dpm,
534 ARMV8_MRC_DSPSR(0),
535 &value);
536 break;
537 case ARMV8_ELR_EL1: /* mapped to LR_svc */
538 retval = dpm->instr_read_data_dcc(dpm,
539 ARMV4_5_MCR(14, 0, 14, 0, 5, 0),
540 &value);
541 break;
542 case ARMV8_ELR_EL2: /* mapped to ELR_hyp */
543 retval = dpm->instr_read_data_r0(dpm,
544 ARMV8_MRS_T1(0, 14, 0, 1),
545 &value);
546 break;
547 case ARMV8_ELR_EL3: /* mapped to LR_mon */
548 retval = dpm->instr_read_data_dcc(dpm,
549 ARMV4_5_MCR(14, 0, 14, 0, 5, 0),
550 &value);
551 break;
552 case ARMV8_ESR_EL1: /* mapped to DFSR */
553 retval = dpm->instr_read_data_r0(dpm,
554 ARMV4_5_MRC(15, 0, 0, 5, 0, 0),
555 &value);
556 break;
557 case ARMV8_ESR_EL2: /* mapped to HSR */
558 retval = dpm->instr_read_data_r0(dpm,
559 ARMV4_5_MRC(15, 4, 0, 5, 2, 0),
560 &value);
561 break;
562 case ARMV8_ESR_EL3: /* FIXME: no equivalent in aarch32? */
563 retval = ERROR_FAIL;
564 break;
565 case ARMV8_SPSR_EL1: /* mapped to SPSR_svc */
566 retval = dpm->instr_read_data_r0(dpm,
567 ARMV8_MRS_XPSR_T1(1, 0),
568 &value);
569 break;
570 case ARMV8_SPSR_EL2: /* mapped to SPSR_hyp */
571 retval = dpm->instr_read_data_r0(dpm,
572 ARMV8_MRS_XPSR_T1(1, 0),
573 &value);
574 break;
575 case ARMV8_SPSR_EL3: /* mapped to SPSR_mon */
576 retval = dpm->instr_read_data_r0(dpm,
577 ARMV8_MRS_XPSR_T1(1, 0),
578 &value);
579 break;
580 case ARMV8_FPSR:
581 /* "VMRS r0, FPSCR"; then return via DCC */
582 retval = dpm->instr_read_data_r0(dpm,
583 ARMV4_5_VMRS(0), &value);
584 break;
585 default:
586 retval = ERROR_FAIL;
587 break;
588 }
589
590 if (retval == ERROR_OK && regval)
591 *regval = value;
592
593 return retval;
594 }
595
596 static int armv8_read_reg_simdfp_aarch32(struct armv8_common *armv8, int regnum, uint64_t *lvalue, uint64_t *hvalue)
597 {
598 int retval = ERROR_FAIL;
599 struct arm_dpm *dpm = &armv8->dpm;
600 struct reg *reg_r1 = dpm->arm->core_cache->reg_list + ARMV8_R1;
601 uint32_t value_r0 = 0, value_r1 = 0;
602 unsigned num = (regnum - ARMV8_V0) << 1;
603
604 switch (regnum) {
605 case ARMV8_V0 ... ARMV8_V15:
606 /* we are going to write R1, mark it dirty */
607 reg_r1->dirty = true;
608 /* move from double word register to r0:r1: "vmov r0, r1, vm"
609 * then read r0 via dcc
610 */
611 retval = dpm->instr_read_data_r0(dpm,
612 ARMV4_5_VMOV(1, 1, 0, (num >> 4), (num & 0xf)),
613 &value_r0);
614 if (retval != ERROR_OK)
615 return retval;
616 /* read r1 via dcc */
617 retval = dpm->instr_read_data_dcc(dpm,
618 ARMV4_5_MCR(14, 0, 1, 0, 5, 0),
619 &value_r1);
620 if (retval != ERROR_OK)
621 return retval;
622 *lvalue = value_r1;
623 *lvalue = ((*lvalue) << 32) | value_r0;
624
625 num++;
626 /* repeat above steps for high 64 bits of V register */
627 retval = dpm->instr_read_data_r0(dpm,
628 ARMV4_5_VMOV(1, 1, 0, (num >> 4), (num & 0xf)),
629 &value_r0);
630 if (retval != ERROR_OK)
631 return retval;
632 retval = dpm->instr_read_data_dcc(dpm,
633 ARMV4_5_MCR(14, 0, 1, 0, 5, 0),
634 &value_r1);
635 if (retval != ERROR_OK)
636 return retval;
637 *hvalue = value_r1;
638 *hvalue = ((*hvalue) << 32) | value_r0;
639 break;
640 default:
641 retval = ERROR_FAIL;
642 break;
643 }
644
645 return retval;
646 }
647
648 static int armv8_write_reg32(struct armv8_common *armv8, int regnum, uint64_t value)
649 {
650 struct arm_dpm *dpm = &armv8->dpm;
651 int retval;
652
653 switch (regnum) {
654 case ARMV8_R0 ... ARMV8_R14:
655 /* load register from DCC: "MRC p14, 0, Rnum, c0, c5, 0" */
656 retval = dpm->instr_write_data_dcc(dpm,
657 ARMV4_5_MRC(14, 0, regnum, 0, 5, 0), value);
658 break;
659 case ARMV8_SP:
660 retval = dpm->instr_write_data_dcc(dpm,
661 ARMV4_5_MRC(14, 0, 13, 0, 5, 0), value);
662 break;
663 case ARMV8_PC:/* PC
664 * read r0 from DCC; then "MOV pc, r0" */
665 retval = dpm->instr_write_data_r0(dpm,
666 ARMV8_MCR_DLR(0), value);
667 break;
668 case ARMV8_XPSR: /* CPSR */
669 /* read r0 from DCC, then "MCR r0, DSPSR" */
670 retval = dpm->instr_write_data_r0(dpm,
671 ARMV8_MCR_DSPSR(0), value);
672 break;
673 case ARMV8_ELR_EL1: /* mapped to LR_svc */
674 retval = dpm->instr_write_data_dcc(dpm,
675 ARMV4_5_MRC(14, 0, 14, 0, 5, 0),
676 value);
677 break;
678 case ARMV8_ELR_EL2: /* mapped to ELR_hyp */
679 retval = dpm->instr_write_data_r0(dpm,
680 ARMV8_MSR_GP_T1(0, 14, 0, 1),
681 value);
682 break;
683 case ARMV8_ELR_EL3: /* mapped to LR_mon */
684 retval = dpm->instr_write_data_dcc(dpm,
685 ARMV4_5_MRC(14, 0, 14, 0, 5, 0),
686 value);
687 break;
688 case ARMV8_ESR_EL1: /* mapped to DFSR */
689 retval = dpm->instr_write_data_r0(dpm,
690 ARMV4_5_MCR(15, 0, 0, 5, 0, 0),
691 value);
692 break;
693 case ARMV8_ESR_EL2: /* mapped to HSR */
694 retval = dpm->instr_write_data_r0(dpm,
695 ARMV4_5_MCR(15, 4, 0, 5, 2, 0),
696 value);
697 break;
698 case ARMV8_ESR_EL3: /* FIXME: no equivalent in aarch32? */
699 retval = ERROR_FAIL;
700 break;
701 case ARMV8_SPSR_EL1: /* mapped to SPSR_svc */
702 retval = dpm->instr_write_data_r0(dpm,
703 ARMV8_MSR_GP_XPSR_T1(1, 0, 15),
704 value);
705 break;
706 case ARMV8_SPSR_EL2: /* mapped to SPSR_hyp */
707 retval = dpm->instr_write_data_r0(dpm,
708 ARMV8_MSR_GP_XPSR_T1(1, 0, 15),
709 value);
710 break;
711 case ARMV8_SPSR_EL3: /* mapped to SPSR_mon */
712 retval = dpm->instr_write_data_r0(dpm,
713 ARMV8_MSR_GP_XPSR_T1(1, 0, 15),
714 value);
715 break;
716 case ARMV8_FPSR:
717 /* move to r0 from DCC, then "VMSR FPSCR, r0" */
718 retval = dpm->instr_write_data_r0(dpm,
719 ARMV4_5_VMSR(0), value);
720 break;
721 default:
722 retval = ERROR_FAIL;
723 break;
724 }
725
726 return retval;
727
728 }
729
730 static int armv8_write_reg_simdfp_aarch32(struct armv8_common *armv8, int regnum, uint64_t lvalue, uint64_t hvalue)
731 {
732 int retval = ERROR_FAIL;
733 struct arm_dpm *dpm = &armv8->dpm;
734 struct reg *reg_r1 = dpm->arm->core_cache->reg_list + ARMV8_R1;
735 uint32_t value_r0 = 0, value_r1 = 0;
736 unsigned num = (regnum - ARMV8_V0) << 1;
737
738 switch (regnum) {
739 case ARMV8_V0 ... ARMV8_V15:
740 /* we are going to write R1, mark it dirty */
741 reg_r1->dirty = true;
742 value_r1 = lvalue >> 32;
743 value_r0 = lvalue & 0xFFFFFFFF;
744 /* write value_r1 to r1 via dcc */
745 retval = dpm->instr_write_data_dcc(dpm,
746 ARMV4_5_MRC(14, 0, 1, 0, 5, 0),
747 value_r1);
748 if (retval != ERROR_OK)
749 return retval;
750 /* write value_r0 to r0 via dcc then,
751 * move to double word register from r0:r1: "vmov vm, r0, r1"
752 */
753 retval = dpm->instr_write_data_r0(dpm,
754 ARMV4_5_VMOV(0, 1, 0, (num >> 4), (num & 0xf)),
755 value_r0);
756 if (retval != ERROR_OK)
757 return retval;
758
759 num++;
760 /* repeat above steps for high 64 bits of V register */
761 value_r1 = hvalue >> 32;
762 value_r0 = hvalue & 0xFFFFFFFF;
763 retval = dpm->instr_write_data_dcc(dpm,
764 ARMV4_5_MRC(14, 0, 1, 0, 5, 0),
765 value_r1);
766 if (retval != ERROR_OK)
767 return retval;
768 retval = dpm->instr_write_data_r0(dpm,
769 ARMV4_5_VMOV(0, 1, 0, (num >> 4), (num & 0xf)),
770 value_r0);
771 break;
772 default:
773 retval = ERROR_FAIL;
774 break;
775 }
776
777 return retval;
778 }
779
780 void armv8_select_reg_access(struct armv8_common *armv8, bool is_aarch64)
781 {
782 if (is_aarch64) {
783 armv8->read_reg_u64 = armv8_read_reg;
784 armv8->write_reg_u64 = armv8_write_reg;
785 armv8->read_reg_u128 = armv8_read_reg_simdfp_aarch64;
786 armv8->write_reg_u128 = armv8_write_reg_simdfp_aarch64;
787
788 } else {
789 armv8->read_reg_u64 = armv8_read_reg32;
790 armv8->write_reg_u64 = armv8_write_reg32;
791 armv8->read_reg_u128 = armv8_read_reg_simdfp_aarch32;
792 armv8->write_reg_u128 = armv8_write_reg_simdfp_aarch32;
793 }
794 }
795
796 /* retrieve core id cluster id */
797 int armv8_read_mpidr(struct armv8_common *armv8)
798 {
799 int retval = ERROR_FAIL;
800 struct arm *arm = &armv8->arm;
801 struct arm_dpm *dpm = armv8->arm.dpm;
802 uint32_t mpidr;
803
804 retval = dpm->prepare(dpm);
805 if (retval != ERROR_OK)
806 goto done;
807
808 /* check if we're in an unprivileged mode */
809 if (armv8_curel_from_core_mode(arm->core_mode) < SYSTEM_CUREL_EL1) {
810 retval = armv8_dpm_modeswitch(dpm, ARMV8_64_EL1H);
811 if (retval != ERROR_OK)
812 return retval;
813 }
814
815 retval = dpm->instr_read_data_r0(dpm, armv8_opcode(armv8, READ_REG_MPIDR), &mpidr);
816 if (retval != ERROR_OK)
817 goto done;
818 if (mpidr & 1U<<31) {
819 armv8->multi_processor_system = (mpidr >> 30) & 1;
820 armv8->cluster_id = (mpidr >> 8) & 0xf;
821 armv8->cpu_id = mpidr & 0x3;
822 LOG_INFO("%s cluster %x core %x %s", target_name(armv8->arm.target),
823 armv8->cluster_id,
824 armv8->cpu_id,
825 armv8->multi_processor_system == 0 ? "multi core" : "single core");
826 } else
827 LOG_ERROR("mpidr not in multiprocessor format");
828
829 done:
830 armv8_dpm_modeswitch(dpm, ARM_MODE_ANY);
831 dpm->finish(dpm);
832 return retval;
833 }
834
835 /**
836 * Configures host-side ARM records to reflect the specified CPSR.
837 * Later, code can use arm_reg_current() to map register numbers
838 * according to how they are exposed by this mode.
839 */
840 void armv8_set_cpsr(struct arm *arm, uint32_t cpsr)
841 {
842 uint32_t mode = cpsr & 0x1F;
843
844 /* NOTE: this may be called very early, before the register
845 * cache is set up. We can't defend against many errors, in
846 * particular against CPSRs that aren't valid *here* ...
847 */
848 if (arm->cpsr) {
849 buf_set_u32(arm->cpsr->value, 0, 32, cpsr);
850 arm->cpsr->valid = true;
851 arm->cpsr->dirty = false;
852 }
853
854 /* Older ARMs won't have the J bit */
855 enum arm_state state = 0xFF;
856
857 if ((cpsr & 0x10) != 0) {
858 /* Aarch32 state */
859 if (cpsr & (1 << 5)) { /* T */
860 if (cpsr & (1 << 24)) { /* J */
861 LOG_WARNING("ThumbEE -- incomplete support");
862 state = ARM_STATE_THUMB_EE;
863 } else
864 state = ARM_STATE_THUMB;
865 } else {
866 if (cpsr & (1 << 24)) { /* J */
867 LOG_ERROR("Jazelle state handling is BROKEN!");
868 state = ARM_STATE_JAZELLE;
869 } else
870 state = ARM_STATE_ARM;
871 }
872 } else {
873 /* Aarch64 state */
874 state = ARM_STATE_AARCH64;
875 }
876
877 arm->core_state = state;
878 arm->core_mode = mode;
879
880 LOG_DEBUG("set CPSR %#8.8x: %s mode, %s state", (unsigned) cpsr,
881 armv8_mode_name(arm->core_mode),
882 armv8_state_strings[arm->core_state]);
883 }
884
885 static void armv8_show_fault_registers32(struct armv8_common *armv8)
886 {
887 uint32_t dfsr, ifsr, dfar, ifar;
888 struct arm_dpm *dpm = armv8->arm.dpm;
889 int retval;
890
891 retval = dpm->prepare(dpm);
892 if (retval != ERROR_OK)
893 return;
894
895 /* ARMV4_5_MRC(cpnum, op1, r0, crn, crm, op2) */
896
897 /* c5/c0 - {data, instruction} fault status registers */
898 retval = dpm->instr_read_data_r0(dpm,
899 ARMV4_5_MRC(15, 0, 0, 5, 0, 0),
900 &dfsr);
901 if (retval != ERROR_OK)
902 goto done;
903
904 retval = dpm->instr_read_data_r0(dpm,
905 ARMV4_5_MRC(15, 0, 0, 5, 0, 1),
906 &ifsr);
907 if (retval != ERROR_OK)
908 goto done;
909
910 /* c6/c0 - {data, instruction} fault address registers */
911 retval = dpm->instr_read_data_r0(dpm,
912 ARMV4_5_MRC(15, 0, 0, 6, 0, 0),
913 &dfar);
914 if (retval != ERROR_OK)
915 goto done;
916
917 retval = dpm->instr_read_data_r0(dpm,
918 ARMV4_5_MRC(15, 0, 0, 6, 0, 2),
919 &ifar);
920 if (retval != ERROR_OK)
921 goto done;
922
923 LOG_USER("Data fault registers DFSR: %8.8" PRIx32
924 ", DFAR: %8.8" PRIx32, dfsr, dfar);
925 LOG_USER("Instruction fault registers IFSR: %8.8" PRIx32
926 ", IFAR: %8.8" PRIx32, ifsr, ifar);
927
928 done:
929 /* (void) */ dpm->finish(dpm);
930 }
931
932 static __attribute__((unused)) void armv8_show_fault_registers(struct target *target)
933 {
934 struct armv8_common *armv8 = target_to_armv8(target);
935
936 if (armv8->arm.core_state != ARM_STATE_AARCH64)
937 armv8_show_fault_registers32(armv8);
938 }
939
940 /* method adapted to cortex A : reused arm v4 v5 method*/
941 int armv8_mmu_translate_va(struct target *target, target_addr_t va, target_addr_t *val)
942 {
943 return ERROR_OK;
944 }
945
946 static void armv8_decode_cacheability(int attr)
947 {
948 if (attr == 0) {
949 LOG_USER_N("UNPREDICTABLE");
950 return;
951 }
952 if (attr == 4) {
953 LOG_USER_N("Non-cacheable");
954 return;
955 }
956 switch (attr & 0xC) {
957 case 0:
958 LOG_USER_N("Write-Through Transient");
959 break;
960 case 0x4:
961 LOG_USER_N("Write-Back Transient");
962 break;
963 case 0x8:
964 LOG_USER_N("Write-Through Non-transient");
965 break;
966 case 0xC:
967 LOG_USER_N("Write-Back Non-transient");
968 break;
969 }
970 if (attr & 2)
971 LOG_USER_N(" Read-Allocate");
972 else
973 LOG_USER_N(" No-Read Allocate");
974 if (attr & 1)
975 LOG_USER_N(" Write-Allocate");
976 else
977 LOG_USER_N(" No-Write Allocate");
978 }
979
980 static void armv8_decode_memory_attr(int attr)
981 {
982 if (attr == 0x40) {
983 LOG_USER("Normal Memory, Inner Non-cacheable, "
984 "Outer Non-cacheable, XS=0");
985 } else if (attr == 0xA0) {
986 LOG_USER("Normal Memory, Inner Write-through Cacheable, "
987 "Outer Write-through Cacheable, Read-Allocate, "
988 "No-Write Allocate, Non-transient, XS=0");
989 } else if (attr == 0xF0) {
990 LOG_USER("Tagged Normal Memory, Inner Write-Back, "
991 "Outer Write-Back, Read-Allocate, Write-Allocate, "
992 "Non-transient");
993 } else if ((attr & 0xF0) == 0) {
994 switch (attr & 0xC) {
995 case 0:
996 LOG_USER_N("Device-nGnRnE Memory");
997 break;
998 case 0x4:
999 LOG_USER_N("Device-nGnRE Memory");
1000 break;
1001 case 0x8:
1002 LOG_USER_N("Device-nGRE Memory");
1003 break;
1004 case 0xC:
1005 LOG_USER_N("Device-GRE Memory");
1006 break;
1007 }
1008 if (attr & 1)
1009 LOG_USER(", XS=0");
1010 else
1011 LOG_USER_N("\n");
1012 } else {
1013 LOG_USER_N("Normal Memory, Inner ");
1014 armv8_decode_cacheability(attr & 0xF);
1015 LOG_USER_N(", Outer ");
1016 armv8_decode_cacheability(attr >> 4);
1017 LOG_USER_N("\n");
1018 }
1019 }
1020
1021 /* V8 method VA TO PA */
1022 int armv8_mmu_translate_va_pa(struct target *target, target_addr_t va,
1023 target_addr_t *val, int meminfo)
1024 {
1025 struct armv8_common *armv8 = target_to_armv8(target);
1026 struct arm *arm = target_to_arm(target);
1027 struct arm_dpm *dpm = &armv8->dpm;
1028 enum arm_mode target_mode = ARM_MODE_ANY;
1029 uint32_t retval;
1030 uint32_t instr = 0;
1031 uint64_t par;
1032
1033 static const char * const shared_name[] = {
1034 "Non-", "UNDEFINED ", "Outer ", "Inner "
1035 };
1036
1037 static const char * const secure_name[] = {
1038 "Secure", "Not Secure"
1039 };
1040
1041 if (target->state != TARGET_HALTED) {
1042 LOG_TARGET_ERROR(target, "not halted");
1043 return ERROR_TARGET_NOT_HALTED;
1044 }
1045
1046 retval = dpm->prepare(dpm);
1047 if (retval != ERROR_OK)
1048 return retval;
1049
1050 switch (armv8_curel_from_core_mode(arm->core_mode)) {
1051 case SYSTEM_CUREL_EL0:
1052 instr = ARMV8_SYS(SYSTEM_ATS12E0R, 0);
1053 /* can only execute instruction at EL2 */
1054 target_mode = ARMV8_64_EL2H;
1055 break;
1056 case SYSTEM_CUREL_EL1:
1057 instr = ARMV8_SYS(SYSTEM_ATS12E1R, 0);
1058 /* can only execute instruction at EL2 */
1059 target_mode = ARMV8_64_EL2H;
1060 break;
1061 case SYSTEM_CUREL_EL2:
1062 instr = ARMV8_SYS(SYSTEM_ATS1E2R, 0);
1063 break;
1064 case SYSTEM_CUREL_EL3:
1065 instr = ARMV8_SYS(SYSTEM_ATS1E3R, 0);
1066 break;
1067
1068 default:
1069 break;
1070 };
1071
1072 if (target_mode != ARM_MODE_ANY)
1073 armv8_dpm_modeswitch(dpm, target_mode);
1074
1075 /* write VA to R0 and execute translation instruction */
1076 retval = dpm->instr_write_data_r0_64(dpm, instr, (uint64_t)va);
1077 /* read result from PAR_EL1 */
1078 if (retval == ERROR_OK)
1079 retval = dpm->instr_read_data_r0_64(dpm, ARMV8_MRS(SYSTEM_PAR_EL1, 0), &par);
1080
1081 /* switch back to saved PE mode */
1082 if (target_mode != ARM_MODE_ANY)
1083 armv8_dpm_modeswitch(dpm, ARM_MODE_ANY);
1084
1085 dpm->finish(dpm);
1086
1087 if (retval != ERROR_OK)
1088 return retval;
1089
1090 if (par & 1) {
1091 LOG_ERROR("Address translation failed at stage %i, FST=%x, PTW=%i",
1092 ((int)(par >> 9) & 1)+1, (int)(par >> 1) & 0x3f, (int)(par >> 8) & 1);
1093
1094 *val = 0;
1095 retval = ERROR_FAIL;
1096 } else {
1097 *val = (par & 0xFFFFFFFFF000UL) | (va & 0xFFF);
1098 if (meminfo) {
1099 int SH = (par >> 7) & 3;
1100 int NS = (par >> 9) & 1;
1101 int ATTR = (par >> 56) & 0xFF;
1102
1103 LOG_USER("%sshareable, %s",
1104 shared_name[SH], secure_name[NS]);
1105 armv8_decode_memory_attr(ATTR);
1106 }
1107 }
1108
1109 return retval;
1110 }
1111
1112 COMMAND_HANDLER(armv8_handle_exception_catch_command)
1113 {
1114 struct target *target = get_current_target(CMD_CTX);
1115 struct armv8_common *armv8 = target_to_armv8(target);
1116 uint32_t edeccr = 0;
1117 unsigned int argp = 0;
1118 int retval;
1119
1120 static const struct nvp nvp_ecatch_modes[] = {
1121 { .name = "off", .value = 0 },
1122 { .name = "nsec_el1", .value = (1 << 5) },
1123 { .name = "nsec_el2", .value = (2 << 5) },
1124 { .name = "nsec_el12", .value = (3 << 5) },
1125 { .name = "sec_el1", .value = (1 << 1) },
1126 { .name = "sec_el3", .value = (4 << 1) },
1127 { .name = "sec_el13", .value = (5 << 1) },
1128 { .name = NULL, .value = -1 },
1129 };
1130 const struct nvp *n;
1131
1132 if (CMD_ARGC == 0) {
1133 const char *sec = NULL, *nsec = NULL;
1134
1135 retval = mem_ap_read_atomic_u32(armv8->debug_ap,
1136 armv8->debug_base + CPUV8_DBG_ECCR, &edeccr);
1137 if (retval != ERROR_OK)
1138 return retval;
1139
1140 n = nvp_value2name(nvp_ecatch_modes, edeccr & 0x0f);
1141 if (n->name)
1142 sec = n->name;
1143
1144 n = nvp_value2name(nvp_ecatch_modes, edeccr & 0xf0);
1145 if (n->name)
1146 nsec = n->name;
1147
1148 if (!sec || !nsec) {
1149 LOG_WARNING("Exception Catch: unknown exception catch configuration: EDECCR = %02" PRIx32, edeccr & 0xff);
1150 return ERROR_FAIL;
1151 }
1152
1153 command_print(CMD, "Exception Catch: Secure: %s, Non-Secure: %s", sec, nsec);
1154 return ERROR_OK;
1155 }
1156
1157 while (argp < CMD_ARGC) {
1158 n = nvp_name2value(nvp_ecatch_modes, CMD_ARGV[argp]);
1159 if (!n->name) {
1160 LOG_ERROR("Unknown option: %s", CMD_ARGV[argp]);
1161 return ERROR_FAIL;
1162 }
1163
1164 LOG_DEBUG("found: %s", n->name);
1165
1166 edeccr |= n->value;
1167 argp++;
1168 }
1169
1170 retval = mem_ap_write_atomic_u32(armv8->debug_ap,
1171 armv8->debug_base + CPUV8_DBG_ECCR, edeccr);
1172 if (retval != ERROR_OK)
1173 return retval;
1174
1175 return ERROR_OK;
1176 }
1177
1178 COMMAND_HANDLER(armv8_pauth_command)
1179 {
1180 struct target *target = get_current_target(CMD_CTX);
1181 struct armv8_common *armv8 = target_to_armv8(target);
1182 return CALL_COMMAND_HANDLER(handle_command_parse_bool,
1183 &armv8->enable_pauth,
1184 "pauth feature");
1185 }
1186
1187 int armv8_handle_cache_info_command(struct command_invocation *cmd,
1188 struct armv8_cache_common *armv8_cache)
1189 {
1190 if (armv8_cache->info == -1) {
1191 command_print(cmd, "cache not yet identified");
1192 return ERROR_OK;
1193 }
1194
1195 if (armv8_cache->display_cache_info)
1196 armv8_cache->display_cache_info(cmd, armv8_cache);
1197 return ERROR_OK;
1198 }
1199
1200 static int armv8_setup_semihosting(struct target *target, int enable)
1201 {
1202 return ERROR_OK;
1203 }
1204
1205 int armv8_init_arch_info(struct target *target, struct armv8_common *armv8)
1206 {
1207 struct arm *arm = &armv8->arm;
1208 arm->arch_info = armv8;
1209 target->arch_info = &armv8->arm;
1210 arm->setup_semihosting = armv8_setup_semihosting;
1211 /* target is useful in all function arm v4 5 compatible */
1212 armv8->arm.target = target;
1213 armv8->arm.common_magic = ARM_COMMON_MAGIC;
1214 armv8->common_magic = ARMV8_COMMON_MAGIC;
1215
1216 armv8->armv8_mmu.armv8_cache.l2_cache = NULL;
1217 armv8->armv8_mmu.armv8_cache.info = -1;
1218 armv8->armv8_mmu.armv8_cache.flush_all_data_cache = NULL;
1219 armv8->armv8_mmu.armv8_cache.display_cache_info = NULL;
1220 return ERROR_OK;
1221 }
1222
1223 static int armv8_aarch64_state(struct target *target)
1224 {
1225 struct arm *arm = target_to_arm(target);
1226
1227 if (arm->common_magic != ARM_COMMON_MAGIC) {
1228 LOG_ERROR("BUG: called for a non-ARM target");
1229 return ERROR_FAIL;
1230 }
1231
1232 LOG_USER("%s halted in %s state due to %s, current mode: %s\n"
1233 "cpsr: 0x%8.8" PRIx32 " pc: 0x%" PRIx64 "%s",
1234 target_name(target),
1235 armv8_state_strings[arm->core_state],
1236 debug_reason_name(target),
1237 armv8_mode_name(arm->core_mode),
1238 buf_get_u32(arm->cpsr->value, 0, 32),
1239 buf_get_u64(arm->pc->value, 0, 64),
1240 (target->semihosting && target->semihosting->is_active) ? ", semihosting" : "");
1241
1242 return ERROR_OK;
1243 }
1244
1245 int armv8_arch_state(struct target *target)
1246 {
1247 static const char * const state[] = {
1248 "disabled", "enabled"
1249 };
1250
1251 struct armv8_common *armv8 = target_to_armv8(target);
1252 struct arm *arm = &armv8->arm;
1253
1254 if (armv8->common_magic != ARMV8_COMMON_MAGIC) {
1255 LOG_ERROR("BUG: called for a non-Armv8 target");
1256 return ERROR_COMMAND_SYNTAX_ERROR;
1257 }
1258
1259 if (arm->core_state == ARM_STATE_AARCH64)
1260 armv8_aarch64_state(target);
1261 else
1262 arm_arch_state(target);
1263
1264 LOG_USER("MMU: %s, D-Cache: %s, I-Cache: %s",
1265 state[armv8->armv8_mmu.mmu_enabled],
1266 state[armv8->armv8_mmu.armv8_cache.d_u_cache_enabled],
1267 state[armv8->armv8_mmu.armv8_cache.i_cache_enabled]);
1268
1269 if (arm->core_mode == ARM_MODE_ABT)
1270 armv8_show_fault_registers(target);
1271
1272 if (target->debug_reason == DBG_REASON_WATCHPOINT)
1273 LOG_USER("Watchpoint triggered at " TARGET_ADDR_FMT, armv8->dpm.wp_addr);
1274
1275 return ERROR_OK;
1276 }
1277
1278 static struct reg_data_type aarch64_vector_base_types[] = {
1279 {REG_TYPE_IEEE_DOUBLE, "ieee_double", 0, {NULL} },
1280 {REG_TYPE_UINT64, "uint64", 0, {NULL} },
1281 {REG_TYPE_INT64, "int64", 0, {NULL} },
1282 {REG_TYPE_IEEE_SINGLE, "ieee_single", 0, {NULL} },
1283 {REG_TYPE_UINT32, "uint32", 0, {NULL} },
1284 {REG_TYPE_INT32, "int32", 0, {NULL} },
1285 {REG_TYPE_UINT16, "uint16", 0, {NULL} },
1286 {REG_TYPE_INT16, "int16", 0, {NULL} },
1287 {REG_TYPE_UINT8, "uint8", 0, {NULL} },
1288 {REG_TYPE_INT8, "int8", 0, {NULL} },
1289 {REG_TYPE_UINT128, "uint128", 0, {NULL} },
1290 {REG_TYPE_INT128, "int128", 0, {NULL} }
1291 };
1292
1293 static struct reg_data_type_vector aarch64_vector_types[] = {
1294 {aarch64_vector_base_types + 0, 2},
1295 {aarch64_vector_base_types + 1, 2},
1296 {aarch64_vector_base_types + 2, 2},
1297 {aarch64_vector_base_types + 3, 4},
1298 {aarch64_vector_base_types + 4, 4},
1299 {aarch64_vector_base_types + 5, 4},
1300 {aarch64_vector_base_types + 6, 8},
1301 {aarch64_vector_base_types + 7, 8},
1302 {aarch64_vector_base_types + 8, 16},
1303 {aarch64_vector_base_types + 9, 16},
1304 {aarch64_vector_base_types + 10, 01},
1305 {aarch64_vector_base_types + 11, 01},
1306 };
1307
1308 static struct reg_data_type aarch64_fpu_vector[] = {
1309 {REG_TYPE_ARCH_DEFINED, "v2d", REG_TYPE_CLASS_VECTOR, {aarch64_vector_types + 0} },
1310 {REG_TYPE_ARCH_DEFINED, "v2u", REG_TYPE_CLASS_VECTOR, {aarch64_vector_types + 1} },
1311 {REG_TYPE_ARCH_DEFINED, "v2i", REG_TYPE_CLASS_VECTOR, {aarch64_vector_types + 2} },
1312 {REG_TYPE_ARCH_DEFINED, "v4f", REG_TYPE_CLASS_VECTOR, {aarch64_vector_types + 3} },
1313 {REG_TYPE_ARCH_DEFINED, "v4u", REG_TYPE_CLASS_VECTOR, {aarch64_vector_types + 4} },
1314 {REG_TYPE_ARCH_DEFINED, "v4i", REG_TYPE_CLASS_VECTOR, {aarch64_vector_types + 5} },
1315 {REG_TYPE_ARCH_DEFINED, "v8u", REG_TYPE_CLASS_VECTOR, {aarch64_vector_types + 6} },
1316 {REG_TYPE_ARCH_DEFINED, "v8i", REG_TYPE_CLASS_VECTOR, {aarch64_vector_types + 7} },
1317 {REG_TYPE_ARCH_DEFINED, "v16u", REG_TYPE_CLASS_VECTOR, {aarch64_vector_types + 8} },
1318 {REG_TYPE_ARCH_DEFINED, "v16i", REG_TYPE_CLASS_VECTOR, {aarch64_vector_types + 9} },
1319 {REG_TYPE_ARCH_DEFINED, "v1u", REG_TYPE_CLASS_VECTOR, {aarch64_vector_types + 10} },
1320 {REG_TYPE_ARCH_DEFINED, "v1i", REG_TYPE_CLASS_VECTOR, {aarch64_vector_types + 11} },
1321 };
1322
1323 static struct reg_data_type_union_field aarch64_union_fields_vnd[] = {
1324 {"f", aarch64_fpu_vector + 0, aarch64_union_fields_vnd + 1},
1325 {"u", aarch64_fpu_vector + 1, aarch64_union_fields_vnd + 2},
1326 {"s", aarch64_fpu_vector + 2, NULL},
1327 };
1328
1329 static struct reg_data_type_union_field aarch64_union_fields_vns[] = {
1330 {"f", aarch64_fpu_vector + 3, aarch64_union_fields_vns + 1},
1331 {"u", aarch64_fpu_vector + 4, aarch64_union_fields_vns + 2},
1332 {"s", aarch64_fpu_vector + 5, NULL},
1333 };
1334
1335 static struct reg_data_type_union_field aarch64_union_fields_vnh[] = {
1336 {"u", aarch64_fpu_vector + 6, aarch64_union_fields_vnh + 1},
1337 {"s", aarch64_fpu_vector + 7, NULL},
1338 };
1339
1340 static struct reg_data_type_union_field aarch64_union_fields_vnb[] = {
1341 {"u", aarch64_fpu_vector + 8, aarch64_union_fields_vnb + 1},
1342 {"s", aarch64_fpu_vector + 9, NULL},
1343 };
1344
1345 static struct reg_data_type_union_field aarch64_union_fields_vnq[] = {
1346 {"u", aarch64_fpu_vector + 10, aarch64_union_fields_vnq + 1},
1347 {"s", aarch64_fpu_vector + 11, NULL},
1348 };
1349
1350 static struct reg_data_type_union aarch64_union_types[] = {
1351 {aarch64_union_fields_vnd},
1352 {aarch64_union_fields_vns},
1353 {aarch64_union_fields_vnh},
1354 {aarch64_union_fields_vnb},
1355 {aarch64_union_fields_vnq},
1356 };
1357
1358 static struct reg_data_type aarch64_fpu_union[] = {
1359 {REG_TYPE_ARCH_DEFINED, "vnd", REG_TYPE_CLASS_UNION, {.reg_type_union = aarch64_union_types + 0} },
1360 {REG_TYPE_ARCH_DEFINED, "vns", REG_TYPE_CLASS_UNION, {.reg_type_union = aarch64_union_types + 1} },
1361 {REG_TYPE_ARCH_DEFINED, "vnh", REG_TYPE_CLASS_UNION, {.reg_type_union = aarch64_union_types + 2} },
1362 {REG_TYPE_ARCH_DEFINED, "vnb", REG_TYPE_CLASS_UNION, {.reg_type_union = aarch64_union_types + 3} },
1363 {REG_TYPE_ARCH_DEFINED, "vnq", REG_TYPE_CLASS_UNION, {.reg_type_union = aarch64_union_types + 4} },
1364 };
1365
1366 static struct reg_data_type_union_field aarch64v_union_fields[] = {
1367 {"d", aarch64_fpu_union + 0, aarch64v_union_fields + 1},
1368 {"s", aarch64_fpu_union + 1, aarch64v_union_fields + 2},
1369 {"h", aarch64_fpu_union + 2, aarch64v_union_fields + 3},
1370 {"b", aarch64_fpu_union + 3, aarch64v_union_fields + 4},
1371 {"q", aarch64_fpu_union + 4, NULL},
1372 };
1373
1374 static struct reg_data_type_union aarch64v_union[] = {
1375 {aarch64v_union_fields}
1376 };
1377
1378 static struct reg_data_type aarch64v[] = {
1379 {REG_TYPE_ARCH_DEFINED, "aarch64v", REG_TYPE_CLASS_UNION,
1380 {.reg_type_union = aarch64v_union} },
1381 };
1382
1383 static struct reg_data_type_bitfield aarch64_cpsr_bits[] = {
1384 { 0, 0, REG_TYPE_UINT8 },
1385 { 2, 3, REG_TYPE_UINT8 },
1386 { 4, 4, REG_TYPE_UINT8 },
1387 { 6, 6, REG_TYPE_BOOL },
1388 { 7, 7, REG_TYPE_BOOL },
1389 { 8, 8, REG_TYPE_BOOL },
1390 { 9, 9, REG_TYPE_BOOL },
1391 { 20, 20, REG_TYPE_BOOL },
1392 { 21, 21, REG_TYPE_BOOL },
1393 { 28, 28, REG_TYPE_BOOL },
1394 { 29, 29, REG_TYPE_BOOL },
1395 { 30, 30, REG_TYPE_BOOL },
1396 { 31, 31, REG_TYPE_BOOL },
1397 };
1398
1399 static struct reg_data_type_flags_field aarch64_cpsr_fields[] = {
1400 { "SP", aarch64_cpsr_bits + 0, aarch64_cpsr_fields + 1 },
1401 { "EL", aarch64_cpsr_bits + 1, aarch64_cpsr_fields + 2 },
1402 { "nRW", aarch64_cpsr_bits + 2, aarch64_cpsr_fields + 3 },
1403 { "F", aarch64_cpsr_bits + 3, aarch64_cpsr_fields + 4 },
1404 { "I", aarch64_cpsr_bits + 4, aarch64_cpsr_fields + 5 },
1405 { "A", aarch64_cpsr_bits + 5, aarch64_cpsr_fields + 6 },
1406 { "D", aarch64_cpsr_bits + 6, aarch64_cpsr_fields + 7 },
1407 { "IL", aarch64_cpsr_bits + 7, aarch64_cpsr_fields + 8 },
1408 { "SS", aarch64_cpsr_bits + 8, aarch64_cpsr_fields + 9 },
1409 { "V", aarch64_cpsr_bits + 9, aarch64_cpsr_fields + 10 },
1410 { "C", aarch64_cpsr_bits + 10, aarch64_cpsr_fields + 11 },
1411 { "Z", aarch64_cpsr_bits + 11, aarch64_cpsr_fields + 12 },
1412 { "N", aarch64_cpsr_bits + 12, NULL }
1413 };
1414
1415 static struct reg_data_type_flags aarch64_cpsr_flags[] = {
1416 { 4, aarch64_cpsr_fields }
1417 };
1418
1419 static struct reg_data_type aarch64_flags_cpsr[] = {
1420 {REG_TYPE_ARCH_DEFINED, "cpsr_flags", REG_TYPE_CLASS_FLAGS,
1421 {.reg_type_flags = aarch64_cpsr_flags} },
1422 };
1423
1424 static const struct {
1425 unsigned id;
1426 const char *name;
1427 unsigned bits;
1428 enum arm_mode mode;
1429 enum reg_type type;
1430 const char *group;
1431 const char *feature;
1432 struct reg_data_type *data_type;
1433 } armv8_regs[] = {
1434 { ARMV8_R0, "x0", 64, ARM_MODE_ANY, REG_TYPE_UINT64, "general", "org.gnu.gdb.aarch64.core", NULL},
1435 { ARMV8_R1, "x1", 64, ARM_MODE_ANY, REG_TYPE_UINT64, "general", "org.gnu.gdb.aarch64.core", NULL},
1436 { ARMV8_R2, "x2", 64, ARM_MODE_ANY, REG_TYPE_UINT64, "general", "org.gnu.gdb.aarch64.core", NULL},
1437 { ARMV8_R3, "x3", 64, ARM_MODE_ANY, REG_TYPE_UINT64, "general", "org.gnu.gdb.aarch64.core", NULL},
1438 { ARMV8_R4, "x4", 64, ARM_MODE_ANY, REG_TYPE_UINT64, "general", "org.gnu.gdb.aarch64.core", NULL},
1439 { ARMV8_R5, "x5", 64, ARM_MODE_ANY, REG_TYPE_UINT64, "general", "org.gnu.gdb.aarch64.core", NULL},
1440 { ARMV8_R6, "x6", 64, ARM_MODE_ANY, REG_TYPE_UINT64, "general", "org.gnu.gdb.aarch64.core", NULL},
1441 { ARMV8_R7, "x7", 64, ARM_MODE_ANY, REG_TYPE_UINT64, "general", "org.gnu.gdb.aarch64.core", NULL},
1442 { ARMV8_R8, "x8", 64, ARM_MODE_ANY, REG_TYPE_UINT64, "general", "org.gnu.gdb.aarch64.core", NULL},
1443 { ARMV8_R9, "x9", 64, ARM_MODE_ANY, REG_TYPE_UINT64, "general", "org.gnu.gdb.aarch64.core", NULL},
1444 { ARMV8_R10, "x10", 64, ARM_MODE_ANY, REG_TYPE_UINT64, "general", "org.gnu.gdb.aarch64.core", NULL},
1445 { ARMV8_R11, "x11", 64, ARM_MODE_ANY, REG_TYPE_UINT64, "general", "org.gnu.gdb.aarch64.core", NULL},
1446 { ARMV8_R12, "x12", 64, ARM_MODE_ANY, REG_TYPE_UINT64, "general", "org.gnu.gdb.aarch64.core", NULL},
1447 { ARMV8_R13, "x13", 64, ARM_MODE_ANY, REG_TYPE_UINT64, "general", "org.gnu.gdb.aarch64.core", NULL},
1448 { ARMV8_R14, "x14", 64, ARM_MODE_ANY, REG_TYPE_UINT64, "general", "org.gnu.gdb.aarch64.core", NULL},
1449 { ARMV8_R15, "x15", 64, ARM_MODE_ANY, REG_TYPE_UINT64, "general", "org.gnu.gdb.aarch64.core", NULL},
1450 { ARMV8_R16, "x16", 64, ARM_MODE_ANY, REG_TYPE_UINT64, "general", "org.gnu.gdb.aarch64.core", NULL},
1451 { ARMV8_R17, "x17", 64, ARM_MODE_ANY, REG_TYPE_UINT64, "general", "org.gnu.gdb.aarch64.core", NULL},
1452 { ARMV8_R18, "x18", 64, ARM_MODE_ANY, REG_TYPE_UINT64, "general", "org.gnu.gdb.aarch64.core", NULL},
1453 { ARMV8_R19, "x19", 64, ARM_MODE_ANY, REG_TYPE_UINT64, "general", "org.gnu.gdb.aarch64.core", NULL},
1454 { ARMV8_R20, "x20", 64, ARM_MODE_ANY, REG_TYPE_UINT64, "general", "org.gnu.gdb.aarch64.core", NULL},
1455 { ARMV8_R21, "x21", 64, ARM_MODE_ANY, REG_TYPE_UINT64, "general", "org.gnu.gdb.aarch64.core", NULL},
1456 { ARMV8_R22, "x22", 64, ARM_MODE_ANY, REG_TYPE_UINT64, "general", "org.gnu.gdb.aarch64.core", NULL},
1457 { ARMV8_R23, "x23", 64, ARM_MODE_ANY, REG_TYPE_UINT64, "general", "org.gnu.gdb.aarch64.core", NULL},
1458 { ARMV8_R24, "x24", 64, ARM_MODE_ANY, REG_TYPE_UINT64, "general", "org.gnu.gdb.aarch64.core", NULL},
1459 { ARMV8_R25, "x25", 64, ARM_MODE_ANY, REG_TYPE_UINT64, "general", "org.gnu.gdb.aarch64.core", NULL},
1460 { ARMV8_R26, "x26", 64, ARM_MODE_ANY, REG_TYPE_UINT64, "general", "org.gnu.gdb.aarch64.core", NULL},
1461 { ARMV8_R27, "x27", 64, ARM_MODE_ANY, REG_TYPE_UINT64, "general", "org.gnu.gdb.aarch64.core", NULL},
1462 { ARMV8_R28, "x28", 64, ARM_MODE_ANY, REG_TYPE_UINT64, "general", "org.gnu.gdb.aarch64.core", NULL},
1463 { ARMV8_R29, "x29", 64, ARM_MODE_ANY, REG_TYPE_UINT64, "general", "org.gnu.gdb.aarch64.core", NULL},
1464 { ARMV8_R30, "x30", 64, ARM_MODE_ANY, REG_TYPE_UINT64, "general", "org.gnu.gdb.aarch64.core", NULL},
1465
1466 { ARMV8_SP, "sp", 64, ARM_MODE_ANY, REG_TYPE_DATA_PTR, "general", "org.gnu.gdb.aarch64.core", NULL},
1467 { ARMV8_PC, "pc", 64, ARM_MODE_ANY, REG_TYPE_CODE_PTR, "general", "org.gnu.gdb.aarch64.core", NULL},
1468 { ARMV8_XPSR, "cpsr", 32, ARM_MODE_ANY, REG_TYPE_ARCH_DEFINED,
1469 "general", "org.gnu.gdb.aarch64.core", aarch64_flags_cpsr},
1470 { ARMV8_V0, "v0", 128, ARM_MODE_ANY, REG_TYPE_ARCH_DEFINED, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v},
1471 { ARMV8_V1, "v1", 128, ARM_MODE_ANY, REG_TYPE_ARCH_DEFINED, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v},
1472 { ARMV8_V2, "v2", 128, ARM_MODE_ANY, REG_TYPE_ARCH_DEFINED, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v},
1473 { ARMV8_V3, "v3", 128, ARM_MODE_ANY, REG_TYPE_ARCH_DEFINED, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v},
1474 { ARMV8_V4, "v4", 128, ARM_MODE_ANY, REG_TYPE_ARCH_DEFINED, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v},
1475 { ARMV8_V5, "v5", 128, ARM_MODE_ANY, REG_TYPE_ARCH_DEFINED, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v},
1476 { ARMV8_V6, "v6", 128, ARM_MODE_ANY, REG_TYPE_ARCH_DEFINED, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v},
1477 { ARMV8_V7, "v7", 128, ARM_MODE_ANY, REG_TYPE_ARCH_DEFINED, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v},
1478 { ARMV8_V8, "v8", 128, ARM_MODE_ANY, REG_TYPE_ARCH_DEFINED, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v},
1479 { ARMV8_V9, "v9", 128, ARM_MODE_ANY, REG_TYPE_ARCH_DEFINED, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v},
1480 { ARMV8_V10, "v10", 128, ARM_MODE_ANY, REG_TYPE_ARCH_DEFINED, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v},
1481 { ARMV8_V11, "v11", 128, ARM_MODE_ANY, REG_TYPE_ARCH_DEFINED, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v},
1482 { ARMV8_V12, "v12", 128, ARM_MODE_ANY, REG_TYPE_ARCH_DEFINED, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v},
1483 { ARMV8_V13, "v13", 128, ARM_MODE_ANY, REG_TYPE_ARCH_DEFINED, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v},
1484 { ARMV8_V14, "v14", 128, ARM_MODE_ANY, REG_TYPE_ARCH_DEFINED, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v},
1485 { ARMV8_V15, "v15", 128, ARM_MODE_ANY, REG_TYPE_ARCH_DEFINED, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v},
1486 { ARMV8_V16, "v16", 128, ARM_MODE_ANY, REG_TYPE_ARCH_DEFINED, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v},
1487 { ARMV8_V17, "v17", 128, ARM_MODE_ANY, REG_TYPE_ARCH_DEFINED, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v},
1488 { ARMV8_V18, "v18", 128, ARM_MODE_ANY, REG_TYPE_ARCH_DEFINED, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v},
1489 { ARMV8_V19, "v19", 128, ARM_MODE_ANY, REG_TYPE_ARCH_DEFINED, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v},
1490 { ARMV8_V20, "v20", 128, ARM_MODE_ANY, REG_TYPE_ARCH_DEFINED, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v},
1491 { ARMV8_V21, "v21", 128, ARM_MODE_ANY, REG_TYPE_ARCH_DEFINED, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v},
1492 { ARMV8_V22, "v22", 128, ARM_MODE_ANY, REG_TYPE_ARCH_DEFINED, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v},
1493 { ARMV8_V23, "v23", 128, ARM_MODE_ANY, REG_TYPE_ARCH_DEFINED, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v},
1494 { ARMV8_V24, "v24", 128, ARM_MODE_ANY, REG_TYPE_ARCH_DEFINED, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v},
1495 { ARMV8_V25, "v25", 128, ARM_MODE_ANY, REG_TYPE_ARCH_DEFINED, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v},
1496 { ARMV8_V26, "v26", 128, ARM_MODE_ANY, REG_TYPE_ARCH_DEFINED, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v},
1497 { ARMV8_V27, "v27", 128, ARM_MODE_ANY, REG_TYPE_ARCH_DEFINED, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v},
1498 { ARMV8_V28, "v28", 128, ARM_MODE_ANY, REG_TYPE_ARCH_DEFINED, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v},
1499 { ARMV8_V29, "v29", 128, ARM_MODE_ANY, REG_TYPE_ARCH_DEFINED, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v},
1500 { ARMV8_V30, "v30", 128, ARM_MODE_ANY, REG_TYPE_ARCH_DEFINED, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v},
1501 { ARMV8_V31, "v31", 128, ARM_MODE_ANY, REG_TYPE_ARCH_DEFINED, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v},
1502 { ARMV8_FPSR, "fpsr", 32, ARM_MODE_ANY, REG_TYPE_UINT32, "simdfp", "org.gnu.gdb.aarch64.fpu", NULL},
1503 { ARMV8_FPCR, "fpcr", 32, ARM_MODE_ANY, REG_TYPE_UINT32, "simdfp", "org.gnu.gdb.aarch64.fpu", NULL},
1504
1505 { ARMV8_ELR_EL1, "ELR_EL1", 64, ARMV8_64_EL1H, REG_TYPE_CODE_PTR, "banked", "net.sourceforge.openocd.banked",
1506 NULL},
1507 { ARMV8_ESR_EL1, "ESR_EL1", 32, ARMV8_64_EL1H, REG_TYPE_UINT32, "banked", "net.sourceforge.openocd.banked",
1508 NULL},
1509 { ARMV8_SPSR_EL1, "SPSR_EL1", 32, ARMV8_64_EL1H, REG_TYPE_UINT32, "banked", "net.sourceforge.openocd.banked",
1510 NULL},
1511
1512 { ARMV8_ELR_EL2, "ELR_EL2", 64, ARMV8_64_EL2H, REG_TYPE_CODE_PTR, "banked", "net.sourceforge.openocd.banked",
1513 NULL},
1514 { ARMV8_ESR_EL2, "ESR_EL2", 32, ARMV8_64_EL2H, REG_TYPE_UINT32, "banked", "net.sourceforge.openocd.banked",
1515 NULL},
1516 { ARMV8_SPSR_EL2, "SPSR_EL2", 32, ARMV8_64_EL2H, REG_TYPE_UINT32, "banked", "net.sourceforge.openocd.banked",
1517 NULL},
1518
1519 { ARMV8_ELR_EL3, "ELR_EL3", 64, ARMV8_64_EL3H, REG_TYPE_CODE_PTR, "banked", "net.sourceforge.openocd.banked",
1520 NULL},
1521 { ARMV8_ESR_EL3, "ESR_EL3", 32, ARMV8_64_EL3H, REG_TYPE_UINT32, "banked", "net.sourceforge.openocd.banked",
1522 NULL},
1523 { ARMV8_SPSR_EL3, "SPSR_EL3", 32, ARMV8_64_EL3H, REG_TYPE_UINT32, "banked", "net.sourceforge.openocd.banked",
1524 NULL},
1525 { ARMV8_PAUTH_DMASK, "pauth_dmask", 64, ARM_MODE_ANY, REG_TYPE_UINT64, NULL, "org.gnu.gdb.aarch64.pauth", NULL},
1526 { ARMV8_PAUTH_CMASK, "pauth_cmask", 64, ARM_MODE_ANY, REG_TYPE_UINT64, NULL, "org.gnu.gdb.aarch64.pauth", NULL},
1527 };
1528
1529 static const struct {
1530 unsigned id;
1531 unsigned mapping;
1532 const char *name;
1533 unsigned bits;
1534 enum arm_mode mode;
1535 enum reg_type type;
1536 const char *group;
1537 const char *feature;
1538 } armv8_regs32[] = {
1539 { ARMV8_R0, 0, "r0", 32, ARM_MODE_ANY, REG_TYPE_UINT32, "general", "org.gnu.gdb.arm.core" },
1540 { ARMV8_R1, 0, "r1", 32, ARM_MODE_ANY, REG_TYPE_UINT32, "general", "org.gnu.gdb.arm.core" },
1541 { ARMV8_R2, 0, "r2", 32, ARM_MODE_ANY, REG_TYPE_UINT32, "general", "org.gnu.gdb.arm.core" },
1542 { ARMV8_R3, 0, "r3", 32, ARM_MODE_ANY, REG_TYPE_UINT32, "general", "org.gnu.gdb.arm.core" },
1543 { ARMV8_R4, 0, "r4", 32, ARM_MODE_ANY, REG_TYPE_UINT32, "general", "org.gnu.gdb.arm.core" },
1544 { ARMV8_R5, 0, "r5", 32, ARM_MODE_ANY, REG_TYPE_UINT32, "general", "org.gnu.gdb.arm.core" },
1545 { ARMV8_R6, 0, "r6", 32, ARM_MODE_ANY, REG_TYPE_UINT32, "general", "org.gnu.gdb.arm.core" },
1546 { ARMV8_R7, 0, "r7", 32, ARM_MODE_ANY, REG_TYPE_UINT32, "general", "org.gnu.gdb.arm.core" },
1547 { ARMV8_R8, 0, "r8", 32, ARM_MODE_ANY, REG_TYPE_UINT32, "general", "org.gnu.gdb.arm.core" },
1548 { ARMV8_R9, 0, "r9", 32, ARM_MODE_ANY, REG_TYPE_UINT32, "general", "org.gnu.gdb.arm.core" },
1549 { ARMV8_R10, 0, "r10", 32, ARM_MODE_ANY, REG_TYPE_UINT32, "general", "org.gnu.gdb.arm.core" },
1550 { ARMV8_R11, 0, "r11", 32, ARM_MODE_ANY, REG_TYPE_UINT32, "general", "org.gnu.gdb.arm.core" },
1551 { ARMV8_R12, 0, "r12", 32, ARM_MODE_ANY, REG_TYPE_UINT32, "general", "org.gnu.gdb.arm.core" },
1552 { ARMV8_R13, 0, "sp", 32, ARM_MODE_ANY, REG_TYPE_DATA_PTR, "general", "org.gnu.gdb.arm.core" },
1553 { ARMV8_R14, 0, "lr", 32, ARM_MODE_ANY, REG_TYPE_CODE_PTR, "general", "org.gnu.gdb.arm.core" },
1554 { ARMV8_PC, 0, "pc", 32, ARM_MODE_ANY, REG_TYPE_CODE_PTR, "general", "org.gnu.gdb.arm.core" },
1555 { ARMV8_XPSR, 0, "cpsr", 32, ARM_MODE_ANY, REG_TYPE_UINT32, "general", "org.gnu.gdb.arm.core" },
1556 { ARMV8_V0, 0, "d0", 64, ARM_MODE_ANY, REG_TYPE_IEEE_DOUBLE, NULL, "org.gnu.gdb.arm.vfp"},
1557 { ARMV8_V0, 8, "d1", 64, ARM_MODE_ANY, REG_TYPE_IEEE_DOUBLE, NULL, "org.gnu.gdb.arm.vfp"},
1558 { ARMV8_V1, 0, "d2", 64, ARM_MODE_ANY, REG_TYPE_IEEE_DOUBLE, NULL, "org.gnu.gdb.arm.vfp"},
1559 { ARMV8_V1, 8, "d3", 64, ARM_MODE_ANY, REG_TYPE_IEEE_DOUBLE, NULL, "org.gnu.gdb.arm.vfp"},
1560 { ARMV8_V2, 0, "d4", 64, ARM_MODE_ANY, REG_TYPE_IEEE_DOUBLE, NULL, "org.gnu.gdb.arm.vfp"},
1561 { ARMV8_V2, 8, "d5", 64, ARM_MODE_ANY, REG_TYPE_IEEE_DOUBLE, NULL, "org.gnu.gdb.arm.vfp"},
1562 { ARMV8_V3, 0, "d6", 64, ARM_MODE_ANY, REG_TYPE_IEEE_DOUBLE, NULL, "org.gnu.gdb.arm.vfp"},
1563 { ARMV8_V3, 8, "d7", 64, ARM_MODE_ANY, REG_TYPE_IEEE_DOUBLE, NULL, "org.gnu.gdb.arm.vfp"},
1564 { ARMV8_V4, 0, "d8", 64, ARM_MODE_ANY, REG_TYPE_IEEE_DOUBLE, NULL, "org.gnu.gdb.arm.vfp"},
1565 { ARMV8_V4, 8, "d9", 64, ARM_MODE_ANY, REG_TYPE_IEEE_DOUBLE, NULL, "org.gnu.gdb.arm.vfp"},
1566 { ARMV8_V5, 0, "d10", 64, ARM_MODE_ANY, REG_TYPE_IEEE_DOUBLE, NULL, "org.gnu.gdb.arm.vfp"},
1567 { ARMV8_V5, 8, "d11", 64, ARM_MODE_ANY, REG_TYPE_IEEE_DOUBLE, NULL, "org.gnu.gdb.arm.vfp"},
1568 { ARMV8_V6, 0, "d12", 64, ARM_MODE_ANY, REG_TYPE_IEEE_DOUBLE, NULL, "org.gnu.gdb.arm.vfp"},
1569 { ARMV8_V6, 8, "d13", 64, ARM_MODE_ANY, REG_TYPE_IEEE_DOUBLE, NULL, "org.gnu.gdb.arm.vfp"},
1570 { ARMV8_V7, 0, "d14", 64, ARM_MODE_ANY, REG_TYPE_IEEE_DOUBLE, NULL, "org.gnu.gdb.arm.vfp"},
1571 { ARMV8_V7, 8, "d15", 64, ARM_MODE_ANY, REG_TYPE_IEEE_DOUBLE, NULL, "org.gnu.gdb.arm.vfp"},
1572 { ARMV8_V8, 0, "d16", 64, ARM_MODE_ANY, REG_TYPE_IEEE_DOUBLE, NULL, "org.gnu.gdb.arm.vfp"},
1573 { ARMV8_V8, 8, "d17", 64, ARM_MODE_ANY, REG_TYPE_IEEE_DOUBLE, NULL, "org.gnu.gdb.arm.vfp"},
1574 { ARMV8_V9, 0, "d18", 64, ARM_MODE_ANY, REG_TYPE_IEEE_DOUBLE, NULL, "org.gnu.gdb.arm.vfp"},
1575 { ARMV8_V9, 8, "d19", 64, ARM_MODE_ANY, REG_TYPE_IEEE_DOUBLE, NULL, "org.gnu.gdb.arm.vfp"},
1576 { ARMV8_V10, 0, "d20", 64, ARM_MODE_ANY, REG_TYPE_IEEE_DOUBLE, NULL, "org.gnu.gdb.arm.vfp"},
1577 { ARMV8_V10, 8, "d21", 64, ARM_MODE_ANY, REG_TYPE_IEEE_DOUBLE, NULL, "org.gnu.gdb.arm.vfp"},
1578 { ARMV8_V11, 0, "d22", 64, ARM_MODE_ANY, REG_TYPE_IEEE_DOUBLE, NULL, "org.gnu.gdb.arm.vfp"},
1579 { ARMV8_V11, 8, "d23", 64, ARM_MODE_ANY, REG_TYPE_IEEE_DOUBLE, NULL, "org.gnu.gdb.arm.vfp"},
1580 { ARMV8_V12, 0, "d24", 64, ARM_MODE_ANY, REG_TYPE_IEEE_DOUBLE, NULL, "org.gnu.gdb.arm.vfp"},
1581 { ARMV8_V12, 8, "d25", 64, ARM_MODE_ANY, REG_TYPE_IEEE_DOUBLE, NULL, "org.gnu.gdb.arm.vfp"},
1582 { ARMV8_V13, 0, "d26", 64, ARM_MODE_ANY, REG_TYPE_IEEE_DOUBLE, NULL, "org.gnu.gdb.arm.vfp"},
1583 { ARMV8_V13, 8, "d27", 64, ARM_MODE_ANY, REG_TYPE_IEEE_DOUBLE, NULL, "org.gnu.gdb.arm.vfp"},
1584 { ARMV8_V14, 0, "d28", 64, ARM_MODE_ANY, REG_TYPE_IEEE_DOUBLE, NULL, "org.gnu.gdb.arm.vfp"},
1585 { ARMV8_V14, 8, "d29", 64, ARM_MODE_ANY, REG_TYPE_IEEE_DOUBLE, NULL, "org.gnu.gdb.arm.vfp"},
1586 { ARMV8_V15, 0, "d30", 64, ARM_MODE_ANY, REG_TYPE_IEEE_DOUBLE, NULL, "org.gnu.gdb.arm.vfp"},
1587 { ARMV8_V15, 8, "d31", 64, ARM_MODE_ANY, REG_TYPE_IEEE_DOUBLE, NULL, "org.gnu.gdb.arm.vfp"},
1588 { ARMV8_FPSR, 0, "fpscr", 32, ARM_MODE_ANY, REG_TYPE_UINT32, "float", "org.gnu.gdb.arm.vfp"},
1589 };
1590
1591 #define ARMV8_NUM_REGS ARRAY_SIZE(armv8_regs)
1592 #define ARMV8_NUM_REGS32 ARRAY_SIZE(armv8_regs32)
1593
1594 static int armv8_get_core_reg(struct reg *reg)
1595 {
1596 struct arm_reg *armv8_reg = reg->arch_info;
1597 struct target *target = armv8_reg->target;
1598 struct arm *arm = target_to_arm(target);
1599
1600 if (target->state != TARGET_HALTED)
1601 return ERROR_TARGET_NOT_HALTED;
1602
1603 return arm->read_core_reg(target, reg, armv8_reg->num, arm->core_mode);
1604 }
1605
1606 static int armv8_set_core_reg(struct reg *reg, uint8_t *buf)
1607 {
1608 struct arm_reg *armv8_reg = reg->arch_info;
1609 struct target *target = armv8_reg->target;
1610 struct arm *arm = target_to_arm(target);
1611 uint64_t value = buf_get_u64(buf, 0, reg->size);
1612
1613 if (target->state != TARGET_HALTED)
1614 return ERROR_TARGET_NOT_HALTED;
1615
1616 if (reg->size <= 64) {
1617 if (reg == arm->cpsr)
1618 armv8_set_cpsr(arm, (uint32_t)value);
1619 else {
1620 buf_set_u64(reg->value, 0, reg->size, value);
1621 reg->valid = true;
1622 }
1623 } else if (reg->size <= 128) {
1624 uint64_t hvalue = buf_get_u64(buf + 8, 0, reg->size - 64);
1625
1626 buf_set_u64(reg->value, 0, 64, value);
1627 buf_set_u64(reg->value + 8, 0, reg->size - 64, hvalue);
1628 reg->valid = true;
1629 }
1630
1631 reg->dirty = true;
1632
1633 return ERROR_OK;
1634 }
1635
1636 static const struct reg_arch_type armv8_reg_type = {
1637 .get = armv8_get_core_reg,
1638 .set = armv8_set_core_reg,
1639 };
1640
1641 static int armv8_get_core_reg32(struct reg *reg)
1642 {
1643 struct arm_reg *armv8_reg = reg->arch_info;
1644 struct target *target = armv8_reg->target;
1645 struct arm *arm = target_to_arm(target);
1646 struct reg_cache *cache = arm->core_cache;
1647 struct reg *reg64;
1648 int retval;
1649
1650 if (target->state != TARGET_HALTED)
1651 return ERROR_TARGET_NOT_HALTED;
1652
1653 /* get the corresponding Aarch64 register */
1654 reg64 = cache->reg_list + armv8_reg->num;
1655 if (reg64->valid) {
1656 reg->valid = true;
1657 return ERROR_OK;
1658 }
1659
1660 retval = arm->read_core_reg(target, reg64, armv8_reg->num, arm->core_mode);
1661 if (retval == ERROR_OK)
1662 reg->valid = reg64->valid;
1663
1664 return retval;
1665 }
1666
1667 static int armv8_set_core_reg32(struct reg *reg, uint8_t *buf)
1668 {
1669 struct arm_reg *armv8_reg = reg->arch_info;
1670 struct target *target = armv8_reg->target;
1671 struct arm *arm = target_to_arm(target);
1672 struct reg_cache *cache = arm->core_cache;
1673 struct reg *reg64 = cache->reg_list + armv8_reg->num;
1674 uint32_t value = buf_get_u32(buf, 0, 32);
1675
1676 if (target->state != TARGET_HALTED)
1677 return ERROR_TARGET_NOT_HALTED;
1678
1679 if (reg64 == arm->cpsr) {
1680 armv8_set_cpsr(arm, value);
1681 } else {
1682 if (reg->size <= 32)
1683 buf_set_u32(reg->value, 0, 32, value);
1684 else if (reg->size <= 64) {
1685 uint64_t value64 = buf_get_u64(buf, 0, 64);
1686 buf_set_u64(reg->value, 0, 64, value64);
1687 }
1688 reg->valid = true;
1689 reg64->valid = true;
1690 }
1691
1692 reg64->dirty = true;
1693
1694 return ERROR_OK;
1695 }
1696
1697 static const struct reg_arch_type armv8_reg32_type = {
1698 .get = armv8_get_core_reg32,
1699 .set = armv8_set_core_reg32,
1700 };
1701
1702 /** Builds cache of architecturally defined registers. */
1703 struct reg_cache *armv8_build_reg_cache(struct target *target)
1704 {
1705 struct armv8_common *armv8 = target_to_armv8(target);
1706 struct arm *arm = &armv8->arm;
1707 int num_regs = ARMV8_NUM_REGS;
1708 int num_regs32 = ARMV8_NUM_REGS32;
1709 struct reg_cache **cache_p = register_get_last_cache_p(&target->reg_cache);
1710 struct reg_cache *cache = malloc(sizeof(struct reg_cache));
1711 struct reg_cache *cache32 = malloc(sizeof(struct reg_cache));
1712 struct reg *reg_list = calloc(num_regs, sizeof(struct reg));
1713 struct reg *reg_list32 = calloc(num_regs32, sizeof(struct reg));
1714 struct arm_reg *arch_info = calloc(num_regs, sizeof(struct arm_reg));
1715 struct reg_feature *feature;
1716 int i;
1717
1718 /* Build the process context cache */
1719 cache->name = "Aarch64 registers";
1720 cache->next = cache32;
1721 cache->reg_list = reg_list;
1722 cache->num_regs = num_regs;
1723
1724 for (i = 0; i < num_regs; i++) {
1725 arch_info[i].num = armv8_regs[i].id;
1726 arch_info[i].mode = armv8_regs[i].mode;
1727 arch_info[i].target = target;
1728 arch_info[i].arm = arm;
1729
1730 reg_list[i].name = armv8_regs[i].name;
1731 reg_list[i].size = armv8_regs[i].bits;
1732 reg_list[i].value = &arch_info[i].value[0];
1733 reg_list[i].type = &armv8_reg_type;
1734 reg_list[i].arch_info = &arch_info[i];
1735
1736 reg_list[i].group = armv8_regs[i].group;
1737 reg_list[i].number = i;
1738 reg_list[i].exist = true;
1739 reg_list[i].caller_save = true; /* gdb defaults to true */
1740
1741 feature = calloc(1, sizeof(struct reg_feature));
1742 if (feature) {
1743 feature->name = armv8_regs[i].feature;
1744 reg_list[i].feature = feature;
1745 } else
1746 LOG_ERROR("unable to allocate feature list");
1747
1748 reg_list[i].reg_data_type = calloc(1, sizeof(struct reg_data_type));
1749 if (reg_list[i].reg_data_type) {
1750 if (!armv8_regs[i].data_type)
1751 reg_list[i].reg_data_type->type = armv8_regs[i].type;
1752 else
1753 *reg_list[i].reg_data_type = *armv8_regs[i].data_type;
1754 } else
1755 LOG_ERROR("unable to allocate reg type list");
1756
1757 if (i == ARMV8_PAUTH_CMASK || i == ARMV8_PAUTH_DMASK)
1758 reg_list[i].exist = armv8->enable_pauth;
1759 }
1760
1761 arm->cpsr = reg_list + ARMV8_XPSR;
1762 arm->pc = reg_list + ARMV8_PC;
1763 arm->core_cache = cache;
1764
1765 /* shadow cache for ARM mode registers */
1766 cache32->name = "Aarch32 registers";
1767 cache32->next = NULL;
1768 cache32->reg_list = reg_list32;
1769 cache32->num_regs = num_regs32;
1770
1771 for (i = 0; i < num_regs32; i++) {
1772 reg_list32[i].name = armv8_regs32[i].name;
1773 reg_list32[i].size = armv8_regs32[i].bits;
1774 reg_list32[i].value = &arch_info[armv8_regs32[i].id].value[armv8_regs32[i].mapping];
1775 reg_list32[i].type = &armv8_reg32_type;
1776 reg_list32[i].arch_info = &arch_info[armv8_regs32[i].id];
1777 reg_list32[i].group = armv8_regs32[i].group;
1778 reg_list32[i].number = i;
1779 reg_list32[i].exist = true;
1780 reg_list32[i].caller_save = true;
1781
1782 feature = calloc(1, sizeof(struct reg_feature));
1783 if (feature) {
1784 feature->name = armv8_regs32[i].feature;
1785 reg_list32[i].feature = feature;
1786 } else
1787 LOG_ERROR("unable to allocate feature list");
1788
1789 reg_list32[i].reg_data_type = calloc(1, sizeof(struct reg_data_type));
1790 if (reg_list32[i].reg_data_type)
1791 reg_list32[i].reg_data_type->type = armv8_regs32[i].type;
1792 else
1793 LOG_ERROR("unable to allocate reg type list");
1794 }
1795
1796 (*cache_p) = cache;
1797 return cache;
1798 }
1799
1800 struct reg *armv8_reg_current(struct arm *arm, unsigned regnum)
1801 {
1802 struct reg *r;
1803
1804 if (regnum > (ARMV8_LAST_REG - 1))
1805 return NULL;
1806
1807 r = arm->core_cache->reg_list + regnum;
1808 return r;
1809 }
1810
1811 static void armv8_free_cache(struct reg_cache *cache, bool regs32)
1812 {
1813 struct reg *reg;
1814 unsigned int i;
1815
1816 if (!cache)
1817 return;
1818
1819 for (i = 0; i < cache->num_regs; i++) {
1820 reg = &cache->reg_list[i];
1821
1822 free(reg->feature);
1823 free(reg->reg_data_type);
1824 }
1825
1826 if (!regs32)
1827 free(cache->reg_list[0].arch_info);
1828 free(cache->reg_list);
1829 free(cache);
1830 }
1831
1832 void armv8_free_reg_cache(struct target *target)
1833 {
1834 struct armv8_common *armv8 = target_to_armv8(target);
1835 struct arm *arm = &armv8->arm;
1836 struct reg_cache *cache = NULL, *cache32 = NULL;
1837
1838 cache = arm->core_cache;
1839 if (cache)
1840 cache32 = cache->next;
1841 armv8_free_cache(cache32, true);
1842 armv8_free_cache(cache, false);
1843 arm->core_cache = NULL;
1844 }
1845
1846 const struct command_registration armv8_command_handlers[] = {
1847 {
1848 .name = "catch_exc",
1849 .handler = armv8_handle_exception_catch_command,
1850 .mode = COMMAND_EXEC,
1851 .help = "configure exception catch",
1852 .usage = "[(nsec_el1,nsec_el2,sec_el1,sec_el3)+,off]",
1853 },
1854 {
1855 .name = "pauth",
1856 .handler = armv8_pauth_command,
1857 .mode = COMMAND_CONFIG,
1858 .help = "enable or disable providing GDB with an 8-bytes mask to "
1859 "remove signature bits added by pointer authentication."
1860 "Pointer authentication feature is broken until gdb 12.1, going to be fixed. "
1861 "Consider using a newer version of gdb if you want enable "
1862 "pauth feature.",
1863 .usage = "[on|off]",
1864 },
1865 COMMAND_REGISTRATION_DONE
1866 };
1867
1868 const char *armv8_get_gdb_arch(const struct target *target)
1869 {
1870 struct arm *arm = target_to_arm(target);
1871 return arm->core_state == ARM_STATE_AARCH64 ? "aarch64" : "arm";
1872 }
1873
1874 int armv8_get_gdb_reg_list(struct target *target,
1875 struct reg **reg_list[], int *reg_list_size,
1876 enum target_register_class reg_class)
1877 {
1878 struct arm *arm = target_to_arm(target);
1879 int i;
1880
1881 if (arm->core_state == ARM_STATE_AARCH64) {
1882
1883 LOG_DEBUG("Creating Aarch64 register list for target %s", target_name(target));
1884
1885 switch (reg_class) {
1886 case REG_CLASS_GENERAL:
1887 *reg_list_size = ARMV8_V0;
1888 *reg_list = malloc(sizeof(struct reg *) * (*reg_list_size));
1889
1890 for (i = 0; i < *reg_list_size; i++)
1891 (*reg_list)[i] = armv8_reg_current(arm, i);
1892 return ERROR_OK;
1893
1894 case REG_CLASS_ALL:
1895 *reg_list_size = ARMV8_LAST_REG;
1896 *reg_list = malloc(sizeof(struct reg *) * (*reg_list_size));
1897
1898 for (i = 0; i < *reg_list_size; i++)
1899 (*reg_list)[i] = armv8_reg_current(arm, i);
1900
1901 return ERROR_OK;
1902
1903 default:
1904 LOG_ERROR("not a valid register class type in query.");
1905 return ERROR_FAIL;
1906 }
1907 } else {
1908 struct reg_cache *cache32 = arm->core_cache->next;
1909
1910 LOG_DEBUG("Creating Aarch32 register list for target %s", target_name(target));
1911
1912 switch (reg_class) {
1913 case REG_CLASS_GENERAL:
1914 *reg_list_size = ARMV8_R14 + 3;
1915 *reg_list = malloc(sizeof(struct reg *) * (*reg_list_size));
1916
1917 for (i = 0; i < *reg_list_size; i++)
1918 (*reg_list)[i] = cache32->reg_list + i;
1919
1920 return ERROR_OK;
1921 case REG_CLASS_ALL:
1922 *reg_list_size = cache32->num_regs;
1923 *reg_list = malloc(sizeof(struct reg *) * (*reg_list_size));
1924
1925 for (i = 0; i < *reg_list_size; i++)
1926 (*reg_list)[i] = cache32->reg_list + i;
1927
1928 return ERROR_OK;
1929 default:
1930 LOG_ERROR("not a valid register class type in query.");
1931 return ERROR_FAIL;
1932 }
1933 }
1934 }
1935
1936 int armv8_set_dbgreg_bits(struct armv8_common *armv8, unsigned int reg, unsigned long mask, unsigned long value)
1937 {
1938 uint32_t tmp;
1939
1940 /* Read register */
1941 int retval = mem_ap_read_atomic_u32(armv8->debug_ap,
1942 armv8->debug_base + reg, &tmp);
1943 if (retval != ERROR_OK)
1944 return retval;
1945
1946 /* clear bitfield */
1947 tmp &= ~mask;
1948 /* put new value */
1949 tmp |= value & mask;
1950
1951 /* write new value */
1952 retval = mem_ap_write_atomic_u32(armv8->debug_ap,
1953 armv8->debug_base + reg, tmp);
1954 return retval;
1955 }

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)