aarch64: simplify armv8_set_cpsr()
[openocd.git] / src / target / armv8.c
1 /***************************************************************************
2 * Copyright (C) 2015 by David Ung *
3 * *
4 * This program is free software; you can redistribute it and/or modify *
5 * it under the terms of the GNU General Public License as published by *
6 * the Free Software Foundation; either version 2 of the License, or *
7 * (at your option) any later version. *
8 * *
9 * This program is distributed in the hope that it will be useful, *
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
12 * GNU General Public License for more details. *
13 * *
14 * You should have received a copy of the GNU General Public License *
15 * along with this program; if not, write to the *
16 * Free Software Foundation, Inc., *
17 ***************************************************************************/
18
19 #ifdef HAVE_CONFIG_H
20 #include "config.h"
21 #endif
22
23 #include <helper/replacements.h>
24
25 #include "armv8.h"
26 #include "arm_disassembler.h"
27
28 #include "register.h"
29 #include <helper/binarybuffer.h>
30 #include <helper/command.h>
31
32 #include <stdlib.h>
33 #include <string.h>
34 #include <unistd.h>
35
36 #include "armv8_opcodes.h"
37 #include "target.h"
38 #include "target_type.h"
39
40 #define __unused __attribute__((unused))
41
42 static const char * const armv8_state_strings[] = {
43 "AArch32", "Thumb", "Jazelle", "ThumbEE", "AArch64",
44 };
45
46 static const struct {
47 const char *name;
48 unsigned psr;
49 /* For user and system modes, these list indices for all registers.
50 * otherwise they're just indices for the shadow registers and SPSR.
51 */
52 unsigned short n_indices;
53 const uint8_t *indices;
54 } armv8_mode_data[] = {
55 /* These special modes are currently only supported
56 * by ARMv6M and ARMv7M profiles */
57 {
58 .name = "USR",
59 .psr = ARM_MODE_USR,
60 },
61 {
62 .name = "FIQ",
63 .psr = ARM_MODE_FIQ,
64 },
65 {
66 .name = "IRQ",
67 .psr = ARM_MODE_IRQ,
68 },
69 {
70 .name = "SVC",
71 .psr = ARM_MODE_SVC,
72 },
73 {
74 .name = "MON",
75 .psr = ARM_MODE_MON,
76 },
77 {
78 .name = "ABT",
79 .psr = ARM_MODE_ABT,
80 },
81 {
82 .name = "EL0T",
83 .psr = ARMV8_64_EL0T,
84 },
85 {
86 .name = "EL1T",
87 .psr = ARMV8_64_EL1T,
88 },
89 {
90 .name = "EL1H",
91 .psr = ARMV8_64_EL1H,
92 },
93 {
94 .name = "EL2T",
95 .psr = ARMV8_64_EL2T,
96 },
97 {
98 .name = "EL2H",
99 .psr = ARMV8_64_EL2H,
100 },
101 {
102 .name = "EL3T",
103 .psr = ARMV8_64_EL3T,
104 },
105 {
106 .name = "EL3H",
107 .psr = ARMV8_64_EL3H,
108 },
109 };
110
111 /** Map PSR mode bits to the name of an ARM processor operating mode. */
112 const char *armv8_mode_name(unsigned psr_mode)
113 {
114 for (unsigned i = 0; i < ARRAY_SIZE(armv8_mode_data); i++) {
115 if (armv8_mode_data[i].psr == psr_mode)
116 return armv8_mode_data[i].name;
117 }
118 LOG_ERROR("unrecognized psr mode: %#02x", psr_mode);
119 return "UNRECOGNIZED";
120 }
121
122 int armv8_mode_to_number(enum arm_mode mode)
123 {
124 switch (mode) {
125 case ARM_MODE_ANY:
126 /* map MODE_ANY to user mode */
127 case ARM_MODE_USR:
128 return 0;
129 case ARM_MODE_FIQ:
130 return 1;
131 case ARM_MODE_IRQ:
132 return 2;
133 case ARM_MODE_SVC:
134 return 3;
135 case ARM_MODE_ABT:
136 return 4;
137 case ARM_MODE_UND:
138 return 5;
139 case ARM_MODE_SYS:
140 return 6;
141 case ARM_MODE_MON:
142 return 7;
143 case ARMV8_64_EL0T:
144 return 8;
145 case ARMV8_64_EL1T:
146 return 9;
147 case ARMV8_64_EL1H:
148 return 10;
149 case ARMV8_64_EL2T:
150 return 11;
151 case ARMV8_64_EL2H:
152 return 12;
153 case ARMV8_64_EL3T:
154 return 13;
155 case ARMV8_64_EL3H:
156 return 14;
157
158 default:
159 LOG_ERROR("invalid mode value encountered %d", mode);
160 return -1;
161 }
162 }
163
164
165 static int armv8_read_core_reg(struct target *target, struct reg *r,
166 int num, enum arm_mode mode)
167 {
168 uint64_t reg_value;
169 int retval;
170 struct arm_reg *armv8_core_reg;
171 struct armv8_common *armv8 = target_to_armv8(target);
172
173 assert(num < (int)armv8->arm.core_cache->num_regs);
174
175 armv8_core_reg = armv8->arm.core_cache->reg_list[num].arch_info;
176 retval = armv8->load_core_reg_u64(target,
177 armv8_core_reg->num, &reg_value);
178
179 buf_set_u64(armv8->arm.core_cache->reg_list[num].value, 0, 64, reg_value);
180 armv8->arm.core_cache->reg_list[num].valid = 1;
181 armv8->arm.core_cache->reg_list[num].dirty = 0;
182
183 return retval;
184 }
185
186 #if 0
187 static int armv8_write_core_reg(struct target *target, struct reg *r,
188 int num, enum arm_mode mode, target_addr_t value)
189 {
190 int retval;
191 struct arm_reg *armv8_core_reg;
192 struct armv8_common *armv8 = target_to_armv8(target);
193
194 assert(num < (int)armv8->arm.core_cache->num_regs);
195
196 armv8_core_reg = armv8->arm.core_cache->reg_list[num].arch_info;
197 retval = armv8->store_core_reg_u64(target,
198 armv8_core_reg->num,
199 value);
200 if (retval != ERROR_OK) {
201 LOG_ERROR("JTAG failure");
202 armv8->arm.core_cache->reg_list[num].dirty = armv8->arm.core_cache->reg_list[num].valid;
203 return ERROR_JTAG_DEVICE_ERROR;
204 }
205
206 LOG_DEBUG("write core reg %i value 0x%" PRIx64 "", num, value);
207 armv8->arm.core_cache->reg_list[num].valid = 1;
208 armv8->arm.core_cache->reg_list[num].dirty = 0;
209
210 return ERROR_OK;
211 }
212 #endif
213
214 /* retrieve core id cluster id */
215 int armv8_read_mpidr(struct armv8_common *armv8)
216 {
217 int retval = ERROR_FAIL;
218 struct arm_dpm *dpm = armv8->arm.dpm;
219 uint32_t mpidr;
220
221 retval = dpm->prepare(dpm);
222 if (retval != ERROR_OK)
223 goto done;
224
225 retval = dpm->instr_read_data_r0(dpm, armv8_opcode(armv8, READ_REG_MPIDR), &mpidr);
226 if (retval != ERROR_OK)
227 goto done;
228 if (mpidr & 1<<31) {
229 armv8->multi_processor_system = (mpidr >> 30) & 1;
230 armv8->cluster_id = (mpidr >> 8) & 0xf;
231 armv8->cpu_id = mpidr & 0x3;
232 LOG_INFO("%s cluster %x core %x %s", target_name(armv8->arm.target),
233 armv8->cluster_id,
234 armv8->cpu_id,
235 armv8->multi_processor_system == 0 ? "multi core" : "mono core");
236
237 } else
238 LOG_ERROR("mpdir not in multiprocessor format");
239
240 done:
241 dpm->finish(dpm);
242 return retval;
243 }
244
245 /**
246 * Configures host-side ARM records to reflect the specified CPSR.
247 * Later, code can use arm_reg_current() to map register numbers
248 * according to how they are exposed by this mode.
249 */
250 void armv8_set_cpsr(struct arm *arm, uint32_t cpsr)
251 {
252 uint32_t mode = cpsr & 0x1F;
253
254 /* NOTE: this may be called very early, before the register
255 * cache is set up. We can't defend against many errors, in
256 * particular against CPSRs that aren't valid *here* ...
257 */
258 if (arm->cpsr) {
259 buf_set_u32(arm->cpsr->value, 0, 32, cpsr);
260 arm->cpsr->valid = 1;
261 arm->cpsr->dirty = 0;
262 }
263
264 /* Older ARMs won't have the J bit */
265 enum arm_state state = 0xFF;
266
267 if (((cpsr & 0x10) >> 4) == 0) {
268 state = ARM_STATE_AARCH64;
269 } else {
270 if (cpsr & (1 << 5)) { /* T */
271 if (cpsr & (1 << 24)) { /* J */
272 LOG_WARNING("ThumbEE -- incomplete support");
273 state = ARM_STATE_THUMB_EE;
274 } else
275 state = ARM_STATE_THUMB;
276 } else {
277 if (cpsr & (1 << 24)) { /* J */
278 LOG_ERROR("Jazelle state handling is BROKEN!");
279 state = ARM_STATE_JAZELLE;
280 } else
281 state = ARM_STATE_ARM;
282 }
283 }
284 arm->core_state = state;
285 if (arm->core_state == ARM_STATE_AARCH64)
286 arm->core_mode = (mode << 4) | 0xf;
287 else
288 arm->core_mode = mode;
289
290 LOG_DEBUG("set CPSR %#8.8x: %s mode, %s state", (unsigned) cpsr,
291 armv8_mode_name(arm->core_mode),
292 armv8_state_strings[arm->core_state]);
293 }
294
295 static void armv8_show_fault_registers32(struct armv8_common *armv8)
296 {
297 uint32_t dfsr, ifsr, dfar, ifar;
298 struct arm_dpm *dpm = armv8->arm.dpm;
299 int retval;
300
301 retval = dpm->prepare(dpm);
302 if (retval != ERROR_OK)
303 return;
304
305 /* ARMV4_5_MRC(cpnum, op1, r0, CRn, CRm, op2) */
306
307 /* c5/c0 - {data, instruction} fault status registers */
308 retval = dpm->instr_read_data_r0(dpm,
309 T32_FMTITR(ARMV4_5_MRC(15, 0, 0, 5, 0, 0)),
310 &dfsr);
311 if (retval != ERROR_OK)
312 goto done;
313
314 retval = dpm->instr_read_data_r0(dpm,
315 T32_FMTITR(ARMV4_5_MRC(15, 0, 0, 5, 0, 1)),
316 &ifsr);
317 if (retval != ERROR_OK)
318 goto done;
319
320 /* c6/c0 - {data, instruction} fault address registers */
321 retval = dpm->instr_read_data_r0(dpm,
322 T32_FMTITR(ARMV4_5_MRC(15, 0, 0, 6, 0, 0)),
323 &dfar);
324 if (retval != ERROR_OK)
325 goto done;
326
327 retval = dpm->instr_read_data_r0(dpm,
328 T32_FMTITR(ARMV4_5_MRC(15, 0, 0, 6, 0, 2)),
329 &ifar);
330 if (retval != ERROR_OK)
331 goto done;
332
333 LOG_USER("Data fault registers DFSR: %8.8" PRIx32
334 ", DFAR: %8.8" PRIx32, dfsr, dfar);
335 LOG_USER("Instruction fault registers IFSR: %8.8" PRIx32
336 ", IFAR: %8.8" PRIx32, ifsr, ifar);
337
338 done:
339 /* (void) */ dpm->finish(dpm);
340 }
341
342 static void armv8_show_fault_registers(struct target *target)
343 {
344 struct armv8_common *armv8 = target_to_armv8(target);
345
346 if (armv8->arm.core_state != ARM_STATE_AARCH64)
347 armv8_show_fault_registers32(armv8);
348 }
349
350 static uint8_t armv8_pa_size(uint32_t ps)
351 {
352 uint8_t ret = 0;
353 switch (ps) {
354 case 0:
355 ret = 32;
356 break;
357 case 1:
358 ret = 36;
359 break;
360 case 2:
361 ret = 40;
362 break;
363 case 3:
364 ret = 42;
365 break;
366 case 4:
367 ret = 44;
368 break;
369 case 5:
370 ret = 48;
371 break;
372 default:
373 LOG_INFO("Unknow physicall address size");
374 break;
375 }
376 return ret;
377 }
378
379 static __unused int armv8_read_ttbcr32(struct target *target)
380 {
381 struct armv8_common *armv8 = target_to_armv8(target);
382 struct arm_dpm *dpm = armv8->arm.dpm;
383 uint32_t ttbcr, ttbcr_n;
384 int retval = dpm->prepare(dpm);
385 if (retval != ERROR_OK)
386 goto done;
387 /* MRC p15,0,<Rt>,c2,c0,2 ; Read CP15 Translation Table Base Control Register*/
388 retval = dpm->instr_read_data_r0(dpm,
389 T32_FMTITR(ARMV4_5_MRC(15, 0, 0, 2, 0, 2)),
390 &ttbcr);
391 if (retval != ERROR_OK)
392 goto done;
393
394 LOG_DEBUG("ttbcr %" PRIx32, ttbcr);
395
396 ttbcr_n = ttbcr & 0x7;
397 armv8->armv8_mmu.ttbcr = ttbcr;
398
399 /*
400 * ARM Architecture Reference Manual (ARMv7-A and ARMv7-Redition),
401 * document # ARM DDI 0406C
402 */
403 armv8->armv8_mmu.ttbr_range[0] = 0xffffffff >> ttbcr_n;
404 armv8->armv8_mmu.ttbr_range[1] = 0xffffffff;
405 armv8->armv8_mmu.ttbr_mask[0] = 0xffffffff << (14 - ttbcr_n);
406 armv8->armv8_mmu.ttbr_mask[1] = 0xffffffff << 14;
407
408 LOG_DEBUG("ttbr1 %s, ttbr0_mask %" PRIx32 " ttbr1_mask %" PRIx32,
409 (ttbcr_n != 0) ? "used" : "not used",
410 armv8->armv8_mmu.ttbr_mask[0],
411 armv8->armv8_mmu.ttbr_mask[1]);
412
413 done:
414 dpm->finish(dpm);
415 return retval;
416 }
417
418 static __unused int armv8_read_ttbcr(struct target *target)
419 {
420 struct armv8_common *armv8 = target_to_armv8(target);
421 struct arm_dpm *dpm = armv8->arm.dpm;
422 struct arm *arm = &armv8->arm;
423 uint32_t ttbcr;
424 uint64_t ttbcr_64;
425
426 int retval = dpm->prepare(dpm);
427 if (retval != ERROR_OK)
428 goto done;
429
430 /* claaer ttrr1_used and ttbr0_mask */
431 memset(&armv8->armv8_mmu.ttbr1_used, 0, sizeof(armv8->armv8_mmu.ttbr1_used));
432 memset(&armv8->armv8_mmu.ttbr0_mask, 0, sizeof(armv8->armv8_mmu.ttbr0_mask));
433
434 switch (arm->core_mode) {
435 case ARMV8_64_EL3H:
436 case ARMV8_64_EL3T:
437 retval = dpm->instr_read_data_r0(dpm,
438 ARMV8_MRS(SYSTEM_TCR_EL3, 0),
439 &ttbcr);
440 retval += dpm->instr_read_data_r0_64(dpm,
441 ARMV8_MRS(SYSTEM_TTBR0_EL3, 0),
442 &armv8->ttbr_base);
443 if (retval != ERROR_OK)
444 goto done;
445 armv8->va_size = 64 - (ttbcr & 0x3F);
446 armv8->pa_size = armv8_pa_size((ttbcr >> 16) & 7);
447 armv8->page_size = (ttbcr >> 14) & 3;
448 break;
449 case ARMV8_64_EL2T:
450 case ARMV8_64_EL2H:
451 retval = dpm->instr_read_data_r0(dpm,
452 ARMV8_MRS(SYSTEM_TCR_EL2, 0),
453 &ttbcr);
454 retval += dpm->instr_read_data_r0_64(dpm,
455 ARMV8_MRS(SYSTEM_TTBR0_EL2, 0),
456 &armv8->ttbr_base);
457 if (retval != ERROR_OK)
458 goto done;
459 armv8->va_size = 64 - (ttbcr & 0x3F);
460 armv8->pa_size = armv8_pa_size((ttbcr >> 16) & 7);
461 armv8->page_size = (ttbcr >> 14) & 3;
462 break;
463 case ARMV8_64_EL0T:
464 case ARMV8_64_EL1T:
465 case ARMV8_64_EL1H:
466 retval = dpm->instr_read_data_r0_64(dpm,
467 ARMV8_MRS(SYSTEM_TCR_EL1, 0),
468 &ttbcr_64);
469 armv8->va_size = 64 - (ttbcr_64 & 0x3F);
470 armv8->pa_size = armv8_pa_size((ttbcr_64 >> 32) & 7);
471 armv8->page_size = (ttbcr_64 >> 14) & 3;
472 armv8->armv8_mmu.ttbr1_used = (((ttbcr_64 >> 16) & 0x3F) != 0) ? 1 : 0;
473 armv8->armv8_mmu.ttbr0_mask = 0x0000FFFFFFFFFFFF;
474 retval += dpm->instr_read_data_r0_64(dpm,
475 ARMV8_MRS(SYSTEM_TTBR0_EL1 | (armv8->armv8_mmu.ttbr1_used), 0),
476 &armv8->ttbr_base);
477 if (retval != ERROR_OK)
478 goto done;
479 break;
480 default:
481 LOG_ERROR("unknow core state");
482 retval = ERROR_FAIL;
483 break;
484 }
485 if (retval != ERROR_OK)
486 goto done;
487
488 if (armv8->armv8_mmu.ttbr1_used == 1)
489 LOG_INFO("TTBR0 access above %" PRIx64, (uint64_t)(armv8->armv8_mmu.ttbr0_mask));
490
491 done:
492 dpm->finish(dpm);
493 return retval;
494 }
495
496 /* method adapted to cortex A : reused arm v4 v5 method*/
497 int armv8_mmu_translate_va(struct target *target, target_addr_t va, target_addr_t *val)
498 {
499 return ERROR_OK;
500 }
501
502 /* V8 method VA TO PA */
503 int armv8_mmu_translate_va_pa(struct target *target, target_addr_t va,
504 target_addr_t *val, int meminfo)
505 {
506 struct armv8_common *armv8 = target_to_armv8(target);
507 struct arm *arm = target_to_arm(target);
508 struct arm_dpm *dpm = &armv8->dpm;
509 uint32_t retval;
510 uint32_t instr = 0;
511 uint64_t par;
512
513 static const char * const shared_name[] = {
514 "Non-", "UNDEFINED ", "Outer ", "Inner "
515 };
516
517 static const char * const secure_name[] = {
518 "Secure", "Not Secure"
519 };
520
521 retval = dpm->prepare(dpm);
522 if (retval != ERROR_OK)
523 return retval;
524
525 switch (armv8_curel_from_core_mode(arm)) {
526 case SYSTEM_CUREL_EL0:
527 instr = ARMV8_SYS(SYSTEM_ATS12E0R, 0);
528 /* can only execute instruction at EL2 */
529 dpmv8_modeswitch(dpm, ARMV8_64_EL2T);
530 break;
531 case SYSTEM_CUREL_EL1:
532 instr = ARMV8_SYS(SYSTEM_ATS12E1R, 0);
533 /* can only execute instruction at EL2 */
534 dpmv8_modeswitch(dpm, ARMV8_64_EL2T);
535 break;
536 case SYSTEM_CUREL_EL2:
537 instr = ARMV8_SYS(SYSTEM_ATS1E2R, 0);
538 break;
539 case SYSTEM_CUREL_EL3:
540 instr = ARMV8_SYS(SYSTEM_ATS1E3R, 0);
541 break;
542
543 default:
544 break;
545 };
546
547 /* write VA to R0 and execute translation instruction */
548 retval = dpm->instr_write_data_r0_64(dpm, instr, (uint64_t)va);
549 /* read result from PAR_EL1 */
550 if (retval == ERROR_OK)
551 retval = dpm->instr_read_data_r0_64(dpm, ARMV8_MRS(SYSTEM_PAR_EL1, 0), &par);
552
553 dpm->finish(dpm);
554
555 /* switch back to saved PE mode */
556 dpmv8_modeswitch(dpm, ARM_MODE_ANY);
557
558 if (retval != ERROR_OK)
559 return retval;
560
561 if (par & 1) {
562 LOG_ERROR("Address translation failed at stage %i, FST=%x, PTW=%i",
563 ((int)(par >> 9) & 1)+1, (int)(par >> 1) & 0x3f, (int)(par >> 8) & 1);
564
565 *val = 0;
566 retval = ERROR_FAIL;
567 } else {
568 *val = (par & 0xFFFFFFFFF000UL) | (va & 0xFFF);
569 if (meminfo) {
570 int SH = (par >> 7) & 3;
571 int NS = (par >> 9) & 1;
572 int ATTR = (par >> 56) & 0xFF;
573
574 char *memtype = (ATTR & 0xF0) == 0 ? "Device Memory" : "Normal Memory";
575
576 LOG_USER("%sshareable, %s",
577 shared_name[SH], secure_name[NS]);
578 LOG_USER("%s", memtype);
579 }
580 }
581
582 return retval;
583 }
584
585 int armv8_handle_cache_info_command(struct command_context *cmd_ctx,
586 struct armv8_cache_common *armv8_cache)
587 {
588 if (armv8_cache->info == -1) {
589 command_print(cmd_ctx, "cache not yet identified");
590 return ERROR_OK;
591 }
592
593 if (armv8_cache->display_cache_info)
594 armv8_cache->display_cache_info(cmd_ctx, armv8_cache);
595 return ERROR_OK;
596 }
597
598 int armv8_init_arch_info(struct target *target, struct armv8_common *armv8)
599 {
600 struct arm *arm = &armv8->arm;
601 arm->arch_info = armv8;
602 target->arch_info = &armv8->arm;
603 /* target is useful in all function arm v4 5 compatible */
604 armv8->arm.target = target;
605 armv8->arm.common_magic = ARM_COMMON_MAGIC;
606 armv8->common_magic = ARMV8_COMMON_MAGIC;
607
608 arm->read_core_reg = armv8_read_core_reg;
609 #if 0
610 arm->write_core_reg = armv8_write_core_reg;
611 #endif
612
613 armv8->armv8_mmu.armv8_cache.l2_cache = NULL;
614 armv8->armv8_mmu.armv8_cache.info = -1;
615 armv8->armv8_mmu.armv8_cache.flush_all_data_cache = NULL;
616 armv8->armv8_mmu.armv8_cache.display_cache_info = NULL;
617 return ERROR_OK;
618 }
619
620 int armv8_aarch64_state(struct target *target)
621 {
622 struct arm *arm = target_to_arm(target);
623
624 if (arm->common_magic != ARM_COMMON_MAGIC) {
625 LOG_ERROR("BUG: called for a non-ARM target");
626 return ERROR_FAIL;
627 }
628
629 LOG_USER("target halted in %s state due to %s, current mode: %s\n"
630 "cpsr: 0x%8.8" PRIx32 " pc: 0x%" PRIx64 "%s",
631 armv8_state_strings[arm->core_state],
632 debug_reason_name(target),
633 armv8_mode_name(arm->core_mode),
634 buf_get_u32(arm->cpsr->value, 0, 32),
635 buf_get_u64(arm->pc->value, 0, 64),
636 arm->is_semihosting ? ", semihosting" : "");
637
638 return ERROR_OK;
639 }
640
641 int armv8_arch_state(struct target *target)
642 {
643 static const char * const state[] = {
644 "disabled", "enabled"
645 };
646
647 struct armv8_common *armv8 = target_to_armv8(target);
648 struct arm *arm = &armv8->arm;
649
650 if (armv8->common_magic != ARMV8_COMMON_MAGIC) {
651 LOG_ERROR("BUG: called for a non-Armv8 target");
652 return ERROR_COMMAND_SYNTAX_ERROR;
653 }
654
655 if (arm->core_state == ARM_STATE_AARCH64)
656 armv8_aarch64_state(target);
657 else
658 arm_arch_state(target);
659
660 LOG_USER("MMU: %s, D-Cache: %s, I-Cache: %s",
661 state[armv8->armv8_mmu.mmu_enabled],
662 state[armv8->armv8_mmu.armv8_cache.d_u_cache_enabled],
663 state[armv8->armv8_mmu.armv8_cache.i_cache_enabled]);
664
665 if (arm->core_mode == ARM_MODE_ABT)
666 armv8_show_fault_registers(target);
667
668 if (target->debug_reason == DBG_REASON_WATCHPOINT)
669 LOG_USER("Watchpoint triggered at PC %#08x",
670 (unsigned) armv8->dpm.wp_pc);
671
672 return ERROR_OK;
673 }
674
675 static const struct {
676 unsigned id;
677 const char *name;
678 unsigned bits;
679 enum reg_type type;
680 const char *group;
681 const char *feature;
682 } armv8_regs[] = {
683 { ARMV8_R0, "x0", 64, REG_TYPE_UINT64, "general", "org.gnu.gdb.aarch64.core" },
684 { ARMV8_R1, "x1", 64, REG_TYPE_UINT64, "general", "org.gnu.gdb.aarch64.core" },
685 { ARMV8_R2, "x2", 64, REG_TYPE_UINT64, "general", "org.gnu.gdb.aarch64.core" },
686 { ARMV8_R3, "x3", 64, REG_TYPE_UINT64, "general", "org.gnu.gdb.aarch64.core" },
687 { ARMV8_R4, "x4", 64, REG_TYPE_UINT64, "general", "org.gnu.gdb.aarch64.core" },
688 { ARMV8_R5, "x5", 64, REG_TYPE_UINT64, "general", "org.gnu.gdb.aarch64.core" },
689 { ARMV8_R6, "x6", 64, REG_TYPE_UINT64, "general", "org.gnu.gdb.aarch64.core" },
690 { ARMV8_R7, "x7", 64, REG_TYPE_UINT64, "general", "org.gnu.gdb.aarch64.core" },
691 { ARMV8_R8, "x8", 64, REG_TYPE_UINT64, "general", "org.gnu.gdb.aarch64.core" },
692 { ARMV8_R9, "x9", 64, REG_TYPE_UINT64, "general", "org.gnu.gdb.aarch64.core" },
693 { ARMV8_R10, "x10", 64, REG_TYPE_UINT64, "general", "org.gnu.gdb.aarch64.core" },
694 { ARMV8_R11, "x11", 64, REG_TYPE_UINT64, "general", "org.gnu.gdb.aarch64.core" },
695 { ARMV8_R12, "x12", 64, REG_TYPE_UINT64, "general", "org.gnu.gdb.aarch64.core" },
696 { ARMV8_R13, "x13", 64, REG_TYPE_UINT64, "general", "org.gnu.gdb.aarch64.core" },
697 { ARMV8_R14, "x14", 64, REG_TYPE_UINT64, "general", "org.gnu.gdb.aarch64.core" },
698 { ARMV8_R15, "x15", 64, REG_TYPE_UINT64, "general", "org.gnu.gdb.aarch64.core" },
699 { ARMV8_R16, "x16", 64, REG_TYPE_UINT64, "general", "org.gnu.gdb.aarch64.core" },
700 { ARMV8_R17, "x17", 64, REG_TYPE_UINT64, "general", "org.gnu.gdb.aarch64.core" },
701 { ARMV8_R18, "x18", 64, REG_TYPE_UINT64, "general", "org.gnu.gdb.aarch64.core" },
702 { ARMV8_R19, "x19", 64, REG_TYPE_UINT64, "general", "org.gnu.gdb.aarch64.core" },
703 { ARMV8_R20, "x20", 64, REG_TYPE_UINT64, "general", "org.gnu.gdb.aarch64.core" },
704 { ARMV8_R21, "x21", 64, REG_TYPE_UINT64, "general", "org.gnu.gdb.aarch64.core" },
705 { ARMV8_R22, "x22", 64, REG_TYPE_UINT64, "general", "org.gnu.gdb.aarch64.core" },
706 { ARMV8_R23, "x23", 64, REG_TYPE_UINT64, "general", "org.gnu.gdb.aarch64.core" },
707 { ARMV8_R24, "x24", 64, REG_TYPE_UINT64, "general", "org.gnu.gdb.aarch64.core" },
708 { ARMV8_R25, "x25", 64, REG_TYPE_UINT64, "general", "org.gnu.gdb.aarch64.core" },
709 { ARMV8_R26, "x26", 64, REG_TYPE_UINT64, "general", "org.gnu.gdb.aarch64.core" },
710 { ARMV8_R27, "x27", 64, REG_TYPE_UINT64, "general", "org.gnu.gdb.aarch64.core" },
711 { ARMV8_R28, "x28", 64, REG_TYPE_UINT64, "general", "org.gnu.gdb.aarch64.core" },
712 { ARMV8_R29, "x29", 64, REG_TYPE_UINT64, "general", "org.gnu.gdb.aarch64.core" },
713 { ARMV8_R30, "x30", 64, REG_TYPE_UINT64, "general", "org.gnu.gdb.aarch64.core" },
714
715 { ARMV8_R31, "sp", 64, REG_TYPE_DATA_PTR, "general", "org.gnu.gdb.aarch64.core" },
716 { ARMV8_PC, "pc", 64, REG_TYPE_CODE_PTR, "general", "org.gnu.gdb.aarch64.core" },
717
718 { ARMV8_xPSR, "CPSR", 32, REG_TYPE_UINT32, "general", "org.gnu.gdb.aarch64.core" },
719 };
720
721 #define ARMV8_NUM_REGS ARRAY_SIZE(armv8_regs)
722
723
724 static int armv8_get_core_reg(struct reg *reg)
725 {
726 int retval;
727 struct arm_reg *armv8_reg = reg->arch_info;
728 struct target *target = armv8_reg->target;
729 struct arm *arm = target_to_arm(target);
730
731 if (target->state != TARGET_HALTED)
732 return ERROR_TARGET_NOT_HALTED;
733
734 retval = arm->read_core_reg(target, reg, armv8_reg->num, arm->core_mode);
735
736 return retval;
737 }
738
739 static int armv8_set_core_reg(struct reg *reg, uint8_t *buf)
740 {
741 struct arm_reg *armv8_reg = reg->arch_info;
742 struct target *target = armv8_reg->target;
743 struct arm *arm = target_to_arm(target);
744 uint64_t value = buf_get_u64(buf, 0, 64);
745
746 if (target->state != TARGET_HALTED)
747 return ERROR_TARGET_NOT_HALTED;
748
749 if (reg == arm->cpsr) {
750 armv8_set_cpsr(arm, (uint32_t)value);
751 } else {
752 buf_set_u64(reg->value, 0, 64, value);
753 reg->valid = 1;
754 }
755
756 reg->dirty = 1;
757
758 return ERROR_OK;
759 }
760
761 static const struct reg_arch_type armv8_reg_type = {
762 .get = armv8_get_core_reg,
763 .set = armv8_set_core_reg,
764 };
765
766 /** Builds cache of architecturally defined registers. */
767 struct reg_cache *armv8_build_reg_cache(struct target *target)
768 {
769 struct armv8_common *armv8 = target_to_armv8(target);
770 struct arm *arm = &armv8->arm;
771 int num_regs = ARMV8_NUM_REGS;
772 struct reg_cache **cache_p = register_get_last_cache_p(&target->reg_cache);
773 struct reg_cache *cache = malloc(sizeof(struct reg_cache));
774 struct reg *reg_list = calloc(num_regs, sizeof(struct reg));
775 struct arm_reg *arch_info = calloc(num_regs, sizeof(struct arm_reg));
776 struct reg_feature *feature;
777 int i;
778
779 /* Build the process context cache */
780 cache->name = "arm v8 registers";
781 cache->next = NULL;
782 cache->reg_list = reg_list;
783 cache->num_regs = num_regs;
784 (*cache_p) = cache;
785
786 for (i = 0; i < num_regs; i++) {
787 arch_info[i].num = armv8_regs[i].id;
788 arch_info[i].target = target;
789 arch_info[i].arm = arm;
790
791 reg_list[i].name = armv8_regs[i].name;
792 reg_list[i].size = armv8_regs[i].bits;
793 reg_list[i].value = calloc(1, 8);
794 reg_list[i].dirty = 0;
795 reg_list[i].valid = 0;
796 reg_list[i].type = &armv8_reg_type;
797 reg_list[i].arch_info = &arch_info[i];
798
799 reg_list[i].group = armv8_regs[i].group;
800 reg_list[i].number = i;
801 reg_list[i].exist = true;
802 reg_list[i].caller_save = true; /* gdb defaults to true */
803
804 feature = calloc(1, sizeof(struct reg_feature));
805 if (feature) {
806 feature->name = armv8_regs[i].feature;
807 reg_list[i].feature = feature;
808 } else
809 LOG_ERROR("unable to allocate feature list");
810
811 reg_list[i].reg_data_type = calloc(1, sizeof(struct reg_data_type));
812 if (reg_list[i].reg_data_type)
813 reg_list[i].reg_data_type->type = armv8_regs[i].type;
814 else
815 LOG_ERROR("unable to allocate reg type list");
816 }
817
818 arm->cpsr = reg_list + ARMV8_xPSR;
819 arm->pc = reg_list + ARMV8_PC;
820 arm->core_cache = cache;
821
822 return cache;
823 }
824
825 struct reg *armv8_reg_current(struct arm *arm, unsigned regnum)
826 {
827 struct reg *r;
828
829 if (regnum > (ARMV8_LAST_REG - 1))
830 return NULL;
831
832 r = arm->core_cache->reg_list + regnum;
833 return r;
834 }
835
836 const struct command_registration armv8_command_handlers[] = {
837 {
838 .chain = dap_command_handlers,
839 },
840 COMMAND_REGISTRATION_DONE
841 };
842
843
844 int armv8_get_gdb_reg_list(struct target *target,
845 struct reg **reg_list[], int *reg_list_size,
846 enum target_register_class reg_class)
847 {
848 struct arm *arm = target_to_arm(target);
849 int i;
850
851 switch (reg_class) {
852 case REG_CLASS_GENERAL:
853 case REG_CLASS_ALL:
854 *reg_list_size = ARMV8_LAST_REG;
855 *reg_list = malloc(sizeof(struct reg *) * (*reg_list_size));
856
857 for (i = 0; i < ARMV8_LAST_REG; i++)
858 (*reg_list)[i] = armv8_reg_current(arm, i);
859
860 return ERROR_OK;
861
862 default:
863 LOG_ERROR("not a valid register class type in query.");
864 return ERROR_FAIL;
865 break;
866 }
867 }

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)