OpenOCD
armv8_dpm.c
Go to the documentation of this file.
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 
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 
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);
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 
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 
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 
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 
313  uint32_t opcode, uint64_t data)
314 {
315  struct armv8_common *armv8 = dpm->arm->arch_info;
316  int retval;
317 
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)
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 */
340  if (retval == ERROR_OK)
342  return retval;
343 }
344 
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 
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 
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 */
386  if (retval != ERROR_OK)
387  return retval;
388 
389  return dpmv8_read_dcc(armv8, data, &dpm->dscr);
390 }
391 
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 */
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 int 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 %08" PRIx32 " cr %08" PRIx32, vr, cr);
445 
446  retval = mem_ap_write_atomic_u32(armv8->debug_ap, vr, addr);
447  if (retval != ERROR_OK)
448  return retval;
449  return mem_ap_write_atomic_u32(armv8->debug_ap, cr, control);
450 }
451 #endif
452 
453 static int dpmv8_bpwp_disable(struct arm_dpm *dpm, unsigned int index_t)
454 {
455  struct armv8_common *armv8 = dpm->arm->arch_info;
456  uint32_t cr;
457 
458  switch (index_t) {
459  case 0 ... 15:
460  cr = armv8->debug_base + CPUV8_DBG_BCR_BASE;
461  break;
462  case 16 ... 31:
463  cr = armv8->debug_base + CPUV8_DBG_WCR_BASE;
464  index_t -= 16;
465  break;
466  default:
467  return ERROR_FAIL;
468  }
469  cr += 16 * index_t;
470 
471  LOG_DEBUG("A: bpwp disable, cr %08" PRIx32, cr);
472 
473  /* clear control register */
474  return mem_ap_write_atomic_u32(armv8->debug_ap, cr, 0);
475 }
476 
477 /*
478  * Coprocessor support
479  */
480 
481 /* Read coprocessor */
482 static int dpmv8_mrc(struct target *target, int cpnum,
483  uint32_t op1, uint32_t op2, uint32_t crn, uint32_t crm,
484  uint32_t *value)
485 {
486  struct arm *arm = target_to_arm(target);
487  struct arm_dpm *dpm = arm->dpm;
488  int retval;
489 
490  retval = dpm->prepare(dpm);
491  if (retval != ERROR_OK)
492  return retval;
493 
494  LOG_DEBUG("MRC p%d, %d, r0, c%d, c%d, %d", cpnum,
495  (int) op1, (int) crn,
496  (int) crm, (int) op2);
497 
498  /* read coprocessor register into R0; return via DCC */
499  retval = dpm->instr_read_data_r0(dpm,
500  ARMV4_5_MRC(cpnum, op1, 0, crn, crm, op2),
501  value);
502 
503  dpm->finish(dpm);
504  return retval;
505 }
506 
507 static int dpmv8_mcr(struct target *target, int cpnum,
508  uint32_t op1, uint32_t op2, uint32_t crn, uint32_t crm,
509  uint32_t value)
510 {
511  struct arm *arm = target_to_arm(target);
512  struct arm_dpm *dpm = arm->dpm;
513  int retval;
514 
515  retval = dpm->prepare(dpm);
516  if (retval != ERROR_OK)
517  return retval;
518 
519  LOG_DEBUG("MCR p%d, %d, r0, c%d, c%d, %d", cpnum,
520  (int) op1, (int) crn,
521  (int) crm, (int) op2);
522 
523  /* read DCC into r0; then write coprocessor register from R0 */
524  retval = dpm->instr_write_data_r0(dpm,
525  ARMV4_5_MCR(cpnum, op1, 0, crn, crm, op2),
526  value);
527 
528  dpm->finish(dpm);
529  return retval;
530 }
531 
532 /*----------------------------------------------------------------------*/
533 
534 /*
535  * Register access utilities
536  */
537 
539 {
540  struct armv8_common *armv8 = (struct armv8_common *)dpm->arm->arch_info;
541  int retval = ERROR_OK;
542  unsigned int target_el;
543  enum arm_state core_state;
544  uint32_t cpsr;
545 
546  /* restore previous mode */
547  if (mode == ARM_MODE_ANY) {
548  cpsr = buf_get_u32(dpm->arm->cpsr->value, 0, 32);
549 
550  LOG_DEBUG("restoring mode, cpsr = 0x%08"PRIx32, cpsr);
551 
552  } else {
553  LOG_DEBUG("setting mode 0x%x", mode);
554  cpsr = mode;
555  }
556 
557  switch (cpsr & 0x1f) {
558  /* aarch32 modes */
559  case ARM_MODE_USR:
560  target_el = 0;
561  break;
562  case ARM_MODE_SVC:
563  case ARM_MODE_ABT:
564  case ARM_MODE_IRQ:
565  case ARM_MODE_FIQ:
566  case ARM_MODE_SYS:
567  target_el = 1;
568  break;
569  /*
570  * TODO: handle ARM_MODE_HYP
571  * case ARM_MODE_HYP:
572  * target_el = 2;
573  * break;
574  */
575  case ARM_MODE_MON:
576  target_el = 3;
577  break;
578  /* aarch64 modes */
579  default:
580  target_el = (cpsr >> 2) & 3;
581  }
582 
583  if (target_el > SYSTEM_CUREL_EL3) {
584  LOG_ERROR("%s: Invalid target exception level %i", __func__, target_el);
585  return ERROR_FAIL;
586  }
587 
588  LOG_DEBUG("target_el = %i, last_el = %i", target_el, dpm->last_el);
589  if (dpm->last_el == target_el)
590  return ERROR_OK; /* nothing to do */
591 
592  if (target_el > dpm->last_el) {
593  retval = dpm->instr_execute(dpm,
594  armv8_opcode(armv8, ARMV8_OPC_DCPS) | target_el);
595 
596  /* DCPS clobbers registers just like an exception taken */
598  } else {
599  core_state = armv8_dpm_get_core_state(dpm);
600  if (core_state != ARM_STATE_AARCH64) {
601  /* cannot do DRPS/ERET when already in EL0 */
602  if (dpm->last_el != 0) {
603  /* load SPSR with the desired mode and execute DRPS */
604  LOG_DEBUG("SPSR = 0x%08"PRIx32, cpsr);
605  retval = dpm->instr_write_data_r0(dpm,
606  ARMV8_MSR_GP_XPSR_T1(1, 0, 15), cpsr);
607  if (retval == ERROR_OK)
608  retval = dpm->instr_execute(dpm, armv8_opcode(armv8, ARMV8_OPC_DRPS));
609  }
610  } else {
611  /*
612  * need to execute multiple DRPS instructions until target_el
613  * is reached
614  */
615  while (retval == ERROR_OK && dpm->last_el != target_el) {
616  unsigned int cur_el = dpm->last_el;
617  retval = dpm->instr_execute(dpm, armv8_opcode(armv8, ARMV8_OPC_DRPS));
618  if (cur_el == dpm->last_el) {
619  LOG_INFO("Cannot reach EL %i, SPSR corrupted?", target_el);
620  break;
621  }
622  }
623  }
624 
625  /* On executing DRPS, DSPSR and DLR become UNKNOWN, mark them as dirty */
626  dpm->arm->cpsr->dirty = true;
627  dpm->arm->pc->dirty = true;
628 
629  /*
630  * re-evaluate the core state, we might be in Aarch32 state now
631  * we rely on dpm->dscr being up-to-date
632  */
633  core_state = armv8_dpm_get_core_state(dpm);
634  armv8_select_opcodes(armv8, core_state == ARM_STATE_AARCH64);
635  armv8_select_reg_access(armv8, core_state == ARM_STATE_AARCH64);
636  }
637 
638  return retval;
639 }
640 
641 /*
642  * Common register read, relies on armv8_select_reg_access() having been called.
643  */
644 static int dpmv8_read_reg(struct arm_dpm *dpm, struct reg *r, unsigned int regnum)
645 {
646  struct armv8_common *armv8 = dpm->arm->arch_info;
647  int retval = ERROR_FAIL;
648 
649  if (r->size <= 64) {
650  uint64_t value_64;
651  retval = armv8->read_reg_u64(armv8, regnum, &value_64);
652 
653  if (retval == ERROR_OK) {
654  r->valid = true;
655  r->dirty = false;
656  buf_set_u64(r->value, 0, r->size, value_64);
657  if (r->size == 64)
658  LOG_DEBUG("READ: %s, %16.8llx", r->name, (unsigned long long) value_64);
659  else
660  LOG_DEBUG("READ: %s, %8.8x", r->name, (unsigned int) value_64);
661  }
662  } else if (r->size <= 128) {
663  uint64_t lvalue = 0, hvalue = 0;
664  retval = armv8->read_reg_u128(armv8, regnum, &lvalue, &hvalue);
665 
666  if (retval == ERROR_OK) {
667  r->valid = true;
668  r->dirty = false;
669 
670  buf_set_u64(r->value, 0, 64, lvalue);
671  buf_set_u64(r->value + 8, 0, r->size - 64, hvalue);
672 
673  LOG_DEBUG("READ: %s, lvalue=%16.8llx", r->name, (unsigned long long) lvalue);
674  LOG_DEBUG("READ: %s, hvalue=%16.8llx", r->name, (unsigned long long) hvalue);
675  }
676  }
677 
678  if (retval != ERROR_OK)
679  LOG_DEBUG("Failed to read %s register", r->name);
680 
681  return retval;
682 }
683 
684 /*
685  * Common register write, relies on armv8_select_reg_access() having been called.
686  */
687 static int dpmv8_write_reg(struct arm_dpm *dpm, struct reg *r, unsigned int regnum)
688 {
689  struct armv8_common *armv8 = dpm->arm->arch_info;
690  int retval = ERROR_FAIL;
691 
692  if (r->size <= 64) {
693  uint64_t value_64;
694 
695  value_64 = buf_get_u64(r->value, 0, r->size);
696  retval = armv8->write_reg_u64(armv8, regnum, value_64);
697 
698  if (retval == ERROR_OK) {
699  r->dirty = false;
700  if (r->size == 64)
701  LOG_DEBUG("WRITE: %s, %16.8llx", r->name, (unsigned long long)value_64);
702  else
703  LOG_DEBUG("WRITE: %s, %8.8x", r->name, (unsigned int)value_64);
704  }
705  } else if (r->size <= 128) {
706  uint64_t lvalue, hvalue;
707 
708  lvalue = buf_get_u64(r->value, 0, 64);
709  hvalue = buf_get_u64(r->value + 8, 0, r->size - 64);
710  retval = armv8->write_reg_u128(armv8, regnum, lvalue, hvalue);
711 
712  if (retval == ERROR_OK) {
713  r->dirty = false;
714 
715  LOG_DEBUG("WRITE: %s, lvalue=%16.8llx", r->name, (unsigned long long) lvalue);
716  LOG_DEBUG("WRITE: %s, hvalue=%16.8llx", r->name, (unsigned long long) hvalue);
717  }
718  }
719 
720  if (retval != ERROR_OK)
721  LOG_DEBUG("Failed to write %s register", r->name);
722 
723  return retval;
724 }
725 
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  /* read the remaining registers that would be required by GDB 'g' packet */
776  for (unsigned int i = ARMV8_R2; i <= ARMV8_PC ; i++) {
777  struct arm_reg *arm_reg;
778 
779  /* in AArch32 skip AArch64 registers */
780  /* TODO: this should be detected below through arm_reg->mode */
781  if (arm->core_state != ARM_STATE_AARCH64 && i > ARMV8_R14 && i < ARMV8_PC)
782  continue;
783 
784  r = armv8_reg_current(arm, i);
785  if (!r->exist || 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 &&
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, bool *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 
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  */
890  for (unsigned int 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->is_set : NULL);
896  if (retval != ERROR_OK)
897  goto done;
898  }
899  }
900 
901  /* enable/disable watchpoints */
902  for (unsigned int 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->is_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 int i = 1; i < cache->num_regs; i++) {
923  struct arm_reg *r;
924 
925  /* skip non-existent */
926  if (!cache->reg_list[i].exist)
927  continue;
928  /* skip PC and CPSR */
929  if (i == ARMV8_PC || i == ARMV8_XPSR)
930  continue;
931  /* skip invalid */
932  if (!cache->reg_list[i].valid)
933  continue;
934  /* skip non-dirty */
935  if (!cache->reg_list[i].dirty)
936  continue;
937 
938  /* skip all registers not on the current EL */
939  r = cache->reg_list[i].arch_info;
940  if (r->mode != ARM_MODE_ANY &&
942  continue;
943 
944  retval = dpmv8_write_reg(dpm, &cache->reg_list[i], i);
945  if (retval != ERROR_OK)
946  break;
947  }
948 
949  /* flush CPSR and PC */
950  if (retval == ERROR_OK)
951  retval = dpmv8_write_reg(dpm, &cache->reg_list[ARMV8_XPSR], ARMV8_XPSR);
952  if (retval == ERROR_OK)
953  retval = dpmv8_write_reg(dpm, &cache->reg_list[ARMV8_PC], ARMV8_PC);
954  /* flush R0 -- it's *very* dirty by now */
955  if (retval == ERROR_OK)
956  retval = dpmv8_write_reg(dpm, &cache->reg_list[0], 0);
957  if (retval == ERROR_OK)
958  dpm->instr_cpsr_sync(dpm);
959 done:
960  dpm->finish(dpm);
961  return retval;
962 }
963 
964 /*
965  * Standard ARM register accessors ... there are three methods
966  * in "struct arm", to support individual read/write and bulk read
967  * of registers.
968  */
969 
970 static int armv8_dpm_read_core_reg(struct target *target, struct reg *r,
971  int regnum, enum arm_mode mode)
972 {
973  struct arm *arm = target_to_arm(target);
974  struct arm_dpm *dpm = target_to_arm(target)->dpm;
975  int retval;
976  int max = arm->core_cache->num_regs;
977 
978  if (regnum < 0 || regnum >= max)
980 
981  /*
982  * REVISIT what happens if we try to read SPSR in a core mode
983  * which has no such register?
984  */
985  retval = dpm->prepare(dpm);
986  if (retval != ERROR_OK)
987  return retval;
988 
989  retval = dpmv8_read_reg(dpm, r, regnum);
990  if (retval != ERROR_OK)
991  goto fail;
992 
993 fail:
994  dpm->finish(dpm);
995  return retval;
996 }
997 
998 static int armv8_dpm_write_core_reg(struct target *target, struct reg *r,
999  int regnum, enum arm_mode mode, uint8_t *value)
1000 {
1001  struct arm *arm = target_to_arm(target);
1002  struct arm_dpm *dpm = target_to_arm(target)->dpm;
1003  int retval;
1004  int max = arm->core_cache->num_regs;
1005 
1006  if (regnum < 0 || regnum > max)
1008 
1009  /* REVISIT what happens if we try to write SPSR in a core mode
1010  * which has no such register?
1011  */
1012 
1013  retval = dpm->prepare(dpm);
1014  if (retval != ERROR_OK)
1015  return retval;
1016 
1017  retval = dpmv8_write_reg(dpm, r, regnum);
1018 
1019  /* always clean up, regardless of error */
1020  dpm->finish(dpm);
1021 
1022  return retval;
1023 }
1024 
1026 {
1027  struct arm *arm = target_to_arm(target);
1028  struct arm_dpm *dpm = arm->dpm;
1029  struct reg_cache *cache = arm->core_cache;
1030  int retval;
1031  bool did_read;
1032 
1033  retval = dpm->prepare(dpm);
1034  if (retval != ERROR_OK)
1035  goto done;
1036 
1037  do {
1038  enum arm_mode mode = ARM_MODE_ANY;
1039 
1040  did_read = false;
1041 
1042  /* We "know" arm_dpm_read_current_registers() was called so
1043  * the unmapped registers (R0..R7, PC, AND CPSR) and some
1044  * view of R8..R14 are current. We also "know" oddities of
1045  * register mapping: special cases for R8..R12 and SPSR.
1046  *
1047  * Pick some mode with unread registers and read them all.
1048  * Repeat until done.
1049  */
1050  for (unsigned int i = 0; i < cache->num_regs; i++) {
1051  struct arm_reg *r;
1052 
1053  if (!cache->reg_list[i].exist || cache->reg_list[i].valid)
1054  continue;
1055  r = cache->reg_list[i].arch_info;
1056 
1057  /* may need to pick a mode and set CPSR */
1058  if (!did_read) {
1059  did_read = true;
1060  mode = r->mode;
1061 
1062  /* For regular (ARM_MODE_ANY) R8..R12
1063  * in case we've entered debug state
1064  * in FIQ mode we need to patch mode.
1065  */
1066  if (mode != ARM_MODE_ANY)
1067  retval = armv8_dpm_modeswitch(dpm, mode);
1068  else
1069  retval = armv8_dpm_modeswitch(dpm, ARM_MODE_USR);
1070 
1071  if (retval != ERROR_OK)
1072  goto done;
1073  }
1074  if (r->mode != mode)
1075  continue;
1076 
1077  /* CPSR was read, so "R16" must mean SPSR */
1078  retval = dpmv8_read_reg(dpm,
1079  &cache->reg_list[i],
1080  (r->num == 16) ? 17 : r->num);
1081  if (retval != ERROR_OK)
1082  goto done;
1083  }
1084 
1085  } while (did_read);
1086 
1087  retval = armv8_dpm_modeswitch(dpm, ARM_MODE_ANY);
1088  dpm->finish(dpm);
1089 done:
1090  return retval;
1091 }
1092 
1093 
1094 /*----------------------------------------------------------------------*/
1095 
1096 /*
1097  * Breakpoint and Watchpoint support.
1098  *
1099  * Hardware {break,watch}points are usually left active, to minimize
1100  * debug entry/exit costs. When they are set or cleared, it's done in
1101  * batches. Also, DPM-conformant hardware can update debug registers
1102  * regardless of whether the CPU is running or halted ... though that
1103  * fact isn't currently leveraged.
1104  */
1105 
1106 static int dpmv8_bpwp_setup(struct arm_dpm *dpm, struct dpm_bpwp *xp,
1107  uint32_t addr, uint32_t length)
1108 {
1109  uint32_t control;
1110 
1111  control = (1 << 0) /* enable */
1112  | (3 << 1); /* both user and privileged access */
1113 
1114  /* Match 1, 2, or all 4 byte addresses in this word.
1115  *
1116  * FIXME: v7 hardware allows lengths up to 2 GB for BP and WP.
1117  * Support larger length, when addr is suitably aligned. In
1118  * particular, allow watchpoints on 8 byte "double" values.
1119  *
1120  * REVISIT allow watchpoints on unaligned 2-bit values; and on
1121  * v7 hardware, unaligned 4-byte ones too.
1122  */
1123  switch (length) {
1124  case 1:
1125  control |= (1 << (addr & 3)) << 5;
1126  break;
1127  case 2:
1128  /* require 2-byte alignment */
1129  if (!(addr & 1)) {
1130  control |= (3 << (addr & 2)) << 5;
1131  break;
1132  }
1133  /* FALL THROUGH */
1134  case 4:
1135  /* require 4-byte alignment */
1136  if (!(addr & 3)) {
1137  control |= 0xf << 5;
1138  break;
1139  }
1140  /* FALL THROUGH */
1141  default:
1142  LOG_ERROR("unsupported {break,watch}point length/alignment");
1144  }
1145 
1146  /* other shared control bits:
1147  * bits 15:14 == 0 ... both secure and nonsecure states (v6.1+ only)
1148  * bit 20 == 0 ... not linked to a context ID
1149  * bit 28:24 == 0 ... not ignoring N LSBs (v7 only)
1150  */
1151 
1152  xp->address = addr & ~3;
1153  xp->control = control;
1154  xp->dirty = true;
1155 
1156  LOG_DEBUG("BPWP: addr %8.8" PRIx32 ", control %" PRIx32 ", number %d",
1157  xp->address, control, xp->number);
1158 
1159  /* hardware is updated in write_dirty_registers() */
1160  return ERROR_OK;
1161 }
1162 
1163 static int dpmv8_add_breakpoint(struct target *target, struct breakpoint *bp)
1164 {
1165  struct arm *arm = target_to_arm(target);
1166  struct arm_dpm *dpm = arm->dpm;
1168 
1169  if (bp->length < 2)
1171  if (!dpm->bpwp_enable)
1172  return retval;
1173 
1174  /* FIXME we need a generic solution for software breakpoints. */
1175  if (bp->type == BKPT_SOFT)
1176  LOG_DEBUG("using HW bkpt, not SW...");
1177 
1178  for (unsigned int i = 0; i < dpm->nbp; i++) {
1179  if (!dpm->dbp[i].bp) {
1180  retval = dpmv8_bpwp_setup(dpm, &dpm->dbp[i].bpwp,
1181  bp->address, bp->length);
1182  if (retval == ERROR_OK)
1183  dpm->dbp[i].bp = bp;
1184  break;
1185  }
1186  }
1187 
1188  return retval;
1189 }
1190 
1191 static int dpmv8_remove_breakpoint(struct target *target, struct breakpoint *bp)
1192 {
1193  struct arm *arm = target_to_arm(target);
1194  struct arm_dpm *dpm = arm->dpm;
1195  int retval = ERROR_COMMAND_SYNTAX_ERROR;
1196 
1197  for (unsigned int i = 0; i < dpm->nbp; i++) {
1198  if (dpm->dbp[i].bp == bp) {
1199  dpm->dbp[i].bp = NULL;
1200  dpm->dbp[i].bpwp.dirty = true;
1201 
1202  /* hardware is updated in write_dirty_registers() */
1203  retval = ERROR_OK;
1204  break;
1205  }
1206  }
1207 
1208  return retval;
1209 }
1210 
1211 static int dpmv8_watchpoint_setup(struct arm_dpm *dpm, unsigned int index_t,
1212  struct watchpoint *wp)
1213 {
1214  int retval;
1215  struct dpm_wp *dwp = dpm->dwp + index_t;
1216  uint32_t control;
1217 
1218  /* this hardware doesn't support data value matching or masking */
1220  LOG_DEBUG("watchpoint values and masking not supported");
1222  }
1223 
1224  retval = dpmv8_bpwp_setup(dpm, &dwp->bpwp, wp->address, wp->length);
1225  if (retval != ERROR_OK)
1226  return retval;
1227 
1228  control = dwp->bpwp.control;
1229  switch (wp->rw) {
1230  case WPT_READ:
1231  control |= 1 << 3;
1232  break;
1233  case WPT_WRITE:
1234  control |= 2 << 3;
1235  break;
1236  case WPT_ACCESS:
1237  control |= 3 << 3;
1238  break;
1239  }
1240  dwp->bpwp.control = control;
1241 
1242  dpm->dwp[index_t].wp = wp;
1243 
1244  return retval;
1245 }
1246 
1247 static int dpmv8_add_watchpoint(struct target *target, struct watchpoint *wp)
1248 {
1249  struct arm *arm = target_to_arm(target);
1250  struct arm_dpm *dpm = arm->dpm;
1252 
1253  if (dpm->bpwp_enable) {
1254  for (unsigned int i = 0; i < dpm->nwp; i++) {
1255  if (!dpm->dwp[i].wp) {
1256  retval = dpmv8_watchpoint_setup(dpm, i, wp);
1257  break;
1258  }
1259  }
1260  }
1261 
1262  return retval;
1263 }
1264 
1265 static int dpmv8_remove_watchpoint(struct target *target, struct watchpoint *wp)
1266 {
1267  struct arm *arm = target_to_arm(target);
1268  struct arm_dpm *dpm = arm->dpm;
1269  int retval = ERROR_COMMAND_SYNTAX_ERROR;
1270 
1271  for (unsigned int i = 0; i < dpm->nwp; i++) {
1272  if (dpm->dwp[i].wp == wp) {
1273  dpm->dwp[i].wp = NULL;
1274  dpm->dwp[i].bpwp.dirty = true;
1275 
1276  /* hardware is updated in write_dirty_registers() */
1277  retval = ERROR_OK;
1278  break;
1279  }
1280  }
1281 
1282  return retval;
1283 }
1284 
1285 /*
1286  * Handle exceptions taken in debug state. This happens mostly for memory
1287  * accesses that violated a MMU policy. Taking an exception while in debug
1288  * state clobbers certain state registers on the target exception level.
1289  * Just mark those registers dirty so that they get restored on resume.
1290  * This works both for Aarch32 and Aarch64 states.
1291  *
1292  * This function must not perform any actions that trigger another exception
1293  * or a recursion will happen.
1294  */
1295 void armv8_dpm_handle_exception(struct arm_dpm *dpm, bool do_restore)
1296 {
1297  struct armv8_common *armv8 = dpm->arm->arch_info;
1298  struct reg_cache *cache = dpm->arm->core_cache;
1299  enum arm_state core_state;
1300  uint64_t dlr;
1301  uint32_t dspsr;
1302  unsigned int el;
1303 
1304  static const int clobbered_regs_by_el[3][5] = {
1308  };
1309 
1310  el = (dpm->dscr >> 8) & 3;
1311 
1312  /* safety check, must not happen since EL0 cannot be a target for an exception */
1313  if (el < SYSTEM_CUREL_EL1 || el > SYSTEM_CUREL_EL3) {
1314  LOG_ERROR("%s: EL %i is invalid, DSCR corrupted?", __func__, el);
1315  return;
1316  }
1317 
1318  /* Clear sticky error */
1319  mem_ap_write_u32(armv8->debug_ap,
1320  armv8->debug_base + CPUV8_DBG_DRCR, DRCR_CSE);
1321 
1322  armv8->read_reg_u64(armv8, ARMV8_XPSR, &dlr);
1323  dspsr = dlr;
1324  armv8->read_reg_u64(armv8, ARMV8_PC, &dlr);
1325 
1326  LOG_DEBUG("Exception taken to EL %i, DLR=0x%016"PRIx64" DSPSR=0x%08"PRIx32,
1327  el, dlr, dspsr);
1328 
1329  /* mark all clobbered registers as dirty */
1330  for (int i = 0; i < 5; i++)
1331  cache->reg_list[clobbered_regs_by_el[el-1][i]].dirty = true;
1332 
1333  /*
1334  * re-evaluate the core state, we might be in Aarch64 state now
1335  * we rely on dpm->dscr being up-to-date
1336  */
1337  core_state = armv8_dpm_get_core_state(dpm);
1338  armv8_select_opcodes(armv8, core_state == ARM_STATE_AARCH64);
1339  armv8_select_reg_access(armv8, core_state == ARM_STATE_AARCH64);
1340 
1341  if (do_restore)
1343 }
1344 
1345 /*----------------------------------------------------------------------*/
1346 
1347 /*
1348  * Other debug and support utilities
1349  */
1350 
1351 void armv8_dpm_report_dscr(struct arm_dpm *dpm, uint32_t dscr)
1352 {
1353  struct target *target = dpm->arm->target;
1354 
1355  dpm->dscr = dscr;
1356  dpm->last_el = (dscr >> 8) & 3;
1357 
1358  /* Examine debug reason */
1359  switch (DSCR_ENTRY(dscr)) {
1360  /* FALL THROUGH -- assume a v6 core in abort mode */
1361  case DSCRV8_ENTRY_EXT_DEBUG: /* EDBGRQ */
1363  break;
1364  case DSCRV8_ENTRY_HALT_STEP_EXECLU: /* HALT step */
1365  case DSCRV8_ENTRY_HALT_STEP_NORMAL: /* Halt step*/
1368  break;
1369  case DSCRV8_ENTRY_HLT: /* HLT instruction (software breakpoint) */
1370  case DSCRV8_ENTRY_BKPT: /* SW BKPT (?) */
1371  case DSCRV8_ENTRY_RESET_CATCH: /* Reset catch */
1372  case DSCRV8_ENTRY_OS_UNLOCK: /*OS unlock catch*/
1373  case DSCRV8_ENTRY_SW_ACCESS_DBG: /*SW access dbg register*/
1375  break;
1376  case DSCRV8_ENTRY_WATCHPOINT: /* asynch watchpoint */
1378  break;
1379  case DSCRV8_ENTRY_EXCEPTION_CATCH: /*exception catch*/
1381  break;
1382  default:
1384  break;
1385  }
1386 
1387 }
1388 
1389 /*----------------------------------------------------------------------*/
1390 
1391 /*
1392  * Setup and management support.
1393  */
1394 
1401 int armv8_dpm_setup(struct arm_dpm *dpm)
1402 {
1403  struct arm *arm = dpm->arm;
1404  struct target *target = arm->target;
1405  struct reg_cache *cache;
1406  arm->dpm = dpm;
1407 
1408  /* register access setup */
1412 
1413  if (!arm->core_cache) {
1414  cache = armv8_build_reg_cache(target);
1415  if (!cache)
1416  return ERROR_FAIL;
1417  }
1418 
1419  /* coprocessor access setup */
1420  arm->mrc = dpmv8_mrc;
1421  arm->mcr = dpmv8_mcr;
1422 
1423  dpm->prepare = dpmv8_dpm_prepare;
1424  dpm->finish = dpmv8_dpm_finish;
1425 
1432 
1437 
1439 
1440 /* dpm->bpwp_enable = dpmv8_bpwp_enable; */
1442 
1443  /* breakpoint setup -- optional until it works everywhere */
1444  if (!target->type->add_breakpoint) {
1447  }
1448 
1449  /* watchpoint setup */
1450  if (!target->type->add_watchpoint) {
1453  }
1454 
1455  /* FIXME add vector catch support */
1456 
1457  dpm->nbp = 1 + ((dpm->didr >> 12) & 0xf);
1458  dpm->dbp = calloc(dpm->nbp, sizeof(*dpm->dbp));
1459 
1460  dpm->nwp = 1 + ((dpm->didr >> 20) & 0xf);
1461  dpm->dwp = calloc(dpm->nwp, sizeof(*dpm->dwp));
1462 
1463  if (!dpm->dbp || !dpm->dwp) {
1464  free(dpm->dbp);
1465  free(dpm->dwp);
1466  return ERROR_FAIL;
1467  }
1468 
1469  LOG_INFO("%s: hardware has %d breakpoints, %d watchpoints",
1470  target_name(target), dpm->nbp, dpm->nwp);
1471 
1472  /* REVISIT ... and some of those breakpoints could match
1473  * execution context IDs...
1474  */
1475 
1476  return ERROR_OK;
1477 }
1478 
1484 {
1485  /* Disable all breakpoints and watchpoints at startup. */
1486  if (dpm->bpwp_disable) {
1487  unsigned int i;
1488 
1489  for (i = 0; i < dpm->nbp; i++) {
1490  dpm->dbp[i].bpwp.number = i;
1491  (void) dpm->bpwp_disable(dpm, i);
1492  }
1493  for (i = 0; i < dpm->nwp; i++) {
1494  dpm->dwp[i].bpwp.number = 16 + i;
1495  (void) dpm->bpwp_disable(dpm, 16 + i);
1496  }
1497  } else
1498  LOG_WARNING("%s: can't disable breakpoints and watchpoints",
1499  target_name(dpm->arm->target));
1500 
1501  return ERROR_OK;
1502 }
Holds the interface to ARM cores.
struct reg * armv8_reg_current(struct arm *arm, unsigned int regnum)
Definition: armv8.c:1884
arm_mode
Represent state of an ARM core.
Definition: arm.h:82
@ ARM_MODE_IRQ
Definition: arm.h:85
@ ARM_MODE_SYS
Definition: arm.h:92
@ ARM_MODE_MON
Definition: arm.h:87
@ ARM_MODE_FIQ
Definition: arm.h:84
@ ARM_MODE_ANY
Definition: arm.h:106
@ ARM_MODE_USR
Definition: arm.h:83
@ ARM_MODE_SVC
Definition: arm.h:86
@ ARM_MODE_ABT
Definition: arm.h:88
static struct arm * target_to_arm(const struct target *target)
Convert target handle to generic ARM target state handle.
Definition: arm.h:261
arm_state
The PSR "T" and "J" bits define the mode of "classic ARM" cores.
Definition: arm.h:150
@ ARM_STATE_ARM
Definition: arm.h:151
@ ARM_STATE_AARCH64
Definition: arm.h:155
struct reg_cache * armv8_build_reg_cache(struct target *target)
Builds cache of architecturally defined registers.
Definition: armv8.c:1787
int mem_ap_read_u32(struct adiv5_ap *ap, target_addr_t address, uint32_t *value)
Asynchronous (queued) read of a word from memory or a system register.
Definition: arm_adi_v5.c:237
int mem_ap_write_u32(struct adiv5_ap *ap, target_addr_t address, uint32_t value)
Asynchronous (queued) write of a word to memory or a system register.
Definition: arm_adi_v5.c:289
int mem_ap_read_atomic_u32(struct adiv5_ap *ap, target_addr_t address, uint32_t *value)
Synchronous read of a word from memory or a system register.
Definition: arm_adi_v5.c:266
int mem_ap_write_atomic_u32(struct adiv5_ap *ap, target_addr_t address, uint32_t value)
Synchronous write of a word to memory or a system register.
Definition: arm_adi_v5.c:318
#define DSCR_ENTRY(dscr)
Definition: arm_dpm.h:197
#define DSCR_DTR_TX_FULL
Definition: arm_dpm.h:194
#define DSCR_DTR_RX_FULL
Definition: arm_dpm.h:195
#define ARMV4_5_MRC(cp, op1, rd, crn, crm, op2)
Definition: arm_opcodes.h:186
#define ARMV4_5_MCR(cp, op1, rd, crn, crm, op2)
Definition: arm_opcodes.h:209
enum arm_mode mode
Definition: armv4_5.c:277
void armv8_set_cpsr(struct arm *arm, uint32_t cpsr)
Configures host-side ARM records to reflect the specified CPSR.
Definition: armv8.c:924
void armv8_select_reg_access(struct armv8_common *armv8, bool is_aarch64)
Definition: armv8.c:864
#define CPUV8_DBG_DRCR
Definition: armv8.h:262
#define CPUV8_DBG_BVR_BASE
Definition: armv8.h:272
#define CPUV8_DBG_DSCR
Definition: armv8.h:261
#define CPUV8_DBG_DTRTX
Definition: armv8.h:270
#define CPUV8_DBG_WVR_BASE
Definition: armv8.h:274
#define CPUV8_DBG_WCR_BASE
Definition: armv8.h:275
@ ARMV8_R14
Definition: armv8.h:32
@ ARMV8_ESR_EL2
Definition: armv8.h:94
@ ARMV8_R0
Definition: armv8.h:18
@ ARMV8_ESR_EL1
Definition: armv8.h:90
@ ARMV8_R1
Definition: armv8.h:19
@ ARMV8_SPSR_EL3
Definition: armv8.h:99
@ ARMV8_SPSR_EL2
Definition: armv8.h:95
@ ARMV8_ELR_EL3
Definition: armv8.h:97
@ ARMV8_XPSR
Definition: armv8.h:52
@ ARMV8_FPCR
Definition: armv8.h:87
@ ARMV8_PC
Definition: armv8.h:51
@ ARMV8_V0
Definition: armv8.h:54
@ ARMV8_SPSR_EL1
Definition: armv8.h:91
@ ARMV8_ELR_EL2
Definition: armv8.h:93
@ ARMV8_ESR_EL3
Definition: armv8.h:98
@ ARMV8_ELR_EL1
Definition: armv8.h:89
@ ARMV8_R2
Definition: armv8.h:20
static unsigned int armv8_curel_from_core_mode(enum arm_mode core_mode)
Definition: armv8.h:308
#define CPUV8_DBG_ITR
Definition: armv8.h:268
#define CPUV8_DBG_DTRRX
Definition: armv8.h:267
#define CPUV8_DBG_BCR_BASE
Definition: armv8.h:273
static int dpmv8_add_watchpoint(struct target *target, struct watchpoint *wp)
Definition: armv8_dpm.c:1247
void armv8_dpm_report_dscr(struct arm_dpm *dpm, uint32_t dscr)
Definition: armv8_dpm.c:1351
static int dpmv8_instr_execute(struct arm_dpm *dpm, uint32_t opcode)
Definition: armv8_dpm.c:262
static int dpmv8_mcr(struct target *target, int cpnum, uint32_t op1, uint32_t op2, uint32_t crn, uint32_t crm, uint32_t value)
Definition: armv8_dpm.c:507
static int dpmv8_instr_write_data_dcc_64(struct arm_dpm *dpm, uint32_t opcode, uint64_t data)
Definition: armv8_dpm.c:280
static int dpmv8_bpwp_setup(struct arm_dpm *dpm, struct dpm_bpwp *xp, uint32_t addr, uint32_t length)
Definition: armv8_dpm.c:1106
static int armv8_dpm_read_core_reg(struct target *target, struct reg *r, int regnum, enum arm_mode mode)
Definition: armv8_dpm.c:970
static int dpmv8_instr_write_data_r0_64(struct arm_dpm *dpm, uint32_t opcode, uint64_t data)
Definition: armv8_dpm.c:312
int armv8_dpm_write_dirty_registers(struct arm_dpm *dpm, bool bpwp)
Writes all modified core registers for all processor modes.
Definition: armv8_dpm.c:872
static int dpmv8_add_breakpoint(struct target *target, struct breakpoint *bp)
Definition: armv8_dpm.c:1163
static int dpmv8_instr_cpsr_sync(struct arm_dpm *dpm)
Definition: armv8_dpm.c:333
static int dpmv8_read_dcc_64(struct armv8_common *armv8, uint64_t *data, uint32_t *dscr_p)
Definition: armv8_dpm.c:109
static int dpmv8_watchpoint_setup(struct arm_dpm *dpm, unsigned int index_t, struct watchpoint *wp)
Definition: armv8_dpm.c:1211
static int dpmv8_read_reg(struct arm_dpm *dpm, struct reg *r, unsigned int regnum)
Definition: armv8_dpm.c:644
static int dpmv8_instr_read_data_dcc(struct arm_dpm *dpm, uint32_t opcode, uint32_t *data)
Definition: armv8_dpm.c:345
enum arm_state armv8_dpm_get_core_state(struct arm_dpm *dpm)
Get core state from EDSCR, without necessity to retrieve CPSR.
Definition: armv8_dpm.c:41
static int dpmv8_dpm_finish(struct arm_dpm *dpm)
Definition: armv8_dpm.c:191
static int dpmv8_instr_write_data_dcc(struct arm_dpm *dpm, uint32_t opcode, uint32_t data)
Definition: armv8_dpm.c:267
static int dpmv8_write_dcc(struct armv8_common *armv8, uint32_t data)
Definition: armv8_dpm.c:57
int armv8_dpm_read_current_registers(struct arm_dpm *dpm)
Read basic registers of the current context: R0 to R15, and CPSR in AArch32 state or R0 to R31,...
Definition: armv8_dpm.c:734
static int dpmv8_instr_read_data_r0_64(struct arm_dpm *dpm, uint32_t opcode, uint64_t *data)
Definition: armv8_dpm.c:392
static int dpmv8_remove_breakpoint(struct target *target, struct breakpoint *bp)
Definition: armv8_dpm.c:1191
static int dpmv8_write_reg(struct arm_dpm *dpm, struct reg *r, unsigned int regnum)
Definition: armv8_dpm.c:687
int armv8_dpm_initialize(struct arm_dpm *dpm)
Reinitializes DPM state at the beginning of a new debug session or after a reset which may have affec...
Definition: armv8_dpm.c:1483
static int dpmv8_bpwp_disable(struct arm_dpm *dpm, unsigned int index_t)
Definition: armv8_dpm.c:453
static int dpmv8_instr_read_data_dcc_64(struct arm_dpm *dpm, uint32_t opcode, uint64_t *data)
Definition: armv8_dpm.c:359
static int dpmv8_write_dcc_64(struct armv8_common *armv8, uint64_t data)
Definition: armv8_dpm.c:63
static int dpmv8_instr_read_data_r0(struct arm_dpm *dpm, uint32_t opcode, uint32_t *data)
Definition: armv8_dpm.c:373
static int dpmv8_read_dcc(struct armv8_common *armv8, uint32_t *data, uint32_t *dscr_p)
Definition: armv8_dpm.c:74
int armv8_dpm_modeswitch(struct arm_dpm *dpm, enum arm_mode mode)
Definition: armv8_dpm.c:538
static int armv8_dpm_write_core_reg(struct target *target, struct reg *r, int regnum, enum arm_mode mode, uint8_t *value)
Definition: armv8_dpm.c:998
static int dpmv8_maybe_update_bpwp(struct arm_dpm *dpm, bool bpwp, struct dpm_bpwp *xp, bool *set_p)
Definition: armv8_dpm.c:820
void armv8_dpm_handle_exception(struct arm_dpm *dpm, bool do_restore)
Definition: armv8_dpm.c:1295
static int dpmv8_dpm_prepare(struct arm_dpm *dpm)
Definition: armv8_dpm.c:153
int armv8_dpm_setup(struct arm_dpm *dpm)
Hooks up this DPM to its associated target; call only once.
Definition: armv8_dpm.c:1401
static int dpmv8_instr_write_data_r0(struct arm_dpm *dpm, uint32_t opcode, uint32_t data)
Definition: armv8_dpm.c:293
static int dpmv8_mrc(struct target *target, int cpnum, uint32_t op1, uint32_t op2, uint32_t crn, uint32_t crm, uint32_t *value)
Definition: armv8_dpm.c:482
static int dpmv8_remove_watchpoint(struct target *target, struct watchpoint *wp)
Definition: armv8_dpm.c:1265
#define T32_FMTITR(instr)
Definition: armv8_dpm.c:23
static int dpmv8_exec_opcode(struct arm_dpm *dpm, uint32_t opcode, uint32_t *p_dscr)
Definition: armv8_dpm.c:197
static int armv8_dpm_full_context(struct target *target)
Definition: armv8_dpm.c:1025
#define DSCRV8_ENTRY_BKPT
Definition: armv8_dpm.h:60
#define DSCRV8_ENTRY_HALT_STEP
Definition: armv8_dpm.h:70
#define DSCRV8_ENTRY_SW_ACCESS_DBG
Definition: armv8_dpm.h:68
#define DSCRV8_ENTRY_RESET_CATCH
Definition: armv8_dpm.h:65
#define DSCRV8_ENTRY_HALT_STEP_EXECLU
Definition: armv8_dpm.h:63
#define DSCRV8_ENTRY_WATCHPOINT
Definition: armv8_dpm.h:66
#define DSCRV8_ENTRY_HLT
Definition: armv8_dpm.h:67
#define DSCRV8_ENTRY_HALT_STEP_NORMAL
Definition: armv8_dpm.h:62
#define DRCR_CSE
Definition: armv8_dpm.h:74
#define DSCRV8_ENTRY_EXT_DEBUG
Definition: armv8_dpm.h:61
#define DSCRV8_ENTRY_OS_UNLOCK
Definition: armv8_dpm.h:64
#define DSCRV8_ENTRY_EXCEPTION_CATCH
Definition: armv8_dpm.h:69
#define DSCR_ERR
Definition: armv8_dpm.h:37
#define DSCR_ITE
Definition: armv8_dpm.h:47
void armv8_select_opcodes(struct armv8_common *armv8, bool state_is_aarch64)
Definition: armv8_opcodes.c:73
#define ARMV8_MSR_GP(system, rt)
#define SYSTEM_CUREL_EL3
Definition: armv8_opcodes.h:17
#define ARMV8_MRS(system, rt)
#define ARMV8_MSR_GP_XPSR_T1(r, rn, mask)
armv8_opcode
@ ARMV8_OPC_ISB_SY
@ WRITE_REG_DTRTX
@ READ_REG_DSPSR
@ READ_REG_DTRRX
@ ARMV8_OPC_DCPS
@ ARMV8_OPC_DRPS
@ ARMV8_OPC_DSB_SY
#define SYSTEM_DBG_DBGDTR_EL0
Definition: armv8_opcodes.h:64
static uint32_t buf_get_u32(const uint8_t *_buffer, unsigned int first, unsigned int num)
Retrieves num bits from _buffer, starting at the first bit, returning the bits in a 32-bit word.
Definition: binarybuffer.h:104
static uint64_t buf_get_u64(const uint8_t *_buffer, unsigned int first, unsigned int num)
Retrieves num bits from _buffer, starting at the first bit, returning the bits in a 64-bit word.
Definition: binarybuffer.h:134
static void buf_set_u64(uint8_t *_buffer, unsigned int first, unsigned int num, uint64_t value)
Sets num bits in _buffer, starting at the first bit, using the bits in value.
Definition: binarybuffer.h:65
@ BKPT_SOFT
Definition: breakpoints.h:19
#define WATCHPOINT_IGNORE_DATA_VALUE_MASK
Definition: breakpoints.h:39
@ WPT_ACCESS
Definition: breakpoints.h:23
@ WPT_READ
Definition: breakpoints.h:23
@ WPT_WRITE
Definition: breakpoints.h:23
#define ERROR_COMMAND_SYNTAX_ERROR
Definition: command.h:402
uint8_t length
Definition: esp_usb_jtag.c:1
The JTAG interface can be implemented with a software or hardware fifo.
#define LOG_WARNING(expr ...)
Definition: log.h:129
#define ERROR_FAIL
Definition: log.h:170
#define LOG_ERROR(expr ...)
Definition: log.h:132
#define LOG_INFO(expr ...)
Definition: log.h:126
#define LOG_DEBUG(expr ...)
Definition: log.h:109
#define ERROR_OK
Definition: log.h:164
target_addr_t addr
Start address to search for the control block.
Definition: rtt/rtt.c:28
This wraps an implementation of DPM primitives.
Definition: arm_dpm.h:47
int(* instr_read_data_dcc)(struct arm_dpm *dpm, uint32_t opcode, uint32_t *data)
Runs one instruction, reading data from dcc after execution.
Definition: arm_dpm.h:91
uint64_t didr
Cache of DIDR.
Definition: arm_dpm.h:51
int(* instr_write_data_r0_64)(struct arm_dpm *dpm, uint32_t opcode, uint64_t data)
Runs one instruction, writing data to R0 before execution.
Definition: arm_dpm.h:82
int(* instr_read_data_dcc_64)(struct arm_dpm *dpm, uint32_t opcode, uint64_t *data)
Definition: arm_dpm.h:94
int(* instr_execute)(struct arm_dpm *dpm, uint32_t opcode)
Runs one instruction.
Definition: arm_dpm.h:60
int(* instr_write_data_dcc_64)(struct arm_dpm *dpm, uint32_t opcode, uint64_t data)
Definition: arm_dpm.h:68
int(* instr_write_data_r0)(struct arm_dpm *dpm, uint32_t opcode, uint32_t data)
Runs one instruction, writing data to R0 before execution.
Definition: arm_dpm.h:72
struct arm * arm
Definition: arm_dpm.h:48
int(* bpwp_enable)(struct arm_dpm *dpm, unsigned int index_value, uint32_t addr, uint32_t control)
Enables one breakpoint or watchpoint by writing to the hardware registers.
Definition: arm_dpm.h:122
int(* finish)(struct arm_dpm *dpm)
Invoke after a series of instruction operations.
Definition: arm_dpm.h:57
struct dpm_bp * dbp
Definition: arm_dpm.h:139
unsigned int last_el
Recent exception level on armv8.
Definition: arm_dpm.h:153
int(* instr_write_data_dcc)(struct arm_dpm *dpm, uint32_t opcode, uint32_t data)
Runs one instruction, writing data to DCC before execution.
Definition: arm_dpm.h:65
unsigned int nwp
Definition: arm_dpm.h:138
int(* prepare)(struct arm_dpm *dpm)
Invoke before a series of instruction operations.
Definition: arm_dpm.h:54
int(* instr_read_data_r0)(struct arm_dpm *dpm, uint32_t opcode, uint32_t *data)
Runs one instruction, reading data from r0 after execution.
Definition: arm_dpm.h:98
int(* instr_read_data_r0_64)(struct arm_dpm *dpm, uint32_t opcode, uint64_t *data)
Definition: arm_dpm.h:108
struct reg *(* arm_reg_current)(struct arm *arm, unsigned int regnum)
Definition: arm_dpm.h:111
unsigned int nbp
Definition: arm_dpm.h:137
struct dpm_wp * dwp
Definition: arm_dpm.h:140
int(* bpwp_disable)(struct arm_dpm *dpm, unsigned int index_value)
Disables one breakpoint or watchpoint by clearing its hardware control registers.
Definition: arm_dpm.h:130
int(* instr_cpsr_sync)(struct arm_dpm *dpm)
Optional core-specific operation invoked after CPSR writes.
Definition: arm_dpm.h:86
uint32_t dscr
Recent value of DSCR.
Definition: arm_dpm.h:150
Definition: arm.h:280
int num
Definition: arm.h:281
enum arm_mode mode
Definition: arm.h:282
Represents a generic ARM core, with standard application registers.
Definition: arm.h:175
int(* full_context)(struct target *target)
Retrieve all core registers, for display.
Definition: arm.h:221
void * arch_info
Definition: arm.h:251
int(* mrc)(struct target *target, int cpnum, uint32_t op1, uint32_t op2, uint32_t crn, uint32_t crm, uint32_t *value)
Read coprocessor register.
Definition: arm.h:230
enum arm_mode core_mode
Record the current core mode: SVC, USR, or some other mode.
Definition: arm.h:196
struct reg * cpsr
Handle to the CPSR/xPSR; valid in all core modes.
Definition: arm.h:184
struct reg * pc
Handle to the PC; valid in all core modes.
Definition: arm.h:181
int(* write_core_reg)(struct target *target, struct reg *reg, int num, enum arm_mode mode, uint8_t *value)
Definition: arm.h:226
int(* read_core_reg)(struct target *target, struct reg *reg, int num, enum arm_mode mode)
Retrieve a single core register.
Definition: arm.h:224
struct reg_cache * core_cache
Definition: arm.h:178
struct arm_dpm * dpm
Handle for the debug module, if one is present.
Definition: arm.h:213
int(* mcr)(struct target *target, int cpnum, uint32_t op1, uint32_t op2, uint32_t crn, uint32_t crm, uint32_t value)
Write coprocessor register.
Definition: arm.h:241
struct target * target
Backpointer to the target.
Definition: arm.h:210
enum arm_state core_state
Record the current core state: ARM, Thumb, or otherwise.
Definition: arm.h:199
struct arm_dpm dpm
Definition: armv8.h:191
target_addr_t debug_base
Definition: armv8.h:192
int(* read_reg_u64)(struct armv8_common *armv8, int num, uint64_t *value)
Definition: armv8.h:222
int(* write_reg_u128)(struct armv8_common *armv8, int num, uint64_t lvalue, uint64_t hvalue)
Definition: armv8.h:228
struct adiv5_ap * debug_ap
Definition: armv8.h:193
int(* read_reg_u128)(struct armv8_common *armv8, int num, uint64_t *lvalue, uint64_t *hvalue)
Definition: armv8.h:226
int(* write_reg_u64)(struct armv8_common *armv8, int num, uint64_t value)
Definition: armv8.h:223
unsigned int length
Definition: breakpoints.h:29
enum breakpoint_type type
Definition: breakpoints.h:30
bool is_set
Definition: breakpoints.h:31
target_addr_t address
Definition: breakpoints.h:27
Definition: arm_dpm.h:29
struct dpm_bpwp bpwp
Definition: arm_dpm.h:31
struct breakpoint * bp
Definition: arm_dpm.h:30
uint32_t control
Definition: arm_dpm.h:24
unsigned int number
Definition: arm_dpm.h:22
bool dirty
Definition: arm_dpm.h:26
uint32_t address
Definition: arm_dpm.h:23
Definition: arm_dpm.h:34
struct watchpoint * wp
Definition: arm_dpm.h:35
struct dpm_bpwp bpwp
Definition: arm_dpm.h:36
unsigned int num_regs
Definition: register.h:148
struct reg * reg_list
Definition: register.h:147
Definition: register.h:111
bool valid
Definition: register.h:126
bool exist
Definition: register.h:128
uint32_t size
Definition: register.h:132
uint8_t * value
Definition: register.h:122
void * arch_info
Definition: register.h:140
bool dirty
Definition: register.h:124
const char * name
Definition: register.h:113
int(* add_breakpoint)(struct target *target, struct breakpoint *breakpoint)
Definition: target_type.h:153
int(* add_watchpoint)(struct target *target, struct watchpoint *watchpoint)
Definition: target_type.h:164
int(* remove_breakpoint)(struct target *target, struct breakpoint *breakpoint)
Definition: target_type.h:161
int(* remove_watchpoint)(struct target *target, struct watchpoint *watchpoint)
Definition: target_type.h:170
Definition: target.h:116
enum target_debug_reason debug_reason
Definition: target.h:154
struct target_type * type
Definition: target.h:117
uint64_t mask
Definition: breakpoints.h:44
enum watchpoint_rw rw
Definition: breakpoints.h:46
bool is_set
Definition: breakpoints.h:47
unsigned int length
Definition: breakpoints.h:43
target_addr_t address
Definition: breakpoints.h:42
@ DBG_REASON_UNDEFINED
Definition: target.h:77
@ DBG_REASON_DBGRQ
Definition: target.h:69
@ DBG_REASON_SINGLESTEP
Definition: target.h:73
@ DBG_REASON_WATCHPOINT
Definition: target.h:71
@ DBG_REASON_EXC_CATCH
Definition: target.h:76
@ DBG_REASON_BREAKPOINT
Definition: target.h:70
static const char * target_name(const struct target *target)
Returns the instance-specific name of the specified target.
Definition: target.h:233
#define ERROR_TARGET_RESOURCE_NOT_AVAILABLE
Definition: target.h:794
int64_t timeval_ms(void)
uint64_t target_addr_t
Definition: types.h:335
#define NULL
Definition: usb.h:16