X-Git-Url: https://review.openocd.org/gitweb?a=blobdiff_plain;f=src%2Ftarget%2Fsemihosting_common.c;h=61a69d1bd14a4bcf3d209cb70804390379e06783;hb=7e64e5a895ecd9bf25c5d2b39ff3119dafa30489;hp=beeb4742ab2d9cb1bfe9a60866bd540a848ac3d1;hpb=2517bae6c1438350255dca63e7d1c1e06c64b6bb;p=openocd.git diff --git a/src/target/semihosting_common.c b/src/target/semihosting_common.c index beeb4742ab..61a69d1bd1 100644 --- a/src/target/semihosting_common.c +++ b/src/target/semihosting_common.c @@ -89,6 +89,8 @@ extern int gdb_actual_connections; * Initialize common semihosting support. * * @param target Pointer to the target to initialize. + * @param setup + * @param post_result * @return An error status if there is a problem during initialization. */ int semihosting_common_init(struct target *target, void *setup, @@ -145,7 +147,7 @@ int semihosting_common(struct target *target) { struct semihosting *semihosting = target->semihosting; if (!semihosting) { - /* Silently ignore if the semhosting field was not set. */ + /* Silently ignore if the semihosting field was not set. */ return ERROR_OK; } @@ -225,6 +227,10 @@ int semihosting_common(struct target *target) else { int fd = semihosting_get_field(target, 0, fields); if (semihosting->is_fileio) { + if (fd == 0 || fd == 1 || fd == 2) { + semihosting->result = 0; + break; + } semihosting->hit_fileio = true; fileio_info->identifier = "close"; fileio_info->param_1 = fd; @@ -341,7 +347,7 @@ int semihosting_common(struct target *target) "semihosting: *** application exited normally ***\n"); } } else if (semihosting->param == ADP_STOPPED_RUN_TIME_ERROR) { - /* Chosen more or less arbitrarly to have a nicer message, + /* Chosen more or less arbitrarily to have a nicer message, * otherwise all other return the same exit code 1. */ if (!gdb_actual_connections) exit(1); @@ -445,8 +451,8 @@ int semihosting_common(struct target *target) * - –1 if an error occurs. */ if (semihosting->is_fileio) { - LOG_ERROR("SYS_FLEN not supported by semihosting fileio"); - return ERROR_FAIL; + semihosting->result = -1; + semihosting->sys_errno = EINVAL; } retval = semihosting_read_fields(target, 1, fields); if (retval != ERROR_OK) @@ -690,9 +696,19 @@ int semihosting_common(struct target *target) /* TODO: implement the :semihosting-features special file. * */ if (semihosting->is_fileio) { - if (strcmp((char *)fn, ":tt") == 0) - semihosting->result = 0; - else { + if (strcmp((char *)fn, ":semihosting-features") == 0) { + semihosting->result = -1; + semihosting->sys_errno = EINVAL; + } else if (strcmp((char *)fn, ":tt") == 0) { + if (mode == 0) + semihosting->result = 0; + else if (mode == 4) + semihosting->result = 1; + else if (mode == 8) + semihosting->result = 2; + else + semihosting->result = -1; + } else { semihosting->hit_fileio = true; fileio_info->identifier = "open"; fileio_info->param_1 = addr; @@ -930,6 +946,8 @@ int semihosting_common(struct target *target) uint8_t *fn1 = malloc(len1+1); uint8_t *fn2 = malloc(len2+1); if (!fn1 || !fn2) { + free(fn1); + free(fn2); semihosting->result = -1; semihosting->sys_errno = ENOMEM; } else { @@ -1397,8 +1415,9 @@ static int semihosting_read_fields(struct target *target, size_t number, uint8_t *fields) { struct semihosting *semihosting = target->semihosting; - return target_read_memory(target, semihosting->param, - semihosting->word_size_bytes, number, fields); + /* Use 4-byte multiples to trigger fast memory access. */ + return target_read_memory(target, semihosting->param, 4, + number * (semihosting->word_size_bytes / 4), fields); } /** @@ -1408,8 +1427,9 @@ static int semihosting_write_fields(struct target *target, size_t number, uint8_t *fields) { struct semihosting *semihosting = target->semihosting; - return target_write_memory(target, semihosting->param, - semihosting->word_size_bytes, number, fields); + /* Use 4-byte multiples to trigger fast memory access. */ + return target_write_memory(target, semihosting->param, 4, + number * (semihosting->word_size_bytes / 4), fields); } /** @@ -1443,7 +1463,7 @@ static void semihosting_set_field(struct target *target, uint64_t value, /* ------------------------------------------------------------------------- * Common semihosting commands handlers. */ -__COMMAND_HANDLER(handle_common_semihosting_command) +static __COMMAND_HANDLER(handle_common_semihosting_command) { struct target *target = get_current_target(CMD_CTX); @@ -1454,7 +1474,7 @@ __COMMAND_HANDLER(handle_common_semihosting_command) struct semihosting *semihosting = target->semihosting; if (!semihosting) { - command_print(CMD_CTX, "semihosting not supported for current target"); + command_print(CMD, "semihosting not supported for current target"); return ERROR_FAIL; } @@ -1477,15 +1497,14 @@ __COMMAND_HANDLER(handle_common_semihosting_command) semihosting->is_active = is_active; } - command_print(CMD_CTX, "semihosting is %s", + command_print(CMD, "semihosting is %s", semihosting->is_active ? "enabled" : "disabled"); return ERROR_OK; } - -__COMMAND_HANDLER(handle_common_semihosting_fileio_command) +static __COMMAND_HANDLER(handle_common_semihosting_fileio_command) { struct target *target = get_current_target(CMD_CTX); @@ -1496,26 +1515,26 @@ __COMMAND_HANDLER(handle_common_semihosting_fileio_command) struct semihosting *semihosting = target->semihosting; if (!semihosting) { - command_print(CMD_CTX, "semihosting not supported for current target"); + command_print(CMD, "semihosting not supported for current target"); return ERROR_FAIL; } if (!semihosting->is_active) { - command_print(CMD_CTX, "semihosting not yet enabled for current target"); + command_print(CMD, "semihosting not yet enabled for current target"); return ERROR_FAIL; } if (CMD_ARGC > 0) COMMAND_PARSE_ENABLE(CMD_ARGV[0], semihosting->is_fileio); - command_print(CMD_CTX, "semihosting fileio is %s", + command_print(CMD, "semihosting fileio is %s", semihosting->is_fileio ? "enabled" : "disabled"); return ERROR_OK; } -__COMMAND_HANDLER(handle_common_semihosting_cmdline) +static __COMMAND_HANDLER(handle_common_semihosting_cmdline) { struct target *target = get_current_target(CMD_CTX); unsigned int i; @@ -1527,7 +1546,7 @@ __COMMAND_HANDLER(handle_common_semihosting_cmdline) struct semihosting *semihosting = target->semihosting; if (!semihosting) { - command_print(CMD_CTX, "semihosting not supported for current target"); + command_print(CMD, "semihosting not supported for current target"); return ERROR_FAIL; } @@ -1542,13 +1561,13 @@ __COMMAND_HANDLER(handle_common_semihosting_cmdline) semihosting->cmdline = cmdline; } - command_print(CMD_CTX, "semihosting command line is [%s]", + command_print(CMD, "semihosting command line is [%s]", semihosting->cmdline); return ERROR_OK; } -__COMMAND_HANDLER(handle_common_semihosting_resumable_exit_command) +static __COMMAND_HANDLER(handle_common_semihosting_resumable_exit_command) { struct target *target = get_current_target(CMD_CTX); @@ -1559,21 +1578,53 @@ __COMMAND_HANDLER(handle_common_semihosting_resumable_exit_command) struct semihosting *semihosting = target->semihosting; if (!semihosting) { - command_print(CMD_CTX, "semihosting not supported for current target"); + command_print(CMD, "semihosting not supported for current target"); return ERROR_FAIL; } if (!semihosting->is_active) { - command_print(CMD_CTX, "semihosting not yet enabled for current target"); + command_print(CMD, "semihosting not yet enabled for current target"); return ERROR_FAIL; } if (CMD_ARGC > 0) COMMAND_PARSE_ENABLE(CMD_ARGV[0], semihosting->has_resumable_exit); - command_print(CMD_CTX, "semihosting resumable exit is %s", + command_print(CMD, "semihosting resumable exit is %s", semihosting->has_resumable_exit ? "enabled" : "disabled"); return ERROR_OK; } + +const struct command_registration semihosting_common_handlers[] = { + { + "semihosting", + .handler = handle_common_semihosting_command, + .mode = COMMAND_EXEC, + .usage = "['enable'|'disable']", + .help = "activate support for semihosting operations", + }, + { + "semihosting_cmdline", + .handler = handle_common_semihosting_cmdline, + .mode = COMMAND_EXEC, + .usage = "arguments", + .help = "command line arguments to be passed to program", + }, + { + "semihosting_fileio", + .handler = handle_common_semihosting_fileio_command, + .mode = COMMAND_EXEC, + .usage = "['enable'|'disable']", + .help = "activate support for semihosting fileio operations", + }, + { + "semihosting_resexit", + .handler = handle_common_semihosting_resumable_exit_command, + .mode = COMMAND_EXEC, + .usage = "['enable'|'disable']", + .help = "activate support for semihosting resumable exit", + }, + COMMAND_REGISTRATION_DONE +};