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

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)