target/cortex_m: Add Realtek Real-M200 and M300
[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) & 0b1)
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;
729 * sets the core mode (such as USR or IRQ) and state (such as ARM or Thumb).
730 * In normal operation this is called on entry to halting debug state,
731 * possibly after some other operations supporting restore of debug state
732 * or making sure the CPU is fully idle (drain write buffer, etc).
733 */
734 int armv8_dpm_read_current_registers(struct arm_dpm *dpm)
735 {
736 struct arm *arm = dpm->arm;
737 struct armv8_common *armv8 = (struct armv8_common *)arm->arch_info;
738 struct reg_cache *cache;
739 struct reg *r;
740 uint32_t cpsr;
741 int retval;
742
743 retval = dpm->prepare(dpm);
744 if (retval != ERROR_OK)
745 return retval;
746
747 cache = arm->core_cache;
748
749 /* read R0 first (it's used for scratch), then CPSR */
750 r = cache->reg_list + ARMV8_R0;
751 if (!r->valid) {
752 retval = dpmv8_read_reg(dpm, r, ARMV8_R0);
753 if (retval != ERROR_OK)
754 goto fail;
755 }
756 r->dirty = true;
757
758 /* read R1, too, it will be clobbered during memory access */
759 r = cache->reg_list + ARMV8_R1;
760 if (!r->valid) {
761 retval = dpmv8_read_reg(dpm, r, ARMV8_R1);
762 if (retval != ERROR_OK)
763 goto fail;
764 }
765
766 /* read cpsr to r0 and get it back */
767 retval = dpm->instr_read_data_r0(dpm,
768 armv8_opcode(armv8, READ_REG_DSPSR), &cpsr);
769 if (retval != ERROR_OK)
770 goto fail;
771
772 /* update core mode and state */
773 armv8_set_cpsr(arm, cpsr);
774
775 for (unsigned int i = ARMV8_PC; i < cache->num_regs ; i++) {
776 struct arm_reg *arm_reg;
777
778 r = armv8_reg_current(arm, i);
779 if (!r->exist || r->valid)
780 continue;
781
782 /* Skip reading FP-SIMD registers */
783 if (r->number >= ARMV8_V0 && r->number <= ARMV8_FPCR)
784 continue;
785
786 /*
787 * Only read registers that are available from the
788 * current EL (or core mode).
789 */
790 arm_reg = r->arch_info;
791 if (arm_reg->mode != ARM_MODE_ANY &&
792 dpm->last_el != armv8_curel_from_core_mode(arm_reg->mode))
793 continue;
794
795 /* Special case: ARM_MODE_SYS has no SPSR at EL1 */
796 if (r->number == ARMV8_SPSR_EL1 && arm->core_mode == ARM_MODE_SYS)
797 continue;
798
799 retval = dpmv8_read_reg(dpm, r, i);
800 if (retval != ERROR_OK)
801 goto fail;
802
803 }
804
805 fail:
806 dpm->finish(dpm);
807 return retval;
808 }
809
810 /* Avoid needless I/O ... leave breakpoints and watchpoints alone
811 * unless they're removed, or need updating because of single-stepping
812 * or running debugger code.
813 */
814 static int dpmv8_maybe_update_bpwp(struct arm_dpm *dpm, bool bpwp,
815 struct dpm_bpwp *xp, bool *set_p)
816 {
817 int retval = ERROR_OK;
818 bool disable;
819
820 if (!set_p) {
821 if (!xp->dirty)
822 goto done;
823 xp->dirty = false;
824 /* removed or startup; we must disable it */
825 disable = true;
826 } else if (bpwp) {
827 if (!xp->dirty)
828 goto done;
829 /* disabled, but we must set it */
830 xp->dirty = disable = false;
831 *set_p = true;
832 } else {
833 if (!*set_p)
834 goto done;
835 /* set, but we must temporarily disable it */
836 xp->dirty = disable = true;
837 *set_p = false;
838 }
839
840 if (disable)
841 retval = dpm->bpwp_disable(dpm, xp->number);
842 else
843 retval = dpm->bpwp_enable(dpm, xp->number,
844 xp->address, xp->control);
845
846 if (retval != ERROR_OK)
847 LOG_ERROR("%s: can't %s HW %spoint %d",
848 disable ? "disable" : "enable",
849 target_name(dpm->arm->target),
850 (xp->number < 16) ? "break" : "watch",
851 xp->number & 0xf);
852 done:
853 return retval;
854 }
855
856 static int dpmv8_add_breakpoint(struct target *target, struct breakpoint *bp);
857
858 /**
859 * Writes all modified core registers for all processor modes. In normal
860 * operation this is called on exit from halting debug state.
861 *
862 * @param dpm: represents the processor
863 * @param bpwp: true ensures breakpoints and watchpoints are set,
864 * false ensures they are cleared
865 */
866 int armv8_dpm_write_dirty_registers(struct arm_dpm *dpm, bool bpwp)
867 {
868 struct arm *arm = dpm->arm;
869 struct reg_cache *cache = arm->core_cache;
870 int retval;
871
872 retval = dpm->prepare(dpm);
873 if (retval != ERROR_OK)
874 goto done;
875
876 /* If we're managing hardware breakpoints for this core, enable
877 * or disable them as requested.
878 *
879 * REVISIT We don't yet manage them for ANY cores. Eventually
880 * we should be able to assume we handle them; but until then,
881 * cope with the hand-crafted breakpoint code.
882 */
883 if (arm->target->type->add_breakpoint == dpmv8_add_breakpoint) {
884 for (unsigned i = 0; i < dpm->nbp; i++) {
885 struct dpm_bp *dbp = dpm->dbp + i;
886 struct breakpoint *bp = dbp->bp;
887
888 retval = dpmv8_maybe_update_bpwp(dpm, bpwp, &dbp->bpwp,
889 bp ? &bp->is_set : NULL);
890 if (retval != ERROR_OK)
891 goto done;
892 }
893 }
894
895 /* enable/disable watchpoints */
896 for (unsigned i = 0; i < dpm->nwp; i++) {
897 struct dpm_wp *dwp = dpm->dwp + i;
898 struct watchpoint *wp = dwp->wp;
899
900 retval = dpmv8_maybe_update_bpwp(dpm, bpwp, &dwp->bpwp,
901 wp ? &wp->is_set : NULL);
902 if (retval != ERROR_OK)
903 goto done;
904 }
905
906 /* NOTE: writes to breakpoint and watchpoint registers might
907 * be queued, and need (efficient/batched) flushing later.
908 */
909
910 /* Restore original core mode and state */
911 retval = armv8_dpm_modeswitch(dpm, ARM_MODE_ANY);
912 if (retval != ERROR_OK)
913 goto done;
914
915 /* check everything except our scratch register R0 */
916 for (unsigned i = 1; i < cache->num_regs; i++) {
917 struct arm_reg *r;
918
919 /* skip non-existent */
920 if (!cache->reg_list[i].exist)
921 continue;
922 /* skip PC and CPSR */
923 if (i == ARMV8_PC || i == ARMV8_XPSR)
924 continue;
925 /* skip invalid */
926 if (!cache->reg_list[i].valid)
927 continue;
928 /* skip non-dirty */
929 if (!cache->reg_list[i].dirty)
930 continue;
931
932 /* skip all registers not on the current EL */
933 r = cache->reg_list[i].arch_info;
934 if (r->mode != ARM_MODE_ANY &&
935 dpm->last_el != armv8_curel_from_core_mode(r->mode))
936 continue;
937
938 retval = dpmv8_write_reg(dpm, &cache->reg_list[i], i);
939 if (retval != ERROR_OK)
940 break;
941 }
942
943 /* flush CPSR and PC */
944 if (retval == ERROR_OK)
945 retval = dpmv8_write_reg(dpm, &cache->reg_list[ARMV8_XPSR], ARMV8_XPSR);
946 if (retval == ERROR_OK)
947 retval = dpmv8_write_reg(dpm, &cache->reg_list[ARMV8_PC], ARMV8_PC);
948 /* flush R0 -- it's *very* dirty by now */
949 if (retval == ERROR_OK)
950 retval = dpmv8_write_reg(dpm, &cache->reg_list[0], 0);
951 if (retval == ERROR_OK)
952 dpm->instr_cpsr_sync(dpm);
953 done:
954 dpm->finish(dpm);
955 return retval;
956 }
957
958 /*
959 * Standard ARM register accessors ... there are three methods
960 * in "struct arm", to support individual read/write and bulk read
961 * of registers.
962 */
963
964 static int armv8_dpm_read_core_reg(struct target *target, struct reg *r,
965 int regnum, enum arm_mode mode)
966 {
967 struct arm *arm = target_to_arm(target);
968 struct arm_dpm *dpm = target_to_arm(target)->dpm;
969 int retval;
970 int max = arm->core_cache->num_regs;
971
972 if (regnum < 0 || regnum >= max)
973 return ERROR_COMMAND_SYNTAX_ERROR;
974
975 /*
976 * REVISIT what happens if we try to read SPSR in a core mode
977 * which has no such register?
978 */
979 retval = dpm->prepare(dpm);
980 if (retval != ERROR_OK)
981 return retval;
982
983 retval = dpmv8_read_reg(dpm, r, regnum);
984 if (retval != ERROR_OK)
985 goto fail;
986
987 fail:
988 /* (void) */ dpm->finish(dpm);
989 return retval;
990 }
991
992 static int armv8_dpm_write_core_reg(struct target *target, struct reg *r,
993 int regnum, enum arm_mode mode, uint8_t *value)
994 {
995 struct arm *arm = target_to_arm(target);
996 struct arm_dpm *dpm = target_to_arm(target)->dpm;
997 int retval;
998 int max = arm->core_cache->num_regs;
999
1000 if (regnum < 0 || regnum > max)
1001 return ERROR_COMMAND_SYNTAX_ERROR;
1002
1003 /* REVISIT what happens if we try to write SPSR in a core mode
1004 * which has no such register?
1005 */
1006
1007 retval = dpm->prepare(dpm);
1008 if (retval != ERROR_OK)
1009 return retval;
1010
1011 retval = dpmv8_write_reg(dpm, r, regnum);
1012
1013 /* always clean up, regardless of error */
1014 dpm->finish(dpm);
1015
1016 return retval;
1017 }
1018
1019 static int armv8_dpm_full_context(struct target *target)
1020 {
1021 struct arm *arm = target_to_arm(target);
1022 struct arm_dpm *dpm = arm->dpm;
1023 struct reg_cache *cache = arm->core_cache;
1024 int retval;
1025 bool did_read;
1026
1027 retval = dpm->prepare(dpm);
1028 if (retval != ERROR_OK)
1029 goto done;
1030
1031 do {
1032 enum arm_mode mode = ARM_MODE_ANY;
1033
1034 did_read = false;
1035
1036 /* We "know" arm_dpm_read_current_registers() was called so
1037 * the unmapped registers (R0..R7, PC, AND CPSR) and some
1038 * view of R8..R14 are current. We also "know" oddities of
1039 * register mapping: special cases for R8..R12 and SPSR.
1040 *
1041 * Pick some mode with unread registers and read them all.
1042 * Repeat until done.
1043 */
1044 for (unsigned i = 0; i < cache->num_regs; i++) {
1045 struct arm_reg *r;
1046
1047 if (!cache->reg_list[i].exist || cache->reg_list[i].valid)
1048 continue;
1049 r = cache->reg_list[i].arch_info;
1050
1051 /* may need to pick a mode and set CPSR */
1052 if (!did_read) {
1053 did_read = true;
1054 mode = r->mode;
1055
1056 /* For regular (ARM_MODE_ANY) R8..R12
1057 * in case we've entered debug state
1058 * in FIQ mode we need to patch mode.
1059 */
1060 if (mode != ARM_MODE_ANY)
1061 retval = armv8_dpm_modeswitch(dpm, mode);
1062 else
1063 retval = armv8_dpm_modeswitch(dpm, ARM_MODE_USR);
1064
1065 if (retval != ERROR_OK)
1066 goto done;
1067 }
1068 if (r->mode != mode)
1069 continue;
1070
1071 /* CPSR was read, so "R16" must mean SPSR */
1072 retval = dpmv8_read_reg(dpm,
1073 &cache->reg_list[i],
1074 (r->num == 16) ? 17 : r->num);
1075 if (retval != ERROR_OK)
1076 goto done;
1077 }
1078
1079 } while (did_read);
1080
1081 retval = armv8_dpm_modeswitch(dpm, ARM_MODE_ANY);
1082 /* (void) */ dpm->finish(dpm);
1083 done:
1084 return retval;
1085 }
1086
1087
1088 /*----------------------------------------------------------------------*/
1089
1090 /*
1091 * Breakpoint and Watchpoint support.
1092 *
1093 * Hardware {break,watch}points are usually left active, to minimize
1094 * debug entry/exit costs. When they are set or cleared, it's done in
1095 * batches. Also, DPM-conformant hardware can update debug registers
1096 * regardless of whether the CPU is running or halted ... though that
1097 * fact isn't currently leveraged.
1098 */
1099
1100 static int dpmv8_bpwp_setup(struct arm_dpm *dpm, struct dpm_bpwp *xp,
1101 uint32_t addr, uint32_t length)
1102 {
1103 uint32_t control;
1104
1105 control = (1 << 0) /* enable */
1106 | (3 << 1); /* both user and privileged access */
1107
1108 /* Match 1, 2, or all 4 byte addresses in this word.
1109 *
1110 * FIXME: v7 hardware allows lengths up to 2 GB for BP and WP.
1111 * Support larger length, when addr is suitably aligned. In
1112 * particular, allow watchpoints on 8 byte "double" values.
1113 *
1114 * REVISIT allow watchpoints on unaligned 2-bit values; and on
1115 * v7 hardware, unaligned 4-byte ones too.
1116 */
1117 switch (length) {
1118 case 1:
1119 control |= (1 << (addr & 3)) << 5;
1120 break;
1121 case 2:
1122 /* require 2-byte alignment */
1123 if (!(addr & 1)) {
1124 control |= (3 << (addr & 2)) << 5;
1125 break;
1126 }
1127 /* FALL THROUGH */
1128 case 4:
1129 /* require 4-byte alignment */
1130 if (!(addr & 3)) {
1131 control |= 0xf << 5;
1132 break;
1133 }
1134 /* FALL THROUGH */
1135 default:
1136 LOG_ERROR("unsupported {break,watch}point length/alignment");
1137 return ERROR_COMMAND_SYNTAX_ERROR;
1138 }
1139
1140 /* other shared control bits:
1141 * bits 15:14 == 0 ... both secure and nonsecure states (v6.1+ only)
1142 * bit 20 == 0 ... not linked to a context ID
1143 * bit 28:24 == 0 ... not ignoring N LSBs (v7 only)
1144 */
1145
1146 xp->address = addr & ~3;
1147 xp->control = control;
1148 xp->dirty = true;
1149
1150 LOG_DEBUG("BPWP: addr %8.8" PRIx32 ", control %" PRIx32 ", number %d",
1151 xp->address, control, xp->number);
1152
1153 /* hardware is updated in write_dirty_registers() */
1154 return ERROR_OK;
1155 }
1156
1157 static int dpmv8_add_breakpoint(struct target *target, struct breakpoint *bp)
1158 {
1159 struct arm *arm = target_to_arm(target);
1160 struct arm_dpm *dpm = arm->dpm;
1161 int retval = ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
1162
1163 if (bp->length < 2)
1164 return ERROR_COMMAND_SYNTAX_ERROR;
1165 if (!dpm->bpwp_enable)
1166 return retval;
1167
1168 /* FIXME we need a generic solution for software breakpoints. */
1169 if (bp->type == BKPT_SOFT)
1170 LOG_DEBUG("using HW bkpt, not SW...");
1171
1172 for (unsigned i = 0; i < dpm->nbp; i++) {
1173 if (!dpm->dbp[i].bp) {
1174 retval = dpmv8_bpwp_setup(dpm, &dpm->dbp[i].bpwp,
1175 bp->address, bp->length);
1176 if (retval == ERROR_OK)
1177 dpm->dbp[i].bp = bp;
1178 break;
1179 }
1180 }
1181
1182 return retval;
1183 }
1184
1185 static int dpmv8_remove_breakpoint(struct target *target, struct breakpoint *bp)
1186 {
1187 struct arm *arm = target_to_arm(target);
1188 struct arm_dpm *dpm = arm->dpm;
1189 int retval = ERROR_COMMAND_SYNTAX_ERROR;
1190
1191 for (unsigned i = 0; i < dpm->nbp; i++) {
1192 if (dpm->dbp[i].bp == bp) {
1193 dpm->dbp[i].bp = NULL;
1194 dpm->dbp[i].bpwp.dirty = true;
1195
1196 /* hardware is updated in write_dirty_registers() */
1197 retval = ERROR_OK;
1198 break;
1199 }
1200 }
1201
1202 return retval;
1203 }
1204
1205 static int dpmv8_watchpoint_setup(struct arm_dpm *dpm, unsigned index_t,
1206 struct watchpoint *wp)
1207 {
1208 int retval;
1209 struct dpm_wp *dwp = dpm->dwp + index_t;
1210 uint32_t control;
1211
1212 /* this hardware doesn't support data value matching or masking */
1213 if (wp->mask != WATCHPOINT_IGNORE_DATA_VALUE_MASK) {
1214 LOG_DEBUG("watchpoint values and masking not supported");
1215 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
1216 }
1217
1218 retval = dpmv8_bpwp_setup(dpm, &dwp->bpwp, wp->address, wp->length);
1219 if (retval != ERROR_OK)
1220 return retval;
1221
1222 control = dwp->bpwp.control;
1223 switch (wp->rw) {
1224 case WPT_READ:
1225 control |= 1 << 3;
1226 break;
1227 case WPT_WRITE:
1228 control |= 2 << 3;
1229 break;
1230 case WPT_ACCESS:
1231 control |= 3 << 3;
1232 break;
1233 }
1234 dwp->bpwp.control = control;
1235
1236 dpm->dwp[index_t].wp = wp;
1237
1238 return retval;
1239 }
1240
1241 static int dpmv8_add_watchpoint(struct target *target, struct watchpoint *wp)
1242 {
1243 struct arm *arm = target_to_arm(target);
1244 struct arm_dpm *dpm = arm->dpm;
1245 int retval = ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
1246
1247 if (dpm->bpwp_enable) {
1248 for (unsigned i = 0; i < dpm->nwp; i++) {
1249 if (!dpm->dwp[i].wp) {
1250 retval = dpmv8_watchpoint_setup(dpm, i, wp);
1251 break;
1252 }
1253 }
1254 }
1255
1256 return retval;
1257 }
1258
1259 static int dpmv8_remove_watchpoint(struct target *target, struct watchpoint *wp)
1260 {
1261 struct arm *arm = target_to_arm(target);
1262 struct arm_dpm *dpm = arm->dpm;
1263 int retval = ERROR_COMMAND_SYNTAX_ERROR;
1264
1265 for (unsigned i = 0; i < dpm->nwp; i++) {
1266 if (dpm->dwp[i].wp == wp) {
1267 dpm->dwp[i].wp = NULL;
1268 dpm->dwp[i].bpwp.dirty = true;
1269
1270 /* hardware is updated in write_dirty_registers() */
1271 retval = ERROR_OK;
1272 break;
1273 }
1274 }
1275
1276 return retval;
1277 }
1278
1279 /*
1280 * Handle exceptions taken in debug state. This happens mostly for memory
1281 * accesses that violated a MMU policy. Taking an exception while in debug
1282 * state clobbers certain state registers on the target exception level.
1283 * Just mark those registers dirty so that they get restored on resume.
1284 * This works both for Aarch32 and Aarch64 states.
1285 *
1286 * This function must not perform any actions that trigger another exception
1287 * or a recursion will happen.
1288 */
1289 void armv8_dpm_handle_exception(struct arm_dpm *dpm, bool do_restore)
1290 {
1291 struct armv8_common *armv8 = dpm->arm->arch_info;
1292 struct reg_cache *cache = dpm->arm->core_cache;
1293 enum arm_state core_state;
1294 uint64_t dlr;
1295 uint32_t dspsr;
1296 unsigned int el;
1297
1298 static const int clobbered_regs_by_el[3][5] = {
1299 { ARMV8_PC, ARMV8_XPSR, ARMV8_ELR_EL1, ARMV8_ESR_EL1, ARMV8_SPSR_EL1 },
1300 { ARMV8_PC, ARMV8_XPSR, ARMV8_ELR_EL2, ARMV8_ESR_EL2, ARMV8_SPSR_EL2 },
1301 { ARMV8_PC, ARMV8_XPSR, ARMV8_ELR_EL3, ARMV8_ESR_EL3, ARMV8_SPSR_EL3 },
1302 };
1303
1304 el = (dpm->dscr >> 8) & 3;
1305
1306 /* safety check, must not happen since EL0 cannot be a target for an exception */
1307 if (el < SYSTEM_CUREL_EL1 || el > SYSTEM_CUREL_EL3) {
1308 LOG_ERROR("%s: EL %i is invalid, DSCR corrupted?", __func__, el);
1309 return;
1310 }
1311
1312 /* Clear sticky error */
1313 mem_ap_write_u32(armv8->debug_ap,
1314 armv8->debug_base + CPUV8_DBG_DRCR, DRCR_CSE);
1315
1316 armv8->read_reg_u64(armv8, ARMV8_XPSR, &dlr);
1317 dspsr = dlr;
1318 armv8->read_reg_u64(armv8, ARMV8_PC, &dlr);
1319
1320 LOG_DEBUG("Exception taken to EL %i, DLR=0x%016"PRIx64" DSPSR=0x%08"PRIx32,
1321 el, dlr, dspsr);
1322
1323 /* mark all clobbered registers as dirty */
1324 for (int i = 0; i < 5; i++)
1325 cache->reg_list[clobbered_regs_by_el[el-1][i]].dirty = true;
1326
1327 /*
1328 * re-evaluate the core state, we might be in Aarch64 state now
1329 * we rely on dpm->dscr being up-to-date
1330 */
1331 core_state = armv8_dpm_get_core_state(dpm);
1332 armv8_select_opcodes(armv8, core_state == ARM_STATE_AARCH64);
1333 armv8_select_reg_access(armv8, core_state == ARM_STATE_AARCH64);
1334
1335 if (do_restore)
1336 armv8_dpm_modeswitch(dpm, ARM_MODE_ANY);
1337 }
1338
1339 /*----------------------------------------------------------------------*/
1340
1341 /*
1342 * Other debug and support utilities
1343 */
1344
1345 void armv8_dpm_report_dscr(struct arm_dpm *dpm, uint32_t dscr)
1346 {
1347 struct target *target = dpm->arm->target;
1348
1349 dpm->dscr = dscr;
1350 dpm->last_el = (dscr >> 8) & 3;
1351
1352 /* Examine debug reason */
1353 switch (DSCR_ENTRY(dscr)) {
1354 /* FALL THROUGH -- assume a v6 core in abort mode */
1355 case DSCRV8_ENTRY_EXT_DEBUG: /* EDBGRQ */
1356 target->debug_reason = DBG_REASON_DBGRQ;
1357 break;
1358 case DSCRV8_ENTRY_HALT_STEP_EXECLU: /* HALT step */
1359 case DSCRV8_ENTRY_HALT_STEP_NORMAL: /* Halt step*/
1360 case DSCRV8_ENTRY_HALT_STEP:
1361 target->debug_reason = DBG_REASON_SINGLESTEP;
1362 break;
1363 case DSCRV8_ENTRY_HLT: /* HLT instruction (software breakpoint) */
1364 case DSCRV8_ENTRY_BKPT: /* SW BKPT (?) */
1365 case DSCRV8_ENTRY_RESET_CATCH: /* Reset catch */
1366 case DSCRV8_ENTRY_OS_UNLOCK: /*OS unlock catch*/
1367 case DSCRV8_ENTRY_SW_ACCESS_DBG: /*SW access dbg register*/
1368 target->debug_reason = DBG_REASON_BREAKPOINT;
1369 break;
1370 case DSCRV8_ENTRY_WATCHPOINT: /* asynch watchpoint */
1371 target->debug_reason = DBG_REASON_WATCHPOINT;
1372 break;
1373 case DSCRV8_ENTRY_EXCEPTION_CATCH: /*exception catch*/
1374 target->debug_reason = DBG_REASON_EXC_CATCH;
1375 break;
1376 default:
1377 target->debug_reason = DBG_REASON_UNDEFINED;
1378 break;
1379 }
1380
1381 }
1382
1383 /*----------------------------------------------------------------------*/
1384
1385 /*
1386 * Setup and management support.
1387 */
1388
1389 /**
1390 * Hooks up this DPM to its associated target; call only once.
1391 * Initially this only covers the register cache.
1392 *
1393 * Oh, and watchpoints. Yeah.
1394 */
1395 int armv8_dpm_setup(struct arm_dpm *dpm)
1396 {
1397 struct arm *arm = dpm->arm;
1398 struct target *target = arm->target;
1399 struct reg_cache *cache;
1400 arm->dpm = dpm;
1401
1402 /* register access setup */
1403 arm->full_context = armv8_dpm_full_context;
1404 arm->read_core_reg = armv8_dpm_read_core_reg;
1405 arm->write_core_reg = armv8_dpm_write_core_reg;
1406
1407 if (!arm->core_cache) {
1408 cache = armv8_build_reg_cache(target);
1409 if (!cache)
1410 return ERROR_FAIL;
1411 }
1412
1413 /* coprocessor access setup */
1414 arm->mrc = dpmv8_mrc;
1415 arm->mcr = dpmv8_mcr;
1416
1417 dpm->prepare = dpmv8_dpm_prepare;
1418 dpm->finish = dpmv8_dpm_finish;
1419
1420 dpm->instr_execute = dpmv8_instr_execute;
1421 dpm->instr_write_data_dcc = dpmv8_instr_write_data_dcc;
1422 dpm->instr_write_data_dcc_64 = dpmv8_instr_write_data_dcc_64;
1423 dpm->instr_write_data_r0 = dpmv8_instr_write_data_r0;
1424 dpm->instr_write_data_r0_64 = dpmv8_instr_write_data_r0_64;
1425 dpm->instr_cpsr_sync = dpmv8_instr_cpsr_sync;
1426
1427 dpm->instr_read_data_dcc = dpmv8_instr_read_data_dcc;
1428 dpm->instr_read_data_dcc_64 = dpmv8_instr_read_data_dcc_64;
1429 dpm->instr_read_data_r0 = dpmv8_instr_read_data_r0;
1430 dpm->instr_read_data_r0_64 = dpmv8_instr_read_data_r0_64;
1431
1432 dpm->arm_reg_current = armv8_reg_current;
1433
1434 /* dpm->bpwp_enable = dpmv8_bpwp_enable; */
1435 dpm->bpwp_disable = dpmv8_bpwp_disable;
1436
1437 /* breakpoint setup -- optional until it works everywhere */
1438 if (!target->type->add_breakpoint) {
1439 target->type->add_breakpoint = dpmv8_add_breakpoint;
1440 target->type->remove_breakpoint = dpmv8_remove_breakpoint;
1441 }
1442
1443 /* watchpoint setup */
1444 if (!target->type->add_watchpoint) {
1445 target->type->add_watchpoint = dpmv8_add_watchpoint;
1446 target->type->remove_watchpoint = dpmv8_remove_watchpoint;
1447 }
1448
1449 /* FIXME add vector catch support */
1450
1451 dpm->nbp = 1 + ((dpm->didr >> 12) & 0xf);
1452 dpm->dbp = calloc(dpm->nbp, sizeof(*dpm->dbp));
1453
1454 dpm->nwp = 1 + ((dpm->didr >> 20) & 0xf);
1455 dpm->dwp = calloc(dpm->nwp, sizeof(*dpm->dwp));
1456
1457 if (!dpm->dbp || !dpm->dwp) {
1458 free(dpm->dbp);
1459 free(dpm->dwp);
1460 return ERROR_FAIL;
1461 }
1462
1463 LOG_INFO("%s: hardware has %d breakpoints, %d watchpoints",
1464 target_name(target), dpm->nbp, dpm->nwp);
1465
1466 /* REVISIT ... and some of those breakpoints could match
1467 * execution context IDs...
1468 */
1469
1470 return ERROR_OK;
1471 }
1472
1473 /**
1474 * Reinitializes DPM state at the beginning of a new debug session
1475 * or after a reset which may have affected the debug module.
1476 */
1477 int armv8_dpm_initialize(struct arm_dpm *dpm)
1478 {
1479 /* Disable all breakpoints and watchpoints at startup. */
1480 if (dpm->bpwp_disable) {
1481 unsigned i;
1482
1483 for (i = 0; i < dpm->nbp; i++) {
1484 dpm->dbp[i].bpwp.number = i;
1485 (void) dpm->bpwp_disable(dpm, i);
1486 }
1487 for (i = 0; i < dpm->nwp; i++) {
1488 dpm->dwp[i].bpwp.number = 16 + i;
1489 (void) dpm->bpwp_disable(dpm, 16 + i);
1490 }
1491 } else
1492 LOG_WARNING("%s: can't disable breakpoints and watchpoints",
1493 target_name(dpm->arm->target));
1494
1495 return ERROR_OK;
1496 }

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)