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