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

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)