All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] serial: smh: Fake tstc
@ 2022-05-17 17:55 Sean Anderson
  2022-06-07 16:47 ` Tom Rini
  0 siblings, 1 reply; 2+ messages in thread
From: Sean Anderson @ 2022-05-17 17:55 UTC (permalink / raw)
  To: u-boot, Tom Rini; +Cc: Simon Glass, Heinrich Schuchardt, Sean Anderson

ARM semihosting provides no provisions for determining if there is
pending input. The only way to determine if there is console input is to
do a read (and block until the user types something). For this reason,
we always return true for tstc (since you will always get input if you
try). However, this behavior can cause problems for code which expects
tstc to eventually be empty. In query_console_serial, there is the
following construct:

	/* empty input buffer */
	while (tstc())
		getchar();

with the current implementation, this effectively turns into an infinite
loop. To avoid this, fake tstc by returning false half of the time. This
is generally OK because the other common construct looks like

	do {
		if (tstc())
			process(getchar());
	} while (!timeout());

so it's fine if we only read a new character every other loop. This will
break things like CYGACC_COMM_IF_GETC_TIMEOUT, but that could be
reworked to test on the timeout instead of calling tstc again (and
ymodem over semihosted serial is not that useful in the first place).

Signed-off-by: Sean Anderson <sean.anderson@seco.com>
---

 drivers/serial/serial_semihosting.c | 15 ++++++++++++++-
 1 file changed, 14 insertions(+), 1 deletion(-)

diff --git a/drivers/serial/serial_semihosting.c b/drivers/serial/serial_semihosting.c
index 2561414e40..cfa1ec3148 100644
--- a/drivers/serial/serial_semihosting.c
+++ b/drivers/serial/serial_semihosting.c
@@ -13,10 +13,12 @@
  * struct smh_serial_priv - Semihosting serial private data
  * @infd: stdin file descriptor (or error)
  * @outfd: stdout file descriptor (or error)
+ * @counter: Counter used to fake pending every other call
  */
 struct smh_serial_priv {
 	int infd;
 	int outfd;
+	unsigned counter;
 };
 
 #if CONFIG_IS_ENABLED(DM_SERIAL)
@@ -68,10 +70,20 @@ static ssize_t smh_serial_puts(struct udevice *dev, const char *s, size_t len)
 	return ret;
 }
 
+static int smh_serial_pending(struct udevice *dev, bool input)
+{
+	struct smh_serial_priv *priv = dev_get_priv(dev);
+
+	if (input)
+		return priv->counter++ & 1;
+	return false;
+}
+
 static const struct dm_serial_ops smh_serial_ops = {
 	.putc = smh_serial_putc,
 	.puts = smh_serial_puts,
 	.getc = smh_serial_getc,
+	.pending = smh_serial_pending,
 };
 
 static int smh_serial_bind(struct udevice *dev)
@@ -106,6 +118,7 @@ U_BOOT_DRVINFO(smh_serial) = {
 #else /* DM_SERIAL */
 static int infd = -ENODEV;
 static int outfd = -ENODEV;
+static unsigned counter = 1;
 
 static int smh_serial_start(void)
 {
@@ -138,7 +151,7 @@ static int smh_serial_getc(void)
 
 static int smh_serial_tstc(void)
 {
-	return 1;
+	return counter++ & 1;
 }
 
 static void smh_serial_puts(const char *s)
-- 
2.35.1.1320.gc452695387.dirty


^ permalink raw reply related	[flat|nested] 2+ messages in thread

* Re: [PATCH] serial: smh: Fake tstc
  2022-05-17 17:55 [PATCH] serial: smh: Fake tstc Sean Anderson
@ 2022-06-07 16:47 ` Tom Rini
  0 siblings, 0 replies; 2+ messages in thread
From: Tom Rini @ 2022-06-07 16:47 UTC (permalink / raw)
  To: Sean Anderson; +Cc: u-boot, Simon Glass, Heinrich Schuchardt

[-- Attachment #1: Type: text/plain, Size: 1298 bytes --]

On Tue, May 17, 2022 at 01:55:07PM -0400, Sean Anderson wrote:

> ARM semihosting provides no provisions for determining if there is
> pending input. The only way to determine if there is console input is to
> do a read (and block until the user types something). For this reason,
> we always return true for tstc (since you will always get input if you
> try). However, this behavior can cause problems for code which expects
> tstc to eventually be empty. In query_console_serial, there is the
> following construct:
> 
> 	/* empty input buffer */
> 	while (tstc())
> 		getchar();
> 
> with the current implementation, this effectively turns into an infinite
> loop. To avoid this, fake tstc by returning false half of the time. This
> is generally OK because the other common construct looks like
> 
> 	do {
> 		if (tstc())
> 			process(getchar());
> 	} while (!timeout());
> 
> so it's fine if we only read a new character every other loop. This will
> break things like CYGACC_COMM_IF_GETC_TIMEOUT, but that could be
> reworked to test on the timeout instead of calling tstc again (and
> ymodem over semihosted serial is not that useful in the first place).
> 
> Signed-off-by: Sean Anderson <sean.anderson@seco.com>

Applied to u-boot/next, thanks!

-- 
Tom

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 659 bytes --]

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2022-06-07 16:49 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-05-17 17:55 [PATCH] serial: smh: Fake tstc Sean Anderson
2022-06-07 16:47 ` Tom Rini

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.