diff options
author | 2023-10-10 11:40:56 +0000 | |
---|---|---|
committer | 2023-10-10 11:40:56 +0000 | |
commit | e02cda008591317b1625707ff8e115a4841aa889 (patch) | |
tree | aee302e3cf8b59ec2d32ec481be3d1afddfc8968 /linux-user/semihost.c | |
parent | cc668e6b7e0ffd8c9d130513d12053cf5eda1d3b (diff) |
Introduce Virtio-loopback epsilon release:
Epsilon release introduces a new compatibility layer which make virtio-loopback
design to work with QEMU and rust-vmm vhost-user backend without require any
changes.
Signed-off-by: Timos Ampelikiotis <t.ampelikiotis@virtualopensystems.com>
Change-Id: I52e57563e08a7d0bdc002f8e928ee61ba0c53dd9
Diffstat (limited to 'linux-user/semihost.c')
-rw-r--r-- | linux-user/semihost.c | 76 |
1 files changed, 76 insertions, 0 deletions
diff --git a/linux-user/semihost.c b/linux-user/semihost.c new file mode 100644 index 000000000..17f074ac5 --- /dev/null +++ b/linux-user/semihost.c @@ -0,0 +1,76 @@ +/* + * ARM Compatible Semihosting Console Support. + * + * Copyright (c) 2019 Linaro Ltd + * + * Currently ARM and RISC-V are unique in having support for + * semihosting support in linux-user. So for now we implement the + * common console API but just for arm and risc-v linux-user. + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#include "qemu/osdep.h" +#include "semihosting/console.h" +#include "qemu.h" +#include "user-internals.h" +#include <termios.h> + +int qemu_semihosting_console_outs(CPUArchState *env, target_ulong addr) +{ + int len = target_strlen(addr); + void *s; + if (len < 0){ + qemu_log_mask(LOG_GUEST_ERROR, + "%s: passed inaccessible address " TARGET_FMT_lx, + __func__, addr); + return 0; + } + s = lock_user(VERIFY_READ, addr, (long)(len + 1), 1); + g_assert(s); /* target_strlen has already verified this will work */ + len = write(STDERR_FILENO, s, len); + unlock_user(s, addr, 0); + return len; +} + +void qemu_semihosting_console_outc(CPUArchState *env, target_ulong addr) +{ + char c; + + if (get_user_u8(c, addr)) { + qemu_log_mask(LOG_GUEST_ERROR, + "%s: passed inaccessible address " TARGET_FMT_lx, + __func__, addr); + } else { + if (write(STDERR_FILENO, &c, 1) != 1) { + qemu_log_mask(LOG_UNIMP, "%s: unexpected write to stdout failure", + __func__); + } + } +} + +/* + * For linux-user we can safely block. However as we want to return as + * soon as a character is read we need to tweak the termio to disable + * line buffering. We restore the old mode afterwards in case the + * program is expecting more normal behaviour. This is slow but + * nothing using semihosting console reading is expecting to be fast. + */ +target_ulong qemu_semihosting_console_inc(CPUArchState *env) +{ + uint8_t c; + struct termios old_tio, new_tio; + + /* Disable line-buffering and echo */ + tcgetattr(STDIN_FILENO, &old_tio); + new_tio = old_tio; + new_tio.c_lflag &= (~ICANON & ~ECHO); + tcsetattr(STDIN_FILENO, TCSANOW, &new_tio); + + c = getchar(); + + /* restore config */ + tcsetattr(STDIN_FILENO, TCSANOW, &old_tio); + + return (target_ulong) c; +} |