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 > >