From: "Alex Bennée" <alex.bennee@linaro.org>
To: qemu-devel@nongnu.org
Cc: Keith Packard <keithp@keithp.com>
Subject: Re: [PATCH] Semihost SYS_READC implementation (v4)
Date: Fri, 25 Oct 2019 10:51:55 +0100 [thread overview]
Message-ID: <8736fhm9tw.fsf@linaro.org> (raw)
In-Reply-To: <20191024224622.12371-1-keithp@keithp.com>
Keith Packard <keithp@keithp.com> writes:
> Provides a blocking call to read a character from the console using
> semihosting.chardev, if specified. This takes some careful command
> line options to use stdio successfully as the serial ports, monitor
> and semihost all want to use stdio. Here's a sample set of command
> line options which share stdio betwen semihost, monitor and serial
> ports:
>
> qemu \
> -chardev stdio,mux=on,id=stdio0 \
> -serial chardev:stdio0 \
> -semihosting-config enable=on,chardev=stdio0 \
> -mon chardev=stdio0,mode=readline
I can see the use for this but I'd like to know what you are testing
with. We only have very basic smoketests in check-tcg but I've tested
with the latest arm-semihosting tests and they are all fine so no
regressions there.
>
> This creates a chardev hooked to stdio and then connects all of the
> subsystems to it. A shorter mechanism would be good to hear about.
Please keep version history bellow --- so they get dropped when the
patch is applied.
>
> v2:
> Add implementation in linux-user/arm/semihost.c
>
> v3: (thanks to Paolo Bonzini <pbonzini@redhat.com>)
> Replace hand-rolled fifo with fifo8
> Avoid mixing code and declarations
> Remove spurious (void) cast of function parameters
> Define qemu_semihosting_console_init when CONFIG_USER_ONLY
>
> v4:
> Add qemu_semihosting_console_init to stubs/semihost.c for
> hosts that don't support semihosting
This doesn't appear to be in the diff which is why I'm seeing a compile
failure for non-CONFIG_SEMIHOST machines. However...
>
> Signed-off-by: Keith Packard <keithp@keithp.com>
> ---
> hw/semihosting/console.c | 73 +++++++++++++++++++++++++++++++
> include/hw/semihosting/console.h | 12 +++++
> include/hw/semihosting/semihost.h | 4 ++
> linux-user/arm/semihost.c | 24 ++++++++++
> target/arm/arm-semi.c | 3 +-
> vl.c | 3 ++
> 6 files changed, 117 insertions(+), 2 deletions(-)
>
> diff --git a/hw/semihosting/console.c b/hw/semihosting/console.c
> index b4b17c8afb..197bff079b 100644
> --- a/hw/semihosting/console.c
> +++ b/hw/semihosting/console.c
> @@ -98,3 +98,76 @@ void qemu_semihosting_console_outc(CPUArchState *env, target_ulong addr)
> __func__, addr);
> }
> }
> +
> +#include <pthread.h>
> +#include "chardev/char-fe.h"
> +#include "sysemu/sysemu.h"
> +#include "qemu/main-loop.h"
> +#include "qapi/error.h"
> +#include "qemu/fifo8.h"
> +
> +#define FIFO_SIZE 1024
> +
> +typedef struct SemihostingConsole {
> + CharBackend backend;
> + pthread_mutex_t mutex;
> + pthread_cond_t cond;
> + bool got;
> + Fifo8 fifo;
> +} SemihostingConsole;
> +
> +static SemihostingConsole console = {
> + .mutex = PTHREAD_MUTEX_INITIALIZER,
> + .cond = PTHREAD_COND_INITIALIZER
> +};
> +
> +static int console_can_read(void *opaque)
> +{
> + SemihostingConsole *c = opaque;
> + int ret;
> + pthread_mutex_lock(&c->mutex);
> + ret = (int) fifo8_num_free(&c->fifo);
> + pthread_mutex_unlock(&c->mutex);
> + return ret;
> +}
> +
> +static void console_read(void *opaque, const uint8_t *buf, int size)
> +{
> + SemihostingConsole *c = opaque;
> + pthread_mutex_lock(&c->mutex);
> + while (size-- && !fifo8_is_full(&c->fifo)) {
> + fifo8_push(&c->fifo, *buf++);
> + }
> + pthread_cond_broadcast(&c->cond);
> + pthread_mutex_unlock(&c->mutex);
> +}
> +
> +target_ulong qemu_semihosting_console_inc(CPUArchState *env)
> +{
> + uint8_t ch;
> + SemihostingConsole *c = &console;
> + qemu_mutex_unlock_iothread();
> + pthread_mutex_lock(&c->mutex);
> + while (fifo8_is_empty(&c->fifo)) {
> + pthread_cond_wait(&c->cond, &c->mutex);
> + }
> + ch = fifo8_pop(&c->fifo);
> + pthread_mutex_unlock(&c->mutex);
> + qemu_mutex_lock_iothread();
> + return (target_ulong) ch;
> +}
> +
> +void qemu_semihosting_console_init(void)
> +{
> + Chardev *chr = semihosting_get_chardev();
> +
> + if (chr) {
> + fifo8_create(&console.fifo, FIFO_SIZE);
> + qemu_chr_fe_init(&console.backend, chr, &error_abort);
> + qemu_chr_fe_set_handlers(&console.backend,
> + console_can_read,
> + console_read,
> + NULL, NULL, &console,
> + NULL, true);
> + }
> +}
> diff --git a/include/hw/semihosting/console.h b/include/hw/semihosting/console.h
> index 9be9754bcd..f7d5905b41 100644
> --- a/include/hw/semihosting/console.h
> +++ b/include/hw/semihosting/console.h
> @@ -37,6 +37,18 @@ int qemu_semihosting_console_outs(CPUArchState *env, target_ulong s);
> */
> void qemu_semihosting_console_outc(CPUArchState *env, target_ulong c);
>
> +/**
> + * qemu_semihosting_console_inc:
> + * @env: CPUArchState
> + *
> + * Receive single character from debug console. This
> + * may be the remote gdb session if a softmmu guest is currently being
> + * debugged.
> + *
> + * Returns: character read or -1 on error
> + */
> +target_ulong qemu_semihosting_console_inc(CPUArchState *env);
> +
> /**
> * qemu_semihosting_log_out:
> * @s: pointer to string
> diff --git a/include/hw/semihosting/semihost.h b/include/hw/semihosting/semihost.h
> index 60fc42d851..b8ce5117ae 100644
> --- a/include/hw/semihosting/semihost.h
> +++ b/include/hw/semihosting/semihost.h
> @@ -56,6 +56,9 @@ static inline Chardev *semihosting_get_chardev(void)
> {
> return NULL;
> }
> +static inline void qemu_semihosting_console_init(void)
> +{
> +}
> #else /* !CONFIG_USER_ONLY */
> bool semihosting_enabled(void);
> SemihostingTarget semihosting_get_target(void);
> @@ -68,6 +71,7 @@ Chardev *semihosting_get_chardev(void);
> void qemu_semihosting_enable(void);
> int qemu_semihosting_config_options(const char *opt);
> void qemu_semihosting_connect_chardevs(void);
> +void qemu_semihosting_console_init(void);
> #endif /* CONFIG_USER_ONLY */
>
> #endif /* SEMIHOST_H */
> diff --git a/linux-user/arm/semihost.c b/linux-user/arm/semihost.c
> index a16b525eec..13a097515b 100644
> --- a/linux-user/arm/semihost.c
> +++ b/linux-user/arm/semihost.c
> @@ -47,3 +47,27 @@ void qemu_semihosting_console_outc(CPUArchState *env, target_ulong addr)
> }
> }
> }
> +
> +#include <poll.h>
Headers should go at the top...I was about to discuss the usage of
poll() but I realise we are in linux-user here so non-POSIX portability
isn't an issue.
> +
> +target_ulong qemu_semihosting_console_inc(CPUArchState *env)
> +{
> + uint8_t c;
> + struct pollfd pollfd = {
> + .fd = STDIN_FILENO,
> + .events = POLLIN
> + };
> +
> + if (poll(&pollfd, 1, -1) != 1) {
> + qemu_log_mask(LOG_UNIMP, "%s: unexpected read from stdin failure",
> + __func__);
> + return (target_ulong) -1;
> + }
> +
> + if (read(STDIN_FILENO, &c, 1) != 1) {
> + qemu_log_mask(LOG_UNIMP, "%s: unexpected read from stdin failure",
> + __func__);
> + return (target_ulong) -1;
> + }
> + return (target_ulong) c;
> +}
> diff --git a/target/arm/arm-semi.c b/target/arm/arm-semi.c
> index 6f7b6d801b..47d61f6fe1 100644
> --- a/target/arm/arm-semi.c
> +++ b/target/arm/arm-semi.c
> @@ -802,8 +802,7 @@ target_ulong do_arm_semihosting(CPUARMState *env)
>
> return guestfd_fns[gf->type].readfn(cpu, gf, arg1, len);
> case TARGET_SYS_READC:
> - qemu_log_mask(LOG_UNIMP, "%s: SYS_READC not implemented", __func__);
> - return 0;
> + return qemu_semihosting_console_inc(env);
I'm not sure this would be correct if there was no character available.
The docs imply it blocks although don't say so explicitly AFAICT.
> case TARGET_SYS_ISTTY:
> GET_ARG(0);
>
> diff --git a/vl.c b/vl.c
> index 4489cfb2bb..ac584d97ea 100644
> --- a/vl.c
> +++ b/vl.c
> @@ -4381,6 +4381,9 @@ int main(int argc, char **argv, char **envp)
> ds = init_displaystate();
> qemu_display_init(ds, &dpy);
>
> + /* connect semihosting console input if requested */
> + qemu_semihosting_console_init();
> +
I'd rather rename qemu_semihosting_connect_chardevs to
qemu_semihosting_init and keep all our bits of semihosting setup in
there rather than having multiple calls out of vl.c
> /* must be after terminal init, SDL library changes signal handlers */
> os_setup_signal_handling();
--
Alex Bennée
next prev parent reply other threads:[~2019-10-25 9:56 UTC|newest]
Thread overview: 45+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-10-23 19:26 [PATCH] Semihost SYS_READC implementation (v3) Keith Packard
2019-10-24 17:33 ` no-reply
2019-10-24 18:54 ` Paolo Bonzini
2019-10-24 22:46 ` [PATCH] Semihost SYS_READC implementation (v4) Keith Packard
2019-10-25 9:51 ` Alex Bennée [this message]
2019-10-25 16:36 ` Keith Packard
2019-10-25 16:49 ` Peter Maydell
2019-10-25 19:15 ` Keith Packard
2019-10-25 20:53 ` Peter Maydell
2019-10-25 23:18 ` Keith Packard
2019-11-04 20:42 ` [PATCH] Semihost SYS_READC implementation (v6) Keith Packard
2019-12-17 8:38 ` Alex Bennée
2019-12-17 9:08 ` Paolo Bonzini
2019-12-17 9:51 ` Alex Bennée
2019-12-17 10:04 ` Paolo Bonzini
2019-12-17 12:14 ` [RFC PATCH] semihosting: suspend recieving CPU when blocked (HACK, WIP) Alex Bennée
2019-12-17 12:22 ` Paolo Bonzini
2019-12-17 13:42 ` Alex Bennée
2019-12-17 13:48 ` Paolo Bonzini
2019-12-17 14:18 ` Alex Bennée
2019-12-17 14:39 ` Paolo Bonzini
2019-12-17 14:39 ` Paolo Bonzini
2019-12-18 17:36 ` Alex Bennée
2019-12-18 21:23 ` Paolo Bonzini
2019-11-05 5:10 ` [PATCH] Semihost SYS_READC implementation (v4) Keith Packard
2019-11-11 14:51 ` Peter Maydell
2019-11-14 15:46 ` Alistair Francis
2019-11-14 17:43 ` Keith Packard
2019-11-14 17:39 ` Keith Packard
2019-11-14 17:47 ` Peter Maydell
2019-11-14 19:20 ` Peter Maydell
2019-11-14 16:14 ` Peter Maydell
2019-11-14 18:05 ` Keith Packard
2019-11-14 18:18 ` Peter Maydell
2019-11-14 19:18 ` Richard Henderson
2019-11-14 19:29 ` Peter Maydell
2019-11-14 20:52 ` Richard Henderson
2019-11-14 21:04 ` Peter Maydell
2019-11-14 22:26 ` Keith Packard
2019-11-15 10:54 ` Peter Maydell
2019-11-15 23:40 ` Keith Packard
2019-10-25 17:02 ` Alex Bennée
2019-10-25 18:17 ` no-reply
2019-10-25 18:20 ` no-reply
2019-10-24 17:43 ` [PATCH] Semihost SYS_READC implementation (v3) no-reply
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=8736fhm9tw.fsf@linaro.org \
--to=alex.bennee@linaro.org \
--cc=keithp@keithp.com \
--cc=qemu-devel@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).