mcr/mrc interface work. Implemented for arm926ejs and arm720t. mcr/mrc commands added.
This commit is contained in:
parent
18aad44f71
commit
0a1356c9cc
|
@ -2,6 +2,9 @@
|
|||
* Copyright (C) 2005 by Dominic Rath *
|
||||
* Dominic.Rath@gmx.de *
|
||||
* *
|
||||
* Copyright (C) 2009 by Øyvind Harboe *
|
||||
* oyvind.harboe@zylin.com *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
|
@ -46,6 +49,9 @@ int arm720t_read_phys_memory(struct target_s *target, uint32_t address, uint32_t
|
|||
int arm720t_write_phys_memory(struct target_s *target, uint32_t address, uint32_t size, uint32_t count, uint8_t *buffer);
|
||||
int arm720t_soft_reset_halt(struct target_s *target);
|
||||
|
||||
static int arm720t_mrc(target_t *target, int cpnum, uint32_t op1, uint32_t op2, uint32_t CRn, uint32_t CRm, uint32_t *value);
|
||||
static int arm720t_mcr(target_t *target, int cpnum, uint32_t op1, uint32_t op2, uint32_t CRn, uint32_t CRm, uint32_t value);
|
||||
|
||||
target_type_t arm720t_target =
|
||||
{
|
||||
.name = "arm720t",
|
||||
|
@ -82,7 +88,9 @@ target_type_t arm720t_target =
|
|||
.target_create = arm720t_target_create,
|
||||
.init_target = arm720t_init_target,
|
||||
.examine = arm7tdmi_examine,
|
||||
.quit = arm720t_quit
|
||||
.quit = arm720t_quit,
|
||||
.mrc = arm720t_mrc,
|
||||
.mcr = arm720t_mcr,
|
||||
|
||||
};
|
||||
|
||||
|
@ -574,3 +582,29 @@ int arm720t_handle_cp15_command(struct command_context_s *cmd_ctx, char *cmd, ch
|
|||
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
|
||||
static int arm720t_mrc(target_t *target, int cpnum, uint32_t op1, uint32_t op2, uint32_t CRn, uint32_t CRm, uint32_t *value)
|
||||
{
|
||||
if (cpnum!=15)
|
||||
{
|
||||
LOG_ERROR("Only cp15 is supported");
|
||||
return ERROR_FAIL;
|
||||
}
|
||||
|
||||
return arm720t_read_cp15(target, mrc_opcode(cpnum, op1, op2, CRn, CRm), value);
|
||||
|
||||
}
|
||||
|
||||
static int arm720t_mcr(target_t *target, int cpnum, uint32_t op1, uint32_t op2, uint32_t CRn, uint32_t CRm, uint32_t value)
|
||||
{
|
||||
if (cpnum!=15)
|
||||
{
|
||||
LOG_ERROR("Only cp15 is supported");
|
||||
return ERROR_FAIL;
|
||||
}
|
||||
|
||||
return arm720t_write_cp15(target, mrc_opcode(cpnum, op1, op2, CRn, CRm), value);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
* Copyright (C) 2007 by Dominic Rath *
|
||||
* Dominic.Rath@gmx.de *
|
||||
* *
|
||||
* Copyright (C) 2009 by Øyvind Harboe *
|
||||
* Copyright (C) 2007,2008,2009 by Øyvind Harboe *
|
||||
* oyvind.harboe@zylin.com *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
|
@ -35,7 +35,6 @@
|
|||
|
||||
/* cli handling */
|
||||
int arm926ejs_handle_cp15_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
|
||||
int arm926ejs_handle_cp15i_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
|
||||
int arm926ejs_handle_cache_info_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
|
||||
|
||||
int arm926ejs_handle_read_cache_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
|
||||
|
@ -52,6 +51,29 @@ int arm926ejs_write_phys_memory(struct target_s *target, uint32_t address, uint3
|
|||
static int arm926ejs_virt2phys(struct target_s *target, uint32_t virtual, uint32_t *physical);
|
||||
static int arm926ejs_mmu(struct target_s *target, int *enabled);
|
||||
|
||||
int arm926ejs_cp15_read(target_t *target, uint32_t op1, uint32_t op2, uint32_t CRn, uint32_t CRm, uint32_t *value);
|
||||
int arm926ejs_cp15_write(target_t *target, uint32_t op1, uint32_t op2, uint32_t CRn, uint32_t CRm, uint32_t value);
|
||||
|
||||
static int arm926ejs_mrc(target_t *target, int cpnum, uint32_t op1, uint32_t op2, uint32_t CRn, uint32_t CRm, uint32_t *value)
|
||||
{
|
||||
if (cpnum!=15)
|
||||
{
|
||||
LOG_ERROR("Only cp15 is supported");
|
||||
return ERROR_FAIL;
|
||||
}
|
||||
return arm926ejs_cp15_read(target, op1, op2, CRn, CRm, value);
|
||||
}
|
||||
|
||||
static int arm926ejs_mcr(target_t *target, int cpnum, uint32_t op1, uint32_t op2, uint32_t CRn, uint32_t CRm, uint32_t value)
|
||||
{
|
||||
if (cpnum!=15)
|
||||
{
|
||||
LOG_ERROR("Only cp15 is supported");
|
||||
return ERROR_FAIL;
|
||||
}
|
||||
return arm926ejs_cp15_write(target, op1, op2, CRn, CRm, value);
|
||||
}
|
||||
|
||||
target_type_t arm926ejs_target =
|
||||
{
|
||||
.name = "arm926ejs",
|
||||
|
@ -94,6 +116,8 @@ target_type_t arm926ejs_target =
|
|||
|
||||
.read_phys_memory = arm926ejs_read_phys_memory,
|
||||
.write_phys_memory = arm926ejs_write_phys_memory,
|
||||
.mrc = arm926ejs_mrc,
|
||||
.mcr = arm926ejs_mcr,
|
||||
};
|
||||
|
||||
int arm926ejs_catch_broken_irscan(uint8_t *captured, void *priv, scan_field_t *field)
|
||||
|
|
|
@ -5,6 +5,9 @@
|
|||
* Copyright (C) 2008 by Spencer Oliver *
|
||||
* spen@spen-soft.co.uk *
|
||||
* *
|
||||
* Copyright (C) 2009 by Øyvind Harboe *
|
||||
* oyvind.harboe@zylin.com *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
|
@ -315,4 +318,19 @@ extern int armv4_5_invalidate_core_regs(target_t *target);
|
|||
*/
|
||||
#define ARMV5_T_BKPT(Im) ((0xbe00 | Im) | ((0xbe00 | Im) << 16))
|
||||
|
||||
/* build basic mrc/mcr opcode */
|
||||
|
||||
static inline uint32_t mrc_opcode(int cpnum, uint32_t op1, uint32_t op2, uint32_t CRn, uint32_t CRm)
|
||||
{
|
||||
uint32_t t = 0;
|
||||
t|=op1<<21;
|
||||
t|=op2<<5;
|
||||
t|=CRn<<16;
|
||||
t|=CRm<<0;
|
||||
return t;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
#endif /* ARMV4_5_H */
|
||||
|
|
|
@ -69,6 +69,7 @@ static int handle_fast_load_image_command(struct command_context_s *cmd_ctx, cha
|
|||
static int handle_fast_load_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
|
||||
|
||||
static int jim_array2mem(Jim_Interp *interp, int argc, Jim_Obj *const *argv);
|
||||
static int jim_mcrmrc(Jim_Interp *interp, int argc, Jim_Obj *const *argv);
|
||||
static int jim_mem2array(Jim_Interp *interp, int argc, Jim_Obj *const *argv);
|
||||
static int jim_target(Jim_Interp *interp, int argc, Jim_Obj *const *argv);
|
||||
|
||||
|
@ -687,6 +688,60 @@ void target_reset_examined(struct target_s *target)
|
|||
}
|
||||
|
||||
|
||||
|
||||
static int default_mrc(struct target_s *target, int cpnum, uint32_t op1, uint32_t op2, uint32_t CRn, uint32_t CRm, uint32_t *value)
|
||||
{
|
||||
LOG_ERROR("Not implemented");
|
||||
return ERROR_FAIL;
|
||||
}
|
||||
|
||||
static int default_mcr(struct target_s *target, int cpnum, uint32_t op1, uint32_t op2, uint32_t CRn, uint32_t CRm, uint32_t value)
|
||||
{
|
||||
LOG_ERROR("Not implemented");
|
||||
return ERROR_FAIL;
|
||||
}
|
||||
|
||||
static int arm_cp_check(struct target_s *target, int cpnum, uint32_t op1, uint32_t op2, uint32_t CRn, uint32_t CRm)
|
||||
{
|
||||
/* basic check */
|
||||
if (!target_was_examined(target))
|
||||
{
|
||||
LOG_ERROR("Target not examined yet");
|
||||
return ERROR_FAIL;
|
||||
}
|
||||
|
||||
if ((cpnum <0) || (cpnum > 15))
|
||||
{
|
||||
LOG_ERROR("Illegal co-processor %d", cpnum);
|
||||
return ERROR_FAIL;
|
||||
}
|
||||
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
int target_mrc(struct target_s *target, int cpnum, uint32_t op1, uint32_t op2, uint32_t CRn, uint32_t CRm, uint32_t *value)
|
||||
{
|
||||
int retval;
|
||||
|
||||
retval = arm_cp_check(target, cpnum, op1, op2, CRn, CRm);
|
||||
if (retval != ERROR_OK)
|
||||
return retval;
|
||||
|
||||
return target->type->mrc(target, cpnum, op1, op2, CRn, CRm, value);
|
||||
}
|
||||
|
||||
int target_mcr(struct target_s *target, int cpnum, uint32_t op1, uint32_t op2, uint32_t CRn, uint32_t CRm, uint32_t value)
|
||||
{
|
||||
int retval;
|
||||
|
||||
retval = arm_cp_check(target, cpnum, op1, op2, CRn, CRm);
|
||||
if (retval != ERROR_OK)
|
||||
return retval;
|
||||
|
||||
return target->type->mcr(target, cpnum, op1, op2, CRn, CRm, value);
|
||||
}
|
||||
|
||||
|
||||
int target_init(struct command_context_s *cmd_ctx)
|
||||
{
|
||||
target_t *target = all_targets;
|
||||
|
@ -722,6 +777,17 @@ int target_init(struct command_context_s *cmd_ctx)
|
|||
target->type->write_phys_memory = target->type->write_memory;
|
||||
}
|
||||
|
||||
if (target->type->mcr == NULL)
|
||||
{
|
||||
target->type->mcr = default_mcr;
|
||||
}
|
||||
|
||||
if (target->type->mrc == NULL)
|
||||
{
|
||||
target->type->mrc = default_mrc;
|
||||
}
|
||||
|
||||
|
||||
/* a non-invasive way(in terms of patches) to add some code that
|
||||
* runs before the type->write/read_memory implementation
|
||||
*/
|
||||
|
@ -1538,6 +1604,9 @@ int target_register_user_commands(struct command_context_s *cmd_ctx)
|
|||
register_jim(cmd_ctx, "ocd_mem2array", jim_mem2array, "read memory and return as a TCL array for script processing <ARRAYNAME> <WIDTH = 32/16/8> <ADDRESS> <COUNT>");
|
||||
register_jim(cmd_ctx, "ocd_array2mem", jim_array2mem, "convert a TCL array to memory locations and write the values <ARRAYNAME> <WIDTH = 32/16/8> <ADDRESS> <COUNT>");
|
||||
|
||||
register_jim(cmd_ctx, "mrc", jim_mcrmrc, "read coprocessor <cpnum> <op1> <op2> <CRn> <CRm>");
|
||||
register_jim(cmd_ctx, "mcr", jim_mcrmrc, "write coprocessor <cpnum> <op1> <op2> <CRn> <CRm> <value>");
|
||||
|
||||
register_command(cmd_ctx, NULL, "fast_load_image", handle_fast_load_image_command, COMMAND_ANY,
|
||||
"same args as load_image, image stored in memory - mainly for profiling purposes");
|
||||
|
||||
|
@ -3355,7 +3424,6 @@ static int jim_array2mem(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
|
|||
|
||||
return target_array2mem(interp,target, argc-1, argv + 1);
|
||||
}
|
||||
|
||||
static int target_array2mem(Jim_Interp *interp, target_t *target, int argc, Jim_Obj *const *argv)
|
||||
{
|
||||
long l;
|
||||
|
@ -4693,10 +4761,90 @@ static int handle_fast_load_command(struct command_context_s *cmd_ctx, char *cmd
|
|||
return retval;
|
||||
}
|
||||
|
||||
static int jim_mcrmrc(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
|
||||
{
|
||||
command_context_t *context;
|
||||
target_t *target;
|
||||
int retval;
|
||||
|
||||
/*
|
||||
* Local Variables:
|
||||
* c-basic-offset: 4
|
||||
* tab-width: 4
|
||||
* End:
|
||||
*/
|
||||
context = Jim_GetAssocData(interp, "context");
|
||||
if (context == NULL) {
|
||||
LOG_ERROR("array2mem: no command context");
|
||||
return JIM_ERR;
|
||||
}
|
||||
target = get_current_target(context);
|
||||
if (target == NULL) {
|
||||
LOG_ERROR("array2mem: no current target");
|
||||
return JIM_ERR;
|
||||
}
|
||||
|
||||
if ((argc < 6) || (argc > 7))
|
||||
{
|
||||
return JIM_ERR;
|
||||
}
|
||||
|
||||
int cpnum;
|
||||
uint32_t op1;
|
||||
uint32_t op2;
|
||||
uint32_t CRn;
|
||||
uint32_t CRm;
|
||||
uint32_t value;
|
||||
|
||||
int e;
|
||||
long l;
|
||||
e = Jim_GetLong(interp, argv[1], &l);
|
||||
if (e != JIM_OK) {
|
||||
return e;
|
||||
}
|
||||
cpnum = l;
|
||||
|
||||
e = Jim_GetLong(interp, argv[2], &l);
|
||||
if (e != JIM_OK) {
|
||||
return e;
|
||||
}
|
||||
op1 = l;
|
||||
|
||||
e = Jim_GetLong(interp, argv[3], &l);
|
||||
if (e != JIM_OK) {
|
||||
return e;
|
||||
}
|
||||
op2 = l;
|
||||
|
||||
e = Jim_GetLong(interp, argv[4], &l);
|
||||
if (e != JIM_OK) {
|
||||
return e;
|
||||
}
|
||||
CRn = l;
|
||||
|
||||
e = Jim_GetLong(interp, argv[5], &l);
|
||||
if (e != JIM_OK) {
|
||||
return e;
|
||||
}
|
||||
CRm = l;
|
||||
|
||||
value = 0;
|
||||
|
||||
LOG_DEBUG("%d %d %d %d %d %d", cpnum, op1, op2, CRn, CRm, value);
|
||||
|
||||
if (argc == 7)
|
||||
{
|
||||
e = Jim_GetLong(interp, argv[6], &l);
|
||||
if (e != JIM_OK) {
|
||||
return e;
|
||||
}
|
||||
value = l;
|
||||
|
||||
retval = target_mcr(target, cpnum, op1, op2, CRn, CRm, value);
|
||||
if (retval != ERROR_OK)
|
||||
return JIM_ERR;
|
||||
} else
|
||||
{
|
||||
retval = target_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;
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
* Copyright (C) 2005 by Dominic Rath *
|
||||
* Dominic.Rath@gmx.de *
|
||||
* *
|
||||
* Copyright (C) 2007,2008 Øyvind Harboe *
|
||||
* Copyright (C) 2007,2008,2009 Øyvind Harboe *
|
||||
* oyvind.harboe@zylin.com *
|
||||
* *
|
||||
* Copyright (C) 2008 by Spencer Oliver *
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
* Copyright (C) 2005 by Dominic Rath *
|
||||
* Dominic.Rath@gmx.de *
|
||||
* *
|
||||
* Copyright (C) 2007,2008 Øyvind Harboe *
|
||||
* Copyright (C) 2007,2008,2009 Øyvind Harboe *
|
||||
* oyvind.harboe@zylin.com *
|
||||
* *
|
||||
* Copyright (C) 2008 by Spencer Oliver *
|
||||
|
@ -202,6 +202,11 @@ struct target_type_s
|
|||
|
||||
int (*mmu)(struct target_s *target, int *enabled);
|
||||
|
||||
/* Read coprocessor - arm specific. Default implementation returns error. */
|
||||
int (*mrc)(struct target_s *target, int cpnum, uint32_t op1, uint32_t op2, uint32_t CRn, uint32_t CRm, uint32_t *value);
|
||||
|
||||
/* Write coprocessor. Default implementation returns error. */
|
||||
int (*mcr)(struct target_s *target, int cpnum, uint32_t op1, uint32_t op2, uint32_t CRn, uint32_t CRm, uint32_t value);
|
||||
};
|
||||
|
||||
#endif // TARGET_TYPE_H
|
||||
|
|
Loading…
Reference in New Issue