armv7a_mmu: s/LOG_ERROR/LOG_WARNING/ on address translation failure
[openocd.git] / src / target / armv8_dpm.c
1 /*
2 * Copyright (C) 2009 by David Brownell
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 */
15
16 #ifdef HAVE_CONFIG_H
17 #include "config.h"
18 #endif
19
20 #include "arm.h"
21 #include "armv8.h"
22 #include "armv8_dpm.h"
23 #include <jtag/jtag.h>
24 #include "register.h"
25 #include "breakpoints.h"
26 #include "target_type.h"
27 #include "armv8_opcodes.h"
28
29 #include "helper/time_support.h"
30
31 /* T32 ITR format */
32 #define T32_FMTITR(instr) (((instr & 0x0000FFFF) << 16) | ((instr & 0xFFFF0000) >> 16))
33
34 /**
35 * @file
36 * Implements various ARM DPM operations using architectural debug registers.
37 * These routines layer over core-specific communication methods to cope with
38 * implementation differences between cores like ARM1136 and Cortex-A8.
39 *
40 * The "Debug Programmers' Model" (DPM) for ARMv6 and ARMv7 is defined by
41 * Part C (Debug Architecture) of the ARM Architecture Reference Manual,
42 * ARMv7-A and ARMv7-R edition (ARM DDI 0406B). In OpenOCD, DPM operations
43 * are abstracted through internal programming interfaces to share code and
44 * to minimize needless differences in debug behavior between cores.
45 */
46
47 /**
48 * Get core state from EDSCR, without necessity to retrieve CPSR
49 */
50 enum arm_state armv8_dpm_get_core_state(struct arm_dpm *dpm)
51 {
52 int el = (dpm->dscr >> 8) & 0x3;
53 int rw = (dpm->dscr >> 10) & 0xF;
54
55 dpm->last_el = el;
56
57 /* In Debug state, each bit gives the current Execution state of each EL */
58 if ((rw >> el) & 0b1)
59 return ARM_STATE_AARCH64;
60
61 return ARM_STATE_ARM;
62 }
63
64 /*----------------------------------------------------------------------*/
65
66 static int dpmv8_write_dcc(struct armv8_common *armv8, uint32_t data)
67 {
68 return mem_ap_write_u32(armv8->debug_ap,
69 armv8->debug_base + CPUV8_DBG_DTRRX, data);
70 }
71
72 static int dpmv8_write_dcc_64(struct armv8_common *armv8, uint64_t data)
73 {
74 int ret;
75 ret = mem_ap_write_u32(armv8->debug_ap,
76 armv8->debug_base + CPUV8_DBG_DTRRX, data);
77 if (ret == ERROR_OK)
78 ret = mem_ap_write_u32(armv8->debug_ap,
79 armv8->debug_base + CPUV8_DBG_DTRTX, data >> 32);
80 return ret;
81 }
82
83 static int dpmv8_read_dcc(struct armv8_common *armv8, uint32_t *data,
84 uint32_t *dscr_p)
85 {
86 uint32_t dscr = DSCR_ITE;
87 int retval;
88
89 if (dscr_p)
90 dscr = *dscr_p;
91
92 /* Wait for DTRRXfull */
93 long long then = timeval_ms();
94 while ((dscr & DSCR_DTR_TX_FULL) == 0) {
95 retval = mem_ap_read_atomic_u32(armv8->debug_ap,
96 armv8->debug_base + CPUV8_DBG_DSCR,
97 &dscr);
98 if (retval != ERROR_OK)
99 return retval;
100 if (timeval_ms() > then + 1000) {
101 LOG_ERROR("Timeout waiting for read dcc");
102 return ERROR_FAIL;
103 }
104 }
105
106 retval = mem_ap_read_atomic_u32(armv8->debug_ap,
107 armv8->debug_base + CPUV8_DBG_DTRTX,
108 data);
109 if (retval != ERROR_OK)
110 return retval;
111
112 if (dscr_p)
113 *dscr_p = dscr;
114
115 return retval;
116 }
117
118 static int dpmv8_read_dcc_64(struct armv8_common *armv8, uint64_t *data,
119 uint32_t *dscr_p)
120 {
121 uint32_t dscr = DSCR_ITE;
122 uint32_t higher;
123 int retval;
124
125 if (dscr_p)
126 dscr = *dscr_p;
127
128 /* Wait for DTRRXfull */
129 long long then = timeval_ms();
130 while ((dscr & DSCR_DTR_TX_FULL) == 0) {
131 retval = mem_ap_read_atomic_u32(armv8->debug_ap,
132 armv8->debug_base + CPUV8_DBG_DSCR,
133 &dscr);
134 if (retval != ERROR_OK)
135 return retval;
136 if (timeval_ms() > then + 1000) {
137 LOG_ERROR("Timeout waiting for DTR_TX_FULL, dscr = 0x%08" PRIx32, dscr);
138 return ERROR_FAIL;
139 }
140 }
141
142 retval = mem_ap_read_atomic_u32(armv8->debug_ap,
143 armv8->debug_base + CPUV8_DBG_DTRTX,
144 (uint32_t *)data);
145 if (retval != ERROR_OK)
146 return retval;
147
148 retval = mem_ap_read_atomic_u32(armv8->debug_ap,
149 armv8->debug_base + CPUV8_DBG_DTRRX,
150 &higher);
151 if (retval != ERROR_OK)
152 return retval;
153
154 *data = *(uint32_t *)data | (uint64_t)higher << 32;
155
156 if (dscr_p)
157 *dscr_p = dscr;
158
159 return retval;
160 }
161
162 static int dpmv8_dpm_prepare(struct arm_dpm *dpm)
163 {
164 struct armv8_common *armv8 = dpm->arm->arch_info;
165 uint32_t dscr;
166 int retval;
167
168 /* set up invariant: ITE is set after ever DPM operation */
169 long long then = timeval_ms();
170 for (;; ) {
171 retval = mem_ap_read_atomic_u32(armv8->debug_ap,
172 armv8->debug_base + CPUV8_DBG_DSCR,
173 &dscr);
174 if (retval != ERROR_OK)
175 return retval;
176 if ((dscr & DSCR_ITE) != 0)
177 break;
178 if (timeval_ms() > then + 1000) {
179 LOG_ERROR("Timeout waiting for dpm prepare");
180 return ERROR_FAIL;
181 }
182 }
183
184 /* update the stored copy of dscr */
185 dpm->dscr = dscr;
186
187 /* this "should never happen" ... */
188 if (dscr & DSCR_DTR_RX_FULL) {
189 LOG_ERROR("DSCR_DTR_RX_FULL, dscr 0x%08" PRIx32, dscr);
190 /* Clear DCCRX */
191 retval = mem_ap_read_u32(armv8->debug_ap,
192 armv8->debug_base + CPUV8_DBG_DTRRX, &dscr);
193 if (retval != ERROR_OK)
194 return retval;
195 }
196
197 return retval;
198 }
199
200 static int dpmv8_dpm_finish(struct arm_dpm *dpm)
201 {
202 /* REVISIT what could be done here? */
203 return ERROR_OK;
204 }
205
206 static int dpmv8_exec_opcode(struct arm_dpm *dpm,
207 uint32_t opcode, uint32_t *p_dscr)
208 {
209 struct armv8_common *armv8 = dpm->arm->arch_info;
210 uint32_t dscr = dpm->dscr;
211 int retval;
212
213 if (p_dscr)
214 dscr = *p_dscr;
215
216 /* Wait for InstrCompl bit to be set */
217 long long then = timeval_ms();
218 while ((dscr & DSCR_ITE) == 0) {
219 retval = mem_ap_read_atomic_u32(armv8->debug_ap,
220 armv8->debug_base + CPUV8_DBG_DSCR, &dscr);
221 if (retval != ERROR_OK) {
222 LOG_ERROR("Could not read DSCR register, opcode = 0x%08" PRIx32, opcode);
223 return retval;
224 }
225 if (timeval_ms() > then + 1000) {
226 LOG_ERROR("Timeout waiting for aarch64_exec_opcode");
227 return ERROR_FAIL;
228 }
229 }
230
231 if (armv8_dpm_get_core_state(dpm) != ARM_STATE_AARCH64)
232 opcode = T32_FMTITR(opcode);
233
234 retval = mem_ap_write_u32(armv8->debug_ap,
235 armv8->debug_base + CPUV8_DBG_ITR, opcode);
236 if (retval != ERROR_OK)
237 return retval;
238
239 then = timeval_ms();
240 do {
241 retval = mem_ap_read_atomic_u32(armv8->debug_ap,
242 armv8->debug_base + CPUV8_DBG_DSCR, &dscr);
243 if (retval != ERROR_OK) {
244 LOG_ERROR("Could not read DSCR register");
245 return retval;
246 }
247 if (timeval_ms() > then + 1000) {
248 LOG_ERROR("Timeout waiting for aarch64_exec_opcode");
249 return ERROR_FAIL;
250 }
251 } while ((dscr & DSCR_ITE) == 0); /* Wait for InstrCompl bit to be set */
252
253 /* update dscr and el after each command execution */
254 dpm->dscr = dscr;
255 if (dpm->last_el != ((dscr >> 8) & 3))
256 LOG_DEBUG("EL %i -> %i", dpm->last_el, (dscr >> 8) & 3);
257 dpm->last_el = (dscr >> 8) & 3;
258
259 if (dscr & DSCR_ERR) {
260 LOG_ERROR("Opcode 0x%08"PRIx32", DSCR.ERR=1, DSCR.EL=%i", opcode, dpm->last_el);
261 armv8_dpm_handle_exception(dpm, true);
262 retval = ERROR_FAIL;
263 }
264
265 if (p_dscr)
266 *p_dscr = dscr;
267
268 return retval;
269 }
270
271 static int dpmv8_instr_execute(struct arm_dpm *dpm, uint32_t opcode)
272 {
273 return dpmv8_exec_opcode(dpm, opcode, NULL);
274 }
275
276 static int dpmv8_instr_write_data_dcc(struct arm_dpm *dpm,
277 uint32_t opcode, uint32_t data)
278 {
279 struct armv8_common *armv8 = dpm->arm->arch_info;
280 int retval;
281
282 retval = dpmv8_write_dcc(armv8, data);
283 if (retval != ERROR_OK)
284 return retval;
285
286 return dpmv8_exec_opcode(dpm, opcode, 0);
287 }
288
289 static int dpmv8_instr_write_data_dcc_64(struct arm_dpm *dpm,
290 uint32_t opcode, uint64_t data)
291 {
292 struct armv8_common *armv8 = dpm->arm->arch_info;
293 int retval;
294
295 retval = dpmv8_write_dcc_64(armv8, data);
296 if (retval != ERROR_OK)
297 return retval;
298
299 return dpmv8_exec_opcode(dpm, opcode, 0);
300 }
301
302 static int dpmv8_instr_write_data_r0(struct arm_dpm *dpm,
303 uint32_t opcode, uint32_t data)
304 {
305 struct armv8_common *armv8 = dpm->arm->arch_info;
306 uint32_t dscr = DSCR_ITE;
307 int retval;
308
309 retval = dpmv8_write_dcc(armv8, data);
310 if (retval != ERROR_OK)
311 return retval;
312
313 retval = dpmv8_exec_opcode(dpm, armv8_opcode(armv8, READ_REG_DTRRX), &dscr);
314 if (retval != ERROR_OK)
315 return retval;
316
317 /* then the opcode, taking data from R0 */
318 return dpmv8_exec_opcode(dpm, opcode, &dscr);
319 }
320
321 static int dpmv8_instr_write_data_r0_64(struct arm_dpm *dpm,
322 uint32_t opcode, uint64_t data)
323 {
324 struct armv8_common *armv8 = dpm->arm->arch_info;
325 int retval;
326
327 if (dpm->arm->core_state != ARM_STATE_AARCH64)
328 return dpmv8_instr_write_data_r0(dpm, opcode, data);
329
330 /* transfer data from DCC to R0 */
331 retval = dpmv8_write_dcc_64(armv8, data);
332 if (retval == ERROR_OK)
333 retval = dpmv8_exec_opcode(dpm, ARMV8_MRS(SYSTEM_DBG_DBGDTR_EL0, 0), &dpm->dscr);
334
335 /* then the opcode, taking data from R0 */
336 if (retval == ERROR_OK)
337 retval = dpmv8_exec_opcode(dpm, opcode, &dpm->dscr);
338
339 return retval;
340 }
341
342 static int dpmv8_instr_cpsr_sync(struct arm_dpm *dpm)
343 {
344 int retval;
345 struct armv8_common *armv8 = dpm->arm->arch_info;
346
347 /* "Prefetch flush" after modifying execution status in CPSR */
348 retval = dpmv8_exec_opcode(dpm, armv8_opcode(armv8, ARMV8_OPC_DSB_SY), &dpm->dscr);
349 if (retval == ERROR_OK)
350 dpmv8_exec_opcode(dpm, armv8_opcode(armv8, ARMV8_OPC_ISB_SY), &dpm->dscr);
351 return retval;
352 }
353
354 static int dpmv8_instr_read_data_dcc(struct arm_dpm *dpm,
355 uint32_t opcode, uint32_t *data)
356 {
357 struct armv8_common *armv8 = dpm->arm->arch_info;
358 int retval;
359
360 /* the opcode, writing data to DCC */
361 retval = dpmv8_exec_opcode(dpm, opcode, &dpm->dscr);
362 if (retval != ERROR_OK)
363 return retval;
364
365 return dpmv8_read_dcc(armv8, data, &dpm->dscr);
366 }
367
368 static int dpmv8_instr_read_data_dcc_64(struct arm_dpm *dpm,
369 uint32_t opcode, uint64_t *data)
370 {
371 struct armv8_common *armv8 = dpm->arm->arch_info;
372 int retval;
373
374 /* the opcode, writing data to DCC */
375 retval = dpmv8_exec_opcode(dpm, opcode, &dpm->dscr);
376 if (retval != ERROR_OK)
377 return retval;
378
379 return dpmv8_read_dcc_64(armv8, data, &dpm->dscr);
380 }
381
382 static int dpmv8_instr_read_data_r0(struct arm_dpm *dpm,
383 uint32_t opcode, uint32_t *data)
384 {
385 struct armv8_common *armv8 = dpm->arm->arch_info;
386 int retval;
387
388 /* the opcode, writing data to R0 */
389 retval = dpmv8_exec_opcode(dpm, opcode, &dpm->dscr);
390 if (retval != ERROR_OK)
391 return retval;
392
393 /* write R0 to DCC */
394 retval = dpmv8_exec_opcode(dpm, armv8_opcode(armv8, WRITE_REG_DTRTX), &dpm->dscr);
395 if (retval != ERROR_OK)
396 return retval;
397
398 return dpmv8_read_dcc(armv8, data, &dpm->dscr);
399 }
400
401 static int dpmv8_instr_read_data_r0_64(struct arm_dpm *dpm,
402 uint32_t opcode, uint64_t *data)
403 {
404 struct armv8_common *armv8 = dpm->arm->arch_info;
405 int retval;
406
407 if (dpm->arm->core_state != ARM_STATE_AARCH64) {
408 uint32_t tmp;
409 retval = dpmv8_instr_read_data_r0(dpm, opcode, &tmp);
410 if (retval == ERROR_OK)
411 *data = tmp;
412 return retval;
413 }
414
415 /* the opcode, writing data to R0 */
416 retval = dpmv8_exec_opcode(dpm, opcode, &dpm->dscr);
417 if (retval != ERROR_OK)
418 return retval;
419
420 /* write R0 to DCC */
421 retval = dpmv8_exec_opcode(dpm, ARMV8_MSR_GP(SYSTEM_DBG_DBGDTR_EL0, 0), &dpm->dscr);
422 if (retval != ERROR_OK)
423 return retval;
424
425 return dpmv8_read_dcc_64(armv8, data, &dpm->dscr);
426 }
427
428 #if 0
429 static int dpmv8_bpwp_enable(struct arm_dpm *dpm, unsigned index_t,
430 target_addr_t addr, uint32_t control)
431 {
432 struct armv8_common *armv8 = dpm->arm->arch_info;
433 uint32_t vr = armv8->debug_base;
434 uint32_t cr = armv8->debug_base;
435 int retval;
436
437 switch (index_t) {
438 case 0 ... 15: /* breakpoints */
439 vr += CPUV8_DBG_BVR_BASE;
440 cr += CPUV8_DBG_BCR_BASE;
441 break;
442 case 16 ... 31: /* watchpoints */
443 vr += CPUV8_DBG_WVR_BASE;
444 cr += CPUV8_DBG_WCR_BASE;
445 index_t -= 16;
446 break;
447 default:
448 return ERROR_FAIL;
449 }
450 vr += 16 * index_t;
451 cr += 16 * index_t;
452
453 LOG_DEBUG("A8: bpwp enable, vr %08x cr %08x",
454 (unsigned) vr, (unsigned) cr);
455
456 retval = mem_ap_write_atomic_u32(armv8->debug_ap, vr, addr);
457 if (retval != ERROR_OK)
458 return retval;
459 return mem_ap_write_atomic_u32(armv8->debug_ap, cr, control);
460 }
461 #endif
462
463 static int dpmv8_bpwp_disable(struct arm_dpm *dpm, unsigned index_t)
464 {
465 struct armv8_common *armv8 = dpm->arm->arch_info;
466 uint32_t cr;
467
468 switch (index_t) {
469 case 0 ... 15:
470 cr = armv8->debug_base + CPUV8_DBG_BCR_BASE;
471 break;
472 case 16 ... 31:
473 cr = armv8->debug_base + CPUV8_DBG_WCR_BASE;
474 index_t -= 16;
475 break;
476 default:
477 return ERROR_FAIL;
478 }
479 cr += 16 * index_t;
480
481 LOG_DEBUG("A: bpwp disable, cr %08x", (unsigned) cr);
482
483 /* clear control register */
484 return mem_ap_write_atomic_u32(armv8->debug_ap, cr, 0);
485 }
486
487 /*
488 * Coprocessor support
489 */
490
491 /* Read coprocessor */
492 static int dpmv8_mrc(struct target *target, int cpnum,
493 uint32_t op1, uint32_t op2, uint32_t CRn, uint32_t CRm,
494 uint32_t *value)
495 {
496 struct arm *arm = target_to_arm(target);
497 struct arm_dpm *dpm = arm->dpm;
498 int retval;
499
500 retval = dpm->prepare(dpm);
501 if (retval != ERROR_OK)
502 return retval;
503
504 LOG_DEBUG("MRC p%d, %d, r0, c%d, c%d, %d", cpnum,
505 (int) op1, (int) CRn,
506 (int) CRm, (int) op2);
507
508 /* read coprocessor register into R0; return via DCC */
509 retval = dpm->instr_read_data_r0(dpm,
510 ARMV4_5_MRC(cpnum, op1, 0, CRn, CRm, op2),
511 value);
512
513 /* (void) */ dpm->finish(dpm);
514 return retval;
515 }
516
517 static int dpmv8_mcr(struct target *target, int cpnum,
518 uint32_t op1, uint32_t op2, uint32_t CRn, uint32_t CRm,
519 uint32_t value)
520 {
521 struct arm *arm = target_to_arm(target);
522 struct arm_dpm *dpm = arm->dpm;
523 int retval;
524
525 retval = dpm->prepare(dpm);
526 if (retval != ERROR_OK)
527 return retval;
528
529 LOG_DEBUG("MCR p%d, %d, r0, c%d, c%d, %d", cpnum,
530 (int) op1, (int) CRn,
531 (int) CRm, (int) op2);
532
533 /* read DCC into r0; then write coprocessor register from R0 */
534 retval = dpm->instr_write_data_r0(dpm,
535 ARMV4_5_MCR(cpnum, op1, 0, CRn, CRm, op2),
536 value);
537
538 /* (void) */ dpm->finish(dpm);
539 return retval;
540 }
541
542 /*----------------------------------------------------------------------*/
543
544 /*
545 * Register access utilities
546 */
547
548 int armv8_dpm_modeswitch(struct arm_dpm *dpm, enum arm_mode mode)
549 {
550 struct armv8_common *armv8 = (struct armv8_common *)dpm->arm->arch_info;
551 int retval = ERROR_OK;
552 unsigned int target_el;
553 enum arm_state core_state;
554 uint32_t cpsr;
555
556 /* restore previous mode */
557 if (mode == ARM_MODE_ANY) {
558 cpsr = buf_get_u32(dpm->arm->cpsr->value, 0, 32);
559
560 LOG_DEBUG("restoring mode, cpsr = 0x%08"PRIx32, cpsr);
561
562 } else {
563 LOG_DEBUG("setting mode 0x%"PRIx32, mode);
564 cpsr = mode;
565 }
566
567 switch (cpsr & 0x1f) {
568 /* aarch32 modes */
569 case ARM_MODE_USR:
570 target_el = 0;
571 break;
572 case ARM_MODE_SVC:
573 case ARM_MODE_ABT:
574 case ARM_MODE_IRQ:
575 case ARM_MODE_FIQ:
576 target_el = 1;
577 break;
578 /*
579 * TODO: handle ARM_MODE_HYP
580 * case ARM_MODE_HYP:
581 * target_el = 2;
582 * break;
583 */
584 case ARM_MODE_MON:
585 target_el = 3;
586 break;
587 /* aarch64 modes */
588 default:
589 target_el = (cpsr >> 2) & 3;
590 }
591
592 if (target_el > SYSTEM_CUREL_EL3) {
593 LOG_ERROR("%s: Invalid target exception level %i", __func__, target_el);
594 return ERROR_FAIL;
595 }
596
597 LOG_DEBUG("target_el = %i, last_el = %i", target_el, dpm->last_el);
598 if (target_el > dpm->last_el) {
599 retval = dpm->instr_execute(dpm,
600 armv8_opcode(armv8, ARMV8_OPC_DCPS) | target_el);
601
602 /* DCPS clobbers registers just like an exception taken */
603 armv8_dpm_handle_exception(dpm, false);
604 } else {
605 core_state = armv8_dpm_get_core_state(dpm);
606 if (core_state != ARM_STATE_AARCH64) {
607 /* cannot do DRPS/ERET when already in EL0 */
608 if (dpm->last_el != 0) {
609 /* load SPSR with the desired mode and execute DRPS */
610 LOG_DEBUG("SPSR = 0x%08"PRIx32, cpsr);
611 retval = dpm->instr_write_data_r0(dpm,
612 ARMV8_MSR_GP_xPSR_T1(1, 0, 15), cpsr);
613 if (retval == ERROR_OK)
614 retval = dpm->instr_execute(dpm, armv8_opcode(armv8, ARMV8_OPC_DRPS));
615 }
616 } else {
617 /*
618 * need to execute multiple DRPS instructions until target_el
619 * is reached
620 */
621 while (retval == ERROR_OK && dpm->last_el != target_el) {
622 unsigned int cur_el = dpm->last_el;
623 retval = dpm->instr_execute(dpm, armv8_opcode(armv8, ARMV8_OPC_DRPS));
624 if (cur_el == dpm->last_el) {
625 LOG_INFO("Cannot reach EL %i, SPSR corrupted?", target_el);
626 break;
627 }
628 }
629 }
630
631 /* On executing DRPS, DSPSR and DLR become UNKNOWN, mark them as dirty */
632 dpm->arm->cpsr->dirty = true;
633 dpm->arm->pc->dirty = true;
634
635 /*
636 * re-evaluate the core state, we might be in Aarch32 state now
637 * we rely on dpm->dscr being up-to-date
638 */
639 core_state = armv8_dpm_get_core_state(dpm);
640 armv8_select_opcodes(armv8, core_state == ARM_STATE_AARCH64);
641 armv8_select_reg_access(armv8, core_state == ARM_STATE_AARCH64);
642 }
643
644 return retval;
645 }
646
647 /*
648 * Common register read, relies on armv8_select_reg_access() having been called.
649 */
650 static int dpmv8_read_reg(struct arm_dpm *dpm, struct reg *r, unsigned regnum)
651 {
652 struct armv8_common *armv8 = dpm->arm->arch_info;
653 int retval = ERROR_FAIL;
654
655 if (r->size <= 64) {
656 uint64_t value_64;
657 retval = armv8->read_reg_u64(armv8, regnum, &value_64);
658
659 if (retval == ERROR_OK) {
660 r->valid = true;
661 r->dirty = false;
662 buf_set_u64(r->value, 0, r->size, value_64);
663 if (r->size == 64)
664 LOG_DEBUG("READ: %s, %16.8llx", r->name, (unsigned long long) value_64);
665 else
666 LOG_DEBUG("READ: %s, %8.8x", r->name, (unsigned int) value_64);
667 }
668 } else if (r->size <= 128) {
669 uint64_t lvalue = 0, hvalue = 0;
670 retval = armv8->read_reg_u128(armv8, regnum, &lvalue, &hvalue);
671
672 if (retval == ERROR_OK) {
673 r->valid = true;
674 r->dirty = false;
675
676 buf_set_u64(r->value, 0, 64, lvalue);
677 buf_set_u64(r->value + 8, 0, r->size - 64, hvalue);
678
679 LOG_DEBUG("READ: %s, lvalue=%16.8llx", r->name, (unsigned long long) lvalue);
680 LOG_DEBUG("READ: %s, hvalue=%16.8llx", r->name, (unsigned long long) hvalue);
681 }
682 }
683 return retval;
684 }
685
686 /*
687 * Common register write, relies on armv8_select_reg_access() having been called.
688 */
689 static int dpmv8_write_reg(struct arm_dpm *dpm, struct reg *r, unsigned regnum)
690 {
691 struct armv8_common *armv8 = dpm->arm->arch_info;
692 int retval = ERROR_FAIL;
693
694 if (r->size <= 64) {
695 uint64_t value_64;
696
697 value_64 = buf_get_u64(r->value, 0, r->size);
698 retval = armv8->write_reg_u64(armv8, regnum, value_64);
699
700 if (retval == ERROR_OK) {
701 r->dirty = false;
702 if (r->size == 64)
703 LOG_DEBUG("WRITE: %s, %16.8llx", r->name, (unsigned long long)value_64);
704 else
705 LOG_DEBUG("WRITE: %s, %8.8x", r->name, (unsigned int)value_64);
706 }
707 } else if (r->size <= 128) {
708 uint64_t lvalue, hvalue;
709
710 lvalue = buf_get_u64(r->value, 0, 64);
711 hvalue = buf_get_u64(r->value + 8, 0, r->size - 64);
712 retval = armv8->write_reg_u128(armv8, regnum, lvalue, hvalue);
713
714 if (retval == ERROR_OK) {
715 r->dirty = false;
716
717 LOG_DEBUG("WRITE: %s, lvalue=%16.8llx", r->name, (unsigned long long) lvalue);
718 LOG_DEBUG("WRITE: %s, hvalue=%16.8llx", r->name, (unsigned long long) hvalue);
719 }
720 }
721
722 return retval;
723 }
724
725 /**
726 * Read basic registers of the the current context: R0 to R15, and CPSR;
727 * sets the core mode (such as USR or IRQ) and state (such as ARM or Thumb).
728 * In normal operation this is called on entry to halting debug state,
729 * possibly after some other operations supporting restore of debug state
730 * or making sure the CPU is fully idle (drain write buffer, etc).
731 */
732 int armv8_dpm_read_current_registers(struct arm_dpm *dpm)
733 {
734 struct arm *arm = dpm->arm;
735 struct armv8_common *armv8 = (struct armv8_common *)arm->arch_info;
736 struct reg_cache *cache;
737 struct reg *r;
738 uint32_t cpsr;
739 int retval;
740
741 retval = dpm->prepare(dpm);
742 if (retval != ERROR_OK)
743 return retval;
744
745 cache = arm->core_cache;
746
747 /* read R0 first (it's used for scratch), then CPSR */
748 r = cache->reg_list + ARMV8_R0;
749 if (!r->valid) {
750 retval = dpmv8_read_reg(dpm, r, ARMV8_R0);
751 if (retval != ERROR_OK)
752 goto fail;
753 }
754 r->dirty = true;
755
756 /* read R1, too, it will be clobbered during memory access */
757 r = cache->reg_list + ARMV8_R1;
758 if (!r->valid) {
759 retval = dpmv8_read_reg(dpm, r, ARMV8_R1);
760 if (retval != ERROR_OK)
761 goto fail;
762 }
763
764 /* read cpsr to r0 and get it back */
765 retval = dpm->instr_read_data_r0(dpm,
766 armv8_opcode(armv8, READ_REG_DSPSR), &cpsr);
767 if (retval != ERROR_OK)
768 goto fail;
769
770 /* update core mode and state */
771 armv8_set_cpsr(arm, cpsr);
772
773 for (unsigned int i = ARMV8_PC; i < cache->num_regs ; i++) {
774 struct arm_reg *arm_reg;
775
776 r = armv8_reg_current(arm, i);
777 if (r->valid)
778 continue;
779
780 /* Skip reading FP-SIMD registers */
781 if (r->number >= ARMV8_V0 && r->number <= ARMV8_FPCR)
782 continue;
783
784 /*
785 * Only read registers that are available from the
786 * current EL (or core mode).
787 */
788 arm_reg = r->arch_info;
789 if (arm_reg->mode != ARM_MODE_ANY &&
790 dpm->last_el != armv8_curel_from_core_mode(arm_reg->mode))
791 continue;
792
793 retval = dpmv8_read_reg(dpm, r, i);
794 if (retval != ERROR_OK)
795 goto fail;
796
797 }
798
799 fail:
800 dpm->finish(dpm);
801 return retval;
802 }
803
804 /* Avoid needless I/O ... leave breakpoints and watchpoints alone
805 * unless they're removed, or need updating because of single-stepping
806 * or running debugger code.
807 */
808 static int dpmv8_maybe_update_bpwp(struct arm_dpm *dpm, bool bpwp,
809 struct dpm_bpwp *xp, int *set_p)
810 {
811 int retval = ERROR_OK;
812 bool disable;
813
814 if (!set_p) {
815 if (!xp->dirty)
816 goto done;
817 xp->dirty = false;
818 /* removed or startup; we must disable it */
819 disable = true;
820 } else if (bpwp) {
821 if (!xp->dirty)
822 goto done;
823 /* disabled, but we must set it */
824 xp->dirty = disable = false;
825 *set_p = true;
826 } else {
827 if (!*set_p)
828 goto done;
829 /* set, but we must temporarily disable it */
830 xp->dirty = disable = true;
831 *set_p = false;
832 }
833
834 if (disable)
835 retval = dpm->bpwp_disable(dpm, xp->number);
836 else
837 retval = dpm->bpwp_enable(dpm, xp->number,
838 xp->address, xp->control);
839
840 if (retval != ERROR_OK)
841 LOG_ERROR("%s: can't %s HW %spoint %d",
842 disable ? "disable" : "enable",
843 target_name(dpm->arm->target),
844 (xp->number < 16) ? "break" : "watch",
845 xp->number & 0xf);
846 done:
847 return retval;
848 }
849
850 static int dpmv8_add_breakpoint(struct target *target, struct breakpoint *bp);
851
852 /**
853 * Writes all modified core registers for all processor modes. In normal
854 * operation this is called on exit from halting debug state.
855 *
856 * @param dpm: represents the processor
857 * @param bpwp: true ensures breakpoints and watchpoints are set,
858 * false ensures they are cleared
859 */
860 int armv8_dpm_write_dirty_registers(struct arm_dpm *dpm, bool bpwp)
861 {
862 struct arm *arm = dpm->arm;
863 struct reg_cache *cache = arm->core_cache;
864 int retval;
865
866 retval = dpm->prepare(dpm);
867 if (retval != ERROR_OK)
868 goto done;
869
870 /* If we're managing hardware breakpoints for this core, enable
871 * or disable them as requested.
872 *
873 * REVISIT We don't yet manage them for ANY cores. Eventually
874 * we should be able to assume we handle them; but until then,
875 * cope with the hand-crafted breakpoint code.
876 */
877 if (arm->target->type->add_breakpoint == dpmv8_add_breakpoint) {
878 for (unsigned i = 0; i < dpm->nbp; i++) {
879 struct dpm_bp *dbp = dpm->dbp + i;
880 struct breakpoint *bp = dbp->bp;
881
882 retval = dpmv8_maybe_update_bpwp(dpm, bpwp, &dbp->bpwp,
883 bp ? &bp->set : NULL);
884 if (retval != ERROR_OK)
885 goto done;
886 }
887 }
888
889 /* enable/disable watchpoints */
890 for (unsigned i = 0; i < dpm->nwp; i++) {
891 struct dpm_wp *dwp = dpm->dwp + i;
892 struct watchpoint *wp = dwp->wp;
893
894 retval = dpmv8_maybe_update_bpwp(dpm, bpwp, &dwp->bpwp,
895 wp ? &wp->set : NULL);
896 if (retval != ERROR_OK)
897 goto done;
898 }
899
900 /* NOTE: writes to breakpoint and watchpoint registers might
901 * be queued, and need (efficient/batched) flushing later.
902 */
903
904 /* Restore original core mode and state */
905 retval = armv8_dpm_modeswitch(dpm, ARM_MODE_ANY);
906 if (retval != ERROR_OK)
907 goto done;
908
909 /* check everything except our scratch register R0 */
910 for (unsigned i = 1; i < cache->num_regs; i++) {
911 struct arm_reg *r;
912
913 /* skip PC and CPSR */
914 if (i == ARMV8_PC || i == ARMV8_xPSR)
915 continue;
916 /* skip invalid */
917 if (!cache->reg_list[i].valid)
918 continue;
919 /* skip non-dirty */
920 if (!cache->reg_list[i].dirty)
921 continue;
922
923 /* skip all registers not on the current EL */
924 r = cache->reg_list[i].arch_info;
925 if (r->mode != ARM_MODE_ANY &&
926 dpm->last_el != armv8_curel_from_core_mode(r->mode))
927 continue;
928
929 retval = dpmv8_write_reg(dpm, &cache->reg_list[i], i);
930 if (retval != ERROR_OK)
931 break;
932 }
933
934 /* flush CPSR and PC */
935 if (retval == ERROR_OK)
936 retval = dpmv8_write_reg(dpm, &cache->reg_list[ARMV8_xPSR], ARMV8_xPSR);
937 if (retval == ERROR_OK)
938 retval = dpmv8_write_reg(dpm, &cache->reg_list[ARMV8_PC], ARMV8_PC);
939 /* flush R0 -- it's *very* dirty by now */
940 if (retval == ERROR_OK)
941 retval = dpmv8_write_reg(dpm, &cache->reg_list[0], 0);
942 if (retval == ERROR_OK)
943 dpm->instr_cpsr_sync(dpm);
944 done:
945 dpm->finish(dpm);
946 return retval;
947 }
948
949 /*
950 * Standard ARM register accessors ... there are three methods
951 * in "struct arm", to support individual read/write and bulk read
952 * of registers.
953 */
954
955 static int armv8_dpm_read_core_reg(struct target *target, struct reg *r,
956 int regnum, enum arm_mode mode)
957 {
958 struct arm *arm = target_to_arm(target);
959 struct arm_dpm *dpm = target_to_arm(target)->dpm;
960 int retval;
961 int max = arm->core_cache->num_regs;
962
963 if (regnum < 0 || regnum >= max)
964 return ERROR_COMMAND_SYNTAX_ERROR;
965
966 /*
967 * REVISIT what happens if we try to read SPSR in a core mode
968 * which has no such register?
969 */
970 retval = dpm->prepare(dpm);
971 if (retval != ERROR_OK)
972 return retval;
973
974 retval = dpmv8_read_reg(dpm, r, regnum);
975 if (retval != ERROR_OK)
976 goto fail;
977
978 fail:
979 /* (void) */ dpm->finish(dpm);
980 return retval;
981 }
982
983 static int armv8_dpm_write_core_reg(struct target *target, struct reg *r,
984 int regnum, enum arm_mode mode, uint8_t *value)
985 {
986 struct arm *arm = target_to_arm(target);
987 struct arm_dpm *dpm = target_to_arm(target)->dpm;
988 int retval;
989 int max = arm->core_cache->num_regs;
990
991 if (regnum < 0 || regnum > max)
992 return ERROR_COMMAND_SYNTAX_ERROR;
993
994 /* REVISIT what happens if we try to write SPSR in a core mode
995 * which has no such register?
996 */
997
998 retval = dpm->prepare(dpm);
999 if (retval != ERROR_OK)
1000 return retval;
1001
1002 retval = dpmv8_write_reg(dpm, r, regnum);
1003
1004 /* always clean up, regardless of error */
1005 dpm->finish(dpm);
1006
1007 return retval;
1008 }
1009
1010 static int armv8_dpm_full_context(struct target *target)
1011 {
1012 struct arm *arm = target_to_arm(target);
1013 struct arm_dpm *dpm = arm->dpm;
1014 struct reg_cache *cache = arm->core_cache;
1015 int retval;
1016 bool did_read;
1017
1018 retval = dpm->prepare(dpm);
1019 if (retval != ERROR_OK)
1020 goto done;
1021
1022 do {
1023 enum arm_mode mode = ARM_MODE_ANY;
1024
1025 did_read = false;
1026
1027 /* We "know" arm_dpm_read_current_registers() was called so
1028 * the unmapped registers (R0..R7, PC, AND CPSR) and some
1029 * view of R8..R14 are current. We also "know" oddities of
1030 * register mapping: special cases for R8..R12 and SPSR.
1031 *
1032 * Pick some mode with unread registers and read them all.
1033 * Repeat until done.
1034 */
1035 for (unsigned i = 0; i < cache->num_regs; i++) {
1036 struct arm_reg *r;
1037
1038 if (cache->reg_list[i].valid)
1039 continue;
1040 r = cache->reg_list[i].arch_info;
1041
1042 /* may need to pick a mode and set CPSR */
1043 if (!did_read) {
1044 did_read = true;
1045 mode = r->mode;
1046
1047 /* For regular (ARM_MODE_ANY) R8..R12
1048 * in case we've entered debug state
1049 * in FIQ mode we need to patch mode.
1050 */
1051 if (mode != ARM_MODE_ANY)
1052 retval = armv8_dpm_modeswitch(dpm, mode);
1053 else
1054 retval = armv8_dpm_modeswitch(dpm, ARM_MODE_USR);
1055
1056 if (retval != ERROR_OK)
1057 goto done;
1058 }
1059 if (r->mode != mode)
1060 continue;
1061
1062 /* CPSR was read, so "R16" must mean SPSR */
1063 retval = dpmv8_read_reg(dpm,
1064 &cache->reg_list[i],
1065 (r->num == 16) ? 17 : r->num);
1066 if (retval != ERROR_OK)
1067 goto done;
1068 }
1069
1070 } while (did_read);
1071
1072 retval = armv8_dpm_modeswitch(dpm, ARM_MODE_ANY);
1073 /* (void) */ dpm->finish(dpm);
1074 done:
1075 return retval;
1076 }
1077
1078
1079 /*----------------------------------------------------------------------*/
1080
1081 /*
1082 * Breakpoint and Watchpoint support.
1083 *
1084 * Hardware {break,watch}points are usually left active, to minimize
1085 * debug entry/exit costs. When they are set or cleared, it's done in
1086 * batches. Also, DPM-conformant hardware can update debug registers
1087 * regardless of whether the CPU is running or halted ... though that
1088 * fact isn't currently leveraged.
1089 */
1090
1091 static int dpmv8_bpwp_setup(struct arm_dpm *dpm, struct dpm_bpwp *xp,
1092 uint32_t addr, uint32_t length)
1093 {
1094 uint32_t control;
1095
1096 control = (1 << 0) /* enable */
1097 | (3 << 1); /* both user and privileged access */
1098
1099 /* Match 1, 2, or all 4 byte addresses in this word.
1100 *
1101 * FIXME: v7 hardware allows lengths up to 2 GB for BP and WP.
1102 * Support larger length, when addr is suitably aligned. In
1103 * particular, allow watchpoints on 8 byte "double" values.
1104 *
1105 * REVISIT allow watchpoints on unaligned 2-bit values; and on
1106 * v7 hardware, unaligned 4-byte ones too.
1107 */
1108 switch (length) {
1109 case 1:
1110 control |= (1 << (addr & 3)) << 5;
1111 break;
1112 case 2:
1113 /* require 2-byte alignment */
1114 if (!(addr & 1)) {
1115 control |= (3 << (addr & 2)) << 5;
1116 break;
1117 }
1118 /* FALL THROUGH */
1119 case 4:
1120 /* require 4-byte alignment */
1121 if (!(addr & 3)) {
1122 control |= 0xf << 5;
1123 break;
1124 }
1125 /* FALL THROUGH */
1126 default:
1127 LOG_ERROR("unsupported {break,watch}point length/alignment");
1128 return ERROR_COMMAND_SYNTAX_ERROR;
1129 }
1130
1131 /* other shared control bits:
1132 * bits 15:14 == 0 ... both secure and nonsecure states (v6.1+ only)
1133 * bit 20 == 0 ... not linked to a context ID
1134 * bit 28:24 == 0 ... not ignoring N LSBs (v7 only)
1135 */
1136
1137 xp->address = addr & ~3;
1138 xp->control = control;
1139 xp->dirty = true;
1140
1141 LOG_DEBUG("BPWP: addr %8.8" PRIx32 ", control %" PRIx32 ", number %d",
1142 xp->address, control, xp->number);
1143
1144 /* hardware is updated in write_dirty_registers() */
1145 return ERROR_OK;
1146 }
1147
1148 static int dpmv8_add_breakpoint(struct target *target, struct breakpoint *bp)
1149 {
1150 struct arm *arm = target_to_arm(target);
1151 struct arm_dpm *dpm = arm->dpm;
1152 int retval = ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
1153
1154 if (bp->length < 2)
1155 return ERROR_COMMAND_SYNTAX_ERROR;
1156 if (!dpm->bpwp_enable)
1157 return retval;
1158
1159 /* FIXME we need a generic solution for software breakpoints. */
1160 if (bp->type == BKPT_SOFT)
1161 LOG_DEBUG("using HW bkpt, not SW...");
1162
1163 for (unsigned i = 0; i < dpm->nbp; i++) {
1164 if (!dpm->dbp[i].bp) {
1165 retval = dpmv8_bpwp_setup(dpm, &dpm->dbp[i].bpwp,
1166 bp->address, bp->length);
1167 if (retval == ERROR_OK)
1168 dpm->dbp[i].bp = bp;
1169 break;
1170 }
1171 }
1172
1173 return retval;
1174 }
1175
1176 static int dpmv8_remove_breakpoint(struct target *target, struct breakpoint *bp)
1177 {
1178 struct arm *arm = target_to_arm(target);
1179 struct arm_dpm *dpm = arm->dpm;
1180 int retval = ERROR_COMMAND_SYNTAX_ERROR;
1181
1182 for (unsigned i = 0; i < dpm->nbp; i++) {
1183 if (dpm->dbp[i].bp == bp) {
1184 dpm->dbp[i].bp = NULL;
1185 dpm->dbp[i].bpwp.dirty = true;
1186
1187 /* hardware is updated in write_dirty_registers() */
1188 retval = ERROR_OK;
1189 break;
1190 }
1191 }
1192
1193 return retval;
1194 }
1195
1196 static int dpmv8_watchpoint_setup(struct arm_dpm *dpm, unsigned index_t,
1197 struct watchpoint *wp)
1198 {
1199 int retval;
1200 struct dpm_wp *dwp = dpm->dwp + index_t;
1201 uint32_t control;
1202
1203 /* this hardware doesn't support data value matching or masking */
1204 if (wp->value || wp->mask != ~(uint32_t)0) {
1205 LOG_DEBUG("watchpoint values and masking not supported");
1206 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
1207 }
1208
1209 retval = dpmv8_bpwp_setup(dpm, &dwp->bpwp, wp->address, wp->length);
1210 if (retval != ERROR_OK)
1211 return retval;
1212
1213 control = dwp->bpwp.control;
1214 switch (wp->rw) {
1215 case WPT_READ:
1216 control |= 1 << 3;
1217 break;
1218 case WPT_WRITE:
1219 control |= 2 << 3;
1220 break;
1221 case WPT_ACCESS:
1222 control |= 3 << 3;
1223 break;
1224 }
1225 dwp->bpwp.control = control;
1226
1227 dpm->dwp[index_t].wp = wp;
1228
1229 return retval;
1230 }
1231
1232 static int dpmv8_add_watchpoint(struct target *target, struct watchpoint *wp)
1233 {
1234 struct arm *arm = target_to_arm(target);
1235 struct arm_dpm *dpm = arm->dpm;
1236 int retval = ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
1237
1238 if (dpm->bpwp_enable) {
1239 for (unsigned i = 0; i < dpm->nwp; i++) {
1240 if (!dpm->dwp[i].wp) {
1241 retval = dpmv8_watchpoint_setup(dpm, i, wp);
1242 break;
1243 }
1244 }
1245 }
1246
1247 return retval;
1248 }
1249
1250 static int dpmv8_remove_watchpoint(struct target *target, struct watchpoint *wp)
1251 {
1252 struct arm *arm = target_to_arm(target);
1253 struct arm_dpm *dpm = arm->dpm;
1254 int retval = ERROR_COMMAND_SYNTAX_ERROR;
1255
1256 for (unsigned i = 0; i < dpm->nwp; i++) {
1257 if (dpm->dwp[i].wp == wp) {
1258 dpm->dwp[i].wp = NULL;
1259 dpm->dwp[i].bpwp.dirty = true;
1260
1261 /* hardware is updated in write_dirty_registers() */
1262 retval = ERROR_OK;
1263 break;
1264 }
1265 }
1266
1267 return retval;
1268 }
1269
1270 void armv8_dpm_report_wfar(struct arm_dpm *dpm, uint64_t addr)
1271 {
1272 switch (dpm->arm->core_state) {
1273 case ARM_STATE_ARM:
1274 case ARM_STATE_AARCH64:
1275 addr -= 8;
1276 break;
1277 case ARM_STATE_THUMB:
1278 case ARM_STATE_THUMB_EE:
1279 addr -= 4;
1280 break;
1281 case ARM_STATE_JAZELLE:
1282 /* ?? */
1283 break;
1284 default:
1285 LOG_DEBUG("Unknown core_state");
1286 break;
1287 }
1288 dpm->wp_pc = addr;
1289 }
1290
1291 /*
1292 * Handle exceptions taken in debug state. This happens mostly for memory
1293 * accesses that violated a MMU policy. Taking an exception while in debug
1294 * state clobbers certain state registers on the target exception level.
1295 * Just mark those registers dirty so that they get restored on resume.
1296 * This works both for Aarch32 and Aarch64 states.
1297 *
1298 * This function must not perform any actions that trigger another exception
1299 * or a recursion will happen.
1300 */
1301 void armv8_dpm_handle_exception(struct arm_dpm *dpm, bool do_restore)
1302 {
1303 struct armv8_common *armv8 = dpm->arm->arch_info;
1304 struct reg_cache *cache = dpm->arm->core_cache;
1305 enum arm_state core_state;
1306 uint64_t dlr;
1307 uint32_t dspsr;
1308 unsigned int el;
1309
1310 static const int clobbered_regs_by_el[3][5] = {
1311 { ARMV8_PC, ARMV8_xPSR, ARMV8_ELR_EL1, ARMV8_ESR_EL1, ARMV8_SPSR_EL1 },
1312 { ARMV8_PC, ARMV8_xPSR, ARMV8_ELR_EL2, ARMV8_ESR_EL2, ARMV8_SPSR_EL2 },
1313 { ARMV8_PC, ARMV8_xPSR, ARMV8_ELR_EL3, ARMV8_ESR_EL3, ARMV8_SPSR_EL3 },
1314 };
1315
1316 el = (dpm->dscr >> 8) & 3;
1317
1318 /* safety check, must not happen since EL0 cannot be a target for an exception */
1319 if (el < SYSTEM_CUREL_EL1 || el > SYSTEM_CUREL_EL3) {
1320 LOG_ERROR("%s: EL %i is invalid, DSCR corrupted?", __func__, el);
1321 return;
1322 }
1323
1324 /* Clear sticky error */
1325 mem_ap_write_u32(armv8->debug_ap,
1326 armv8->debug_base + CPUV8_DBG_DRCR, DRCR_CSE);
1327
1328 armv8->read_reg_u64(armv8, ARMV8_xPSR, &dlr);
1329 dspsr = dlr;
1330 armv8->read_reg_u64(armv8, ARMV8_PC, &dlr);
1331
1332 LOG_DEBUG("Exception taken to EL %i, DLR=0x%016"PRIx64" DSPSR=0x%08"PRIx32,
1333 el, dlr, dspsr);
1334
1335 /* mark all clobbered registers as dirty */
1336 for (int i = 0; i < 5; i++)
1337 cache->reg_list[clobbered_regs_by_el[el-1][i]].dirty = true;
1338
1339 /*
1340 * re-evaluate the core state, we might be in Aarch64 state now
1341 * we rely on dpm->dscr being up-to-date
1342 */
1343 core_state = armv8_dpm_get_core_state(dpm);
1344 armv8_select_opcodes(armv8, core_state == ARM_STATE_AARCH64);
1345 armv8_select_reg_access(armv8, core_state == ARM_STATE_AARCH64);
1346
1347 if (do_restore)
1348 armv8_dpm_modeswitch(dpm, ARM_MODE_ANY);
1349 }
1350
1351 /*----------------------------------------------------------------------*/
1352
1353 /*
1354 * Other debug and support utilities
1355 */
1356
1357 void armv8_dpm_report_dscr(struct arm_dpm *dpm, uint32_t dscr)
1358 {
1359 struct target *target = dpm->arm->target;
1360
1361 dpm->dscr = dscr;
1362 dpm->last_el = (dscr >> 8) & 3;
1363
1364 /* Examine debug reason */
1365 switch (DSCR_ENTRY(dscr)) {
1366 /* FALL THROUGH -- assume a v6 core in abort mode */
1367 case DSCRV8_ENTRY_EXT_DEBUG: /* EDBGRQ */
1368 target->debug_reason = DBG_REASON_DBGRQ;
1369 break;
1370 case DSCRV8_ENTRY_HALT_STEP_EXECLU: /* HALT step */
1371 case DSCRV8_ENTRY_HALT_STEP_NORMAL: /* Halt step*/
1372 case DSCRV8_ENTRY_HALT_STEP:
1373 target->debug_reason = DBG_REASON_SINGLESTEP;
1374 break;
1375 case DSCRV8_ENTRY_HLT: /* HLT instruction (software breakpoint) */
1376 case DSCRV8_ENTRY_BKPT: /* SW BKPT (?) */
1377 case DSCRV8_ENTRY_RESET_CATCH: /* Reset catch */
1378 case DSCRV8_ENTRY_OS_UNLOCK: /*OS unlock catch*/
1379 case DSCRV8_ENTRY_EXCEPTION_CATCH: /*exception catch*/
1380 case DSCRV8_ENTRY_SW_ACCESS_DBG: /*SW access dbg register*/
1381 target->debug_reason = DBG_REASON_BREAKPOINT;
1382 break;
1383 case DSCRV8_ENTRY_WATCHPOINT: /* asynch watchpoint */
1384 target->debug_reason = DBG_REASON_WATCHPOINT;
1385 break;
1386 default:
1387 target->debug_reason = DBG_REASON_UNDEFINED;
1388 break;
1389 }
1390
1391 }
1392
1393 /*----------------------------------------------------------------------*/
1394
1395 /*
1396 * Setup and management support.
1397 */
1398
1399 /**
1400 * Hooks up this DPM to its associated target; call only once.
1401 * Initially this only covers the register cache.
1402 *
1403 * Oh, and watchpoints. Yeah.
1404 */
1405 int armv8_dpm_setup(struct arm_dpm *dpm)
1406 {
1407 struct arm *arm = dpm->arm;
1408 struct target *target = arm->target;
1409 struct reg_cache *cache;
1410 arm->dpm = dpm;
1411
1412 /* register access setup */
1413 arm->full_context = armv8_dpm_full_context;
1414 arm->read_core_reg = armv8_dpm_read_core_reg;
1415 arm->write_core_reg = armv8_dpm_write_core_reg;
1416
1417 if (arm->core_cache == NULL) {
1418 cache = armv8_build_reg_cache(target);
1419 if (!cache)
1420 return ERROR_FAIL;
1421 }
1422
1423 /* coprocessor access setup */
1424 arm->mrc = dpmv8_mrc;
1425 arm->mcr = dpmv8_mcr;
1426
1427 dpm->prepare = dpmv8_dpm_prepare;
1428 dpm->finish = dpmv8_dpm_finish;
1429
1430 dpm->instr_execute = dpmv8_instr_execute;
1431 dpm->instr_write_data_dcc = dpmv8_instr_write_data_dcc;
1432 dpm->instr_write_data_dcc_64 = dpmv8_instr_write_data_dcc_64;
1433 dpm->instr_write_data_r0 = dpmv8_instr_write_data_r0;
1434 dpm->instr_write_data_r0_64 = dpmv8_instr_write_data_r0_64;
1435 dpm->instr_cpsr_sync = dpmv8_instr_cpsr_sync;
1436
1437 dpm->instr_read_data_dcc = dpmv8_instr_read_data_dcc;
1438 dpm->instr_read_data_dcc_64 = dpmv8_instr_read_data_dcc_64;
1439 dpm->instr_read_data_r0 = dpmv8_instr_read_data_r0;
1440 dpm->instr_read_data_r0_64 = dpmv8_instr_read_data_r0_64;
1441
1442 dpm->arm_reg_current = armv8_reg_current;
1443
1444 /* dpm->bpwp_enable = dpmv8_bpwp_enable; */
1445 dpm->bpwp_disable = dpmv8_bpwp_disable;
1446
1447 /* breakpoint setup -- optional until it works everywhere */
1448 if (!target->type->add_breakpoint) {
1449 target->type->add_breakpoint = dpmv8_add_breakpoint;
1450 target->type->remove_breakpoint = dpmv8_remove_breakpoint;
1451 }
1452
1453 /* watchpoint setup */
1454 target->type->add_watchpoint = dpmv8_add_watchpoint;
1455 target->type->remove_watchpoint = dpmv8_remove_watchpoint;
1456
1457 /* FIXME add vector catch support */
1458
1459 dpm->nbp = 1 + ((dpm->didr >> 12) & 0xf);
1460 dpm->dbp = calloc(dpm->nbp, sizeof *dpm->dbp);
1461
1462 dpm->nwp = 1 + ((dpm->didr >> 20) & 0xf);
1463 dpm->dwp = calloc(dpm->nwp, sizeof *dpm->dwp);
1464
1465 if (!dpm->dbp || !dpm->dwp) {
1466 free(dpm->dbp);
1467 free(dpm->dwp);
1468 return ERROR_FAIL;
1469 }
1470
1471 LOG_INFO("%s: hardware has %d breakpoints, %d watchpoints",
1472 target_name(target), dpm->nbp, dpm->nwp);
1473
1474 /* REVISIT ... and some of those breakpoints could match
1475 * execution context IDs...
1476 */
1477
1478 return ERROR_OK;
1479 }
1480
1481 /**
1482 * Reinitializes DPM state at the beginning of a new debug session
1483 * or after a reset which may have affected the debug module.
1484 */
1485 int armv8_dpm_initialize(struct arm_dpm *dpm)
1486 {
1487 /* Disable all breakpoints and watchpoints at startup. */
1488 if (dpm->bpwp_disable) {
1489 unsigned i;
1490
1491 for (i = 0; i < dpm->nbp; i++) {
1492 dpm->dbp[i].bpwp.number = i;
1493 (void) dpm->bpwp_disable(dpm, i);
1494 }
1495 for (i = 0; i < dpm->nwp; i++) {
1496 dpm->dwp[i].bpwp.number = 16 + i;
1497 (void) dpm->bpwp_disable(dpm, 16 + i);
1498 }
1499 } else
1500 LOG_WARNING("%s: can't disable breakpoints and watchpoints",
1501 target_name(dpm->arm->target));
1502
1503 return ERROR_OK;
1504 }

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)