[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [PATCH v4 53/53] semihosting: Create semihost_sys_poll_one
From: |
Luc Michel |
Subject: |
Re: [PATCH v4 53/53] semihosting: Create semihost_sys_poll_one |
Date: |
Mon, 27 Jun 2022 11:01:46 +0200 |
User-agent: |
Mutt/1.9.4 (2018-02-28) |
On 13:45 Tue 07 Jun , Richard Henderson wrote:
> This will be used for implementing the xtensa select_one
> system call. Choose "poll" over "select" so that we can
> reuse Glib's g_poll constants and to avoid struct timeval.
>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Luc Michel <lmichel@kalray.eu>
> ---
> include/semihosting/console.h | 16 ++++++++
> include/semihosting/syscalls.h | 3 ++
> semihosting/console.c | 19 ++++++++-
> semihosting/syscalls.c | 70 ++++++++++++++++++++++++++++++++++
> 4 files changed, 106 insertions(+), 2 deletions(-)
>
> diff --git a/include/semihosting/console.h b/include/semihosting/console.h
> index 20c31d89d4..61b0cb3a94 100644
> --- a/include/semihosting/console.h
> +++ b/include/semihosting/console.h
> @@ -53,4 +53,20 @@ int qemu_semihosting_console_write(void *buf, int len);
> */
> int qemu_semihosting_log_out(const char *s, int len);
>
> +/*
> + * qemu_semihosting_console_block_until_ready:
> + * @cs: CPUState
> + *
> + * If no data is available we suspend the CPU and will re-execute the
> + * instruction when data is available.
> + */
> +void qemu_semihosting_console_block_until_ready(CPUState *cs);
> +
> +/**
> + * qemu_semihosting_console_ready:
> + *
> + * Return true if characters are available for read; does not block.
> + */
> +bool qemu_semihosting_console_ready(void);
> +
> #endif /* SEMIHOST_CONSOLE_H */
> diff --git a/include/semihosting/syscalls.h b/include/semihosting/syscalls.h
> index 347200cb9f..3a5ec229eb 100644
> --- a/include/semihosting/syscalls.h
> +++ b/include/semihosting/syscalls.h
> @@ -69,4 +69,7 @@ void semihost_sys_system(CPUState *cs,
> gdb_syscall_complete_cb complete,
> void semihost_sys_gettimeofday(CPUState *cs, gdb_syscall_complete_cb
> complete,
> target_ulong tv_addr, target_ulong tz_addr);
>
> +void semihost_sys_poll_one(CPUState *cs, gdb_syscall_complete_cb complete,
> + int fd, GIOCondition cond, int timeout);
> +
> #endif /* SEMIHOSTING_SYSCALLS_H */
> diff --git a/semihosting/console.c b/semihosting/console.c
> index c84ab97ab6..cda7cf1905 100644
> --- a/semihosting/console.c
> +++ b/semihosting/console.c
> @@ -77,10 +77,17 @@ static void console_read(void *opaque, const uint8_t
> *buf, int size)
> c->sleeping_cpus = NULL;
> }
>
> -int qemu_semihosting_console_read(CPUState *cs, void *buf, int len)
> +bool qemu_semihosting_console_ready(void)
> +{
> + SemihostingConsole *c = &console;
> +
> + g_assert(qemu_mutex_iothread_locked());
> + return !fifo8_is_empty(&c->fifo);
> +}
> +
> +void qemu_semihosting_console_block_until_ready(CPUState *cs)
> {
> SemihostingConsole *c = &console;
> - int ret = 0;
>
> g_assert(qemu_mutex_iothread_locked());
>
> @@ -92,6 +99,14 @@ int qemu_semihosting_console_read(CPUState *cs, void *buf,
> int len)
> cpu_loop_exit(cs);
> /* never returns */
> }
> +}
> +
> +int qemu_semihosting_console_read(CPUState *cs, void *buf, int len)
> +{
> + SemihostingConsole *c = &console;
> + int ret = 0;
> +
> + qemu_semihosting_console_block_until_ready(cs);
>
> /* Read until buffer full or fifo exhausted. */
> do {
> diff --git a/semihosting/syscalls.c b/semihosting/syscalls.c
> index 9e499b1751..4847f66c02 100644
> --- a/semihosting/syscalls.c
> +++ b/semihosting/syscalls.c
> @@ -520,6 +520,21 @@ static void host_gettimeofday(CPUState *cs,
> gdb_syscall_complete_cb complete,
> unlock_user(p, tv_addr, sizeof(struct gdb_timeval));
> }
>
> +#ifndef CONFIG_USER_ONLY
> +static void host_poll_one(CPUState *cs, gdb_syscall_complete_cb complete,
> + GuestFD *gf, GIOCondition cond, int timeout)
> +{
> + /*
> + * Since this is only used by xtensa in system mode, and stdio is
> + * handled through GuestFDConsole, and there are no semihosting
> + * system calls for sockets and the like, that means this descriptor
> + * must be a normal file. Normal files never block and are thus
> + * always ready.
> + */
> + complete(cs, cond & (G_IO_IN | G_IO_OUT), 0);
> +}
> +#endif
> +
> /*
> * Static file semihosting syscall implementations.
> */
> @@ -628,6 +643,34 @@ static void console_fstat(CPUState *cs,
> gdb_syscall_complete_cb complete,
> complete(cs, ret ? -1 : 0, ret ? -ret : 0);
> }
>
> +#ifndef CONFIG_USER_ONLY
> +static void console_poll_one(CPUState *cs, gdb_syscall_complete_cb complete,
> + GuestFD *gf, GIOCondition cond, int timeout)
> +{
> + /* The semihosting console does not support urgent data or errors. */
> + cond &= G_IO_IN | G_IO_OUT;
> +
> + /*
> + * Since qemu_semihosting_console_write never blocks, we can
> + * consider output always ready -- leave G_IO_OUT alone.
> + * All that remains is to conditionally signal input ready.
> + * Since output ready causes an immediate return, only block
> + * for G_IO_IN alone.
> + *
> + * TODO: Implement proper timeout. For now, only support
> + * indefinite wait or immediate poll.
> + */
> + if (cond == G_IO_IN && timeout < 0) {
> + qemu_semihosting_console_block_until_ready(cs);
> + /* We returned -- input must be ready. */
> + } else if ((cond & G_IO_IN) && !qemu_semihosting_console_ready()) {
> + cond &= ~G_IO_IN;
> + }
> +
> + complete(cs, cond, 0);
> +}
> +#endif
> +
> /*
> * Syscall entry points.
> */
> @@ -906,3 +949,30 @@ void semihost_sys_gettimeofday(CPUState *cs,
> gdb_syscall_complete_cb complete,
> host_gettimeofday(cs, complete, tv_addr, tz_addr);
> }
> }
> +
> +#ifndef CONFIG_USER_ONLY
> +void semihost_sys_poll_one(CPUState *cs, gdb_syscall_complete_cb complete,
> + int fd, GIOCondition cond, int timeout)
> +{
> + GuestFD *gf = get_guestfd(fd);
> +
> + if (!gf) {
> + complete(cs, G_IO_NVAL, 1);
> + return;
> + }
> + switch (gf->type) {
> + case GuestFDGDB:
> + complete(cs, G_IO_NVAL, 1);
> + break;
> + case GuestFDHost:
> + host_poll_one(cs, complete, gf, cond, timeout);
> + break;
> + case GuestFDConsole:
> + console_poll_one(cs, complete, gf, cond, timeout);
> + break;
> + case GuestFDStatic:
> + default:
> + g_assert_not_reached();
> + }
> +}
> +#endif
> --
> 2.34.1
>
>
>
>
> To declare a filtering error, please use the following link :
> https://www.security-mail.net/reporter.php?mid=10175.629fd339.9c340.0&r=lmichel%40kalrayinc.com&s=qemu-devel-bounces%2Blmichel%3Dkalrayinc.com%40nongnu.org&o=%5BPATCH+v4+53%2F53%5D+semihosting%3A+Create+semihost_sys_poll_one&verdict=C&c=0a7b4120e6d77de407da84480eecf3246fb89c81
>
--
- [PATCH v4 43/53] semihosting: Expand qemu_semihosting_console_inc to read, (continued)
- [PATCH v4 43/53] semihosting: Expand qemu_semihosting_console_inc to read, Richard Henderson, 2022/06/07
- [PATCH v4 51/53] semihosting: Use console_out_gf for SYS_WRITE0, Richard Henderson, 2022/06/07
- [PATCH v4 50/53] semihosting: Remove qemu_semihosting_console_outc, Richard Henderson, 2022/06/07
- [PATCH v4 52/53] semihosting: Remove qemu_semihosting_console_outs, Richard Henderson, 2022/06/07
- [PATCH v4 53/53] semihosting: Create semihost_sys_poll_one, Richard Henderson, 2022/06/07
- Re: [PATCH v4 53/53] semihosting: Create semihost_sys_poll_one,
Luc Michel <=
- [PATCH v4 44/53] semihosting: Cleanup chardev init, Richard Henderson, 2022/06/07