86bb8707e43e3f7d13279bfbe4bced0ab148eb2a
[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_dpm *dpm = armv8->arm.dpm;
624 uint32_t mpidr;
625
626 retval = dpm->prepare(dpm);
627 if (retval != ERROR_OK)
628 goto done;
629
630 retval = dpm->instr_read_data_r0(dpm, armv8_opcode(armv8, READ_REG_MPIDR), &mpidr);
631 if (retval != ERROR_OK)
632 goto done;
633 if (mpidr & 1<<31) {
634 armv8->multi_processor_system = (mpidr >> 30) & 1;
635 armv8->cluster_id = (mpidr >> 8) & 0xf;
636 armv8->cpu_id = mpidr & 0x3;
637 LOG_INFO("%s cluster %x core %x %s", target_name(armv8->arm.target),
638 armv8->cluster_id,
639 armv8->cpu_id,
640 armv8->multi_processor_system == 0 ? "multi core" : "single core");
641 } else
642 LOG_ERROR("mpidr not in multiprocessor format");
643
644 done:
645 dpm->finish(dpm);
646 return retval;
647 }
648
649 /**
650 * Configures host-side ARM records to reflect the specified CPSR.
651 * Later, code can use arm_reg_current() to map register numbers
652 * according to how they are exposed by this mode.
653 */
654 void armv8_set_cpsr(struct arm *arm, uint32_t cpsr)
655 {
656 uint32_t mode = cpsr & 0x1F;
657
658 /* NOTE: this may be called very early, before the register
659 * cache is set up. We can't defend against many errors, in
660 * particular against CPSRs that aren't valid *here* ...
661 */
662 if (arm->cpsr) {
663 buf_set_u32(arm->cpsr->value, 0, 32, cpsr);
664 arm->cpsr->valid = 1;
665 arm->cpsr->dirty = 0;
666 }
667
668 /* Older ARMs won't have the J bit */
669 enum arm_state state = 0xFF;
670
671 if ((cpsr & 0x10) != 0) {
672 /* Aarch32 state */
673 if (cpsr & (1 << 5)) { /* T */
674 if (cpsr & (1 << 24)) { /* J */
675 LOG_WARNING("ThumbEE -- incomplete support");
676 state = ARM_STATE_THUMB_EE;
677 } else
678 state = ARM_STATE_THUMB;
679 } else {
680 if (cpsr & (1 << 24)) { /* J */
681 LOG_ERROR("Jazelle state handling is BROKEN!");
682 state = ARM_STATE_JAZELLE;
683 } else
684 state = ARM_STATE_ARM;
685 }
686 } else {
687 /* Aarch64 state */
688 state = ARM_STATE_AARCH64;
689 }
690
691 arm->core_state = state;
692 arm->core_mode = mode;
693
694 LOG_DEBUG("set CPSR %#8.8x: %s mode, %s state", (unsigned) cpsr,
695 armv8_mode_name(arm->core_mode),
696 armv8_state_strings[arm->core_state]);
697 }
698
699 static void armv8_show_fault_registers32(struct armv8_common *armv8)
700 {
701 uint32_t dfsr, ifsr, dfar, ifar;
702 struct arm_dpm *dpm = armv8->arm.dpm;
703 int retval;
704
705 retval = dpm->prepare(dpm);
706 if (retval != ERROR_OK)
707 return;
708
709 /* ARMV4_5_MRC(cpnum, op1, r0, CRn, CRm, op2) */
710
711 /* c5/c0 - {data, instruction} fault status registers */
712 retval = dpm->instr_read_data_r0(dpm,
713 ARMV4_5_MRC(15, 0, 0, 5, 0, 0),
714 &dfsr);
715 if (retval != ERROR_OK)
716 goto done;
717
718 retval = dpm->instr_read_data_r0(dpm,
719 ARMV4_5_MRC(15, 0, 0, 5, 0, 1),
720 &ifsr);
721 if (retval != ERROR_OK)
722 goto done;
723
724 /* c6/c0 - {data, instruction} fault address registers */
725 retval = dpm->instr_read_data_r0(dpm,
726 ARMV4_5_MRC(15, 0, 0, 6, 0, 0),
727 &dfar);
728 if (retval != ERROR_OK)
729 goto done;
730
731 retval = dpm->instr_read_data_r0(dpm,
732 ARMV4_5_MRC(15, 0, 0, 6, 0, 2),
733 &ifar);
734 if (retval != ERROR_OK)
735 goto done;
736
737 LOG_USER("Data fault registers DFSR: %8.8" PRIx32
738 ", DFAR: %8.8" PRIx32, dfsr, dfar);
739 LOG_USER("Instruction fault registers IFSR: %8.8" PRIx32
740 ", IFAR: %8.8" PRIx32, ifsr, ifar);
741
742 done:
743 /* (void) */ dpm->finish(dpm);
744 }
745
746 static __attribute__((unused)) void armv8_show_fault_registers(struct target *target)
747 {
748 struct armv8_common *armv8 = target_to_armv8(target);
749
750 if (armv8->arm.core_state != ARM_STATE_AARCH64)
751 armv8_show_fault_registers32(armv8);
752 }
753
754 static uint8_t armv8_pa_size(uint32_t ps)
755 {
756 uint8_t ret = 0;
757 switch (ps) {
758 case 0:
759 ret = 32;
760 break;
761 case 1:
762 ret = 36;
763 break;
764 case 2:
765 ret = 40;
766 break;
767 case 3:
768 ret = 42;
769 break;
770 case 4:
771 ret = 44;
772 break;
773 case 5:
774 ret = 48;
775 break;
776 default:
777 LOG_INFO("Unknow physicall address size");
778 break;
779 }
780 return ret;
781 }
782
783 static __attribute__((unused)) int armv8_read_ttbcr32(struct target *target)
784 {
785 struct armv8_common *armv8 = target_to_armv8(target);
786 struct arm_dpm *dpm = armv8->arm.dpm;
787 uint32_t ttbcr, ttbcr_n;
788 int retval = dpm->prepare(dpm);
789 if (retval != ERROR_OK)
790 goto done;
791 /* MRC p15,0,<Rt>,c2,c0,2 ; Read CP15 Translation Table Base Control Register*/
792 retval = dpm->instr_read_data_r0(dpm,
793 ARMV4_5_MRC(15, 0, 0, 2, 0, 2),
794 &ttbcr);
795 if (retval != ERROR_OK)
796 goto done;
797
798 LOG_DEBUG("ttbcr %" PRIx32, ttbcr);
799
800 ttbcr_n = ttbcr & 0x7;
801 armv8->armv8_mmu.ttbcr = ttbcr;
802
803 /*
804 * ARM Architecture Reference Manual (ARMv7-A and ARMv7-Redition),
805 * document # ARM DDI 0406C
806 */
807 armv8->armv8_mmu.ttbr_range[0] = 0xffffffff >> ttbcr_n;
808 armv8->armv8_mmu.ttbr_range[1] = 0xffffffff;
809 armv8->armv8_mmu.ttbr_mask[0] = 0xffffffff << (14 - ttbcr_n);
810 armv8->armv8_mmu.ttbr_mask[1] = 0xffffffff << 14;
811
812 LOG_DEBUG("ttbr1 %s, ttbr0_mask %" PRIx32 " ttbr1_mask %" PRIx32,
813 (ttbcr_n != 0) ? "used" : "not used",
814 armv8->armv8_mmu.ttbr_mask[0],
815 armv8->armv8_mmu.ttbr_mask[1]);
816
817 done:
818 dpm->finish(dpm);
819 return retval;
820 }
821
822 static __attribute__((unused)) int armv8_read_ttbcr(struct target *target)
823 {
824 struct armv8_common *armv8 = target_to_armv8(target);
825 struct arm_dpm *dpm = armv8->arm.dpm;
826 struct arm *arm = &armv8->arm;
827 uint32_t ttbcr;
828 uint64_t ttbcr_64;
829
830 int retval = dpm->prepare(dpm);
831 if (retval != ERROR_OK)
832 goto done;
833
834 /* claaer ttrr1_used and ttbr0_mask */
835 memset(&armv8->armv8_mmu.ttbr1_used, 0, sizeof(armv8->armv8_mmu.ttbr1_used));
836 memset(&armv8->armv8_mmu.ttbr0_mask, 0, sizeof(armv8->armv8_mmu.ttbr0_mask));
837
838 switch (armv8_curel_from_core_mode(arm->core_mode)) {
839 case SYSTEM_CUREL_EL3:
840 retval = dpm->instr_read_data_r0(dpm,
841 ARMV8_MRS(SYSTEM_TCR_EL3, 0),
842 &ttbcr);
843 retval += dpm->instr_read_data_r0_64(dpm,
844 ARMV8_MRS(SYSTEM_TTBR0_EL3, 0),
845 &armv8->ttbr_base);
846 if (retval != ERROR_OK)
847 goto done;
848 armv8->va_size = 64 - (ttbcr & 0x3F);
849 armv8->pa_size = armv8_pa_size((ttbcr >> 16) & 7);
850 armv8->page_size = (ttbcr >> 14) & 3;
851 break;
852 case SYSTEM_CUREL_EL2:
853 retval = dpm->instr_read_data_r0(dpm,
854 ARMV8_MRS(SYSTEM_TCR_EL2, 0),
855 &ttbcr);
856 retval += dpm->instr_read_data_r0_64(dpm,
857 ARMV8_MRS(SYSTEM_TTBR0_EL2, 0),
858 &armv8->ttbr_base);
859 if (retval != ERROR_OK)
860 goto done;
861 armv8->va_size = 64 - (ttbcr & 0x3F);
862 armv8->pa_size = armv8_pa_size((ttbcr >> 16) & 7);
863 armv8->page_size = (ttbcr >> 14) & 3;
864 break;
865 case SYSTEM_CUREL_EL0:
866 armv8_dpm_modeswitch(dpm, ARMV8_64_EL1H);
867 /* fall through */
868 case SYSTEM_CUREL_EL1:
869 retval = dpm->instr_read_data_r0_64(dpm,
870 ARMV8_MRS(SYSTEM_TCR_EL1, 0),
871 &ttbcr_64);
872 armv8->va_size = 64 - (ttbcr_64 & 0x3F);
873 armv8->pa_size = armv8_pa_size((ttbcr_64 >> 32) & 7);
874 armv8->page_size = (ttbcr_64 >> 14) & 3;
875 armv8->armv8_mmu.ttbr1_used = (((ttbcr_64 >> 16) & 0x3F) != 0) ? 1 : 0;
876 armv8->armv8_mmu.ttbr0_mask = 0x0000FFFFFFFFFFFF;
877 retval += dpm->instr_read_data_r0_64(dpm,
878 ARMV8_MRS(SYSTEM_TTBR0_EL1 | (armv8->armv8_mmu.ttbr1_used), 0),
879 &armv8->ttbr_base);
880 if (retval != ERROR_OK)
881 goto done;
882 break;
883 default:
884 LOG_ERROR("unknow core state");
885 retval = ERROR_FAIL;
886 break;
887 }
888 if (retval != ERROR_OK)
889 goto done;
890
891 if (armv8->armv8_mmu.ttbr1_used == 1)
892 LOG_INFO("TTBR0 access above %" PRIx64, (uint64_t)(armv8->armv8_mmu.ttbr0_mask));
893
894 done:
895 armv8_dpm_modeswitch(dpm, ARM_MODE_ANY);
896 dpm->finish(dpm);
897 return retval;
898 }
899
900 /* method adapted to cortex A : reused arm v4 v5 method*/
901 int armv8_mmu_translate_va(struct target *target, target_addr_t va, target_addr_t *val)
902 {
903 return ERROR_OK;
904 }
905
906 /* V8 method VA TO PA */
907 int armv8_mmu_translate_va_pa(struct target *target, target_addr_t va,
908 target_addr_t *val, int meminfo)
909 {
910 struct armv8_common *armv8 = target_to_armv8(target);
911 struct arm *arm = target_to_arm(target);
912 struct arm_dpm *dpm = &armv8->dpm;
913 enum arm_mode target_mode = ARM_MODE_ANY;
914 uint32_t retval;
915 uint32_t instr = 0;
916 uint64_t par;
917
918 static const char * const shared_name[] = {
919 "Non-", "UNDEFINED ", "Outer ", "Inner "
920 };
921
922 static const char * const secure_name[] = {
923 "Secure", "Not Secure"
924 };
925
926 retval = dpm->prepare(dpm);
927 if (retval != ERROR_OK)
928 return retval;
929
930 switch (armv8_curel_from_core_mode(arm->core_mode)) {
931 case SYSTEM_CUREL_EL0:
932 instr = ARMV8_SYS(SYSTEM_ATS12E0R, 0);
933 /* can only execute instruction at EL2 */
934 target_mode = ARMV8_64_EL2H;
935 break;
936 case SYSTEM_CUREL_EL1:
937 instr = ARMV8_SYS(SYSTEM_ATS12E1R, 0);
938 /* can only execute instruction at EL2 */
939 target_mode = ARMV8_64_EL2H;
940 break;
941 case SYSTEM_CUREL_EL2:
942 instr = ARMV8_SYS(SYSTEM_ATS1E2R, 0);
943 break;
944 case SYSTEM_CUREL_EL3:
945 instr = ARMV8_SYS(SYSTEM_ATS1E3R, 0);
946 break;
947
948 default:
949 break;
950 };
951
952 if (target_mode != ARM_MODE_ANY)
953 armv8_dpm_modeswitch(dpm, target_mode);
954
955 /* write VA to R0 and execute translation instruction */
956 retval = dpm->instr_write_data_r0_64(dpm, instr, (uint64_t)va);
957 /* read result from PAR_EL1 */
958 if (retval == ERROR_OK)
959 retval = dpm->instr_read_data_r0_64(dpm, ARMV8_MRS(SYSTEM_PAR_EL1, 0), &par);
960
961 /* switch back to saved PE mode */
962 if (target_mode != ARM_MODE_ANY)
963 armv8_dpm_modeswitch(dpm, ARM_MODE_ANY);
964
965 dpm->finish(dpm);
966
967 if (retval != ERROR_OK)
968 return retval;
969
970 if (par & 1) {
971 LOG_ERROR("Address translation failed at stage %i, FST=%x, PTW=%i",
972 ((int)(par >> 9) & 1)+1, (int)(par >> 1) & 0x3f, (int)(par >> 8) & 1);
973
974 *val = 0;
975 retval = ERROR_FAIL;
976 } else {
977 *val = (par & 0xFFFFFFFFF000UL) | (va & 0xFFF);
978 if (meminfo) {
979 int SH = (par >> 7) & 3;
980 int NS = (par >> 9) & 1;
981 int ATTR = (par >> 56) & 0xFF;
982
983 char *memtype = (ATTR & 0xF0) == 0 ? "Device Memory" : "Normal Memory";
984
985 LOG_USER("%sshareable, %s",
986 shared_name[SH], secure_name[NS]);
987 LOG_USER("%s", memtype);
988 }
989 }
990
991 return retval;
992 }
993
994 int armv8_handle_cache_info_command(struct command_context *cmd_ctx,
995 struct armv8_cache_common *armv8_cache)
996 {
997 if (armv8_cache->info == -1) {
998 command_print(cmd_ctx, "cache not yet identified");
999 return ERROR_OK;
1000 }
1001
1002 if (armv8_cache->display_cache_info)
1003 armv8_cache->display_cache_info(cmd_ctx, armv8_cache);
1004 return ERROR_OK;
1005 }
1006
1007 int armv8_init_arch_info(struct target *target, struct armv8_common *armv8)
1008 {
1009 struct arm *arm = &armv8->arm;
1010 arm->arch_info = armv8;
1011 target->arch_info = &armv8->arm;
1012 /* target is useful in all function arm v4 5 compatible */
1013 armv8->arm.target = target;
1014 armv8->arm.common_magic = ARM_COMMON_MAGIC;
1015 armv8->common_magic = ARMV8_COMMON_MAGIC;
1016
1017 armv8->armv8_mmu.armv8_cache.l2_cache = NULL;
1018 armv8->armv8_mmu.armv8_cache.info = -1;
1019 armv8->armv8_mmu.armv8_cache.flush_all_data_cache = NULL;
1020 armv8->armv8_mmu.armv8_cache.display_cache_info = NULL;
1021 return ERROR_OK;
1022 }
1023
1024 int armv8_aarch64_state(struct target *target)
1025 {
1026 struct arm *arm = target_to_arm(target);
1027
1028 if (arm->common_magic != ARM_COMMON_MAGIC) {
1029 LOG_ERROR("BUG: called for a non-ARM target");
1030 return ERROR_FAIL;
1031 }
1032
1033 LOG_USER("target halted in %s state due to %s, current mode: %s\n"
1034 "cpsr: 0x%8.8" PRIx32 " pc: 0x%" PRIx64 "%s",
1035 armv8_state_strings[arm->core_state],
1036 debug_reason_name(target),
1037 armv8_mode_name(arm->core_mode),
1038 buf_get_u32(arm->cpsr->value, 0, 32),
1039 buf_get_u64(arm->pc->value, 0, 64),
1040 arm->is_semihosting ? ", semihosting" : "");
1041
1042 return ERROR_OK;
1043 }
1044
1045 int armv8_arch_state(struct target *target)
1046 {
1047 static const char * const state[] = {
1048 "disabled", "enabled"
1049 };
1050
1051 struct armv8_common *armv8 = target_to_armv8(target);
1052 struct arm *arm = &armv8->arm;
1053
1054 if (armv8->common_magic != ARMV8_COMMON_MAGIC) {
1055 LOG_ERROR("BUG: called for a non-Armv8 target");
1056 return ERROR_COMMAND_SYNTAX_ERROR;
1057 }
1058
1059 if (arm->core_state == ARM_STATE_AARCH64)
1060 armv8_aarch64_state(target);
1061 else
1062 arm_arch_state(target);
1063
1064 LOG_USER("MMU: %s, D-Cache: %s, I-Cache: %s",
1065 state[armv8->armv8_mmu.mmu_enabled],
1066 state[armv8->armv8_mmu.armv8_cache.d_u_cache_enabled],
1067 state[armv8->armv8_mmu.armv8_cache.i_cache_enabled]);
1068
1069 if (arm->core_mode == ARM_MODE_ABT)
1070 armv8_show_fault_registers(target);
1071
1072 if (target->debug_reason == DBG_REASON_WATCHPOINT)
1073 LOG_USER("Watchpoint triggered at PC %#08x",
1074 (unsigned) armv8->dpm.wp_pc);
1075
1076 return ERROR_OK;
1077 }
1078
1079 static struct reg_data_type aarch64_vector_base_types[] = {
1080 {REG_TYPE_IEEE_DOUBLE, "ieee_double", 0, {NULL} },
1081 {REG_TYPE_UINT64, "uint64", 0, {NULL} },
1082 {REG_TYPE_INT64, "int64", 0, {NULL} },
1083 {REG_TYPE_IEEE_SINGLE, "ieee_single", 0, {NULL} },
1084 {REG_TYPE_UINT32, "uint32", 0, {NULL} },
1085 {REG_TYPE_INT32, "int32", 0, {NULL} },
1086 {REG_TYPE_UINT16, "uint16", 0, {NULL} },
1087 {REG_TYPE_INT16, "int16", 0, {NULL} },
1088 {REG_TYPE_UINT8, "uint8", 0, {NULL} },
1089 {REG_TYPE_INT8, "int8", 0, {NULL} },
1090 {REG_TYPE_UINT128, "uint128", 0, {NULL} },
1091 {REG_TYPE_INT128, "int128", 0, {NULL} }
1092 };
1093
1094 static struct reg_data_type_vector aarch64_vector_types[] = {
1095 {aarch64_vector_base_types + 0, 2},
1096 {aarch64_vector_base_types + 1, 2},
1097 {aarch64_vector_base_types + 2, 2},
1098 {aarch64_vector_base_types + 3, 4},
1099 {aarch64_vector_base_types + 4, 4},
1100 {aarch64_vector_base_types + 5, 4},
1101 {aarch64_vector_base_types + 6, 8},
1102 {aarch64_vector_base_types + 7, 8},
1103 {aarch64_vector_base_types + 8, 16},
1104 {aarch64_vector_base_types + 9, 16},
1105 {aarch64_vector_base_types + 10, 01},
1106 {aarch64_vector_base_types + 11, 01},
1107 };
1108
1109 static struct reg_data_type aarch64_fpu_vector[] = {
1110 {REG_TYPE_ARCH_DEFINED, "v2d", REG_TYPE_CLASS_VECTOR, {aarch64_vector_types + 0} },
1111 {REG_TYPE_ARCH_DEFINED, "v2u", REG_TYPE_CLASS_VECTOR, {aarch64_vector_types + 1} },
1112 {REG_TYPE_ARCH_DEFINED, "v2i", REG_TYPE_CLASS_VECTOR, {aarch64_vector_types + 2} },
1113 {REG_TYPE_ARCH_DEFINED, "v4f", REG_TYPE_CLASS_VECTOR, {aarch64_vector_types + 3} },
1114 {REG_TYPE_ARCH_DEFINED, "v4u", REG_TYPE_CLASS_VECTOR, {aarch64_vector_types + 4} },
1115 {REG_TYPE_ARCH_DEFINED, "v4i", REG_TYPE_CLASS_VECTOR, {aarch64_vector_types + 5} },
1116 {REG_TYPE_ARCH_DEFINED, "v8u", REG_TYPE_CLASS_VECTOR, {aarch64_vector_types + 6} },
1117 {REG_TYPE_ARCH_DEFINED, "v8i", REG_TYPE_CLASS_VECTOR, {aarch64_vector_types + 7} },
1118 {REG_TYPE_ARCH_DEFINED, "v16u", REG_TYPE_CLASS_VECTOR, {aarch64_vector_types + 8} },
1119 {REG_TYPE_ARCH_DEFINED, "v16i", REG_TYPE_CLASS_VECTOR, {aarch64_vector_types + 9} },
1120 {REG_TYPE_ARCH_DEFINED, "v1u", REG_TYPE_CLASS_VECTOR, {aarch64_vector_types + 10} },
1121 {REG_TYPE_ARCH_DEFINED, "v1i", REG_TYPE_CLASS_VECTOR, {aarch64_vector_types + 11} },
1122 };
1123
1124 static struct reg_data_type_union_field aarch64_union_fields_vnd[] = {
1125 {"f", aarch64_fpu_vector + 0, aarch64_union_fields_vnd + 1},
1126 {"u", aarch64_fpu_vector + 1, aarch64_union_fields_vnd + 2},
1127 {"s", aarch64_fpu_vector + 2, NULL},
1128 };
1129
1130 static struct reg_data_type_union_field aarch64_union_fields_vns[] = {
1131 {"f", aarch64_fpu_vector + 3, aarch64_union_fields_vns + 1},
1132 {"u", aarch64_fpu_vector + 4, aarch64_union_fields_vns + 2},
1133 {"s", aarch64_fpu_vector + 5, NULL},
1134 };
1135
1136 static struct reg_data_type_union_field aarch64_union_fields_vnh[] = {
1137 {"u", aarch64_fpu_vector + 6, aarch64_union_fields_vnh + 1},
1138 {"s", aarch64_fpu_vector + 7, NULL},
1139 };
1140
1141 static struct reg_data_type_union_field aarch64_union_fields_vnb[] = {
1142 {"u", aarch64_fpu_vector + 8, aarch64_union_fields_vnb + 1},
1143 {"s", aarch64_fpu_vector + 9, NULL},
1144 };
1145
1146 static struct reg_data_type_union_field aarch64_union_fields_vnq[] = {
1147 {"u", aarch64_fpu_vector + 10, aarch64_union_fields_vnq + 1},
1148 {"s", aarch64_fpu_vector + 11, NULL},
1149 };
1150
1151 static struct reg_data_type_union aarch64_union_types[] = {
1152 {aarch64_union_fields_vnd},
1153 {aarch64_union_fields_vns},
1154 {aarch64_union_fields_vnh},
1155 {aarch64_union_fields_vnb},
1156 {aarch64_union_fields_vnq},
1157 };
1158
1159 static struct reg_data_type aarch64_fpu_union[] = {
1160 {REG_TYPE_ARCH_DEFINED, "vnd", REG_TYPE_CLASS_UNION, {.reg_type_union = aarch64_union_types + 0} },
1161 {REG_TYPE_ARCH_DEFINED, "vns", REG_TYPE_CLASS_UNION, {.reg_type_union = aarch64_union_types + 1} },
1162 {REG_TYPE_ARCH_DEFINED, "vnh", REG_TYPE_CLASS_UNION, {.reg_type_union = aarch64_union_types + 2} },
1163 {REG_TYPE_ARCH_DEFINED, "vnb", REG_TYPE_CLASS_UNION, {.reg_type_union = aarch64_union_types + 3} },
1164 {REG_TYPE_ARCH_DEFINED, "vnq", REG_TYPE_CLASS_UNION, {.reg_type_union = aarch64_union_types + 4} },
1165 };
1166
1167 static struct reg_data_type_union_field aarch64v_union_fields[] = {
1168 {"d", aarch64_fpu_union + 0, aarch64v_union_fields + 1},
1169 {"s", aarch64_fpu_union + 1, aarch64v_union_fields + 2},
1170 {"h", aarch64_fpu_union + 2, aarch64v_union_fields + 3},
1171 {"b", aarch64_fpu_union + 3, aarch64v_union_fields + 4},
1172 {"q", aarch64_fpu_union + 4, NULL},
1173 };
1174
1175 static struct reg_data_type_union aarch64v_union[] = {
1176 {aarch64v_union_fields}
1177 };
1178
1179 static struct reg_data_type aarch64v[] = {
1180 {REG_TYPE_ARCH_DEFINED, "aarch64v", REG_TYPE_CLASS_UNION, {.reg_type_union = aarch64v_union} },
1181 };
1182
1183 static const struct {
1184 unsigned id;
1185 const char *name;
1186 unsigned bits;
1187 enum arm_mode mode;
1188 enum reg_type type;
1189 const char *group;
1190 const char *feature;
1191 struct reg_data_type *data_type;
1192 } armv8_regs[] = {
1193 { ARMV8_R0, "x0", 64, ARM_MODE_ANY, REG_TYPE_UINT64, "general", "org.gnu.gdb.aarch64.core", NULL},
1194 { ARMV8_R1, "x1", 64, ARM_MODE_ANY, REG_TYPE_UINT64, "general", "org.gnu.gdb.aarch64.core", NULL},
1195 { ARMV8_R2, "x2", 64, ARM_MODE_ANY, REG_TYPE_UINT64, "general", "org.gnu.gdb.aarch64.core", NULL},
1196 { ARMV8_R3, "x3", 64, ARM_MODE_ANY, REG_TYPE_UINT64, "general", "org.gnu.gdb.aarch64.core", NULL},
1197 { ARMV8_R4, "x4", 64, ARM_MODE_ANY, REG_TYPE_UINT64, "general", "org.gnu.gdb.aarch64.core", NULL},
1198 { ARMV8_R5, "x5", 64, ARM_MODE_ANY, REG_TYPE_UINT64, "general", "org.gnu.gdb.aarch64.core", NULL},
1199 { ARMV8_R6, "x6", 64, ARM_MODE_ANY, REG_TYPE_UINT64, "general", "org.gnu.gdb.aarch64.core", NULL},
1200 { ARMV8_R7, "x7", 64, ARM_MODE_ANY, REG_TYPE_UINT64, "general", "org.gnu.gdb.aarch64.core", NULL},
1201 { ARMV8_R8, "x8", 64, ARM_MODE_ANY, REG_TYPE_UINT64, "general", "org.gnu.gdb.aarch64.core", NULL},
1202 { ARMV8_R9, "x9", 64, ARM_MODE_ANY, REG_TYPE_UINT64, "general", "org.gnu.gdb.aarch64.core", NULL},
1203 { ARMV8_R10, "x10", 64, ARM_MODE_ANY, REG_TYPE_UINT64, "general", "org.gnu.gdb.aarch64.core", NULL},
1204 { ARMV8_R11, "x11", 64, ARM_MODE_ANY, REG_TYPE_UINT64, "general", "org.gnu.gdb.aarch64.core", NULL},
1205 { ARMV8_R12, "x12", 64, ARM_MODE_ANY, REG_TYPE_UINT64, "general", "org.gnu.gdb.aarch64.core", NULL},
1206 { ARMV8_R13, "x13", 64, ARM_MODE_ANY, REG_TYPE_UINT64, "general", "org.gnu.gdb.aarch64.core", NULL},
1207 { ARMV8_R14, "x14", 64, ARM_MODE_ANY, REG_TYPE_UINT64, "general", "org.gnu.gdb.aarch64.core", NULL},
1208 { ARMV8_R15, "x15", 64, ARM_MODE_ANY, REG_TYPE_UINT64, "general", "org.gnu.gdb.aarch64.core", NULL},
1209 { ARMV8_R16, "x16", 64, ARM_MODE_ANY, REG_TYPE_UINT64, "general", "org.gnu.gdb.aarch64.core", NULL},
1210 { ARMV8_R17, "x17", 64, ARM_MODE_ANY, REG_TYPE_UINT64, "general", "org.gnu.gdb.aarch64.core", NULL},
1211 { ARMV8_R18, "x18", 64, ARM_MODE_ANY, REG_TYPE_UINT64, "general", "org.gnu.gdb.aarch64.core", NULL},
1212 { ARMV8_R19, "x19", 64, ARM_MODE_ANY, REG_TYPE_UINT64, "general", "org.gnu.gdb.aarch64.core", NULL},
1213 { ARMV8_R20, "x20", 64, ARM_MODE_ANY, REG_TYPE_UINT64, "general", "org.gnu.gdb.aarch64.core", NULL},
1214 { ARMV8_R21, "x21", 64, ARM_MODE_ANY, REG_TYPE_UINT64, "general", "org.gnu.gdb.aarch64.core", NULL},
1215 { ARMV8_R22, "x22", 64, ARM_MODE_ANY, REG_TYPE_UINT64, "general", "org.gnu.gdb.aarch64.core", NULL},
1216 { ARMV8_R23, "x23", 64, ARM_MODE_ANY, REG_TYPE_UINT64, "general", "org.gnu.gdb.aarch64.core", NULL},
1217 { ARMV8_R24, "x24", 64, ARM_MODE_ANY, REG_TYPE_UINT64, "general", "org.gnu.gdb.aarch64.core", NULL},
1218 { ARMV8_R25, "x25", 64, ARM_MODE_ANY, REG_TYPE_UINT64, "general", "org.gnu.gdb.aarch64.core", NULL},
1219 { ARMV8_R26, "x26", 64, ARM_MODE_ANY, REG_TYPE_UINT64, "general", "org.gnu.gdb.aarch64.core", NULL},
1220 { ARMV8_R27, "x27", 64, ARM_MODE_ANY, REG_TYPE_UINT64, "general", "org.gnu.gdb.aarch64.core", NULL},
1221 { ARMV8_R28, "x28", 64, ARM_MODE_ANY, REG_TYPE_UINT64, "general", "org.gnu.gdb.aarch64.core", NULL},
1222 { ARMV8_R29, "x29", 64, ARM_MODE_ANY, REG_TYPE_UINT64, "general", "org.gnu.gdb.aarch64.core", NULL},
1223 { ARMV8_R30, "x30", 64, ARM_MODE_ANY, REG_TYPE_UINT64, "general", "org.gnu.gdb.aarch64.core", NULL},
1224
1225 { ARMV8_SP, "sp", 64, ARM_MODE_ANY, REG_TYPE_DATA_PTR, "general", "org.gnu.gdb.aarch64.core", NULL},
1226 { ARMV8_PC, "pc", 64, ARM_MODE_ANY, REG_TYPE_CODE_PTR, "general", "org.gnu.gdb.aarch64.core", NULL},
1227
1228 { ARMV8_xPSR, "CPSR", 32, ARM_MODE_ANY, REG_TYPE_UINT32, "general", "org.gnu.gdb.aarch64.core", NULL},
1229
1230 { ARMV8_V0, "v0", 128, ARM_MODE_ANY, REG_TYPE_ARCH_DEFINED, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v},
1231 { ARMV8_V1, "v1", 128, ARM_MODE_ANY, REG_TYPE_ARCH_DEFINED, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v},
1232 { ARMV8_V2, "v2", 128, ARM_MODE_ANY, REG_TYPE_ARCH_DEFINED, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v},
1233 { ARMV8_V3, "v3", 128, ARM_MODE_ANY, REG_TYPE_ARCH_DEFINED, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v},
1234 { ARMV8_V4, "v4", 128, ARM_MODE_ANY, REG_TYPE_ARCH_DEFINED, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v},
1235 { ARMV8_V5, "v5", 128, ARM_MODE_ANY, REG_TYPE_ARCH_DEFINED, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v},
1236 { ARMV8_V6, "v6", 128, ARM_MODE_ANY, REG_TYPE_ARCH_DEFINED, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v},
1237 { ARMV8_V7, "v7", 128, ARM_MODE_ANY, REG_TYPE_ARCH_DEFINED, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v},
1238 { ARMV8_V8, "v8", 128, ARM_MODE_ANY, REG_TYPE_ARCH_DEFINED, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v},
1239 { ARMV8_V9, "v9", 128, ARM_MODE_ANY, REG_TYPE_ARCH_DEFINED, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v},
1240 { ARMV8_V10, "v10", 128, ARM_MODE_ANY, REG_TYPE_ARCH_DEFINED, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v},
1241 { ARMV8_V11, "v11", 128, ARM_MODE_ANY, REG_TYPE_ARCH_DEFINED, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v},
1242 { ARMV8_V12, "v12", 128, ARM_MODE_ANY, REG_TYPE_ARCH_DEFINED, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v},
1243 { ARMV8_V13, "v13", 128, ARM_MODE_ANY, REG_TYPE_ARCH_DEFINED, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v},
1244 { ARMV8_V14, "v14", 128, ARM_MODE_ANY, REG_TYPE_ARCH_DEFINED, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v},
1245 { ARMV8_V15, "v15", 128, ARM_MODE_ANY, REG_TYPE_ARCH_DEFINED, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v},
1246 { ARMV8_V16, "v16", 128, ARM_MODE_ANY, REG_TYPE_ARCH_DEFINED, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v},
1247 { ARMV8_V17, "v17", 128, ARM_MODE_ANY, REG_TYPE_ARCH_DEFINED, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v},
1248 { ARMV8_V18, "v18", 128, ARM_MODE_ANY, REG_TYPE_ARCH_DEFINED, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v},
1249 { ARMV8_V19, "v19", 128, ARM_MODE_ANY, REG_TYPE_ARCH_DEFINED, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v},
1250 { ARMV8_V20, "v20", 128, ARM_MODE_ANY, REG_TYPE_ARCH_DEFINED, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v},
1251 { ARMV8_V21, "v21", 128, ARM_MODE_ANY, REG_TYPE_ARCH_DEFINED, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v},
1252 { ARMV8_V22, "v22", 128, ARM_MODE_ANY, REG_TYPE_ARCH_DEFINED, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v},
1253 { ARMV8_V23, "v23", 128, ARM_MODE_ANY, REG_TYPE_ARCH_DEFINED, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v},
1254 { ARMV8_V24, "v24", 128, ARM_MODE_ANY, REG_TYPE_ARCH_DEFINED, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v},
1255 { ARMV8_V25, "v25", 128, ARM_MODE_ANY, REG_TYPE_ARCH_DEFINED, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v},
1256 { ARMV8_V26, "v26", 128, ARM_MODE_ANY, REG_TYPE_ARCH_DEFINED, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v},
1257 { ARMV8_V27, "v27", 128, ARM_MODE_ANY, REG_TYPE_ARCH_DEFINED, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v},
1258 { ARMV8_V28, "v28", 128, ARM_MODE_ANY, REG_TYPE_ARCH_DEFINED, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v},
1259 { ARMV8_V29, "v29", 128, ARM_MODE_ANY, REG_TYPE_ARCH_DEFINED, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v},
1260 { ARMV8_V30, "v30", 128, ARM_MODE_ANY, REG_TYPE_ARCH_DEFINED, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v},
1261 { ARMV8_V31, "v31", 128, ARM_MODE_ANY, REG_TYPE_ARCH_DEFINED, "simdfp", "org.gnu.gdb.aarch64.fpu", aarch64v},
1262 { ARMV8_FPSR, "fpsr", 32, ARM_MODE_ANY, REG_TYPE_UINT32, "simdfp", "org.gnu.gdb.aarch64.fpu", NULL},
1263 { ARMV8_FPCR, "fpcr", 32, ARM_MODE_ANY, REG_TYPE_UINT32, "simdfp", "org.gnu.gdb.aarch64.fpu", NULL},
1264
1265 { ARMV8_ELR_EL1, "ELR_EL1", 64, ARMV8_64_EL1H, REG_TYPE_CODE_PTR, "banked", "net.sourceforge.openocd.banked",
1266 NULL},
1267 { ARMV8_ESR_EL1, "ESR_EL1", 32, ARMV8_64_EL1H, REG_TYPE_UINT32, "banked", "net.sourceforge.openocd.banked",
1268 NULL},
1269 { ARMV8_SPSR_EL1, "SPSR_EL1", 32, ARMV8_64_EL1H, REG_TYPE_UINT32, "banked", "net.sourceforge.openocd.banked",
1270 NULL},
1271
1272 { ARMV8_ELR_EL2, "ELR_EL2", 64, ARMV8_64_EL2H, REG_TYPE_CODE_PTR, "banked", "net.sourceforge.openocd.banked",
1273 NULL},
1274 { ARMV8_ESR_EL2, "ESR_EL2", 32, ARMV8_64_EL2H, REG_TYPE_UINT32, "banked", "net.sourceforge.openocd.banked",
1275 NULL},
1276 { ARMV8_SPSR_EL2, "SPSR_EL2", 32, ARMV8_64_EL2H, REG_TYPE_UINT32, "banked", "net.sourceforge.openocd.banked",
1277 NULL},
1278
1279 { ARMV8_ELR_EL3, "ELR_EL3", 64, ARMV8_64_EL3H, REG_TYPE_CODE_PTR, "banked", "net.sourceforge.openocd.banked",
1280 NULL},
1281 { ARMV8_ESR_EL3, "ESR_EL3", 32, ARMV8_64_EL3H, REG_TYPE_UINT32, "banked", "net.sourceforge.openocd.banked",
1282 NULL},
1283 { ARMV8_SPSR_EL3, "SPSR_EL3", 32, ARMV8_64_EL3H, REG_TYPE_UINT32, "banked", "net.sourceforge.openocd.banked",
1284 NULL},
1285 };
1286
1287 static const struct {
1288 unsigned id;
1289 unsigned mapping;
1290 const char *name;
1291 unsigned bits;
1292 enum arm_mode mode;
1293 enum reg_type type;
1294 const char *group;
1295 const char *feature;
1296 } armv8_regs32[] = {
1297 { ARMV8_R0, 0, "r0", 32, ARM_MODE_ANY, REG_TYPE_UINT32, "general", "org.gnu.gdb.arm.core" },
1298 { ARMV8_R1, 0, "r1", 32, ARM_MODE_ANY, REG_TYPE_UINT32, "general", "org.gnu.gdb.arm.core" },
1299 { ARMV8_R2, 0, "r2", 32, ARM_MODE_ANY, REG_TYPE_UINT32, "general", "org.gnu.gdb.arm.core" },
1300 { ARMV8_R3, 0, "r3", 32, ARM_MODE_ANY, REG_TYPE_UINT32, "general", "org.gnu.gdb.arm.core" },
1301 { ARMV8_R4, 0, "r4", 32, ARM_MODE_ANY, REG_TYPE_UINT32, "general", "org.gnu.gdb.arm.core" },
1302 { ARMV8_R5, 0, "r5", 32, ARM_MODE_ANY, REG_TYPE_UINT32, "general", "org.gnu.gdb.arm.core" },
1303 { ARMV8_R6, 0, "r6", 32, ARM_MODE_ANY, REG_TYPE_UINT32, "general", "org.gnu.gdb.arm.core" },
1304 { ARMV8_R7, 0, "r7", 32, ARM_MODE_ANY, REG_TYPE_UINT32, "general", "org.gnu.gdb.arm.core" },
1305 { ARMV8_R8, 0, "r8", 32, ARM_MODE_ANY, REG_TYPE_UINT32, "general", "org.gnu.gdb.arm.core" },
1306 { ARMV8_R9, 0, "r9", 32, ARM_MODE_ANY, REG_TYPE_UINT32, "general", "org.gnu.gdb.arm.core" },
1307 { ARMV8_R10, 0, "r10", 32, ARM_MODE_ANY, REG_TYPE_UINT32, "general", "org.gnu.gdb.arm.core" },
1308 { ARMV8_R11, 0, "r11", 32, ARM_MODE_ANY, REG_TYPE_UINT32, "general", "org.gnu.gdb.arm.core" },
1309 { ARMV8_R12, 0, "r12", 32, ARM_MODE_ANY, REG_TYPE_UINT32, "general", "org.gnu.gdb.arm.core" },
1310 { ARMV8_R13, 0, "sp", 32, ARM_MODE_ANY, REG_TYPE_DATA_PTR, "general", "org.gnu.gdb.arm.core" },
1311 { ARMV8_R14, 0, "lr", 32, ARM_MODE_ANY, REG_TYPE_CODE_PTR, "general", "org.gnu.gdb.arm.core" },
1312 { ARMV8_PC, 0, "pc", 32, ARM_MODE_ANY, REG_TYPE_CODE_PTR, "general", "org.gnu.gdb.arm.core" },
1313 { ARMV8_xPSR, 0, "cpsr", 32, ARM_MODE_ANY, REG_TYPE_UINT32, "general", "org.gnu.gdb.arm.core" },
1314 { ARMV8_V0, 0, "d0", 64, ARM_MODE_ANY, REG_TYPE_IEEE_DOUBLE, NULL, "org.gnu.gdb.arm.vfp"},
1315 { ARMV8_V0, 8, "d1", 64, ARM_MODE_ANY, REG_TYPE_IEEE_DOUBLE, NULL, "org.gnu.gdb.arm.vfp"},
1316 { ARMV8_V1, 0, "d2", 64, ARM_MODE_ANY, REG_TYPE_IEEE_DOUBLE, NULL, "org.gnu.gdb.arm.vfp"},
1317 { ARMV8_V1, 8, "d3", 64, ARM_MODE_ANY, REG_TYPE_IEEE_DOUBLE, NULL, "org.gnu.gdb.arm.vfp"},
1318 { ARMV8_V2, 0, "d4", 64, ARM_MODE_ANY, REG_TYPE_IEEE_DOUBLE, NULL, "org.gnu.gdb.arm.vfp"},
1319 { ARMV8_V2, 8, "d5", 64, ARM_MODE_ANY, REG_TYPE_IEEE_DOUBLE, NULL, "org.gnu.gdb.arm.vfp"},
1320 { ARMV8_V3, 0, "d6", 64, ARM_MODE_ANY, REG_TYPE_IEEE_DOUBLE, NULL, "org.gnu.gdb.arm.vfp"},
1321 { ARMV8_V3, 8, "d7", 64, ARM_MODE_ANY, REG_TYPE_IEEE_DOUBLE, NULL, "org.gnu.gdb.arm.vfp"},
1322 { ARMV8_V4, 0, "d8", 64, ARM_MODE_ANY, REG_TYPE_IEEE_DOUBLE, NULL, "org.gnu.gdb.arm.vfp"},
1323 { ARMV8_V4, 8, "d9", 64, ARM_MODE_ANY, REG_TYPE_IEEE_DOUBLE, NULL, "org.gnu.gdb.arm.vfp"},
1324 { ARMV8_V5, 0, "d10", 64, ARM_MODE_ANY, REG_TYPE_IEEE_DOUBLE, NULL, "org.gnu.gdb.arm.vfp"},
1325 { ARMV8_V5, 8, "d11", 64, ARM_MODE_ANY, REG_TYPE_IEEE_DOUBLE, NULL, "org.gnu.gdb.arm.vfp"},
1326 { ARMV8_V6, 0, "d12", 64, ARM_MODE_ANY, REG_TYPE_IEEE_DOUBLE, NULL, "org.gnu.gdb.arm.vfp"},
1327 { ARMV8_V6, 8, "d13", 64, ARM_MODE_ANY, REG_TYPE_IEEE_DOUBLE, NULL, "org.gnu.gdb.arm.vfp"},
1328 { ARMV8_V7, 0, "d14", 64, ARM_MODE_ANY, REG_TYPE_IEEE_DOUBLE, NULL, "org.gnu.gdb.arm.vfp"},
1329 { ARMV8_V7, 8, "d15", 64, ARM_MODE_ANY, REG_TYPE_IEEE_DOUBLE, NULL, "org.gnu.gdb.arm.vfp"},
1330 { ARMV8_V8, 0, "d16", 64, ARM_MODE_ANY, REG_TYPE_IEEE_DOUBLE, NULL, "org.gnu.gdb.arm.vfp"},
1331 { ARMV8_V8, 8, "d17", 64, ARM_MODE_ANY, REG_TYPE_IEEE_DOUBLE, NULL, "org.gnu.gdb.arm.vfp"},
1332 { ARMV8_V9, 0, "d18", 64, ARM_MODE_ANY, REG_TYPE_IEEE_DOUBLE, NULL, "org.gnu.gdb.arm.vfp"},
1333 { ARMV8_V9, 8, "d19", 64, ARM_MODE_ANY, REG_TYPE_IEEE_DOUBLE, NULL, "org.gnu.gdb.arm.vfp"},
1334 { ARMV8_V10, 0, "d20", 64, ARM_MODE_ANY, REG_TYPE_IEEE_DOUBLE, NULL, "org.gnu.gdb.arm.vfp"},
1335 { ARMV8_V10, 8, "d21", 64, ARM_MODE_ANY, REG_TYPE_IEEE_DOUBLE, NULL, "org.gnu.gdb.arm.vfp"},
1336 { ARMV8_V11, 0, "d22", 64, ARM_MODE_ANY, REG_TYPE_IEEE_DOUBLE, NULL, "org.gnu.gdb.arm.vfp"},
1337 { ARMV8_V11, 8, "d23", 64, ARM_MODE_ANY, REG_TYPE_IEEE_DOUBLE, NULL, "org.gnu.gdb.arm.vfp"},
1338 { ARMV8_V12, 0, "d24", 64, ARM_MODE_ANY, REG_TYPE_IEEE_DOUBLE, NULL, "org.gnu.gdb.arm.vfp"},
1339 { ARMV8_V12, 8, "d25", 64, ARM_MODE_ANY, REG_TYPE_IEEE_DOUBLE, NULL, "org.gnu.gdb.arm.vfp"},
1340 { ARMV8_V13, 0, "d26", 64, ARM_MODE_ANY, REG_TYPE_IEEE_DOUBLE, NULL, "org.gnu.gdb.arm.vfp"},
1341 { ARMV8_V13, 8, "d27", 64, ARM_MODE_ANY, REG_TYPE_IEEE_DOUBLE, NULL, "org.gnu.gdb.arm.vfp"},
1342 { ARMV8_V14, 0, "d28", 64, ARM_MODE_ANY, REG_TYPE_IEEE_DOUBLE, NULL, "org.gnu.gdb.arm.vfp"},
1343 { ARMV8_V14, 8, "d29", 64, ARM_MODE_ANY, REG_TYPE_IEEE_DOUBLE, NULL, "org.gnu.gdb.arm.vfp"},
1344 { ARMV8_V15, 0, "d30", 64, ARM_MODE_ANY, REG_TYPE_IEEE_DOUBLE, NULL, "org.gnu.gdb.arm.vfp"},
1345 { ARMV8_V15, 8, "d31", 64, ARM_MODE_ANY, REG_TYPE_IEEE_DOUBLE, NULL, "org.gnu.gdb.arm.vfp"},
1346 { ARMV8_FPSR, 0, "fpscr", 32, ARM_MODE_ANY, REG_TYPE_UINT32, "float", "org.gnu.gdb.arm.vfp"},
1347 };
1348
1349 #define ARMV8_NUM_REGS ARRAY_SIZE(armv8_regs)
1350 #define ARMV8_NUM_REGS32 ARRAY_SIZE(armv8_regs32)
1351
1352 static int armv8_get_core_reg(struct reg *reg)
1353 {
1354 struct arm_reg *armv8_reg = reg->arch_info;
1355 struct target *target = armv8_reg->target;
1356 struct arm *arm = target_to_arm(target);
1357
1358 if (target->state != TARGET_HALTED)
1359 return ERROR_TARGET_NOT_HALTED;
1360
1361 return arm->read_core_reg(target, reg, armv8_reg->num, arm->core_mode);
1362 }
1363
1364 static int armv8_set_core_reg(struct reg *reg, uint8_t *buf)
1365 {
1366 struct arm_reg *armv8_reg = reg->arch_info;
1367 struct target *target = armv8_reg->target;
1368 struct arm *arm = target_to_arm(target);
1369 uint64_t value = buf_get_u64(buf, 0, reg->size);
1370
1371 if (target->state != TARGET_HALTED)
1372 return ERROR_TARGET_NOT_HALTED;
1373
1374 if (reg->size <= 64) {
1375 if (reg == arm->cpsr)
1376 armv8_set_cpsr(arm, (uint32_t)value);
1377 else {
1378 buf_set_u64(reg->value, 0, reg->size, value);
1379 reg->valid = 1;
1380 }
1381 } else if (reg->size <= 128) {
1382 uint64_t hvalue = buf_get_u64(buf + 8, 0, reg->size - 64);
1383
1384 buf_set_u64(reg->value, 0, 64, value);
1385 buf_set_u64(reg->value + 8, 0, reg->size - 64, hvalue);
1386 reg->valid = 1;
1387 }
1388
1389 reg->dirty = 1;
1390
1391 return ERROR_OK;
1392 }
1393
1394 static const struct reg_arch_type armv8_reg_type = {
1395 .get = armv8_get_core_reg,
1396 .set = armv8_set_core_reg,
1397 };
1398
1399 static int armv8_get_core_reg32(struct reg *reg)
1400 {
1401 struct arm_reg *armv8_reg = reg->arch_info;
1402 struct target *target = armv8_reg->target;
1403 struct arm *arm = target_to_arm(target);
1404 struct reg_cache *cache = arm->core_cache;
1405 struct reg *reg64;
1406 int retval;
1407
1408 /* get the corresponding Aarch64 register */
1409 reg64 = cache->reg_list + armv8_reg->num;
1410 if (reg64->valid) {
1411 reg->valid = true;
1412 return ERROR_OK;
1413 }
1414
1415 retval = arm->read_core_reg(target, reg64, armv8_reg->num, arm->core_mode);
1416 if (retval == ERROR_OK)
1417 reg->valid = reg64->valid;
1418
1419 return retval;
1420 }
1421
1422 static int armv8_set_core_reg32(struct reg *reg, uint8_t *buf)
1423 {
1424 struct arm_reg *armv8_reg = reg->arch_info;
1425 struct target *target = armv8_reg->target;
1426 struct arm *arm = target_to_arm(target);
1427 struct reg_cache *cache = arm->core_cache;
1428 struct reg *reg64 = cache->reg_list + armv8_reg->num;
1429 uint32_t value = buf_get_u32(buf, 0, 32);
1430
1431 if (reg64 == arm->cpsr) {
1432 armv8_set_cpsr(arm, value);
1433 } else {
1434 if (reg->size <= 32)
1435 buf_set_u32(reg->value, 0, 32, value);
1436 else if (reg->size <= 64) {
1437 uint64_t value64 = buf_get_u64(buf, 0, 64);
1438 buf_set_u64(reg->value, 0, 64, value64);
1439 }
1440 reg->valid = 1;
1441 reg64->valid = 1;
1442 }
1443
1444 reg64->dirty = 1;
1445
1446 return ERROR_OK;
1447 }
1448
1449 static const struct reg_arch_type armv8_reg32_type = {
1450 .get = armv8_get_core_reg32,
1451 .set = armv8_set_core_reg32,
1452 };
1453
1454 /** Builds cache of architecturally defined registers. */
1455 struct reg_cache *armv8_build_reg_cache(struct target *target)
1456 {
1457 struct armv8_common *armv8 = target_to_armv8(target);
1458 struct arm *arm = &armv8->arm;
1459 int num_regs = ARMV8_NUM_REGS;
1460 int num_regs32 = ARMV8_NUM_REGS32;
1461 struct reg_cache **cache_p = register_get_last_cache_p(&target->reg_cache);
1462 struct reg_cache *cache = malloc(sizeof(struct reg_cache));
1463 struct reg_cache *cache32 = malloc(sizeof(struct reg_cache));
1464 struct reg *reg_list = calloc(num_regs, sizeof(struct reg));
1465 struct reg *reg_list32 = calloc(num_regs32, sizeof(struct reg));
1466 struct arm_reg *arch_info = calloc(num_regs, sizeof(struct arm_reg));
1467 struct reg_feature *feature;
1468 int i;
1469
1470 /* Build the process context cache */
1471 cache->name = "Aarch64 registers";
1472 cache->next = cache32;
1473 cache->reg_list = reg_list;
1474 cache->num_regs = num_regs;
1475
1476 for (i = 0; i < num_regs; i++) {
1477 arch_info[i].num = armv8_regs[i].id;
1478 arch_info[i].mode = armv8_regs[i].mode;
1479 arch_info[i].target = target;
1480 arch_info[i].arm = arm;
1481
1482 reg_list[i].name = armv8_regs[i].name;
1483 reg_list[i].size = armv8_regs[i].bits;
1484 reg_list[i].value = &arch_info[i].value[0];
1485 reg_list[i].type = &armv8_reg_type;
1486 reg_list[i].arch_info = &arch_info[i];
1487
1488 reg_list[i].group = armv8_regs[i].group;
1489 reg_list[i].number = i;
1490 reg_list[i].exist = true;
1491 reg_list[i].caller_save = true; /* gdb defaults to true */
1492
1493 feature = calloc(1, sizeof(struct reg_feature));
1494 if (feature) {
1495 feature->name = armv8_regs[i].feature;
1496 reg_list[i].feature = feature;
1497 } else
1498 LOG_ERROR("unable to allocate feature list");
1499
1500 if (armv8_regs[i].data_type == NULL) {
1501 reg_list[i].reg_data_type = calloc(1, sizeof(struct reg_data_type));
1502 if (reg_list[i].reg_data_type)
1503 reg_list[i].reg_data_type->type = armv8_regs[i].type;
1504 else
1505 LOG_ERROR("unable to allocate reg type list");
1506 } else
1507 reg_list[i].reg_data_type = armv8_regs[i].data_type;
1508
1509 }
1510
1511 arm->cpsr = reg_list + ARMV8_xPSR;
1512 arm->pc = reg_list + ARMV8_PC;
1513 arm->core_cache = cache;
1514
1515 /* shadow cache for ARM mode registers */
1516 cache32->name = "Aarch32 registers";
1517 cache32->next = NULL;
1518 cache32->reg_list = reg_list32;
1519 cache32->num_regs = num_regs32;
1520
1521 for (i = 0; i < num_regs32; i++) {
1522 reg_list32[i].name = armv8_regs32[i].name;
1523 reg_list32[i].size = armv8_regs32[i].bits;
1524 reg_list32[i].value = &arch_info[armv8_regs32[i].id].value[armv8_regs32[i].mapping];
1525 reg_list32[i].type = &armv8_reg32_type;
1526 reg_list32[i].arch_info = &arch_info[armv8_regs32[i].id];
1527 reg_list32[i].group = armv8_regs32[i].group;
1528 reg_list32[i].number = i;
1529 reg_list32[i].exist = true;
1530 reg_list32[i].caller_save = true;
1531
1532 feature = calloc(1, sizeof(struct reg_feature));
1533 if (feature) {
1534 feature->name = armv8_regs32[i].feature;
1535 reg_list32[i].feature = feature;
1536 } else
1537 LOG_ERROR("unable to allocate feature list");
1538
1539 reg_list32[i].reg_data_type = calloc(1, sizeof(struct reg_data_type));
1540 if (reg_list32[i].reg_data_type)
1541 reg_list32[i].reg_data_type->type = armv8_regs32[i].type;
1542 else
1543 LOG_ERROR("unable to allocate reg type list");
1544 }
1545
1546 (*cache_p) = cache;
1547 return cache;
1548 }
1549
1550 struct reg *armv8_reg_current(struct arm *arm, unsigned regnum)
1551 {
1552 struct reg *r;
1553
1554 if (regnum > (ARMV8_LAST_REG - 1))
1555 return NULL;
1556
1557 r = arm->core_cache->reg_list + regnum;
1558 return r;
1559 }
1560
1561 const struct command_registration armv8_command_handlers[] = {
1562 {
1563 .chain = dap_command_handlers,
1564 },
1565 COMMAND_REGISTRATION_DONE
1566 };
1567
1568
1569 int armv8_get_gdb_reg_list(struct target *target,
1570 struct reg **reg_list[], int *reg_list_size,
1571 enum target_register_class reg_class)
1572 {
1573 struct arm *arm = target_to_arm(target);
1574 int i;
1575
1576 if (arm->core_state == ARM_STATE_AARCH64) {
1577
1578 LOG_DEBUG("Creating Aarch64 register list for target %s", target_name(target));
1579
1580 switch (reg_class) {
1581 case REG_CLASS_GENERAL:
1582 *reg_list_size = ARMV8_V0;
1583 *reg_list = malloc(sizeof(struct reg *) * (*reg_list_size));
1584
1585 for (i = 0; i < *reg_list_size; i++)
1586 (*reg_list)[i] = armv8_reg_current(arm, i);
1587 return ERROR_OK;
1588
1589 case REG_CLASS_ALL:
1590 *reg_list_size = ARMV8_LAST_REG;
1591 *reg_list = malloc(sizeof(struct reg *) * (*reg_list_size));
1592
1593 for (i = 0; i < *reg_list_size; i++)
1594 (*reg_list)[i] = armv8_reg_current(arm, i);
1595
1596 return ERROR_OK;
1597
1598 default:
1599 LOG_ERROR("not a valid register class type in query.");
1600 return ERROR_FAIL;
1601 }
1602 } else {
1603 struct reg_cache *cache32 = arm->core_cache->next;
1604
1605 LOG_DEBUG("Creating Aarch32 register list for target %s", target_name(target));
1606
1607 switch (reg_class) {
1608 case REG_CLASS_GENERAL:
1609 *reg_list_size = ARMV8_R14 + 3;
1610 *reg_list = malloc(sizeof(struct reg *) * (*reg_list_size));
1611
1612 for (i = 0; i < *reg_list_size; i++)
1613 (*reg_list)[i] = cache32->reg_list + i;
1614
1615 return ERROR_OK;
1616 case REG_CLASS_ALL:
1617 *reg_list_size = cache32->num_regs;
1618 *reg_list = malloc(sizeof(struct reg *) * (*reg_list_size));
1619
1620 for (i = 0; i < *reg_list_size; i++)
1621 (*reg_list)[i] = cache32->reg_list + i;
1622
1623 return ERROR_OK;
1624 default:
1625 LOG_ERROR("not a valid register class type in query.");
1626 return ERROR_FAIL;
1627 }
1628 }
1629 }
1630
1631 int armv8_set_dbgreg_bits(struct armv8_common *armv8, unsigned int reg, unsigned long mask, unsigned long value)
1632 {
1633 uint32_t tmp;
1634
1635 /* Read register */
1636 int retval = mem_ap_read_atomic_u32(armv8->debug_ap,
1637 armv8->debug_base + reg, &tmp);
1638 if (ERROR_OK != retval)
1639 return retval;
1640
1641 /* clear bitfield */
1642 tmp &= ~mask;
1643 /* put new value */
1644 tmp |= value & mask;
1645
1646 /* write new value */
1647 retval = mem_ap_write_atomic_u32(armv8->debug_ap,
1648 armv8->debug_base + reg, tmp);
1649 return retval;
1650 }

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)