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 <kei...@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(-) diff --git a/hw/semihosting/config.c b/hw/semihosting/config.c index 9807f10cb0..1bf3125f0c 100644 --- a/hw/semihosting/config.c +++ b/hw/semihosting/config.c @@ -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; - } -} diff --git a/hw/semihosting/console.c b/hw/semihosting/console.c index 9b4fee9260..345f21b8e5 100644 --- a/hw/semihosting/console.c +++ b/hw/semihosting/console.c @@ -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); } diff --git a/include/hw/semihosting/semihost.h b/include/hw/semihosting/semihost.h index b8ce5117ae..bbde8bd807 100644 --- a/include/hw/semihosting/semihost.h +++ b/include/hw/semihosting/semihost.h @@ -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); diff --git a/softmmu/vl.c b/softmmu/vl.c index 7c1c6d37ef..b2bad58575 100644 --- a/softmmu/vl.c +++ b/softmmu/vl.c @@ -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) { -- 2.28.0