Hi,

Can anyone review my patch ?
This patch can improve performance of semihosting with respect to
key-strokes.

Thanks.

On Tue, Oct 18, 2022 at 10:10 AM Kautuk Consul <kcon...@ventanamicro.com>
wrote:

> The semihosting->stdin_fd is initially in blocking mode.
> Due to this there is a possibility that the system software blocks
> waiting for a key-press from the user. This can adversely affect
> various housekeeping aspects of system software such as the
> scheduling of the system software tasks/processes/threads.
>
> Specifically, in my case I am booting the Linux kernel on RISCV
> that routes all console read and write character requests to the
> openSBI firmware. Since the openSBI firmware blocks waiting for a
> key-press and openocd is waiting in getchar() the entire Linux
> kernel scheduling is blocked due to which there are various stalls
> in the kernel.
>
> This patch introduces a new command called semihosting_stdfd that
> enables us to put any of the standard input/output/error fds into
> non-blocking mode. After applying this patch and running the
> semihosting_std command my scheduling and kernel thread stalls were
> removed and I could get the Linux bash prompt and could successfully
> run shell commands and observe their outputs in semihosting console.
>
> This same command can be extended if anyone wants to add more
> controls to the semihosting standard file descriptors.
>
> Also added documentation for this new command.
>
> Signed-off-by: Kautuk Consul <kcon...@ventanamicro.com>
> ---
>  doc/openocd.texi                |  7 ++++
>  src/target/semihosting_common.c | 58 +++++++++++++++++++++++++++++++++
>  2 files changed, 65 insertions(+)
>
> diff --git a/doc/openocd.texi b/doc/openocd.texi
> index 2a8626b80..b0bd976b0 100644
> --- a/doc/openocd.texi
> +++ b/doc/openocd.texi
> @@ -9579,6 +9579,13 @@ Set the base directory for semihosting I/O, either
> an absolute path or a path re
>  Use "." for the current directory.
>  @end deffn
>
> +@deffn {Command} {arm semihosting_stdfd} ['in'|'out'|'err']
> ['blocking'|'nonblocking']
> +@cindex ARM semihosting
> +Set/unset the O_NONBLOCK file status flag in the
> semihosting->std[in|out|err]_fd file descriptor. This file status
> +flag affects the appropriate standard file descriptor's
> blocking/non-blocking status thus affecting the
> +responsiveness of the semihosting console to inputs/outputs from/to
> standard input/output/error file descriptors.
> +@end deffn
> +
>  @section ARMv4 and ARMv5 Architecture
>  @cindex ARMv4
>  @cindex ARMv5
> diff --git a/src/target/semihosting_common.c
> b/src/target/semihosting_common.c
> index dc0dae2c8..94a4883f0 100644
> --- a/src/target/semihosting_common.c
> +++ b/src/target/semihosting_common.c
> @@ -2038,6 +2038,57 @@
> COMMAND_HANDLER(handle_common_semihosting_basedir_command)
>         return ERROR_OK;
>  }
>
> +COMMAND_HANDLER(handle_common_semihosting_stdfd_command)
> +{
> +       struct target *target = get_current_target(CMD_CTX);
> +
> +       if (!target) {
> +               LOG_ERROR("No target selected");
> +               return ERROR_FAIL;
> +       }
> +
> +       struct semihosting *semihosting = target->semihosting;
> +       if (!semihosting) {
> +               command_print(CMD, "semihosting not supported for current
> target");
> +               return ERROR_FAIL;
> +       }
> +
> +       if (!semihosting->is_active) {
> +               command_print(CMD, "semihosting not yet enabled for
> current target");
> +               return ERROR_FAIL;
> +       }
> +
> +       int flags;
> +       int fd;
> +
> +       if (CMD_ARGC < 2 || CMD_ARGC > 2)
> +               return ERROR_COMMAND_SYNTAX_ERROR;
> +
> +       if (strcmp(CMD_ARGV[0], "in") == 0)
> +               fd = semihosting->stdin_fd;
> +       else if (strcmp(CMD_ARGV[0], "out") == 0)
> +               fd = semihosting->stdout_fd;
> +       else if (strcmp(CMD_ARGV[0], "err") == 0)
> +               fd = semihosting->stderr_fd;
> +       else
> +               return ERROR_COMMAND_SYNTAX_ERROR;
> +
> +       if (strcmp(CMD_ARGV[1], "blocking") == 0) {
> +               flags = fcntl(fd, F_GETFL, 0);
> +               flags & O_NONBLOCK ? fcntl(fd, F_SETFL, flags &
> (~O_NONBLOCK)) : 1;
> +       } else if (strcmp(CMD_ARGV[1], "nonblocking") == 0) {
> +               flags = fcntl(fd, F_GETFL, 0);
> +               flags & O_NONBLOCK ? 1 : fcntl(fd, F_SETFL, flags |
> O_NONBLOCK);
> +       } else {
> +               return ERROR_COMMAND_SYNTAX_ERROR;
> +       }
> +
> +       command_print(CMD, "semihosting %s standard fd set to %s",
> +               CMD_ARGV[0], CMD_ARGV[1]);
> +
> +       return ERROR_OK;
> +}
> +
>  const struct command_registration semihosting_common_handlers[] = {
>         {
>                 .name = "semihosting",
> @@ -2088,5 +2139,12 @@ const struct command_registration
> semihosting_common_handlers[] = {
>                 .usage = "[dir]",
>                 .help = "set the base directory for semihosting I/O
> operations",
>         },
> +       {
> +               .name = "semihosting_stdfd",
> +               .handler = handle_common_semihosting_stdfd_command,
> +               .mode = COMMAND_EXEC,
> +               .usage = "['in'|'out'|'err'] ['blocking'|'nonblocking']",
> +               .help = "control the semihosting->std*_fd file descriptor
> flags",
> +       },
>         COMMAND_REGISTRATION_DONE
>  };
> --
> 2.34.1
>
>


Reply via email to