summaryrefslogtreecommitdiff
path: root/src/target/arm7_9_common.c
diff options
context:
space:
mode:
authorNicolas Pitre <nico@fluxnic.net>2009-12-03 17:27:13 -0500
committerDavid Brownell <dbrownell@users.sourceforge.net>2009-12-03 18:42:01 -0800
commited59dfc80aa6fc48a0894c8e46cee675f38ac949 (patch)
tree2f0e0d1f3efb989f5b43f794536cce04bbd3e622 /src/target/arm7_9_common.c
parentf62c035c5277871193fa9904f430cf57221c0b89 (diff)
downloadopenocd_libswd-ed59dfc80aa6fc48a0894c8e46cee675f38ac949.tar.gz
openocd_libswd-ed59dfc80aa6fc48a0894c8e46cee675f38ac949.tar.bz2
openocd_libswd-ed59dfc80aa6fc48a0894c8e46cee675f38ac949.tar.xz
openocd_libswd-ed59dfc80aa6fc48a0894c8e46cee675f38ac949.zip
basic ARM semihosting support
Semihosting enables code running on an ARM target to use the I/O facilities on the host computer. The target application must be linked against a library that forwards operation requests by using the SVC instruction that is trapped at the Supervisor Call vector by the debugger. The "hosted" library version provided with CodeSourcery's Sourcery G++ Lite for ARM EABI is one example. This is currently available for ARM9 processors, but any ARM variant should be able to support this with little additional work. Tested using binaries compiled with Sourcery G++ Lite 2009q1-161 and ARM RVCT 3.0. [dbrownell@users.sourceforge.net: doc tweaks, NEWS] Signed-off-by: Nicolas Pitre <nico@marvell.com> Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
Diffstat (limited to 'src/target/arm7_9_common.c')
-rw-r--r--src/target/arm7_9_common.c44
1 files changed, 44 insertions, 0 deletions
diff --git a/src/target/arm7_9_common.c b/src/target/arm7_9_common.c
index 255a85f5..7318b5f3 100644
--- a/src/target/arm7_9_common.c
+++ b/src/target/arm7_9_common.c
@@ -36,6 +36,7 @@
#include "etm.h"
#include <helper/time_support.h>
#include "arm_simulator.h"
+#include "arm_semihosting.h"
#include "algorithm.h"
#include "register.h"
@@ -915,6 +916,9 @@ int arm7_9_poll(struct target *target)
}
}
+ if (arm_semihosting(target, &retval) != 0)
+ return retval;
+
if ((retval = target_call_event_callbacks(target, TARGET_EVENT_HALTED)) != ERROR_OK)
{
return retval;
@@ -2814,6 +2818,39 @@ COMMAND_HANDLER(handle_arm7_9_dcc_downloads_command)
return ERROR_OK;
}
+COMMAND_HANDLER(handle_arm7_9_semihosting_command)
+{
+ struct target *target = get_current_target(CMD_CTX);
+ struct arm7_9_common *arm7_9 = target_to_arm7_9(target);
+
+ if (!is_arm7_9(arm7_9))
+ {
+ command_print(CMD_CTX, "current target isn't an ARM7/ARM9 target");
+ return ERROR_TARGET_INVALID;
+ }
+
+ if (CMD_ARGC > 0)
+ {
+ COMMAND_PARSE_ENABLE(CMD_ARGV[0], semihosting_active);
+
+ /* TODO: support other methods if vector catch is unavailable */
+ if (arm7_9->has_vector_catch) {
+ struct reg *vector_catch = &arm7_9->eice_cache->reg_list[EICE_VEC_CATCH];
+ if (!vector_catch->valid)
+ embeddedice_read_reg(vector_catch);
+ buf_set_u32(vector_catch->value, 2, 1, semihosting_active);
+ embeddedice_store_reg(vector_catch);
+ } else if (semihosting_active) {
+ command_print(CMD_CTX, "vector catch unavailable");
+ semihosting_active = 0;
+ }
+ }
+
+ command_print(CMD_CTX, "semihosting is %s", (semihosting_active) ? "enabled" : "disabled");
+
+ return ERROR_OK;
+}
+
int arm7_9_init_arch_info(struct target *target, struct arm7_9_common *arm7_9)
{
int retval = ERROR_OK;
@@ -2867,6 +2904,13 @@ static const struct command_registration arm7_9_any_command_handlers[] = {
.usage = "<enable | disable>",
.help = "use DCC downloads for larger memory writes",
},
+ {
+ "semihosting",
+ .handler = &handle_arm7_9_semihosting_command,
+ .mode = COMMAND_EXEC,
+ .usage = "<enable | disable>",
+ .help = "activate support for semihosting operations",
+ },
COMMAND_REGISTRATION_DONE
};
const struct command_registration arm7_9_command_handlers[] = {