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

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)