ARM11: added mrc/mcr support to arm11 code.
authorØyvind Harboe <oyvind.harboe@zylin.com>
Mon, 26 Oct 2009 13:39:32 +0000 (14:39 +0100)
committerØyvind Harboe <oyvind.harboe@zylin.com>
Thu, 5 Nov 2009 22:57:49 +0000 (23:57 +0100)
Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
TODO
src/target/arm11.c

diff --git a/TODO b/TODO
index 11318a9956d31b542b0d3824ea242b9bbd05471d..8713e818553ce839993c987e425791fc3a4eda31 100644 (file)
--- a/TODO
+++ b/TODO
@@ -143,7 +143,7 @@ Once the above are completed:
 - regression: "reset halt" between 729(works) and 788(fails): @par
 https://lists.berlios.de/pipermail/openocd-development/2009-July/009206.html
 - mcr/mrc target->type support
-  - missing from ARM11, ARM920t, ARM966e, XScale.
+  - missing from ARM920t, ARM966e, XScale.
   It's possible that the current syntax is unable to support read-modify-write
   operations(see arm966e).
   - mcr/mrc - retire cp15 commands when there the mrc/mrc commands have been
index 1e82b9389b91f08c310fea48a51e78d0c650c0b3..f1e062adf86d0f8bd9a5f51cb538fb4e4fec6fb8 100644 (file)
@@ -60,6 +60,10 @@ bool arm11_config_hardware_step                              = false;
 #define ARM11_HANDLER(x)       \
        .x                              = arm11_##x
 
+
+static int arm11_mrc(target_t *target, int cpnum, uint32_t op1, uint32_t op2, uint32_t CRn, uint32_t CRm, uint32_t *value);
+static int arm11_mcr(target_t *target, int cpnum, uint32_t op1, uint32_t op2, uint32_t CRn, uint32_t CRm, uint32_t value);
+
 target_type_t arm11_target =
 {
        .name                   = "arm11",
@@ -97,6 +101,9 @@ target_type_t arm11_target =
        ARM11_HANDLER(target_create),
        ARM11_HANDLER(init_target),
        ARM11_HANDLER(examine),
+       .mrc = arm11_mrc,
+       .mcr = arm11_mcr,
+
 };
 
 int arm11_regs_arch_type = -1;
@@ -2191,6 +2198,52 @@ int arm11_handle_mcr(struct command_context_s *cmd_ctx, char *cmd, char **args,
        return arm11_handle_mrc_mcr(cmd_ctx, cmd, args, argc, false);
 }
 
+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);
+}
+
+
 int arm11_register_commands(struct command_context_s *cmd_ctx)
 {
        FNC_INFO;