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

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)