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

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)