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

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)