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

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)