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

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)