summaryrefslogtreecommitdiffstats
path: root/drivers/serial
diff options
context:
space:
mode:
authorMarcelo Politzer <marcelo.politzer@cartesi.io>2021-09-27 17:05:21 -0300
committerSascha Hauer <s.hauer@pengutronix.de>2021-10-05 09:03:39 +0200
commit866e6e41cda21de6704fef3dae0c8e9c93436968 (patch)
treeb342c51759132a02a7f51e26640fbb9836ae276e /drivers/serial
parentf0620fb1f72f246c821e0720db8b47461c4a0fa5 (diff)
downloadbarebox-866e6e41cda21de6704fef3dae0c8e9c93436968.tar.gz
barebox-866e6e41cda21de6704fef3dae0c8e9c93436968.tar.xz
serial: implement riscv SBI console support
Implement a console over legacy SBI (version 0.1.0). There is a tiny ringbuffer to simplify checking for presence and reading characters as separate steps. Link: https://lore.barebox.org/20210927200521.7996-1-marcelo.politzer@cartesi.io Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Diffstat (limited to 'drivers/serial')
-rw-r--r--drivers/serial/Kconfig8
-rw-r--r--drivers/serial/Makefile1
-rw-r--r--drivers/serial/serial_sbi.c58
3 files changed, 67 insertions, 0 deletions
diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig
index b9750d1774..5e30ea388b 100644
--- a/drivers/serial/Kconfig
+++ b/drivers/serial/Kconfig
@@ -173,4 +173,12 @@ config SERIAL_SIFIVE
contains a SiFive UART IP block. This type of UART is present on
SiFive FU540 SoCs, among others.
+config SERIAL_SBI
+ tristate "RISCV Serial support over SBI's HTIF"
+ depends on OFDEVICE
+ depends on RISCV_SBI
+ help
+ Select this option if you are building barebox for a RISCV platform
+ that implements a serial over SBI.
+
endmenu
diff --git a/drivers/serial/Makefile b/drivers/serial/Makefile
index 5120b17376..b1de436ed6 100644
--- a/drivers/serial/Makefile
+++ b/drivers/serial/Makefile
@@ -24,3 +24,4 @@ obj-$(CONFIG_DRIVER_SERIAL_DIGIC) += serial_digic.o
obj-$(CONFIG_DRIVER_SERIAL_LPUART) += serial_lpuart.o
obj-$(CONFIG_VIRTIO_CONSOLE) += virtio_console.o
obj-$(CONFIG_SERIAL_SIFIVE) += serial_sifive.o
+obj-$(CONFIG_SERIAL_SBI) += serial_sbi.o
diff --git a/drivers/serial/serial_sbi.c b/drivers/serial/serial_sbi.c
new file mode 100644
index 0000000000..2ea28fea5b
--- /dev/null
+++ b/drivers/serial/serial_sbi.c
@@ -0,0 +1,58 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2021 Marcelo Politzer <marcelo.politzer@cartesi.io>
+ */
+
+#include <common.h>
+#include <driver.h>
+#include <malloc.h>
+#include <asm/sbi.h>
+
+struct sbi_serial_priv {
+ struct console_device cdev;
+ uint8_t b[2], head, tail;
+};
+
+static int sbi_serial_getc(struct console_device *cdev)
+{
+ struct sbi_serial_priv *priv = cdev->dev->priv;
+ if (priv->head == priv->tail)
+ return -1;
+ return priv->b[priv->head++ & 0x1];
+}
+
+static void sbi_serial_putc(struct console_device *cdev, const char ch)
+{
+ sbi_console_putchar(ch);
+}
+
+static int sbi_serial_tstc(struct console_device *cdev)
+{
+ struct sbi_serial_priv *priv = cdev->dev->priv;
+ int c = sbi_console_getchar();
+
+ if (c != -1)
+ priv->b[priv->tail++ & 0x1] = c;
+ return priv->head != priv->tail;
+}
+
+static int sbi_serial_probe(struct device_d *dev)
+{
+ struct sbi_serial_priv *priv;
+
+ priv = dev->priv = xzalloc(sizeof(*priv));
+ priv->cdev.dev = dev;
+ priv->cdev.putc = sbi_serial_putc;
+ priv->cdev.getc = sbi_serial_getc;
+ priv->cdev.tstc = sbi_serial_tstc;
+ priv->cdev.flush = 0;
+ priv->cdev.setbrg = 0;
+
+ return console_register(&priv->cdev);
+}
+
+static struct driver_d serial_sbi_driver = {
+ .name = "riscv-serial-sbi",
+ .probe = sbi_serial_probe,
+};
+postcore_platform_driver(serial_sbi_driver);