diff options
author | Richard Henderson <richard.henderson@linaro.org> | 2022-05-01 12:31:08 -0700 |
---|---|---|
committer | Richard Henderson <richard.henderson@linaro.org> | 2022-06-28 04:35:52 +0530 |
commit | e7fb6f320548c1b0c25d291466a0249ee80d91b6 (patch) | |
tree | 418c8dc3bae7cc3dfcb21b749ed5fcd5a9f60fe5 /semihosting | |
parent | 3367d452b001e91547634756e32246610701df5c (diff) | |
download | qemu-e7fb6f320548c1b0c25d291466a0249ee80d91b6.zip qemu-e7fb6f320548c1b0c25d291466a0249ee80d91b6.tar.gz qemu-e7fb6f320548c1b0c25d291466a0249ee80d91b6.tar.bz2 |
semihosting: Expand qemu_semihosting_console_inc to read
Allow more than one character to be read at one time.
Will be used by m68k and nios2 semihosting for stdio.
Reviewed-by: Luc Michel <lmichel@kalray.eu>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Diffstat (limited to 'semihosting')
-rw-r--r-- | semihosting/arm-compat-semi.c | 11 | ||||
-rw-r--r-- | semihosting/console.c | 16 |
2 files changed, 21 insertions, 6 deletions
diff --git a/semihosting/arm-compat-semi.c b/semihosting/arm-compat-semi.c index 40f3730..fdb143a 100644 --- a/semihosting/arm-compat-semi.c +++ b/semihosting/arm-compat-semi.c @@ -428,8 +428,15 @@ void do_common_semihosting(CPUState *cs) break; case TARGET_SYS_READC: - ret = qemu_semihosting_console_inc(cs); - common_semi_set_ret(cs, ret); + { + uint8_t ch; + int ret = qemu_semihosting_console_read(cs, &ch, 1); + if (ret == 1) { + common_semi_cb(cs, ch, 0); + } else { + common_semi_cb(cs, -1, EIO); + } + } break; case TARGET_SYS_ISERROR: diff --git a/semihosting/console.c b/semihosting/console.c index 17ece6b..e5ac3f2 100644 --- a/semihosting/console.c +++ b/semihosting/console.c @@ -144,12 +144,14 @@ static void console_read(void *opaque, const uint8_t *buf, int size) c->sleeping_cpus = NULL; } -target_ulong qemu_semihosting_console_inc(CPUState *cs) +int qemu_semihosting_console_read(CPUState *cs, void *buf, int len) { - uint8_t ch; SemihostingConsole *c = &console; + int ret = 0; g_assert(qemu_mutex_iothread_locked()); + + /* Block if the fifo is completely empty. */ if (fifo8_is_empty(&c->fifo)) { c->sleeping_cpus = g_slist_prepend(c->sleeping_cpus, cs); cs->halted = 1; @@ -157,8 +159,14 @@ target_ulong qemu_semihosting_console_inc(CPUState *cs) cpu_loop_exit(cs); /* never returns */ } - ch = fifo8_pop(&c->fifo); - return (target_ulong) ch; + + /* Read until buffer full or fifo exhausted. */ + do { + *(char *)(buf + ret) = fifo8_pop(&c->fifo); + ret++; + } while (ret < len && !fifo8_is_empty(&c->fifo)); + + return ret; } void qemu_semihosting_console_init(void) |