aarch64: refactor armv8 dpm
[openocd.git] / src / target / aarch64.c
1 /***************************************************************************
2 * Copyright (C) 2015 by David Ung *
3 * *
4 * This program is free software; you can redistribute it and/or modify *
5 * it under the terms of the GNU General Public License as published by *
6 * the Free Software Foundation; either version 2 of the License, or *
7 * (at your option) any later version. *
8 * *
9 * This program is distributed in the hope that it will be useful, *
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
12 * GNU General Public License for more details. *
13 * *
14 * You should have received a copy of the GNU General Public License *
15 * along with this program; if not, write to the *
16 * Free Software Foundation, Inc., *
17 * *
18 ***************************************************************************/
19
20 #ifdef HAVE_CONFIG_H
21 #include "config.h"
22 #endif
23
24 #include "breakpoints.h"
25 #include "aarch64.h"
26 #include "register.h"
27 #include "target_request.h"
28 #include "target_type.h"
29 #include "armv8_opcodes.h"
30 #include "armv8_cache.h"
31 #include <helper/time_support.h>
32
33 static int aarch64_poll(struct target *target);
34 static int aarch64_debug_entry(struct target *target);
35 static int aarch64_restore_context(struct target *target, bool bpwp);
36 static int aarch64_set_breakpoint(struct target *target,
37 struct breakpoint *breakpoint, uint8_t matchmode);
38 static int aarch64_set_context_breakpoint(struct target *target,
39 struct breakpoint *breakpoint, uint8_t matchmode);
40 static int aarch64_set_hybrid_breakpoint(struct target *target,
41 struct breakpoint *breakpoint);
42 static int aarch64_unset_breakpoint(struct target *target,
43 struct breakpoint *breakpoint);
44 static int aarch64_mmu(struct target *target, int *enabled);
45 static int aarch64_virt2phys(struct target *target,
46 target_addr_t virt, target_addr_t *phys);
47 static int aarch64_read_apb_ap_memory(struct target *target,
48 uint64_t address, uint32_t size, uint32_t count, uint8_t *buffer);
49
50 static int aarch64_restore_system_control_reg(struct target *target)
51 {
52 int retval = ERROR_OK;
53
54 struct aarch64_common *aarch64 = target_to_aarch64(target);
55 struct armv8_common *armv8 = target_to_armv8(target);
56
57 if (aarch64->system_control_reg != aarch64->system_control_reg_curr) {
58 aarch64->system_control_reg_curr = aarch64->system_control_reg;
59 /* LOG_INFO("cp15_control_reg: %8.8" PRIx32, cortex_v8->cp15_control_reg); */
60
61 switch (armv8->arm.core_mode) {
62 case ARMV8_64_EL0T:
63 case ARMV8_64_EL1T:
64 case ARMV8_64_EL1H:
65 retval = armv8->arm.msr(target, 3, /*op 0*/
66 0, 1, /* op1, op2 */
67 0, 0, /* CRn, CRm */
68 aarch64->system_control_reg);
69 if (retval != ERROR_OK)
70 return retval;
71 break;
72 case ARMV8_64_EL2T:
73 case ARMV8_64_EL2H:
74 retval = armv8->arm.msr(target, 3, /*op 0*/
75 4, 1, /* op1, op2 */
76 0, 0, /* CRn, CRm */
77 aarch64->system_control_reg);
78 if (retval != ERROR_OK)
79 return retval;
80 break;
81 case ARMV8_64_EL3H:
82 case ARMV8_64_EL3T:
83 retval = armv8->arm.msr(target, 3, /*op 0*/
84 6, 1, /* op1, op2 */
85 0, 0, /* CRn, CRm */
86 aarch64->system_control_reg);
87 if (retval != ERROR_OK)
88 return retval;
89 break;
90 default:
91 retval = armv8->arm.mcr(target, 15, 0, 0, 1, 0, aarch64->system_control_reg);
92 if (retval != ERROR_OK)
93 return retval;
94 break;
95 }
96 }
97 return retval;
98 }
99
100 /* check address before aarch64_apb read write access with mmu on
101 * remove apb predictible data abort */
102 static int aarch64_check_address(struct target *target, uint32_t address)
103 {
104 /* TODO */
105 return ERROR_OK;
106 }
107 /* modify system_control_reg in order to enable or disable mmu for :
108 * - virt2phys address conversion
109 * - read or write memory in phys or virt address */
110 static int aarch64_mmu_modify(struct target *target, int enable)
111 {
112 struct aarch64_common *aarch64 = target_to_aarch64(target);
113 struct armv8_common *armv8 = &aarch64->armv8_common;
114 int retval = ERROR_OK;
115
116 if (enable) {
117 /* if mmu enabled at target stop and mmu not enable */
118 if (!(aarch64->system_control_reg & 0x1U)) {
119 LOG_ERROR("trying to enable mmu on target stopped with mmu disable");
120 return ERROR_FAIL;
121 }
122 if (!(aarch64->system_control_reg_curr & 0x1U)) {
123 aarch64->system_control_reg_curr |= 0x1U;
124 switch (armv8->arm.core_mode) {
125 case ARMV8_64_EL0T:
126 case ARMV8_64_EL1T:
127 case ARMV8_64_EL1H:
128 retval = armv8->arm.msr(target, 3, /*op 0*/
129 0, 0, /* op1, op2 */
130 1, 0, /* CRn, CRm */
131 aarch64->system_control_reg_curr);
132 if (retval != ERROR_OK)
133 return retval;
134 break;
135 case ARMV8_64_EL2T:
136 case ARMV8_64_EL2H:
137 retval = armv8->arm.msr(target, 3, /*op 0*/
138 4, 0, /* op1, op2 */
139 1, 0, /* CRn, CRm */
140 aarch64->system_control_reg_curr);
141 if (retval != ERROR_OK)
142 return retval;
143 break;
144 case ARMV8_64_EL3H:
145 case ARMV8_64_EL3T:
146 retval = armv8->arm.msr(target, 3, /*op 0*/
147 6, 0, /* op1, op2 */
148 1, 0, /* CRn, CRm */
149 aarch64->system_control_reg_curr);
150 if (retval != ERROR_OK)
151 return retval;
152 break;
153 default:
154 LOG_DEBUG("unknow cpu state 0x%x" PRIx32, armv8->arm.core_state);
155 }
156 }
157 } else {
158 if (aarch64->system_control_reg_curr & 0x4U) {
159 /* data cache is active */
160 aarch64->system_control_reg_curr &= ~0x4U;
161 /* flush data cache armv7 function to be called */
162 if (armv8->armv8_mmu.armv8_cache.flush_all_data_cache)
163 armv8->armv8_mmu.armv8_cache.flush_all_data_cache(target);
164 }
165 if ((aarch64->system_control_reg_curr & 0x1U)) {
166 aarch64->system_control_reg_curr &= ~0x1U;
167 switch (armv8->arm.core_mode) {
168 case ARMV8_64_EL0T:
169 case ARMV8_64_EL1T:
170 case ARMV8_64_EL1H:
171 retval = armv8->arm.msr(target, 3, /*op 0*/
172 0, 0, /* op1, op2 */
173 1, 0, /* CRn, CRm */
174 aarch64->system_control_reg_curr);
175 if (retval != ERROR_OK)
176 return retval;
177 break;
178 case ARMV8_64_EL2T:
179 case ARMV8_64_EL2H:
180 retval = armv8->arm.msr(target, 3, /*op 0*/
181 4, 0, /* op1, op2 */
182 1, 0, /* CRn, CRm */
183 aarch64->system_control_reg_curr);
184 if (retval != ERROR_OK)
185 return retval;
186 break;
187 case ARMV8_64_EL3H:
188 case ARMV8_64_EL3T:
189 retval = armv8->arm.msr(target, 3, /*op 0*/
190 6, 0, /* op1, op2 */
191 1, 0, /* CRn, CRm */
192 aarch64->system_control_reg_curr);
193 if (retval != ERROR_OK)
194 return retval;
195 break;
196 default:
197 LOG_DEBUG("unknow cpu state 0x%x" PRIx32, armv8->arm.core_state);
198 break;
199 }
200 }
201 }
202 return retval;
203 }
204
205 /*
206 * Basic debug access, very low level assumes state is saved
207 */
208 static int aarch64_init_debug_access(struct target *target)
209 {
210 struct armv8_common *armv8 = target_to_armv8(target);
211 int retval;
212 uint32_t dummy;
213
214 LOG_DEBUG(" ");
215
216 /* Clear Sticky Power Down status Bit in PRSR to enable access to
217 the registers in the Core Power Domain */
218 retval = mem_ap_read_atomic_u32(armv8->debug_ap,
219 armv8->debug_base + CPUV8_DBG_PRSR, &dummy);
220 if (retval != ERROR_OK)
221 return retval;
222
223 /*
224 * Static CTI configuration:
225 * Channel 0 -> trigger outputs HALT request to PE
226 * Channel 1 -> trigger outputs Resume request to PE
227 * Gate all channel trigger events from entering the CTM
228 */
229
230 /* Enable CTI */
231 retval = mem_ap_write_atomic_u32(armv8->debug_ap,
232 armv8->cti_base + CTI_CTR, 1);
233 /* By default, gate all channel triggers to and from the CTM */
234 if (retval == ERROR_OK)
235 retval = mem_ap_write_atomic_u32(armv8->debug_ap,
236 armv8->cti_base + CTI_GATE, 0);
237 /* output halt requests to PE on channel 0 trigger */
238 if (retval == ERROR_OK)
239 retval = mem_ap_write_atomic_u32(armv8->debug_ap,
240 armv8->cti_base + CTI_OUTEN0, CTI_CHNL(0));
241 /* output restart requests to PE on channel 1 trigger */
242 if (retval == ERROR_OK)
243 retval = mem_ap_write_atomic_u32(armv8->debug_ap,
244 armv8->cti_base + CTI_OUTEN1, CTI_CHNL(1));
245 if (retval != ERROR_OK)
246 return retval;
247
248 /* Resync breakpoint registers */
249
250 /* Since this is likely called from init or reset, update target state information*/
251 return aarch64_poll(target);
252 }
253
254 /* Write to memory mapped registers directly with no cache or mmu handling */
255 static int aarch64_dap_write_memap_register_u32(struct target *target,
256 uint32_t address,
257 uint32_t value)
258 {
259 int retval;
260 struct armv8_common *armv8 = target_to_armv8(target);
261
262 retval = mem_ap_write_atomic_u32(armv8->debug_ap, address, value);
263
264 return retval;
265 }
266
267 static int aarch64_dpm_setup(struct aarch64_common *a8, uint64_t debug)
268 {
269 struct arm_dpm *dpm = &a8->armv8_common.dpm;
270 int retval;
271
272 dpm->arm = &a8->armv8_common.arm;
273 dpm->didr = debug;
274
275 retval = armv8_dpm_setup(dpm);
276 if (retval == ERROR_OK)
277 retval = armv8_dpm_initialize(dpm);
278
279 return retval;
280 }
281
282 static struct target *get_aarch64(struct target *target, int32_t coreid)
283 {
284 struct target_list *head;
285 struct target *curr;
286
287 head = target->head;
288 while (head != (struct target_list *)NULL) {
289 curr = head->target;
290 if ((curr->coreid == coreid) && (curr->state == TARGET_HALTED))
291 return curr;
292 head = head->next;
293 }
294 return target;
295 }
296 static int aarch64_halt(struct target *target);
297
298 static int aarch64_halt_smp(struct target *target)
299 {
300 int retval = ERROR_OK;
301 struct target_list *head = target->head;
302
303 while (head != (struct target_list *)NULL) {
304 struct target *curr = head->target;
305 struct armv8_common *armv8 = target_to_armv8(curr);
306
307 /* open the gate for channel 0 to let HALT requests pass to the CTM */
308 if (curr->smp)
309 retval = mem_ap_write_atomic_u32(armv8->debug_ap,
310 armv8->cti_base + CTI_GATE, CTI_CHNL(0));
311 if (retval != ERROR_OK)
312 break;
313
314 head = head->next;
315 }
316
317 /* halt the target PE */
318 if (retval == ERROR_OK)
319 retval = aarch64_halt(target);
320
321 return retval;
322 }
323
324 static int update_halt_gdb(struct target *target)
325 {
326 int retval = 0;
327 if (target->gdb_service && target->gdb_service->core[0] == -1) {
328 target->gdb_service->target = target;
329 target->gdb_service->core[0] = target->coreid;
330 retval += aarch64_halt_smp(target);
331 }
332 return retval;
333 }
334
335 /*
336 * Cortex-A8 Run control
337 */
338
339 static int aarch64_poll(struct target *target)
340 {
341 int retval = ERROR_OK;
342 uint32_t dscr;
343 struct aarch64_common *aarch64 = target_to_aarch64(target);
344 struct armv8_common *armv8 = &aarch64->armv8_common;
345 enum target_state prev_target_state = target->state;
346 /* toggle to another core is done by gdb as follow */
347 /* maint packet J core_id */
348 /* continue */
349 /* the next polling trigger an halt event sent to gdb */
350 if ((target->state == TARGET_HALTED) && (target->smp) &&
351 (target->gdb_service) &&
352 (target->gdb_service->target == NULL)) {
353 target->gdb_service->target =
354 get_aarch64(target, target->gdb_service->core[1]);
355 target_call_event_callbacks(target, TARGET_EVENT_HALTED);
356 return retval;
357 }
358 retval = mem_ap_read_atomic_u32(armv8->debug_ap,
359 armv8->debug_base + CPUV8_DBG_DSCR, &dscr);
360 if (retval != ERROR_OK)
361 return retval;
362 aarch64->cpudbg_dscr = dscr;
363
364 if (DSCR_RUN_MODE(dscr) == 0x3) {
365 if (prev_target_state != TARGET_HALTED) {
366 /* We have a halting debug event */
367 LOG_DEBUG("Target halted");
368 target->state = TARGET_HALTED;
369 if ((prev_target_state == TARGET_RUNNING)
370 || (prev_target_state == TARGET_UNKNOWN)
371 || (prev_target_state == TARGET_RESET)) {
372 retval = aarch64_debug_entry(target);
373 if (retval != ERROR_OK)
374 return retval;
375 if (target->smp) {
376 retval = update_halt_gdb(target);
377 if (retval != ERROR_OK)
378 return retval;
379 }
380 target_call_event_callbacks(target,
381 TARGET_EVENT_HALTED);
382 }
383 if (prev_target_state == TARGET_DEBUG_RUNNING) {
384 LOG_DEBUG(" ");
385
386 retval = aarch64_debug_entry(target);
387 if (retval != ERROR_OK)
388 return retval;
389 if (target->smp) {
390 retval = update_halt_gdb(target);
391 if (retval != ERROR_OK)
392 return retval;
393 }
394
395 target_call_event_callbacks(target,
396 TARGET_EVENT_DEBUG_HALTED);
397 }
398 }
399 } else
400 target->state = TARGET_RUNNING;
401
402 return retval;
403 }
404
405 static int aarch64_halt(struct target *target)
406 {
407 int retval = ERROR_OK;
408 uint32_t dscr;
409 struct armv8_common *armv8 = target_to_armv8(target);
410
411 /*
412 * add HDE in halting debug mode
413 */
414 retval = mem_ap_read_atomic_u32(armv8->debug_ap,
415 armv8->debug_base + CPUV8_DBG_DSCR, &dscr);
416 if (retval == ERROR_OK)
417 retval = mem_ap_write_atomic_u32(armv8->debug_ap,
418 armv8->debug_base + CPUV8_DBG_DSCR, dscr | DSCR_HDE);
419 if (retval != ERROR_OK)
420 return retval;
421
422 /* trigger an event on channel 0, this outputs a halt request to the PE */
423 retval = mem_ap_write_atomic_u32(armv8->debug_ap,
424 armv8->cti_base + CTI_APPPULSE, CTI_CHNL(0));
425 if (retval != ERROR_OK)
426 return retval;
427
428 long long then = timeval_ms();
429 for (;; ) {
430 retval = mem_ap_read_atomic_u32(armv8->debug_ap,
431 armv8->debug_base + CPUV8_DBG_DSCR, &dscr);
432 if (retval != ERROR_OK)
433 return retval;
434 if ((dscr & DSCRV8_HALT_MASK) != 0)
435 break;
436 if (timeval_ms() > then + 1000) {
437 LOG_ERROR("Timeout waiting for halt");
438 return ERROR_FAIL;
439 }
440 }
441
442 target->debug_reason = DBG_REASON_DBGRQ;
443
444 return ERROR_OK;
445 }
446
447 static int aarch64_internal_restore(struct target *target, int current,
448 uint64_t *address, int handle_breakpoints, int debug_execution)
449 {
450 struct armv8_common *armv8 = target_to_armv8(target);
451 struct arm *arm = &armv8->arm;
452 int retval;
453 uint64_t resume_pc;
454
455 if (!debug_execution)
456 target_free_all_working_areas(target);
457
458 /* current = 1: continue on current pc, otherwise continue at <address> */
459 resume_pc = buf_get_u64(arm->pc->value, 0, 64);
460 if (!current)
461 resume_pc = *address;
462 else
463 *address = resume_pc;
464
465 /* Make sure that the Armv7 gdb thumb fixups does not
466 * kill the return address
467 */
468 switch (arm->core_state) {
469 case ARM_STATE_ARM:
470 resume_pc &= 0xFFFFFFFC;
471 break;
472 case ARM_STATE_AARCH64:
473 resume_pc &= 0xFFFFFFFFFFFFFFFC;
474 break;
475 case ARM_STATE_THUMB:
476 case ARM_STATE_THUMB_EE:
477 /* When the return address is loaded into PC
478 * bit 0 must be 1 to stay in Thumb state
479 */
480 resume_pc |= 0x1;
481 break;
482 case ARM_STATE_JAZELLE:
483 LOG_ERROR("How do I resume into Jazelle state??");
484 return ERROR_FAIL;
485 }
486 LOG_DEBUG("resume pc = 0x%16" PRIx64, resume_pc);
487 buf_set_u64(arm->pc->value, 0, 64, resume_pc);
488 arm->pc->dirty = 1;
489 arm->pc->valid = 1;
490 dpmv8_modeswitch(&armv8->dpm, ARM_MODE_ANY);
491
492 /* called it now before restoring context because it uses cpu
493 * register r0 for restoring system control register */
494 retval = aarch64_restore_system_control_reg(target);
495 if (retval != ERROR_OK)
496 return retval;
497 retval = aarch64_restore_context(target, handle_breakpoints);
498 if (retval != ERROR_OK)
499 return retval;
500 target->debug_reason = DBG_REASON_NOTHALTED;
501 target->state = TARGET_RUNNING;
502
503 /* registers are now invalid */
504 register_cache_invalidate(arm->core_cache);
505
506 return retval;
507 }
508
509 static int aarch64_internal_restart(struct target *target, bool slave_pe)
510 {
511 struct armv8_common *armv8 = target_to_armv8(target);
512 struct arm *arm = &armv8->arm;
513 int retval;
514 uint32_t dscr;
515 /*
516 * * Restart core and wait for it to be started. Clear ITRen and sticky
517 * * exception flags: see ARMv7 ARM, C5.9.
518 *
519 * REVISIT: for single stepping, we probably want to
520 * disable IRQs by default, with optional override...
521 */
522
523 retval = mem_ap_read_atomic_u32(armv8->debug_ap,
524 armv8->debug_base + CPUV8_DBG_DSCR, &dscr);
525 if (retval != ERROR_OK)
526 return retval;
527
528 if ((dscr & DSCR_ITE) == 0)
529 LOG_ERROR("DSCR InstrCompl must be set before leaving debug!");
530
531 /* make sure to acknowledge the halt event before resuming */
532 retval = mem_ap_write_atomic_u32(armv8->debug_ap,
533 armv8->cti_base + CTI_INACK, CTI_TRIG(HALT));
534
535 /*
536 * open the CTI gate for channel 1 so that the restart events
537 * get passed along to all PEs
538 */
539 if (retval == ERROR_OK)
540 retval = mem_ap_write_atomic_u32(armv8->debug_ap,
541 armv8->cti_base + CTI_GATE, CTI_CHNL(1));
542 if (retval != ERROR_OK)
543 return retval;
544
545 if (!slave_pe) {
546 /* trigger an event on channel 1, generates a restart request to the PE */
547 retval = mem_ap_write_atomic_u32(armv8->debug_ap,
548 armv8->cti_base + CTI_APPPULSE, CTI_CHNL(1));
549 if (retval != ERROR_OK)
550 return retval;
551
552 long long then = timeval_ms();
553 for (;; ) {
554 retval = mem_ap_read_atomic_u32(armv8->debug_ap,
555 armv8->debug_base + CPUV8_DBG_DSCR, &dscr);
556 if (retval != ERROR_OK)
557 return retval;
558 if ((dscr & DSCR_HDE) != 0)
559 break;
560 if (timeval_ms() > then + 1000) {
561 LOG_ERROR("Timeout waiting for resume");
562 return ERROR_FAIL;
563 }
564 }
565 }
566
567 target->debug_reason = DBG_REASON_NOTHALTED;
568 target->state = TARGET_RUNNING;
569
570 /* registers are now invalid */
571 register_cache_invalidate(arm->core_cache);
572
573 return ERROR_OK;
574 }
575
576 static int aarch64_restore_smp(struct target *target, int handle_breakpoints)
577 {
578 int retval = 0;
579 struct target_list *head;
580 struct target *curr;
581 uint64_t address;
582 head = target->head;
583 while (head != (struct target_list *)NULL) {
584 curr = head->target;
585 if ((curr != target) && (curr->state != TARGET_RUNNING)) {
586 /* resume current address , not in step mode */
587 retval += aarch64_internal_restore(curr, 1, &address,
588 handle_breakpoints, 0);
589 retval += aarch64_internal_restart(curr, true);
590 }
591 head = head->next;
592
593 }
594 return retval;
595 }
596
597 static int aarch64_resume(struct target *target, int current,
598 target_addr_t address, int handle_breakpoints, int debug_execution)
599 {
600 int retval = 0;
601 uint64_t addr = address;
602
603 /* dummy resume for smp toggle in order to reduce gdb impact */
604 if ((target->smp) && (target->gdb_service->core[1] != -1)) {
605 /* simulate a start and halt of target */
606 target->gdb_service->target = NULL;
607 target->gdb_service->core[0] = target->gdb_service->core[1];
608 /* fake resume at next poll we play the target core[1], see poll*/
609 target_call_event_callbacks(target, TARGET_EVENT_RESUMED);
610 return 0;
611 }
612 aarch64_internal_restore(target, current, &addr, handle_breakpoints,
613 debug_execution);
614 if (target->smp) {
615 target->gdb_service->core[0] = -1;
616 retval = aarch64_restore_smp(target, handle_breakpoints);
617 if (retval != ERROR_OK)
618 return retval;
619 }
620 aarch64_internal_restart(target, false);
621
622 if (!debug_execution) {
623 target->state = TARGET_RUNNING;
624 target_call_event_callbacks(target, TARGET_EVENT_RESUMED);
625 LOG_DEBUG("target resumed at 0x%" PRIx64, addr);
626 } else {
627 target->state = TARGET_DEBUG_RUNNING;
628 target_call_event_callbacks(target, TARGET_EVENT_DEBUG_RESUMED);
629 LOG_DEBUG("target debug resumed at 0x%" PRIx64, addr);
630 }
631
632 return ERROR_OK;
633 }
634
635 static int aarch64_debug_entry(struct target *target)
636 {
637 int retval = ERROR_OK;
638 struct aarch64_common *aarch64 = target_to_aarch64(target);
639 struct armv8_common *armv8 = target_to_armv8(target);
640
641 LOG_DEBUG("dscr = 0x%08" PRIx32, aarch64->cpudbg_dscr);
642
643 /* REVISIT see A8 TRM 12.11.4 steps 2..3 -- make sure that any
644 * imprecise data aborts get discarded by issuing a Data
645 * Synchronization Barrier: ARMV4_5_MCR(15, 0, 0, 7, 10, 4).
646 */
647
648 /* make sure to clear all sticky errors */
649 retval = mem_ap_write_atomic_u32(armv8->debug_ap,
650 armv8->debug_base + CPUV8_DBG_DRCR, DRCR_CSE);
651 if (retval != ERROR_OK)
652 return retval;
653
654 /* Examine debug reason */
655 armv8_dpm_report_dscr(&armv8->dpm, aarch64->cpudbg_dscr);
656
657 /* save address of instruction that triggered the watchpoint? */
658 if (target->debug_reason == DBG_REASON_WATCHPOINT) {
659 uint32_t tmp;
660 uint64_t wfar = 0;
661
662 retval = mem_ap_read_atomic_u32(armv8->debug_ap,
663 armv8->debug_base + CPUV8_DBG_WFAR1,
664 &tmp);
665 if (retval != ERROR_OK)
666 return retval;
667 wfar = tmp;
668 wfar = (wfar << 32);
669 retval = mem_ap_read_atomic_u32(armv8->debug_ap,
670 armv8->debug_base + CPUV8_DBG_WFAR0,
671 &tmp);
672 if (retval != ERROR_OK)
673 return retval;
674 wfar |= tmp;
675 armv8_dpm_report_wfar(&armv8->dpm, wfar);
676 }
677
678 retval = armv8_dpm_read_current_registers(&armv8->dpm);
679
680 if (armv8->post_debug_entry) {
681 retval = armv8->post_debug_entry(target);
682 if (retval != ERROR_OK)
683 return retval;
684 }
685
686 return retval;
687 }
688
689 static int aarch64_post_debug_entry(struct target *target)
690 {
691 struct aarch64_common *aarch64 = target_to_aarch64(target);
692 struct armv8_common *armv8 = &aarch64->armv8_common;
693 int retval;
694
695 /* clear sticky errors */
696 mem_ap_write_atomic_u32(armv8->debug_ap,
697 armv8->debug_base + CPUV8_DBG_DRCR, DRCR_CSE);
698
699 switch (armv8->arm.core_mode) {
700 case ARMV8_64_EL0T:
701 case ARMV8_64_EL1T:
702 case ARMV8_64_EL1H:
703 retval = armv8->arm.mrs(target, 3, /*op 0*/
704 0, 0, /* op1, op2 */
705 1, 0, /* CRn, CRm */
706 &aarch64->system_control_reg);
707 if (retval != ERROR_OK)
708 return retval;
709 break;
710 case ARMV8_64_EL2T:
711 case ARMV8_64_EL2H:
712 retval = armv8->arm.mrs(target, 3, /*op 0*/
713 4, 0, /* op1, op2 */
714 1, 0, /* CRn, CRm */
715 &aarch64->system_control_reg);
716 if (retval != ERROR_OK)
717 return retval;
718 break;
719 case ARMV8_64_EL3H:
720 case ARMV8_64_EL3T:
721 retval = armv8->arm.mrs(target, 3, /*op 0*/
722 6, 0, /* op1, op2 */
723 1, 0, /* CRn, CRm */
724 &aarch64->system_control_reg);
725 if (retval != ERROR_OK)
726 return retval;
727 break;
728 default:
729 retval = armv8->arm.mrc(target, 15, 0, 0, 1, 0, &aarch64->system_control_reg);
730 if (retval != ERROR_OK)
731 return retval;
732 break;
733 }
734
735 LOG_DEBUG("System_register: %8.8" PRIx32, aarch64->system_control_reg);
736 aarch64->system_control_reg_curr = aarch64->system_control_reg;
737
738 if (armv8->armv8_mmu.armv8_cache.ctype == -1)
739 armv8_identify_cache(target);
740
741 armv8->armv8_mmu.mmu_enabled =
742 (aarch64->system_control_reg & 0x1U) ? 1 : 0;
743 armv8->armv8_mmu.armv8_cache.d_u_cache_enabled =
744 (aarch64->system_control_reg & 0x4U) ? 1 : 0;
745 armv8->armv8_mmu.armv8_cache.i_cache_enabled =
746 (aarch64->system_control_reg & 0x1000U) ? 1 : 0;
747 aarch64->curr_mode = armv8->arm.core_mode;
748 return ERROR_OK;
749 }
750
751 static int aarch64_set_dscr_bits(struct target *target, unsigned long bit_mask, unsigned long value)
752 {
753 struct armv8_common *armv8 = target_to_armv8(target);
754 uint32_t dscr;
755
756 /* Read DSCR */
757 int retval = mem_ap_read_atomic_u32(armv8->debug_ap,
758 armv8->debug_base + CPUV8_DBG_DSCR, &dscr);
759 if (ERROR_OK != retval)
760 return retval;
761
762 /* clear bitfield */
763 dscr &= ~bit_mask;
764 /* put new value */
765 dscr |= value & bit_mask;
766
767 /* write new DSCR */
768 retval = mem_ap_write_atomic_u32(armv8->debug_ap,
769 armv8->debug_base + CPUV8_DBG_DSCR, dscr);
770 return retval;
771 }
772
773 static int aarch64_step(struct target *target, int current, target_addr_t address,
774 int handle_breakpoints)
775 {
776 struct armv8_common *armv8 = target_to_armv8(target);
777 int retval;
778 uint32_t edecr;
779
780 if (target->state != TARGET_HALTED) {
781 LOG_WARNING("target not halted");
782 return ERROR_TARGET_NOT_HALTED;
783 }
784
785 retval = mem_ap_read_atomic_u32(armv8->debug_ap,
786 armv8->debug_base + CPUV8_DBG_EDECR, &edecr);
787 if (retval != ERROR_OK)
788 return retval;
789
790 /* make sure EDECR.SS is not set when restoring the register */
791 edecr &= ~0x4;
792
793 /* set EDECR.SS to enter hardware step mode */
794 retval = mem_ap_write_atomic_u32(armv8->debug_ap,
795 armv8->debug_base + CPUV8_DBG_EDECR, (edecr|0x4));
796 if (retval != ERROR_OK)
797 return retval;
798
799 /* disable interrupts while stepping */
800 retval = aarch64_set_dscr_bits(target, 0x3 << 22, 0x3 << 22);
801 if (retval != ERROR_OK)
802 return ERROR_OK;
803
804 /* resume the target */
805 retval = aarch64_resume(target, current, address, 0, 0);
806 if (retval != ERROR_OK)
807 return retval;
808
809 long long then = timeval_ms();
810 while (target->state != TARGET_HALTED) {
811 retval = aarch64_poll(target);
812 if (retval != ERROR_OK)
813 return retval;
814 if (timeval_ms() > then + 1000) {
815 LOG_ERROR("timeout waiting for target halt");
816 return ERROR_FAIL;
817 }
818 }
819
820 /* restore EDECR */
821 retval = mem_ap_write_atomic_u32(armv8->debug_ap,
822 armv8->debug_base + CPUV8_DBG_EDECR, edecr);
823 if (retval != ERROR_OK)
824 return retval;
825
826 /* restore interrupts */
827 retval = aarch64_set_dscr_bits(target, 0x3 << 22, 0);
828 if (retval != ERROR_OK)
829 return ERROR_OK;
830
831 return ERROR_OK;
832 }
833
834 static int aarch64_restore_context(struct target *target, bool bpwp)
835 {
836 struct armv8_common *armv8 = target_to_armv8(target);
837
838 LOG_DEBUG(" ");
839
840 if (armv8->pre_restore_context)
841 armv8->pre_restore_context(target);
842
843 return armv8_dpm_write_dirty_registers(&armv8->dpm, bpwp);
844
845 }
846
847 /*
848 * Cortex-A8 Breakpoint and watchpoint functions
849 */
850
851 /* Setup hardware Breakpoint Register Pair */
852 static int aarch64_set_breakpoint(struct target *target,
853 struct breakpoint *breakpoint, uint8_t matchmode)
854 {
855 int retval;
856 int brp_i = 0;
857 uint32_t control;
858 uint8_t byte_addr_select = 0x0F;
859 struct aarch64_common *aarch64 = target_to_aarch64(target);
860 struct armv8_common *armv8 = &aarch64->armv8_common;
861 struct aarch64_brp *brp_list = aarch64->brp_list;
862 uint32_t dscr;
863
864 if (breakpoint->set) {
865 LOG_WARNING("breakpoint already set");
866 return ERROR_OK;
867 }
868
869 if (breakpoint->type == BKPT_HARD) {
870 int64_t bpt_value;
871 while (brp_list[brp_i].used && (brp_i < aarch64->brp_num))
872 brp_i++;
873 if (brp_i >= aarch64->brp_num) {
874 LOG_ERROR("ERROR Can not find free Breakpoint Register Pair");
875 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
876 }
877 breakpoint->set = brp_i + 1;
878 if (breakpoint->length == 2)
879 byte_addr_select = (3 << (breakpoint->address & 0x02));
880 control = ((matchmode & 0x7) << 20)
881 | (1 << 13)
882 | (byte_addr_select << 5)
883 | (3 << 1) | 1;
884 brp_list[brp_i].used = 1;
885 brp_list[brp_i].value = breakpoint->address & 0xFFFFFFFFFFFFFFFC;
886 brp_list[brp_i].control = control;
887 bpt_value = brp_list[brp_i].value;
888
889 retval = aarch64_dap_write_memap_register_u32(target, armv8->debug_base
890 + CPUV8_DBG_BVR_BASE + 16 * brp_list[brp_i].BRPn,
891 (uint32_t)(bpt_value & 0xFFFFFFFF));
892 if (retval != ERROR_OK)
893 return retval;
894 retval = aarch64_dap_write_memap_register_u32(target, armv8->debug_base
895 + CPUV8_DBG_BVR_BASE + 4 + 16 * brp_list[brp_i].BRPn,
896 (uint32_t)(bpt_value >> 32));
897 if (retval != ERROR_OK)
898 return retval;
899
900 retval = aarch64_dap_write_memap_register_u32(target, armv8->debug_base
901 + CPUV8_DBG_BCR_BASE + 16 * brp_list[brp_i].BRPn,
902 brp_list[brp_i].control);
903 if (retval != ERROR_OK)
904 return retval;
905 LOG_DEBUG("brp %i control 0x%0" PRIx32 " value 0x%" TARGET_PRIxADDR, brp_i,
906 brp_list[brp_i].control,
907 brp_list[brp_i].value);
908
909 } else if (breakpoint->type == BKPT_SOFT) {
910 uint8_t code[4];
911
912 buf_set_u32(code, 0, 32, ARMV8_HLT(0x11));
913 retval = target_read_memory(target,
914 breakpoint->address & 0xFFFFFFFFFFFFFFFE,
915 breakpoint->length, 1,
916 breakpoint->orig_instr);
917 if (retval != ERROR_OK)
918 return retval;
919
920 armv8_cache_d_inner_flush_virt(armv8,
921 breakpoint->address & 0xFFFFFFFFFFFFFFFE,
922 breakpoint->length);
923
924 retval = target_write_memory(target,
925 breakpoint->address & 0xFFFFFFFFFFFFFFFE,
926 breakpoint->length, 1, code);
927 if (retval != ERROR_OK)
928 return retval;
929
930 armv8_cache_d_inner_flush_virt(armv8,
931 breakpoint->address & 0xFFFFFFFFFFFFFFFE,
932 breakpoint->length);
933
934 armv8_cache_i_inner_inval_virt(armv8,
935 breakpoint->address & 0xFFFFFFFFFFFFFFFE,
936 breakpoint->length);
937
938 breakpoint->set = 0x11; /* Any nice value but 0 */
939 }
940
941 retval = mem_ap_read_atomic_u32(armv8->debug_ap,
942 armv8->debug_base + CPUV8_DBG_DSCR, &dscr);
943 /* Ensure that halting debug mode is enable */
944 dscr = dscr | DSCR_HDE;
945 retval = mem_ap_write_atomic_u32(armv8->debug_ap,
946 armv8->debug_base + CPUV8_DBG_DSCR, dscr);
947 if (retval != ERROR_OK) {
948 LOG_DEBUG("Failed to set DSCR.HDE");
949 return retval;
950 }
951
952 return ERROR_OK;
953 }
954
955 static int aarch64_set_context_breakpoint(struct target *target,
956 struct breakpoint *breakpoint, uint8_t matchmode)
957 {
958 int retval = ERROR_FAIL;
959 int brp_i = 0;
960 uint32_t control;
961 uint8_t byte_addr_select = 0x0F;
962 struct aarch64_common *aarch64 = target_to_aarch64(target);
963 struct armv8_common *armv8 = &aarch64->armv8_common;
964 struct aarch64_brp *brp_list = aarch64->brp_list;
965
966 if (breakpoint->set) {
967 LOG_WARNING("breakpoint already set");
968 return retval;
969 }
970 /*check available context BRPs*/
971 while ((brp_list[brp_i].used ||
972 (brp_list[brp_i].type != BRP_CONTEXT)) && (brp_i < aarch64->brp_num))
973 brp_i++;
974
975 if (brp_i >= aarch64->brp_num) {
976 LOG_ERROR("ERROR Can not find free Breakpoint Register Pair");
977 return ERROR_FAIL;
978 }
979
980 breakpoint->set = brp_i + 1;
981 control = ((matchmode & 0x7) << 20)
982 | (1 << 13)
983 | (byte_addr_select << 5)
984 | (3 << 1) | 1;
985 brp_list[brp_i].used = 1;
986 brp_list[brp_i].value = (breakpoint->asid);
987 brp_list[brp_i].control = control;
988 retval = aarch64_dap_write_memap_register_u32(target, armv8->debug_base
989 + CPUV8_DBG_BVR_BASE + 16 * brp_list[brp_i].BRPn,
990 brp_list[brp_i].value);
991 if (retval != ERROR_OK)
992 return retval;
993 retval = aarch64_dap_write_memap_register_u32(target, armv8->debug_base
994 + CPUV8_DBG_BCR_BASE + 16 * brp_list[brp_i].BRPn,
995 brp_list[brp_i].control);
996 if (retval != ERROR_OK)
997 return retval;
998 LOG_DEBUG("brp %i control 0x%0" PRIx32 " value 0x%" TARGET_PRIxADDR, brp_i,
999 brp_list[brp_i].control,
1000 brp_list[brp_i].value);
1001 return ERROR_OK;
1002
1003 }
1004
1005 static int aarch64_set_hybrid_breakpoint(struct target *target, struct breakpoint *breakpoint)
1006 {
1007 int retval = ERROR_FAIL;
1008 int brp_1 = 0; /* holds the contextID pair */
1009 int brp_2 = 0; /* holds the IVA pair */
1010 uint32_t control_CTX, control_IVA;
1011 uint8_t CTX_byte_addr_select = 0x0F;
1012 uint8_t IVA_byte_addr_select = 0x0F;
1013 uint8_t CTX_machmode = 0x03;
1014 uint8_t IVA_machmode = 0x01;
1015 struct aarch64_common *aarch64 = target_to_aarch64(target);
1016 struct armv8_common *armv8 = &aarch64->armv8_common;
1017 struct aarch64_brp *brp_list = aarch64->brp_list;
1018
1019 if (breakpoint->set) {
1020 LOG_WARNING("breakpoint already set");
1021 return retval;
1022 }
1023 /*check available context BRPs*/
1024 while ((brp_list[brp_1].used ||
1025 (brp_list[brp_1].type != BRP_CONTEXT)) && (brp_1 < aarch64->brp_num))
1026 brp_1++;
1027
1028 printf("brp(CTX) found num: %d\n", brp_1);
1029 if (brp_1 >= aarch64->brp_num) {
1030 LOG_ERROR("ERROR Can not find free Breakpoint Register Pair");
1031 return ERROR_FAIL;
1032 }
1033
1034 while ((brp_list[brp_2].used ||
1035 (brp_list[brp_2].type != BRP_NORMAL)) && (brp_2 < aarch64->brp_num))
1036 brp_2++;
1037
1038 printf("brp(IVA) found num: %d\n", brp_2);
1039 if (brp_2 >= aarch64->brp_num) {
1040 LOG_ERROR("ERROR Can not find free Breakpoint Register Pair");
1041 return ERROR_FAIL;
1042 }
1043
1044 breakpoint->set = brp_1 + 1;
1045 breakpoint->linked_BRP = brp_2;
1046 control_CTX = ((CTX_machmode & 0x7) << 20)
1047 | (brp_2 << 16)
1048 | (0 << 14)
1049 | (CTX_byte_addr_select << 5)
1050 | (3 << 1) | 1;
1051 brp_list[brp_1].used = 1;
1052 brp_list[brp_1].value = (breakpoint->asid);
1053 brp_list[brp_1].control = control_CTX;
1054 retval = aarch64_dap_write_memap_register_u32(target, armv8->debug_base
1055 + CPUV8_DBG_BVR_BASE + 16 * brp_list[brp_1].BRPn,
1056 brp_list[brp_1].value);
1057 if (retval != ERROR_OK)
1058 return retval;
1059 retval = aarch64_dap_write_memap_register_u32(target, armv8->debug_base
1060 + CPUV8_DBG_BCR_BASE + 16 * brp_list[brp_1].BRPn,
1061 brp_list[brp_1].control);
1062 if (retval != ERROR_OK)
1063 return retval;
1064
1065 control_IVA = ((IVA_machmode & 0x7) << 20)
1066 | (brp_1 << 16)
1067 | (1 << 13)
1068 | (IVA_byte_addr_select << 5)
1069 | (3 << 1) | 1;
1070 brp_list[brp_2].used = 1;
1071 brp_list[brp_2].value = breakpoint->address & 0xFFFFFFFFFFFFFFFC;
1072 brp_list[brp_2].control = control_IVA;
1073 retval = aarch64_dap_write_memap_register_u32(target, armv8->debug_base
1074 + CPUV8_DBG_BVR_BASE + 16 * brp_list[brp_2].BRPn,
1075 brp_list[brp_2].value & 0xFFFFFFFF);
1076 if (retval != ERROR_OK)
1077 return retval;
1078 retval = aarch64_dap_write_memap_register_u32(target, armv8->debug_base
1079 + CPUV8_DBG_BVR_BASE + 4 + 16 * brp_list[brp_2].BRPn,
1080 brp_list[brp_2].value >> 32);
1081 if (retval != ERROR_OK)
1082 return retval;
1083 retval = aarch64_dap_write_memap_register_u32(target, armv8->debug_base
1084 + CPUV8_DBG_BCR_BASE + 16 * brp_list[brp_2].BRPn,
1085 brp_list[brp_2].control);
1086 if (retval != ERROR_OK)
1087 return retval;
1088
1089 return ERROR_OK;
1090 }
1091
1092 static int aarch64_unset_breakpoint(struct target *target, struct breakpoint *breakpoint)
1093 {
1094 int retval;
1095 struct aarch64_common *aarch64 = target_to_aarch64(target);
1096 struct armv8_common *armv8 = &aarch64->armv8_common;
1097 struct aarch64_brp *brp_list = aarch64->brp_list;
1098
1099 if (!breakpoint->set) {
1100 LOG_WARNING("breakpoint not set");
1101 return ERROR_OK;
1102 }
1103
1104 if (breakpoint->type == BKPT_HARD) {
1105 if ((breakpoint->address != 0) && (breakpoint->asid != 0)) {
1106 int brp_i = breakpoint->set - 1;
1107 int brp_j = breakpoint->linked_BRP;
1108 if ((brp_i < 0) || (brp_i >= aarch64->brp_num)) {
1109 LOG_DEBUG("Invalid BRP number in breakpoint");
1110 return ERROR_OK;
1111 }
1112 LOG_DEBUG("rbp %i control 0x%0" PRIx32 " value 0x%" TARGET_PRIxADDR, brp_i,
1113 brp_list[brp_i].control, brp_list[brp_i].value);
1114 brp_list[brp_i].used = 0;
1115 brp_list[brp_i].value = 0;
1116 brp_list[brp_i].control = 0;
1117 retval = aarch64_dap_write_memap_register_u32(target, armv8->debug_base
1118 + CPUV8_DBG_BCR_BASE + 16 * brp_list[brp_i].BRPn,
1119 brp_list[brp_i].control);
1120 if (retval != ERROR_OK)
1121 return retval;
1122 retval = aarch64_dap_write_memap_register_u32(target, armv8->debug_base
1123 + CPUV8_DBG_BVR_BASE + 16 * brp_list[brp_i].BRPn,
1124 (uint32_t)brp_list[brp_i].value);
1125 if (retval != ERROR_OK)
1126 return retval;
1127 retval = aarch64_dap_write_memap_register_u32(target, armv8->debug_base
1128 + CPUV8_DBG_BVR_BASE + 4 + 16 * brp_list[brp_i].BRPn,
1129 (uint32_t)brp_list[brp_i].value);
1130 if (retval != ERROR_OK)
1131 return retval;
1132 if ((brp_j < 0) || (brp_j >= aarch64->brp_num)) {
1133 LOG_DEBUG("Invalid BRP number in breakpoint");
1134 return ERROR_OK;
1135 }
1136 LOG_DEBUG("rbp %i control 0x%0" PRIx32 " value 0x%0" PRIx64, brp_j,
1137 brp_list[brp_j].control, brp_list[brp_j].value);
1138 brp_list[brp_j].used = 0;
1139 brp_list[brp_j].value = 0;
1140 brp_list[brp_j].control = 0;
1141 retval = aarch64_dap_write_memap_register_u32(target, armv8->debug_base
1142 + CPUV8_DBG_BCR_BASE + 16 * brp_list[brp_j].BRPn,
1143 brp_list[brp_j].control);
1144 if (retval != ERROR_OK)
1145 return retval;
1146 retval = aarch64_dap_write_memap_register_u32(target, armv8->debug_base
1147 + CPUV8_DBG_BVR_BASE + 16 * brp_list[brp_j].BRPn,
1148 (uint32_t)brp_list[brp_j].value);
1149 if (retval != ERROR_OK)
1150 return retval;
1151 retval = aarch64_dap_write_memap_register_u32(target, armv8->debug_base
1152 + CPUV8_DBG_BVR_BASE + 4 + 16 * brp_list[brp_j].BRPn,
1153 (uint32_t)brp_list[brp_j].value);
1154 if (retval != ERROR_OK)
1155 return retval;
1156
1157 breakpoint->linked_BRP = 0;
1158 breakpoint->set = 0;
1159 return ERROR_OK;
1160
1161 } else {
1162 int brp_i = breakpoint->set - 1;
1163 if ((brp_i < 0) || (brp_i >= aarch64->brp_num)) {
1164 LOG_DEBUG("Invalid BRP number in breakpoint");
1165 return ERROR_OK;
1166 }
1167 LOG_DEBUG("rbp %i control 0x%0" PRIx32 " value 0x%0" PRIx64, brp_i,
1168 brp_list[brp_i].control, brp_list[brp_i].value);
1169 brp_list[brp_i].used = 0;
1170 brp_list[brp_i].value = 0;
1171 brp_list[brp_i].control = 0;
1172 retval = aarch64_dap_write_memap_register_u32(target, armv8->debug_base
1173 + CPUV8_DBG_BCR_BASE + 16 * brp_list[brp_i].BRPn,
1174 brp_list[brp_i].control);
1175 if (retval != ERROR_OK)
1176 return retval;
1177 retval = aarch64_dap_write_memap_register_u32(target, armv8->debug_base
1178 + CPUV8_DBG_BVR_BASE + 16 * brp_list[brp_i].BRPn,
1179 brp_list[brp_i].value);
1180 if (retval != ERROR_OK)
1181 return retval;
1182
1183 retval = aarch64_dap_write_memap_register_u32(target, armv8->debug_base
1184 + CPUV8_DBG_BVR_BASE + 4 + 16 * brp_list[brp_i].BRPn,
1185 (uint32_t)brp_list[brp_i].value);
1186 if (retval != ERROR_OK)
1187 return retval;
1188 breakpoint->set = 0;
1189 return ERROR_OK;
1190 }
1191 } else {
1192 /* restore original instruction (kept in target endianness) */
1193
1194 armv8_cache_d_inner_flush_virt(armv8,
1195 breakpoint->address & 0xFFFFFFFFFFFFFFFE,
1196 breakpoint->length);
1197
1198 if (breakpoint->length == 4) {
1199 retval = target_write_memory(target,
1200 breakpoint->address & 0xFFFFFFFFFFFFFFFE,
1201 4, 1, breakpoint->orig_instr);
1202 if (retval != ERROR_OK)
1203 return retval;
1204 } else {
1205 retval = target_write_memory(target,
1206 breakpoint->address & 0xFFFFFFFFFFFFFFFE,
1207 2, 1, breakpoint->orig_instr);
1208 if (retval != ERROR_OK)
1209 return retval;
1210 }
1211
1212 armv8_cache_d_inner_flush_virt(armv8,
1213 breakpoint->address & 0xFFFFFFFFFFFFFFFE,
1214 breakpoint->length);
1215
1216 armv8_cache_i_inner_inval_virt(armv8,
1217 breakpoint->address & 0xFFFFFFFFFFFFFFFE,
1218 breakpoint->length);
1219 }
1220 breakpoint->set = 0;
1221
1222 return ERROR_OK;
1223 }
1224
1225 static int aarch64_add_breakpoint(struct target *target,
1226 struct breakpoint *breakpoint)
1227 {
1228 struct aarch64_common *aarch64 = target_to_aarch64(target);
1229
1230 if ((breakpoint->type == BKPT_HARD) && (aarch64->brp_num_available < 1)) {
1231 LOG_INFO("no hardware breakpoint available");
1232 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
1233 }
1234
1235 if (breakpoint->type == BKPT_HARD)
1236 aarch64->brp_num_available--;
1237
1238 return aarch64_set_breakpoint(target, breakpoint, 0x00); /* Exact match */
1239 }
1240
1241 static int aarch64_add_context_breakpoint(struct target *target,
1242 struct breakpoint *breakpoint)
1243 {
1244 struct aarch64_common *aarch64 = target_to_aarch64(target);
1245
1246 if ((breakpoint->type == BKPT_HARD) && (aarch64->brp_num_available < 1)) {
1247 LOG_INFO("no hardware breakpoint available");
1248 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
1249 }
1250
1251 if (breakpoint->type == BKPT_HARD)
1252 aarch64->brp_num_available--;
1253
1254 return aarch64_set_context_breakpoint(target, breakpoint, 0x02); /* asid match */
1255 }
1256
1257 static int aarch64_add_hybrid_breakpoint(struct target *target,
1258 struct breakpoint *breakpoint)
1259 {
1260 struct aarch64_common *aarch64 = target_to_aarch64(target);
1261
1262 if ((breakpoint->type == BKPT_HARD) && (aarch64->brp_num_available < 1)) {
1263 LOG_INFO("no hardware breakpoint available");
1264 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
1265 }
1266
1267 if (breakpoint->type == BKPT_HARD)
1268 aarch64->brp_num_available--;
1269
1270 return aarch64_set_hybrid_breakpoint(target, breakpoint); /* ??? */
1271 }
1272
1273
1274 static int aarch64_remove_breakpoint(struct target *target, struct breakpoint *breakpoint)
1275 {
1276 struct aarch64_common *aarch64 = target_to_aarch64(target);
1277
1278 #if 0
1279 /* It is perfectly possible to remove breakpoints while the target is running */
1280 if (target->state != TARGET_HALTED) {
1281 LOG_WARNING("target not halted");
1282 return ERROR_TARGET_NOT_HALTED;
1283 }
1284 #endif
1285
1286 if (breakpoint->set) {
1287 aarch64_unset_breakpoint(target, breakpoint);
1288 if (breakpoint->type == BKPT_HARD)
1289 aarch64->brp_num_available++;
1290 }
1291
1292 return ERROR_OK;
1293 }
1294
1295 /*
1296 * Cortex-A8 Reset functions
1297 */
1298
1299 static int aarch64_assert_reset(struct target *target)
1300 {
1301 struct armv8_common *armv8 = target_to_armv8(target);
1302
1303 LOG_DEBUG(" ");
1304
1305 /* FIXME when halt is requested, make it work somehow... */
1306
1307 /* Issue some kind of warm reset. */
1308 if (target_has_event_action(target, TARGET_EVENT_RESET_ASSERT))
1309 target_handle_event(target, TARGET_EVENT_RESET_ASSERT);
1310 else if (jtag_get_reset_config() & RESET_HAS_SRST) {
1311 /* REVISIT handle "pulls" cases, if there's
1312 * hardware that needs them to work.
1313 */
1314 jtag_add_reset(0, 1);
1315 } else {
1316 LOG_ERROR("%s: how to reset?", target_name(target));
1317 return ERROR_FAIL;
1318 }
1319
1320 /* registers are now invalid */
1321 register_cache_invalidate(armv8->arm.core_cache);
1322
1323 target->state = TARGET_RESET;
1324
1325 return ERROR_OK;
1326 }
1327
1328 static int aarch64_deassert_reset(struct target *target)
1329 {
1330 int retval;
1331
1332 LOG_DEBUG(" ");
1333
1334 /* be certain SRST is off */
1335 jtag_add_reset(0, 0);
1336
1337 retval = aarch64_poll(target);
1338 if (retval != ERROR_OK)
1339 return retval;
1340
1341 if (target->reset_halt) {
1342 if (target->state != TARGET_HALTED) {
1343 LOG_WARNING("%s: ran after reset and before halt ...",
1344 target_name(target));
1345 retval = target_halt(target);
1346 if (retval != ERROR_OK)
1347 return retval;
1348 }
1349 }
1350
1351 return ERROR_OK;
1352 }
1353
1354 static int aarch64_write_apb_ap_memory(struct target *target,
1355 uint64_t address, uint32_t size,
1356 uint32_t count, const uint8_t *buffer)
1357 {
1358 /* write memory through APB-AP */
1359 int retval = ERROR_COMMAND_SYNTAX_ERROR;
1360 struct armv8_common *armv8 = target_to_armv8(target);
1361 struct arm_dpm *dpm = &armv8->dpm;
1362 struct arm *arm = &armv8->arm;
1363 int total_bytes = count * size;
1364 int total_u32;
1365 int start_byte = address & 0x3;
1366 int end_byte = (address + total_bytes) & 0x3;
1367 struct reg *reg;
1368 uint32_t dscr;
1369 uint8_t *tmp_buff = NULL;
1370
1371 LOG_DEBUG("Writing APB-AP memory address 0x%" PRIx64 " size %" PRIu32 " count%" PRIu32,
1372 address, size, count);
1373 if (target->state != TARGET_HALTED) {
1374 LOG_WARNING("target not halted");
1375 return ERROR_TARGET_NOT_HALTED;
1376 }
1377
1378 total_u32 = DIV_ROUND_UP((address & 3) + total_bytes, 4);
1379
1380 /* Mark register R0 as dirty, as it will be used
1381 * for transferring the data.
1382 * It will be restored automatically when exiting
1383 * debug mode
1384 */
1385 reg = armv8_reg_current(arm, 1);
1386 reg->dirty = true;
1387
1388 reg = armv8_reg_current(arm, 0);
1389 reg->dirty = true;
1390
1391 /* clear any abort */
1392 retval = mem_ap_write_atomic_u32(armv8->debug_ap,
1393 armv8->debug_base + CPUV8_DBG_DRCR, DRCR_CSE);
1394 if (retval != ERROR_OK)
1395 return retval;
1396
1397
1398 /* This algorithm comes from DDI0487A.g, chapter J9.1 */
1399
1400 /* The algorithm only copies 32 bit words, so the buffer
1401 * should be expanded to include the words at either end.
1402 * The first and last words will be read first to avoid
1403 * corruption if needed.
1404 */
1405 tmp_buff = malloc(total_u32 * 4);
1406
1407 if ((start_byte != 0) && (total_u32 > 1)) {
1408 /* First bytes not aligned - read the 32 bit word to avoid corrupting
1409 * the other bytes in the word.
1410 */
1411 retval = aarch64_read_apb_ap_memory(target, (address & ~0x3), 4, 1, tmp_buff);
1412 if (retval != ERROR_OK)
1413 goto error_free_buff_w;
1414 }
1415
1416 /* If end of write is not aligned, or the write is less than 4 bytes */
1417 if ((end_byte != 0) ||
1418 ((total_u32 == 1) && (total_bytes != 4))) {
1419
1420 /* Read the last word to avoid corruption during 32 bit write */
1421 int mem_offset = (total_u32-1) * 4;
1422 retval = aarch64_read_apb_ap_memory(target, (address & ~0x3) + mem_offset, 4, 1, &tmp_buff[mem_offset]);
1423 if (retval != ERROR_OK)
1424 goto error_free_buff_w;
1425 }
1426
1427 /* Copy the write buffer over the top of the temporary buffer */
1428 memcpy(&tmp_buff[start_byte], buffer, total_bytes);
1429
1430 /* We now have a 32 bit aligned buffer that can be written */
1431
1432 /* Read DSCR */
1433 retval = mem_ap_read_atomic_u32(armv8->debug_ap,
1434 armv8->debug_base + CPUV8_DBG_DSCR, &dscr);
1435 if (retval != ERROR_OK)
1436 goto error_free_buff_w;
1437
1438 /* Set Normal access mode */
1439 dscr = (dscr & ~DSCR_MA);
1440 retval = mem_ap_write_atomic_u32(armv8->debug_ap,
1441 armv8->debug_base + CPUV8_DBG_DSCR, dscr);
1442
1443 if (arm->core_state == ARM_STATE_AARCH64) {
1444 /* Write X0 with value 'address' using write procedure */
1445 /* Step 1.a+b - Write the address for read access into DBGDTR_EL0 */
1446 /* Step 1.c - Copy value from DTR to R0 using instruction mrs DBGDTR_EL0, x0 */
1447 retval = dpm->instr_write_data_dcc_64(dpm,
1448 ARMV8_MRS(SYSTEM_DBG_DBGDTR_EL0, 0), address & ~0x3ULL);
1449 } else {
1450 /* Write R0 with value 'address' using write procedure */
1451 /* Step 1.a+b - Write the address for read access into DBGDTRRX */
1452 /* Step 1.c - Copy value from DTR to R0 using instruction mrc DBGDTRTXint, r0 */
1453 dpm->instr_write_data_dcc(dpm,
1454 T32_FMTITR(ARMV4_5_MRC(14, 0, 0, 0, 5, 0)), address & ~0x3ULL);
1455
1456 }
1457 /* Step 1.d - Change DCC to memory mode */
1458 dscr = dscr | DSCR_MA;
1459 retval += mem_ap_write_atomic_u32(armv8->debug_ap,
1460 armv8->debug_base + CPUV8_DBG_DSCR, dscr);
1461 if (retval != ERROR_OK)
1462 goto error_unset_dtr_w;
1463
1464
1465 /* Step 2.a - Do the write */
1466 retval = mem_ap_write_buf_noincr(armv8->debug_ap,
1467 tmp_buff, 4, total_u32, armv8->debug_base + CPUV8_DBG_DTRRX);
1468 if (retval != ERROR_OK)
1469 goto error_unset_dtr_w;
1470
1471 /* Step 3.a - Switch DTR mode back to Normal mode */
1472 dscr = (dscr & ~DSCR_MA);
1473 retval = mem_ap_write_atomic_u32(armv8->debug_ap,
1474 armv8->debug_base + CPUV8_DBG_DSCR, dscr);
1475 if (retval != ERROR_OK)
1476 goto error_unset_dtr_w;
1477
1478 /* Check for sticky abort flags in the DSCR */
1479 retval = mem_ap_read_atomic_u32(armv8->debug_ap,
1480 armv8->debug_base + CPUV8_DBG_DSCR, &dscr);
1481 if (retval != ERROR_OK)
1482 goto error_free_buff_w;
1483 if (dscr & (DSCR_ERR | DSCR_SYS_ERROR_PEND)) {
1484 /* Abort occurred - clear it and exit */
1485 LOG_ERROR("abort occurred - dscr = 0x%08" PRIx32, dscr);
1486 mem_ap_write_atomic_u32(armv8->debug_ap,
1487 armv8->debug_base + CPUV8_DBG_DRCR, 1<<2);
1488 goto error_free_buff_w;
1489 }
1490
1491 /* Done */
1492 free(tmp_buff);
1493 return ERROR_OK;
1494
1495 error_unset_dtr_w:
1496 /* Unset DTR mode */
1497 mem_ap_read_atomic_u32(armv8->debug_ap,
1498 armv8->debug_base + CPUV8_DBG_DSCR, &dscr);
1499 dscr = (dscr & ~DSCR_MA);
1500 mem_ap_write_atomic_u32(armv8->debug_ap,
1501 armv8->debug_base + CPUV8_DBG_DSCR, dscr);
1502 error_free_buff_w:
1503 LOG_ERROR("error");
1504 free(tmp_buff);
1505 return ERROR_FAIL;
1506 }
1507
1508 static int aarch64_read_apb_ap_memory(struct target *target,
1509 target_addr_t address, uint32_t size,
1510 uint32_t count, uint8_t *buffer)
1511 {
1512 /* read memory through APB-AP */
1513 int retval = ERROR_COMMAND_SYNTAX_ERROR;
1514 struct armv8_common *armv8 = target_to_armv8(target);
1515 struct arm_dpm *dpm = &armv8->dpm;
1516 struct arm *arm = &armv8->arm;
1517 int total_bytes = count * size;
1518 int total_u32;
1519 int start_byte = address & 0x3;
1520 int end_byte = (address + total_bytes) & 0x3;
1521 struct reg *reg;
1522 uint32_t dscr;
1523 uint8_t *tmp_buff = NULL;
1524 uint8_t *u8buf_ptr;
1525 uint32_t value;
1526
1527 LOG_DEBUG("Reading APB-AP memory address 0x%" TARGET_PRIxADDR " size %" PRIu32 " count%" PRIu32,
1528 address, size, count);
1529 if (target->state != TARGET_HALTED) {
1530 LOG_WARNING("target not halted");
1531 return ERROR_TARGET_NOT_HALTED;
1532 }
1533
1534 total_u32 = DIV_ROUND_UP((address & 3) + total_bytes, 4);
1535 /* Mark register X0, X1 as dirty, as it will be used
1536 * for transferring the data.
1537 * It will be restored automatically when exiting
1538 * debug mode
1539 */
1540 reg = armv8_reg_current(arm, 1);
1541 reg->dirty = true;
1542
1543 reg = armv8_reg_current(arm, 0);
1544 reg->dirty = true;
1545
1546 /* clear any abort */
1547 retval = mem_ap_write_atomic_u32(armv8->debug_ap,
1548 armv8->debug_base + CPUV8_DBG_DRCR, DRCR_CSE);
1549 if (retval != ERROR_OK)
1550 goto error_free_buff_r;
1551
1552 /* Read DSCR */
1553 retval = mem_ap_read_atomic_u32(armv8->debug_ap,
1554 armv8->debug_base + CPUV8_DBG_DSCR, &dscr);
1555
1556 /* This algorithm comes from DDI0487A.g, chapter J9.1 */
1557
1558 /* Set Normal access mode */
1559 dscr = (dscr & ~DSCR_MA);
1560 retval += mem_ap_write_atomic_u32(armv8->debug_ap,
1561 armv8->debug_base + CPUV8_DBG_DSCR, dscr);
1562
1563 if (arm->core_state == ARM_STATE_AARCH64) {
1564 /* Write X0 with value 'address' using write procedure */
1565 /* Step 1.a+b - Write the address for read access into DBGDTR_EL0 */
1566 /* Step 1.c - Copy value from DTR to R0 using instruction mrs DBGDTR_EL0, x0 */
1567 retval += dpm->instr_write_data_dcc_64(dpm,
1568 ARMV8_MRS(SYSTEM_DBG_DBGDTR_EL0, 0), address & ~0x3ULL);
1569 /* Step 1.d - Dummy operation to ensure EDSCR.Txfull == 1 */
1570 retval += dpm->instr_execute(dpm, ARMV8_MSR_GP(SYSTEM_DBG_DBGDTR_EL0, 0));
1571 /* Step 1.e - Change DCC to memory mode */
1572 dscr = dscr | DSCR_MA;
1573 retval += mem_ap_write_atomic_u32(armv8->debug_ap,
1574 armv8->debug_base + CPUV8_DBG_DSCR, dscr);
1575 /* Step 1.f - read DBGDTRTX and discard the value */
1576 retval += mem_ap_read_atomic_u32(armv8->debug_ap,
1577 armv8->debug_base + CPUV8_DBG_DTRTX, &value);
1578 } else {
1579 /* Write R0 with value 'address' using write procedure */
1580 /* Step 1.a+b - Write the address for read access into DBGDTRRXint */
1581 /* Step 1.c - Copy value from DTR to R0 using instruction mrc DBGDTRTXint, r0 */
1582 retval += dpm->instr_write_data_dcc(dpm,
1583 T32_FMTITR(ARMV4_5_MRC(14, 0, 0, 0, 5, 0)), address & ~0x3ULL);
1584 /* Step 1.d - Dummy operation to ensure EDSCR.Txfull == 1 */
1585 retval += dpm->instr_execute(dpm, T32_FMTITR(ARMV4_5_MCR(14, 0, 0, 0, 5, 0)));
1586 /* Step 1.e - Change DCC to memory mode */
1587 dscr = dscr | DSCR_MA;
1588 retval += mem_ap_write_atomic_u32(armv8->debug_ap,
1589 armv8->debug_base + CPUV8_DBG_DSCR, dscr);
1590 /* Step 1.f - read DBGDTRTX and discard the value */
1591 retval += mem_ap_read_atomic_u32(armv8->debug_ap,
1592 armv8->debug_base + CPUV8_DBG_DTRTX, &value);
1593
1594 }
1595 if (retval != ERROR_OK)
1596 goto error_unset_dtr_r;
1597
1598 /* Optimize the read as much as we can, either way we read in a single pass */
1599 if ((start_byte) || (end_byte)) {
1600 /* The algorithm only copies 32 bit words, so the buffer
1601 * should be expanded to include the words at either end.
1602 * The first and last words will be read into a temp buffer
1603 * to avoid corruption
1604 */
1605 tmp_buff = malloc(total_u32 * 4);
1606 if (!tmp_buff)
1607 goto error_unset_dtr_r;
1608
1609 /* use the tmp buffer to read the entire data */
1610 u8buf_ptr = tmp_buff;
1611 } else
1612 /* address and read length are aligned so read directly into the passed buffer */
1613 u8buf_ptr = buffer;
1614
1615 /* Read the data - Each read of the DTRTX register causes the instruction to be reissued
1616 * Abort flags are sticky, so can be read at end of transactions
1617 *
1618 * This data is read in aligned to 32 bit boundary.
1619 */
1620
1621 /* Step 2.a - Loop n-1 times, each read of DBGDTRTX reads the data from [X0] and
1622 * increments X0 by 4. */
1623 retval = mem_ap_read_buf_noincr(armv8->debug_ap, u8buf_ptr, 4, total_u32-1,
1624 armv8->debug_base + CPUV8_DBG_DTRTX);
1625 if (retval != ERROR_OK)
1626 goto error_unset_dtr_r;
1627
1628 /* Step 3.a - set DTR access mode back to Normal mode */
1629 dscr = (dscr & ~DSCR_MA);
1630 retval = mem_ap_write_atomic_u32(armv8->debug_ap,
1631 armv8->debug_base + CPUV8_DBG_DSCR, dscr);
1632 if (retval != ERROR_OK)
1633 goto error_free_buff_r;
1634
1635 /* Step 3.b - read DBGDTRTX for the final value */
1636 retval = mem_ap_read_atomic_u32(armv8->debug_ap,
1637 armv8->debug_base + CPUV8_DBG_DTRTX, &value);
1638 memcpy(u8buf_ptr + (total_u32-1) * 4, &value, 4);
1639
1640 /* Check for sticky abort flags in the DSCR */
1641 retval = mem_ap_read_atomic_u32(armv8->debug_ap,
1642 armv8->debug_base + CPUV8_DBG_DSCR, &dscr);
1643 if (retval != ERROR_OK)
1644 goto error_free_buff_r;
1645 if (dscr & (DSCR_ERR | DSCR_SYS_ERROR_PEND)) {
1646 /* Abort occurred - clear it and exit */
1647 LOG_ERROR("abort occurred - dscr = 0x%08" PRIx32, dscr);
1648 mem_ap_write_atomic_u32(armv8->debug_ap,
1649 armv8->debug_base + CPUV8_DBG_DRCR, DRCR_CSE);
1650 goto error_free_buff_r;
1651 }
1652
1653 /* check if we need to copy aligned data by applying any shift necessary */
1654 if (tmp_buff) {
1655 memcpy(buffer, tmp_buff + start_byte, total_bytes);
1656 free(tmp_buff);
1657 }
1658
1659 /* Done */
1660 return ERROR_OK;
1661
1662 error_unset_dtr_r:
1663 /* Unset DTR mode */
1664 mem_ap_read_atomic_u32(armv8->debug_ap,
1665 armv8->debug_base + CPUV8_DBG_DSCR, &dscr);
1666 dscr = (dscr & ~DSCR_MA);
1667 mem_ap_write_atomic_u32(armv8->debug_ap,
1668 armv8->debug_base + CPUV8_DBG_DSCR, dscr);
1669 error_free_buff_r:
1670 LOG_ERROR("error");
1671 free(tmp_buff);
1672 return ERROR_FAIL;
1673 }
1674
1675 static int aarch64_read_phys_memory(struct target *target,
1676 target_addr_t address, uint32_t size,
1677 uint32_t count, uint8_t *buffer)
1678 {
1679 int retval = ERROR_COMMAND_SYNTAX_ERROR;
1680 LOG_DEBUG("Reading memory at real address 0x%" TARGET_PRIxADDR "; size %" PRId32 "; count %" PRId32,
1681 address, size, count);
1682
1683 if (count && buffer) {
1684 /* read memory through APB-AP */
1685 retval = aarch64_mmu_modify(target, 0);
1686 if (retval != ERROR_OK)
1687 return retval;
1688 retval = aarch64_read_apb_ap_memory(target, address, size, count, buffer);
1689 }
1690 return retval;
1691 }
1692
1693 static int aarch64_read_memory(struct target *target, target_addr_t address,
1694 uint32_t size, uint32_t count, uint8_t *buffer)
1695 {
1696 int mmu_enabled = 0;
1697 int retval;
1698
1699 /* aarch64 handles unaligned memory access */
1700 LOG_DEBUG("Reading memory at address 0x%" TARGET_PRIxADDR "; size %" PRId32 "; count %" PRId32, address,
1701 size, count);
1702
1703 /* determine if MMU was enabled on target stop */
1704 retval = aarch64_mmu(target, &mmu_enabled);
1705 if (retval != ERROR_OK)
1706 return retval;
1707
1708 if (mmu_enabled) {
1709 retval = aarch64_check_address(target, address);
1710 if (retval != ERROR_OK)
1711 return retval;
1712 /* enable MMU as we could have disabled it for phys access */
1713 retval = aarch64_mmu_modify(target, 1);
1714 if (retval != ERROR_OK)
1715 return retval;
1716 }
1717 return aarch64_read_apb_ap_memory(target, address, size, count, buffer);
1718 }
1719
1720 static int aarch64_write_phys_memory(struct target *target,
1721 target_addr_t address, uint32_t size,
1722 uint32_t count, const uint8_t *buffer)
1723 {
1724 int retval = ERROR_COMMAND_SYNTAX_ERROR;
1725
1726 LOG_DEBUG("Writing memory to real address 0x%" TARGET_PRIxADDR "; size %" PRId32 "; count %" PRId32, address,
1727 size, count);
1728
1729 if (count && buffer) {
1730 /* write memory through APB-AP */
1731 retval = aarch64_mmu_modify(target, 0);
1732 if (retval != ERROR_OK)
1733 return retval;
1734 return aarch64_write_apb_ap_memory(target, address, size, count, buffer);
1735 }
1736
1737 return retval;
1738 }
1739
1740 static int aarch64_write_memory(struct target *target, target_addr_t address,
1741 uint32_t size, uint32_t count, const uint8_t *buffer)
1742 {
1743 int mmu_enabled = 0;
1744 int retval;
1745
1746 /* aarch64 handles unaligned memory access */
1747 LOG_DEBUG("Writing memory at address 0x%" TARGET_PRIxADDR "; size %" PRId32
1748 "; count %" PRId32, address, size, count);
1749
1750 /* determine if MMU was enabled on target stop */
1751 retval = aarch64_mmu(target, &mmu_enabled);
1752 if (retval != ERROR_OK)
1753 return retval;
1754
1755 if (mmu_enabled) {
1756 retval = aarch64_check_address(target, address);
1757 if (retval != ERROR_OK)
1758 return retval;
1759 /* enable MMU as we could have disabled it for phys access */
1760 retval = aarch64_mmu_modify(target, 1);
1761 if (retval != ERROR_OK)
1762 return retval;
1763 }
1764 return aarch64_write_apb_ap_memory(target, address, size, count, buffer);
1765 }
1766
1767 static int aarch64_handle_target_request(void *priv)
1768 {
1769 struct target *target = priv;
1770 struct armv8_common *armv8 = target_to_armv8(target);
1771 int retval;
1772
1773 if (!target_was_examined(target))
1774 return ERROR_OK;
1775 if (!target->dbg_msg_enabled)
1776 return ERROR_OK;
1777
1778 if (target->state == TARGET_RUNNING) {
1779 uint32_t request;
1780 uint32_t dscr;
1781 retval = mem_ap_read_atomic_u32(armv8->debug_ap,
1782 armv8->debug_base + CPUV8_DBG_DSCR, &dscr);
1783
1784 /* check if we have data */
1785 while ((dscr & DSCR_DTR_TX_FULL) && (retval == ERROR_OK)) {
1786 retval = mem_ap_read_atomic_u32(armv8->debug_ap,
1787 armv8->debug_base + CPUV8_DBG_DTRTX, &request);
1788 if (retval == ERROR_OK) {
1789 target_request(target, request);
1790 retval = mem_ap_read_atomic_u32(armv8->debug_ap,
1791 armv8->debug_base + CPUV8_DBG_DSCR, &dscr);
1792 }
1793 }
1794 }
1795
1796 return ERROR_OK;
1797 }
1798
1799 static int aarch64_examine_first(struct target *target)
1800 {
1801 struct aarch64_common *aarch64 = target_to_aarch64(target);
1802 struct armv8_common *armv8 = &aarch64->armv8_common;
1803 struct adiv5_dap *swjdp = armv8->arm.dap;
1804 int i;
1805 int retval = ERROR_OK;
1806 uint64_t debug, ttypr;
1807 uint32_t cpuid;
1808 uint32_t tmp0, tmp1;
1809 debug = ttypr = cpuid = 0;
1810
1811 /* We do one extra read to ensure DAP is configured,
1812 * we call ahbap_debugport_init(swjdp) instead
1813 */
1814 retval = dap_dp_init(swjdp);
1815 if (retval != ERROR_OK)
1816 return retval;
1817
1818 /* Search for the APB-AB - it is needed for access to debug registers */
1819 retval = dap_find_ap(swjdp, AP_TYPE_APB_AP, &armv8->debug_ap);
1820 if (retval != ERROR_OK) {
1821 LOG_ERROR("Could not find APB-AP for debug access");
1822 return retval;
1823 }
1824
1825 retval = mem_ap_init(armv8->debug_ap);
1826 if (retval != ERROR_OK) {
1827 LOG_ERROR("Could not initialize the APB-AP");
1828 return retval;
1829 }
1830
1831 armv8->debug_ap->memaccess_tck = 80;
1832
1833 if (!target->dbgbase_set) {
1834 uint32_t dbgbase;
1835 /* Get ROM Table base */
1836 uint32_t apid;
1837 int32_t coreidx = target->coreid;
1838 retval = dap_get_debugbase(armv8->debug_ap, &dbgbase, &apid);
1839 if (retval != ERROR_OK)
1840 return retval;
1841 /* Lookup 0x15 -- Processor DAP */
1842 retval = dap_lookup_cs_component(armv8->debug_ap, dbgbase, 0x15,
1843 &armv8->debug_base, &coreidx);
1844 if (retval != ERROR_OK)
1845 return retval;
1846 LOG_DEBUG("Detected core %" PRId32 " dbgbase: %08" PRIx32
1847 " apid: %08" PRIx32, coreidx, armv8->debug_base, apid);
1848 } else
1849 armv8->debug_base = target->dbgbase;
1850
1851 retval = mem_ap_write_atomic_u32(armv8->debug_ap,
1852 armv8->debug_base + CPUV8_DBG_LOCKACCESS, 0xC5ACCE55);
1853 if (retval != ERROR_OK) {
1854 LOG_DEBUG("LOCK debug access fail");
1855 return retval;
1856 }
1857
1858 retval = mem_ap_write_atomic_u32(armv8->debug_ap,
1859 armv8->debug_base + CPUV8_DBG_OSLAR, 0);
1860 if (retval != ERROR_OK) {
1861 LOG_DEBUG("Examine %s failed", "oslock");
1862 return retval;
1863 }
1864
1865 retval = mem_ap_read_atomic_u32(armv8->debug_ap,
1866 armv8->debug_base + CPUV8_DBG_MAINID0, &cpuid);
1867 if (retval != ERROR_OK) {
1868 LOG_DEBUG("Examine %s failed", "CPUID");
1869 return retval;
1870 }
1871
1872 retval = mem_ap_read_atomic_u32(armv8->debug_ap,
1873 armv8->debug_base + CPUV8_DBG_MEMFEATURE0, &tmp0);
1874 retval += mem_ap_read_atomic_u32(armv8->debug_ap,
1875 armv8->debug_base + CPUV8_DBG_MEMFEATURE0 + 4, &tmp1);
1876 if (retval != ERROR_OK) {
1877 LOG_DEBUG("Examine %s failed", "Memory Model Type");
1878 return retval;
1879 }
1880 ttypr |= tmp1;
1881 ttypr = (ttypr << 32) | tmp0;
1882
1883 retval = mem_ap_read_atomic_u32(armv8->debug_ap,
1884 armv8->debug_base + CPUV8_DBG_DBGFEATURE0, &tmp0);
1885 retval += mem_ap_read_atomic_u32(armv8->debug_ap,
1886 armv8->debug_base + CPUV8_DBG_DBGFEATURE0 + 4, &tmp1);
1887 if (retval != ERROR_OK) {
1888 LOG_DEBUG("Examine %s failed", "ID_AA64DFR0_EL1");
1889 return retval;
1890 }
1891 debug |= tmp1;
1892 debug = (debug << 32) | tmp0;
1893
1894 LOG_DEBUG("cpuid = 0x%08" PRIx32, cpuid);
1895 LOG_DEBUG("ttypr = 0x%08" PRIx64, ttypr);
1896 LOG_DEBUG("debug = 0x%08" PRIx64, debug);
1897
1898 if (target->ctibase == 0) {
1899 /* assume a v8 rom table layout */
1900 armv8->cti_base = target->ctibase = armv8->debug_base + 0x10000;
1901 LOG_INFO("Target ctibase is not set, assuming 0x%0" PRIx32, target->ctibase);
1902 } else
1903 armv8->cti_base = target->ctibase;
1904
1905 armv8->arm.core_type = ARM_MODE_MON;
1906 retval = aarch64_dpm_setup(aarch64, debug);
1907 if (retval != ERROR_OK)
1908 return retval;
1909
1910 /* Setup Breakpoint Register Pairs */
1911 aarch64->brp_num = (uint32_t)((debug >> 12) & 0x0F) + 1;
1912 aarch64->brp_num_context = (uint32_t)((debug >> 28) & 0x0F) + 1;
1913 aarch64->brp_num_available = aarch64->brp_num;
1914 aarch64->brp_list = calloc(aarch64->brp_num, sizeof(struct aarch64_brp));
1915 for (i = 0; i < aarch64->brp_num; i++) {
1916 aarch64->brp_list[i].used = 0;
1917 if (i < (aarch64->brp_num-aarch64->brp_num_context))
1918 aarch64->brp_list[i].type = BRP_NORMAL;
1919 else
1920 aarch64->brp_list[i].type = BRP_CONTEXT;
1921 aarch64->brp_list[i].value = 0;
1922 aarch64->brp_list[i].control = 0;
1923 aarch64->brp_list[i].BRPn = i;
1924 }
1925
1926 LOG_DEBUG("Configured %i hw breakpoints", aarch64->brp_num);
1927
1928 target_set_examined(target);
1929 return ERROR_OK;
1930 }
1931
1932 static int aarch64_examine(struct target *target)
1933 {
1934 int retval = ERROR_OK;
1935
1936 /* don't re-probe hardware after each reset */
1937 if (!target_was_examined(target))
1938 retval = aarch64_examine_first(target);
1939
1940 /* Configure core debug access */
1941 if (retval == ERROR_OK)
1942 retval = aarch64_init_debug_access(target);
1943
1944 return retval;
1945 }
1946
1947 /*
1948 * Cortex-A8 target creation and initialization
1949 */
1950
1951 static int aarch64_init_target(struct command_context *cmd_ctx,
1952 struct target *target)
1953 {
1954 /* examine_first() does a bunch of this */
1955 return ERROR_OK;
1956 }
1957
1958 static int aarch64_init_arch_info(struct target *target,
1959 struct aarch64_common *aarch64, struct jtag_tap *tap)
1960 {
1961 struct armv8_common *armv8 = &aarch64->armv8_common;
1962 struct adiv5_dap *dap = armv8->arm.dap;
1963
1964 armv8->arm.dap = dap;
1965
1966 /* Setup struct aarch64_common */
1967 aarch64->common_magic = AARCH64_COMMON_MAGIC;
1968 /* tap has no dap initialized */
1969 if (!tap->dap) {
1970 tap->dap = dap_init();
1971
1972 /* Leave (only) generic DAP stuff for debugport_init() */
1973 tap->dap->tap = tap;
1974 }
1975
1976 armv8->arm.dap = tap->dap;
1977
1978 aarch64->fast_reg_read = 0;
1979
1980 /* register arch-specific functions */
1981 armv8->examine_debug_reason = NULL;
1982
1983 armv8->post_debug_entry = aarch64_post_debug_entry;
1984
1985 armv8->pre_restore_context = NULL;
1986
1987 armv8->armv8_mmu.read_physical_memory = aarch64_read_phys_memory;
1988
1989 /* REVISIT v7a setup should be in a v7a-specific routine */
1990 armv8_init_arch_info(target, armv8);
1991 target_register_timer_callback(aarch64_handle_target_request, 1, 1, target);
1992
1993 return ERROR_OK;
1994 }
1995
1996 static int aarch64_target_create(struct target *target, Jim_Interp *interp)
1997 {
1998 struct aarch64_common *aarch64 = calloc(1, sizeof(struct aarch64_common));
1999
2000 return aarch64_init_arch_info(target, aarch64, target->tap);
2001 }
2002
2003 static int aarch64_mmu(struct target *target, int *enabled)
2004 {
2005 if (target->state != TARGET_HALTED) {
2006 LOG_ERROR("%s: target not halted", __func__);
2007 return ERROR_TARGET_INVALID;
2008 }
2009
2010 *enabled = target_to_aarch64(target)->armv8_common.armv8_mmu.mmu_enabled;
2011 return ERROR_OK;
2012 }
2013
2014 static int aarch64_virt2phys(struct target *target, target_addr_t virt,
2015 target_addr_t *phys)
2016 {
2017 return armv8_mmu_translate_va(target, virt, phys);
2018 }
2019
2020 COMMAND_HANDLER(aarch64_handle_cache_info_command)
2021 {
2022 struct target *target = get_current_target(CMD_CTX);
2023 struct armv8_common *armv8 = target_to_armv8(target);
2024
2025 return armv8_handle_cache_info_command(CMD_CTX,
2026 &armv8->armv8_mmu.armv8_cache);
2027 }
2028
2029
2030 COMMAND_HANDLER(aarch64_handle_dbginit_command)
2031 {
2032 struct target *target = get_current_target(CMD_CTX);
2033 if (!target_was_examined(target)) {
2034 LOG_ERROR("target not examined yet");
2035 return ERROR_FAIL;
2036 }
2037
2038 return aarch64_init_debug_access(target);
2039 }
2040 COMMAND_HANDLER(aarch64_handle_smp_off_command)
2041 {
2042 struct target *target = get_current_target(CMD_CTX);
2043 /* check target is an smp target */
2044 struct target_list *head;
2045 struct target *curr;
2046 head = target->head;
2047 target->smp = 0;
2048 if (head != (struct target_list *)NULL) {
2049 while (head != (struct target_list *)NULL) {
2050 curr = head->target;
2051 curr->smp = 0;
2052 head = head->next;
2053 }
2054 /* fixes the target display to the debugger */
2055 target->gdb_service->target = target;
2056 }
2057 return ERROR_OK;
2058 }
2059
2060 COMMAND_HANDLER(aarch64_handle_smp_on_command)
2061 {
2062 struct target *target = get_current_target(CMD_CTX);
2063 struct target_list *head;
2064 struct target *curr;
2065 head = target->head;
2066 if (head != (struct target_list *)NULL) {
2067 target->smp = 1;
2068 while (head != (struct target_list *)NULL) {
2069 curr = head->target;
2070 curr->smp = 1;
2071 head = head->next;
2072 }
2073 }
2074 return ERROR_OK;
2075 }
2076
2077 COMMAND_HANDLER(aarch64_handle_smp_gdb_command)
2078 {
2079 struct target *target = get_current_target(CMD_CTX);
2080 int retval = ERROR_OK;
2081 struct target_list *head;
2082 head = target->head;
2083 if (head != (struct target_list *)NULL) {
2084 if (CMD_ARGC == 1) {
2085 int coreid = 0;
2086 COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], coreid);
2087 if (ERROR_OK != retval)
2088 return retval;
2089 target->gdb_service->core[1] = coreid;
2090
2091 }
2092 command_print(CMD_CTX, "gdb coreid %" PRId32 " -> %" PRId32, target->gdb_service->core[0]
2093 , target->gdb_service->core[1]);
2094 }
2095 return ERROR_OK;
2096 }
2097
2098 static const struct command_registration aarch64_exec_command_handlers[] = {
2099 {
2100 .name = "cache_info",
2101 .handler = aarch64_handle_cache_info_command,
2102 .mode = COMMAND_EXEC,
2103 .help = "display information about target caches",
2104 .usage = "",
2105 },
2106 {
2107 .name = "dbginit",
2108 .handler = aarch64_handle_dbginit_command,
2109 .mode = COMMAND_EXEC,
2110 .help = "Initialize core debug",
2111 .usage = "",
2112 },
2113 { .name = "smp_off",
2114 .handler = aarch64_handle_smp_off_command,
2115 .mode = COMMAND_EXEC,
2116 .help = "Stop smp handling",
2117 .usage = "",
2118 },
2119 {
2120 .name = "smp_on",
2121 .handler = aarch64_handle_smp_on_command,
2122 .mode = COMMAND_EXEC,
2123 .help = "Restart smp handling",
2124 .usage = "",
2125 },
2126 {
2127 .name = "smp_gdb",
2128 .handler = aarch64_handle_smp_gdb_command,
2129 .mode = COMMAND_EXEC,
2130 .help = "display/fix current core played to gdb",
2131 .usage = "",
2132 },
2133
2134
2135 COMMAND_REGISTRATION_DONE
2136 };
2137 static const struct command_registration aarch64_command_handlers[] = {
2138 {
2139 .chain = arm_command_handlers,
2140 },
2141 {
2142 .chain = armv8_command_handlers,
2143 },
2144 {
2145 .name = "cortex_a",
2146 .mode = COMMAND_ANY,
2147 .help = "Cortex-A command group",
2148 .usage = "",
2149 .chain = aarch64_exec_command_handlers,
2150 },
2151 COMMAND_REGISTRATION_DONE
2152 };
2153
2154 struct target_type aarch64_target = {
2155 .name = "aarch64",
2156
2157 .poll = aarch64_poll,
2158 .arch_state = armv8_arch_state,
2159
2160 .halt = aarch64_halt,
2161 .resume = aarch64_resume,
2162 .step = aarch64_step,
2163
2164 .assert_reset = aarch64_assert_reset,
2165 .deassert_reset = aarch64_deassert_reset,
2166
2167 /* REVISIT allow exporting VFP3 registers ... */
2168 .get_gdb_reg_list = armv8_get_gdb_reg_list,
2169
2170 .read_memory = aarch64_read_memory,
2171 .write_memory = aarch64_write_memory,
2172
2173 .checksum_memory = arm_checksum_memory,
2174 .blank_check_memory = arm_blank_check_memory,
2175
2176 .run_algorithm = armv4_5_run_algorithm,
2177
2178 .add_breakpoint = aarch64_add_breakpoint,
2179 .add_context_breakpoint = aarch64_add_context_breakpoint,
2180 .add_hybrid_breakpoint = aarch64_add_hybrid_breakpoint,
2181 .remove_breakpoint = aarch64_remove_breakpoint,
2182 .add_watchpoint = NULL,
2183 .remove_watchpoint = NULL,
2184
2185 .commands = aarch64_command_handlers,
2186 .target_create = aarch64_target_create,
2187 .init_target = aarch64_init_target,
2188 .examine = aarch64_examine,
2189
2190 .read_phys_memory = aarch64_read_phys_memory,
2191 .write_phys_memory = aarch64_write_phys_memory,
2192 .mmu = aarch64_mmu,
2193 .virt2phys = aarch64_virt2phys,
2194 };

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)