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>
diff --git a/hw/semihosting/config.c b/hw/semihosting/config.c
index f1d3fe1..2a8e7e1 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 @@
.name = "target",
.type = QEMU_OPT_STRING,
}, {
+ .name = "chardev",
+ .type = QEMU_OPT_STRING,
+ }, {
.name = "arg",
.type = QEMU_OPT_STRING,
},
@@ -46,12 +50,14 @@
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 @@
}
}
+Chardev *semihosting_get_chardev(void)
+{
+ return semihosting.chardev;
+}
+
void qemu_semihosting_enable(void)
{
semihosting.enabled = true;
@@ -132,6 +143,8 @@
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 @@
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 01826bd..466ea6d 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);
+ }
}
/*