[PATCH 4/4] serial: smh: Implement puts for DM

Sean Anderson sean.anderson at seco.com
Mon Apr 4 20:18:00 CEST 2022


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 <sean.anderson at seco.com>
---

 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 fae82598cb..4ced6c0a5d 100644
--- a/drivers/serial/Kconfig
+++ b/drivers/serial/Kconfig
@@ -808,6 +808,7 @@ config SCIF_CONSOLE
 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 62b1b2241b..4328b3dac5 100644
--- a/drivers/serial/serial_semihosting.c
+++ b/drivers/serial/serial_semihosting.c
@@ -5,12 +5,14 @@
 
 #include <common.h>
 #include <dm.h>
+#include <malloc.h>
 #include <serial.h>
 #include <semihosting.h>
 
 /**
  * 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.35.1.1320.gc452695387.dirty



More information about the U-Boot mailing list