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

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)