armv8: spelling and formatting updates
[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 #define __unused __attribute__((unused))
41
42 static const char * const armv8_state_strings[] = {
43 "AArch32", "Thumb", "Jazelle", "ThumbEE", "AArch64",
44 };
45
46 static const struct {
47 const char *name;
48 unsigned psr;
49 } armv8_mode_data[] = {
50 /* These special modes are currently only supported
51 * by ARMv6M and ARMv7M profiles */
52 {
53 .name = "USR",
54 .psr = ARM_MODE_USR,
55 },
56 {
57 .name = "FIQ",
58 .psr = ARM_MODE_FIQ,
59 },
60 {
61 .name = "IRQ",
62 .psr = ARM_MODE_IRQ,
63 },
64 {
65 .name = "SVC",
66 .psr = ARM_MODE_SVC,
67 },
68 {
69 .name = "MON",
70 .psr = ARM_MODE_MON,
71 },
72 {
73 .name = "ABT",
74 .psr = ARM_MODE_ABT,
75 },
76 {
77 .name = "EL0T",
78 .psr = ARMV8_64_EL0T,
79 },
80 {
81 .name = "EL1T",
82 .psr = ARMV8_64_EL1T,
83 },
84 {
85 .name = "EL1H",
86 .psr = ARMV8_64_EL1H,
87 },
88 {
89 .name = "EL2T",
90 .psr = ARMV8_64_EL2T,
91 },
92 {
93 .name = "EL2H",
94 .psr = ARMV8_64_EL2H,
95 },
96 {
97 .name = "EL3T",
98 .psr = ARMV8_64_EL3T,
99 },
100 {
101 .name = "EL3H",
102 .psr = ARMV8_64_EL3H,
103 },
104 };
105
106 /** Map PSR mode bits to the name of an ARM processor operating mode. */
107 const char *armv8_mode_name(unsigned psr_mode)
108 {
109 for (unsigned i = 0; i < ARRAY_SIZE(armv8_mode_data); i++) {
110 if (armv8_mode_data[i].psr == psr_mode)
111 return armv8_mode_data[i].name;
112 }
113 LOG_ERROR("unrecognized psr mode: %#02x", psr_mode);
114 return "UNRECOGNIZED";
115 }
116
117 int armv8_mode_to_number(enum arm_mode mode)
118 {
119 switch (mode) {
120 case ARM_MODE_ANY:
121 /* map MODE_ANY to user mode */
122 case ARM_MODE_USR:
123 return 0;
124 case ARM_MODE_FIQ:
125 return 1;
126 case ARM_MODE_IRQ:
127 return 2;
128 case ARM_MODE_SVC:
129 return 3;
130 case ARM_MODE_ABT:
131 return 4;
132 case ARM_MODE_UND:
133 return 5;
134 case ARM_MODE_SYS:
135 return 6;
136 case ARM_MODE_MON:
137 return 7;
138 case ARMV8_64_EL0T:
139 return 8;
140 case ARMV8_64_EL1T:
141 return 9;
142 case ARMV8_64_EL1H:
143 return 10;
144 case ARMV8_64_EL2T:
145 return 11;
146 case ARMV8_64_EL2H:
147 return 12;
148 case ARMV8_64_EL3T:
149 return 13;
150 case ARMV8_64_EL3H:
151 return 14;
152
153 default:
154 LOG_ERROR("invalid mode value encountered %d", mode);
155 return -1;
156 }
157 }
158
159 static int armv8_read_reg(struct armv8_common *armv8, int regnum, uint64_t *regval)
160 {
161 struct arm_dpm *dpm = &armv8->dpm;
162 int retval;
163 uint32_t value;
164 uint64_t value_64;
165
166 switch (regnum) {
167 case 0 ... 30:
168 retval = dpm->instr_read_data_dcc_64(dpm,
169 ARMV8_MSR_GP(SYSTEM_DBG_DBGDTR_EL0, regnum), &value_64);
170 break;
171 case ARMV8_SP:
172 retval = dpm->instr_read_data_r0_64(dpm,
173 ARMV8_MOVFSP_64(0), &value_64);
174 break;
175 case ARMV8_PC:
176 retval = dpm->instr_read_data_r0_64(dpm,
177 ARMV8_MRS_DLR(0), &value_64);
178 break;
179 case ARMV8_xPSR:
180 retval = dpm->instr_read_data_r0(dpm,
181 ARMV8_MRS_DSPSR(0), &value);
182 value_64 = value;
183 break;
184 case ARMV8_ELR_EL1:
185 retval = dpm->instr_read_data_r0_64(dpm,
186 ARMV8_MRS(SYSTEM_ELR_EL1, 0), &value_64);
187 break;
188 case ARMV8_ELR_EL2:
189 retval = dpm->instr_read_data_r0_64(dpm,
190 ARMV8_MRS(SYSTEM_ELR_EL2, 0), &value_64);
191 break;
192 case ARMV8_ELR_EL3:
193 retval = dpm->instr_read_data_r0_64(dpm,
194 ARMV8_MRS(SYSTEM_ELR_EL3, 0), &value_64);
195 break;
196 case ARMV8_ESR_EL1:
197 retval = dpm->instr_read_data_r0(dpm,
198 ARMV8_MRS(SYSTEM_ESR_EL1, 0), &value);
199 value_64 = value;
200 break;
201 case ARMV8_ESR_EL2:
202 retval = dpm->instr_read_data_r0(dpm,
203 ARMV8_MRS(SYSTEM_ESR_EL2, 0), &value);
204 value_64 = value;
205 break;
206 case ARMV8_ESR_EL3:
207 retval = dpm->instr_read_data_r0(dpm,
208 ARMV8_MRS(SYSTEM_ESR_EL3, 0), &value);
209 value_64 = value;
210 break;
211 case ARMV8_SPSR_EL1:
212 retval = dpm->instr_read_data_r0(dpm,
213 ARMV8_MRS(SYSTEM_SPSR_EL1, 0), &value);
214 value_64 = value;
215 break;
216 case ARMV8_SPSR_EL2:
217 retval = dpm->instr_read_data_r0(dpm,
218 ARMV8_MRS(SYSTEM_SPSR_EL2, 0), &value);
219 value_64 = value;
220 break;
221 case ARMV8_SPSR_EL3:
222 retval = dpm->instr_read_data_r0(dpm,
223 ARMV8_MRS(SYSTEM_SPSR_EL3, 0), &value);
224 value_64 = value;
225 break;
226 default:
227 retval = ERROR_FAIL;
228 break;
229 }
230
231 if (retval == ERROR_OK && regval != NULL)
232 *regval = value_64;
233
234 return retval;
235 }
236
237 static int armv8_write_reg(struct armv8_common *armv8, int regnum, uint64_t value_64)
238 {
239 struct arm_dpm *dpm = &armv8->dpm;
240 int retval;
241 uint32_t value;
242
243 switch (regnum) {
244 case 0 ... 30:
245 retval = dpm->instr_write_data_dcc_64(dpm,
246 ARMV8_MRS(SYSTEM_DBG_DBGDTR_EL0, regnum),
247 value_64);
248 break;
249 case ARMV8_SP:
250 retval = dpm->instr_write_data_r0_64(dpm,
251 ARMV8_MOVTSP_64(0),
252 value_64);
253 break;
254 case ARMV8_PC:
255 retval = dpm->instr_write_data_r0_64(dpm,
256 ARMV8_MSR_DLR(0),
257 value_64);
258 break;
259 case ARMV8_xPSR:
260 value = value_64;
261 retval = dpm->instr_write_data_r0(dpm,
262 ARMV8_MSR_DSPSR(0),
263 value);
264 break;
265 /* registers clobbered by taking exception in debug state */
266 case ARMV8_ELR_EL1:
267 retval = dpm->instr_write_data_r0_64(dpm,
268 ARMV8_MSR_GP(SYSTEM_ELR_EL1, 0), value_64);
269 break;
270 case ARMV8_ELR_EL2:
271 retval = dpm->instr_write_data_r0_64(dpm,
272 ARMV8_MSR_GP(SYSTEM_ELR_EL2, 0), value_64);
273 break;
274 case ARMV8_ELR_EL3:
275 retval = dpm->instr_write_data_r0_64(dpm,
276 ARMV8_MSR_GP(SYSTEM_ELR_EL3, 0), value_64);
277 break;
278 case ARMV8_ESR_EL1:
279 value = value_64;
280 retval = dpm->instr_write_data_r0(dpm,
281 ARMV8_MSR_GP(SYSTEM_ESR_EL1, 0), value);
282 break;
283 case ARMV8_ESR_EL2:
284 value = value_64;
285 retval = dpm->instr_write_data_r0(dpm,
286 ARMV8_MSR_GP(SYSTEM_ESR_EL2, 0), value);
287 break;
288 case ARMV8_ESR_EL3:
289 value = value_64;
290 retval = dpm->instr_write_data_r0(dpm,
291 ARMV8_MSR_GP(SYSTEM_ESR_EL3, 0), value);
292 break;
293 case ARMV8_SPSR_EL1:
294 value = value_64;
295 retval = dpm->instr_write_data_r0(dpm,
296 ARMV8_MSR_GP(SYSTEM_SPSR_EL1, 0), value);
297 break;
298 case ARMV8_SPSR_EL2:
299 value = value_64;
300 retval = dpm->instr_write_data_r0(dpm,
301 ARMV8_MSR_GP(SYSTEM_SPSR_EL2, 0), value);
302 break;
303 case ARMV8_SPSR_EL3:
304 value = value_64;
305 retval = dpm->instr_write_data_r0(dpm,
306 ARMV8_MSR_GP(SYSTEM_SPSR_EL3, 0), value);
307 break;
308 default:
309 retval = ERROR_FAIL;
310 break;
311 }
312
313 return retval;
314 }
315
316 static int armv8_read_reg32(struct armv8_common *armv8, int regnum, uint64_t *regval)
317 {
318 struct arm_dpm *dpm = &armv8->dpm;
319 uint32_t value = 0;
320 int retval;
321
322 switch (regnum) {
323 case ARMV8_R0 ... ARMV8_R14:
324 /* return via DCC: "MCR p14, 0, Rnum, c0, c5, 0" */
325 retval = dpm->instr_read_data_dcc(dpm,
326 ARMV4_5_MCR(14, 0, regnum, 0, 5, 0),
327 &value);
328 break;
329 case ARMV8_SP:
330 retval = dpm->instr_read_data_dcc(dpm,
331 ARMV4_5_MCR(14, 0, 13, 0, 5, 0),
332 &value);
333 break;
334 case ARMV8_PC:
335 retval = dpm->instr_read_data_r0(dpm,
336 ARMV8_MRC_DLR(0),
337 &value);
338 break;
339 case ARMV8_xPSR:
340 retval = dpm->instr_read_data_r0(dpm,
341 ARMV8_MRC_DSPSR(0),
342 &value);
343 break;
344 case ARMV8_ELR_EL1: /* mapped to LR_svc */
345 retval = dpm->instr_read_data_dcc(dpm,
346 ARMV4_5_MCR(14, 0, 14, 0, 5, 0),
347 &value);
348 break;
349 case ARMV8_ELR_EL2: /* mapped to ELR_hyp */
350 retval = dpm->instr_read_data_r0(dpm,
351 ARMV8_MRS_T1(0, 14, 0, 1),
352 &value);
353 break;
354 case ARMV8_ELR_EL3: /* mapped to LR_mon */
355 retval = dpm->instr_read_data_dcc(dpm,
356 ARMV4_5_MCR(14, 0, 14, 0, 5, 0),
357 &value);
358 break;
359 case ARMV8_ESR_EL1: /* mapped to DFSR */
360 retval = dpm->instr_read_data_r0(dpm,
361 ARMV4_5_MRC(15, 0, 0, 5, 0, 0),
362 &value);
363 break;
364 case ARMV8_ESR_EL2: /* mapped to HSR */
365 retval = dpm->instr_read_data_r0(dpm,
366 ARMV4_5_MRC(15, 4, 0, 5, 2, 0),
367 &value);
368 break;
369 case ARMV8_ESR_EL3: /* FIXME: no equivalent in aarch32? */
370 retval = ERROR_FAIL;
371 break;
372 case ARMV8_SPSR_EL1: /* mapped to SPSR_svc */
373 retval = dpm->instr_read_data_r0(dpm,
374 ARMV8_MRS_xPSR_T1(1, 0),
375 &value);
376 break;
377 case ARMV8_SPSR_EL2: /* mapped to SPSR_hyp */
378 retval = dpm->instr_read_data_r0(dpm,
379 ARMV8_MRS_xPSR_T1(1, 0),
380 &value);
381 break;
382 case ARMV8_SPSR_EL3: /* mapped to SPSR_mon */
383 retval = dpm->instr_read_data_r0(dpm,
384 ARMV8_MRS_xPSR_T1(1, 0),
385 &value);
386 break;
387 default:
388 retval = ERROR_FAIL;
389 break;
390 }
391
392 if (retval == ERROR_OK && regval != NULL)
393 *regval = value;
394
395 return retval;
396 }
397
398 static int armv8_write_reg32(struct armv8_common *armv8, int regnum, uint64_t value)
399 {
400 struct arm_dpm *dpm = &armv8->dpm;
401 int retval;
402
403 switch (regnum) {
404 case ARMV8_R0 ... ARMV8_R14:
405 /* load register from DCC: "MRC p14, 0, Rnum, c0, c5, 0" */
406 retval = dpm->instr_write_data_dcc(dpm,
407 ARMV4_5_MRC(14, 0, regnum, 0, 5, 0), value);
408 break;
409 case ARMV8_SP:
410 retval = dpm->instr_write_data_dcc(dpm,
411 ARMV4_5_MRC(14, 0, 13, 0, 5, 0), value);
412 break;
413 case ARMV8_PC:/* PC
414 * read r0 from DCC; then "MOV pc, r0" */
415 retval = dpm->instr_write_data_r0(dpm,
416 ARMV8_MCR_DLR(0), value);
417 break;
418 case ARMV8_xPSR: /* CPSR */
419 /* read r0 from DCC, then "MCR r0, DSPSR" */
420 retval = dpm->instr_write_data_r0(dpm,
421 ARMV8_MCR_DSPSR(0), value);
422 break;
423 case ARMV8_ELR_EL1: /* mapped to LR_svc */
424 retval = dpm->instr_write_data_dcc(dpm,
425 ARMV4_5_MRC(14, 0, 14, 0, 5, 0),
426 value);
427 break;
428 case ARMV8_ELR_EL2: /* mapped to ELR_hyp */
429 retval = dpm->instr_write_data_r0(dpm,
430 ARMV8_MSR_GP_T1(0, 14, 0, 1),
431 value);
432 break;
433 case ARMV8_ELR_EL3: /* mapped to LR_mon */
434 retval = dpm->instr_write_data_dcc(dpm,
435 ARMV4_5_MRC(14, 0, 14, 0, 5, 0),
436 value);
437 break;
438 case ARMV8_ESR_EL1: /* mapped to DFSR */
439 retval = dpm->instr_write_data_r0(dpm,
440 ARMV4_5_MCR(15, 0, 0, 5, 0, 0),
441 value);
442 break;
443 case ARMV8_ESR_EL2: /* mapped to HSR */
444 retval = dpm->instr_write_data_r0(dpm,
445 ARMV4_5_MCR(15, 4, 0, 5, 2, 0),
446 value);
447 break;
448 case ARMV8_ESR_EL3: /* FIXME: no equivalent in aarch32? */
449 retval = ERROR_FAIL;
450 break;
451 case ARMV8_SPSR_EL1: /* mapped to SPSR_svc */
452 retval = dpm->instr_write_data_r0(dpm,
453 ARMV8_MSR_GP_xPSR_T1(1, 0, 15),
454 value);
455 break;
456 case ARMV8_SPSR_EL2: /* mapped to SPSR_hyp */
457 retval = dpm->instr_write_data_r0(dpm,
458 ARMV8_MSR_GP_xPSR_T1(1, 0, 15),
459 value);
460 break;
461 case ARMV8_SPSR_EL3: /* mapped to SPSR_mon */
462 retval = dpm->instr_write_data_r0(dpm,
463 ARMV8_MSR_GP_xPSR_T1(1, 0, 15),
464 value);
465 break;
466 default:
467 retval = ERROR_FAIL;
468 break;
469 }
470
471 return retval;
472
473 }
474
475 void armv8_select_reg_access(struct armv8_common *armv8, bool is_aarch64)
476 {
477 if (is_aarch64) {
478 armv8->read_reg_u64 = armv8_read_reg;
479 armv8->write_reg_u64 = armv8_write_reg;
480 } else {
481 armv8->read_reg_u64 = armv8_read_reg32;
482 armv8->write_reg_u64 = armv8_write_reg32;
483 }
484 }
485
486 /* retrieve core id cluster id */
487 int armv8_read_mpidr(struct armv8_common *armv8)
488 {
489 int retval = ERROR_FAIL;
490 struct arm_dpm *dpm = armv8->arm.dpm;
491 uint32_t mpidr;
492
493 retval = dpm->prepare(dpm);
494 if (retval != ERROR_OK)
495 goto done;
496
497 retval = dpm->instr_read_data_r0(dpm, armv8_opcode(armv8, READ_REG_MPIDR), &mpidr);
498 if (retval != ERROR_OK)
499 goto done;
500 if (mpidr & 1<<31) {
501 armv8->multi_processor_system = (mpidr >> 30) & 1;
502 armv8->cluster_id = (mpidr >> 8) & 0xf;
503 armv8->cpu_id = mpidr & 0x3;
504 LOG_INFO("%s cluster %x core %x %s", target_name(armv8->arm.target),
505 armv8->cluster_id,
506 armv8->cpu_id,
507 armv8->multi_processor_system == 0 ? "multi core" : "single core");
508 } else
509 LOG_ERROR("mpidr not in multiprocessor format");
510
511 done:
512 dpm->finish(dpm);
513 return retval;
514 }
515
516 /**
517 * Configures host-side ARM records to reflect the specified CPSR.
518 * Later, code can use arm_reg_current() to map register numbers
519 * according to how they are exposed by this mode.
520 */
521 void armv8_set_cpsr(struct arm *arm, uint32_t cpsr)
522 {
523 uint32_t mode = cpsr & 0x1F;
524
525 /* NOTE: this may be called very early, before the register
526 * cache is set up. We can't defend against many errors, in
527 * particular against CPSRs that aren't valid *here* ...
528 */
529 if (arm->cpsr) {
530 buf_set_u32(arm->cpsr->value, 0, 32, cpsr);
531 arm->cpsr->valid = 1;
532 arm->cpsr->dirty = 0;
533 }
534
535 /* Older ARMs won't have the J bit */
536 enum arm_state state = 0xFF;
537
538 if (((cpsr & 0x10) >> 4) == 0) {
539 state = ARM_STATE_AARCH64;
540 } else {
541 if (cpsr & (1 << 5)) { /* T */
542 if (cpsr & (1 << 24)) { /* J */
543 LOG_WARNING("ThumbEE -- incomplete support");
544 state = ARM_STATE_THUMB_EE;
545 } else
546 state = ARM_STATE_THUMB;
547 } else {
548 if (cpsr & (1 << 24)) { /* J */
549 LOG_ERROR("Jazelle state handling is BROKEN!");
550 state = ARM_STATE_JAZELLE;
551 } else
552 state = ARM_STATE_ARM;
553 }
554 }
555 arm->core_state = state;
556 if (arm->core_state == ARM_STATE_AARCH64)
557 arm->core_mode = (mode << 4) | 0xf;
558 else
559 arm->core_mode = mode;
560
561 LOG_DEBUG("set CPSR %#8.8x: %s mode, %s state", (unsigned) cpsr,
562 armv8_mode_name(arm->core_mode),
563 armv8_state_strings[arm->core_state]);
564 }
565
566 static void armv8_show_fault_registers32(struct armv8_common *armv8)
567 {
568 uint32_t dfsr, ifsr, dfar, ifar;
569 struct arm_dpm *dpm = armv8->arm.dpm;
570 int retval;
571
572 retval = dpm->prepare(dpm);
573 if (retval != ERROR_OK)
574 return;
575
576 /* ARMV4_5_MRC(cpnum, op1, r0, CRn, CRm, op2) */
577
578 /* c5/c0 - {data, instruction} fault status registers */
579 retval = dpm->instr_read_data_r0(dpm,
580 ARMV4_5_MRC(15, 0, 0, 5, 0, 0),
581 &dfsr);
582 if (retval != ERROR_OK)
583 goto done;
584
585 retval = dpm->instr_read_data_r0(dpm,
586 ARMV4_5_MRC(15, 0, 0, 5, 0, 1),
587 &ifsr);
588 if (retval != ERROR_OK)
589 goto done;
590
591 /* c6/c0 - {data, instruction} fault address registers */
592 retval = dpm->instr_read_data_r0(dpm,
593 ARMV4_5_MRC(15, 0, 0, 6, 0, 0),
594 &dfar);
595 if (retval != ERROR_OK)
596 goto done;
597
598 retval = dpm->instr_read_data_r0(dpm,
599 ARMV4_5_MRC(15, 0, 0, 6, 0, 2),
600 &ifar);
601 if (retval != ERROR_OK)
602 goto done;
603
604 LOG_USER("Data fault registers DFSR: %8.8" PRIx32
605 ", DFAR: %8.8" PRIx32, dfsr, dfar);
606 LOG_USER("Instruction fault registers IFSR: %8.8" PRIx32
607 ", IFAR: %8.8" PRIx32, ifsr, ifar);
608
609 done:
610 /* (void) */ dpm->finish(dpm);
611 }
612
613 static __unused void armv8_show_fault_registers(struct target *target)
614 {
615 struct armv8_common *armv8 = target_to_armv8(target);
616
617 if (armv8->arm.core_state != ARM_STATE_AARCH64)
618 armv8_show_fault_registers32(armv8);
619 }
620
621 static uint8_t armv8_pa_size(uint32_t ps)
622 {
623 uint8_t ret = 0;
624 switch (ps) {
625 case 0:
626 ret = 32;
627 break;
628 case 1:
629 ret = 36;
630 break;
631 case 2:
632 ret = 40;
633 break;
634 case 3:
635 ret = 42;
636 break;
637 case 4:
638 ret = 44;
639 break;
640 case 5:
641 ret = 48;
642 break;
643 default:
644 LOG_INFO("Unknow physicall address size");
645 break;
646 }
647 return ret;
648 }
649
650 static __unused int armv8_read_ttbcr32(struct target *target)
651 {
652 struct armv8_common *armv8 = target_to_armv8(target);
653 struct arm_dpm *dpm = armv8->arm.dpm;
654 uint32_t ttbcr, ttbcr_n;
655 int retval = dpm->prepare(dpm);
656 if (retval != ERROR_OK)
657 goto done;
658 /* MRC p15,0,<Rt>,c2,c0,2 ; Read CP15 Translation Table Base Control Register*/
659 retval = dpm->instr_read_data_r0(dpm,
660 ARMV4_5_MRC(15, 0, 0, 2, 0, 2),
661 &ttbcr);
662 if (retval != ERROR_OK)
663 goto done;
664
665 LOG_DEBUG("ttbcr %" PRIx32, ttbcr);
666
667 ttbcr_n = ttbcr & 0x7;
668 armv8->armv8_mmu.ttbcr = ttbcr;
669
670 /*
671 * ARM Architecture Reference Manual (ARMv7-A and ARMv7-Redition),
672 * document # ARM DDI 0406C
673 */
674 armv8->armv8_mmu.ttbr_range[0] = 0xffffffff >> ttbcr_n;
675 armv8->armv8_mmu.ttbr_range[1] = 0xffffffff;
676 armv8->armv8_mmu.ttbr_mask[0] = 0xffffffff << (14 - ttbcr_n);
677 armv8->armv8_mmu.ttbr_mask[1] = 0xffffffff << 14;
678
679 LOG_DEBUG("ttbr1 %s, ttbr0_mask %" PRIx32 " ttbr1_mask %" PRIx32,
680 (ttbcr_n != 0) ? "used" : "not used",
681 armv8->armv8_mmu.ttbr_mask[0],
682 armv8->armv8_mmu.ttbr_mask[1]);
683
684 done:
685 dpm->finish(dpm);
686 return retval;
687 }
688
689 static __unused int armv8_read_ttbcr(struct target *target)
690 {
691 struct armv8_common *armv8 = target_to_armv8(target);
692 struct arm_dpm *dpm = armv8->arm.dpm;
693 struct arm *arm = &armv8->arm;
694 uint32_t ttbcr;
695 uint64_t ttbcr_64;
696
697 int retval = dpm->prepare(dpm);
698 if (retval != ERROR_OK)
699 goto done;
700
701 /* claaer ttrr1_used and ttbr0_mask */
702 memset(&armv8->armv8_mmu.ttbr1_used, 0, sizeof(armv8->armv8_mmu.ttbr1_used));
703 memset(&armv8->armv8_mmu.ttbr0_mask, 0, sizeof(armv8->armv8_mmu.ttbr0_mask));
704
705 switch (armv8_curel_from_core_mode(arm->core_mode)) {
706 case SYSTEM_CUREL_EL3:
707 retval = dpm->instr_read_data_r0(dpm,
708 ARMV8_MRS(SYSTEM_TCR_EL3, 0),
709 &ttbcr);
710 retval += dpm->instr_read_data_r0_64(dpm,
711 ARMV8_MRS(SYSTEM_TTBR0_EL3, 0),
712 &armv8->ttbr_base);
713 if (retval != ERROR_OK)
714 goto done;
715 armv8->va_size = 64 - (ttbcr & 0x3F);
716 armv8->pa_size = armv8_pa_size((ttbcr >> 16) & 7);
717 armv8->page_size = (ttbcr >> 14) & 3;
718 break;
719 case SYSTEM_CUREL_EL2:
720 retval = dpm->instr_read_data_r0(dpm,
721 ARMV8_MRS(SYSTEM_TCR_EL2, 0),
722 &ttbcr);
723 retval += dpm->instr_read_data_r0_64(dpm,
724 ARMV8_MRS(SYSTEM_TTBR0_EL2, 0),
725 &armv8->ttbr_base);
726 if (retval != ERROR_OK)
727 goto done;
728 armv8->va_size = 64 - (ttbcr & 0x3F);
729 armv8->pa_size = armv8_pa_size((ttbcr >> 16) & 7);
730 armv8->page_size = (ttbcr >> 14) & 3;
731 break;
732 case SYSTEM_CUREL_EL0:
733 armv8_dpm_modeswitch(dpm, ARMV8_64_EL1H);
734 /* fall through */
735 case SYSTEM_CUREL_EL1:
736 retval = dpm->instr_read_data_r0_64(dpm,
737 ARMV8_MRS(SYSTEM_TCR_EL1, 0),
738 &ttbcr_64);
739 armv8->va_size = 64 - (ttbcr_64 & 0x3F);
740 armv8->pa_size = armv8_pa_size((ttbcr_64 >> 32) & 7);
741 armv8->page_size = (ttbcr_64 >> 14) & 3;
742 armv8->armv8_mmu.ttbr1_used = (((ttbcr_64 >> 16) & 0x3F) != 0) ? 1 : 0;
743 armv8->armv8_mmu.ttbr0_mask = 0x0000FFFFFFFFFFFF;
744 retval += dpm->instr_read_data_r0_64(dpm,
745 ARMV8_MRS(SYSTEM_TTBR0_EL1 | (armv8->armv8_mmu.ttbr1_used), 0),
746 &armv8->ttbr_base);
747 if (retval != ERROR_OK)
748 goto done;
749 break;
750 default:
751 LOG_ERROR("unknow core state");
752 retval = ERROR_FAIL;
753 break;
754 }
755 if (retval != ERROR_OK)
756 goto done;
757
758 if (armv8->armv8_mmu.ttbr1_used == 1)
759 LOG_INFO("TTBR0 access above %" PRIx64, (uint64_t)(armv8->armv8_mmu.ttbr0_mask));
760
761 done:
762 armv8_dpm_modeswitch(dpm, ARM_MODE_ANY);
763 dpm->finish(dpm);
764 return retval;
765 }
766
767 /* method adapted to cortex A : reused arm v4 v5 method*/
768 int armv8_mmu_translate_va(struct target *target, target_addr_t va, target_addr_t *val)
769 {
770 return ERROR_OK;
771 }
772
773 /* V8 method VA TO PA */
774 int armv8_mmu_translate_va_pa(struct target *target, target_addr_t va,
775 target_addr_t *val, int meminfo)
776 {
777 struct armv8_common *armv8 = target_to_armv8(target);
778 struct arm *arm = target_to_arm(target);
779 struct arm_dpm *dpm = &armv8->dpm;
780 enum arm_mode target_mode = ARM_MODE_ANY;
781 uint32_t retval;
782 uint32_t instr = 0;
783 uint64_t par;
784
785 static const char * const shared_name[] = {
786 "Non-", "UNDEFINED ", "Outer ", "Inner "
787 };
788
789 static const char * const secure_name[] = {
790 "Secure", "Not Secure"
791 };
792
793 retval = dpm->prepare(dpm);
794 if (retval != ERROR_OK)
795 return retval;
796
797 switch (armv8_curel_from_core_mode(arm->core_mode)) {
798 case SYSTEM_CUREL_EL0:
799 instr = ARMV8_SYS(SYSTEM_ATS12E0R, 0);
800 /* can only execute instruction at EL2 */
801 target_mode = ARMV8_64_EL2H;
802 break;
803 case SYSTEM_CUREL_EL1:
804 instr = ARMV8_SYS(SYSTEM_ATS12E1R, 0);
805 /* can only execute instruction at EL2 */
806 target_mode = ARMV8_64_EL2H;
807 break;
808 case SYSTEM_CUREL_EL2:
809 instr = ARMV8_SYS(SYSTEM_ATS1E2R, 0);
810 break;
811 case SYSTEM_CUREL_EL3:
812 instr = ARMV8_SYS(SYSTEM_ATS1E3R, 0);
813 break;
814
815 default:
816 break;
817 };
818
819 if (target_mode != ARM_MODE_ANY)
820 armv8_dpm_modeswitch(dpm, target_mode);
821
822 /* write VA to R0 and execute translation instruction */
823 retval = dpm->instr_write_data_r0_64(dpm, instr, (uint64_t)va);
824 /* read result from PAR_EL1 */
825 if (retval == ERROR_OK)
826 retval = dpm->instr_read_data_r0_64(dpm, ARMV8_MRS(SYSTEM_PAR_EL1, 0), &par);
827
828 /* switch back to saved PE mode */
829 if (target_mode != ARM_MODE_ANY)
830 armv8_dpm_modeswitch(dpm, ARM_MODE_ANY);
831
832 dpm->finish(dpm);
833
834 if (retval != ERROR_OK)
835 return retval;
836
837 if (par & 1) {
838 LOG_ERROR("Address translation failed at stage %i, FST=%x, PTW=%i",
839 ((int)(par >> 9) & 1)+1, (int)(par >> 1) & 0x3f, (int)(par >> 8) & 1);
840
841 *val = 0;
842 retval = ERROR_FAIL;
843 } else {
844 *val = (par & 0xFFFFFFFFF000UL) | (va & 0xFFF);
845 if (meminfo) {
846 int SH = (par >> 7) & 3;
847 int NS = (par >> 9) & 1;
848 int ATTR = (par >> 56) & 0xFF;
849
850 char *memtype = (ATTR & 0xF0) == 0 ? "Device Memory" : "Normal Memory";
851
852 LOG_USER("%sshareable, %s",
853 shared_name[SH], secure_name[NS]);
854 LOG_USER("%s", memtype);
855 }
856 }
857
858 return retval;
859 }
860
861 int armv8_handle_cache_info_command(struct command_context *cmd_ctx,
862 struct armv8_cache_common *armv8_cache)
863 {
864 if (armv8_cache->info == -1) {
865 command_print(cmd_ctx, "cache not yet identified");
866 return ERROR_OK;
867 }
868
869 if (armv8_cache->display_cache_info)
870 armv8_cache->display_cache_info(cmd_ctx, armv8_cache);
871 return ERROR_OK;
872 }
873
874 int armv8_init_arch_info(struct target *target, struct armv8_common *armv8)
875 {
876 struct arm *arm = &armv8->arm;
877 arm->arch_info = armv8;
878 target->arch_info = &armv8->arm;
879 /* target is useful in all function arm v4 5 compatible */
880 armv8->arm.target = target;
881 armv8->arm.common_magic = ARM_COMMON_MAGIC;
882 armv8->common_magic = ARMV8_COMMON_MAGIC;
883
884 armv8->armv8_mmu.armv8_cache.l2_cache = NULL;
885 armv8->armv8_mmu.armv8_cache.info = -1;
886 armv8->armv8_mmu.armv8_cache.flush_all_data_cache = NULL;
887 armv8->armv8_mmu.armv8_cache.display_cache_info = NULL;
888 return ERROR_OK;
889 }
890
891 int armv8_aarch64_state(struct target *target)
892 {
893 struct arm *arm = target_to_arm(target);
894
895 if (arm->common_magic != ARM_COMMON_MAGIC) {
896 LOG_ERROR("BUG: called for a non-ARM target");
897 return ERROR_FAIL;
898 }
899
900 LOG_USER("target halted in %s state due to %s, current mode: %s\n"
901 "cpsr: 0x%8.8" PRIx32 " pc: 0x%" PRIx64 "%s",
902 armv8_state_strings[arm->core_state],
903 debug_reason_name(target),
904 armv8_mode_name(arm->core_mode),
905 buf_get_u32(arm->cpsr->value, 0, 32),
906 buf_get_u64(arm->pc->value, 0, 64),
907 arm->is_semihosting ? ", semihosting" : "");
908
909 return ERROR_OK;
910 }
911
912 int armv8_arch_state(struct target *target)
913 {
914 static const char * const state[] = {
915 "disabled", "enabled"
916 };
917
918 struct armv8_common *armv8 = target_to_armv8(target);
919 struct arm *arm = &armv8->arm;
920
921 if (armv8->common_magic != ARMV8_COMMON_MAGIC) {
922 LOG_ERROR("BUG: called for a non-Armv8 target");
923 return ERROR_COMMAND_SYNTAX_ERROR;
924 }
925
926 if (arm->core_state == ARM_STATE_AARCH64)
927 armv8_aarch64_state(target);
928 else
929 arm_arch_state(target);
930
931 LOG_USER("MMU: %s, D-Cache: %s, I-Cache: %s",
932 state[armv8->armv8_mmu.mmu_enabled],
933 state[armv8->armv8_mmu.armv8_cache.d_u_cache_enabled],
934 state[armv8->armv8_mmu.armv8_cache.i_cache_enabled]);
935
936 if (arm->core_mode == ARM_MODE_ABT)
937 armv8_show_fault_registers(target);
938
939 if (target->debug_reason == DBG_REASON_WATCHPOINT)
940 LOG_USER("Watchpoint triggered at PC %#08x",
941 (unsigned) armv8->dpm.wp_pc);
942
943 return ERROR_OK;
944 }
945
946 static const struct {
947 unsigned id;
948 const char *name;
949 unsigned bits;
950 enum arm_mode mode;
951 enum reg_type type;
952 const char *group;
953 const char *feature;
954 } armv8_regs[] = {
955 { ARMV8_R0, "x0", 64, ARM_MODE_ANY, REG_TYPE_UINT64, "general", "org.gnu.gdb.aarch64.core" },
956 { ARMV8_R1, "x1", 64, ARM_MODE_ANY, REG_TYPE_UINT64, "general", "org.gnu.gdb.aarch64.core" },
957 { ARMV8_R2, "x2", 64, ARM_MODE_ANY, REG_TYPE_UINT64, "general", "org.gnu.gdb.aarch64.core" },
958 { ARMV8_R3, "x3", 64, ARM_MODE_ANY, REG_TYPE_UINT64, "general", "org.gnu.gdb.aarch64.core" },
959 { ARMV8_R4, "x4", 64, ARM_MODE_ANY, REG_TYPE_UINT64, "general", "org.gnu.gdb.aarch64.core" },
960 { ARMV8_R5, "x5", 64, ARM_MODE_ANY, REG_TYPE_UINT64, "general", "org.gnu.gdb.aarch64.core" },
961 { ARMV8_R6, "x6", 64, ARM_MODE_ANY, REG_TYPE_UINT64, "general", "org.gnu.gdb.aarch64.core" },
962 { ARMV8_R7, "x7", 64, ARM_MODE_ANY, REG_TYPE_UINT64, "general", "org.gnu.gdb.aarch64.core" },
963 { ARMV8_R8, "x8", 64, ARM_MODE_ANY, REG_TYPE_UINT64, "general", "org.gnu.gdb.aarch64.core" },
964 { ARMV8_R9, "x9", 64, ARM_MODE_ANY, REG_TYPE_UINT64, "general", "org.gnu.gdb.aarch64.core" },
965 { ARMV8_R10, "x10", 64, ARM_MODE_ANY, REG_TYPE_UINT64, "general", "org.gnu.gdb.aarch64.core" },
966 { ARMV8_R11, "x11", 64, ARM_MODE_ANY, REG_TYPE_UINT64, "general", "org.gnu.gdb.aarch64.core" },
967 { ARMV8_R12, "x12", 64, ARM_MODE_ANY, REG_TYPE_UINT64, "general", "org.gnu.gdb.aarch64.core" },
968 { ARMV8_R13, "x13", 64, ARM_MODE_ANY, REG_TYPE_UINT64, "general", "org.gnu.gdb.aarch64.core" },
969 { ARMV8_R14, "x14", 64, ARM_MODE_ANY, REG_TYPE_UINT64, "general", "org.gnu.gdb.aarch64.core" },
970 { ARMV8_R15, "x15", 64, ARM_MODE_ANY, REG_TYPE_UINT64, "general", "org.gnu.gdb.aarch64.core" },
971 { ARMV8_R16, "x16", 64, ARM_MODE_ANY, REG_TYPE_UINT64, "general", "org.gnu.gdb.aarch64.core" },
972 { ARMV8_R17, "x17", 64, ARM_MODE_ANY, REG_TYPE_UINT64, "general", "org.gnu.gdb.aarch64.core" },
973 { ARMV8_R18, "x18", 64, ARM_MODE_ANY, REG_TYPE_UINT64, "general", "org.gnu.gdb.aarch64.core" },
974 { ARMV8_R19, "x19", 64, ARM_MODE_ANY, REG_TYPE_UINT64, "general", "org.gnu.gdb.aarch64.core" },
975 { ARMV8_R20, "x20", 64, ARM_MODE_ANY, REG_TYPE_UINT64, "general", "org.gnu.gdb.aarch64.core" },
976 { ARMV8_R21, "x21", 64, ARM_MODE_ANY, REG_TYPE_UINT64, "general", "org.gnu.gdb.aarch64.core" },
977 { ARMV8_R22, "x22", 64, ARM_MODE_ANY, REG_TYPE_UINT64, "general", "org.gnu.gdb.aarch64.core" },
978 { ARMV8_R23, "x23", 64, ARM_MODE_ANY, REG_TYPE_UINT64, "general", "org.gnu.gdb.aarch64.core" },
979 { ARMV8_R24, "x24", 64, ARM_MODE_ANY, REG_TYPE_UINT64, "general", "org.gnu.gdb.aarch64.core" },
980 { ARMV8_R25, "x25", 64, ARM_MODE_ANY, REG_TYPE_UINT64, "general", "org.gnu.gdb.aarch64.core" },
981 { ARMV8_R26, "x26", 64, ARM_MODE_ANY, REG_TYPE_UINT64, "general", "org.gnu.gdb.aarch64.core" },
982 { ARMV8_R27, "x27", 64, ARM_MODE_ANY, REG_TYPE_UINT64, "general", "org.gnu.gdb.aarch64.core" },
983 { ARMV8_R28, "x28", 64, ARM_MODE_ANY, REG_TYPE_UINT64, "general", "org.gnu.gdb.aarch64.core" },
984 { ARMV8_R29, "x29", 64, ARM_MODE_ANY, REG_TYPE_UINT64, "general", "org.gnu.gdb.aarch64.core" },
985 { ARMV8_R30, "x30", 64, ARM_MODE_ANY, REG_TYPE_UINT64, "general", "org.gnu.gdb.aarch64.core" },
986
987 { ARMV8_SP, "sp", 64, ARM_MODE_ANY, REG_TYPE_DATA_PTR, "general", "org.gnu.gdb.aarch64.core" },
988 { ARMV8_PC, "pc", 64, ARM_MODE_ANY, REG_TYPE_CODE_PTR, "general", "org.gnu.gdb.aarch64.core" },
989
990 { ARMV8_xPSR, "CPSR", 32, ARM_MODE_ANY, REG_TYPE_UINT32, "general", "org.gnu.gdb.aarch64.core" },
991
992 { ARMV8_ELR_EL1, "ELR_EL1", 64, ARMV8_64_EL1H, REG_TYPE_CODE_PTR, "banked", "net.sourceforge.openocd.banked" },
993 { ARMV8_ESR_EL1, "ESR_EL1", 32, ARMV8_64_EL1H, REG_TYPE_UINT32, "banked", "net.sourceforge.openocd.banked" },
994 { ARMV8_SPSR_EL1, "SPSR_EL1", 32, ARMV8_64_EL1H, REG_TYPE_UINT32, "banked", "net.sourceforge.openocd.banked" },
995
996 { ARMV8_ELR_EL2, "ELR_EL2", 64, ARMV8_64_EL2H, REG_TYPE_CODE_PTR, "banked", "net.sourceforge.openocd.banked" },
997 { ARMV8_ESR_EL2, "ESR_EL2", 32, ARMV8_64_EL2H, REG_TYPE_UINT32, "banked", "net.sourceforge.openocd.banked" },
998 { ARMV8_SPSR_EL2, "SPSR_EL2", 32, ARMV8_64_EL2H, REG_TYPE_UINT32, "banked", "net.sourceforge.openocd.banked" },
999
1000 { ARMV8_ELR_EL3, "ELR_EL3", 64, ARMV8_64_EL3H, REG_TYPE_CODE_PTR, "banked", "net.sourceforge.openocd.banked" },
1001 { ARMV8_ESR_EL3, "ESR_EL3", 32, ARMV8_64_EL3H, REG_TYPE_UINT32, "banked", "net.sourceforge.openocd.banked" },
1002 { ARMV8_SPSR_EL3, "SPSR_EL3", 32, ARMV8_64_EL3H, REG_TYPE_UINT32, "banked", "net.sourceforge.openocd.banked" },
1003 };
1004
1005 static const struct {
1006 unsigned id;
1007 const char *name;
1008 unsigned bits;
1009 enum arm_mode mode;
1010 enum reg_type type;
1011 const char *group;
1012 const char *feature;
1013 } armv8_regs32[] = {
1014 { ARMV8_R0, "r0", 32, ARM_MODE_ANY, REG_TYPE_UINT32, "general", "org.gnu.gdb.arm.core" },
1015 { ARMV8_R1, "r1", 32, ARM_MODE_ANY, REG_TYPE_UINT32, "general", "org.gnu.gdb.arm.core" },
1016 { ARMV8_R2, "r2", 32, ARM_MODE_ANY, REG_TYPE_UINT32, "general", "org.gnu.gdb.arm.core" },
1017 { ARMV8_R3, "r3", 32, ARM_MODE_ANY, REG_TYPE_UINT32, "general", "org.gnu.gdb.arm.core" },
1018 { ARMV8_R4, "r4", 32, ARM_MODE_ANY, REG_TYPE_UINT32, "general", "org.gnu.gdb.arm.core" },
1019 { ARMV8_R5, "r5", 32, ARM_MODE_ANY, REG_TYPE_UINT32, "general", "org.gnu.gdb.arm.core" },
1020 { ARMV8_R6, "r6", 32, ARM_MODE_ANY, REG_TYPE_UINT32, "general", "org.gnu.gdb.arm.core" },
1021 { ARMV8_R7, "r7", 32, ARM_MODE_ANY, REG_TYPE_UINT32, "general", "org.gnu.gdb.arm.core" },
1022 { ARMV8_R8, "r8", 32, ARM_MODE_ANY, REG_TYPE_UINT32, "general", "org.gnu.gdb.arm.core" },
1023 { ARMV8_R9, "r9", 32, ARM_MODE_ANY, REG_TYPE_UINT32, "general", "org.gnu.gdb.arm.core" },
1024 { ARMV8_R10, "r10", 32, ARM_MODE_ANY, REG_TYPE_UINT32, "general", "org.gnu.gdb.arm.core" },
1025 { ARMV8_R11, "r11", 32, ARM_MODE_ANY, REG_TYPE_UINT32, "general", "org.gnu.gdb.arm.core" },
1026 { ARMV8_R12, "r12", 32, ARM_MODE_ANY, REG_TYPE_UINT32, "general", "org.gnu.gdb.arm.core" },
1027 { ARMV8_R13, "sp", 32, ARM_MODE_ANY, REG_TYPE_DATA_PTR, "general", "org.gnu.gdb.arm.core" },
1028 { ARMV8_R14, "lr", 32, ARM_MODE_ANY, REG_TYPE_CODE_PTR, "general", "org.gnu.gdb.arm.core" },
1029 { ARMV8_PC, "pc", 32, ARM_MODE_ANY, REG_TYPE_CODE_PTR, "general", "org.gnu.gdb.arm.core" },
1030 { ARMV8_xPSR, "cpsr", 32, ARM_MODE_ANY, REG_TYPE_UINT32, "general", "org.gnu.gdb.arm.core" },
1031 };
1032
1033 #define ARMV8_NUM_REGS ARRAY_SIZE(armv8_regs)
1034 #define ARMV8_NUM_REGS32 ARRAY_SIZE(armv8_regs32)
1035
1036 static int armv8_get_core_reg(struct reg *reg)
1037 {
1038 struct arm_reg *armv8_reg = reg->arch_info;
1039 struct target *target = armv8_reg->target;
1040 struct arm *arm = target_to_arm(target);
1041
1042 if (target->state != TARGET_HALTED)
1043 return ERROR_TARGET_NOT_HALTED;
1044
1045 return arm->read_core_reg(target, reg, armv8_reg->num, arm->core_mode);
1046 }
1047
1048 static int armv8_set_core_reg(struct reg *reg, uint8_t *buf)
1049 {
1050 struct arm_reg *armv8_reg = reg->arch_info;
1051 struct target *target = armv8_reg->target;
1052 struct arm *arm = target_to_arm(target);
1053 uint64_t value = buf_get_u64(buf, 0, 64);
1054
1055 if (target->state != TARGET_HALTED)
1056 return ERROR_TARGET_NOT_HALTED;
1057
1058 if (reg == arm->cpsr) {
1059 armv8_set_cpsr(arm, (uint32_t)value);
1060 } else {
1061 buf_set_u64(reg->value, 0, 64, value);
1062 reg->valid = 1;
1063 }
1064
1065 reg->dirty = 1;
1066
1067 return ERROR_OK;
1068 }
1069
1070 static const struct reg_arch_type armv8_reg_type = {
1071 .get = armv8_get_core_reg,
1072 .set = armv8_set_core_reg,
1073 };
1074
1075 static int armv8_get_core_reg32(struct reg *reg)
1076 {
1077 struct arm_reg *armv8_reg = reg->arch_info;
1078 struct target *target = armv8_reg->target;
1079 struct arm *arm = target_to_arm(target);
1080 struct reg_cache *cache = arm->core_cache;
1081 struct reg *reg64;
1082 int retval;
1083
1084 /* get the corresponding Aarch64 register */
1085 reg64 = cache->reg_list + armv8_reg->num;
1086 if (reg64->valid) {
1087 reg->valid = true;
1088 return ERROR_OK;
1089 }
1090
1091 retval = arm->read_core_reg(target, reg64, armv8_reg->num, arm->core_mode);
1092 if (retval == ERROR_OK)
1093 reg->valid = reg64->valid;
1094
1095 return retval;
1096 }
1097
1098 static int armv8_set_core_reg32(struct reg *reg, uint8_t *buf)
1099 {
1100 struct arm_reg *armv8_reg = reg->arch_info;
1101 struct target *target = armv8_reg->target;
1102 struct arm *arm = target_to_arm(target);
1103 struct reg_cache *cache = arm->core_cache;
1104 struct reg *reg64 = cache->reg_list + armv8_reg->num;
1105 uint32_t value = buf_get_u32(buf, 0, 32);
1106
1107 if (reg64 == arm->cpsr) {
1108 armv8_set_cpsr(arm, value);
1109 } else {
1110 buf_set_u32(reg->value, 0, 32, value);
1111 reg->valid = 1;
1112 reg64->valid = 1;
1113 }
1114
1115 reg64->dirty = 1;
1116
1117 return ERROR_OK;
1118 }
1119
1120 static const struct reg_arch_type armv8_reg32_type = {
1121 .get = armv8_get_core_reg32,
1122 .set = armv8_set_core_reg32,
1123 };
1124
1125 /** Builds cache of architecturally defined registers. */
1126 struct reg_cache *armv8_build_reg_cache(struct target *target)
1127 {
1128 struct armv8_common *armv8 = target_to_armv8(target);
1129 struct arm *arm = &armv8->arm;
1130 int num_regs = ARMV8_NUM_REGS;
1131 int num_regs32 = ARMV8_NUM_REGS32;
1132 struct reg_cache **cache_p = register_get_last_cache_p(&target->reg_cache);
1133 struct reg_cache *cache = malloc(sizeof(struct reg_cache));
1134 struct reg_cache *cache32 = malloc(sizeof(struct reg_cache));
1135 struct reg *reg_list = calloc(num_regs, sizeof(struct reg));
1136 struct reg *reg_list32 = calloc(num_regs32, sizeof(struct reg));
1137 struct arm_reg *arch_info = calloc(num_regs, sizeof(struct arm_reg));
1138 struct reg_feature *feature;
1139 int i;
1140
1141 /* Build the process context cache */
1142 cache->name = "Aarch64 registers";
1143 cache->next = cache32;
1144 cache->reg_list = reg_list;
1145 cache->num_regs = num_regs;
1146
1147 for (i = 0; i < num_regs; i++) {
1148 arch_info[i].num = armv8_regs[i].id;
1149 arch_info[i].mode = armv8_regs[i].mode;
1150 arch_info[i].target = target;
1151 arch_info[i].arm = arm;
1152
1153 reg_list[i].name = armv8_regs[i].name;
1154 reg_list[i].size = armv8_regs[i].bits;
1155 reg_list[i].value = &arch_info[i].value[0];
1156 reg_list[i].type = &armv8_reg_type;
1157 reg_list[i].arch_info = &arch_info[i];
1158
1159 reg_list[i].group = armv8_regs[i].group;
1160 reg_list[i].number = i;
1161 reg_list[i].exist = true;
1162 reg_list[i].caller_save = true; /* gdb defaults to true */
1163
1164 feature = calloc(1, sizeof(struct reg_feature));
1165 if (feature) {
1166 feature->name = armv8_regs[i].feature;
1167 reg_list[i].feature = feature;
1168 } else
1169 LOG_ERROR("unable to allocate feature list");
1170
1171 reg_list[i].reg_data_type = calloc(1, sizeof(struct reg_data_type));
1172 if (reg_list[i].reg_data_type)
1173 reg_list[i].reg_data_type->type = armv8_regs[i].type;
1174 else
1175 LOG_ERROR("unable to allocate reg type list");
1176 }
1177
1178 arm->cpsr = reg_list + ARMV8_xPSR;
1179 arm->pc = reg_list + ARMV8_PC;
1180 arm->core_cache = cache;
1181
1182 /* shadow cache for ARM mode registers */
1183 cache32->name = "Aarch32 registers";
1184 cache32->next = NULL;
1185 cache32->reg_list = reg_list32;
1186 cache32->num_regs = num_regs32;
1187
1188 for (i = 0; i < num_regs32; i++) {
1189 reg_list32[i].name = armv8_regs32[i].name;
1190 reg_list32[i].size = armv8_regs32[i].bits;
1191 reg_list32[i].value = &arch_info[armv8_regs32[i].id].value[0];
1192 reg_list32[i].type = &armv8_reg32_type;
1193 reg_list32[i].arch_info = &arch_info[armv8_regs32[i].id];
1194 reg_list32[i].group = armv8_regs32[i].group;
1195 reg_list32[i].number = i;
1196 reg_list32[i].exist = true;
1197 reg_list32[i].caller_save = true;
1198
1199 feature = calloc(1, sizeof(struct reg_feature));
1200 if (feature) {
1201 feature->name = armv8_regs32[i].feature;
1202 reg_list32[i].feature = feature;
1203 } else
1204 LOG_ERROR("unable to allocate feature list");
1205
1206 reg_list32[i].reg_data_type = calloc(1, sizeof(struct reg_data_type));
1207 if (reg_list32[i].reg_data_type)
1208 reg_list32[i].reg_data_type->type = armv8_regs32[i].type;
1209 else
1210 LOG_ERROR("unable to allocate reg type list");
1211 }
1212
1213 (*cache_p) = cache;
1214 return cache;
1215 }
1216
1217 struct reg *armv8_reg_current(struct arm *arm, unsigned regnum)
1218 {
1219 struct reg *r;
1220
1221 if (regnum > (ARMV8_LAST_REG - 1))
1222 return NULL;
1223
1224 r = arm->core_cache->reg_list + regnum;
1225 return r;
1226 }
1227
1228 const struct command_registration armv8_command_handlers[] = {
1229 {
1230 .chain = dap_command_handlers,
1231 },
1232 COMMAND_REGISTRATION_DONE
1233 };
1234
1235
1236 int armv8_get_gdb_reg_list(struct target *target,
1237 struct reg **reg_list[], int *reg_list_size,
1238 enum target_register_class reg_class)
1239 {
1240 struct arm *arm = target_to_arm(target);
1241 int i;
1242
1243 if (arm->core_state == ARM_STATE_AARCH64) {
1244
1245 LOG_DEBUG("Creating Aarch64 register list for target %s", target_name(target));
1246
1247 switch (reg_class) {
1248 case REG_CLASS_GENERAL:
1249 *reg_list_size = ARMV8_ELR_EL1;
1250 *reg_list = malloc(sizeof(struct reg *) * (*reg_list_size));
1251
1252 for (i = 0; i < *reg_list_size; i++)
1253 (*reg_list)[i] = armv8_reg_current(arm, i);
1254 return ERROR_OK;
1255
1256 case REG_CLASS_ALL:
1257 *reg_list_size = ARMV8_LAST_REG;
1258 *reg_list = malloc(sizeof(struct reg *) * (*reg_list_size));
1259
1260 for (i = 0; i < *reg_list_size; i++)
1261 (*reg_list)[i] = armv8_reg_current(arm, i);
1262
1263 return ERROR_OK;
1264
1265 default:
1266 LOG_ERROR("not a valid register class type in query.");
1267 return ERROR_FAIL;
1268 }
1269 } else {
1270 struct reg_cache *cache32 = arm->core_cache->next;
1271
1272 LOG_DEBUG("Creating Aarch32 register list for target %s", target_name(target));
1273
1274 switch (reg_class) {
1275 case REG_CLASS_GENERAL:
1276 case REG_CLASS_ALL:
1277 *reg_list_size = cache32->num_regs;
1278 *reg_list = malloc(sizeof(struct reg *) * (*reg_list_size));
1279
1280 for (i = 0; i < *reg_list_size; i++)
1281 (*reg_list)[i] = cache32->reg_list + i;
1282
1283 return ERROR_OK;
1284 default:
1285 LOG_ERROR("not a valid register class type in query.");
1286 return ERROR_FAIL;
1287 }
1288 }
1289 }
1290
1291 int armv8_set_dbgreg_bits(struct armv8_common *armv8, unsigned int reg, unsigned long mask, unsigned long value)
1292 {
1293 uint32_t tmp;
1294
1295 /* Read register */
1296 int retval = mem_ap_read_atomic_u32(armv8->debug_ap,
1297 armv8->debug_base + reg, &tmp);
1298 if (ERROR_OK != retval)
1299 return retval;
1300
1301 /* clear bitfield */
1302 tmp &= ~mask;
1303 /* put new value */
1304 tmp |= value & mask;
1305
1306 /* write new value */
1307 retval = mem_ap_write_atomic_u32(armv8->debug_ap,
1308 armv8->debug_base + reg, tmp);
1309 return retval;
1310 }

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)