summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorØyvind Harboe <oyvind.harboe@zylin.com>2009-10-23 12:38:19 +0200
committerØyvind Harboe <oyvind.harboe@zylin.com>2009-10-23 12:39:00 +0200
commit0a1356c9ccff42e2c41af3a3c0ae8b1330aa970b (patch)
treeb769d296e2032240291978b4f8a035c97fd8183a
parent18aad44f7121a4fa76d53a4ae653b047cd9ad916 (diff)
downloadopenocd+libswd-0a1356c9ccff42e2c41af3a3c0ae8b1330aa970b.tar.gz
openocd+libswd-0a1356c9ccff42e2c41af3a3c0ae8b1330aa970b.tar.bz2
openocd+libswd-0a1356c9ccff42e2c41af3a3c0ae8b1330aa970b.tar.xz
openocd+libswd-0a1356c9ccff42e2c41af3a3c0ae8b1330aa970b.zip
mcr/mrc interface work. Implemented for arm926ejs and arm720t. mcr/mrc commands added.
-rw-r--r--src/target/arm720t.c36
-rw-r--r--src/target/arm926ejs.c28
-rw-r--r--src/target/armv4_5.h18
-rw-r--r--src/target/target.c162
-rw-r--r--src/target/target.h2
-rw-r--r--src/target/target_type.h7
6 files changed, 241 insertions, 12 deletions
diff --git a/src/target/arm720t.c b/src/target/arm720t.c
index 71440ebe..6ed66cd6 100644
--- a/src/target/arm720t.c
+++ b/src/target/arm720t.c
@@ -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);
+}
+
+
diff --git a/src/target/arm926ejs.c b/src/target/arm926ejs.c
index 9c9628a3..90611747 100644
--- a/src/target/arm926ejs.c
+++ b/src/target/arm926ejs.c
@@ -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)
diff --git a/src/target/armv4_5.h b/src/target/armv4_5.h
index 7ea3826a..80f28db3 100644
--- a/src/target/armv4_5.h
+++ b/src/target/armv4_5.h
@@ -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 */
diff --git a/src/target/target.c b/src/target/target.c
index eb93fb7b..336a7f71 100644
--- a/src/target/target.c
+++ b/src/target/target.c
@@ -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;
+}
diff --git a/src/target/target.h b/src/target/target.h
index 19d8013a..ef578378 100644
--- a/src/target/target.h
+++ b/src/target/target.h
@@ -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 *
diff --git a/src/target/target_type.h b/src/target/target_type.h
index aab4321f..83baa252 100644
--- a/src/target/target_type.h
+++ b/src/target/target_type.h
@@ -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