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

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)