aboutsummaryrefslogtreecommitdiff
path: root/hw/usb
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2018-02-09 13:27:40 +0000
committerPeter Maydell <peter.maydell@linaro.org>2018-02-09 13:27:40 +0000
commitf31cd9e4e2172a4807f390194978c61e717791d2 (patch)
treeb625ba38f6fa0503edc61a64942a6c1d07e99cd0 /hw/usb
parentfdcbebe4519ec76cb500ab7698c1ea7ed8ebc962 (diff)
parentbbba7757bacc9f890a3f028d328b4b429dbe78ec (diff)
downloadqemu-f31cd9e4e2172a4807f390194978c61e717791d2.zip
qemu-f31cd9e4e2172a4807f390194978c61e717791d2.tar.gz
qemu-f31cd9e4e2172a4807f390194978c61e717791d2.tar.bz2
Merge remote-tracking branch 'remotes/pmaydell/tags/pull-target-arm-20180209' into staging
target-arm queue: * Support M profile derived exceptions on exception entry and exit * Implement AArch64 v8.2 crypto insns (SHA-512, SHA-3, SM3, SM4) * Implement working i.MX6 SD controller * Various devices preparatory to i.MX7 support * Preparatory patches for SVE emulation * v8M: Fix bug in implementation of 'TT' insn * Give useful error if user tries to use userspace GICv3 with KVM # gpg: Signature made Fri 09 Feb 2018 11:01:23 GMT # gpg: using RSA key 3C2525ED14360CDE # gpg: Good signature from "Peter Maydell <peter.maydell@linaro.org>" # gpg: aka "Peter Maydell <pmaydell@gmail.com>" # gpg: aka "Peter Maydell <pmaydell@chiark.greenend.org.uk>" # Primary key fingerprint: E1A5 C593 CD41 9DE2 8E83 15CF 3C25 25ED 1436 0CDE * remotes/pmaydell/tags/pull-target-arm-20180209: (30 commits) hw/core/generic-loader: Allow PC to be set on command line target/arm/translate.c: Fix missing 'break' for TT insns target/arm/kvm: gic: Prevent creating userspace GICv3 with KVM target/arm: Add SVE state to TB->FLAGS target/arm: Add ZCR_ELx target/arm: Add SVE to migration state target/arm: Add predicate registers for SVE target/arm: Expand vector registers for SVE hw/arm: Move virt's PSCI DT fixup code to arm/boot.c usb: Add basic code to emulate Chipidea USB IP i.MX: Add implementation of i.MX7 GPR IP block i.MX: Add i.MX7 GPT variant i.MX: Add code to emulate GPCv2 IP block i.MX: Add code to emulate i.MX7 SNVS IP-block i.MX: Add code to emulate i.MX2 watchdog IP block i.MX: Add code to emulate i.MX7 CCM, PMU and ANALOG IP blocks hw: i.MX: Convert i.MX6 to use TYPE_IMX_USDHC sdhci: Add i.MX specific subtype of SDHCI target/arm: enable user-mode SHA-3, SM3, SM4 and SHA-512 instruction support target/arm: implement SM4 instructions ... Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'hw/usb')
-rw-r--r--hw/usb/Makefile.objs1
-rw-r--r--hw/usb/chipidea.c176
2 files changed, 177 insertions, 0 deletions
diff --git a/hw/usb/Makefile.objs b/hw/usb/Makefile.objs
index fbcd498..41be700 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 0000000..60d67f8
--- /dev/null
+++ b/hw/usb/chipidea.c
@@ -0,0 +1,176 @@
+/*
+ * Copyright (c) 2018, Impinj, Inc.
+ *
+ * Chipidea USB block emulation code
+ *
+ * Author: Andrey Smirnov <andrew.smirnov@gmail.com>
+ *
+ * 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,
+ .ops = &chipidea_dc_ops,
+ },
+ };
+
+ memory_region_init_io(&ci->iomem[i],
+ obj,
+ regions[i].ops,
+ ci,
+ regions[i].name,
+ regions[i].size);
+
+ memory_region_add_subregion(&ehci->mem,
+ regions[i].offset,
+ &ci->iomem[i]);
+ }
+}
+
+static void chipidea_class_init(ObjectClass *klass, void *data)
+{
+ DeviceClass *dc = DEVICE_CLASS(klass);
+ SysBusEHCIClass *sec = SYS_BUS_EHCI_CLASS(klass);
+
+ /*
+ * Offsets used were taken from i.MX7Dual Applications Processor
+ * Reference Manual, Rev 0.1, p. 3177, Table 11-59
+ */
+ sec->capsbase = 0x100;
+ sec->opregbase = 0x140;
+ sec->portnr = 1;
+
+ set_bit(DEVICE_CATEGORY_USB, dc->categories);
+ dc->desc = "Chipidea USB Module";
+}
+
+static const TypeInfo chipidea_info = {
+ .name = TYPE_CHIPIDEA,
+ .parent = TYPE_SYS_BUS_EHCI,
+ .instance_size = sizeof(ChipideaState),
+ .instance_init = chipidea_init,
+ .class_init = chipidea_class_init,
+};
+
+static void chipidea_register_type(void)
+{
+ type_register_static(&chipidea_info);
+}
+type_init(chipidea_register_type)