diff mbox series

semihosting: Merge semihosting console init functions to fix READC

Message ID 20201028213512.3002352-1-keithp@keithp.com
State New, archived
Headers show
Series semihosting: Merge semihosting console init functions to fix READC | expand

Commit Message

Keith Packard Oct. 28, 2020, 9:35 p.m. UTC
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(-)
diff mbox series

Patch

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) {