target/aarch64: add AArch64 mdd and mwd support
[openocd.git] / src / target / aarch64.c
1 // SPDX-License-Identifier: GPL-2.0-or-later
2
3 /***************************************************************************
4 * Copyright (C) 2015 by David Ung *
5 * *
6 ***************************************************************************/
7
8 #ifdef HAVE_CONFIG_H
9 #include "config.h"
10 #endif
11
12 #include "breakpoints.h"
13 #include "aarch64.h"
14 #include "a64_disassembler.h"
15 #include "register.h"
16 #include "target_request.h"
17 #include "target_type.h"
18 #include "armv8_opcodes.h"
19 #include "armv8_cache.h"
20 #include "arm_coresight.h"
21 #include "arm_semihosting.h"
22 #include "jtag/interface.h"
23 #include "smp.h"
24 #include <helper/nvp.h>
25 #include <helper/time_support.h>
26
27 enum restart_mode {
28 RESTART_LAZY,
29 RESTART_SYNC,
30 };
31
32 enum halt_mode {
33 HALT_LAZY,
34 HALT_SYNC,
35 };
36
37 struct aarch64_private_config {
38 struct adiv5_private_config adiv5_config;
39 struct arm_cti *cti;
40 };
41
42 static int aarch64_poll(struct target *target);
43 static int aarch64_debug_entry(struct target *target);
44 static int aarch64_restore_context(struct target *target, bool bpwp);
45 static int aarch64_set_breakpoint(struct target *target,
46 struct breakpoint *breakpoint, uint8_t matchmode);
47 static int aarch64_set_context_breakpoint(struct target *target,
48 struct breakpoint *breakpoint, uint8_t matchmode);
49 static int aarch64_set_hybrid_breakpoint(struct target *target,
50 struct breakpoint *breakpoint);
51 static int aarch64_unset_breakpoint(struct target *target,
52 struct breakpoint *breakpoint);
53 static int aarch64_mmu(struct target *target, int *enabled);
54 static int aarch64_virt2phys(struct target *target,
55 target_addr_t virt, target_addr_t *phys);
56 static int aarch64_read_cpu_memory(struct target *target,
57 uint64_t address, uint32_t size, uint32_t count, uint8_t *buffer);
58
59 static int aarch64_restore_system_control_reg(struct target *target)
60 {
61 enum arm_mode target_mode = ARM_MODE_ANY;
62 int retval = ERROR_OK;
63 uint32_t instr;
64
65 struct aarch64_common *aarch64 = target_to_aarch64(target);
66 struct armv8_common *armv8 = target_to_armv8(target);
67
68 if (aarch64->system_control_reg != aarch64->system_control_reg_curr) {
69 aarch64->system_control_reg_curr = aarch64->system_control_reg;
70 /* LOG_INFO("cp15_control_reg: %8.8" PRIx32, cortex_v8->cp15_control_reg); */
71
72 switch (armv8->arm.core_mode) {
73 case ARMV8_64_EL0T:
74 target_mode = ARMV8_64_EL1H;
75 /* fall through */
76 case ARMV8_64_EL1T:
77 case ARMV8_64_EL1H:
78 instr = ARMV8_MSR_GP(SYSTEM_SCTLR_EL1, 0);
79 break;
80 case ARMV8_64_EL2T:
81 case ARMV8_64_EL2H:
82 instr = ARMV8_MSR_GP(SYSTEM_SCTLR_EL2, 0);
83 break;
84 case ARMV8_64_EL3H:
85 case ARMV8_64_EL3T:
86 instr = ARMV8_MSR_GP(SYSTEM_SCTLR_EL3, 0);
87 break;
88
89 case ARM_MODE_SVC:
90 case ARM_MODE_ABT:
91 case ARM_MODE_FIQ:
92 case ARM_MODE_IRQ:
93 case ARM_MODE_HYP:
94 case ARM_MODE_UND:
95 case ARM_MODE_SYS:
96 instr = ARMV4_5_MCR(15, 0, 0, 1, 0, 0);
97 break;
98
99 default:
100 LOG_ERROR("cannot read system control register in this mode: (%s : 0x%x)",
101 armv8_mode_name(armv8->arm.core_mode), armv8->arm.core_mode);
102 return ERROR_FAIL;
103 }
104
105 if (target_mode != ARM_MODE_ANY)
106 armv8_dpm_modeswitch(&armv8->dpm, target_mode);
107
108 retval = armv8->dpm.instr_write_data_r0(&armv8->dpm, instr, aarch64->system_control_reg);
109 if (retval != ERROR_OK)
110 return retval;
111
112 if (target_mode != ARM_MODE_ANY)
113 armv8_dpm_modeswitch(&armv8->dpm, ARM_MODE_ANY);
114 }
115
116 return retval;
117 }
118
119 /* modify system_control_reg in order to enable or disable mmu for :
120 * - virt2phys address conversion
121 * - read or write memory in phys or virt address */
122 static int aarch64_mmu_modify(struct target *target, int enable)
123 {
124 struct aarch64_common *aarch64 = target_to_aarch64(target);
125 struct armv8_common *armv8 = &aarch64->armv8_common;
126 int retval = ERROR_OK;
127 enum arm_mode target_mode = ARM_MODE_ANY;
128 uint32_t instr = 0;
129
130 if (enable) {
131 /* if mmu enabled at target stop and mmu not enable */
132 if (!(aarch64->system_control_reg & 0x1U)) {
133 LOG_ERROR("trying to enable mmu on target stopped with mmu disable");
134 return ERROR_FAIL;
135 }
136 if (!(aarch64->system_control_reg_curr & 0x1U))
137 aarch64->system_control_reg_curr |= 0x1U;
138 } else {
139 if (aarch64->system_control_reg_curr & 0x4U) {
140 /* data cache is active */
141 aarch64->system_control_reg_curr &= ~0x4U;
142 /* flush data cache armv8 function to be called */
143 if (armv8->armv8_mmu.armv8_cache.flush_all_data_cache)
144 armv8->armv8_mmu.armv8_cache.flush_all_data_cache(target);
145 }
146 if ((aarch64->system_control_reg_curr & 0x1U)) {
147 aarch64->system_control_reg_curr &= ~0x1U;
148 }
149 }
150
151 switch (armv8->arm.core_mode) {
152 case ARMV8_64_EL0T:
153 target_mode = ARMV8_64_EL1H;
154 /* fall through */
155 case ARMV8_64_EL1T:
156 case ARMV8_64_EL1H:
157 instr = ARMV8_MSR_GP(SYSTEM_SCTLR_EL1, 0);
158 break;
159 case ARMV8_64_EL2T:
160 case ARMV8_64_EL2H:
161 instr = ARMV8_MSR_GP(SYSTEM_SCTLR_EL2, 0);
162 break;
163 case ARMV8_64_EL3H:
164 case ARMV8_64_EL3T:
165 instr = ARMV8_MSR_GP(SYSTEM_SCTLR_EL3, 0);
166 break;
167
168 case ARM_MODE_SVC:
169 case ARM_MODE_ABT:
170 case ARM_MODE_FIQ:
171 case ARM_MODE_IRQ:
172 case ARM_MODE_HYP:
173 case ARM_MODE_UND:
174 case ARM_MODE_SYS:
175 instr = ARMV4_5_MCR(15, 0, 0, 1, 0, 0);
176 break;
177
178 default:
179 LOG_DEBUG("unknown cpu state 0x%x", armv8->arm.core_mode);
180 break;
181 }
182 if (target_mode != ARM_MODE_ANY)
183 armv8_dpm_modeswitch(&armv8->dpm, target_mode);
184
185 retval = armv8->dpm.instr_write_data_r0(&armv8->dpm, instr,
186 aarch64->system_control_reg_curr);
187
188 if (target_mode != ARM_MODE_ANY)
189 armv8_dpm_modeswitch(&armv8->dpm, ARM_MODE_ANY);
190
191 return retval;
192 }
193
194 /*
195 * Basic debug access, very low level assumes state is saved
196 */
197 static int aarch64_init_debug_access(struct target *target)
198 {
199 struct armv8_common *armv8 = target_to_armv8(target);
200 int retval;
201 uint32_t dummy;
202
203 LOG_DEBUG("%s", target_name(target));
204
205 retval = mem_ap_write_atomic_u32(armv8->debug_ap,
206 armv8->debug_base + CPUV8_DBG_OSLAR, 0);
207 if (retval != ERROR_OK) {
208 LOG_DEBUG("Examine %s failed", "oslock");
209 return retval;
210 }
211
212 /* Clear Sticky Power Down status Bit in PRSR to enable access to
213 the registers in the Core Power Domain */
214 retval = mem_ap_read_atomic_u32(armv8->debug_ap,
215 armv8->debug_base + CPUV8_DBG_PRSR, &dummy);
216 if (retval != ERROR_OK)
217 return retval;
218
219 /*
220 * Static CTI configuration:
221 * Channel 0 -> trigger outputs HALT request to PE
222 * Channel 1 -> trigger outputs Resume request to PE
223 * Gate all channel trigger events from entering the CTM
224 */
225
226 /* Enable CTI */
227 retval = arm_cti_enable(armv8->cti, true);
228 /* By default, gate all channel events to and from the CTM */
229 if (retval == ERROR_OK)
230 retval = arm_cti_write_reg(armv8->cti, CTI_GATE, 0);
231 /* output halt requests to PE on channel 0 event */
232 if (retval == ERROR_OK)
233 retval = arm_cti_write_reg(armv8->cti, CTI_OUTEN0, CTI_CHNL(0));
234 /* output restart requests to PE on channel 1 event */
235 if (retval == ERROR_OK)
236 retval = arm_cti_write_reg(armv8->cti, CTI_OUTEN1, CTI_CHNL(1));
237 if (retval != ERROR_OK)
238 return retval;
239
240 /* Resync breakpoint registers */
241
242 return ERROR_OK;
243 }
244
245 /* Write to memory mapped registers directly with no cache or mmu handling */
246 static int aarch64_dap_write_memap_register_u32(struct target *target,
247 target_addr_t address,
248 uint32_t value)
249 {
250 int retval;
251 struct armv8_common *armv8 = target_to_armv8(target);
252
253 retval = mem_ap_write_atomic_u32(armv8->debug_ap, address, value);
254
255 return retval;
256 }
257
258 static int aarch64_dpm_setup(struct aarch64_common *a8, uint64_t debug)
259 {
260 struct arm_dpm *dpm = &a8->armv8_common.dpm;
261 int retval;
262
263 dpm->arm = &a8->armv8_common.arm;
264 dpm->didr = debug;
265
266 retval = armv8_dpm_setup(dpm);
267 if (retval == ERROR_OK)
268 retval = armv8_dpm_initialize(dpm);
269
270 return retval;
271 }
272
273 static int aarch64_set_dscr_bits(struct target *target, unsigned long bit_mask, unsigned long value)
274 {
275 struct armv8_common *armv8 = target_to_armv8(target);
276 return armv8_set_dbgreg_bits(armv8, CPUV8_DBG_DSCR, bit_mask, value);
277 }
278
279 static int aarch64_check_state_one(struct target *target,
280 uint32_t mask, uint32_t val, int *p_result, uint32_t *p_prsr)
281 {
282 struct armv8_common *armv8 = target_to_armv8(target);
283 uint32_t prsr;
284 int retval;
285
286 retval = mem_ap_read_atomic_u32(armv8->debug_ap,
287 armv8->debug_base + CPUV8_DBG_PRSR, &prsr);
288 if (retval != ERROR_OK)
289 return retval;
290
291 if (p_prsr)
292 *p_prsr = prsr;
293
294 if (p_result)
295 *p_result = (prsr & mask) == (val & mask);
296
297 return ERROR_OK;
298 }
299
300 static int aarch64_wait_halt_one(struct target *target)
301 {
302 int retval = ERROR_OK;
303 uint32_t prsr;
304
305 int64_t then = timeval_ms();
306 for (;;) {
307 int halted;
308
309 retval = aarch64_check_state_one(target, PRSR_HALT, PRSR_HALT, &halted, &prsr);
310 if (retval != ERROR_OK || halted)
311 break;
312
313 if (timeval_ms() > then + 1000) {
314 retval = ERROR_TARGET_TIMEOUT;
315 LOG_DEBUG("target %s timeout, prsr=0x%08"PRIx32, target_name(target), prsr);
316 break;
317 }
318 }
319 return retval;
320 }
321
322 static int aarch64_prepare_halt_smp(struct target *target, bool exc_target, struct target **p_first)
323 {
324 int retval = ERROR_OK;
325 struct target_list *head;
326 struct target *first = NULL;
327
328 LOG_DEBUG("target %s exc %i", target_name(target), exc_target);
329
330 foreach_smp_target(head, target->smp_targets) {
331 struct target *curr = head->target;
332 struct armv8_common *armv8 = target_to_armv8(curr);
333
334 if (exc_target && curr == target)
335 continue;
336 if (!target_was_examined(curr))
337 continue;
338 if (curr->state != TARGET_RUNNING)
339 continue;
340
341 /* HACK: mark this target as prepared for halting */
342 curr->debug_reason = DBG_REASON_DBGRQ;
343
344 /* open the gate for channel 0 to let HALT requests pass to the CTM */
345 retval = arm_cti_ungate_channel(armv8->cti, 0);
346 if (retval == ERROR_OK)
347 retval = aarch64_set_dscr_bits(curr, DSCR_HDE, DSCR_HDE);
348 if (retval != ERROR_OK)
349 break;
350
351 LOG_DEBUG("target %s prepared", target_name(curr));
352
353 if (!first)
354 first = curr;
355 }
356
357 if (p_first) {
358 if (exc_target && first)
359 *p_first = first;
360 else
361 *p_first = target;
362 }
363
364 return retval;
365 }
366
367 static int aarch64_halt_one(struct target *target, enum halt_mode mode)
368 {
369 int retval = ERROR_OK;
370 struct armv8_common *armv8 = target_to_armv8(target);
371
372 LOG_DEBUG("%s", target_name(target));
373
374 /* allow Halting Debug Mode */
375 retval = aarch64_set_dscr_bits(target, DSCR_HDE, DSCR_HDE);
376 if (retval != ERROR_OK)
377 return retval;
378
379 /* trigger an event on channel 0, this outputs a halt request to the PE */
380 retval = arm_cti_pulse_channel(armv8->cti, 0);
381 if (retval != ERROR_OK)
382 return retval;
383
384 if (mode == HALT_SYNC) {
385 retval = aarch64_wait_halt_one(target);
386 if (retval != ERROR_OK) {
387 if (retval == ERROR_TARGET_TIMEOUT)
388 LOG_ERROR("Timeout waiting for target %s halt", target_name(target));
389 return retval;
390 }
391 }
392
393 return ERROR_OK;
394 }
395
396 static int aarch64_halt_smp(struct target *target, bool exc_target)
397 {
398 struct target *next = target;
399 int retval;
400
401 /* prepare halt on all PEs of the group */
402 retval = aarch64_prepare_halt_smp(target, exc_target, &next);
403
404 if (exc_target && next == target)
405 return retval;
406
407 /* halt the target PE */
408 if (retval == ERROR_OK)
409 retval = aarch64_halt_one(next, HALT_LAZY);
410
411 if (retval != ERROR_OK)
412 return retval;
413
414 /* wait for all PEs to halt */
415 int64_t then = timeval_ms();
416 for (;;) {
417 bool all_halted = true;
418 struct target_list *head;
419 struct target *curr;
420
421 foreach_smp_target(head, target->smp_targets) {
422 int halted;
423
424 curr = head->target;
425
426 if (!target_was_examined(curr))
427 continue;
428
429 retval = aarch64_check_state_one(curr, PRSR_HALT, PRSR_HALT, &halted, NULL);
430 if (retval != ERROR_OK || !halted) {
431 all_halted = false;
432 break;
433 }
434 }
435
436 if (all_halted)
437 break;
438
439 if (timeval_ms() > then + 1000) {
440 retval = ERROR_TARGET_TIMEOUT;
441 break;
442 }
443
444 /*
445 * HACK: on Hi6220 there are 8 cores organized in 2 clusters
446 * and it looks like the CTI's are not connected by a common
447 * trigger matrix. It seems that we need to halt one core in each
448 * cluster explicitly. So if we find that a core has not halted
449 * yet, we trigger an explicit halt for the second cluster.
450 */
451 retval = aarch64_halt_one(curr, HALT_LAZY);
452 if (retval != ERROR_OK)
453 break;
454 }
455
456 return retval;
457 }
458
459 static int update_halt_gdb(struct target *target, enum target_debug_reason debug_reason)
460 {
461 struct target *gdb_target = NULL;
462 struct target_list *head;
463 struct target *curr;
464
465 if (debug_reason == DBG_REASON_NOTHALTED) {
466 LOG_DEBUG("Halting remaining targets in SMP group");
467 aarch64_halt_smp(target, true);
468 }
469
470 /* poll all targets in the group, but skip the target that serves GDB */
471 foreach_smp_target(head, target->smp_targets) {
472 curr = head->target;
473 /* skip calling context */
474 if (curr == target)
475 continue;
476 if (!target_was_examined(curr))
477 continue;
478 /* skip targets that were already halted */
479 if (curr->state == TARGET_HALTED)
480 continue;
481 /* remember the gdb_service->target */
482 if (curr->gdb_service)
483 gdb_target = curr->gdb_service->target;
484 /* skip it */
485 if (curr == gdb_target)
486 continue;
487
488 /* avoid recursion in aarch64_poll() */
489 curr->smp = 0;
490 aarch64_poll(curr);
491 curr->smp = 1;
492 }
493
494 /* after all targets were updated, poll the gdb serving target */
495 if (gdb_target && gdb_target != target)
496 aarch64_poll(gdb_target);
497
498 return ERROR_OK;
499 }
500
501 /*
502 * Aarch64 Run control
503 */
504
505 static int aarch64_poll(struct target *target)
506 {
507 enum target_state prev_target_state;
508 int retval = ERROR_OK;
509 int halted;
510
511 retval = aarch64_check_state_one(target,
512 PRSR_HALT, PRSR_HALT, &halted, NULL);
513 if (retval != ERROR_OK)
514 return retval;
515
516 if (halted) {
517 prev_target_state = target->state;
518 if (prev_target_state != TARGET_HALTED) {
519 enum target_debug_reason debug_reason = target->debug_reason;
520
521 /* We have a halting debug event */
522 target->state = TARGET_HALTED;
523 LOG_DEBUG("Target %s halted", target_name(target));
524 retval = aarch64_debug_entry(target);
525 if (retval != ERROR_OK)
526 return retval;
527
528 if (target->smp)
529 update_halt_gdb(target, debug_reason);
530
531 if (arm_semihosting(target, &retval) != 0)
532 return retval;
533
534 switch (prev_target_state) {
535 case TARGET_RUNNING:
536 case TARGET_UNKNOWN:
537 case TARGET_RESET:
538 target_call_event_callbacks(target, TARGET_EVENT_HALTED);
539 break;
540 case TARGET_DEBUG_RUNNING:
541 target_call_event_callbacks(target, TARGET_EVENT_DEBUG_HALTED);
542 break;
543 default:
544 break;
545 }
546 }
547 } else
548 target->state = TARGET_RUNNING;
549
550 return retval;
551 }
552
553 static int aarch64_halt(struct target *target)
554 {
555 struct armv8_common *armv8 = target_to_armv8(target);
556 armv8->last_run_control_op = ARMV8_RUNCONTROL_HALT;
557
558 if (target->smp)
559 return aarch64_halt_smp(target, false);
560
561 return aarch64_halt_one(target, HALT_SYNC);
562 }
563
564 static int aarch64_restore_one(struct target *target, int current,
565 uint64_t *address, int handle_breakpoints, int debug_execution)
566 {
567 struct armv8_common *armv8 = target_to_armv8(target);
568 struct arm *arm = &armv8->arm;
569 int retval;
570 uint64_t resume_pc;
571
572 LOG_DEBUG("%s", target_name(target));
573
574 if (!debug_execution)
575 target_free_all_working_areas(target);
576
577 /* current = 1: continue on current pc, otherwise continue at <address> */
578 resume_pc = buf_get_u64(arm->pc->value, 0, 64);
579 if (!current)
580 resume_pc = *address;
581 else
582 *address = resume_pc;
583
584 /* Make sure that the Armv7 gdb thumb fixups does not
585 * kill the return address
586 */
587 switch (arm->core_state) {
588 case ARM_STATE_ARM:
589 resume_pc &= 0xFFFFFFFC;
590 break;
591 case ARM_STATE_AARCH64:
592 resume_pc &= 0xFFFFFFFFFFFFFFFCULL;
593 break;
594 case ARM_STATE_THUMB:
595 case ARM_STATE_THUMB_EE:
596 /* When the return address is loaded into PC
597 * bit 0 must be 1 to stay in Thumb state
598 */
599 resume_pc |= 0x1;
600 break;
601 case ARM_STATE_JAZELLE:
602 LOG_ERROR("How do I resume into Jazelle state??");
603 return ERROR_FAIL;
604 }
605 LOG_DEBUG("resume pc = 0x%016" PRIx64, resume_pc);
606 buf_set_u64(arm->pc->value, 0, 64, resume_pc);
607 arm->pc->dirty = true;
608 arm->pc->valid = true;
609
610 /* called it now before restoring context because it uses cpu
611 * register r0 for restoring system control register */
612 retval = aarch64_restore_system_control_reg(target);
613 if (retval == ERROR_OK)
614 retval = aarch64_restore_context(target, handle_breakpoints);
615
616 return retval;
617 }
618
619 /**
620 * prepare single target for restart
621 *
622 *
623 */
624 static int aarch64_prepare_restart_one(struct target *target)
625 {
626 struct armv8_common *armv8 = target_to_armv8(target);
627 int retval;
628 uint32_t dscr;
629 uint32_t tmp;
630
631 LOG_DEBUG("%s", target_name(target));
632
633 retval = mem_ap_read_atomic_u32(armv8->debug_ap,
634 armv8->debug_base + CPUV8_DBG_DSCR, &dscr);
635 if (retval != ERROR_OK)
636 return retval;
637
638 if ((dscr & DSCR_ITE) == 0)
639 LOG_ERROR("DSCR.ITE must be set before leaving debug!");
640 if ((dscr & DSCR_ERR) != 0)
641 LOG_ERROR("DSCR.ERR must be cleared before leaving debug!");
642
643 /* acknowledge a pending CTI halt event */
644 retval = arm_cti_ack_events(armv8->cti, CTI_TRIG(HALT));
645 /*
646 * open the CTI gate for channel 1 so that the restart events
647 * get passed along to all PEs. Also close gate for channel 0
648 * to isolate the PE from halt events.
649 */
650 if (retval == ERROR_OK)
651 retval = arm_cti_ungate_channel(armv8->cti, 1);
652 if (retval == ERROR_OK)
653 retval = arm_cti_gate_channel(armv8->cti, 0);
654
655 /* make sure that DSCR.HDE is set */
656 if (retval == ERROR_OK) {
657 dscr |= DSCR_HDE;
658 retval = mem_ap_write_atomic_u32(armv8->debug_ap,
659 armv8->debug_base + CPUV8_DBG_DSCR, dscr);
660 }
661
662 if (retval == ERROR_OK) {
663 /* clear sticky bits in PRSR, SDR is now 0 */
664 retval = mem_ap_read_atomic_u32(armv8->debug_ap,
665 armv8->debug_base + CPUV8_DBG_PRSR, &tmp);
666 }
667
668 return retval;
669 }
670
671 static int aarch64_do_restart_one(struct target *target, enum restart_mode mode)
672 {
673 struct armv8_common *armv8 = target_to_armv8(target);
674 int retval;
675
676 LOG_DEBUG("%s", target_name(target));
677
678 /* trigger an event on channel 1, generates a restart request to the PE */
679 retval = arm_cti_pulse_channel(armv8->cti, 1);
680 if (retval != ERROR_OK)
681 return retval;
682
683 if (mode == RESTART_SYNC) {
684 int64_t then = timeval_ms();
685 for (;;) {
686 int resumed;
687 /*
688 * if PRSR.SDR is set now, the target did restart, even
689 * if it's now already halted again (e.g. due to breakpoint)
690 */
691 retval = aarch64_check_state_one(target,
692 PRSR_SDR, PRSR_SDR, &resumed, NULL);
693 if (retval != ERROR_OK || resumed)
694 break;
695
696 if (timeval_ms() > then + 1000) {
697 LOG_ERROR("%s: Timeout waiting for resume"PRIx32, target_name(target));
698 retval = ERROR_TARGET_TIMEOUT;
699 break;
700 }
701 }
702 }
703
704 if (retval != ERROR_OK)
705 return retval;
706
707 target->debug_reason = DBG_REASON_NOTHALTED;
708 target->state = TARGET_RUNNING;
709
710 return ERROR_OK;
711 }
712
713 static int aarch64_restart_one(struct target *target, enum restart_mode mode)
714 {
715 int retval;
716
717 LOG_DEBUG("%s", target_name(target));
718
719 retval = aarch64_prepare_restart_one(target);
720 if (retval == ERROR_OK)
721 retval = aarch64_do_restart_one(target, mode);
722
723 return retval;
724 }
725
726 /*
727 * prepare all but the current target for restart
728 */
729 static int aarch64_prep_restart_smp(struct target *target, int handle_breakpoints, struct target **p_first)
730 {
731 int retval = ERROR_OK;
732 struct target_list *head;
733 struct target *first = NULL;
734 uint64_t address;
735
736 foreach_smp_target(head, target->smp_targets) {
737 struct target *curr = head->target;
738
739 /* skip calling target */
740 if (curr == target)
741 continue;
742 if (!target_was_examined(curr))
743 continue;
744 if (curr->state != TARGET_HALTED)
745 continue;
746
747 /* resume at current address, not in step mode */
748 retval = aarch64_restore_one(curr, 1, &address, handle_breakpoints, 0);
749 if (retval == ERROR_OK)
750 retval = aarch64_prepare_restart_one(curr);
751 if (retval != ERROR_OK) {
752 LOG_ERROR("failed to restore target %s", target_name(curr));
753 break;
754 }
755 /* remember the first valid target in the group */
756 if (!first)
757 first = curr;
758 }
759
760 if (p_first)
761 *p_first = first;
762
763 return retval;
764 }
765
766
767 static int aarch64_step_restart_smp(struct target *target)
768 {
769 int retval = ERROR_OK;
770 struct target_list *head;
771 struct target *first = NULL;
772
773 LOG_DEBUG("%s", target_name(target));
774
775 retval = aarch64_prep_restart_smp(target, 0, &first);
776 if (retval != ERROR_OK)
777 return retval;
778
779 if (first)
780 retval = aarch64_do_restart_one(first, RESTART_LAZY);
781 if (retval != ERROR_OK) {
782 LOG_DEBUG("error restarting target %s", target_name(first));
783 return retval;
784 }
785
786 int64_t then = timeval_ms();
787 for (;;) {
788 struct target *curr = target;
789 bool all_resumed = true;
790
791 foreach_smp_target(head, target->smp_targets) {
792 uint32_t prsr;
793 int resumed;
794
795 curr = head->target;
796
797 if (curr == target)
798 continue;
799
800 if (!target_was_examined(curr))
801 continue;
802
803 retval = aarch64_check_state_one(curr,
804 PRSR_SDR, PRSR_SDR, &resumed, &prsr);
805 if (retval != ERROR_OK || (!resumed && (prsr & PRSR_HALT))) {
806 all_resumed = false;
807 break;
808 }
809
810 if (curr->state != TARGET_RUNNING) {
811 curr->state = TARGET_RUNNING;
812 curr->debug_reason = DBG_REASON_NOTHALTED;
813 target_call_event_callbacks(curr, TARGET_EVENT_RESUMED);
814 }
815 }
816
817 if (all_resumed)
818 break;
819
820 if (timeval_ms() > then + 1000) {
821 LOG_ERROR("%s: timeout waiting for target resume", __func__);
822 retval = ERROR_TARGET_TIMEOUT;
823 break;
824 }
825 /*
826 * HACK: on Hi6220 there are 8 cores organized in 2 clusters
827 * and it looks like the CTI's are not connected by a common
828 * trigger matrix. It seems that we need to halt one core in each
829 * cluster explicitly. So if we find that a core has not halted
830 * yet, we trigger an explicit resume for the second cluster.
831 */
832 retval = aarch64_do_restart_one(curr, RESTART_LAZY);
833 if (retval != ERROR_OK)
834 break;
835 }
836
837 return retval;
838 }
839
840 static int aarch64_resume(struct target *target, int current,
841 target_addr_t address, int handle_breakpoints, int debug_execution)
842 {
843 int retval = 0;
844 uint64_t addr = address;
845
846 struct armv8_common *armv8 = target_to_armv8(target);
847 armv8->last_run_control_op = ARMV8_RUNCONTROL_RESUME;
848
849 if (target->state != TARGET_HALTED) {
850 LOG_TARGET_ERROR(target, "not halted");
851 return ERROR_TARGET_NOT_HALTED;
852 }
853
854 /*
855 * If this target is part of a SMP group, prepare the others
856 * targets for resuming. This involves restoring the complete
857 * target register context and setting up CTI gates to accept
858 * resume events from the trigger matrix.
859 */
860 if (target->smp) {
861 retval = aarch64_prep_restart_smp(target, handle_breakpoints, NULL);
862 if (retval != ERROR_OK)
863 return retval;
864 }
865
866 /* all targets prepared, restore and restart the current target */
867 retval = aarch64_restore_one(target, current, &addr, handle_breakpoints,
868 debug_execution);
869 if (retval == ERROR_OK)
870 retval = aarch64_restart_one(target, RESTART_SYNC);
871 if (retval != ERROR_OK)
872 return retval;
873
874 if (target->smp) {
875 int64_t then = timeval_ms();
876 for (;;) {
877 struct target *curr = target;
878 struct target_list *head;
879 bool all_resumed = true;
880
881 foreach_smp_target(head, target->smp_targets) {
882 uint32_t prsr;
883 int resumed;
884
885 curr = head->target;
886 if (curr == target)
887 continue;
888 if (!target_was_examined(curr))
889 continue;
890
891 retval = aarch64_check_state_one(curr,
892 PRSR_SDR, PRSR_SDR, &resumed, &prsr);
893 if (retval != ERROR_OK || (!resumed && (prsr & PRSR_HALT))) {
894 all_resumed = false;
895 break;
896 }
897
898 if (curr->state != TARGET_RUNNING) {
899 curr->state = TARGET_RUNNING;
900 curr->debug_reason = DBG_REASON_NOTHALTED;
901 target_call_event_callbacks(curr, TARGET_EVENT_RESUMED);
902 }
903 }
904
905 if (all_resumed)
906 break;
907
908 if (timeval_ms() > then + 1000) {
909 LOG_ERROR("%s: timeout waiting for target %s to resume", __func__, target_name(curr));
910 retval = ERROR_TARGET_TIMEOUT;
911 break;
912 }
913
914 /*
915 * HACK: on Hi6220 there are 8 cores organized in 2 clusters
916 * and it looks like the CTI's are not connected by a common
917 * trigger matrix. It seems that we need to halt one core in each
918 * cluster explicitly. So if we find that a core has not halted
919 * yet, we trigger an explicit resume for the second cluster.
920 */
921 retval = aarch64_do_restart_one(curr, RESTART_LAZY);
922 if (retval != ERROR_OK)
923 break;
924 }
925 }
926
927 if (retval != ERROR_OK)
928 return retval;
929
930 target->debug_reason = DBG_REASON_NOTHALTED;
931
932 if (!debug_execution) {
933 target->state = TARGET_RUNNING;
934 target_call_event_callbacks(target, TARGET_EVENT_RESUMED);
935 LOG_DEBUG("target resumed at 0x%" PRIx64, addr);
936 } else {
937 target->state = TARGET_DEBUG_RUNNING;
938 target_call_event_callbacks(target, TARGET_EVENT_DEBUG_RESUMED);
939 LOG_DEBUG("target debug resumed at 0x%" PRIx64, addr);
940 }
941
942 return ERROR_OK;
943 }
944
945 static int aarch64_debug_entry(struct target *target)
946 {
947 int retval = ERROR_OK;
948 struct armv8_common *armv8 = target_to_armv8(target);
949 struct arm_dpm *dpm = &armv8->dpm;
950 enum arm_state core_state;
951 uint32_t dscr;
952
953 /* make sure to clear all sticky errors */
954 retval = mem_ap_write_atomic_u32(armv8->debug_ap,
955 armv8->debug_base + CPUV8_DBG_DRCR, DRCR_CSE);
956 if (retval == ERROR_OK)
957 retval = mem_ap_read_atomic_u32(armv8->debug_ap,
958 armv8->debug_base + CPUV8_DBG_DSCR, &dscr);
959 if (retval == ERROR_OK)
960 retval = arm_cti_ack_events(armv8->cti, CTI_TRIG(HALT));
961
962 if (retval != ERROR_OK)
963 return retval;
964
965 LOG_DEBUG("%s dscr = 0x%08" PRIx32, target_name(target), dscr);
966
967 dpm->dscr = dscr;
968 core_state = armv8_dpm_get_core_state(dpm);
969 armv8_select_opcodes(armv8, core_state == ARM_STATE_AARCH64);
970 armv8_select_reg_access(armv8, core_state == ARM_STATE_AARCH64);
971
972 /* close the CTI gate for all events */
973 if (retval == ERROR_OK)
974 retval = arm_cti_write_reg(armv8->cti, CTI_GATE, 0);
975 /* discard async exceptions */
976 if (retval == ERROR_OK)
977 retval = dpm->instr_cpsr_sync(dpm);
978 if (retval != ERROR_OK)
979 return retval;
980
981 /* Examine debug reason */
982 armv8_dpm_report_dscr(dpm, dscr);
983
984 /* save the memory address that triggered the watchpoint */
985 if (target->debug_reason == DBG_REASON_WATCHPOINT) {
986 uint32_t tmp;
987
988 retval = mem_ap_read_atomic_u32(armv8->debug_ap,
989 armv8->debug_base + CPUV8_DBG_EDWAR0, &tmp);
990 if (retval != ERROR_OK)
991 return retval;
992 target_addr_t edwar = tmp;
993
994 /* EDWAR[63:32] has unknown content in aarch32 state */
995 if (core_state == ARM_STATE_AARCH64) {
996 retval = mem_ap_read_atomic_u32(armv8->debug_ap,
997 armv8->debug_base + CPUV8_DBG_EDWAR1, &tmp);
998 if (retval != ERROR_OK)
999 return retval;
1000 edwar |= ((target_addr_t)tmp) << 32;
1001 }
1002
1003 armv8->dpm.wp_addr = edwar;
1004 }
1005
1006 retval = armv8_dpm_read_current_registers(&armv8->dpm);
1007
1008 if (retval == ERROR_OK && armv8->post_debug_entry)
1009 retval = armv8->post_debug_entry(target);
1010
1011 return retval;
1012 }
1013
1014 static int aarch64_post_debug_entry(struct target *target)
1015 {
1016 struct aarch64_common *aarch64 = target_to_aarch64(target);
1017 struct armv8_common *armv8 = &aarch64->armv8_common;
1018 int retval;
1019 enum arm_mode target_mode = ARM_MODE_ANY;
1020 uint32_t instr;
1021
1022 switch (armv8->arm.core_mode) {
1023 case ARMV8_64_EL0T:
1024 target_mode = ARMV8_64_EL1H;
1025 /* fall through */
1026 case ARMV8_64_EL1T:
1027 case ARMV8_64_EL1H:
1028 instr = ARMV8_MRS(SYSTEM_SCTLR_EL1, 0);
1029 break;
1030 case ARMV8_64_EL2T:
1031 case ARMV8_64_EL2H:
1032 instr = ARMV8_MRS(SYSTEM_SCTLR_EL2, 0);
1033 break;
1034 case ARMV8_64_EL3H:
1035 case ARMV8_64_EL3T:
1036 instr = ARMV8_MRS(SYSTEM_SCTLR_EL3, 0);
1037 break;
1038
1039 case ARM_MODE_SVC:
1040 case ARM_MODE_ABT:
1041 case ARM_MODE_FIQ:
1042 case ARM_MODE_IRQ:
1043 case ARM_MODE_HYP:
1044 case ARM_MODE_UND:
1045 case ARM_MODE_SYS:
1046 instr = ARMV4_5_MRC(15, 0, 0, 1, 0, 0);
1047 break;
1048
1049 default:
1050 LOG_ERROR("cannot read system control register in this mode: (%s : 0x%x)",
1051 armv8_mode_name(armv8->arm.core_mode), armv8->arm.core_mode);
1052 return ERROR_FAIL;
1053 }
1054
1055 if (target_mode != ARM_MODE_ANY)
1056 armv8_dpm_modeswitch(&armv8->dpm, target_mode);
1057
1058 retval = armv8->dpm.instr_read_data_r0(&armv8->dpm, instr, &aarch64->system_control_reg);
1059 if (retval != ERROR_OK)
1060 return retval;
1061
1062 if (target_mode != ARM_MODE_ANY)
1063 armv8_dpm_modeswitch(&armv8->dpm, ARM_MODE_ANY);
1064
1065 LOG_DEBUG("System_register: %8.8" PRIx32, aarch64->system_control_reg);
1066 aarch64->system_control_reg_curr = aarch64->system_control_reg;
1067
1068 if (armv8->armv8_mmu.armv8_cache.info == -1) {
1069 armv8_identify_cache(armv8);
1070 armv8_read_mpidr(armv8);
1071 }
1072 if (armv8->is_armv8r) {
1073 armv8->armv8_mmu.mmu_enabled = 0;
1074 } else {
1075 armv8->armv8_mmu.mmu_enabled =
1076 (aarch64->system_control_reg & 0x1U) ? 1 : 0;
1077 }
1078 armv8->armv8_mmu.armv8_cache.d_u_cache_enabled =
1079 (aarch64->system_control_reg & 0x4U) ? 1 : 0;
1080 armv8->armv8_mmu.armv8_cache.i_cache_enabled =
1081 (aarch64->system_control_reg & 0x1000U) ? 1 : 0;
1082 return ERROR_OK;
1083 }
1084
1085 /*
1086 * single-step a target
1087 */
1088 static int aarch64_step(struct target *target, int current, target_addr_t address,
1089 int handle_breakpoints)
1090 {
1091 struct armv8_common *armv8 = target_to_armv8(target);
1092 struct aarch64_common *aarch64 = target_to_aarch64(target);
1093 int saved_retval = ERROR_OK;
1094 int poll_retval;
1095 int retval;
1096 uint32_t edecr;
1097
1098 armv8->last_run_control_op = ARMV8_RUNCONTROL_STEP;
1099
1100 if (target->state != TARGET_HALTED) {
1101 LOG_TARGET_ERROR(target, "not halted");
1102 return ERROR_TARGET_NOT_HALTED;
1103 }
1104
1105 retval = mem_ap_read_atomic_u32(armv8->debug_ap,
1106 armv8->debug_base + CPUV8_DBG_EDECR, &edecr);
1107 /* make sure EDECR.SS is not set when restoring the register */
1108
1109 if (retval == ERROR_OK) {
1110 edecr &= ~0x4;
1111 /* set EDECR.SS to enter hardware step mode */
1112 retval = mem_ap_write_atomic_u32(armv8->debug_ap,
1113 armv8->debug_base + CPUV8_DBG_EDECR, (edecr|0x4));
1114 }
1115 /* disable interrupts while stepping */
1116 if (retval == ERROR_OK && aarch64->isrmasking_mode == AARCH64_ISRMASK_ON)
1117 retval = aarch64_set_dscr_bits(target, 0x3 << 22, 0x3 << 22);
1118 /* bail out if stepping setup has failed */
1119 if (retval != ERROR_OK)
1120 return retval;
1121
1122 if (target->smp && (current == 1)) {
1123 /*
1124 * isolate current target so that it doesn't get resumed
1125 * together with the others
1126 */
1127 retval = arm_cti_gate_channel(armv8->cti, 1);
1128 /* resume all other targets in the group */
1129 if (retval == ERROR_OK)
1130 retval = aarch64_step_restart_smp(target);
1131 if (retval != ERROR_OK) {
1132 LOG_ERROR("Failed to restart non-stepping targets in SMP group");
1133 return retval;
1134 }
1135 LOG_DEBUG("Restarted all non-stepping targets in SMP group");
1136 }
1137
1138 /* all other targets running, restore and restart the current target */
1139 retval = aarch64_restore_one(target, current, &address, 0, 0);
1140 if (retval == ERROR_OK)
1141 retval = aarch64_restart_one(target, RESTART_LAZY);
1142
1143 if (retval != ERROR_OK)
1144 return retval;
1145
1146 LOG_DEBUG("target step-resumed at 0x%" PRIx64, address);
1147 if (!handle_breakpoints)
1148 target_call_event_callbacks(target, TARGET_EVENT_RESUMED);
1149
1150 int64_t then = timeval_ms();
1151 for (;;) {
1152 int stepped;
1153 uint32_t prsr;
1154
1155 retval = aarch64_check_state_one(target,
1156 PRSR_SDR|PRSR_HALT, PRSR_SDR|PRSR_HALT, &stepped, &prsr);
1157 if (retval != ERROR_OK || stepped)
1158 break;
1159
1160 if (timeval_ms() > then + 100) {
1161 LOG_ERROR("timeout waiting for target %s halt after step",
1162 target_name(target));
1163 retval = ERROR_TARGET_TIMEOUT;
1164 break;
1165 }
1166 }
1167
1168 /*
1169 * At least on one SoC (Renesas R8A7795) stepping over a WFI instruction
1170 * causes a timeout. The core takes the step but doesn't complete it and so
1171 * debug state is never entered. However, you can manually halt the core
1172 * as an external debug even is also a WFI wakeup event.
1173 */
1174 if (retval == ERROR_TARGET_TIMEOUT)
1175 saved_retval = aarch64_halt_one(target, HALT_SYNC);
1176
1177 poll_retval = aarch64_poll(target);
1178
1179 /* restore EDECR */
1180 retval = mem_ap_write_atomic_u32(armv8->debug_ap,
1181 armv8->debug_base + CPUV8_DBG_EDECR, edecr);
1182 if (retval != ERROR_OK)
1183 return retval;
1184
1185 /* restore interrupts */
1186 if (aarch64->isrmasking_mode == AARCH64_ISRMASK_ON) {
1187 retval = aarch64_set_dscr_bits(target, 0x3 << 22, 0);
1188 if (retval != ERROR_OK)
1189 return ERROR_OK;
1190 }
1191
1192 if (saved_retval != ERROR_OK)
1193 return saved_retval;
1194
1195 if (poll_retval != ERROR_OK)
1196 return poll_retval;
1197
1198 return ERROR_OK;
1199 }
1200
1201 static int aarch64_restore_context(struct target *target, bool bpwp)
1202 {
1203 struct armv8_common *armv8 = target_to_armv8(target);
1204 struct arm *arm = &armv8->arm;
1205
1206 int retval;
1207
1208 LOG_DEBUG("%s", target_name(target));
1209
1210 if (armv8->pre_restore_context)
1211 armv8->pre_restore_context(target);
1212
1213 retval = armv8_dpm_write_dirty_registers(&armv8->dpm, bpwp);
1214 if (retval == ERROR_OK) {
1215 /* registers are now invalid */
1216 register_cache_invalidate(arm->core_cache);
1217 register_cache_invalidate(arm->core_cache->next);
1218 }
1219
1220 return retval;
1221 }
1222
1223 /*
1224 * Cortex-A8 Breakpoint and watchpoint functions
1225 */
1226
1227 /* Setup hardware Breakpoint Register Pair */
1228 static int aarch64_set_breakpoint(struct target *target,
1229 struct breakpoint *breakpoint, uint8_t matchmode)
1230 {
1231 int retval;
1232 int brp_i = 0;
1233 uint32_t control;
1234 uint8_t byte_addr_select = 0x0F;
1235 struct aarch64_common *aarch64 = target_to_aarch64(target);
1236 struct armv8_common *armv8 = &aarch64->armv8_common;
1237 struct aarch64_brp *brp_list = aarch64->brp_list;
1238
1239 if (breakpoint->is_set) {
1240 LOG_WARNING("breakpoint already set");
1241 return ERROR_OK;
1242 }
1243
1244 if (breakpoint->type == BKPT_HARD) {
1245 int64_t bpt_value;
1246 while (brp_list[brp_i].used && (brp_i < aarch64->brp_num))
1247 brp_i++;
1248 if (brp_i >= aarch64->brp_num) {
1249 LOG_ERROR("ERROR Can not find free Breakpoint Register Pair");
1250 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
1251 }
1252 breakpoint_hw_set(breakpoint, brp_i);
1253 if (breakpoint->length == 2)
1254 byte_addr_select = (3 << (breakpoint->address & 0x02));
1255 control = ((matchmode & 0x7) << 20)
1256 | (1 << 13)
1257 | (byte_addr_select << 5)
1258 | (3 << 1) | 1;
1259 brp_list[brp_i].used = 1;
1260 brp_list[brp_i].value = breakpoint->address & 0xFFFFFFFFFFFFFFFCULL;
1261 brp_list[brp_i].control = control;
1262 bpt_value = brp_list[brp_i].value;
1263
1264 retval = aarch64_dap_write_memap_register_u32(target, armv8->debug_base
1265 + CPUV8_DBG_BVR_BASE + 16 * brp_list[brp_i].brpn,
1266 (uint32_t)(bpt_value & 0xFFFFFFFF));
1267 if (retval != ERROR_OK)
1268 return retval;
1269 retval = aarch64_dap_write_memap_register_u32(target, armv8->debug_base
1270 + CPUV8_DBG_BVR_BASE + 4 + 16 * brp_list[brp_i].brpn,
1271 (uint32_t)(bpt_value >> 32));
1272 if (retval != ERROR_OK)
1273 return retval;
1274
1275 retval = aarch64_dap_write_memap_register_u32(target, armv8->debug_base
1276 + CPUV8_DBG_BCR_BASE + 16 * brp_list[brp_i].brpn,
1277 brp_list[brp_i].control);
1278 if (retval != ERROR_OK)
1279 return retval;
1280 LOG_DEBUG("brp %i control 0x%0" PRIx32 " value 0x%" TARGET_PRIxADDR, brp_i,
1281 brp_list[brp_i].control,
1282 brp_list[brp_i].value);
1283
1284 } else if (breakpoint->type == BKPT_SOFT) {
1285 uint32_t opcode;
1286 uint8_t code[4];
1287
1288 if (armv8_dpm_get_core_state(&armv8->dpm) == ARM_STATE_AARCH64) {
1289 opcode = ARMV8_HLT(11);
1290
1291 if (breakpoint->length != 4)
1292 LOG_ERROR("bug: breakpoint length should be 4 in AArch64 mode");
1293 } else {
1294 /**
1295 * core_state is ARM_STATE_ARM
1296 * in that case the opcode depends on breakpoint length:
1297 * - if length == 4 => A32 opcode
1298 * - if length == 2 => T32 opcode
1299 * - if length == 3 => T32 opcode (refer to gdb doc : ARM-Breakpoint-Kinds)
1300 * in that case the length should be changed from 3 to 4 bytes
1301 **/
1302 opcode = (breakpoint->length == 4) ? ARMV8_HLT_A1(11) :
1303 (uint32_t) (ARMV8_HLT_T1(11) | ARMV8_HLT_T1(11) << 16);
1304
1305 if (breakpoint->length == 3)
1306 breakpoint->length = 4;
1307 }
1308
1309 buf_set_u32(code, 0, 32, opcode);
1310
1311 retval = target_read_memory(target,
1312 breakpoint->address & 0xFFFFFFFFFFFFFFFEULL,
1313 breakpoint->length, 1,
1314 breakpoint->orig_instr);
1315 if (retval != ERROR_OK)
1316 return retval;
1317
1318 armv8_cache_d_inner_flush_virt(armv8,
1319 breakpoint->address & 0xFFFFFFFFFFFFFFFEULL,
1320 breakpoint->length);
1321
1322 retval = target_write_memory(target,
1323 breakpoint->address & 0xFFFFFFFFFFFFFFFEULL,
1324 breakpoint->length, 1, code);
1325 if (retval != ERROR_OK)
1326 return retval;
1327
1328 armv8_cache_d_inner_flush_virt(armv8,
1329 breakpoint->address & 0xFFFFFFFFFFFFFFFEULL,
1330 breakpoint->length);
1331
1332 armv8_cache_i_inner_inval_virt(armv8,
1333 breakpoint->address & 0xFFFFFFFFFFFFFFFEULL,
1334 breakpoint->length);
1335
1336 breakpoint->is_set = true;
1337 }
1338
1339 /* Ensure that halting debug mode is enable */
1340 retval = aarch64_set_dscr_bits(target, DSCR_HDE, DSCR_HDE);
1341 if (retval != ERROR_OK) {
1342 LOG_DEBUG("Failed to set DSCR.HDE");
1343 return retval;
1344 }
1345
1346 return ERROR_OK;
1347 }
1348
1349 static int aarch64_set_context_breakpoint(struct target *target,
1350 struct breakpoint *breakpoint, uint8_t matchmode)
1351 {
1352 int retval = ERROR_FAIL;
1353 int brp_i = 0;
1354 uint32_t control;
1355 uint8_t byte_addr_select = 0x0F;
1356 struct aarch64_common *aarch64 = target_to_aarch64(target);
1357 struct armv8_common *armv8 = &aarch64->armv8_common;
1358 struct aarch64_brp *brp_list = aarch64->brp_list;
1359
1360 if (breakpoint->is_set) {
1361 LOG_WARNING("breakpoint already set");
1362 return retval;
1363 }
1364 /*check available context BRPs*/
1365 while ((brp_list[brp_i].used ||
1366 (brp_list[brp_i].type != BRP_CONTEXT)) && (brp_i < aarch64->brp_num))
1367 brp_i++;
1368
1369 if (brp_i >= aarch64->brp_num) {
1370 LOG_ERROR("ERROR Can not find free Breakpoint Register Pair");
1371 return ERROR_FAIL;
1372 }
1373
1374 breakpoint_hw_set(breakpoint, brp_i);
1375 control = ((matchmode & 0x7) << 20)
1376 | (1 << 13)
1377 | (byte_addr_select << 5)
1378 | (3 << 1) | 1;
1379 brp_list[brp_i].used = 1;
1380 brp_list[brp_i].value = (breakpoint->asid);
1381 brp_list[brp_i].control = control;
1382 retval = aarch64_dap_write_memap_register_u32(target, armv8->debug_base
1383 + CPUV8_DBG_BVR_BASE + 16 * brp_list[brp_i].brpn,
1384 brp_list[brp_i].value);
1385 if (retval != ERROR_OK)
1386 return retval;
1387 retval = aarch64_dap_write_memap_register_u32(target, armv8->debug_base
1388 + CPUV8_DBG_BCR_BASE + 16 * brp_list[brp_i].brpn,
1389 brp_list[brp_i].control);
1390 if (retval != ERROR_OK)
1391 return retval;
1392 LOG_DEBUG("brp %i control 0x%0" PRIx32 " value 0x%" TARGET_PRIxADDR, brp_i,
1393 brp_list[brp_i].control,
1394 brp_list[brp_i].value);
1395 return ERROR_OK;
1396
1397 }
1398
1399 static int aarch64_set_hybrid_breakpoint(struct target *target, struct breakpoint *breakpoint)
1400 {
1401 int retval = ERROR_FAIL;
1402 int brp_1 = 0; /* holds the contextID pair */
1403 int brp_2 = 0; /* holds the IVA pair */
1404 uint32_t control_ctx, control_iva;
1405 uint8_t ctx_byte_addr_select = 0x0F;
1406 uint8_t iva_byte_addr_select = 0x0F;
1407 uint8_t ctx_machmode = 0x03;
1408 uint8_t iva_machmode = 0x01;
1409 struct aarch64_common *aarch64 = target_to_aarch64(target);
1410 struct armv8_common *armv8 = &aarch64->armv8_common;
1411 struct aarch64_brp *brp_list = aarch64->brp_list;
1412
1413 if (breakpoint->is_set) {
1414 LOG_WARNING("breakpoint already set");
1415 return retval;
1416 }
1417 /*check available context BRPs*/
1418 while ((brp_list[brp_1].used ||
1419 (brp_list[brp_1].type != BRP_CONTEXT)) && (brp_1 < aarch64->brp_num))
1420 brp_1++;
1421
1422 LOG_DEBUG("brp(CTX) found num: %d", brp_1);
1423 if (brp_1 >= aarch64->brp_num) {
1424 LOG_ERROR("ERROR Can not find free Breakpoint Register Pair");
1425 return ERROR_FAIL;
1426 }
1427
1428 while ((brp_list[brp_2].used ||
1429 (brp_list[brp_2].type != BRP_NORMAL)) && (brp_2 < aarch64->brp_num))
1430 brp_2++;
1431
1432 LOG_DEBUG("brp(IVA) found num: %d", brp_2);
1433 if (brp_2 >= aarch64->brp_num) {
1434 LOG_ERROR("ERROR Can not find free Breakpoint Register Pair");
1435 return ERROR_FAIL;
1436 }
1437
1438 breakpoint_hw_set(breakpoint, brp_1);
1439 breakpoint->linked_brp = brp_2;
1440 control_ctx = ((ctx_machmode & 0x7) << 20)
1441 | (brp_2 << 16)
1442 | (0 << 14)
1443 | (ctx_byte_addr_select << 5)
1444 | (3 << 1) | 1;
1445 brp_list[brp_1].used = 1;
1446 brp_list[brp_1].value = (breakpoint->asid);
1447 brp_list[brp_1].control = control_ctx;
1448 retval = aarch64_dap_write_memap_register_u32(target, armv8->debug_base
1449 + CPUV8_DBG_BVR_BASE + 16 * brp_list[brp_1].brpn,
1450 brp_list[brp_1].value);
1451 if (retval != ERROR_OK)
1452 return retval;
1453 retval = aarch64_dap_write_memap_register_u32(target, armv8->debug_base
1454 + CPUV8_DBG_BCR_BASE + 16 * brp_list[brp_1].brpn,
1455 brp_list[brp_1].control);
1456 if (retval != ERROR_OK)
1457 return retval;
1458
1459 control_iva = ((iva_machmode & 0x7) << 20)
1460 | (brp_1 << 16)
1461 | (1 << 13)
1462 | (iva_byte_addr_select << 5)
1463 | (3 << 1) | 1;
1464 brp_list[brp_2].used = 1;
1465 brp_list[brp_2].value = breakpoint->address & 0xFFFFFFFFFFFFFFFCULL;
1466 brp_list[brp_2].control = control_iva;
1467 retval = aarch64_dap_write_memap_register_u32(target, armv8->debug_base
1468 + CPUV8_DBG_BVR_BASE + 16 * brp_list[brp_2].brpn,
1469 brp_list[brp_2].value & 0xFFFFFFFF);
1470 if (retval != ERROR_OK)
1471 return retval;
1472 retval = aarch64_dap_write_memap_register_u32(target, armv8->debug_base
1473 + CPUV8_DBG_BVR_BASE + 4 + 16 * brp_list[brp_2].brpn,
1474 brp_list[brp_2].value >> 32);
1475 if (retval != ERROR_OK)
1476 return retval;
1477 retval = aarch64_dap_write_memap_register_u32(target, armv8->debug_base
1478 + CPUV8_DBG_BCR_BASE + 16 * brp_list[brp_2].brpn,
1479 brp_list[brp_2].control);
1480 if (retval != ERROR_OK)
1481 return retval;
1482
1483 return ERROR_OK;
1484 }
1485
1486 static int aarch64_unset_breakpoint(struct target *target, struct breakpoint *breakpoint)
1487 {
1488 int retval;
1489 struct aarch64_common *aarch64 = target_to_aarch64(target);
1490 struct armv8_common *armv8 = &aarch64->armv8_common;
1491 struct aarch64_brp *brp_list = aarch64->brp_list;
1492
1493 if (!breakpoint->is_set) {
1494 LOG_WARNING("breakpoint not set");
1495 return ERROR_OK;
1496 }
1497
1498 if (breakpoint->type == BKPT_HARD) {
1499 if ((breakpoint->address != 0) && (breakpoint->asid != 0)) {
1500 int brp_i = breakpoint->number;
1501 int brp_j = breakpoint->linked_brp;
1502 if (brp_i >= aarch64->brp_num) {
1503 LOG_DEBUG("Invalid BRP number in breakpoint");
1504 return ERROR_OK;
1505 }
1506 LOG_DEBUG("rbp %i control 0x%0" PRIx32 " value 0x%" TARGET_PRIxADDR, brp_i,
1507 brp_list[brp_i].control, brp_list[brp_i].value);
1508 brp_list[brp_i].used = 0;
1509 brp_list[brp_i].value = 0;
1510 brp_list[brp_i].control = 0;
1511 retval = aarch64_dap_write_memap_register_u32(target, armv8->debug_base
1512 + CPUV8_DBG_BCR_BASE + 16 * brp_list[brp_i].brpn,
1513 brp_list[brp_i].control);
1514 if (retval != ERROR_OK)
1515 return retval;
1516 retval = aarch64_dap_write_memap_register_u32(target, armv8->debug_base
1517 + CPUV8_DBG_BVR_BASE + 16 * brp_list[brp_i].brpn,
1518 (uint32_t)brp_list[brp_i].value);
1519 if (retval != ERROR_OK)
1520 return retval;
1521 retval = aarch64_dap_write_memap_register_u32(target, armv8->debug_base
1522 + CPUV8_DBG_BVR_BASE + 4 + 16 * brp_list[brp_i].brpn,
1523 (uint32_t)brp_list[brp_i].value);
1524 if (retval != ERROR_OK)
1525 return retval;
1526 if ((brp_j < 0) || (brp_j >= aarch64->brp_num)) {
1527 LOG_DEBUG("Invalid BRP number in breakpoint");
1528 return ERROR_OK;
1529 }
1530 LOG_DEBUG("rbp %i control 0x%0" PRIx32 " value 0x%0" PRIx64, brp_j,
1531 brp_list[brp_j].control, brp_list[brp_j].value);
1532 brp_list[brp_j].used = 0;
1533 brp_list[brp_j].value = 0;
1534 brp_list[brp_j].control = 0;
1535 retval = aarch64_dap_write_memap_register_u32(target, armv8->debug_base
1536 + CPUV8_DBG_BCR_BASE + 16 * brp_list[brp_j].brpn,
1537 brp_list[brp_j].control);
1538 if (retval != ERROR_OK)
1539 return retval;
1540 retval = aarch64_dap_write_memap_register_u32(target, armv8->debug_base
1541 + CPUV8_DBG_BVR_BASE + 16 * brp_list[brp_j].brpn,
1542 (uint32_t)brp_list[brp_j].value);
1543 if (retval != ERROR_OK)
1544 return retval;
1545 retval = aarch64_dap_write_memap_register_u32(target, armv8->debug_base
1546 + CPUV8_DBG_BVR_BASE + 4 + 16 * brp_list[brp_j].brpn,
1547 (uint32_t)brp_list[brp_j].value);
1548 if (retval != ERROR_OK)
1549 return retval;
1550
1551 breakpoint->linked_brp = 0;
1552 breakpoint->is_set = false;
1553 return ERROR_OK;
1554
1555 } else {
1556 int brp_i = breakpoint->number;
1557 if (brp_i >= aarch64->brp_num) {
1558 LOG_DEBUG("Invalid BRP number in breakpoint");
1559 return ERROR_OK;
1560 }
1561 LOG_DEBUG("rbp %i control 0x%0" PRIx32 " value 0x%0" PRIx64, brp_i,
1562 brp_list[brp_i].control, brp_list[brp_i].value);
1563 brp_list[brp_i].used = 0;
1564 brp_list[brp_i].value = 0;
1565 brp_list[brp_i].control = 0;
1566 retval = aarch64_dap_write_memap_register_u32(target, armv8->debug_base
1567 + CPUV8_DBG_BCR_BASE + 16 * brp_list[brp_i].brpn,
1568 brp_list[brp_i].control);
1569 if (retval != ERROR_OK)
1570 return retval;
1571 retval = aarch64_dap_write_memap_register_u32(target, armv8->debug_base
1572 + CPUV8_DBG_BVR_BASE + 16 * brp_list[brp_i].brpn,
1573 brp_list[brp_i].value);
1574 if (retval != ERROR_OK)
1575 return retval;
1576
1577 retval = aarch64_dap_write_memap_register_u32(target, armv8->debug_base
1578 + CPUV8_DBG_BVR_BASE + 4 + 16 * brp_list[brp_i].brpn,
1579 (uint32_t)brp_list[brp_i].value);
1580 if (retval != ERROR_OK)
1581 return retval;
1582 breakpoint->is_set = false;
1583 return ERROR_OK;
1584 }
1585 } else {
1586 /* restore original instruction (kept in target endianness) */
1587
1588 armv8_cache_d_inner_flush_virt(armv8,
1589 breakpoint->address & 0xFFFFFFFFFFFFFFFEULL,
1590 breakpoint->length);
1591
1592 if (breakpoint->length == 4) {
1593 retval = target_write_memory(target,
1594 breakpoint->address & 0xFFFFFFFFFFFFFFFEULL,
1595 4, 1, breakpoint->orig_instr);
1596 if (retval != ERROR_OK)
1597 return retval;
1598 } else {
1599 retval = target_write_memory(target,
1600 breakpoint->address & 0xFFFFFFFFFFFFFFFEULL,
1601 2, 1, breakpoint->orig_instr);
1602 if (retval != ERROR_OK)
1603 return retval;
1604 }
1605
1606 armv8_cache_d_inner_flush_virt(armv8,
1607 breakpoint->address & 0xFFFFFFFFFFFFFFFEULL,
1608 breakpoint->length);
1609
1610 armv8_cache_i_inner_inval_virt(armv8,
1611 breakpoint->address & 0xFFFFFFFFFFFFFFFEULL,
1612 breakpoint->length);
1613 }
1614 breakpoint->is_set = false;
1615
1616 return ERROR_OK;
1617 }
1618
1619 static int aarch64_add_breakpoint(struct target *target,
1620 struct breakpoint *breakpoint)
1621 {
1622 struct aarch64_common *aarch64 = target_to_aarch64(target);
1623
1624 if ((breakpoint->type == BKPT_HARD) && (aarch64->brp_num_available < 1)) {
1625 LOG_INFO("no hardware breakpoint available");
1626 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
1627 }
1628
1629 if (breakpoint->type == BKPT_HARD)
1630 aarch64->brp_num_available--;
1631
1632 return aarch64_set_breakpoint(target, breakpoint, 0x00); /* Exact match */
1633 }
1634
1635 static int aarch64_add_context_breakpoint(struct target *target,
1636 struct breakpoint *breakpoint)
1637 {
1638 struct aarch64_common *aarch64 = target_to_aarch64(target);
1639
1640 if ((breakpoint->type == BKPT_HARD) && (aarch64->brp_num_available < 1)) {
1641 LOG_INFO("no hardware breakpoint available");
1642 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
1643 }
1644
1645 if (breakpoint->type == BKPT_HARD)
1646 aarch64->brp_num_available--;
1647
1648 return aarch64_set_context_breakpoint(target, breakpoint, 0x02); /* asid match */
1649 }
1650
1651 static int aarch64_add_hybrid_breakpoint(struct target *target,
1652 struct breakpoint *breakpoint)
1653 {
1654 struct aarch64_common *aarch64 = target_to_aarch64(target);
1655
1656 if ((breakpoint->type == BKPT_HARD) && (aarch64->brp_num_available < 1)) {
1657 LOG_INFO("no hardware breakpoint available");
1658 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
1659 }
1660
1661 if (breakpoint->type == BKPT_HARD)
1662 aarch64->brp_num_available--;
1663
1664 return aarch64_set_hybrid_breakpoint(target, breakpoint); /* ??? */
1665 }
1666
1667 static int aarch64_remove_breakpoint(struct target *target, struct breakpoint *breakpoint)
1668 {
1669 struct aarch64_common *aarch64 = target_to_aarch64(target);
1670
1671 #if 0
1672 /* It is perfectly possible to remove breakpoints while the target is running */
1673 if (target->state != TARGET_HALTED) {
1674 LOG_WARNING("target not halted");
1675 return ERROR_TARGET_NOT_HALTED;
1676 }
1677 #endif
1678
1679 if (breakpoint->is_set) {
1680 aarch64_unset_breakpoint(target, breakpoint);
1681 if (breakpoint->type == BKPT_HARD)
1682 aarch64->brp_num_available++;
1683 }
1684
1685 return ERROR_OK;
1686 }
1687
1688 /* Setup hardware Watchpoint Register Pair */
1689 static int aarch64_set_watchpoint(struct target *target,
1690 struct watchpoint *watchpoint)
1691 {
1692 int retval;
1693 int wp_i = 0;
1694 uint32_t control, offset, length;
1695 struct aarch64_common *aarch64 = target_to_aarch64(target);
1696 struct armv8_common *armv8 = &aarch64->armv8_common;
1697 struct aarch64_brp *wp_list = aarch64->wp_list;
1698
1699 if (watchpoint->is_set) {
1700 LOG_WARNING("watchpoint already set");
1701 return ERROR_OK;
1702 }
1703
1704 while (wp_list[wp_i].used && (wp_i < aarch64->wp_num))
1705 wp_i++;
1706 if (wp_i >= aarch64->wp_num) {
1707 LOG_ERROR("ERROR Can not find free Watchpoint Register Pair");
1708 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
1709 }
1710
1711 control = (1 << 0) /* enable */
1712 | (3 << 1) /* both user and privileged access */
1713 | (1 << 13); /* higher mode control */
1714
1715 switch (watchpoint->rw) {
1716 case WPT_READ:
1717 control |= 1 << 3;
1718 break;
1719 case WPT_WRITE:
1720 control |= 2 << 3;
1721 break;
1722 case WPT_ACCESS:
1723 control |= 3 << 3;
1724 break;
1725 }
1726
1727 /* Match up to 8 bytes. */
1728 offset = watchpoint->address & 7;
1729 length = watchpoint->length;
1730 if (offset + length > sizeof(uint64_t)) {
1731 length = sizeof(uint64_t) - offset;
1732 LOG_WARNING("Adjust watchpoint match inside 8-byte boundary");
1733 }
1734 for (; length > 0; offset++, length--)
1735 control |= (1 << offset) << 5;
1736
1737 wp_list[wp_i].value = watchpoint->address & 0xFFFFFFFFFFFFFFF8ULL;
1738 wp_list[wp_i].control = control;
1739
1740 retval = aarch64_dap_write_memap_register_u32(target, armv8->debug_base
1741 + CPUV8_DBG_WVR_BASE + 16 * wp_list[wp_i].brpn,
1742 (uint32_t)(wp_list[wp_i].value & 0xFFFFFFFF));
1743 if (retval != ERROR_OK)
1744 return retval;
1745 retval = aarch64_dap_write_memap_register_u32(target, armv8->debug_base
1746 + CPUV8_DBG_WVR_BASE + 4 + 16 * wp_list[wp_i].brpn,
1747 (uint32_t)(wp_list[wp_i].value >> 32));
1748 if (retval != ERROR_OK)
1749 return retval;
1750
1751 retval = aarch64_dap_write_memap_register_u32(target, armv8->debug_base
1752 + CPUV8_DBG_WCR_BASE + 16 * wp_list[wp_i].brpn,
1753 control);
1754 if (retval != ERROR_OK)
1755 return retval;
1756 LOG_DEBUG("wp %i control 0x%0" PRIx32 " value 0x%" TARGET_PRIxADDR, wp_i,
1757 wp_list[wp_i].control, wp_list[wp_i].value);
1758
1759 /* Ensure that halting debug mode is enable */
1760 retval = aarch64_set_dscr_bits(target, DSCR_HDE, DSCR_HDE);
1761 if (retval != ERROR_OK) {
1762 LOG_DEBUG("Failed to set DSCR.HDE");
1763 return retval;
1764 }
1765
1766 wp_list[wp_i].used = 1;
1767 watchpoint_set(watchpoint, wp_i);
1768
1769 return ERROR_OK;
1770 }
1771
1772 /* Clear hardware Watchpoint Register Pair */
1773 static int aarch64_unset_watchpoint(struct target *target,
1774 struct watchpoint *watchpoint)
1775 {
1776 int retval;
1777 struct aarch64_common *aarch64 = target_to_aarch64(target);
1778 struct armv8_common *armv8 = &aarch64->armv8_common;
1779 struct aarch64_brp *wp_list = aarch64->wp_list;
1780
1781 if (!watchpoint->is_set) {
1782 LOG_WARNING("watchpoint not set");
1783 return ERROR_OK;
1784 }
1785
1786 int wp_i = watchpoint->number;
1787 if (wp_i >= aarch64->wp_num) {
1788 LOG_DEBUG("Invalid WP number in watchpoint");
1789 return ERROR_OK;
1790 }
1791 LOG_DEBUG("rwp %i control 0x%0" PRIx32 " value 0x%0" PRIx64, wp_i,
1792 wp_list[wp_i].control, wp_list[wp_i].value);
1793 wp_list[wp_i].used = 0;
1794 wp_list[wp_i].value = 0;
1795 wp_list[wp_i].control = 0;
1796 retval = aarch64_dap_write_memap_register_u32(target, armv8->debug_base
1797 + CPUV8_DBG_WCR_BASE + 16 * wp_list[wp_i].brpn,
1798 wp_list[wp_i].control);
1799 if (retval != ERROR_OK)
1800 return retval;
1801 retval = aarch64_dap_write_memap_register_u32(target, armv8->debug_base
1802 + CPUV8_DBG_WVR_BASE + 16 * wp_list[wp_i].brpn,
1803 wp_list[wp_i].value);
1804 if (retval != ERROR_OK)
1805 return retval;
1806
1807 retval = aarch64_dap_write_memap_register_u32(target, armv8->debug_base
1808 + CPUV8_DBG_WVR_BASE + 4 + 16 * wp_list[wp_i].brpn,
1809 (uint32_t)wp_list[wp_i].value);
1810 if (retval != ERROR_OK)
1811 return retval;
1812 watchpoint->is_set = false;
1813
1814 return ERROR_OK;
1815 }
1816
1817 static int aarch64_add_watchpoint(struct target *target,
1818 struct watchpoint *watchpoint)
1819 {
1820 int retval;
1821 struct aarch64_common *aarch64 = target_to_aarch64(target);
1822
1823 if (aarch64->wp_num_available < 1) {
1824 LOG_INFO("no hardware watchpoint available");
1825 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
1826 }
1827
1828 retval = aarch64_set_watchpoint(target, watchpoint);
1829 if (retval == ERROR_OK)
1830 aarch64->wp_num_available--;
1831
1832 return retval;
1833 }
1834
1835 static int aarch64_remove_watchpoint(struct target *target,
1836 struct watchpoint *watchpoint)
1837 {
1838 struct aarch64_common *aarch64 = target_to_aarch64(target);
1839
1840 if (watchpoint->is_set) {
1841 aarch64_unset_watchpoint(target, watchpoint);
1842 aarch64->wp_num_available++;
1843 }
1844
1845 return ERROR_OK;
1846 }
1847
1848 /**
1849 * find out which watchpoint hits
1850 * get exception address and compare the address to watchpoints
1851 */
1852 static int aarch64_hit_watchpoint(struct target *target,
1853 struct watchpoint **hit_watchpoint)
1854 {
1855 if (target->debug_reason != DBG_REASON_WATCHPOINT)
1856 return ERROR_FAIL;
1857
1858 struct armv8_common *armv8 = target_to_armv8(target);
1859
1860 target_addr_t exception_address;
1861 struct watchpoint *wp;
1862
1863 exception_address = armv8->dpm.wp_addr;
1864
1865 if (exception_address == 0xFFFFFFFF)
1866 return ERROR_FAIL;
1867
1868 for (wp = target->watchpoints; wp; wp = wp->next)
1869 if (exception_address >= wp->address && exception_address < (wp->address + wp->length)) {
1870 *hit_watchpoint = wp;
1871 return ERROR_OK;
1872 }
1873
1874 return ERROR_FAIL;
1875 }
1876
1877 /*
1878 * Cortex-A8 Reset functions
1879 */
1880
1881 static int aarch64_enable_reset_catch(struct target *target, bool enable)
1882 {
1883 struct armv8_common *armv8 = target_to_armv8(target);
1884 uint32_t edecr;
1885 int retval;
1886
1887 retval = mem_ap_read_atomic_u32(armv8->debug_ap,
1888 armv8->debug_base + CPUV8_DBG_EDECR, &edecr);
1889 LOG_DEBUG("EDECR = 0x%08" PRIx32 ", enable=%d", edecr, enable);
1890 if (retval != ERROR_OK)
1891 return retval;
1892
1893 if (enable)
1894 edecr |= ECR_RCE;
1895 else
1896 edecr &= ~ECR_RCE;
1897
1898 return mem_ap_write_atomic_u32(armv8->debug_ap,
1899 armv8->debug_base + CPUV8_DBG_EDECR, edecr);
1900 }
1901
1902 static int aarch64_clear_reset_catch(struct target *target)
1903 {
1904 struct armv8_common *armv8 = target_to_armv8(target);
1905 uint32_t edesr;
1906 int retval;
1907 bool was_triggered;
1908
1909 /* check if Reset Catch debug event triggered as expected */
1910 retval = mem_ap_read_atomic_u32(armv8->debug_ap,
1911 armv8->debug_base + CPUV8_DBG_EDESR, &edesr);
1912 if (retval != ERROR_OK)
1913 return retval;
1914
1915 was_triggered = !!(edesr & ESR_RC);
1916 LOG_DEBUG("Reset Catch debug event %s",
1917 was_triggered ? "triggered" : "NOT triggered!");
1918
1919 if (was_triggered) {
1920 /* clear pending Reset Catch debug event */
1921 edesr &= ~ESR_RC;
1922 retval = mem_ap_write_atomic_u32(armv8->debug_ap,
1923 armv8->debug_base + CPUV8_DBG_EDESR, edesr);
1924 if (retval != ERROR_OK)
1925 return retval;
1926 }
1927
1928 return ERROR_OK;
1929 }
1930
1931 static int aarch64_assert_reset(struct target *target)
1932 {
1933 struct armv8_common *armv8 = target_to_armv8(target);
1934 enum reset_types reset_config = jtag_get_reset_config();
1935 int retval;
1936
1937 LOG_DEBUG(" ");
1938
1939 /* Issue some kind of warm reset. */
1940 if (target_has_event_action(target, TARGET_EVENT_RESET_ASSERT))
1941 target_handle_event(target, TARGET_EVENT_RESET_ASSERT);
1942 else if (reset_config & RESET_HAS_SRST) {
1943 bool srst_asserted = false;
1944
1945 if (target->reset_halt && !(reset_config & RESET_SRST_PULLS_TRST)) {
1946 if (target_was_examined(target)) {
1947
1948 if (reset_config & RESET_SRST_NO_GATING) {
1949 /*
1950 * SRST needs to be asserted *before* Reset Catch
1951 * debug event can be set up.
1952 */
1953 adapter_assert_reset();
1954 srst_asserted = true;
1955 }
1956
1957 /* make sure to clear all sticky errors */
1958 mem_ap_write_atomic_u32(armv8->debug_ap,
1959 armv8->debug_base + CPUV8_DBG_DRCR, DRCR_CSE);
1960
1961 /* set up Reset Catch debug event to halt the CPU after reset */
1962 retval = aarch64_enable_reset_catch(target, true);
1963 if (retval != ERROR_OK)
1964 LOG_WARNING("%s: Error enabling Reset Catch debug event; the CPU will not halt immediately after reset!",
1965 target_name(target));
1966 } else {
1967 LOG_WARNING("%s: Target not examined, will not halt immediately after reset!",
1968 target_name(target));
1969 }
1970 }
1971
1972 /* REVISIT handle "pulls" cases, if there's
1973 * hardware that needs them to work.
1974 */
1975 if (!srst_asserted)
1976 adapter_assert_reset();
1977 } else {
1978 LOG_ERROR("%s: how to reset?", target_name(target));
1979 return ERROR_FAIL;
1980 }
1981
1982 /* registers are now invalid */
1983 if (target_was_examined(target)) {
1984 register_cache_invalidate(armv8->arm.core_cache);
1985 register_cache_invalidate(armv8->arm.core_cache->next);
1986 }
1987
1988 target->state = TARGET_RESET;
1989
1990 return ERROR_OK;
1991 }
1992
1993 static int aarch64_deassert_reset(struct target *target)
1994 {
1995 int retval;
1996
1997 LOG_DEBUG(" ");
1998
1999 /* be certain SRST is off */
2000 adapter_deassert_reset();
2001
2002 if (!target_was_examined(target))
2003 return ERROR_OK;
2004
2005 retval = aarch64_init_debug_access(target);
2006 if (retval != ERROR_OK)
2007 return retval;
2008
2009 retval = aarch64_poll(target);
2010 if (retval != ERROR_OK)
2011 return retval;
2012
2013 if (target->reset_halt) {
2014 /* clear pending Reset Catch debug event */
2015 retval = aarch64_clear_reset_catch(target);
2016 if (retval != ERROR_OK)
2017 LOG_WARNING("%s: Clearing Reset Catch debug event failed",
2018 target_name(target));
2019
2020 /* disable Reset Catch debug event */
2021 retval = aarch64_enable_reset_catch(target, false);
2022 if (retval != ERROR_OK)
2023 LOG_WARNING("%s: Disabling Reset Catch debug event failed",
2024 target_name(target));
2025
2026 if (target->state != TARGET_HALTED) {
2027 LOG_WARNING("%s: ran after reset and before halt ...",
2028 target_name(target));
2029 if (target_was_examined(target)) {
2030 retval = aarch64_halt_one(target, HALT_LAZY);
2031 if (retval != ERROR_OK)
2032 return retval;
2033 } else {
2034 target->state = TARGET_UNKNOWN;
2035 }
2036 }
2037 }
2038
2039 return ERROR_OK;
2040 }
2041
2042 static int aarch64_write_cpu_memory_slow(struct target *target,
2043 uint32_t size, uint32_t count, const uint8_t *buffer, uint32_t *dscr)
2044 {
2045 struct armv8_common *armv8 = target_to_armv8(target);
2046 struct arm_dpm *dpm = &armv8->dpm;
2047 struct arm *arm = &armv8->arm;
2048 int retval;
2049
2050 if (size > 4 && arm->core_state != ARM_STATE_AARCH64) {
2051 LOG_ERROR("memory write sizes greater than 4 bytes is only supported for AArch64 state");
2052 return ERROR_FAIL;
2053 }
2054
2055 armv8_reg_current(arm, 1)->dirty = true;
2056
2057 /* change DCC to normal mode if necessary */
2058 if (*dscr & DSCR_MA) {
2059 *dscr &= ~DSCR_MA;
2060 retval = mem_ap_write_atomic_u32(armv8->debug_ap,
2061 armv8->debug_base + CPUV8_DBG_DSCR, *dscr);
2062 if (retval != ERROR_OK)
2063 return retval;
2064 }
2065
2066 while (count) {
2067 uint32_t opcode;
2068 uint64_t data;
2069
2070 /* write the data to store into DTRRX (and DTRTX for 64-bit) */
2071 if (size == 1)
2072 data = *buffer;
2073 else if (size == 2)
2074 data = target_buffer_get_u16(target, buffer);
2075 else if (size == 4)
2076 data = target_buffer_get_u32(target, buffer);
2077 else
2078 data = target_buffer_get_u64(target, buffer);
2079
2080 retval = mem_ap_write_atomic_u32(armv8->debug_ap,
2081 armv8->debug_base + CPUV8_DBG_DTRRX, (uint32_t)data);
2082 if (retval == ERROR_OK && size > 4)
2083 retval = mem_ap_write_atomic_u32(armv8->debug_ap,
2084 armv8->debug_base + CPUV8_DBG_DTRTX, (uint32_t)(data >> 32));
2085 if (retval != ERROR_OK)
2086 return retval;
2087
2088 if (arm->core_state == ARM_STATE_AARCH64)
2089 if (size <= 4)
2090 retval = dpm->instr_execute(dpm, ARMV8_MRS(SYSTEM_DBG_DTRRX_EL0, 1));
2091 else
2092 retval = dpm->instr_execute(dpm, ARMV8_MRS(SYSTEM_DBG_DBGDTR_EL0, 1));
2093 else
2094 retval = dpm->instr_execute(dpm, ARMV4_5_MRC(14, 0, 1, 0, 5, 0));
2095 if (retval != ERROR_OK)
2096 return retval;
2097
2098 if (size == 1)
2099 opcode = armv8_opcode(armv8, ARMV8_OPC_STRB_IP);
2100 else if (size == 2)
2101 opcode = armv8_opcode(armv8, ARMV8_OPC_STRH_IP);
2102 else if (size == 4)
2103 opcode = armv8_opcode(armv8, ARMV8_OPC_STRW_IP);
2104 else
2105 opcode = armv8_opcode(armv8, ARMV8_OPC_STRD_IP);
2106
2107 retval = dpm->instr_execute(dpm, opcode);
2108 if (retval != ERROR_OK)
2109 return retval;
2110
2111 /* Advance */
2112 buffer += size;
2113 --count;
2114 }
2115
2116 return ERROR_OK;
2117 }
2118
2119 static int aarch64_write_cpu_memory_fast(struct target *target,
2120 uint32_t count, const uint8_t *buffer, uint32_t *dscr)
2121 {
2122 struct armv8_common *armv8 = target_to_armv8(target);
2123 struct arm *arm = &armv8->arm;
2124 int retval;
2125
2126 armv8_reg_current(arm, 1)->dirty = true;
2127
2128 /* Step 1.d - Change DCC to memory mode */
2129 *dscr |= DSCR_MA;
2130 retval = mem_ap_write_atomic_u32(armv8->debug_ap,
2131 armv8->debug_base + CPUV8_DBG_DSCR, *dscr);
2132 if (retval != ERROR_OK)
2133 return retval;
2134
2135
2136 /* Step 2.a - Do the write */
2137 retval = mem_ap_write_buf_noincr(armv8->debug_ap,
2138 buffer, 4, count, armv8->debug_base + CPUV8_DBG_DTRRX);
2139 if (retval != ERROR_OK)
2140 return retval;
2141
2142 /* Step 3.a - Switch DTR mode back to Normal mode */
2143 *dscr &= ~DSCR_MA;
2144 retval = mem_ap_write_atomic_u32(armv8->debug_ap,
2145 armv8->debug_base + CPUV8_DBG_DSCR, *dscr);
2146 if (retval != ERROR_OK)
2147 return retval;
2148
2149 return ERROR_OK;
2150 }
2151
2152 static int aarch64_write_cpu_memory(struct target *target,
2153 uint64_t address, uint32_t size,
2154 uint32_t count, const uint8_t *buffer)
2155 {
2156 /* write memory through APB-AP */
2157 int retval = ERROR_COMMAND_SYNTAX_ERROR;
2158 struct armv8_common *armv8 = target_to_armv8(target);
2159 struct arm_dpm *dpm = &armv8->dpm;
2160 struct arm *arm = &armv8->arm;
2161 uint32_t dscr;
2162
2163 if (target->state != TARGET_HALTED) {
2164 LOG_TARGET_ERROR(target, "not halted");
2165 return ERROR_TARGET_NOT_HALTED;
2166 }
2167
2168 /* Mark register X0 as dirty, as it will be used
2169 * for transferring the data.
2170 * It will be restored automatically when exiting
2171 * debug mode
2172 */
2173 armv8_reg_current(arm, 0)->dirty = true;
2174
2175 /* This algorithm comes from DDI0487A.g, chapter J9.1 */
2176
2177 /* Read DSCR */
2178 retval = mem_ap_read_atomic_u32(armv8->debug_ap,
2179 armv8->debug_base + CPUV8_DBG_DSCR, &dscr);
2180 if (retval != ERROR_OK)
2181 return retval;
2182
2183 /* Set Normal access mode */
2184 dscr = (dscr & ~DSCR_MA);
2185 retval = mem_ap_write_atomic_u32(armv8->debug_ap,
2186 armv8->debug_base + CPUV8_DBG_DSCR, dscr);
2187 if (retval != ERROR_OK)
2188 return retval;
2189
2190 if (arm->core_state == ARM_STATE_AARCH64) {
2191 /* Write X0 with value 'address' using write procedure */
2192 /* Step 1.a+b - Write the address for read access into DBGDTR_EL0 */
2193 /* Step 1.c - Copy value from DTR to R0 using instruction mrs DBGDTR_EL0, x0 */
2194 retval = dpm->instr_write_data_dcc_64(dpm,
2195 ARMV8_MRS(SYSTEM_DBG_DBGDTR_EL0, 0), address);
2196 } else {
2197 /* Write R0 with value 'address' using write procedure */
2198 /* Step 1.a+b - Write the address for read access into DBGDTRRX */
2199 /* Step 1.c - Copy value from DTR to R0 using instruction mrc DBGDTRTXint, r0 */
2200 retval = dpm->instr_write_data_dcc(dpm,
2201 ARMV4_5_MRC(14, 0, 0, 0, 5, 0), address);
2202 }
2203
2204 if (retval != ERROR_OK)
2205 return retval;
2206
2207 if (size == 4 && (address % 4) == 0)
2208 retval = aarch64_write_cpu_memory_fast(target, count, buffer, &dscr);
2209 else
2210 retval = aarch64_write_cpu_memory_slow(target, size, count, buffer, &dscr);
2211
2212 if (retval != ERROR_OK) {
2213 /* Unset DTR mode */
2214 mem_ap_read_atomic_u32(armv8->debug_ap,
2215 armv8->debug_base + CPUV8_DBG_DSCR, &dscr);
2216 dscr &= ~DSCR_MA;
2217 mem_ap_write_atomic_u32(armv8->debug_ap,
2218 armv8->debug_base + CPUV8_DBG_DSCR, dscr);
2219 }
2220
2221 /* Check for sticky abort flags in the DSCR */
2222 retval = mem_ap_read_atomic_u32(armv8->debug_ap,
2223 armv8->debug_base + CPUV8_DBG_DSCR, &dscr);
2224 if (retval != ERROR_OK)
2225 return retval;
2226
2227 dpm->dscr = dscr;
2228 if (dscr & (DSCR_ERR | DSCR_SYS_ERROR_PEND)) {
2229 /* Abort occurred - clear it and exit */
2230 LOG_ERROR("abort occurred - dscr = 0x%08" PRIx32, dscr);
2231 armv8_dpm_handle_exception(dpm, true);
2232 return ERROR_FAIL;
2233 }
2234
2235 /* Done */
2236 return ERROR_OK;
2237 }
2238
2239 static int aarch64_read_cpu_memory_slow(struct target *target,
2240 uint32_t size, uint32_t count, uint8_t *buffer, uint32_t *dscr)
2241 {
2242 struct armv8_common *armv8 = target_to_armv8(target);
2243 struct arm_dpm *dpm = &armv8->dpm;
2244 struct arm *arm = &armv8->arm;
2245 int retval;
2246
2247 if (size > 4 && arm->core_state != ARM_STATE_AARCH64) {
2248 LOG_ERROR("memory read sizes greater than 4 bytes is only supported for AArch64 state");
2249 return ERROR_FAIL;
2250 }
2251
2252 armv8_reg_current(arm, 1)->dirty = true;
2253
2254 /* change DCC to normal mode (if necessary) */
2255 if (*dscr & DSCR_MA) {
2256 *dscr &= DSCR_MA;
2257 retval = mem_ap_write_atomic_u32(armv8->debug_ap,
2258 armv8->debug_base + CPUV8_DBG_DSCR, *dscr);
2259 if (retval != ERROR_OK)
2260 return retval;
2261 }
2262
2263 while (count) {
2264 uint32_t opcode;
2265 uint32_t lower;
2266 uint32_t higher;
2267 uint64_t data;
2268
2269 if (size == 1)
2270 opcode = armv8_opcode(armv8, ARMV8_OPC_LDRB_IP);
2271 else if (size == 2)
2272 opcode = armv8_opcode(armv8, ARMV8_OPC_LDRH_IP);
2273 else if (size == 4)
2274 opcode = armv8_opcode(armv8, ARMV8_OPC_LDRW_IP);
2275 else
2276 opcode = armv8_opcode(armv8, ARMV8_OPC_LDRD_IP);
2277
2278 retval = dpm->instr_execute(dpm, opcode);
2279 if (retval != ERROR_OK)
2280 return retval;
2281
2282 if (arm->core_state == ARM_STATE_AARCH64)
2283 if (size <= 4)
2284 retval = dpm->instr_execute(dpm, ARMV8_MSR_GP(SYSTEM_DBG_DTRTX_EL0, 1));
2285 else
2286 retval = dpm->instr_execute(dpm, ARMV8_MSR_GP(SYSTEM_DBG_DBGDTR_EL0, 1));
2287 else
2288 retval = dpm->instr_execute(dpm, ARMV4_5_MCR(14, 0, 1, 0, 5, 0));
2289 if (retval != ERROR_OK)
2290 return retval;
2291
2292 retval = mem_ap_read_atomic_u32(armv8->debug_ap,
2293 armv8->debug_base + CPUV8_DBG_DTRTX, &lower);
2294 if (retval == ERROR_OK) {
2295 if (size > 4)
2296 retval = mem_ap_read_atomic_u32(armv8->debug_ap,
2297 armv8->debug_base + CPUV8_DBG_DTRRX, &higher);
2298 else
2299 higher = 0;
2300 }
2301 if (retval != ERROR_OK)
2302 return retval;
2303
2304 data = (uint64_t)lower | (uint64_t)higher << 32;
2305
2306 if (size == 1)
2307 *buffer = (uint8_t)data;
2308 else if (size == 2)
2309 target_buffer_set_u16(target, buffer, (uint16_t)data);
2310 else if (size == 4)
2311 target_buffer_set_u32(target, buffer, (uint32_t)data);
2312 else
2313 target_buffer_set_u64(target, buffer, data);
2314
2315 /* Advance */
2316 buffer += size;
2317 --count;
2318 }
2319
2320 return ERROR_OK;
2321 }
2322
2323 static int aarch64_read_cpu_memory_fast(struct target *target,
2324 uint32_t count, uint8_t *buffer, uint32_t *dscr)
2325 {
2326 struct armv8_common *armv8 = target_to_armv8(target);
2327 struct arm_dpm *dpm = &armv8->dpm;
2328 struct arm *arm = &armv8->arm;
2329 int retval;
2330 uint32_t value;
2331
2332 /* Mark X1 as dirty */
2333 armv8_reg_current(arm, 1)->dirty = true;
2334
2335 if (arm->core_state == ARM_STATE_AARCH64) {
2336 /* Step 1.d - Dummy operation to ensure EDSCR.Txfull == 1 */
2337 retval = dpm->instr_execute(dpm, ARMV8_MSR_GP(SYSTEM_DBG_DBGDTR_EL0, 0));
2338 } else {
2339 /* Step 1.d - Dummy operation to ensure EDSCR.Txfull == 1 */
2340 retval = dpm->instr_execute(dpm, ARMV4_5_MCR(14, 0, 0, 0, 5, 0));
2341 }
2342
2343 if (retval != ERROR_OK)
2344 return retval;
2345
2346 /* Step 1.e - Change DCC to memory mode */
2347 *dscr |= DSCR_MA;
2348 retval = mem_ap_write_atomic_u32(armv8->debug_ap,
2349 armv8->debug_base + CPUV8_DBG_DSCR, *dscr);
2350 if (retval != ERROR_OK)
2351 return retval;
2352
2353 /* Step 1.f - read DBGDTRTX and discard the value */
2354 retval = mem_ap_read_atomic_u32(armv8->debug_ap,
2355 armv8->debug_base + CPUV8_DBG_DTRTX, &value);
2356 if (retval != ERROR_OK)
2357 return retval;
2358
2359 count--;
2360 /* Read the data - Each read of the DTRTX register causes the instruction to be reissued
2361 * Abort flags are sticky, so can be read at end of transactions
2362 *
2363 * This data is read in aligned to 32 bit boundary.
2364 */
2365
2366 if (count) {
2367 /* Step 2.a - Loop n-1 times, each read of DBGDTRTX reads the data from [X0] and
2368 * increments X0 by 4. */
2369 retval = mem_ap_read_buf_noincr(armv8->debug_ap, buffer, 4, count,
2370 armv8->debug_base + CPUV8_DBG_DTRTX);
2371 if (retval != ERROR_OK)
2372 return retval;
2373 }
2374
2375 /* Step 3.a - set DTR access mode back to Normal mode */
2376 *dscr &= ~DSCR_MA;
2377 retval = mem_ap_write_atomic_u32(armv8->debug_ap,
2378 armv8->debug_base + CPUV8_DBG_DSCR, *dscr);
2379 if (retval != ERROR_OK)
2380 return retval;
2381
2382 /* Step 3.b - read DBGDTRTX for the final value */
2383 retval = mem_ap_read_atomic_u32(armv8->debug_ap,
2384 armv8->debug_base + CPUV8_DBG_DTRTX, &value);
2385 if (retval != ERROR_OK)
2386 return retval;
2387
2388 target_buffer_set_u32(target, buffer + count * 4, value);
2389 return retval;
2390 }
2391
2392 static int aarch64_read_cpu_memory(struct target *target,
2393 target_addr_t address, uint32_t size,
2394 uint32_t count, uint8_t *buffer)
2395 {
2396 /* read memory through APB-AP */
2397 int retval = ERROR_COMMAND_SYNTAX_ERROR;
2398 struct armv8_common *armv8 = target_to_armv8(target);
2399 struct arm_dpm *dpm = &armv8->dpm;
2400 struct arm *arm = &armv8->arm;
2401 uint32_t dscr;
2402
2403 LOG_DEBUG("Reading CPU memory address 0x%016" PRIx64 " size %" PRIu32 " count %" PRIu32,
2404 address, size, count);
2405
2406 if (target->state != TARGET_HALTED) {
2407 LOG_TARGET_ERROR(target, "not halted");
2408 return ERROR_TARGET_NOT_HALTED;
2409 }
2410
2411 /* Mark register X0 as dirty, as it will be used
2412 * for transferring the data.
2413 * It will be restored automatically when exiting
2414 * debug mode
2415 */
2416 armv8_reg_current(arm, 0)->dirty = true;
2417
2418 /* Read DSCR */
2419 retval = mem_ap_read_atomic_u32(armv8->debug_ap,
2420 armv8->debug_base + CPUV8_DBG_DSCR, &dscr);
2421 if (retval != ERROR_OK)
2422 return retval;
2423
2424 /* This algorithm comes from DDI0487A.g, chapter J9.1 */
2425
2426 /* Set Normal access mode */
2427 dscr &= ~DSCR_MA;
2428 retval = mem_ap_write_atomic_u32(armv8->debug_ap,
2429 armv8->debug_base + CPUV8_DBG_DSCR, dscr);
2430 if (retval != ERROR_OK)
2431 return retval;
2432
2433 if (arm->core_state == ARM_STATE_AARCH64) {
2434 /* Write X0 with value 'address' using write procedure */
2435 /* Step 1.a+b - Write the address for read access into DBGDTR_EL0 */
2436 /* Step 1.c - Copy value from DTR to R0 using instruction mrs DBGDTR_EL0, x0 */
2437 retval = dpm->instr_write_data_dcc_64(dpm,
2438 ARMV8_MRS(SYSTEM_DBG_DBGDTR_EL0, 0), address);
2439 } else {
2440 /* Write R0 with value 'address' using write procedure */
2441 /* Step 1.a+b - Write the address for read access into DBGDTRRXint */
2442 /* Step 1.c - Copy value from DTR to R0 using instruction mrc DBGDTRTXint, r0 */
2443 retval = dpm->instr_write_data_dcc(dpm,
2444 ARMV4_5_MRC(14, 0, 0, 0, 5, 0), address);
2445 }
2446
2447 if (retval != ERROR_OK)
2448 return retval;
2449
2450 if (size == 4 && (address % 4) == 0)
2451 retval = aarch64_read_cpu_memory_fast(target, count, buffer, &dscr);
2452 else
2453 retval = aarch64_read_cpu_memory_slow(target, size, count, buffer, &dscr);
2454
2455 if (dscr & DSCR_MA) {
2456 dscr &= ~DSCR_MA;
2457 mem_ap_write_atomic_u32(armv8->debug_ap,
2458 armv8->debug_base + CPUV8_DBG_DSCR, dscr);
2459 }
2460
2461 if (retval != ERROR_OK)
2462 return retval;
2463
2464 /* Check for sticky abort flags in the DSCR */
2465 retval = mem_ap_read_atomic_u32(armv8->debug_ap,
2466 armv8->debug_base + CPUV8_DBG_DSCR, &dscr);
2467 if (retval != ERROR_OK)
2468 return retval;
2469
2470 dpm->dscr = dscr;
2471
2472 if (dscr & (DSCR_ERR | DSCR_SYS_ERROR_PEND)) {
2473 /* Abort occurred - clear it and exit */
2474 LOG_ERROR("abort occurred - dscr = 0x%08" PRIx32, dscr);
2475 armv8_dpm_handle_exception(dpm, true);
2476 return ERROR_FAIL;
2477 }
2478
2479 /* Done */
2480 return ERROR_OK;
2481 }
2482
2483 static int aarch64_read_phys_memory(struct target *target,
2484 target_addr_t address, uint32_t size,
2485 uint32_t count, uint8_t *buffer)
2486 {
2487 int retval = ERROR_COMMAND_SYNTAX_ERROR;
2488
2489 if (count && buffer) {
2490 /* read memory through APB-AP */
2491 retval = aarch64_mmu_modify(target, 0);
2492 if (retval != ERROR_OK)
2493 return retval;
2494 retval = aarch64_read_cpu_memory(target, address, size, count, buffer);
2495 }
2496 return retval;
2497 }
2498
2499 static int aarch64_read_memory(struct target *target, target_addr_t address,
2500 uint32_t size, uint32_t count, uint8_t *buffer)
2501 {
2502 int mmu_enabled = 0;
2503 int retval;
2504
2505 /* determine if MMU was enabled on target stop */
2506 retval = aarch64_mmu(target, &mmu_enabled);
2507 if (retval != ERROR_OK)
2508 return retval;
2509
2510 if (mmu_enabled) {
2511 /* enable MMU as we could have disabled it for phys access */
2512 retval = aarch64_mmu_modify(target, 1);
2513 if (retval != ERROR_OK)
2514 return retval;
2515 }
2516 return aarch64_read_cpu_memory(target, address, size, count, buffer);
2517 }
2518
2519 static int aarch64_write_phys_memory(struct target *target,
2520 target_addr_t address, uint32_t size,
2521 uint32_t count, const uint8_t *buffer)
2522 {
2523 int retval = ERROR_COMMAND_SYNTAX_ERROR;
2524
2525 if (count && buffer) {
2526 /* write memory through APB-AP */
2527 retval = aarch64_mmu_modify(target, 0);
2528 if (retval != ERROR_OK)
2529 return retval;
2530 return aarch64_write_cpu_memory(target, address, size, count, buffer);
2531 }
2532
2533 return retval;
2534 }
2535
2536 static int aarch64_write_memory(struct target *target, target_addr_t address,
2537 uint32_t size, uint32_t count, const uint8_t *buffer)
2538 {
2539 int mmu_enabled = 0;
2540 int retval;
2541
2542 /* determine if MMU was enabled on target stop */
2543 retval = aarch64_mmu(target, &mmu_enabled);
2544 if (retval != ERROR_OK)
2545 return retval;
2546
2547 if (mmu_enabled) {
2548 /* enable MMU as we could have disabled it for phys access */
2549 retval = aarch64_mmu_modify(target, 1);
2550 if (retval != ERROR_OK)
2551 return retval;
2552 }
2553 return aarch64_write_cpu_memory(target, address, size, count, buffer);
2554 }
2555
2556 static int aarch64_handle_target_request(void *priv)
2557 {
2558 struct target *target = priv;
2559 struct armv8_common *armv8 = target_to_armv8(target);
2560 int retval;
2561
2562 if (!target_was_examined(target))
2563 return ERROR_OK;
2564 if (!target->dbg_msg_enabled)
2565 return ERROR_OK;
2566
2567 if (target->state == TARGET_RUNNING) {
2568 uint32_t request;
2569 uint32_t dscr;
2570 retval = mem_ap_read_atomic_u32(armv8->debug_ap,
2571 armv8->debug_base + CPUV8_DBG_DSCR, &dscr);
2572
2573 /* check if we have data */
2574 while ((dscr & DSCR_DTR_TX_FULL) && (retval == ERROR_OK)) {
2575 retval = mem_ap_read_atomic_u32(armv8->debug_ap,
2576 armv8->debug_base + CPUV8_DBG_DTRTX, &request);
2577 if (retval == ERROR_OK) {
2578 target_request(target, request);
2579 retval = mem_ap_read_atomic_u32(armv8->debug_ap,
2580 armv8->debug_base + CPUV8_DBG_DSCR, &dscr);
2581 }
2582 }
2583 }
2584
2585 return ERROR_OK;
2586 }
2587
2588 static int aarch64_examine_first(struct target *target)
2589 {
2590 struct aarch64_common *aarch64 = target_to_aarch64(target);
2591 struct armv8_common *armv8 = &aarch64->armv8_common;
2592 struct adiv5_dap *swjdp = armv8->arm.dap;
2593 struct aarch64_private_config *pc = target->private_config;
2594 int i;
2595 int retval = ERROR_OK;
2596 uint64_t debug, ttypr;
2597 uint32_t cpuid;
2598 uint32_t tmp0, tmp1, tmp2, tmp3;
2599 debug = ttypr = cpuid = 0;
2600
2601 if (!pc)
2602 return ERROR_FAIL;
2603
2604 if (!armv8->debug_ap) {
2605 if (pc->adiv5_config.ap_num == DP_APSEL_INVALID) {
2606 /* Search for the APB-AB */
2607 retval = dap_find_get_ap(swjdp, AP_TYPE_APB_AP, &armv8->debug_ap);
2608 if (retval != ERROR_OK) {
2609 LOG_ERROR("Could not find APB-AP for debug access");
2610 return retval;
2611 }
2612 } else {
2613 armv8->debug_ap = dap_get_ap(swjdp, pc->adiv5_config.ap_num);
2614 if (!armv8->debug_ap) {
2615 LOG_ERROR("Cannot get AP");
2616 return ERROR_FAIL;
2617 }
2618 }
2619 }
2620
2621 retval = mem_ap_init(armv8->debug_ap);
2622 if (retval != ERROR_OK) {
2623 LOG_ERROR("Could not initialize the APB-AP");
2624 return retval;
2625 }
2626
2627 armv8->debug_ap->memaccess_tck = 10;
2628
2629 if (!target->dbgbase_set) {
2630 /* Lookup Processor DAP */
2631 retval = dap_lookup_cs_component(armv8->debug_ap, ARM_CS_C9_DEVTYPE_CORE_DEBUG,
2632 &armv8->debug_base, target->coreid);
2633 if (retval != ERROR_OK)
2634 return retval;
2635 LOG_DEBUG("Detected core %" PRId32 " dbgbase: " TARGET_ADDR_FMT,
2636 target->coreid, armv8->debug_base);
2637 } else
2638 armv8->debug_base = target->dbgbase;
2639
2640 retval = mem_ap_write_atomic_u32(armv8->debug_ap,
2641 armv8->debug_base + CPUV8_DBG_OSLAR, 0);
2642 if (retval != ERROR_OK) {
2643 LOG_DEBUG("Examine %s failed", "oslock");
2644 return retval;
2645 }
2646
2647 retval = mem_ap_read_u32(armv8->debug_ap,
2648 armv8->debug_base + CPUV8_DBG_MAINID0, &cpuid);
2649 if (retval != ERROR_OK) {
2650 LOG_DEBUG("Examine %s failed", "CPUID");
2651 return retval;
2652 }
2653
2654 retval = mem_ap_read_u32(armv8->debug_ap,
2655 armv8->debug_base + CPUV8_DBG_MEMFEATURE0, &tmp0);
2656 retval += mem_ap_read_u32(armv8->debug_ap,
2657 armv8->debug_base + CPUV8_DBG_MEMFEATURE0 + 4, &tmp1);
2658 if (retval != ERROR_OK) {
2659 LOG_DEBUG("Examine %s failed", "Memory Model Type");
2660 return retval;
2661 }
2662 retval = mem_ap_read_u32(armv8->debug_ap,
2663 armv8->debug_base + CPUV8_DBG_DBGFEATURE0, &tmp2);
2664 retval += mem_ap_read_u32(armv8->debug_ap,
2665 armv8->debug_base + CPUV8_DBG_DBGFEATURE0 + 4, &tmp3);
2666 if (retval != ERROR_OK) {
2667 LOG_DEBUG("Examine %s failed", "ID_AA64DFR0_EL1");
2668 return retval;
2669 }
2670
2671 retval = dap_run(armv8->debug_ap->dap);
2672 if (retval != ERROR_OK) {
2673 LOG_ERROR("%s: examination failed\n", target_name(target));
2674 return retval;
2675 }
2676
2677 ttypr |= tmp1;
2678 ttypr = (ttypr << 32) | tmp0;
2679 debug |= tmp3;
2680 debug = (debug << 32) | tmp2;
2681
2682 LOG_DEBUG("cpuid = 0x%08" PRIx32, cpuid);
2683 LOG_DEBUG("ttypr = 0x%08" PRIx64, ttypr);
2684 LOG_DEBUG("debug = 0x%08" PRIx64, debug);
2685
2686 if (!pc->cti) {
2687 LOG_TARGET_ERROR(target, "CTI not specified");
2688 return ERROR_FAIL;
2689 }
2690
2691 armv8->cti = pc->cti;
2692
2693 retval = aarch64_dpm_setup(aarch64, debug);
2694 if (retval != ERROR_OK)
2695 return retval;
2696
2697 /* Setup Breakpoint Register Pairs */
2698 aarch64->brp_num = (uint32_t)((debug >> 12) & 0x0F) + 1;
2699 aarch64->brp_num_context = (uint32_t)((debug >> 28) & 0x0F) + 1;
2700 aarch64->brp_num_available = aarch64->brp_num;
2701 aarch64->brp_list = calloc(aarch64->brp_num, sizeof(struct aarch64_brp));
2702 for (i = 0; i < aarch64->brp_num; i++) {
2703 aarch64->brp_list[i].used = 0;
2704 if (i < (aarch64->brp_num-aarch64->brp_num_context))
2705 aarch64->brp_list[i].type = BRP_NORMAL;
2706 else
2707 aarch64->brp_list[i].type = BRP_CONTEXT;
2708 aarch64->brp_list[i].value = 0;
2709 aarch64->brp_list[i].control = 0;
2710 aarch64->brp_list[i].brpn = i;
2711 }
2712
2713 /* Setup Watchpoint Register Pairs */
2714 aarch64->wp_num = (uint32_t)((debug >> 20) & 0x0F) + 1;
2715 aarch64->wp_num_available = aarch64->wp_num;
2716 aarch64->wp_list = calloc(aarch64->wp_num, sizeof(struct aarch64_brp));
2717 for (i = 0; i < aarch64->wp_num; i++) {
2718 aarch64->wp_list[i].used = 0;
2719 aarch64->wp_list[i].type = BRP_NORMAL;
2720 aarch64->wp_list[i].value = 0;
2721 aarch64->wp_list[i].control = 0;
2722 aarch64->wp_list[i].brpn = i;
2723 }
2724
2725 LOG_DEBUG("Configured %i hw breakpoints, %i watchpoints",
2726 aarch64->brp_num, aarch64->wp_num);
2727
2728 target->state = TARGET_UNKNOWN;
2729 target->debug_reason = DBG_REASON_NOTHALTED;
2730 aarch64->isrmasking_mode = AARCH64_ISRMASK_ON;
2731 target_set_examined(target);
2732 return ERROR_OK;
2733 }
2734
2735 static int aarch64_examine(struct target *target)
2736 {
2737 int retval = ERROR_OK;
2738
2739 /* don't re-probe hardware after each reset */
2740 if (!target_was_examined(target))
2741 retval = aarch64_examine_first(target);
2742
2743 /* Configure core debug access */
2744 if (retval == ERROR_OK)
2745 retval = aarch64_init_debug_access(target);
2746
2747 if (retval == ERROR_OK)
2748 retval = aarch64_poll(target);
2749
2750 return retval;
2751 }
2752
2753 /*
2754 * Cortex-A8 target creation and initialization
2755 */
2756
2757 static int aarch64_init_target(struct command_context *cmd_ctx,
2758 struct target *target)
2759 {
2760 /* examine_first() does a bunch of this */
2761 arm_semihosting_init(target);
2762 return ERROR_OK;
2763 }
2764
2765 static int aarch64_init_arch_info(struct target *target,
2766 struct aarch64_common *aarch64, struct adiv5_dap *dap)
2767 {
2768 struct armv8_common *armv8 = &aarch64->armv8_common;
2769
2770 /* Setup struct aarch64_common */
2771 aarch64->common_magic = AARCH64_COMMON_MAGIC;
2772 armv8->arm.dap = dap;
2773
2774 /* register arch-specific functions */
2775 armv8->examine_debug_reason = NULL;
2776 armv8->post_debug_entry = aarch64_post_debug_entry;
2777 armv8->pre_restore_context = NULL;
2778 armv8->armv8_mmu.read_physical_memory = aarch64_read_phys_memory;
2779
2780 armv8_init_arch_info(target, armv8);
2781 target_register_timer_callback(aarch64_handle_target_request, 1,
2782 TARGET_TIMER_TYPE_PERIODIC, target);
2783
2784 return ERROR_OK;
2785 }
2786
2787 static int armv8r_target_create(struct target *target, Jim_Interp *interp)
2788 {
2789 struct aarch64_private_config *pc = target->private_config;
2790 struct aarch64_common *aarch64;
2791
2792 if (adiv5_verify_config(&pc->adiv5_config) != ERROR_OK)
2793 return ERROR_FAIL;
2794
2795 aarch64 = calloc(1, sizeof(struct aarch64_common));
2796 if (!aarch64) {
2797 LOG_ERROR("Out of memory");
2798 return ERROR_FAIL;
2799 }
2800
2801 aarch64->armv8_common.is_armv8r = true;
2802
2803 return aarch64_init_arch_info(target, aarch64, pc->adiv5_config.dap);
2804 }
2805
2806 static int aarch64_target_create(struct target *target, Jim_Interp *interp)
2807 {
2808 struct aarch64_private_config *pc = target->private_config;
2809 struct aarch64_common *aarch64;
2810
2811 if (adiv5_verify_config(&pc->adiv5_config) != ERROR_OK)
2812 return ERROR_FAIL;
2813
2814 aarch64 = calloc(1, sizeof(struct aarch64_common));
2815 if (!aarch64) {
2816 LOG_ERROR("Out of memory");
2817 return ERROR_FAIL;
2818 }
2819
2820 aarch64->armv8_common.is_armv8r = false;
2821
2822 return aarch64_init_arch_info(target, aarch64, pc->adiv5_config.dap);
2823 }
2824
2825 static void aarch64_deinit_target(struct target *target)
2826 {
2827 struct aarch64_common *aarch64 = target_to_aarch64(target);
2828 struct armv8_common *armv8 = &aarch64->armv8_common;
2829 struct arm_dpm *dpm = &armv8->dpm;
2830
2831 if (armv8->debug_ap)
2832 dap_put_ap(armv8->debug_ap);
2833
2834 armv8_free_reg_cache(target);
2835 free(aarch64->brp_list);
2836 free(dpm->dbp);
2837 free(dpm->dwp);
2838 free(target->private_config);
2839 free(aarch64);
2840 }
2841
2842 static int aarch64_mmu(struct target *target, int *enabled)
2843 {
2844 struct aarch64_common *aarch64 = target_to_aarch64(target);
2845 struct armv8_common *armv8 = &aarch64->armv8_common;
2846 if (target->state != TARGET_HALTED) {
2847 LOG_TARGET_ERROR(target, "not halted");
2848 return ERROR_TARGET_NOT_HALTED;
2849 }
2850 if (armv8->is_armv8r)
2851 *enabled = 0;
2852 else
2853 *enabled = target_to_aarch64(target)->armv8_common.armv8_mmu.mmu_enabled;
2854 return ERROR_OK;
2855 }
2856
2857 static int aarch64_virt2phys(struct target *target, target_addr_t virt,
2858 target_addr_t *phys)
2859 {
2860 return armv8_mmu_translate_va_pa(target, virt, phys, 1);
2861 }
2862
2863 /*
2864 * private target configuration items
2865 */
2866 enum aarch64_cfg_param {
2867 CFG_CTI,
2868 };
2869
2870 static const struct jim_nvp nvp_config_opts[] = {
2871 { .name = "-cti", .value = CFG_CTI },
2872 { .name = NULL, .value = -1 }
2873 };
2874
2875 static int aarch64_jim_configure(struct target *target, struct jim_getopt_info *goi)
2876 {
2877 struct aarch64_private_config *pc;
2878 struct jim_nvp *n;
2879 int e;
2880
2881 pc = (struct aarch64_private_config *)target->private_config;
2882 if (!pc) {
2883 pc = calloc(1, sizeof(struct aarch64_private_config));
2884 pc->adiv5_config.ap_num = DP_APSEL_INVALID;
2885 target->private_config = pc;
2886 }
2887
2888 /*
2889 * Call adiv5_jim_configure() to parse the common DAP options
2890 * It will return JIM_CONTINUE if it didn't find any known
2891 * options, JIM_OK if it correctly parsed the topmost option
2892 * and JIM_ERR if an error occurred during parameter evaluation.
2893 * For JIM_CONTINUE, we check our own params.
2894 *
2895 * adiv5_jim_configure() assumes 'private_config' to point to
2896 * 'struct adiv5_private_config'. Override 'private_config'!
2897 */
2898 target->private_config = &pc->adiv5_config;
2899 e = adiv5_jim_configure(target, goi);
2900 target->private_config = pc;
2901 if (e != JIM_CONTINUE)
2902 return e;
2903
2904 /* parse config or cget options ... */
2905 if (goi->argc > 0) {
2906 Jim_SetEmptyResult(goi->interp);
2907
2908 /* check first if topmost item is for us */
2909 e = jim_nvp_name2value_obj(goi->interp, nvp_config_opts,
2910 goi->argv[0], &n);
2911 if (e != JIM_OK)
2912 return JIM_CONTINUE;
2913
2914 e = jim_getopt_obj(goi, NULL);
2915 if (e != JIM_OK)
2916 return e;
2917
2918 switch (n->value) {
2919 case CFG_CTI: {
2920 if (goi->isconfigure) {
2921 Jim_Obj *o_cti;
2922 struct arm_cti *cti;
2923 e = jim_getopt_obj(goi, &o_cti);
2924 if (e != JIM_OK)
2925 return e;
2926 cti = cti_instance_by_jim_obj(goi->interp, o_cti);
2927 if (!cti) {
2928 Jim_SetResultString(goi->interp, "CTI name invalid!", -1);
2929 return JIM_ERR;
2930 }
2931 pc->cti = cti;
2932 } else {
2933 if (goi->argc != 0) {
2934 Jim_WrongNumArgs(goi->interp,
2935 goi->argc, goi->argv,
2936 "NO PARAMS");
2937 return JIM_ERR;
2938 }
2939
2940 if (!pc || !pc->cti) {
2941 Jim_SetResultString(goi->interp, "CTI not configured", -1);
2942 return JIM_ERR;
2943 }
2944 Jim_SetResultString(goi->interp, arm_cti_name(pc->cti), -1);
2945 }
2946 break;
2947 }
2948
2949 default:
2950 return JIM_CONTINUE;
2951 }
2952 }
2953
2954 return JIM_OK;
2955 }
2956
2957 COMMAND_HANDLER(aarch64_handle_cache_info_command)
2958 {
2959 struct target *target = get_current_target(CMD_CTX);
2960 struct armv8_common *armv8 = target_to_armv8(target);
2961
2962 return armv8_handle_cache_info_command(CMD,
2963 &armv8->armv8_mmu.armv8_cache);
2964 }
2965
2966 COMMAND_HANDLER(aarch64_handle_dbginit_command)
2967 {
2968 struct target *target = get_current_target(CMD_CTX);
2969 if (!target_was_examined(target)) {
2970 LOG_ERROR("target not examined yet");
2971 return ERROR_FAIL;
2972 }
2973
2974 return aarch64_init_debug_access(target);
2975 }
2976
2977 COMMAND_HANDLER(aarch64_handle_disassemble_command)
2978 {
2979 struct target *target = get_current_target(CMD_CTX);
2980
2981 if (!target) {
2982 LOG_ERROR("No target selected");
2983 return ERROR_FAIL;
2984 }
2985
2986 struct aarch64_common *aarch64 = target_to_aarch64(target);
2987
2988 if (aarch64->common_magic != AARCH64_COMMON_MAGIC) {
2989 command_print(CMD, "current target isn't an AArch64");
2990 return ERROR_FAIL;
2991 }
2992
2993 int count = 1;
2994 target_addr_t address;
2995
2996 switch (CMD_ARGC) {
2997 case 2:
2998 COMMAND_PARSE_NUMBER(int, CMD_ARGV[1], count);
2999 /* FALL THROUGH */
3000 case 1:
3001 COMMAND_PARSE_ADDRESS(CMD_ARGV[0], address);
3002 break;
3003 default:
3004 return ERROR_COMMAND_SYNTAX_ERROR;
3005 }
3006
3007 return a64_disassemble(CMD, target, address, count);
3008 }
3009
3010 COMMAND_HANDLER(aarch64_mask_interrupts_command)
3011 {
3012 struct target *target = get_current_target(CMD_CTX);
3013 struct aarch64_common *aarch64 = target_to_aarch64(target);
3014
3015 static const struct nvp nvp_maskisr_modes[] = {
3016 { .name = "off", .value = AARCH64_ISRMASK_OFF },
3017 { .name = "on", .value = AARCH64_ISRMASK_ON },
3018 { .name = NULL, .value = -1 },
3019 };
3020 const struct nvp *n;
3021
3022 if (CMD_ARGC > 0) {
3023 n = nvp_name2value(nvp_maskisr_modes, CMD_ARGV[0]);
3024 if (!n->name) {
3025 LOG_ERROR("Unknown parameter: %s - should be off or on", CMD_ARGV[0]);
3026 return ERROR_COMMAND_SYNTAX_ERROR;
3027 }
3028
3029 aarch64->isrmasking_mode = n->value;
3030 }
3031
3032 n = nvp_value2name(nvp_maskisr_modes, aarch64->isrmasking_mode);
3033 command_print(CMD, "aarch64 interrupt mask %s", n->name);
3034
3035 return ERROR_OK;
3036 }
3037
3038 COMMAND_HANDLER(aarch64_mcrmrc_command)
3039 {
3040 bool is_mcr = false;
3041 unsigned int arg_cnt = 5;
3042
3043 if (!strcmp(CMD_NAME, "mcr")) {
3044 is_mcr = true;
3045 arg_cnt = 6;
3046 }
3047
3048 if (arg_cnt != CMD_ARGC)
3049 return ERROR_COMMAND_SYNTAX_ERROR;
3050
3051 struct target *target = get_current_target(CMD_CTX);
3052 if (!target) {
3053 command_print(CMD, "no current target");
3054 return ERROR_FAIL;
3055 }
3056 if (!target_was_examined(target)) {
3057 command_print(CMD, "%s: not yet examined", target_name(target));
3058 return ERROR_TARGET_NOT_EXAMINED;
3059 }
3060
3061 struct arm *arm = target_to_arm(target);
3062 if (!is_arm(arm)) {
3063 command_print(CMD, "%s: not an ARM", target_name(target));
3064 return ERROR_FAIL;
3065 }
3066
3067 if (target->state != TARGET_HALTED) {
3068 command_print(CMD, "Error: [%s] not halted", target_name(target));
3069 return ERROR_TARGET_NOT_HALTED;
3070 }
3071
3072 if (arm->core_state == ARM_STATE_AARCH64) {
3073 command_print(CMD, "%s: not 32-bit arm target", target_name(target));
3074 return ERROR_FAIL;
3075 }
3076
3077 int cpnum;
3078 uint32_t op1;
3079 uint32_t op2;
3080 uint32_t crn;
3081 uint32_t crm;
3082 uint32_t value;
3083
3084 /* NOTE: parameter sequence matches ARM instruction set usage:
3085 * MCR pNUM, op1, rX, CRn, CRm, op2 ; write CP from rX
3086 * MRC pNUM, op1, rX, CRn, CRm, op2 ; read CP into rX
3087 * The "rX" is necessarily omitted; it uses Tcl mechanisms.
3088 */
3089 COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], cpnum);
3090 if (cpnum & ~0xf) {
3091 command_print(CMD, "coprocessor %d out of range", cpnum);
3092 return ERROR_COMMAND_ARGUMENT_INVALID;
3093 }
3094
3095 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], op1);
3096 if (op1 & ~0x7) {
3097 command_print(CMD, "op1 %d out of range", op1);
3098 return ERROR_COMMAND_ARGUMENT_INVALID;
3099 }
3100
3101 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[2], crn);
3102 if (crn & ~0xf) {
3103 command_print(CMD, "CRn %d out of range", crn);
3104 return ERROR_COMMAND_ARGUMENT_INVALID;
3105 }
3106
3107 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[3], crm);
3108 if (crm & ~0xf) {
3109 command_print(CMD, "CRm %d out of range", crm);
3110 return ERROR_COMMAND_ARGUMENT_INVALID;
3111 }
3112
3113 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[4], op2);
3114 if (op2 & ~0x7) {
3115 command_print(CMD, "op2 %d out of range", op2);
3116 return ERROR_COMMAND_ARGUMENT_INVALID;
3117 }
3118
3119 if (is_mcr) {
3120 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[5], value);
3121
3122 /* NOTE: parameters reordered! */
3123 /* ARMV4_5_MCR(cpnum, op1, 0, crn, crm, op2) */
3124 int retval = arm->mcr(target, cpnum, op1, op2, crn, crm, value);
3125 if (retval != ERROR_OK)
3126 return retval;
3127 } else {
3128 value = 0;
3129 /* NOTE: parameters reordered! */
3130 /* ARMV4_5_MRC(cpnum, op1, 0, crn, crm, op2) */
3131 int retval = arm->mrc(target, cpnum, op1, op2, crn, crm, &value);
3132 if (retval != ERROR_OK)
3133 return retval;
3134
3135 command_print(CMD, "0x%" PRIx32, value);
3136 }
3137
3138 return ERROR_OK;
3139 }
3140
3141 static const struct command_registration aarch64_exec_command_handlers[] = {
3142 {
3143 .name = "cache_info",
3144 .handler = aarch64_handle_cache_info_command,
3145 .mode = COMMAND_EXEC,
3146 .help = "display information about target caches",
3147 .usage = "",
3148 },
3149 {
3150 .name = "dbginit",
3151 .handler = aarch64_handle_dbginit_command,
3152 .mode = COMMAND_EXEC,
3153 .help = "Initialize core debug",
3154 .usage = "",
3155 },
3156 {
3157 .name = "disassemble",
3158 .handler = aarch64_handle_disassemble_command,
3159 .mode = COMMAND_EXEC,
3160 .help = "Disassemble instructions",
3161 .usage = "address [count]",
3162 },
3163 {
3164 .name = "maskisr",
3165 .handler = aarch64_mask_interrupts_command,
3166 .mode = COMMAND_ANY,
3167 .help = "mask aarch64 interrupts during single-step",
3168 .usage = "['on'|'off']",
3169 },
3170 {
3171 .name = "mcr",
3172 .mode = COMMAND_EXEC,
3173 .handler = aarch64_mcrmrc_command,
3174 .help = "write coprocessor register",
3175 .usage = "cpnum op1 CRn CRm op2 value",
3176 },
3177 {
3178 .name = "mrc",
3179 .mode = COMMAND_EXEC,
3180 .handler = aarch64_mcrmrc_command,
3181 .help = "read coprocessor register",
3182 .usage = "cpnum op1 CRn CRm op2",
3183 },
3184 {
3185 .chain = smp_command_handlers,
3186 },
3187
3188
3189 COMMAND_REGISTRATION_DONE
3190 };
3191
3192 static const struct command_registration aarch64_command_handlers[] = {
3193 {
3194 .name = "arm",
3195 .mode = COMMAND_ANY,
3196 .help = "ARM Command Group",
3197 .usage = "",
3198 .chain = semihosting_common_handlers
3199 },
3200 {
3201 .chain = armv8_command_handlers,
3202 },
3203 {
3204 .name = "aarch64",
3205 .mode = COMMAND_ANY,
3206 .help = "Aarch64 command group",
3207 .usage = "",
3208 .chain = aarch64_exec_command_handlers,
3209 },
3210 COMMAND_REGISTRATION_DONE
3211 };
3212
3213 struct target_type aarch64_target = {
3214 .name = "aarch64",
3215
3216 .poll = aarch64_poll,
3217 .arch_state = armv8_arch_state,
3218
3219 .halt = aarch64_halt,
3220 .resume = aarch64_resume,
3221 .step = aarch64_step,
3222
3223 .assert_reset = aarch64_assert_reset,
3224 .deassert_reset = aarch64_deassert_reset,
3225
3226 /* REVISIT allow exporting VFP3 registers ... */
3227 .get_gdb_arch = armv8_get_gdb_arch,
3228 .get_gdb_reg_list = armv8_get_gdb_reg_list,
3229
3230 .read_memory = aarch64_read_memory,
3231 .write_memory = aarch64_write_memory,
3232
3233 .add_breakpoint = aarch64_add_breakpoint,
3234 .add_context_breakpoint = aarch64_add_context_breakpoint,
3235 .add_hybrid_breakpoint = aarch64_add_hybrid_breakpoint,
3236 .remove_breakpoint = aarch64_remove_breakpoint,
3237 .add_watchpoint = aarch64_add_watchpoint,
3238 .remove_watchpoint = aarch64_remove_watchpoint,
3239 .hit_watchpoint = aarch64_hit_watchpoint,
3240
3241 .commands = aarch64_command_handlers,
3242 .target_create = aarch64_target_create,
3243 .target_jim_configure = aarch64_jim_configure,
3244 .init_target = aarch64_init_target,
3245 .deinit_target = aarch64_deinit_target,
3246 .examine = aarch64_examine,
3247
3248 .read_phys_memory = aarch64_read_phys_memory,
3249 .write_phys_memory = aarch64_write_phys_memory,
3250 .mmu = aarch64_mmu,
3251 .virt2phys = aarch64_virt2phys,
3252 };
3253
3254 struct target_type armv8r_target = {
3255 .name = "armv8r",
3256
3257 .poll = aarch64_poll,
3258 .arch_state = armv8_arch_state,
3259
3260 .halt = aarch64_halt,
3261 .resume = aarch64_resume,
3262 .step = aarch64_step,
3263
3264 .assert_reset = aarch64_assert_reset,
3265 .deassert_reset = aarch64_deassert_reset,
3266
3267 /* REVISIT allow exporting VFP3 registers ... */
3268 .get_gdb_arch = armv8_get_gdb_arch,
3269 .get_gdb_reg_list = armv8_get_gdb_reg_list,
3270
3271 .read_memory = aarch64_read_phys_memory,
3272 .write_memory = aarch64_write_phys_memory,
3273
3274 .add_breakpoint = aarch64_add_breakpoint,
3275 .add_context_breakpoint = aarch64_add_context_breakpoint,
3276 .add_hybrid_breakpoint = aarch64_add_hybrid_breakpoint,
3277 .remove_breakpoint = aarch64_remove_breakpoint,
3278 .add_watchpoint = aarch64_add_watchpoint,
3279 .remove_watchpoint = aarch64_remove_watchpoint,
3280 .hit_watchpoint = aarch64_hit_watchpoint,
3281
3282 .commands = aarch64_command_handlers,
3283 .target_create = armv8r_target_create,
3284 .target_jim_configure = aarch64_jim_configure,
3285 .init_target = aarch64_init_target,
3286 .deinit_target = aarch64_deinit_target,
3287 .examine = aarch64_examine,
3288 };

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)