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

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)