diff options
author | Nicolas Pitre <nico@fluxnic.net> | 2009-12-03 17:27:13 -0500 |
---|---|---|
committer | David Brownell <dbrownell@users.sourceforge.net> | 2009-12-03 18:42:01 -0800 |
commit | ed59dfc80aa6fc48a0894c8e46cee675f38ac949 (patch) | |
tree | 2f0e0d1f3efb989f5b43f794536cce04bbd3e622 /src/target/arm7_9_common.c | |
parent | f62c035c5277871193fa9904f430cf57221c0b89 (diff) |
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.c | 44 |
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[] = { |