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

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)