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:
David Brownell
2009-12-01 00:48:53 -08:00
parent 209a0197f0
commit 177bbd8891
9 changed files with 228 additions and 218 deletions

View File

@@ -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;
}