|
From: <ge...@op...> - 2018-04-20 17:50:47
|
This is an automated email from Gerrit. Kamal Dasu (kda...@gm...) just uploaded a new patch set to Gerrit, which you can find at http://openocd.zylin.com/4496 -- gerrit commit a95dff051f43cd5e205ef8e4b546e656ae104cad Author: Kamal Dasu <kda...@gm...> Date: Fri Feb 23 13:01:53 2018 -0500 target: aarch64: Adding mcr, mrc 32-bit coprocesor read/write support Added mrc and mcr co-processor read/write support for 32-bit boot mode on aarch64 target. Change-Id: I9e53fc620b43371a9cb6b694e1f6d33c31c3132f Signed-off-by: Kamal Dasu <kda...@gm...> diff --git a/src/target/aarch64.c b/src/target/aarch64.c index cd83502..780436e 100644 --- a/src/target/aarch64.c +++ b/src/target/aarch64.c @@ -2590,6 +2590,144 @@ COMMAND_HANDLER(aarch64_mask_interrupts_command) 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; + + 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 < 6) || (argc > 7)) { + /* FIXME use the command name to verify # params... */ + 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; + + /* FIXME don't assume "mrc" vs "mcr" from the number of params; + * that could easily be a typo! Check both... + * + * FIXME change the call syntax here ... simplest to just pass + * the MRC() or MCR() instruction to be executed. That will also + * let us support the "mrc2" and "mcr2" opcodes (toggling one bit) + * if that's ever needed. + */ + if (argc == 7) { + 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", @@ -2625,9 +2763,24 @@ static const struct command_registration aarch64_exec_command_handlers[] = { .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, -- |