return ERROR_OK;
}
+static int jim_mcrmrc(Jim_Interp *interp, int argc, Jim_Obj * const *argv)
+{
+ struct command_context *context;
+ struct target *target;
+ struct arm *arm;
+ int retval;
+ bool is_mcr = false;
+ int arg_cnt = 0;
+
+ if (Jim_CompareStringImmediate(interp, argv[0], "mcr")) {
+ is_mcr = true;
+ arg_cnt = 7;
+ } else {
+ arg_cnt = 6;
+ }
+
+ context = current_command_context(interp);
+ assert(context != NULL);
+
+ target = get_current_target(context);
+ if (target == NULL) {
+ 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;
+ }
+
+ arm = target_to_arm(target);
+ if (!is_arm(arm)) {
+ LOG_ERROR("%s: not an ARM", target_name(target));
+ return JIM_ERR;
+ }
+
+ if (target->state != TARGET_HALTED)
+ 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) {
+ LOG_ERROR("%s: wrong number of arguments", __func__);
+ return JIM_ERR;
+ }
+
+ int cpnum;
+ uint32_t op1;
+ uint32_t op2;
+ uint32_t CRn;
+ uint32_t CRm;
+ uint32_t value;
+ long l;
+
+ /* NOTE: parameter sequence matches ARM instruction set usage:
+ * MCR pNUM, op1, rX, CRn, CRm, op2 ; write CP from rX
+ * MRC pNUM, op1, rX, CRn, CRm, op2 ; read CP into rX
+ * The "rX" is necessarily omitted; it uses Tcl mechanisms.
+ */
+ retval = Jim_GetLong(interp, argv[1], &l);
+ if (retval != JIM_OK)
+ return retval;
+ if (l & ~0xf) {
+ LOG_ERROR("%s: %s %d out of range", __func__,
+ "coprocessor", (int) l);
+ return JIM_ERR;
+ }
+ cpnum = l;
+
+ retval = Jim_GetLong(interp, argv[2], &l);
+ if (retval != JIM_OK)
+ return retval;
+ if (l & ~0x7) {
+ LOG_ERROR("%s: %s %d out of range", __func__,
+ "op1", (int) l);
+ return JIM_ERR;
+ }
+ op1 = l;
+
+ retval = Jim_GetLong(interp, argv[3], &l);
+ if (retval != JIM_OK)
+ return retval;
+ if (l & ~0xf) {
+ LOG_ERROR("%s: %s %d out of range", __func__,
+ "CRn", (int) l);
+ return JIM_ERR;
+ }
+ CRn = l;
+
+ retval = Jim_GetLong(interp, argv[4], &l);
+ if (retval != JIM_OK)
+ return retval;
+ if (l & ~0xf) {
+ LOG_ERROR("%s: %s %d out of range", __func__,
+ "CRm", (int) l);
+ return JIM_ERR;
+ }
+ CRm = l;
+
+ retval = Jim_GetLong(interp, argv[5], &l);
+ if (retval != JIM_OK)
+ return retval;
+ if (l & ~0x7) {
+ LOG_ERROR("%s: %s %d out of range", __func__,
+ "op2", (int) l);
+ return JIM_ERR;
+ }
+ op2 = l;
+
+ value = 0;
+
+ if (is_mcr == true) {
+ retval = Jim_GetLong(interp, argv[6], &l);
+ if (retval != JIM_OK)
+ return retval;
+ 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;
+
+ Jim_SetResult(interp, Jim_NewIntObj(interp, value));
+ }
+
+ return JIM_OK;
+}
+
static const struct command_registration aarch64_exec_command_handlers[] = {
{
.name = "cache_info",
.help = "mask aarch64 interrupts during single-step",
.usage = "['on'|'off']",
},
+ {
+ .name = "mcr",
+ .mode = COMMAND_EXEC,
+ .jim_handler = jim_mcrmrc,
+ .help = "write coprocessor register",
+ .usage = "cpnum op1 CRn CRm op2 value",
+ },
+ {
+ .name = "mrc",
+ .mode = COMMAND_EXEC,
+ .jim_handler = jim_mcrmrc,
+ .help = "read coprocessor register",
+ .usage = "cpnum op1 CRn CRm op2",
+ },
+
COMMAND_REGISTRATION_DONE
};
+
static const struct command_registration aarch64_command_handlers[] = {
{
.chain = armv8_command_handlers,