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

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)