[Qemu-devel] [PATCH v4 10/14] usb: Add basic code to emulate Chipidea USB IP

2018-01-15 Thread Andrey Smirnov
Add code to emulate Chipidea USB IP (used in i.MX SoCs). Tested to
work against:

-usb -drive if=none,id=stick,file=usb.img,format=raw -device \
 usb-storage,bus=usb-bus.0,drive=stick

Cc: Peter Maydell 
Cc: Jason Wang 
Cc: Philippe Mathieu-Daudé 
Cc: qemu-devel@nongnu.org
Cc: qemu-...@nongnu.org
Cc: yurov...@gmail.com
Signed-off-by: Andrey Smirnov 
---
 hw/usb/Makefile.objs  |   1 +
 hw/usb/chipidea.c | 176 ++
 include/hw/usb/chipidea.h |  16 +
 3 files changed, 193 insertions(+)
 create mode 100644 hw/usb/chipidea.c
 create mode 100644 include/hw/usb/chipidea.h

diff --git a/hw/usb/Makefile.objs b/hw/usb/Makefile.objs
index bdfead6701..5573c182d4 100644
--- a/hw/usb/Makefile.objs
+++ b/hw/usb/Makefile.objs
@@ -12,6 +12,7 @@ common-obj-$(CONFIG_USB_XHCI_NEC) += hcd-xhci-nec.o
 common-obj-$(CONFIG_USB_MUSB) += hcd-musb.o
 
 obj-$(CONFIG_TUSB6010) += tusb6010.o
+obj-$(CONFIG_IMX)  += chipidea.o
 
 # emulated usb devices
 common-obj-$(CONFIG_USB) += dev-hub.o
diff --git a/hw/usb/chipidea.c b/hw/usb/chipidea.c
new file mode 100644
index 00..9bc8df448c
--- /dev/null
+++ b/hw/usb/chipidea.c
@@ -0,0 +1,176 @@
+/*
+ * Copyright (c) 2017, Impinj, Inc.
+ *
+ * Chipidea USB block emulation code
+ *
+ * Author: Andrey Smirnov 
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#include "qemu/osdep.h"
+#include "hw/usb/hcd-ehci.h"
+#include "hw/usb/chipidea.h"
+#include "qemu/log.h"
+
+enum {
+CHIPIDEA_USBx_DCIVERSION   = 0x000,
+CHIPIDEA_USBx_DCCPARAMS= 0x004,
+CHIPIDEA_USBx_DCCPARAMS_HC = BIT(8),
+};
+
+static uint64_t chipidea_read(void *opaque, hwaddr offset,
+   unsigned size)
+{
+return 0;
+}
+
+static void chipidea_write(void *opaque, hwaddr offset,
+uint64_t value, unsigned size)
+{
+}
+
+static const struct MemoryRegionOps chipidea_ops = {
+.read = chipidea_read,
+.write = chipidea_write,
+.endianness = DEVICE_NATIVE_ENDIAN,
+.impl = {
+/*
+ * Our device would not work correctly if the guest was doing
+ * unaligned access. This might not be a limitation on the
+ * real device but in practice there is no reason for a guest
+ * to access this device unaligned.
+ */
+.min_access_size = 4,
+.max_access_size = 4,
+.unaligned = false,
+},
+};
+
+static uint64_t chipidea_dc_read(void *opaque, hwaddr offset,
+ unsigned size)
+{
+switch (offset) {
+case CHIPIDEA_USBx_DCIVERSION:
+return 0x1;
+case CHIPIDEA_USBx_DCCPARAMS:
+/*
+ * Real hardware (at least i.MX7) will also report the
+ * controller as "Device Capable" (and 8 supported endpoints),
+ * but there doesn't seem to be much point in doing so, since
+ * we don't emulate that part.
+ */
+return CHIPIDEA_USBx_DCCPARAMS_HC;
+}
+
+return 0;
+}
+
+static void chipidea_dc_write(void *opaque, hwaddr offset,
+  uint64_t value, unsigned size)
+{
+}
+
+static const struct MemoryRegionOps chipidea_dc_ops = {
+.read = chipidea_dc_read,
+.write = chipidea_dc_write,
+.endianness = DEVICE_NATIVE_ENDIAN,
+.impl = {
+/*
+ * Our device would not work correctly if the guest was doing
+ * unaligned access. This might not be a limitation on the real
+ * device but in practice there is no reason for a guest to access
+ * this device unaligned.
+ */
+.min_access_size = 4,
+.max_access_size = 4,
+.unaligned = false,
+},
+};
+
+static void chipidea_init(Object *obj)
+{
+EHCIState *ehci = &SYS_BUS_EHCI(obj)->ehci;
+ChipideaState *ci = CHIPIDEA(obj);
+int i;
+
+for (i = 0; i < ARRAY_SIZE(ci->iomem); i++) {
+const struct {
+const char *name;
+hwaddr offset;
+uint64_t size;
+const struct MemoryRegionOps *ops;
+} regions[ARRAY_SIZE(ci->iomem)] = {
+/*
+ * Registers located between offsets 0x000 and 0xFC
+ */
+{
+.name   = TYPE_CHIPIDEA ".misc",
+.offset = 0x000,
+.size   = 0x100,
+.ops= &chipidea_ops,
+},
+/*
+ * Registers located between offsets 0x1A4 and 0x1DC
+ */
+{
+.name   = TYPE_CHIPIDEA ".endpoints",
+.offset = 0x1A4,
+.size   = 0x1DC - 0x1A4 + 4,
+.ops= &chipidea_ops,
+},
+/*
+ * USB_x_DCIVERSION and USB_x_DCCPARAMS
+ */
+{
+.name   = TYPE_CHIPIDEA ".dc",
+.offset = 0x120,
+.size   = 8,
+  

Re: [Qemu-devel] [PATCH v4 10/14] usb: Add basic code to emulate Chipidea USB IP

2018-01-16 Thread Peter Maydell
On 16 January 2018 at 01:37, Andrey Smirnov  wrote:
> Add code to emulate Chipidea USB IP (used in i.MX SoCs). Tested to
> work against:
>
> -usb -drive if=none,id=stick,file=usb.img,format=raw -device \
>  usb-storage,bus=usb-bus.0,drive=stick
>
> Cc: Peter Maydell 
> Cc: Jason Wang 
> Cc: Philippe Mathieu-Daudé 
> Cc: qemu-devel@nongnu.org
> Cc: qemu-...@nongnu.org
> Cc: yurov...@gmail.com
> Signed-off-by: Andrey Smirnov 
> ---

This looked a little odd at first but I see it's how we're
implementing TYPE_FUSBH200_EHCI, so I guess it's ok.

Reviewed-by: Peter Maydell 

thanks
-- PMM