xref: /openbmc/qemu/linux-user/semihost.c (revision 2e1cacfb)
1 /*
2  * ARM Compatible Semihosting Console Support.
3  *
4  * Copyright (c) 2019 Linaro Ltd
5  *
6  * Currently ARM and RISC-V are unique in having support for
7  * semihosting support in linux-user. So for now we implement the
8  * common console API but just for arm and risc-v linux-user.
9  *
10  * SPDX-License-Identifier: GPL-2.0-or-later
11  */
12 
13 #include "qemu/osdep.h"
14 #include "semihosting/console.h"
15 #include "qemu.h"
16 #include "user-internals.h"
17 #include <termios.h>
18 
19 /*
20  * For linux-user we can safely block. However as we want to return as
21  * soon as a character is read we need to tweak the termio to disable
22  * line buffering. We restore the old mode afterwards in case the
23  * program is expecting more normal behaviour. This is slow but
24  * nothing using semihosting console reading is expecting to be fast.
25  */
26 int qemu_semihosting_console_read(CPUState *cs, void *buf, int len)
27 {
28     int ret;
29     struct termios old_tio, new_tio;
30 
31     /* Disable line-buffering and echo */
32     tcgetattr(STDIN_FILENO, &old_tio);
33     new_tio = old_tio;
34     new_tio.c_lflag &= (~ICANON & ~ECHO);
35     new_tio.c_cc[VMIN] = 1;
36     new_tio.c_cc[VTIME] = 0;
37     tcsetattr(STDIN_FILENO, TCSANOW, &new_tio);
38 
39     ret = fread(buf, 1, len, stdin);
40 
41     /* restore config */
42     tcsetattr(STDIN_FILENO, TCSANOW, &old_tio);
43 
44     return ret;
45 }
46 
47 int qemu_semihosting_console_write(void *buf, int len)
48 {
49     return fwrite(buf, 1, len, stderr);
50 }
51