forked from auracaster/openocd
target: "mcr" and "mrc" are ARM-specific
Switch "mrc" and "mcr" commands to be toplevel ARM operations, as they should initially have been. Correct the usage message for both commands: it matches ARM documentation (as one wants!) instead of reordering them to match the funky mrc() and mcr() method usage (sigh). For Cortex-A8: restore a line that got accidentally dropped, so the secure monitor mode shadow registers will show again. Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
This commit is contained in:
@@ -790,6 +790,137 @@ usage:
|
||||
return retval;
|
||||
}
|
||||
|
||||
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 = Jim_GetAssocData(interp, "context");
|
||||
if (context == NULL) {
|
||||
LOG_ERROR("%s: no command context", __func__);
|
||||
return JIM_ERR;
|
||||
}
|
||||
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 ((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 arm_exec_command_handlers[] = {
|
||||
{
|
||||
.name = "reg",
|
||||
@@ -811,6 +942,20 @@ static const struct command_registration arm_exec_command_handlers[] = {
|
||||
.usage = "<address> [<count> ['thumb']]",
|
||||
.help = "disassemble instructions ",
|
||||
},
|
||||
{
|
||||
.name = "mcr",
|
||||
.mode = COMMAND_EXEC,
|
||||
.jim_handler = &jim_mcrmrc,
|
||||
.help = "write coprocessor register",
|
||||
.usage = "cpnum op1 CRn op2 CRm value",
|
||||
},
|
||||
{
|
||||
.name = "mrc",
|
||||
.jim_handler = &jim_mcrmrc,
|
||||
.help = "read coprocessor register",
|
||||
.usage = "cpnum op1 CRn op2 CRm",
|
||||
},
|
||||
|
||||
COMMAND_REGISTRATION_DONE
|
||||
};
|
||||
const struct command_registration arm_command_handlers[] = {
|
||||
@@ -1252,6 +1397,24 @@ static int arm_full_context(struct target *target)
|
||||
return retval;
|
||||
}
|
||||
|
||||
static int arm_default_mrc(struct target *target, int cpnum,
|
||||
uint32_t op1, uint32_t op2,
|
||||
uint32_t CRn, uint32_t CRm,
|
||||
uint32_t *value)
|
||||
{
|
||||
LOG_ERROR("%s doesn't implement MRC", target_type_name(target));
|
||||
return ERROR_FAIL;
|
||||
}
|
||||
|
||||
static int arm_default_mcr(struct target *target, int cpnum,
|
||||
uint32_t op1, uint32_t op2,
|
||||
uint32_t CRn, uint32_t CRm,
|
||||
uint32_t value)
|
||||
{
|
||||
LOG_ERROR("%s doesn't implement MCR", target_type_name(target));
|
||||
return ERROR_FAIL;
|
||||
}
|
||||
|
||||
int armv4_5_init_arch_info(struct target *target, struct arm *armv4_5)
|
||||
{
|
||||
target->arch_info = armv4_5;
|
||||
@@ -1267,5 +1430,10 @@ int armv4_5_init_arch_info(struct target *target, struct arm *armv4_5)
|
||||
if (!armv4_5->full_context && armv4_5->read_core_reg)
|
||||
armv4_5->full_context = arm_full_context;
|
||||
|
||||
if (!armv4_5->mrc)
|
||||
armv4_5->mrc = arm_default_mrc;
|
||||
if (!armv4_5->mcr)
|
||||
armv4_5->mcr = arm_default_mcr;
|
||||
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user