From 34855b39beb63ca3cdeabbd704ea610268837ced Mon Sep 17 00:00:00 2001 From: Sean Anderson Date: Mon, 4 Apr 2022 14:18:00 -0400 Subject: [PATCH] serial: smh: Implement puts for DM This adds an implementation of puts for DM. The implementation is not as clean as for the non-DM puts because we have to handle non-nul-terminated string. We also handle short writes (though these are probably very unusual). Signed-off-by: Sean Anderson --- drivers/serial/Kconfig | 1 + drivers/serial/serial_semihosting.c | 31 +++++++++++++++++++++++++++++++ 2 files changed, 32 insertions(+) diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig index 6b189f8..dc514c9 100644 --- a/drivers/serial/Kconfig +++ b/drivers/serial/Kconfig @@ -834,6 +834,7 @@ config SH_SCIF_CLK_FREQ config SEMIHOSTING_SERIAL bool "Semihosting UART support" depends on SEMIHOSTING && !SERIAL_RX_BUFFER + imply SERIAL_PUTS help Select this to enable a serial UART using semihosting. Special halt instructions will be issued which an external debugger (such as a diff --git a/drivers/serial/serial_semihosting.c b/drivers/serial/serial_semihosting.c index 62b1b22..4328b3d 100644 --- a/drivers/serial/serial_semihosting.c +++ b/drivers/serial/serial_semihosting.c @@ -5,12 +5,14 @@ #include #include +#include #include #include /** * struct smh_serial_priv - Semihosting serial private data * @infd: stdin file descriptor (or error) + * @outfd: stdout file descriptor (or error) */ struct smh_serial_priv { int infd; @@ -36,8 +38,36 @@ static int smh_serial_putc(struct udevice *dev, const char ch) return 0; } +static ssize_t smh_serial_puts(struct udevice *dev, const char *s, size_t len) +{ + int ret; + struct smh_serial_priv *priv = dev_get_priv(dev); + unsigned long written; + + if (priv->outfd < 0) { + char *buf; + + /* Try and avoid a copy if we can */ + if (!s[len + 1]) { + smh_puts(s); + return len; + } + + buf = strndup(s, len); + smh_puts(buf); + free(buf); + return len; + } + + ret = smh_write(priv->outfd, s, len, &written); + if (written) + return written; + return ret; +} + static const struct dm_serial_ops smh_serial_ops = { .putc = smh_serial_putc, + .puts = smh_serial_puts, .getc = smh_serial_getc, }; @@ -53,6 +83,7 @@ static int smh_serial_probe(struct udevice *dev) struct smh_serial_priv *priv = dev_get_priv(dev); priv->infd = smh_open(":tt", MODE_READ); + priv->outfd = smh_open(":tt", MODE_WRITE); return 0; } -- 2.7.4