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

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)