@@ -51,14 +51,13 @@ QemuOptsList qemu_semihosting_config_opts = {
typedef struct SemihostingConfig {
bool enabled;
SemihostingTarget target;
- Chardev *chardev;
+ const char *chardev;
const char **argv;
int argc;
const char *cmdline; /* concatenated argv */
} SemihostingConfig;
static SemihostingConfig semihosting;
-static const char *semihost_chardev;
bool semihosting_enabled(void)
{
@@ -122,7 +121,7 @@ void semihosting_arg_fallback(const char *file, const char *cmd)
}
}
-Chardev *semihosting_get_chardev(void)
+const char *semihosting_get_chardev(void)
{
return semihosting.chardev;
}
@@ -145,7 +144,7 @@ int qemu_semihosting_config_options(const char *optarg)
true);
const char *target = qemu_opt_get(opts, "target");
/* setup of chardev is deferred until they are initialised */
- semihost_chardev = qemu_opt_get(opts, "chardev");
+ semihosting.chardev = qemu_opt_get(opts, "chardev");
if (target != NULL) {
if (strcmp("native", target) == 0) {
semihosting.target = SEMIHOSTING_TARGET_NATIVE;
@@ -171,17 +170,3 @@ int qemu_semihosting_config_options(const char *optarg)
return 0;
}
-
-void qemu_semihosting_connect_chardevs(void)
-{
- /* We had to defer this until chardevs were created */
- if (semihost_chardev) {
- Chardev *chr = qemu_chr_find(semihost_chardev);
- if (chr == NULL) {
- error_report("semihosting chardev '%s' not found",
- semihost_chardev);
- exit(1);
- }
- semihosting.chardev = chr;
- }
-}
@@ -29,11 +29,23 @@
#include "qapi/error.h"
#include "qemu/fifo8.h"
+#define FIFO_SIZE 1024
+
+/* Access to this structure is protected by the BQL */
+typedef struct SemihostingConsole {
+ CharBackend backend;
+ GSList *sleeping_cpus;
+ bool got;
+ Fifo8 fifo;
+ Chardev *chardev;
+} SemihostingConsole;
+
+static SemihostingConsole console;
+
int qemu_semihosting_log_out(const char *s, int len)
{
- Chardev *chardev = semihosting_get_chardev();
- if (chardev) {
- return qemu_chr_write_all(chardev, (uint8_t *) s, len);
+ if (console.chardev) {
+ return qemu_chr_write_all(console.chardev, (uint8_t *) s, len);
} else {
return write(STDERR_FILENO, s, len);
}
@@ -107,17 +119,6 @@ void qemu_semihosting_console_outc(CPUArchState *env, target_ulong addr)
}
}
-#define FIFO_SIZE 1024
-
-/* Access to this structure is protected by the BQL */
-typedef struct SemihostingConsole {
- CharBackend backend;
- GSList *sleeping_cpus;
- bool got;
- Fifo8 fifo;
-} SemihostingConsole;
-
-static SemihostingConsole console;
static int console_can_read(void *opaque)
{
@@ -166,15 +167,24 @@ target_ulong qemu_semihosting_console_inc(CPUArchState *env)
void qemu_semihosting_console_init(void)
{
- Chardev *chr = semihosting_get_chardev();
-
- if (chr) {
- fifo8_create(&console.fifo, FIFO_SIZE);
- qemu_chr_fe_init(&console.backend, chr, &error_abort);
- qemu_chr_fe_set_handlers(&console.backend,
- console_can_read,
- console_read,
- NULL, NULL, &console,
- NULL, true);
+ const char *chardev = semihosting_get_chardev();
+
+ if (chardev == NULL) {
+ return;
}
+
+ console.chardev = qemu_chr_find(chardev);
+
+ if (console.chardev == NULL) {
+ error_report("semihosting chardev '%s' not found", chardev);
+ exit(1);
+ }
+
+ fifo8_create(&console.fifo, FIFO_SIZE);
+ qemu_chr_fe_init(&console.backend, console.chardev, &error_abort);
+ qemu_chr_fe_set_handlers(&console.backend,
+ console_can_read,
+ console_read,
+ NULL, NULL, &console,
+ NULL, true);
}
@@ -52,7 +52,7 @@ static inline const char *semihosting_get_cmdline(void)
return NULL;
}
-static inline Chardev *semihosting_get_chardev(void)
+static inline const char *semihosting_get_chardev(void)
{
return NULL;
}
@@ -66,7 +66,7 @@ const char *semihosting_get_arg(int i);
int semihosting_get_argc(void);
const char *semihosting_get_cmdline(void);
void semihosting_arg_fallback(const char *file, const char *cmd);
-Chardev *semihosting_get_chardev(void);
+const char *semihosting_get_chardev(void);
/* for vl.c hooks */
void qemu_semihosting_enable(void);
int qemu_semihosting_config_options(const char *opt);
@@ -4284,9 +4284,6 @@ void qemu_init(int argc, char **argv, char **envp)
qemu_opts_foreach(qemu_find_opts("mon"),
mon_init_func, NULL, &error_fatal);
- /* connect semihosting console input if requested */
- qemu_semihosting_console_init();
-
if (foreach_device_config(DEV_SERIAL, serial_parse) < 0)
exit(1);
if (foreach_device_config(DEV_PARALLEL, parallel_parse) < 0)
@@ -4295,7 +4292,7 @@ void qemu_init(int argc, char **argv, char **envp)
exit(1);
/* now chardevs have been created we may have semihosting to connect */
- qemu_semihosting_connect_chardevs();
+ qemu_semihosting_console_init();
/* If no default VGA is requested, the default is "none". */
if (default_vga) {
Commit 619985e937 (semihosting: defer connect_chardevs a little more to use serialx) moved the call to qemu_semihosting_connect_chardevs until after all of the serial devices were initialized to make semihosting console configuration easier. This change broke semihosting console input as the call to qemu_semihosting_console_init was now made *before* qemu_semihosting_connect_chardevs, which it requires. To fix that, and to make sure it doesn't happen in the future, I've merged these two functions together into qemu_semihosting_console_init, which finds the Chardev and then wires up console input. These were split when semihosting READC was added to control the priority of semihosting input compared with other users of a multiplexed console. With connect_chardevs now occuring much later in qemu initialization, the semihosting console input will have the same priority as it did before the referenced commit was applied. Signed-off-by: Keith Packard <keithp@keithp.com> --- hw/semihosting/config.c | 21 ++--------- hw/semihosting/console.c | 58 ++++++++++++++++++------------- include/hw/semihosting/semihost.h | 4 +-- softmmu/vl.c | 5 +-- 4 files changed, 40 insertions(+), 48 deletions(-)