semihosting: move semihosting cmd to arm cmd group

Move semihosting cmd to the arm cmd group.

Targets that support semihosting will setup the
setup_semihosting callback function.

Signed-off-by: Spencer Oliver <ntfreak@users.sourceforge.net>
This commit is contained in:
Spencer Oliver 2010-02-26 23:29:38 +00:00
parent 550abe7396
commit 9d6ede25dd
4 changed files with 80 additions and 56 deletions

View File

@ -6021,6 +6021,18 @@ Display a table of all banked core registers, fetching the current value from ev
core mode if necessary. core mode if necessary.
@end deffn @end deffn
@deffn Command {arm semihosting} [@option{enable}|@option{disable}]
@cindex ARM semihosting
Display status of semihosting, after optionally changing that status.
Semihosting allows for code executing on an ARM target to use the
I/O facilities on the host computer i.e. the system where OpenOCD
is running. The target application must be linked against a library
implementing the ARM semihosting convention that forwards operation
requests by using a special SVC instruction that is trapped at the
Supervisor Call vector by OpenOCD.
@end deffn
@section ARMv4 and ARMv5 Architecture @section ARMv4 and ARMv5 Architecture
@cindex ARMv4 @cindex ARMv4
@cindex ARMv5 @cindex ARMv5
@ -6073,18 +6085,6 @@ cables (FT2232), but might be unsafe if used with targets running at very low
speeds, like the 32kHz startup clock of an AT91RM9200. speeds, like the 32kHz startup clock of an AT91RM9200.
@end deffn @end deffn
@deffn Command {arm7_9 semihosting} [@option{enable}|@option{disable}]
@cindex ARM semihosting
Display status of semihosting, after optionally changing that status.
Semihosting allows for code executing on an ARM target to use the
I/O facilities on the host computer i.e. the system where OpenOCD
is running. The target application must be linked against a library
implementing the ARM semihosting convention that forwards operation
requests by using a special SVC instruction that is trapped at the
Supervisor Call vector by OpenOCD.
@end deffn
@subsection ARM720T specific commands @subsection ARM720T specific commands
@cindex ARM720T @cindex ARM720T

View File

@ -132,6 +132,8 @@ struct arm {
/** Value to be returned by semihosting SYS_ERRNO request. */ /** Value to be returned by semihosting SYS_ERRNO request. */
int semihosting_errno; int semihosting_errno;
int (*setup_semihosting)(struct target *target, int enable);
/** Backpointer to the target. */ /** Backpointer to the target. */
struct target *target; struct target *target;

View File

@ -2834,54 +2834,32 @@ COMMAND_HANDLER(handle_arm7_9_dcc_downloads_command)
return ERROR_OK; return ERROR_OK;
} }
COMMAND_HANDLER(handle_arm7_9_semihosting_command) int arm7_9_setup_semihosting(struct target *target, int enable)
{ {
struct target *target = get_current_target(CMD_CTX);
struct arm7_9_common *arm7_9 = target_to_arm7_9(target); struct arm7_9_common *arm7_9 = target_to_arm7_9(target);
if (!is_arm7_9(arm7_9)) if (!is_arm7_9(arm7_9))
{ {
command_print(CMD_CTX, "current target isn't an ARM7/ARM9 target"); LOG_USER("current target isn't an ARM7/ARM9 target");
return ERROR_TARGET_INVALID; return ERROR_TARGET_INVALID;
} }
if (CMD_ARGC > 0)
{
int semihosting;
COMMAND_PARSE_ENABLE(CMD_ARGV[0], semihosting);
if (!target_was_examined(target))
{
LOG_ERROR("Target not examined yet");
return ERROR_FAIL;
}
if (arm7_9->has_vector_catch) { if (arm7_9->has_vector_catch) {
struct reg *vector_catch = &arm7_9->eice_cache struct reg *vector_catch = &arm7_9->eice_cache
->reg_list[EICE_VEC_CATCH]; ->reg_list[EICE_VEC_CATCH];
if (!vector_catch->valid) if (!vector_catch->valid)
embeddedice_read_reg(vector_catch); embeddedice_read_reg(vector_catch);
buf_set_u32(vector_catch->value, 2, 1, semihosting); buf_set_u32(vector_catch->value, 2, 1, enable);
embeddedice_store_reg(vector_catch); embeddedice_store_reg(vector_catch);
} else { } else {
/* TODO: allow optional high vectors and/or BKPT_HARD */ /* TODO: allow optional high vectors and/or BKPT_HARD */
if (semihosting) if (enable)
breakpoint_add(target, 8, 4, BKPT_SOFT); breakpoint_add(target, 8, 4, BKPT_SOFT);
else else
breakpoint_remove(target, 8); breakpoint_remove(target, 8);
} }
/* FIXME never let that "catch" be dropped! */
arm7_9->armv4_5_common.is_semihosting = semihosting;
}
command_print(CMD_CTX, "semihosting is %s",
arm7_9->armv4_5_common.is_semihosting
? "enabled" : "disabled");
return ERROR_OK; return ERROR_OK;
} }
@ -2906,6 +2884,7 @@ int arm7_9_init_arch_info(struct target *target, struct arm7_9_common *arm7_9)
armv4_5->read_core_reg = arm7_9_read_core_reg; armv4_5->read_core_reg = arm7_9_read_core_reg;
armv4_5->write_core_reg = arm7_9_write_core_reg; armv4_5->write_core_reg = arm7_9_write_core_reg;
armv4_5->full_context = arm7_9_full_context; armv4_5->full_context = arm7_9_full_context;
armv4_5->setup_semihosting = arm7_9_setup_semihosting;
retval = arm_init_arch_info(target, armv4_5); retval = arm_init_arch_info(target, armv4_5);
if (retval != ERROR_OK) if (retval != ERROR_OK)
@ -2939,13 +2918,6 @@ static const struct command_registration arm7_9_any_command_handlers[] = {
.usage = "['enable'|'disable']", .usage = "['enable'|'disable']",
.help = "use DCC downloads for larger memory writes", .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 COMMAND_REGISTRATION_DONE
}; };
const struct command_registration arm7_9_command_handlers[] = { const struct command_registration arm7_9_command_handlers[] = {

View File

@ -951,6 +951,49 @@ static int jim_mcrmrc(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
return JIM_OK; return JIM_OK;
} }
COMMAND_HANDLER(handle_arm_semihosting_command)
{
struct target *target = get_current_target(CMD_CTX);
struct arm *arm = target ? target_to_arm(target) : NULL;
if (!is_arm(arm)) {
command_print(CMD_CTX, "current target isn't an ARM");
return ERROR_FAIL;
}
if (!arm->setup_semihosting)
{
command_print(CMD_CTX, "semihosting not supported for current target");
}
if (CMD_ARGC > 0)
{
int semihosting;
COMMAND_PARSE_ENABLE(CMD_ARGV[0], semihosting);
if (!target_was_examined(target))
{
LOG_ERROR("Target not examined yet");
return ERROR_FAIL;
}
if (arm->setup_semihosting(target, semihosting) != ERROR_OK) {
LOG_ERROR("Failed to Configure semihosting");
return ERROR_FAIL;
}
/* FIXME never let that "catch" be dropped! */
arm->is_semihosting = semihosting;
}
command_print(CMD_CTX, "semihosting is %s",
arm->is_semihosting
? "enabled" : "disabled");
return ERROR_OK;
}
static const struct command_registration arm_exec_command_handlers[] = { static const struct command_registration arm_exec_command_handlers[] = {
{ {
.name = "reg", .name = "reg",
@ -985,6 +1028,13 @@ static const struct command_registration arm_exec_command_handlers[] = {
.help = "read coprocessor register", .help = "read coprocessor register",
.usage = "cpnum op1 CRn op2 CRm", .usage = "cpnum op1 CRn op2 CRm",
}, },
{
"semihosting",
.handler = handle_arm_semihosting_command,
.mode = COMMAND_EXEC,
.usage = "['enable'|'disable']",
.help = "activate support for semihosting operations",
},
COMMAND_REGISTRATION_DONE COMMAND_REGISTRATION_DONE
}; };