| /* |
| * 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> |
| |
| /* |
| * 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. |
| */ |
| int qemu_semihosting_console_read(CPUState *cs, void *buf, int len) |
| { |
| int ret; |
| 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); |
| new_tio.c_cc[VMIN] = 1; |
| new_tio.c_cc[VTIME] = 0; |
| tcsetattr(STDIN_FILENO, TCSANOW, &new_tio); |
| |
| ret = fread(buf, 1, len, stdin); |
| |
| /* restore config */ |
| tcsetattr(STDIN_FILENO, TCSANOW, &old_tio); |
| |
| return ret; |
| } |
| |
| int qemu_semihosting_console_write(void *buf, int len) |
| { |
| return fwrite(buf, 1, len, stderr); |
| } |