Re: [U-Boot] [PATCH 04/27] virtio: Add virtio over mmio transport driver

2018-09-27 Thread Simon Glass
On 23 September 2018 at 06:42, Bin Meng  wrote:
> VirtIO can use various different buses and virtio devices are
> commonly implemented as PCI devices. But virtual environments
> without PCI support (a common situation in embedded devices
> models) might use simple memory mapped device (“virtio-mmio”)
> instead of the PCI device.
>
> This adds a transport driver that implements UCLASS_VIRTIO for
> virtio over mmio.
>
> Signed-off-by: Tuomas Tynkkynen 
> Signed-off-by: Bin Meng 
> ---
>
>  drivers/virtio/Kconfig   |   7 +
>  drivers/virtio/Makefile  |   1 +
>  drivers/virtio/virtio_mmio.c | 413 
> +++
>  drivers/virtio/virtio_mmio.h | 129 ++
>  4 files changed, 550 insertions(+)
>  create mode 100644 drivers/virtio/virtio_mmio.c
>  create mode 100644 drivers/virtio/virtio_mmio.h

Reviewed-by: Simon Glass 
___
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot


[U-Boot] [PATCH 04/27] virtio: Add virtio over mmio transport driver

2018-09-23 Thread Bin Meng
VirtIO can use various different buses and virtio devices are
commonly implemented as PCI devices. But virtual environments
without PCI support (a common situation in embedded devices
models) might use simple memory mapped device (“virtio-mmio”)
instead of the PCI device.

This adds a transport driver that implements UCLASS_VIRTIO for
virtio over mmio.

Signed-off-by: Tuomas Tynkkynen 
Signed-off-by: Bin Meng 
---

 drivers/virtio/Kconfig   |   7 +
 drivers/virtio/Makefile  |   1 +
 drivers/virtio/virtio_mmio.c | 413 +++
 drivers/virtio/virtio_mmio.h | 129 ++
 4 files changed, 550 insertions(+)
 create mode 100644 drivers/virtio/virtio_mmio.c
 create mode 100644 drivers/virtio/virtio_mmio.h

diff --git a/drivers/virtio/Kconfig b/drivers/virtio/Kconfig
index bdfa96a..60cfaf8 100644
--- a/drivers/virtio/Kconfig
+++ b/drivers/virtio/Kconfig
@@ -11,4 +11,11 @@ config VIRTIO
  This option is selected by any driver which implements the virtio
  bus, such as CONFIG_VIRTIO_MMIO or CONFIG_VIRTIO_PCI.
 
+config VIRTIO_MMIO
+   bool "Platform bus driver for memory mapped virtio devices"
+   select VIRTIO
+   help
+ This driver provides support for memory mapped virtio
+ platform device driver.
+
 endmenu
diff --git a/drivers/virtio/Makefile b/drivers/virtio/Makefile
index 17d264a..2e48785 100644
--- a/drivers/virtio/Makefile
+++ b/drivers/virtio/Makefile
@@ -4,3 +4,4 @@
 # Copyright (C) 2018, Bin Meng 
 
 obj-y += virtio-uclass.o virtio_ring.o
+obj-$(CONFIG_VIRTIO_MMIO) += virtio_mmio.o
diff --git a/drivers/virtio/virtio_mmio.c b/drivers/virtio/virtio_mmio.c
new file mode 100644
index 000..8038b46
--- /dev/null
+++ b/drivers/virtio/virtio_mmio.c
@@ -0,0 +1,413 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2018, Tuomas Tynkkynen 
+ * Copyright (C) 2018, Bin Meng 
+ *
+ * VirtIO memory-maped I/O transport driver
+ * Ported from Linux drivers/virtio/virtio_mmio.c
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include "virtio_mmio.h"
+
+static int virtio_mmio_get_config(struct udevice *udev, unsigned int offset,
+ void *buf, unsigned int len)
+{
+   struct virtio_mmio_priv *priv = dev_get_priv(udev);
+   void __iomem *base = priv->base + VIRTIO_MMIO_CONFIG;
+   u8 b;
+   __le16 w;
+   __le32 l;
+
+   if (priv->version == 1) {
+   u8 *ptr = buf;
+   int i;
+
+   for (i = 0; i < len; i++)
+   ptr[i] = readb(base + offset + i);
+
+   return 0;
+   }
+
+   switch (len) {
+   case 1:
+   b = readb(base + offset);
+   memcpy(buf, , sizeof(b));
+   break;
+   case 2:
+   w = cpu_to_le16(readw(base + offset));
+   memcpy(buf, , sizeof(w));
+   break;
+   case 4:
+   l = cpu_to_le32(readl(base + offset));
+   memcpy(buf, , sizeof(l));
+   break;
+   case 8:
+   l = cpu_to_le32(readl(base + offset));
+   memcpy(buf, , sizeof(l));
+   l = cpu_to_le32(readl(base + offset + sizeof(l)));
+   memcpy(buf + sizeof(l), , sizeof(l));
+   break;
+   default:
+   WARN_ON(true);
+   }
+
+   return 0;
+}
+
+static int virtio_mmio_set_config(struct udevice *udev, unsigned int offset,
+ const void *buf, unsigned int len)
+{
+   struct virtio_mmio_priv *priv = dev_get_priv(udev);
+   void __iomem *base = priv->base + VIRTIO_MMIO_CONFIG;
+   u8 b;
+   __le16 w;
+   __le32 l;
+
+   if (priv->version == 1) {
+   const u8 *ptr = buf;
+   int i;
+
+   for (i = 0; i < len; i++)
+   writeb(ptr[i], base + offset + i);
+
+   return 0;
+   }
+
+   switch (len) {
+   case 1:
+   memcpy(, buf, sizeof(b));
+   writeb(b, base + offset);
+   break;
+   case 2:
+   memcpy(, buf, sizeof(w));
+   writew(le16_to_cpu(w), base + offset);
+   break;
+   case 4:
+   memcpy(, buf, sizeof(l));
+   writel(le32_to_cpu(l), base + offset);
+   break;
+   case 8:
+   memcpy(, buf, sizeof(l));
+   writel(le32_to_cpu(l), base + offset);
+   memcpy(, buf + sizeof(l), sizeof(l));
+   writel(le32_to_cpu(l), base + offset + sizeof(l));
+   break;
+   default:
+   WARN_ON(true);
+   }
+
+   return 0;
+}
+
+static int virtio_mmio_generation(struct udevice *udev, u32 *counter)
+{
+   struct virtio_mmio_priv *priv = dev_get_priv(udev);
+
+   if (priv->version == 1)
+   *counter = 0;
+   else
+   *counter =