mirror of
https://github.com/smaeul/u-boot.git
synced 2025-10-14 04:46:01 +01:00
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 <sean.anderson@seco.com>
This commit is contained in:
parent
679190c41a
commit
34855b39be
@ -834,6 +834,7 @@ config SH_SCIF_CLK_FREQ
|
|||||||
config SEMIHOSTING_SERIAL
|
config SEMIHOSTING_SERIAL
|
||||||
bool "Semihosting UART support"
|
bool "Semihosting UART support"
|
||||||
depends on SEMIHOSTING && !SERIAL_RX_BUFFER
|
depends on SEMIHOSTING && !SERIAL_RX_BUFFER
|
||||||
|
imply SERIAL_PUTS
|
||||||
help
|
help
|
||||||
Select this to enable a serial UART using semihosting. Special halt
|
Select this to enable a serial UART using semihosting. Special halt
|
||||||
instructions will be issued which an external debugger (such as a
|
instructions will be issued which an external debugger (such as a
|
||||||
|
@ -5,12 +5,14 @@
|
|||||||
|
|
||||||
#include <common.h>
|
#include <common.h>
|
||||||
#include <dm.h>
|
#include <dm.h>
|
||||||
|
#include <malloc.h>
|
||||||
#include <serial.h>
|
#include <serial.h>
|
||||||
#include <semihosting.h>
|
#include <semihosting.h>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* struct smh_serial_priv - Semihosting serial private data
|
* struct smh_serial_priv - Semihosting serial private data
|
||||||
* @infd: stdin file descriptor (or error)
|
* @infd: stdin file descriptor (or error)
|
||||||
|
* @outfd: stdout file descriptor (or error)
|
||||||
*/
|
*/
|
||||||
struct smh_serial_priv {
|
struct smh_serial_priv {
|
||||||
int infd;
|
int infd;
|
||||||
@ -36,8 +38,36 @@ static int smh_serial_putc(struct udevice *dev, const char ch)
|
|||||||
return 0;
|
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 = {
|
static const struct dm_serial_ops smh_serial_ops = {
|
||||||
.putc = smh_serial_putc,
|
.putc = smh_serial_putc,
|
||||||
|
.puts = smh_serial_puts,
|
||||||
.getc = smh_serial_getc,
|
.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);
|
struct smh_serial_priv *priv = dev_get_priv(dev);
|
||||||
|
|
||||||
priv->infd = smh_open(":tt", MODE_READ);
|
priv->infd = smh_open(":tt", MODE_READ);
|
||||||
|
priv->outfd = smh_open(":tt", MODE_WRITE);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user