diff options
author | Alex Bennée <alex.bennee@linaro.org> | 2019-05-14 15:30:14 +0100 |
---|---|---|
committer | Alex Bennée <alex.bennee@linaro.org> | 2019-05-28 10:28:50 +0100 |
commit | 4e7f9032cf9bba8558b0fd5ab6a1366d6d7b8ee0 (patch) | |
tree | b260754fa6471caa695fe9e6ac47a454fc5ccb43 /hw | |
parent | a331c6d774123fd3fdb916e58539920727dd2cbd (diff) |
semihosting: enable chardev backed output for console
It will be useful for a number of use-cases to be able to re-direct
output to a file like we do with serial output. This does the wiring
to allow us to treat then semihosting console like just another
character output device.
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
Diffstat (limited to 'hw')
-rw-r--r-- | hw/semihosting/config.c | 26 | ||||
-rw-r--r-- | hw/semihosting/console.c | 9 |
2 files changed, 34 insertions, 1 deletions
diff --git a/hw/semihosting/config.c b/hw/semihosting/config.c index f1d3fe1e4c..2a8e7e1045 100644 --- a/hw/semihosting/config.c +++ b/hw/semihosting/config.c @@ -23,6 +23,7 @@ #include "qemu/config-file.h" #include "qemu/error-report.h" #include "hw/semihosting/semihost.h" +#include "chardev/char.h" QemuOptsList qemu_semihosting_config_opts = { .name = "semihosting-config", @@ -36,6 +37,9 @@ QemuOptsList qemu_semihosting_config_opts = { .name = "target", .type = QEMU_OPT_STRING, }, { + .name = "chardev", + .type = QEMU_OPT_STRING, + }, { .name = "arg", .type = QEMU_OPT_STRING, }, @@ -46,12 +50,14 @@ QemuOptsList qemu_semihosting_config_opts = { typedef struct SemihostingConfig { bool enabled; SemihostingTarget target; + Chardev *chardev; const char **argv; int argc; const char *cmdline; /* concatenated argv */ } SemihostingConfig; static SemihostingConfig semihosting; +static const char *semihost_chardev; bool semihosting_enabled(void) { @@ -115,6 +121,11 @@ void semihosting_arg_fallback(const char *file, const char *cmd) } } +Chardev *semihosting_get_chardev(void) +{ + return semihosting.chardev; +} + void qemu_semihosting_enable(void) { semihosting.enabled = true; @@ -132,6 +143,8 @@ int qemu_semihosting_config_options(const char *optarg) semihosting.enabled = qemu_opt_get_bool(opts, "enable", 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"); if (target != NULL) { if (strcmp("native", target) == 0) { semihosting.target = SEMIHOSTING_TARGET_NATIVE; @@ -158,3 +171,16 @@ 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 01826bd687..466ea6dade 100644 --- a/hw/semihosting/console.c +++ b/hw/semihosting/console.c @@ -17,13 +17,20 @@ #include "qemu/osdep.h" #include "cpu.h" +#include "hw/semihosting/semihost.h" #include "hw/semihosting/console.h" #include "exec/gdbstub.h" #include "qemu/log.h" +#include "chardev/char.h" int qemu_semihosting_log_out(const char *s, int len) { - return write(STDERR_FILENO, s, len); + Chardev *chardev = semihosting_get_chardev(); + if (chardev) { + return qemu_chr_write_all(chardev, (uint8_t *) s, len); + } else { + return write(STDERR_FILENO, s, len); + } } /* |