openocd: trivial replace of jim-nvp with new nvp
[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 /* V8 method VA TO PA */
947 int armv8_mmu_translate_va_pa(struct target *target, target_addr_t va,
948 target_addr_t *val, int meminfo)
949 {
950 struct armv8_common *armv8 = target_to_armv8(target);
951 struct arm *arm = target_to_arm(target);
952 struct arm_dpm *dpm = &armv8->dpm;
953 enum arm_mode target_mode = ARM_MODE_ANY;
954 uint32_t retval;
955 uint32_t instr = 0;
956 uint64_t par;
957
958 static const char * const shared_name[] = {
959 "Non-", "UNDEFINED ", "Outer ", "Inner "
960 };
961
962 static const char * const secure_name[] = {
963 "Secure", "Not Secure"
964 };
965
966 if (target->state != TARGET_HALTED) {
967 LOG_WARNING("target %s not halted", target_name(target));
968 return ERROR_TARGET_NOT_HALTED;
969 }
970
971 retval = dpm->prepare(dpm);
972 if (retval != ERROR_OK)
973 return retval;
974
975 switch (armv8_curel_from_core_mode(arm->core_mode)) {
976 case SYSTEM_CUREL_EL0:
977 instr = ARMV8_SYS(SYSTEM_ATS12E0R, 0);
978 /* can only execute instruction at EL2 */
979 target_mode = ARMV8_64_EL2H;
980 break;
981 case SYSTEM_CUREL_EL1:
982 instr = ARMV8_SYS(SYSTEM_ATS12E1R, 0);
983 /* can only execute instruction at EL2 */
984 target_mode = ARMV8_64_EL2H;
985 break;
986 case SYSTEM_CUREL_EL2:
987 instr = ARMV8_SYS(SYSTEM_ATS1E2R, 0);
988 break;
989 case SYSTEM_CUREL_EL3:
990 instr = ARMV8_SYS(SYSTEM_ATS1E3R, 0);
991 break;
992
993 default:
994 break;
995 };
996
997 if (target_mode != ARM_MODE_ANY)
998 armv8_dpm_modeswitch(dpm, target_mode);
999
1000 /* write VA to R0 and execute translation instruction */
1001 retval = dpm->instr_write_data_r0_64(dpm, instr, (uint64_t)va);
1002 /* read result from PAR_EL1 */
1003 if (retval == ERROR_OK)
1004 retval = dpm->instr_read_data_r0_64(dpm, ARMV8_MRS(SYSTEM_PAR_EL1, 0), &par);
1005
1006 /* switch back to saved PE mode */
1007 if (target_mode != ARM_MODE_ANY)
1008 armv8_dpm_modeswitch(dpm, ARM_MODE_ANY);
1009
1010 dpm->finish(dpm);
1011
1012 if (retval != ERROR_OK)
1013 return retval;
1014
1015 if (par & 1) {
1016 LOG_ERROR("Address translation failed at stage %i, FST=%x, PTW=%i",
1017 ((int)(par >> 9) & 1)+1, (int)(par >> 1) & 0x3f, (int)(par >> 8) & 1);
1018
1019 *val = 0;
1020 retval = ERROR_FAIL;
1021 } else {
1022 *val = (par & 0xFFFFFFFFF000UL) | (va & 0xFFF);
1023 if (meminfo) {
1024 int SH = (par >> 7) & 3;
1025 int NS = (par >> 9) & 1;
1026 int ATTR = (par >> 56) & 0xFF;
1027
1028 char *memtype = (ATTR & 0xF0) == 0 ? "Device Memory" : "Normal Memory";
1029
1030 LOG_USER("%sshareable, %s",
1031 shared_name[SH], secure_name[NS]);
1032 LOG_USER("%s", memtype);
1033 }
1034 }
1035
1036 return retval;
1037 }
1038
1039 COMMAND_HANDLER(armv8_handle_exception_catch_command)
1040 {
1041 struct target *target = get_current_target(CMD_CTX);
1042 struct armv8_common *armv8 = target_to_armv8(target);
1043 uint32_t edeccr = 0;
1044 unsigned int argp = 0;
1045 int retval;
1046
1047 static const struct nvp nvp_ecatch_modes[] = {
1048 { .name = "off", .value = 0 },
1049 { .name = "nsec_el1", .value = (1 << 5) },
1050 { .name = "nsec_el2", .value = (2 << 5) },
1051 { .name = "nsec_el12", .value = (3 << 5) },
1052 { .name = "sec_el1", .value = (1 << 1) },
1053 { .name = "sec_el3", .value = (4 << 1) },
1054 { .name = "sec_el13", .value = (5 << 1) },
1055 { .name = NULL, .value = -1 },
1056 };
1057 const struct nvp *n;
1058
1059 if (CMD_ARGC == 0) {
1060 const char *sec = NULL, *nsec = NULL;
1061
1062 retval = mem_ap_read_atomic_u32(armv8->debug_ap,
1063 armv8->debug_base + CPUV8_DBG_ECCR, &edeccr);
1064 if (retval != ERROR_OK)
1065 return retval;
1066
1067 n = nvp_value2name(nvp_ecatch_modes, edeccr & 0x0f);
1068 if (n->name)
1069 sec = n->name;
1070
1071 n = nvp_value2name(nvp_ecatch_modes, edeccr & 0xf0);
1072 if (n->name)
1073 nsec = n->name;
1074
1075 if (!sec || !nsec) {
1076 LOG_WARNING("Exception Catch: unknown exception catch configuration: EDECCR = %02" PRIx32, edeccr & 0xff);
1077 return ERROR_FAIL;
1078 }
1079
1080 command_print(CMD, "Exception Catch: Secure: %s, Non-Secure: %s", sec, nsec);
1081 return ERROR_OK;
1082 }
1083
1084 while (argp < CMD_ARGC) {
1085 n = nvp_name2value(nvp_ecatch_modes, CMD_ARGV[argp]);
1086 if (!n->name) {
1087 LOG_ERROR("Unknown option: %s", CMD_ARGV[argp]);
1088 return ERROR_FAIL;
1089 }
1090
1091 LOG_DEBUG("found: %s", n->name);
1092
1093 edeccr |= n->value;
1094 argp++;
1095 }
1096
1097 retval = mem_ap_write_atomic_u32(armv8->debug_ap,
1098 armv8->debug_base + CPUV8_DBG_ECCR, edeccr);
1099 if (retval != ERROR_OK)
1100 return retval;
1101
1102 return ERROR_OK;
1103 }
1104
1105 COMMAND_HANDLER(armv8_pauth_command)
1106 {
1107 struct target *target = get_current_target(CMD_CTX);
1108 struct armv8_common *armv8 = target_to_armv8(target);
1109 return CALL_COMMAND_HANDLER(handle_command_parse_bool,
1110 &armv8->enable_pauth,
1111 "pauth feature");
1112 }
1113
1114 int armv8_handle_cache_info_command(struct command_invocation *cmd,
1115 struct armv8_cache_common *armv8_cache)
1116 {
1117 if (armv8_cache->info == -1) {
1118 command_print(cmd, "cache not yet identified");
1119 return ERROR_OK;
1120 }
1121
1122 if (armv8_cache->display_cache_info)
1123 armv8_cache->display_cache_info(cmd, armv8_cache);
1124 return ERROR_OK;
1125 }
1126
1127 static int armv8_setup_semihosting(struct target *target, int enable)
1128 {
1129 return ERROR_OK;
1130 }
1131
1132 int armv8_init_arch_info(struct target *target, struct armv8_common *armv8)
1133 {
1134 struct arm *arm = &armv8->arm;
1135 arm->arch_info = armv8;
1136 target->arch_info = &armv8->arm;
1137 arm->setup_semihosting = armv8_setup_semihosting;
1138 /* target is useful in all function arm v4 5 compatible */
1139 armv8->arm.target = target;
1140 armv8->arm.common_magic = ARM_COMMON_MAGIC;
1141 armv8->common_magic = ARMV8_COMMON_MAGIC;
1142
1143 armv8->armv8_mmu.armv8_cache.l2_cache = NULL;
1144 armv8->armv8_mmu.armv8_cache.info = -1;
1145 armv8->armv8_mmu.armv8_cache.flush_all_data_cache = NULL;
1146 armv8->armv8_mmu.armv8_cache.display_cache_info = NULL;
1147 return ERROR_OK;
1148 }
1149
1150 static int armv8_aarch64_state(struct target *target)
1151 {
1152 struct arm *arm = target_to_arm(target);
1153
1154 if (arm->common_magic != ARM_COMMON_MAGIC) {
1155 LOG_ERROR("BUG: called for a non-ARM target");
1156 return ERROR_FAIL;
1157 }
1158
1159 LOG_USER("%s halted in %s state due to %s, current mode: %s\n"
1160 "cpsr: 0x%8.8" PRIx32 " pc: 0x%" PRIx64 "%s",
1161 target_name(target),
1162 armv8_state_strings[arm->core_state],
1163 debug_reason_name(target),
1164 armv8_mode_name(arm->core_mode),
1165 buf_get_u32(arm->cpsr->value, 0, 32),
1166 buf_get_u64(arm->pc->value, 0, 64),
1167 (target->semihosting && target->semihosting->is_active) ? ", semihosting" : "");
1168
1169 return ERROR_OK;
1170 }
1171
1172 int armv8_arch_state(struct target *target)
1173 {
1174 static const char * const state[] = {
1175 "disabled", "enabled"
1176 };
1177
1178 struct armv8_common *armv8 = target_to_armv8(target);
1179 struct arm *arm = &armv8->arm;
1180
1181 if (armv8->common_magic != ARMV8_COMMON_MAGIC) {
1182 LOG_ERROR("BUG: called for a non-Armv8 target");
1183 return ERROR_COMMAND_SYNTAX_ERROR;
1184 }
1185
1186 if (arm->core_state == ARM_STATE_AARCH64)
1187 armv8_aarch64_state(target);
1188 else
1189 arm_arch_state(target);
1190
1191 LOG_USER("MMU: %s, D-Cache: %s, I-Cache: %s",
1192 state[armv8->armv8_mmu.mmu_enabled],
1193 state[armv8->armv8_mmu.armv8_cache.d_u_cache_enabled],
1194 state[armv8->armv8_mmu.armv8_cache.i_cache_enabled]);
1195
1196 if (arm->core_mode == ARM_MODE_ABT)
1197 armv8_show_fault_registers(target);
1198
1199 if (target->debug_reason == DBG_REASON_WATCHPOINT)
1200 LOG_USER("Watchpoint triggered at " TARGET_ADDR_FMT, armv8->dpm.wp_addr);
1201
1202 return ERROR_OK;
1203 }
1204
1205 static struct reg_data_type aarch64_vector_base_types[] = {
1206 {REG_TYPE_IEEE_DOUBLE, "ieee_double", 0, {NULL} },
1207 {REG_TYPE_UINT64, "uint64", 0, {NULL} },
1208 {REG_TYPE_INT64, "int64", 0, {NULL} },
1209 {REG_TYPE_IEEE_SINGLE, "ieee_single", 0, {NULL} },
1210 {REG_TYPE_UINT32, "uint32", 0, {NULL} },
1211 {REG_TYPE_INT32, "int32", 0, {NULL} },
1212 {REG_TYPE_UINT16, "uint16", 0, {NULL} },
1213 {REG_TYPE_INT16, "int16", 0, {NULL} },
1214 {REG_TYPE_UINT8, "uint8", 0, {NULL} },
1215 {REG_TYPE_INT8, "int8", 0, {NULL} },
1216 {REG_TYPE_UINT128, "uint128", 0, {NULL} },
1217 {REG_TYPE_INT128, "int128", 0, {NULL} }
1218 };
1219
1220 static struct reg_data_type_vector aarch64_vector_types[] = {
1221 {aarch64_vector_base_types + 0, 2},
1222 {aarch64_vector_base_types + 1, 2},
1223 {aarch64_vector_base_types + 2, 2},
1224 {aarch64_vector_base_types + 3, 4},
1225 {aarch64_vector_base_types + 4, 4},
1226 {aarch64_vector_base_types + 5, 4},
1227 {aarch64_vector_base_types + 6, 8},
1228 {aarch64_vector_base_types + 7, 8},
1229 {aarch64_vector_base_types + 8, 16},
1230 {aarch64_vector_base_types + 9, 16},
1231 {aarch64_vector_base_types + 10, 01},
1232 {aarch64_vector_base_types + 11, 01},
1233 };
1234
1235 static struct reg_data_type aarch64_fpu_vector[] = {
1236 {REG_TYPE_ARCH_DEFINED, "v2d", REG_TYPE_CLASS_VECTOR, {aarch64_vector_types + 0} },
1237 {REG_TYPE_ARCH_DEFINED, "v2u", REG_TYPE_CLASS_VECTOR, {aarch64_vector_types + 1} },
1238 {REG_TYPE_ARCH_DEFINED, "v2i", REG_TYPE_CLASS_VECTOR, {aarch64_vector_types + 2} },
1239 {REG_TYPE_ARCH_DEFINED, "v4f", REG_TYPE_CLASS_VECTOR, {aarch64_vector_types + 3} },
1240 {REG_TYPE_ARCH_DEFINED, "v4u", REG_TYPE_CLASS_VECTOR, {aarch64_vector_types + 4} },
1241 {REG_TYPE_ARCH_DEFINED, "v4i", REG_TYPE_CLASS_VECTOR, {aarch64_vector_types + 5} },
1242 {REG_TYPE_ARCH_DEFINED, "v8u", REG_TYPE_CLASS_VECTOR, {aarch64_vector_types + 6} },
1243 {REG_TYPE_ARCH_DEFINED, "v8i", REG_TYPE_CLASS_VECTOR, {aarch64_vector_types + 7} },
1244 {REG_TYPE_ARCH_DEFINED, "v16u", REG_TYPE_CLASS_VECTOR, {aarch64_vector_types + 8} },
1245 {REG_TYPE_ARCH_DEFINED, "v16i", REG_TYPE_CLASS_VECTOR, {aarch64_vector_types + 9} },
1246 {REG_TYPE_ARCH_DEFINED, "v1u", REG_TYPE_CLASS_VECTOR, {aarch64_vector_types + 10} },
1247 {REG_TYPE_ARCH_DEFINED, "v1i", REG_TYPE_CLASS_VECTOR, {aarch64_vector_types + 11} },
1248 };
1249
1250 static struct reg_data_type_union_field aarch64_union_fields_vnd[] = {
1251 {"f", aarch64_fpu_vector + 0, aarch64_union_fields_vnd + 1},
1252 {"u", aarch64_fpu_vector + 1, aarch64_union_fields_vnd + 2},
1253 {"s", aarch64_fpu_vector + 2, NULL},
1254 };
1255
1256 static struct reg_data_type_union_field aarch64_union_fields_vns[] = {
1257 {"f", aarch64_fpu_vector + 3, aarch64_union_fields_vns + 1},
1258 {"u", aarch64_fpu_vector + 4, aarch64_union_fields_vns + 2},
1259 {"s", aarch64_fpu_vector + 5, NULL},
1260 };
1261
1262 static struct reg_data_type_union_field aarch64_union_fields_vnh[] = {
1263 {"u", aarch64_fpu_vector + 6, aarch64_union_fields_vnh + 1},
1264 {"s", aarch64_fpu_vector + 7, NULL},
1265 };
1266
1267 static struct reg_data_type_union_field aarch64_union_fields_vnb[] = {
1268 {"u", aarch64_fpu_vector + 8, aarch64_union_fields_vnb + 1},
1269 {"s", aarch64_fpu_vector + 9, NULL},
1270 };
1271
1272 static struct reg_data_type_union_field aarch64_union_fields_vnq[] = {
1273 {"u", aarch64_fpu_vector + 10, aarch64_union_fields_vnq + 1},
1274 {"s", aarch64_fpu_vector + 11, NULL},
1275 };
1276
1277 static struct reg_data_type_union aarch64_union_types[] = {
1278 {aarch64_union_fields_vnd},
1279 {aarch64_union_fields_vns},
1280 {aarch64_union_fields_vnh},
1281 {aarch64_union_fields_vnb},
1282 {aarch64_union_fields_vnq},
1283 };
1284
1285 static struct reg_data_type aarch64_fpu_union[] = {
1286 {REG_TYPE_ARCH_DEFINED, "vnd", REG_TYPE_CLASS_UNION, {.reg_type_union = aarch64_union_types + 0} },
1287 {REG_TYPE_ARCH_DEFINED, "vns", REG_TYPE_CLASS_UNION, {.reg_type_union = aarch64_union_types + 1} },
1288 {REG_TYPE_ARCH_DEFINED, "vnh", REG_TYPE_CLASS_UNION, {.reg_type_union = aarch64_union_types + 2} },
1289 {REG_TYPE_ARCH_DEFINED, "vnb", REG_TYPE_CLASS_UNION, {.reg_type_union = aarch64_union_types + 3} },
1290 {REG_TYPE_ARCH_DEFINED, "vnq", REG_TYPE_CLASS_UNION, {.reg_type_union = aarch64_union_types + 4} },
1291 };
1292
1293 static struct reg_data_type_union_field aarch64v_union_fields[] = {
1294 {"d", aarch64_fpu_union + 0, aarch64v_union_fields + 1},
1295 {"s", aarch64_fpu_union + 1, aarch64v_union_fields + 2},
1296 {"h", aarch64_fpu_union + 2, aarch64v_union_fields + 3},
1297 {"b", aarch64_fpu_union + 3, aarch64v_union_fields + 4},
1298 {"q", aarch64_fpu_union + 4, NULL},
1299 };
1300
1301 static struct reg_data_type_union aarch64v_union[] = {
1302 {aarch64v_union_fields}
1303 };
1304
1305 static struct reg_data_type aarch64v[] = {
1306 {REG_TYPE_ARCH_DEFINED, "aarch64v", REG_TYPE_CLASS_UNION,
1307 {.reg_type_union = aarch64v_union} },
1308 };
1309
1310 static struct reg_data_type_bitfield aarch64_cpsr_bits[] = {
1311 { 0, 0, REG_TYPE_UINT8 },
1312 { 2, 3, REG_TYPE_UINT8 },
1313 { 4, 4, REG_TYPE_UINT8 },
1314 { 6, 6, REG_TYPE_BOOL },
1315 { 7, 7, REG_TYPE_BOOL },
1316 { 8, 8, REG_TYPE_BOOL },
1317 { 9, 9, REG_TYPE_BOOL },
1318 { 20, 20, REG_TYPE_BOOL },
1319 { 21, 21, REG_TYPE_BOOL },
1320 { 28, 28, REG_TYPE_BOOL },
1321 { 29, 29, REG_TYPE_BOOL },
1322 { 30, 30, REG_TYPE_BOOL },
1323 { 31, 31, REG_TYPE_BOOL },
1324 };
1325
1326 static struct reg_data_type_flags_field aarch64_cpsr_fields[] = {
1327 { "SP", aarch64_cpsr_bits + 0, aarch64_cpsr_fields + 1 },
1328 { "EL", aarch64_cpsr_bits + 1, aarch64_cpsr_fields + 2 },
1329 { "nRW", aarch64_cpsr_bits + 2, aarch64_cpsr_fields + 3 },
1330 { "F", aarch64_cpsr_bits + 3, aarch64_cpsr_fields + 4 },
1331 { "I", aarch64_cpsr_bits + 4, aarch64_cpsr_fields + 5 },
1332 { "A", aarch64_cpsr_bits + 5, aarch64_cpsr_fields + 6 },
1333 { "D", aarch64_cpsr_bits + 6, aarch64_cpsr_fields + 7 },
1334 { "IL", aarch64_cpsr_bits + 7, aarch64_cpsr_fields + 8 },
1335 { "SS", aarch64_cpsr_bits + 8, aarch64_cpsr_fields + 9 },
1336 { "V", aarch64_cpsr_bits + 9, aarch64_cpsr_fields + 10 },
1337 { "C", aarch64_cpsr_bits + 10, aarch64_cpsr_fields + 11 },
1338 { "Z", aarch64_cpsr_bits + 11, aarch64_cpsr_fields + 12 },
1339 { "N", aarch64_cpsr_bits + 12, NULL }
1340 };
1341
1342 static struct reg_data_type_flags aarch64_cpsr_flags[] = {
1343 { 4, aarch64_cpsr_fields }
1344 };
1345
1346 static struct reg_data_type aarch64_flags_cpsr[] = {
1347 {REG_TYPE_ARCH_DEFINED, "cpsr_flags", REG_TYPE_CLASS_FLAGS,
1348 {.reg_type_flags = aarch64_cpsr_flags} },
1349 };
1350
1351 static const struct {
1352 unsigned id;
1353 const char *name;
1354 unsigned bits;
1355 enum arm_mode mode;
1356 enum reg_type type;
1357 const char *group;
1358 const char *feature;
1359 struct reg_data_type *data_type;
1360 } armv8_regs[] = {
1361 { ARMV8_R0, "x0", 64, ARM_MODE_ANY, REG_TYPE_UINT64, "general", "org.gnu.gdb.aarch64.core", NULL},
1362 { ARMV8_R1, "x1", 64, ARM_MODE_ANY, REG_TYPE_UINT64, "general", "org.gnu.gdb.aarch64.core", NULL},
1363 { ARMV8_R2, "x2", 64, ARM_MODE_ANY, REG_TYPE_UINT64, "general", "org.gnu.gdb.aarch64.core", NULL},
1364 { ARMV8_R3, "x3", 64, ARM_MODE_ANY, REG_TYPE_UINT64, "general", "org.gnu.gdb.aarch64.core", NULL},
1365 { ARMV8_R4, "x4", 64, ARM_MODE_ANY, REG_TYPE_UINT64, "general", "org.gnu.gdb.aarch64.core", NULL},
1366 { ARMV8_R5, "x5", 64, ARM_MODE_ANY, REG_TYPE_UINT64, "general", "org.gnu.gdb.aarch64.core", NULL},
1367 { ARMV8_R6, "x6", 64, ARM_MODE_ANY, REG_TYPE_UINT64, "general", "org.gnu.gdb.aarch64.core", NULL},
1368 { ARMV8_R7, "x7", 64, ARM_MODE_ANY, REG_TYPE_UINT64, "general", "org.gnu.gdb.aarch64.core", NULL},
1369 { ARMV8_R8, "x8", 64, ARM_MODE_ANY, REG_TYPE_UINT64, "general", "org.gnu.gdb.aarch64.core", NULL},
1370 { ARMV8_R9, "x9", 64, ARM_MODE_ANY, REG_TYPE_UINT64, "general", "org.gnu.gdb.aarch64.core", NULL},
1371 { ARMV8_R10, "x10", 64, ARM_MODE_ANY, REG_TYPE_UINT64, "general", "org.gnu.gdb.aarch64.core", NULL},
1372 { ARMV8_R11, "x11", 64, ARM_MODE_ANY, REG_TYPE_UINT64, "general", "org.gnu.gdb.aarch64.core", NULL},
1373 { ARMV8_R12, "x12", 64, ARM_MODE_ANY, REG_TYPE_UINT64, "general", "org.gnu.gdb.aarch64.core", NULL},
1374 { ARMV8_R13, "x13", 64, ARM_MODE_ANY, REG_TYPE_UINT64, "general", "org.gnu.gdb.aarch64.core", NULL},
1375 { ARMV8_R14, "x14", 64, ARM_MODE_ANY, REG_TYPE_UINT64, "general", "org.gnu.gdb.aarch64.core", NULL},
1376 { ARMV8_R15, "x15", 64, ARM_MODE_ANY, REG_TYPE_UINT64, "general", "org.gnu.gdb.aarch64.core", NULL},
1377 { ARMV8_R16, "x16", 64, ARM_MODE_ANY, REG_TYPE_UINT64, "general", "org.gnu.gdb.aarch64.core", NULL},
1378 { ARMV8_R17, "x17", 64, ARM_MODE_ANY, REG_TYPE_UINT64, "general", "org.gnu.gdb.aarch64.core", NULL},
1379 { ARMV8_R18, "x18", 64, ARM_MODE_ANY, REG_TYPE_UINT64, "general", "org.gnu.gdb.aarch64.core", NULL},
1380 { ARMV8_R19, "x19", 64, ARM_MODE_ANY, REG_TYPE_UINT64, "general", "org.gnu.gdb.aarch64.core", NULL},
1381 { ARMV8_R20, "x20", 64, ARM_MODE_ANY, REG_TYPE_UINT64, "general", "org.gnu.gdb.aarch64.core", NULL},
1382 { ARMV8_R21, "x21", 64, ARM_MODE_ANY, REG_TYPE_UINT64, "general", "org.gnu.gdb.aarch64.core", NULL},
1383 { ARMV8_R22, "x22", 64, ARM_MODE_ANY, REG_TYPE_UINT64, "general", "org.gnu.gdb.aarch64.core", NULL},
1384 { ARMV8_R23, "x23", 64, ARM_MODE_ANY, REG_TYPE_UINT64, "general", "org.gnu.gdb.aarch64.core", NULL},
1385 { ARMV8_R24, "x24", 64, ARM_MODE_ANY, REG_TYPE_UINT64, "general", "org.gnu.gdb.aarch64.core", NULL},
1386 { ARMV8_R25, "x25", 64, ARM_MODE_ANY, REG_TYPE_UINT64, "general", "org.gnu.gdb.aarch64.core", NULL},
1387 { ARMV8_R26, "x26", 64, ARM_MODE_ANY, REG_TYPE_UINT64, "general", "org.gnu.gdb.aarch64.core", NULL},
1388 { ARMV8_R27, "x27", 64, ARM_MODE_ANY, REG_TYPE_UINT64, "general", "org.gnu.gdb.aarch64.core", NULL},
1389 { ARMV8_R28, "x28", 64, ARM_MODE_ANY, REG_TYPE_UINT64, "general", "org.gnu.gdb.aarch64.core", NULL},
1390 { ARMV8_R29, "x29", 64, ARM_MODE_ANY, REG_TYPE_UINT64, "general", "org.gnu.gdb.aarch64.core", NULL},
1391 { ARMV8_R30, "x30", 64, ARM_MODE_ANY, REG_TYPE_UINT64, "general", "org.gnu.gdb.aarch64.core", NULL},
1392
1393 { ARMV8_SP, "sp", 64, ARM_MODE_ANY, REG_TYPE_DATA_PTR, "general", "org.gnu.gdb.aarch64.core", NULL},
1394 { ARMV8_PC, "pc", 64, ARM_MODE_ANY, REG_TYPE_CODE_PTR, "general", "org.gnu.gdb.aarch64.core", NULL},
1395 { ARMV8_XPSR, "cpsr", 32, ARM_MODE_ANY, REG_TYPE_ARCH_DEFINED,
1396 "general", "org.gnu.gdb.aarch64.core", aarch64_flags_cpsr},
1397 { ARMV8_V0, "v0", 128, ARM_MODE_ANY, REG_TYPE_ARCH_DEFINED, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v},
1398 { ARMV8_V1, "v1", 128, ARM_MODE_ANY, REG_TYPE_ARCH_DEFINED, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v},
1399 { ARMV8_V2, "v2", 128, ARM_MODE_ANY, REG_TYPE_ARCH_DEFINED, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v},
1400 { ARMV8_V3, "v3", 128, ARM_MODE_ANY, REG_TYPE_ARCH_DEFINED, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v},
1401 { ARMV8_V4, "v4", 128, ARM_MODE_ANY, REG_TYPE_ARCH_DEFINED, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v},
1402 { ARMV8_V5, "v5", 128, ARM_MODE_ANY, REG_TYPE_ARCH_DEFINED, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v},
1403 { ARMV8_V6, "v6", 128, ARM_MODE_ANY, REG_TYPE_ARCH_DEFINED, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v},
1404 { ARMV8_V7, "v7", 128, ARM_MODE_ANY, REG_TYPE_ARCH_DEFINED, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v},
1405 { ARMV8_V8, "v8", 128, ARM_MODE_ANY, REG_TYPE_ARCH_DEFINED, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v},
1406 { ARMV8_V9, "v9", 128, ARM_MODE_ANY, REG_TYPE_ARCH_DEFINED, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v},
1407 { ARMV8_V10, "v10", 128, ARM_MODE_ANY, REG_TYPE_ARCH_DEFINED, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v},
1408 { ARMV8_V11, "v11", 128, ARM_MODE_ANY, REG_TYPE_ARCH_DEFINED, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v},
1409 { ARMV8_V12, "v12", 128, ARM_MODE_ANY, REG_TYPE_ARCH_DEFINED, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v},
1410 { ARMV8_V13, "v13", 128, ARM_MODE_ANY, REG_TYPE_ARCH_DEFINED, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v},
1411 { ARMV8_V14, "v14", 128, ARM_MODE_ANY, REG_TYPE_ARCH_DEFINED, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v},
1412 { ARMV8_V15, "v15", 128, ARM_MODE_ANY, REG_TYPE_ARCH_DEFINED, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v},
1413 { ARMV8_V16, "v16", 128, ARM_MODE_ANY, REG_TYPE_ARCH_DEFINED, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v},
1414 { ARMV8_V17, "v17", 128, ARM_MODE_ANY, REG_TYPE_ARCH_DEFINED, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v},
1415 { ARMV8_V18, "v18", 128, ARM_MODE_ANY, REG_TYPE_ARCH_DEFINED, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v},
1416 { ARMV8_V19, "v19", 128, ARM_MODE_ANY, REG_TYPE_ARCH_DEFINED, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v},
1417 { ARMV8_V20, "v20", 128, ARM_MODE_ANY, REG_TYPE_ARCH_DEFINED, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v},
1418 { ARMV8_V21, "v21", 128, ARM_MODE_ANY, REG_TYPE_ARCH_DEFINED, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v},
1419 { ARMV8_V22, "v22", 128, ARM_MODE_ANY, REG_TYPE_ARCH_DEFINED, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v},
1420 { ARMV8_V23, "v23", 128, ARM_MODE_ANY, REG_TYPE_ARCH_DEFINED, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v},
1421 { ARMV8_V24, "v24", 128, ARM_MODE_ANY, REG_TYPE_ARCH_DEFINED, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v},
1422 { ARMV8_V25, "v25", 128, ARM_MODE_ANY, REG_TYPE_ARCH_DEFINED, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v},
1423 { ARMV8_V26, "v26", 128, ARM_MODE_ANY, REG_TYPE_ARCH_DEFINED, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v},
1424 { ARMV8_V27, "v27", 128, ARM_MODE_ANY, REG_TYPE_ARCH_DEFINED, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v},
1425 { ARMV8_V28, "v28", 128, ARM_MODE_ANY, REG_TYPE_ARCH_DEFINED, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v},
1426 { ARMV8_V29, "v29", 128, ARM_MODE_ANY, REG_TYPE_ARCH_DEFINED, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v},
1427 { ARMV8_V30, "v30", 128, ARM_MODE_ANY, REG_TYPE_ARCH_DEFINED, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v},
1428 { ARMV8_V31, "v31", 128, ARM_MODE_ANY, REG_TYPE_ARCH_DEFINED, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v},
1429 { ARMV8_FPSR, "fpsr", 32, ARM_MODE_ANY, REG_TYPE_UINT32, "simdfp", "org.gnu.gdb.aarch64.fpu", NULL},
1430 { ARMV8_FPCR, "fpcr", 32, ARM_MODE_ANY, REG_TYPE_UINT32, "simdfp", "org.gnu.gdb.aarch64.fpu", NULL},
1431
1432 { ARMV8_ELR_EL1, "ELR_EL1", 64, ARMV8_64_EL1H, REG_TYPE_CODE_PTR, "banked", "net.sourceforge.openocd.banked",
1433 NULL},
1434 { ARMV8_ESR_EL1, "ESR_EL1", 32, ARMV8_64_EL1H, REG_TYPE_UINT32, "banked", "net.sourceforge.openocd.banked",
1435 NULL},
1436 { ARMV8_SPSR_EL1, "SPSR_EL1", 32, ARMV8_64_EL1H, REG_TYPE_UINT32, "banked", "net.sourceforge.openocd.banked",
1437 NULL},
1438
1439 { ARMV8_ELR_EL2, "ELR_EL2", 64, ARMV8_64_EL2H, REG_TYPE_CODE_PTR, "banked", "net.sourceforge.openocd.banked",
1440 NULL},
1441 { ARMV8_ESR_EL2, "ESR_EL2", 32, ARMV8_64_EL2H, REG_TYPE_UINT32, "banked", "net.sourceforge.openocd.banked",
1442 NULL},
1443 { ARMV8_SPSR_EL2, "SPSR_EL2", 32, ARMV8_64_EL2H, REG_TYPE_UINT32, "banked", "net.sourceforge.openocd.banked",
1444 NULL},
1445
1446 { ARMV8_ELR_EL3, "ELR_EL3", 64, ARMV8_64_EL3H, REG_TYPE_CODE_PTR, "banked", "net.sourceforge.openocd.banked",
1447 NULL},
1448 { ARMV8_ESR_EL3, "ESR_EL3", 32, ARMV8_64_EL3H, REG_TYPE_UINT32, "banked", "net.sourceforge.openocd.banked",
1449 NULL},
1450 { ARMV8_SPSR_EL3, "SPSR_EL3", 32, ARMV8_64_EL3H, REG_TYPE_UINT32, "banked", "net.sourceforge.openocd.banked",
1451 NULL},
1452 { ARMV8_PAUTH_DMASK, "pauth_dmask", 64, ARM_MODE_ANY, REG_TYPE_UINT64, NULL, "org.gnu.gdb.aarch64.pauth", NULL},
1453 { ARMV8_PAUTH_CMASK, "pauth_cmask", 64, ARM_MODE_ANY, REG_TYPE_UINT64, NULL, "org.gnu.gdb.aarch64.pauth", NULL},
1454 };
1455
1456 static const struct {
1457 unsigned id;
1458 unsigned mapping;
1459 const char *name;
1460 unsigned bits;
1461 enum arm_mode mode;
1462 enum reg_type type;
1463 const char *group;
1464 const char *feature;
1465 } armv8_regs32[] = {
1466 { ARMV8_R0, 0, "r0", 32, ARM_MODE_ANY, REG_TYPE_UINT32, "general", "org.gnu.gdb.arm.core" },
1467 { ARMV8_R1, 0, "r1", 32, ARM_MODE_ANY, REG_TYPE_UINT32, "general", "org.gnu.gdb.arm.core" },
1468 { ARMV8_R2, 0, "r2", 32, ARM_MODE_ANY, REG_TYPE_UINT32, "general", "org.gnu.gdb.arm.core" },
1469 { ARMV8_R3, 0, "r3", 32, ARM_MODE_ANY, REG_TYPE_UINT32, "general", "org.gnu.gdb.arm.core" },
1470 { ARMV8_R4, 0, "r4", 32, ARM_MODE_ANY, REG_TYPE_UINT32, "general", "org.gnu.gdb.arm.core" },
1471 { ARMV8_R5, 0, "r5", 32, ARM_MODE_ANY, REG_TYPE_UINT32, "general", "org.gnu.gdb.arm.core" },
1472 { ARMV8_R6, 0, "r6", 32, ARM_MODE_ANY, REG_TYPE_UINT32, "general", "org.gnu.gdb.arm.core" },
1473 { ARMV8_R7, 0, "r7", 32, ARM_MODE_ANY, REG_TYPE_UINT32, "general", "org.gnu.gdb.arm.core" },
1474 { ARMV8_R8, 0, "r8", 32, ARM_MODE_ANY, REG_TYPE_UINT32, "general", "org.gnu.gdb.arm.core" },
1475 { ARMV8_R9, 0, "r9", 32, ARM_MODE_ANY, REG_TYPE_UINT32, "general", "org.gnu.gdb.arm.core" },
1476 { ARMV8_R10, 0, "r10", 32, ARM_MODE_ANY, REG_TYPE_UINT32, "general", "org.gnu.gdb.arm.core" },
1477 { ARMV8_R11, 0, "r11", 32, ARM_MODE_ANY, REG_TYPE_UINT32, "general", "org.gnu.gdb.arm.core" },
1478 { ARMV8_R12, 0, "r12", 32, ARM_MODE_ANY, REG_TYPE_UINT32, "general", "org.gnu.gdb.arm.core" },
1479 { ARMV8_R13, 0, "sp", 32, ARM_MODE_ANY, REG_TYPE_DATA_PTR, "general", "org.gnu.gdb.arm.core" },
1480 { ARMV8_R14, 0, "lr", 32, ARM_MODE_ANY, REG_TYPE_CODE_PTR, "general", "org.gnu.gdb.arm.core" },
1481 { ARMV8_PC, 0, "pc", 32, ARM_MODE_ANY, REG_TYPE_CODE_PTR, "general", "org.gnu.gdb.arm.core" },
1482 { ARMV8_XPSR, 0, "cpsr", 32, ARM_MODE_ANY, REG_TYPE_UINT32, "general", "org.gnu.gdb.arm.core" },
1483 { ARMV8_V0, 0, "d0", 64, ARM_MODE_ANY, REG_TYPE_IEEE_DOUBLE, NULL, "org.gnu.gdb.arm.vfp"},
1484 { ARMV8_V0, 8, "d1", 64, ARM_MODE_ANY, REG_TYPE_IEEE_DOUBLE, NULL, "org.gnu.gdb.arm.vfp"},
1485 { ARMV8_V1, 0, "d2", 64, ARM_MODE_ANY, REG_TYPE_IEEE_DOUBLE, NULL, "org.gnu.gdb.arm.vfp"},
1486 { ARMV8_V1, 8, "d3", 64, ARM_MODE_ANY, REG_TYPE_IEEE_DOUBLE, NULL, "org.gnu.gdb.arm.vfp"},
1487 { ARMV8_V2, 0, "d4", 64, ARM_MODE_ANY, REG_TYPE_IEEE_DOUBLE, NULL, "org.gnu.gdb.arm.vfp"},
1488 { ARMV8_V2, 8, "d5", 64, ARM_MODE_ANY, REG_TYPE_IEEE_DOUBLE, NULL, "org.gnu.gdb.arm.vfp"},
1489 { ARMV8_V3, 0, "d6", 64, ARM_MODE_ANY, REG_TYPE_IEEE_DOUBLE, NULL, "org.gnu.gdb.arm.vfp"},
1490 { ARMV8_V3, 8, "d7", 64, ARM_MODE_ANY, REG_TYPE_IEEE_DOUBLE, NULL, "org.gnu.gdb.arm.vfp"},
1491 { ARMV8_V4, 0, "d8", 64, ARM_MODE_ANY, REG_TYPE_IEEE_DOUBLE, NULL, "org.gnu.gdb.arm.vfp"},
1492 { ARMV8_V4, 8, "d9", 64, ARM_MODE_ANY, REG_TYPE_IEEE_DOUBLE, NULL, "org.gnu.gdb.arm.vfp"},
1493 { ARMV8_V5, 0, "d10", 64, ARM_MODE_ANY, REG_TYPE_IEEE_DOUBLE, NULL, "org.gnu.gdb.arm.vfp"},
1494 { ARMV8_V5, 8, "d11", 64, ARM_MODE_ANY, REG_TYPE_IEEE_DOUBLE, NULL, "org.gnu.gdb.arm.vfp"},
1495 { ARMV8_V6, 0, "d12", 64, ARM_MODE_ANY, REG_TYPE_IEEE_DOUBLE, NULL, "org.gnu.gdb.arm.vfp"},
1496 { ARMV8_V6, 8, "d13", 64, ARM_MODE_ANY, REG_TYPE_IEEE_DOUBLE, NULL, "org.gnu.gdb.arm.vfp"},
1497 { ARMV8_V7, 0, "d14", 64, ARM_MODE_ANY, REG_TYPE_IEEE_DOUBLE, NULL, "org.gnu.gdb.arm.vfp"},
1498 { ARMV8_V7, 8, "d15", 64, ARM_MODE_ANY, REG_TYPE_IEEE_DOUBLE, NULL, "org.gnu.gdb.arm.vfp"},
1499 { ARMV8_V8, 0, "d16", 64, ARM_MODE_ANY, REG_TYPE_IEEE_DOUBLE, NULL, "org.gnu.gdb.arm.vfp"},
1500 { ARMV8_V8, 8, "d17", 64, ARM_MODE_ANY, REG_TYPE_IEEE_DOUBLE, NULL, "org.gnu.gdb.arm.vfp"},
1501 { ARMV8_V9, 0, "d18", 64, ARM_MODE_ANY, REG_TYPE_IEEE_DOUBLE, NULL, "org.gnu.gdb.arm.vfp"},
1502 { ARMV8_V9, 8, "d19", 64, ARM_MODE_ANY, REG_TYPE_IEEE_DOUBLE, NULL, "org.gnu.gdb.arm.vfp"},
1503 { ARMV8_V10, 0, "d20", 64, ARM_MODE_ANY, REG_TYPE_IEEE_DOUBLE, NULL, "org.gnu.gdb.arm.vfp"},
1504 { ARMV8_V10, 8, "d21", 64, ARM_MODE_ANY, REG_TYPE_IEEE_DOUBLE, NULL, "org.gnu.gdb.arm.vfp"},
1505 { ARMV8_V11, 0, "d22", 64, ARM_MODE_ANY, REG_TYPE_IEEE_DOUBLE, NULL, "org.gnu.gdb.arm.vfp"},
1506 { ARMV8_V11, 8, "d23", 64, ARM_MODE_ANY, REG_TYPE_IEEE_DOUBLE, NULL, "org.gnu.gdb.arm.vfp"},
1507 { ARMV8_V12, 0, "d24", 64, ARM_MODE_ANY, REG_TYPE_IEEE_DOUBLE, NULL, "org.gnu.gdb.arm.vfp"},
1508 { ARMV8_V12, 8, "d25", 64, ARM_MODE_ANY, REG_TYPE_IEEE_DOUBLE, NULL, "org.gnu.gdb.arm.vfp"},
1509 { ARMV8_V13, 0, "d26", 64, ARM_MODE_ANY, REG_TYPE_IEEE_DOUBLE, NULL, "org.gnu.gdb.arm.vfp"},
1510 { ARMV8_V13, 8, "d27", 64, ARM_MODE_ANY, REG_TYPE_IEEE_DOUBLE, NULL, "org.gnu.gdb.arm.vfp"},
1511 { ARMV8_V14, 0, "d28", 64, ARM_MODE_ANY, REG_TYPE_IEEE_DOUBLE, NULL, "org.gnu.gdb.arm.vfp"},
1512 { ARMV8_V14, 8, "d29", 64, ARM_MODE_ANY, REG_TYPE_IEEE_DOUBLE, NULL, "org.gnu.gdb.arm.vfp"},
1513 { ARMV8_V15, 0, "d30", 64, ARM_MODE_ANY, REG_TYPE_IEEE_DOUBLE, NULL, "org.gnu.gdb.arm.vfp"},
1514 { ARMV8_V15, 8, "d31", 64, ARM_MODE_ANY, REG_TYPE_IEEE_DOUBLE, NULL, "org.gnu.gdb.arm.vfp"},
1515 { ARMV8_FPSR, 0, "fpscr", 32, ARM_MODE_ANY, REG_TYPE_UINT32, "float", "org.gnu.gdb.arm.vfp"},
1516 };
1517
1518 #define ARMV8_NUM_REGS ARRAY_SIZE(armv8_regs)
1519 #define ARMV8_NUM_REGS32 ARRAY_SIZE(armv8_regs32)
1520
1521 static int armv8_get_core_reg(struct reg *reg)
1522 {
1523 struct arm_reg *armv8_reg = reg->arch_info;
1524 struct target *target = armv8_reg->target;
1525 struct arm *arm = target_to_arm(target);
1526
1527 if (target->state != TARGET_HALTED)
1528 return ERROR_TARGET_NOT_HALTED;
1529
1530 return arm->read_core_reg(target, reg, armv8_reg->num, arm->core_mode);
1531 }
1532
1533 static int armv8_set_core_reg(struct reg *reg, uint8_t *buf)
1534 {
1535 struct arm_reg *armv8_reg = reg->arch_info;
1536 struct target *target = armv8_reg->target;
1537 struct arm *arm = target_to_arm(target);
1538 uint64_t value = buf_get_u64(buf, 0, reg->size);
1539
1540 if (target->state != TARGET_HALTED)
1541 return ERROR_TARGET_NOT_HALTED;
1542
1543 if (reg->size <= 64) {
1544 if (reg == arm->cpsr)
1545 armv8_set_cpsr(arm, (uint32_t)value);
1546 else {
1547 buf_set_u64(reg->value, 0, reg->size, value);
1548 reg->valid = true;
1549 }
1550 } else if (reg->size <= 128) {
1551 uint64_t hvalue = buf_get_u64(buf + 8, 0, reg->size - 64);
1552
1553 buf_set_u64(reg->value, 0, 64, value);
1554 buf_set_u64(reg->value + 8, 0, reg->size - 64, hvalue);
1555 reg->valid = true;
1556 }
1557
1558 reg->dirty = true;
1559
1560 return ERROR_OK;
1561 }
1562
1563 static const struct reg_arch_type armv8_reg_type = {
1564 .get = armv8_get_core_reg,
1565 .set = armv8_set_core_reg,
1566 };
1567
1568 static int armv8_get_core_reg32(struct reg *reg)
1569 {
1570 struct arm_reg *armv8_reg = reg->arch_info;
1571 struct target *target = armv8_reg->target;
1572 struct arm *arm = target_to_arm(target);
1573 struct reg_cache *cache = arm->core_cache;
1574 struct reg *reg64;
1575 int retval;
1576
1577 if (target->state != TARGET_HALTED)
1578 return ERROR_TARGET_NOT_HALTED;
1579
1580 /* get the corresponding Aarch64 register */
1581 reg64 = cache->reg_list + armv8_reg->num;
1582 if (reg64->valid) {
1583 reg->valid = true;
1584 return ERROR_OK;
1585 }
1586
1587 retval = arm->read_core_reg(target, reg64, armv8_reg->num, arm->core_mode);
1588 if (retval == ERROR_OK)
1589 reg->valid = reg64->valid;
1590
1591 return retval;
1592 }
1593
1594 static int armv8_set_core_reg32(struct reg *reg, uint8_t *buf)
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 struct reg_cache *cache = arm->core_cache;
1600 struct reg *reg64 = cache->reg_list + armv8_reg->num;
1601 uint32_t value = buf_get_u32(buf, 0, 32);
1602
1603 if (target->state != TARGET_HALTED)
1604 return ERROR_TARGET_NOT_HALTED;
1605
1606 if (reg64 == arm->cpsr) {
1607 armv8_set_cpsr(arm, value);
1608 } else {
1609 if (reg->size <= 32)
1610 buf_set_u32(reg->value, 0, 32, value);
1611 else if (reg->size <= 64) {
1612 uint64_t value64 = buf_get_u64(buf, 0, 64);
1613 buf_set_u64(reg->value, 0, 64, value64);
1614 }
1615 reg->valid = true;
1616 reg64->valid = true;
1617 }
1618
1619 reg64->dirty = true;
1620
1621 return ERROR_OK;
1622 }
1623
1624 static const struct reg_arch_type armv8_reg32_type = {
1625 .get = armv8_get_core_reg32,
1626 .set = armv8_set_core_reg32,
1627 };
1628
1629 /** Builds cache of architecturally defined registers. */
1630 struct reg_cache *armv8_build_reg_cache(struct target *target)
1631 {
1632 struct armv8_common *armv8 = target_to_armv8(target);
1633 struct arm *arm = &armv8->arm;
1634 int num_regs = ARMV8_NUM_REGS;
1635 int num_regs32 = ARMV8_NUM_REGS32;
1636 struct reg_cache **cache_p = register_get_last_cache_p(&target->reg_cache);
1637 struct reg_cache *cache = malloc(sizeof(struct reg_cache));
1638 struct reg_cache *cache32 = malloc(sizeof(struct reg_cache));
1639 struct reg *reg_list = calloc(num_regs, sizeof(struct reg));
1640 struct reg *reg_list32 = calloc(num_regs32, sizeof(struct reg));
1641 struct arm_reg *arch_info = calloc(num_regs, sizeof(struct arm_reg));
1642 struct reg_feature *feature;
1643 int i;
1644
1645 /* Build the process context cache */
1646 cache->name = "Aarch64 registers";
1647 cache->next = cache32;
1648 cache->reg_list = reg_list;
1649 cache->num_regs = num_regs;
1650
1651 for (i = 0; i < num_regs; i++) {
1652 arch_info[i].num = armv8_regs[i].id;
1653 arch_info[i].mode = armv8_regs[i].mode;
1654 arch_info[i].target = target;
1655 arch_info[i].arm = arm;
1656
1657 reg_list[i].name = armv8_regs[i].name;
1658 reg_list[i].size = armv8_regs[i].bits;
1659 reg_list[i].value = &arch_info[i].value[0];
1660 reg_list[i].type = &armv8_reg_type;
1661 reg_list[i].arch_info = &arch_info[i];
1662
1663 reg_list[i].group = armv8_regs[i].group;
1664 reg_list[i].number = i;
1665 reg_list[i].exist = true;
1666 reg_list[i].caller_save = true; /* gdb defaults to true */
1667
1668 feature = calloc(1, sizeof(struct reg_feature));
1669 if (feature) {
1670 feature->name = armv8_regs[i].feature;
1671 reg_list[i].feature = feature;
1672 } else
1673 LOG_ERROR("unable to allocate feature list");
1674
1675 reg_list[i].reg_data_type = calloc(1, sizeof(struct reg_data_type));
1676 if (reg_list[i].reg_data_type) {
1677 if (!armv8_regs[i].data_type)
1678 reg_list[i].reg_data_type->type = armv8_regs[i].type;
1679 else
1680 *reg_list[i].reg_data_type = *armv8_regs[i].data_type;
1681 } else
1682 LOG_ERROR("unable to allocate reg type list");
1683
1684 if (i == ARMV8_PAUTH_CMASK || i == ARMV8_PAUTH_DMASK)
1685 reg_list[i].hidden = !armv8->enable_pauth;
1686 }
1687
1688 arm->cpsr = reg_list + ARMV8_XPSR;
1689 arm->pc = reg_list + ARMV8_PC;
1690 arm->core_cache = cache;
1691
1692 /* shadow cache for ARM mode registers */
1693 cache32->name = "Aarch32 registers";
1694 cache32->next = NULL;
1695 cache32->reg_list = reg_list32;
1696 cache32->num_regs = num_regs32;
1697
1698 for (i = 0; i < num_regs32; i++) {
1699 reg_list32[i].name = armv8_regs32[i].name;
1700 reg_list32[i].size = armv8_regs32[i].bits;
1701 reg_list32[i].value = &arch_info[armv8_regs32[i].id].value[armv8_regs32[i].mapping];
1702 reg_list32[i].type = &armv8_reg32_type;
1703 reg_list32[i].arch_info = &arch_info[armv8_regs32[i].id];
1704 reg_list32[i].group = armv8_regs32[i].group;
1705 reg_list32[i].number = i;
1706 reg_list32[i].exist = true;
1707 reg_list32[i].caller_save = true;
1708
1709 feature = calloc(1, sizeof(struct reg_feature));
1710 if (feature) {
1711 feature->name = armv8_regs32[i].feature;
1712 reg_list32[i].feature = feature;
1713 } else
1714 LOG_ERROR("unable to allocate feature list");
1715
1716 reg_list32[i].reg_data_type = calloc(1, sizeof(struct reg_data_type));
1717 if (reg_list32[i].reg_data_type)
1718 reg_list32[i].reg_data_type->type = armv8_regs32[i].type;
1719 else
1720 LOG_ERROR("unable to allocate reg type list");
1721 }
1722
1723 (*cache_p) = cache;
1724 return cache;
1725 }
1726
1727 struct reg *armv8_reg_current(struct arm *arm, unsigned regnum)
1728 {
1729 struct reg *r;
1730
1731 if (regnum > (ARMV8_LAST_REG - 1))
1732 return NULL;
1733
1734 r = arm->core_cache->reg_list + regnum;
1735 return r;
1736 }
1737
1738 static void armv8_free_cache(struct reg_cache *cache, bool regs32)
1739 {
1740 struct reg *reg;
1741 unsigned int i;
1742
1743 if (!cache)
1744 return;
1745
1746 for (i = 0; i < cache->num_regs; i++) {
1747 reg = &cache->reg_list[i];
1748
1749 free(reg->feature);
1750 free(reg->reg_data_type);
1751 }
1752
1753 if (!regs32)
1754 free(cache->reg_list[0].arch_info);
1755 free(cache->reg_list);
1756 free(cache);
1757 }
1758
1759 void armv8_free_reg_cache(struct target *target)
1760 {
1761 struct armv8_common *armv8 = target_to_armv8(target);
1762 struct arm *arm = &armv8->arm;
1763 struct reg_cache *cache = NULL, *cache32 = NULL;
1764
1765 cache = arm->core_cache;
1766 if (cache)
1767 cache32 = cache->next;
1768 armv8_free_cache(cache32, true);
1769 armv8_free_cache(cache, false);
1770 arm->core_cache = NULL;
1771 }
1772
1773 const struct command_registration armv8_command_handlers[] = {
1774 {
1775 .name = "catch_exc",
1776 .handler = armv8_handle_exception_catch_command,
1777 .mode = COMMAND_EXEC,
1778 .help = "configure exception catch",
1779 .usage = "[(nsec_el1,nsec_el2,sec_el1,sec_el3)+,off]",
1780 },
1781 {
1782 .name = "pauth",
1783 .handler = armv8_pauth_command,
1784 .mode = COMMAND_CONFIG,
1785 .help = "enable or disable providing GDB with an 8-bytes mask to "
1786 "remove signature bits added by pointer authentication."
1787 "Pointer authentication feature is broken until gdb 12.1, going to be fixed. "
1788 "Consider using a newer version of gdb if you want enable "
1789 "pauth feature.",
1790 .usage = "[on|off]",
1791 },
1792 COMMAND_REGISTRATION_DONE
1793 };
1794
1795 const char *armv8_get_gdb_arch(struct target *target)
1796 {
1797 struct arm *arm = target_to_arm(target);
1798 return arm->core_state == ARM_STATE_AARCH64 ? "aarch64" : "arm";
1799 }
1800
1801 int armv8_get_gdb_reg_list(struct target *target,
1802 struct reg **reg_list[], int *reg_list_size,
1803 enum target_register_class reg_class)
1804 {
1805 struct arm *arm = target_to_arm(target);
1806 int i;
1807
1808 if (arm->core_state == ARM_STATE_AARCH64) {
1809
1810 LOG_DEBUG("Creating Aarch64 register list for target %s", target_name(target));
1811
1812 switch (reg_class) {
1813 case REG_CLASS_GENERAL:
1814 *reg_list_size = ARMV8_V0;
1815 *reg_list = malloc(sizeof(struct reg *) * (*reg_list_size));
1816
1817 for (i = 0; i < *reg_list_size; i++)
1818 (*reg_list)[i] = armv8_reg_current(arm, i);
1819 return ERROR_OK;
1820
1821 case REG_CLASS_ALL:
1822 *reg_list_size = ARMV8_LAST_REG;
1823 *reg_list = malloc(sizeof(struct reg *) * (*reg_list_size));
1824
1825 for (i = 0; i < *reg_list_size; i++)
1826 (*reg_list)[i] = armv8_reg_current(arm, i);
1827
1828 return ERROR_OK;
1829
1830 default:
1831 LOG_ERROR("not a valid register class type in query.");
1832 return ERROR_FAIL;
1833 }
1834 } else {
1835 struct reg_cache *cache32 = arm->core_cache->next;
1836
1837 LOG_DEBUG("Creating Aarch32 register list for target %s", target_name(target));
1838
1839 switch (reg_class) {
1840 case REG_CLASS_GENERAL:
1841 *reg_list_size = ARMV8_R14 + 3;
1842 *reg_list = malloc(sizeof(struct reg *) * (*reg_list_size));
1843
1844 for (i = 0; i < *reg_list_size; i++)
1845 (*reg_list)[i] = cache32->reg_list + i;
1846
1847 return ERROR_OK;
1848 case REG_CLASS_ALL:
1849 *reg_list_size = cache32->num_regs;
1850 *reg_list = malloc(sizeof(struct reg *) * (*reg_list_size));
1851
1852 for (i = 0; i < *reg_list_size; i++)
1853 (*reg_list)[i] = cache32->reg_list + i;
1854
1855 return ERROR_OK;
1856 default:
1857 LOG_ERROR("not a valid register class type in query.");
1858 return ERROR_FAIL;
1859 }
1860 }
1861 }
1862
1863 int armv8_set_dbgreg_bits(struct armv8_common *armv8, unsigned int reg, unsigned long mask, unsigned long value)
1864 {
1865 uint32_t tmp;
1866
1867 /* Read register */
1868 int retval = mem_ap_read_atomic_u32(armv8->debug_ap,
1869 armv8->debug_base + reg, &tmp);
1870 if (retval != ERROR_OK)
1871 return retval;
1872
1873 /* clear bitfield */
1874 tmp &= ~mask;
1875 /* put new value */
1876 tmp |= value & mask;
1877
1878 /* write new value */
1879 retval = mem_ap_write_atomic_u32(armv8->debug_ap,
1880 armv8->debug_base + reg, tmp);
1881 return retval;
1882 }

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)