+static int dpmv8_instr_read_data_dcc(struct arm_dpm *dpm,
+ uint32_t opcode, uint32_t *data)
+{
+ struct armv8_common *armv8 = dpm->arm->arch_info;
+ int retval;
+
+ /* the opcode, writing data to DCC */
+ retval = dpmv8_exec_opcode(dpm, opcode, &dpm->dscr);
+ if (retval != ERROR_OK)
+ return retval;
+
+ return dpmv8_read_dcc(armv8, data, &dpm->dscr);
+}
+
+static int dpmv8_instr_read_data_dcc_64(struct arm_dpm *dpm,
+ uint32_t opcode, uint64_t *data)
+{
+ struct armv8_common *armv8 = dpm->arm->arch_info;
+ int retval;
+
+ /* the opcode, writing data to DCC */
+ retval = dpmv8_exec_opcode(dpm, opcode, &dpm->dscr);
+ if (retval != ERROR_OK)
+ return retval;
+
+ return dpmv8_read_dcc_64(armv8, data, &dpm->dscr);
+}
+
+static int dpmv8_instr_read_data_r0(struct arm_dpm *dpm,
+ uint32_t opcode, uint32_t *data)
+{
+ struct armv8_common *armv8 = dpm->arm->arch_info;
+ int retval;
+
+ /* the opcode, writing data to R0 */
+ retval = dpmv8_exec_opcode(dpm, opcode, &dpm->dscr);
+ if (retval != ERROR_OK)
+ return retval;
+
+ /* write R0 to DCC */
+ retval = dpmv8_exec_opcode(dpm, armv8_opcode(armv8, WRITE_REG_DTRTX), &dpm->dscr);
+ if (retval != ERROR_OK)
+ return retval;
+
+ return dpmv8_read_dcc(armv8, data, &dpm->dscr);
+}
+
+static int dpmv8_instr_read_data_r0_64(struct arm_dpm *dpm,
+ uint32_t opcode, uint64_t *data)
+{
+ struct armv8_common *armv8 = dpm->arm->arch_info;
+ int retval;
+
+ if (dpm->arm->core_state != ARM_STATE_AARCH64) {
+ uint32_t tmp;
+ retval = dpmv8_instr_read_data_r0(dpm, opcode, &tmp);
+ if (retval == ERROR_OK)
+ *data = tmp;
+ return retval;
+ }
+
+ /* the opcode, writing data to R0 */
+ retval = dpmv8_exec_opcode(dpm, opcode, &dpm->dscr);
+ if (retval != ERROR_OK)
+ return retval;
+
+ /* write R0 to DCC */
+ retval = dpmv8_exec_opcode(dpm, ARMV8_MSR_GP(SYSTEM_DBG_DBGDTR_EL0, 0), &dpm->dscr);
+ if (retval != ERROR_OK)
+ return retval;
+
+ return dpmv8_read_dcc_64(armv8, data, &dpm->dscr);
+}
+
+#if 0
+static int dpmv8_bpwp_enable(struct arm_dpm *dpm, unsigned index_t,
+ target_addr_t addr, uint32_t control)
+{
+ struct armv8_common *armv8 = dpm->arm->arch_info;
+ uint32_t vr = armv8->debug_base;
+ uint32_t cr = armv8->debug_base;
+ int retval;
+
+ switch (index_t) {
+ case 0 ... 15: /* breakpoints */
+ vr += CPUV8_DBG_BVR_BASE;
+ cr += CPUV8_DBG_BCR_BASE;
+ break;
+ case 16 ... 31: /* watchpoints */
+ vr += CPUV8_DBG_WVR_BASE;
+ cr += CPUV8_DBG_WCR_BASE;
+ index_t -= 16;
+ break;
+ default:
+ return ERROR_FAIL;
+ }
+ vr += 16 * index_t;
+ cr += 16 * index_t;
+
+ LOG_DEBUG("A8: bpwp enable, vr %08x cr %08x",
+ (unsigned) vr, (unsigned) cr);
+
+ retval = mem_ap_write_atomic_u32(armv8->debug_ap, vr, addr);
+ if (retval != ERROR_OK)
+ return retval;
+ return mem_ap_write_atomic_u32(armv8->debug_ap, cr, control);
+}
+#endif
+
+static int dpmv8_bpwp_disable(struct arm_dpm *dpm, unsigned index_t)
+{
+ struct armv8_common *armv8 = dpm->arm->arch_info;
+ uint32_t cr;
+
+ switch (index_t) {
+ case 0 ... 15:
+ cr = armv8->debug_base + CPUV8_DBG_BCR_BASE;
+ break;
+ case 16 ... 31:
+ cr = armv8->debug_base + CPUV8_DBG_WCR_BASE;
+ index_t -= 16;
+ break;
+ default:
+ return ERROR_FAIL;
+ }
+ cr += 16 * index_t;
+
+ LOG_DEBUG("A: bpwp disable, cr %08x", (unsigned) cr);
+
+ /* clear control register */
+ return mem_ap_write_atomic_u32(armv8->debug_ap, cr, 0);
+}
+
+/*
+ * Coprocessor support
+ */
+
+/* Read coprocessor */
+static int dpmv8_mrc(struct target *target, int cpnum,