This is an automated email from Gerrit.

"Dietmar May <dietmar....@outlook.com>" just uploaded a new patch set to 
Gerrit, which you can find at https://review.openocd.org/c/openocd/+/6474

-- gerrit

commit 90c934d6465538d471a549d9ecd352df60961819
Author: Dietmar May <dietmar....@outlook.com>
Date:   Thu Aug 19 11:10:18 2021 -0400

    aarch64: implement 64 bit msr/mrs support within existing mcr/mrc cmd
    
    The existing mcr/mrc code checks whether it's in 32 bit mode, and
    silently bails without any warning if it's in 64 bit mode.
    
    This patch instead performs a msr / mrs operation when mcr or mrc is
    issued when in 64 bit mode.
    
    proc warm_reset {} {
        set _t [target current]
        echo "$_t warm reset"
    
        # write b0011 to RMR_EL3 for warm reset into 64-bit mode
        $_t aarch64 mcr 1 6 12 0 2 3
    }
    
    Signed-off-by: Dietmar May  <dietmar....@outlook.com>
    Change-Id: Ib8f198391bcee537bf0e555c357be0bedf628e14

diff --git a/src/target/aarch64.c b/src/target/aarch64.c
index 70e727cf9..f71c735a8 100644
--- a/src/target/aarch64.c
+++ b/src/target/aarch64.c
@@ -2953,6 +2953,113 @@ COMMAND_HANDLER(aarch64_mask_interrupts_command)
        return ERROR_OK;
 }
 
+/* Move to ARM register from coprocessor
+ * o0: Coprocessor number (0 - general, 1 - system)
+ * op1: Coprocessor opcode
+ * rd:  destination register
+ * crn: first coprocessor operand
+ * crm: second coprocessor operand
+ * op2: Second coprocessor opcode
+ */
+#define ARMV8_MRS64(o0, op1, rd, crn, crm, op2) \
+    (0xD5300000 \
+    | (((o0)  & 0x01) << 19) \
+    | (((op1) & 0x07) << 16) \
+    | (((crn) & 0x0F) << 12) \
+    | (((crm) & 0x0F) << 8)  \
+    | (((op2) & 0x07) << 5)  \
+    | ((rd)   & 0x1F) \
+    )
+
+/* Read coprocessor */
+static int dpm_mrs(struct target *target, int o0,
+    uint32_t op1, uint32_t op2, uint32_t crn, uint32_t crm, uint64_t *value)
+{
+    struct aarch64_common *aarch64 = target_to_aarch64(target);
+    struct armv8_common *armv8 = &aarch64->armv8_common;
+    struct arm_dpm *dpm = &armv8->dpm;
+    int retval;
+
+#if 0 //todo aarch64_post_debug_entry brackets instr_read_data_r0
+    if (target_mode != ARM_MODE_ANY)
+        armv8_dpm_modeswitch(dpm, target_mode);
+#else
+    retval = dpm->prepare(dpm);
+    if (retval != ERROR_OK)
+        return retval;
+#endif
+
+    uint32_t instr = ARMV8_MRS64(o0, op1, 0, crn, crm, op2);
+
+    LOG_DEBUG("MRS p%d, %d, r0, c%d, c%d, %d - %08x", o0, 
+       (int) op1, (int) crn, (int) crm, (int) op2, instr);
+
+    /* read coprocessor register into R0; return via DCC */
+    retval = dpm->instr_read_data_r0_64(dpm, instr, value);
+
+#if 0 //todo aarch64_post_debug_entry brackets instr_read_data_r0
+    if (target_mode != ARM_MODE_ANY)
+        armv8_dpm_modeswitch(dpm, ARM_MODE_ANY);
+#else
+    /* (void) */ dpm->finish(dpm);
+#endif
+
+    return retval;
+}
+
+/* Move to coprocessor from ARM register
+ * o0: Coprocessor number (0 - general, 1 - system)
+ * op1: Coprocessor opcode
+ * rd: destination register
+ * crn: first coprocessor operand
+ * crm: second coprocessor operand
+ * op2: Second coprocessor opcode
+ */
+#define ARMV8_MSR64(o0, op1, rd, crn, crm, op2) \
+    (0xD5100000 \
+    | (((o0)  & 0x01) << 19) \
+    | (((op1) & 0x07) << 16) \
+    | (((crn) & 0x0F) << 12) \
+    | (((crm) & 0x0F) << 8)  \
+    | (((op2) & 0x07) << 5)  \
+    | ((rd)   & 0x1F) \
+    )
+
+static int dpm_msr(struct target *target, int o0,
+    uint32_t op1, uint32_t op2, uint32_t crn, uint32_t crm, uint64_t value)
+{
+    struct aarch64_common *aarch64 = target_to_aarch64(target);
+    struct armv8_common *armv8 = &aarch64->armv8_common;
+    struct arm_dpm *dpm = &armv8->dpm;
+    int retval;
+
+#if 0 //todo aarch64_restore_system_control_reg brackets instr_write_data_r0
+    if (target_mode != ARM_MODE_ANY)
+        armv8_dpm_modeswitch(dpm, target_mode);
+#else
+    retval = dpm->prepare(dpm);
+    if (retval != ERROR_OK)
+        return retval;
+#endif
+
+    uint32_t instr = ARMV8_MSR64(o0, op1, 0, crn, crm, op2);
+
+    LOG_TRACE("MSR p%d, %d, r0, c%d, c%d, %d - %08x = 0x%016" PRIx64, o0,
+                       (int) op1, (int) crn, (int) crm, (int) op2, instr, 
value);
+
+    /* read DCC into r0; then write coprocessor register from R0 */
+    retval = dpm->instr_write_data_r0_64(dpm, instr, value);
+
+#if 0 //todo aarch64_restore_system_control_reg brackets instr_write_data_r0
+    if (target_mode != ARM_MODE_ANY)
+        armv8_dpm_modeswitch(dpm, ARM_MODE_ANY);
+#else
+    /* (void) */ dpm->finish(dpm);
+#endif
+
+    return retval;
+}
+
 static int jim_mcrmrc(Jim_Interp *interp, int argc, Jim_Obj * const *argv)
 {
        struct command *c = jim_to_command(interp);
@@ -2989,12 +3096,9 @@ static int jim_mcrmrc(Jim_Interp *interp, int argc, 
Jim_Obj * const *argv)
                return JIM_ERR;
        }
 
-       if (target->state != TARGET_HALTED)
+       if (target->state != TARGET_HALTED) {
+        LOG_ERROR("%s: target not halted", target_name(target));
                return ERROR_TARGET_NOT_HALTED;
-
-       if (arm->core_state == ARM_STATE_AARCH64) {
-               LOG_ERROR("%s: not 32-bit arm target", target_name(target));
-               return JIM_ERR;
        }
 
        if (argc != arg_cnt) {
@@ -3007,7 +3111,6 @@ static int jim_mcrmrc(Jim_Interp *interp, int argc, 
Jim_Obj * const *argv)
        uint32_t op2;
        uint32_t crn;
        uint32_t crm;
-       uint32_t value;
        long l;
 
        /* NOTE:  parameter sequence matches ARM instruction set usage:
@@ -3065,27 +3168,53 @@ static int jim_mcrmrc(Jim_Interp *interp, int argc, 
Jim_Obj * const *argv)
        }
        op2 = l;
 
-       value = 0;
-
        if (is_mcr == true) {
-               retval = Jim_GetLong(interp, argv[6], &l);
-               if (retval != JIM_OK)
-                       return retval;
-               value = l;
+               if (arm->core_state == ARM_STATE_AARCH64) {
+                   jim_wide lw;
+                       retval = Jim_GetWide(interp, argv[6], &lw);
+                       if (retval != JIM_OK)
+                               return retval;
+                       uint64_t value = lw;
 
-               /* NOTE: parameters reordered! */
-               /* ARMV4_5_MCR(cpnum, op1, 0, crn, crm, op2) */
-               retval = arm->mcr(target, cpnum, op1, op2, crn, crm, value);
-               if (retval != ERROR_OK)
-                       return JIM_ERR;
+                       /* NOTE: parameters reordered! */
+                       /* ARMV4_5_MCR(cpnum, op1, 0, crn, crm, op2) */
+               retval = dpm_msr(target, cpnum, op1, op2, crn, crm, value);
+                       if (retval != ERROR_OK)
+                               return JIM_ERR;
+               } else {
+                       retval = Jim_GetLong(interp, argv[6], &l);
+                       if (retval != JIM_OK)
+                               return retval;
+                       uint32_t value = l;
+
+                       /* NOTE: parameters reordered! */
+                       /* ARMV4_5_MCR(cpnum, op1, 0, crn, crm, op2) */
+                       retval = arm->mcr(target, cpnum, op1, op2, crn, crm, 
value);
+                       if (retval != ERROR_OK)
+                               return JIM_ERR;
+               }
        } else {
-               /* NOTE: parameters reordered! */
-               /* ARMV4_5_MRC(cpnum, op1, 0, crn, crm, op2) */
-               retval = arm->mrc(target, cpnum, op1, op2, crn, crm, &value);
-               if (retval != ERROR_OK)
-                       return JIM_ERR;
+               if (arm->core_state == ARM_STATE_AARCH64) {
+                   uint64_t value;
+                       /* NOTE: parameters reordered! */
+                       /* ARMV4_5_MRC(cpnum, op1, 0, crn, crm, op2) */
+            retval = dpm_mrs(target, cpnum, op1, op2, crn, crm, &value);
+                       if (retval != ERROR_OK)
+                               return JIM_ERR;
 
-               Jim_SetResult(interp, Jim_NewIntObj(interp, value));
+            jim_wide lw = value;
+                       Jim_SetResult(interp, Jim_NewWideObj(interp, lw));
+               } else {
+                       uint32_t value;
+                       /* NOTE: parameters reordered! */
+                       /* ARMV4_5_MRC(cpnum, op1, 0, crn, crm, op2) */
+                       retval = arm->mrc(target, cpnum, op1, op2, crn, crm, 
&value);
+                       if (retval != ERROR_OK)
+                               return JIM_ERR;
+
+            l = value;
+                       Jim_SetResult(interp, Jim_NewIntObj(interp, value));
+               }
        }
 
        return JIM_OK;

-- 

Reply via email to