diff mbox series

[1/3] serial: Add RISC-V HTIF console driver

Message ID 20220114162008.70468-2-apatel@ventanamicro.com
State Superseded
Delegated to: Andes
Headers show
Series QEMU spike machine support for U-Boot | expand

Commit Message

Anup Patel Jan. 14, 2022, 4:20 p.m. UTC
Quite a few RISC-V emulators and ISS (including Spike) have host
transfer interface (HTIF) based console. This patch adds HTIF
based console driver for RISC-V platforms which depends totally
on DT node for HTIF register base address.

Signed-off-by: Anup Patel <apatel@ventanamicro.com>
Reviewed-by: Philipp Tomsich <philipp.tomsich@vrull.eu>
---
 drivers/serial/Kconfig       |   8 ++
 drivers/serial/Makefile      |   1 +
 drivers/serial/serial_htif.c | 178 +++++++++++++++++++++++++++++++++++
 3 files changed, 187 insertions(+)
 create mode 100644 drivers/serial/serial_htif.c

Comments

Rick Chen Jan. 25, 2022, 1:14 a.m. UTC | #1
> From: Anup Patel <apatel@ventanamicro.com>
> Sent: Saturday, January 15, 2022 12:20 AM
> To: Rick Jian-Zhi Chen(陳建志) <rick@andestech.com>; Bin Meng <bmeng.cn@gmail.com>
> Cc: Atish Patra <atishp@atishpatra.org>; Alistair Francis <Alistair.Francis@wdc.com>; Anup Patel <anup@brainfault.org>; U-Boot Mailing List <u-boot@lists.denx.de>; Anup Patel <apatel@ventanamicro.com>; Philipp Tomsich <philipp.tomsich@vrull.eu>
> Subject: [PATCH 1/3] serial: Add RISC-V HTIF console driver
>
> Quite a few RISC-V emulators and ISS (including Spike) have host transfer interface (HTIF) based console. This patch adds HTIF based console driver for RISC-V platforms which depends totally on DT node for HTIF register base address.
>
> Signed-off-by: Anup Patel <apatel@ventanamicro.com>
> Reviewed-by: Philipp Tomsich <philipp.tomsich@vrull.eu>
> ---
>  drivers/serial/Kconfig       |   8 ++
>  drivers/serial/Makefile      |   1 +
>  drivers/serial/serial_htif.c | 178 +++++++++++++++++++++++++++++++++++
>  3 files changed, 187 insertions(+)

Reviewed-by: Rick Chen <rick@andestech.com>
Bin Meng Jan. 25, 2022, 4:52 a.m. UTC | #2
On Sat, Jan 15, 2022 at 12:20 AM Anup Patel <apatel@ventanamicro.com> wrote:
>
> Quite a few RISC-V emulators and ISS (including Spike) have host
> transfer interface (HTIF) based console. This patch adds HTIF
> based console driver for RISC-V platforms which depends totally
> on DT node for HTIF register base address.
>
> Signed-off-by: Anup Patel <apatel@ventanamicro.com>
> Reviewed-by: Philipp Tomsich <philipp.tomsich@vrull.eu>
> ---
>  drivers/serial/Kconfig       |   8 ++
>  drivers/serial/Makefile      |   1 +
>  drivers/serial/serial_htif.c | 178 +++++++++++++++++++++++++++++++++++
>  3 files changed, 187 insertions(+)
>  create mode 100644 drivers/serial/serial_htif.c
>
> diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig
> index 6c8fdda9a0..345d1881f5 100644
> --- a/drivers/serial/Kconfig
> +++ b/drivers/serial/Kconfig
> @@ -866,6 +866,14 @@ config PXA_SERIAL
>           If you have a machine based on a Marvell XScale PXA2xx CPU you
>           can enable its onboard serial ports by enabling this option.
>
> +config HTIF_CONSOLE
> +       bool "RISC-V HTIF console support"
> +       depends on DM_SERIAL && 64BIT

Does this driver not work on 32-bit?

> +       help
> +         Select this to enable host transfer interface (HTIF) based serial
> +         console. The HTIF device is quite common in RISC-V emulators and
> +         RISC-V ISS so this driver allows using U-Boot on such platforms.
> +
>  config SIFIVE_SERIAL
>         bool "SiFive UART support"
>         depends on DM_SERIAL

Regards,
Bin
Anup Patel Jan. 25, 2022, 6 a.m. UTC | #3
On Tue, Jan 25, 2022 at 10:22 AM Bin Meng <bmeng.cn@gmail.com> wrote:
>
> On Sat, Jan 15, 2022 at 12:20 AM Anup Patel <apatel@ventanamicro.com> wrote:
> >
> > Quite a few RISC-V emulators and ISS (including Spike) have host
> > transfer interface (HTIF) based console. This patch adds HTIF
> > based console driver for RISC-V platforms which depends totally
> > on DT node for HTIF register base address.
> >
> > Signed-off-by: Anup Patel <apatel@ventanamicro.com>
> > Reviewed-by: Philipp Tomsich <philipp.tomsich@vrull.eu>
> > ---
> >  drivers/serial/Kconfig       |   8 ++
> >  drivers/serial/Makefile      |   1 +
> >  drivers/serial/serial_htif.c | 178 +++++++++++++++++++++++++++++++++++
> >  3 files changed, 187 insertions(+)
> >  create mode 100644 drivers/serial/serial_htif.c
> >
> > diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig
> > index 6c8fdda9a0..345d1881f5 100644
> > --- a/drivers/serial/Kconfig
> > +++ b/drivers/serial/Kconfig
> > @@ -866,6 +866,14 @@ config PXA_SERIAL
> >           If you have a machine based on a Marvell XScale PXA2xx CPU you
> >           can enable its onboard serial ports by enabling this option.
> >
> > +config HTIF_CONSOLE
> > +       bool "RISC-V HTIF console support"
> > +       depends on DM_SERIAL && 64BIT
>
> Does this driver not work on 32-bit?

Only putc() works but getc() does not work on 32-bit. Same issue
is there with OpenSBI and BBL as well. That's why I have restricted
this driver to 64-bit only.

>
> > +       help
> > +         Select this to enable host transfer interface (HTIF) based serial
> > +         console. The HTIF device is quite common in RISC-V emulators and
> > +         RISC-V ISS so this driver allows using U-Boot on such platforms.
> > +
> >  config SIFIVE_SERIAL
> >         bool "SiFive UART support"
> >         depends on DM_SERIAL
>
> Regards,
> Bin

Regards,
Anup
Bin Meng Jan. 25, 2022, 9:16 a.m. UTC | #4
On Tue, Jan 25, 2022 at 2:00 PM Anup Patel <apatel@ventanamicro.com> wrote:
>
> On Tue, Jan 25, 2022 at 10:22 AM Bin Meng <bmeng.cn@gmail.com> wrote:
> >
> > On Sat, Jan 15, 2022 at 12:20 AM Anup Patel <apatel@ventanamicro.com> wrote:
> > >
> > > Quite a few RISC-V emulators and ISS (including Spike) have host
> > > transfer interface (HTIF) based console. This patch adds HTIF
> > > based console driver for RISC-V platforms which depends totally
> > > on DT node for HTIF register base address.
> > >
> > > Signed-off-by: Anup Patel <apatel@ventanamicro.com>
> > > Reviewed-by: Philipp Tomsich <philipp.tomsich@vrull.eu>
> > > ---
> > >  drivers/serial/Kconfig       |   8 ++
> > >  drivers/serial/Makefile      |   1 +
> > >  drivers/serial/serial_htif.c | 178 +++++++++++++++++++++++++++++++++++
> > >  3 files changed, 187 insertions(+)
> > >  create mode 100644 drivers/serial/serial_htif.c
> > >
> > > diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig
> > > index 6c8fdda9a0..345d1881f5 100644
> > > --- a/drivers/serial/Kconfig
> > > +++ b/drivers/serial/Kconfig
> > > @@ -866,6 +866,14 @@ config PXA_SERIAL
> > >           If you have a machine based on a Marvell XScale PXA2xx CPU you
> > >           can enable its onboard serial ports by enabling this option.
> > >
> > > +config HTIF_CONSOLE
> > > +       bool "RISC-V HTIF console support"
> > > +       depends on DM_SERIAL && 64BIT
> >
> > Does this driver not work on 32-bit?
>
> Only putc() works but getc() does not work on 32-bit. Same issue
> is there with OpenSBI and BBL as well. That's why I have restricted
> this driver to 64-bit only.
>

I don't get it. Is this a QEMU riscv32 bug?

Regards,
Bin
Anup Patel Jan. 25, 2022, 11:31 a.m. UTC | #5
On Tue, Jan 25, 2022 at 2:46 PM Bin Meng <bmeng.cn@gmail.com> wrote:
>
> On Tue, Jan 25, 2022 at 2:00 PM Anup Patel <apatel@ventanamicro.com> wrote:
> >
> > On Tue, Jan 25, 2022 at 10:22 AM Bin Meng <bmeng.cn@gmail.com> wrote:
> > >
> > > On Sat, Jan 15, 2022 at 12:20 AM Anup Patel <apatel@ventanamicro.com> wrote:
> > > >
> > > > Quite a few RISC-V emulators and ISS (including Spike) have host
> > > > transfer interface (HTIF) based console. This patch adds HTIF
> > > > based console driver for RISC-V platforms which depends totally
> > > > on DT node for HTIF register base address.
> > > >
> > > > Signed-off-by: Anup Patel <apatel@ventanamicro.com>
> > > > Reviewed-by: Philipp Tomsich <philipp.tomsich@vrull.eu>
> > > > ---
> > > >  drivers/serial/Kconfig       |   8 ++
> > > >  drivers/serial/Makefile      |   1 +
> > > >  drivers/serial/serial_htif.c | 178 +++++++++++++++++++++++++++++++++++
> > > >  3 files changed, 187 insertions(+)
> > > >  create mode 100644 drivers/serial/serial_htif.c
> > > >
> > > > diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig
> > > > index 6c8fdda9a0..345d1881f5 100644
> > > > --- a/drivers/serial/Kconfig
> > > > +++ b/drivers/serial/Kconfig
> > > > @@ -866,6 +866,14 @@ config PXA_SERIAL
> > > >           If you have a machine based on a Marvell XScale PXA2xx CPU you
> > > >           can enable its onboard serial ports by enabling this option.
> > > >
> > > > +config HTIF_CONSOLE
> > > > +       bool "RISC-V HTIF console support"
> > > > +       depends on DM_SERIAL && 64BIT
> > >
> > > Does this driver not work on 32-bit?
> >
> > Only putc() works but getc() does not work on 32-bit. Same issue
> > is there with OpenSBI and BBL as well. That's why I have restricted
> > this driver to 64-bit only.
> >
>
> I don't get it. Is this a QEMU riscv32 bug?

It's a bug in the HTIF device itself. There is no documentation of
HTIF as well. All implementations (including QEMU spike) simply
follow how Spike ISS implements HTIF.

In other words, HTIF is yet another undocumented device in
RISC-V world.

Regards,
Anup
diff mbox series

Patch

diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig
index 6c8fdda9a0..345d1881f5 100644
--- a/drivers/serial/Kconfig
+++ b/drivers/serial/Kconfig
@@ -866,6 +866,14 @@  config PXA_SERIAL
 	  If you have a machine based on a Marvell XScale PXA2xx CPU you
 	  can enable its onboard serial ports by enabling this option.
 
+config HTIF_CONSOLE
+	bool "RISC-V HTIF console support"
+	depends on DM_SERIAL && 64BIT
+	help
+	  Select this to enable host transfer interface (HTIF) based serial
+	  console. The HTIF device is quite common in RISC-V emulators and
+	  RISC-V ISS so this driver allows using U-Boot on such platforms.
+
 config SIFIVE_SERIAL
 	bool "SiFive UART support"
 	depends on DM_SERIAL
diff --git a/drivers/serial/Makefile b/drivers/serial/Makefile
index 8168af640f..52e70aa191 100644
--- a/drivers/serial/Makefile
+++ b/drivers/serial/Makefile
@@ -73,6 +73,7 @@  obj-$(CONFIG_OWL_SERIAL) += serial_owl.o
 obj-$(CONFIG_OMAP_SERIAL) += serial_omap.o
 obj-$(CONFIG_MTK_SERIAL) += serial_mtk.o
 obj-$(CONFIG_MT7620_SERIAL) += serial_mt7620.o
+obj-$(CONFIG_HTIF_CONSOLE) += serial_htif.o
 obj-$(CONFIG_SIFIVE_SERIAL) += serial_sifive.o
 obj-$(CONFIG_XEN_SERIAL) += serial_xen.o
 
diff --git a/drivers/serial/serial_htif.c b/drivers/serial/serial_htif.c
new file mode 100644
index 0000000000..5d2bf0aaeb
--- /dev/null
+++ b/drivers/serial/serial_htif.c
@@ -0,0 +1,178 @@ 
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2022 Ventana Micro Systems Inc.
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <errno.h>
+#include <fdtdec.h>
+#include <log.h>
+#include <watchdog.h>
+#include <asm/global_data.h>
+#include <asm/io.h>
+#include <linux/compiler.h>
+#include <serial.h>
+#include <linux/err.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#define HTIF_DATA_BITS		48
+#define HTIF_DATA_MASK		((1ULL << HTIF_DATA_BITS) - 1)
+#define HTIF_DATA_SHIFT		0
+#define HTIF_CMD_BITS		8
+#define HTIF_CMD_MASK		((1ULL << HTIF_CMD_BITS) - 1)
+#define HTIF_CMD_SHIFT		48
+#define HTIF_DEV_BITS		8
+#define HTIF_DEV_MASK		((1ULL << HTIF_DEV_BITS) - 1)
+#define HTIF_DEV_SHIFT		56
+
+#define HTIF_DEV_SYSTEM		0
+#define HTIF_DEV_CONSOLE	1
+
+#define HTIF_CONSOLE_CMD_GETC	0
+#define HTIF_CONSOLE_CMD_PUTC	1
+
+#if __riscv_xlen == 64
+# define TOHOST_CMD(dev, cmd, payload) \
+	(((u64)(dev) << HTIF_DEV_SHIFT) | \
+	 ((u64)(cmd) << HTIF_CMD_SHIFT) | \
+	 (u64)(payload))
+#else
+# define TOHOST_CMD(dev, cmd, payload) ({ \
+	if ((dev) || (cmd)) \
+		__builtin_trap(); \
+	(payload); })
+#endif
+#define FROMHOST_DEV(fromhost_value) \
+	((u64)((fromhost_value) >> HTIF_DEV_SHIFT) & HTIF_DEV_MASK)
+#define FROMHOST_CMD(fromhost_value) \
+	((u64)((fromhost_value) >> HTIF_CMD_SHIFT) & HTIF_CMD_MASK)
+#define FROMHOST_DATA(fromhost_value) \
+	((u64)((fromhost_value) >> HTIF_DATA_SHIFT) & HTIF_DATA_MASK)
+
+struct htif_plat {
+	void *fromhost;
+	void *tohost;
+	int console_char;
+};
+
+static void __check_fromhost(struct htif_plat *plat)
+{
+	u64 fh = readq(plat->fromhost);
+
+	if (!fh)
+		return;
+	writeq(0, plat->fromhost);
+
+	/* this should be from the console */
+	if (FROMHOST_DEV(fh) != HTIF_DEV_CONSOLE)
+		__builtin_trap();
+	switch (FROMHOST_CMD(fh)) {
+	case HTIF_CONSOLE_CMD_GETC:
+		plat->console_char = 1 + (u8)FROMHOST_DATA(fh);
+		break;
+	case HTIF_CONSOLE_CMD_PUTC:
+		break;
+	default:
+		__builtin_trap();
+	}
+}
+
+static void __set_tohost(struct htif_plat *plat,
+			 u64 dev, u64 cmd, u64 data)
+{
+	while (readq(plat->tohost))
+		__check_fromhost(plat);
+	writeq(TOHOST_CMD(dev, cmd, data), plat->tohost);
+}
+
+static int htif_serial_putc(struct udevice *dev, const char ch)
+{
+	struct htif_plat *plat = dev_get_plat(dev);
+
+	__set_tohost(plat, HTIF_DEV_CONSOLE, HTIF_CONSOLE_CMD_PUTC, ch);
+	return 0;
+}
+
+static int htif_serial_getc(struct udevice *dev)
+{
+	int ch;
+	struct htif_plat *plat = dev_get_plat(dev);
+
+	if (plat->console_char < 0)
+		__check_fromhost(plat);
+
+	if (plat->console_char >= 0) {
+		ch = plat->console_char;
+		plat->console_char = -1;
+		__set_tohost(plat, HTIF_DEV_CONSOLE, HTIF_CONSOLE_CMD_GETC, 0);
+		return (ch) ? ch - 1 : -EAGAIN;
+	}
+
+	return -EAGAIN;
+}
+
+static int htif_serial_pending(struct udevice *dev, bool input)
+{
+	struct htif_plat *plat = dev_get_plat(dev);
+
+	if (!input)
+		return 0;
+
+	if (plat->console_char < 0)
+		__check_fromhost(plat);
+
+	return (plat->console_char >= 0) ? 1 : 0;
+}
+
+static int htif_serial_probe(struct udevice *dev)
+{
+	struct htif_plat *plat = dev_get_plat(dev);
+
+	/* Queue first getc request */
+	__set_tohost(plat, HTIF_DEV_CONSOLE, HTIF_CONSOLE_CMD_GETC, 0);
+
+	return 0;
+}
+
+static int htif_serial_of_to_plat(struct udevice *dev)
+{
+	fdt_addr_t addr;
+	struct htif_plat *plat = dev_get_plat(dev);
+
+	addr = dev_read_addr_index(dev, 0);
+	if (addr == FDT_ADDR_T_NONE)
+		return -ENODEV;
+	plat->fromhost = (void *)(uintptr_t)addr;
+	plat->tohost = plat->fromhost + sizeof(u64);
+
+	addr = dev_read_addr_index(dev, 1);
+	if (addr != FDT_ADDR_T_NONE)
+		plat->tohost = (void *)(uintptr_t)addr;
+
+	plat->console_char = -1;
+
+	return 0;
+}
+
+static const struct dm_serial_ops htif_serial_ops = {
+	.putc = htif_serial_putc,
+	.getc = htif_serial_getc,
+	.pending = htif_serial_pending,
+};
+
+static const struct udevice_id htif_serial_ids[] = {
+	{ .compatible = "ucb,htif0" },
+	{ }
+};
+
+U_BOOT_DRIVER(serial_htif) = {
+	.name		= "serial_htif",
+	.id		= UCLASS_SERIAL,
+	.of_match	= htif_serial_ids,
+	.of_to_plat	= htif_serial_of_to_plat,
+	.plat_auto	= sizeof(struct htif_plat),
+	.probe		= htif_serial_probe,
+	.ops		= &htif_serial_ops,
+};