This is an automated email from Gerrit.

"Jeremy Linton <lintonrjer...@gmail.com>" just uploaded a new patch set to 
Gerrit, which you can find at https://review.openocd.org/c/openocd/+/7054

-- gerrit

commit 6adb604762437da65488488897aa21aae63f4dba
Author: Jeremy Linton <lintonrjer...@gmail.com>
Date:   Mon Jun 20 15:08:57 2022 -0500

    aarch64: Add mrs/msr sysreg commands
    
    Armv8 has two modes, aarch32 which is intended
    to be backwards compatible with 32-bit armv7 and
    aarch64 which is an entirely new 64-bit mode. As
    such the older mcr/mrc commands aren't the correct
    method of accessing the newer 64-bit system registers.
    
    These newer system registers are accessed via mrs/msr
    and have a slightly different encoding mechanism. Because
    of that, lets add the 64-bit sys reg read/write commands
    of the form:
    
    aarch64 mrs sysreg | (op1 CRn op1 CRm op2)
    
    Which reports the value of the named system register,
    where sysreg is one of a limited number of ascii sysregs
    that openocd understands (ex: midr) or the individual
    instruction encoding fields described in the manuals.
    
    alternatively,
    
    aarch64 msr sysreg | (op1 CRn op1 CRm op2) value
    
    Writes `value` to the identified system register.
    
    Signed-off-by: Jeremy Linton <lintonrjer...@gmail.com>
    Change-Id: I4fe6dcc74a13a440e4aaf9375e41883f3fd2918f

diff --git a/src/target/aarch64.c b/src/target/aarch64.c
index e4d420f07a..b6fff89627 100644
--- a/src/target/aarch64.c
+++ b/src/target/aarch64.c
@@ -2967,6 +2967,201 @@ COMMAND_HANDLER(aarch64_mask_interrupts_command)
        return ERROR_OK;
 }
 
+
+static struct sysreg_nameop_t {
+       char *name;
+    uint32_t value;
+} sysreg_nameop[] = {
+       {"ELR_EL1", SYSTEM_ELR_EL1},
+       {"ELR_EL2", SYSTEM_ELR_EL2},
+       {"ELR_EL3", SYSTEM_ELR_EL3},
+       {"SCTLR_EL1", SYSTEM_SCTLR_EL1},
+       {"SCTLR_EL2", SYSTEM_SCTLR_EL2},
+       {"SCTLR_EL3", SYSTEM_SCTLR_EL3},
+       {"FPCR", SYSTEM_FPCR},
+       {"FPSR", SYSTEM_FPSR},
+       {"DAIF", SYSTEM_DAIF},
+       {"NZCV", SYSTEM_NZCV},
+       {"SP_EL0", SYSTEM_SP_EL0},
+       {"SP_EL1", SYSTEM_SP_EL1},
+       {"SP_EL2", SYSTEM_SP_EL2},
+       {"SP_SEL", SYSTEM_SP_SEL},
+       {"SPSR_ABT", SYSTEM_SPSR_ABT},
+       {"SPSR_FIQ", SYSTEM_SPSR_FIQ},
+       {"SPSR_IRQ", SYSTEM_SPSR_IRQ},
+       {"SPSR_UND", SYSTEM_SPSR_UND},
+       {"SPSR_EL1", SYSTEM_SPSR_EL1},
+       {"SPSR_EL2", SYSTEM_SPSR_EL2},
+       {"SPSR_EL3", SYSTEM_SPSR_EL3},
+       {"ISR_EL1", SYSTEM_ISR_EL1},
+       {"DISR_EL1", SYSTEM_DISR_EL1},
+       {"DBG_DSPSR_EL0", SYSTEM_DBG_DSPSR_EL0},
+       {"DBG_DLR_EL0", SYSTEM_DBG_DLR_EL0},
+       {"DBG_DTRRX_EL0", SYSTEM_DBG_DTRRX_EL0},
+       {"DBG_DTRTX_EL0", SYSTEM_DBG_DTRTX_EL0},
+       {"DBG_DBGDTR_EL0", SYSTEM_DBG_DBGDTR_EL0},
+       {"CCSIDR", SYSTEM_CCSIDR},
+       {"CLIDR", SYSTEM_CLIDR},
+       {"CSSELR", SYSTEM_CSSELR},
+       {"CTYPE", SYSTEM_CTYPE},
+       {"CTR", SYSTEM_CTR},
+       {"DCCISW", SYSTEM_DCCISW},
+       {"DCCSW", SYSTEM_DCCSW},
+       {"ICIVAU", SYSTEM_ICIVAU},
+       {"DCCVAU", SYSTEM_DCCVAU},
+       {"DCCIVAC", SYSTEM_DCCIVAC},
+       {"MIDR", SYSTEM_MIDR},
+       {"MPIDR", SYSTEM_MPIDR},
+       {"REVIDR", SYSTEM_REVIDR},
+       {"TCR_EL1", SYSTEM_TCR_EL1},
+       {"TCR_EL2", SYSTEM_TCR_EL2},
+       {"TCR_EL3", SYSTEM_TCR_EL3},
+       {"TTBR0_EL1", SYSTEM_TTBR0_EL1},
+       {"TTBR0_EL2", SYSTEM_TTBR0_EL2},
+       {"TTBR0_EL3", SYSTEM_TTBR0_EL3},
+       {"TTBR1_EL1", SYSTEM_TTBR1_EL1},
+       {"PAR_EL1", SYSTEM_PAR_EL1},
+       {"ATS12E0R", SYSTEM_ATS12E0R},
+       {"ATS12E1R", SYSTEM_ATS12E1R},
+       {"ATS1E2R", SYSTEM_ATS1E2R},
+       {"ATS1E3R", SYSTEM_ATS1E3R},
+       {"FAR_EL1", SYSTEM_FAR_EL1},
+       {"FAR_EL2", SYSTEM_FAR_EL2},
+       {"FAR_EL3", SYSTEM_FAR_EL3},
+       {"ESR_EL1", SYSTEM_ESR_EL1},
+       {"ESR_EL2", SYSTEM_ESR_EL2},
+       {"ESR_EL3", SYSTEM_ESR_EL3},
+       {NULL, 0}
+};
+
+/* read/write system registers (mrs=read) (msr=write)*/
+static int jim_mrsmsr(Jim_Interp *interp, int argc, Jim_Obj * const *argv)
+{
+       struct command *c = jim_to_command(interp);
+       struct command_context *context;
+       struct target *target;
+       struct armv8_common *armv8;
+       int retval;
+       bool is_msr = false;
+       uint64_t sr;
+
+       if (!strcmp(c->name, "msr")) {
+               is_msr = true;
+       }
+
+       context = current_command_context(interp);
+       assert(context);
+
+       target = get_current_target(context);
+       if (!target) {
+               LOG_ERROR("%s: no current target", __func__);
+               return JIM_ERR;
+       }
+       if (!target_was_examined(target)) {
+               LOG_ERROR("%s: not yet examined", target_name(target));
+               return JIM_ERR;
+       }
+
+       armv8 = target_to_armv8(target);
+       if (!is_armv8(armv8)) {
+               LOG_ERROR("%s: not an ARMv8", target_name(target));
+               return JIM_ERR;
+       }
+
+       if (target->state != TARGET_HALTED)
+               return ERROR_TARGET_NOT_HALTED;
+
+       if (armv8->arm.core_state != ARM_STATE_AARCH64) {
+               LOG_ERROR("%s: not 64-bit arm target", target_name(target));
+               return JIM_ERR;
+       }
+
+       long l;
+       int len;
+       int names = 0;
+       char *argv1 = (char *)Jim_GetString(argv[1], &len);
+       char name_buf[32];
+       char jim_buf[256];
+       uint32_t reg = 0;
+
+       while (sysreg_nameop[names].name != NULL)
+       {
+               if (strcasecmp(argv1, sysreg_nameop[names].name) == 0)
+               {
+                       reg = sysreg_nameop[names].value;
+                       if (is_msr) {
+                               if (Jim_GetLong(interp, argv[2],(int64_t*) &sr) 
!= JIM_OK)
+                                       return JIM_ERR;
+                       }
+                       break;
+               }
+               names++;
+       }
+
+       if (sysreg_nameop[names].name == NULL)
+       {
+               /* didn't find the name, try to form the register from vals */
+               int arg[5];
+
+               for (names = 1; names < 6; names++ ) {
+                       /* ok try value parsing */
+                       if (Jim_GetLong(interp, argv[names], &l) != JIM_OK)
+                               return JIM_ERR;
+                       if (l & ~0xf) {
+                               LOG_ERROR("%s: %d %d out of range", __func__,   
names, (int) l);
+                               return JIM_ERR;
+                       }
+                       arg[names-1] = l;
+               }
+               reg = ARMV8_SYSREG(arg[0], arg[1], arg[2], arg[3], arg[4]);
+
+               // create a regname for the result
+               snprintf(name_buf, 32, "0x%X", reg);
+               argv1 = name_buf;
+               if (is_msr) {
+                       if (Jim_GetLong(interp, argv[6],(int64_t*) &sr) != 
JIM_OK)
+                               return JIM_ERR;
+               }
+
+       }
+
+       retval = armv8->dpm.prepare(&armv8->dpm);
+       if (retval != ERROR_OK) {
+               LOG_ERROR("%s: can't dpm->prepare", __func__);
+               return retval;
+       }
+
+       if (is_msr)
+       {
+               retval = armv8->dpm.instr_write_data_r0_64(&armv8->dpm, 
ARMV8_MSR_GP(reg, 0), sr);
+               if (retval != ERROR_OK) {
+                       LOG_ERROR("%s: can't dpm->write64", __func__);
+                       return retval;
+               }
+               sprintf(jim_buf, "msr %s: (wrote) 0x%lX", argv1, sr);
+               Jim_SetResultString(interp, jim_buf, -1);
+       }
+       else
+       {
+               retval = armv8->dpm.instr_read_data_r0_64(&armv8->dpm, 
ARMV8_MRS(reg, 0), &sr);
+               if (retval != ERROR_OK) {
+                       LOG_ERROR("%s: can't dpm->read64", __func__);
+                       return retval;
+               }
+               sprintf(jim_buf, "mrs %s: (read) 0x%lX", argv1, sr);
+               Jim_SetResultString(interp, jim_buf, -1);
+       }
+
+       retval = armv8->dpm.finish(&armv8->dpm);
+       if (retval != ERROR_OK) {
+               LOG_ERROR("%s: can't dpm->finish", __func__);
+               return retval;
+       }
+
+       return JIM_OK;
+}
+
+
 static int jim_mcrmrc(Jim_Interp *interp, int argc, Jim_Obj * const *argv)
 {
        struct command *c = jim_to_command(interp);
@@ -3148,6 +3343,21 @@ static const struct command_registration 
aarch64_exec_command_handlers[] = {
                .help = "read coprocessor register",
                .usage = "cpnum op1 CRn CRm op2",
        },
+       {
+               .name = "mrs",
+               .mode = COMMAND_EXEC,
+               .jim_handler = jim_mrsmsr,
+               .help = "read system register",
+               .usage = "sysreg | [op0 CRn op1 CRm op2]",
+       },
+       {
+               .name = "msr",
+               .mode = COMMAND_EXEC,
+               .jim_handler = jim_mrsmsr,
+               .help = "write system register",
+               .usage = "sysreg | op0 CRn op1 CRm op2 width, value",
+       },
+
        {
                .chain = smp_command_handlers,
        },

-- 

Reply via email to