+static int arm11_mrc_inner(target_t *target, int cpnum, uint32_t op1, uint32_t op2, uint32_t CRn, uint32_t CRm, uint32_t *value, bool read)
+{
+ int retval;
+ arm11_common_t * arm11 = target->arch_info;
+
+ uint32_t instr = 0xEE000010 |
+ (cpnum << 8) |
+ (op1 << 21) |
+ (CRn << 16) |
+ (CRm << 0) |
+ (op2 << 5);
+
+ if (read)
+ instr |= 0x00100000;
+
+ retval = arm11_run_instr_data_prepare(arm11);
+ if (retval != ERROR_OK)
+ return retval;
+
+ if (read)
+ {
+ retval = arm11_run_instr_data_from_core_via_r0(arm11, instr, value);
+ if (retval != ERROR_OK)
+ return retval;
+ }
+ else
+ {
+ retval = arm11_run_instr_data_to_core_via_r0(arm11, instr, *value);
+ if (retval != ERROR_OK)
+ return retval;
+ }
+
+ return arm11_run_instr_data_finish(arm11);
+}
+
+static int arm11_mrc(target_t *target, int cpnum, uint32_t op1, uint32_t op2, uint32_t CRn, uint32_t CRm, uint32_t *value)
+{
+ return arm11_mrc_inner(target, cpnum, op1, op2, CRn, CRm, value, true);
+}
+
+static int arm11_mcr(target_t *target, int cpnum, uint32_t op1, uint32_t op2, uint32_t CRn, uint32_t CRm, uint32_t value)
+{
+ return arm11_mrc_inner(target, cpnum, op1, op2, CRn, CRm, &value, false);
+}
+
+