Message ID | 1601376942-9648-1-git-send-email-sai.pavan.boddu@xilinx.com |
---|---|
Headers | show |
Series | Add Versal usb model | expand |
On Tue, Sep 29, 2020 at 04:25:40PM +0530, Sai Pavan Boddu wrote: > This module emulates control registers of versal usb2 controller, this is added > just to make guest happy. In general this module would control the phy-reset > signal from usb controller, data coherency of the transactions, signals > the host system errors received from controller. Hi Sai, This looks OK to me but it suffers from the updating IRQs from reset-cb issue. Look at hw/char/cadence_uart.c as an example on how to fix that. Thanks, Edgar > > Signed-off-by: Sai Pavan Boddu <sai.pavan.boddu@xilinx.com> > Signed-off-by: Vikram Garhwal <fnu.vikram@xilinx.com> > --- > hw/misc/meson.build | 1 + > hw/misc/xlnx-versal-usb2-ctrl-regs.c | 222 +++++++++++++++++++++++++++ > include/hw/misc/xlnx-versal-usb2-ctrl-regs.h | 45 ++++++ > 3 files changed, 268 insertions(+) > create mode 100644 hw/misc/xlnx-versal-usb2-ctrl-regs.c > create mode 100644 include/hw/misc/xlnx-versal-usb2-ctrl-regs.h > > diff --git a/hw/misc/meson.build b/hw/misc/meson.build > index 793d45b..b336dd1 100644 > --- a/hw/misc/meson.build > +++ b/hw/misc/meson.build > @@ -109,3 +109,4 @@ specific_ss.add(when: 'CONFIG_MIPS_CPS', if_true: files('mips_cmgcr.c', 'mips_cp > specific_ss.add(when: 'CONFIG_MIPS_ITU', if_true: files('mips_itu.c')) > > specific_ss.add(when: 'CONFIG_SBSA_REF', if_true: files('sbsa_ec.c')) > +specific_ss.add(when: 'CONFIG_XLNX_VERSAL', if_true: files('xlnx-versal-usb2-ctrl-regs.c')) > diff --git a/hw/misc/xlnx-versal-usb2-ctrl-regs.c b/hw/misc/xlnx-versal-usb2-ctrl-regs.c > new file mode 100644 > index 0000000..94fd7cf > --- /dev/null > +++ b/hw/misc/xlnx-versal-usb2-ctrl-regs.c > @@ -0,0 +1,222 @@ > +/* > + * QEMU model of the VersalUsb2CtrlRegs Register control/Status block for > + * USB2.0 controller > + * > + * This module should control phy_reset, permanent device plugs, frame length > + * time adjust & setting of coherency paths. None of which are emulated in > + * present model. > + * > + * Copyright (c) 2020 Xilinx Inc. Vikram Garhwal <fnu.vikram@xilinx.com> > + * > + * Permission is hereby granted, free of charge, to any person obtaining a copy > + * of this software and associated documentation files (the "Software"), to deal > + * in the Software without restriction, including without limitation the rights > + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell > + * copies of the Software, and to permit persons to whom the Software is > + * furnished to do so, subject to the following conditions: > + * > + * The above copyright notice and this permission notice shall be included in > + * all copies or substantial portions of the Software. > + * > + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR > + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, > + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL > + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER > + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, > + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN > + * THE SOFTWARE. > + */ > + > +#include "qemu/osdep.h" > +#include "hw/sysbus.h" > +#include "hw/irq.h" > +#include "hw/register.h" > +#include "qemu/bitops.h" > +#include "qemu/log.h" > +#include "qom/object.h" > +#include "migration/vmstate.h" > +#include "hw/misc/xlnx-versal-usb2-ctrl-regs.h" > + > +#ifndef XILINX_VERSAL_USB2_CTRL_REGS_ERR_DEBUG > +#define XILINX_VERSAL_USB2_CTRL_REGS_ERR_DEBUG 0 > +#endif > + > +REG32(BUS_FILTER, 0x30) > + FIELD(BUS_FILTER, BYPASS, 0, 4) > +REG32(PORT, 0x34) > + FIELD(PORT, HOST_SMI_BAR_WR, 4, 1) > + FIELD(PORT, HOST_SMI_PCI_CMD_REG_WR, 3, 1) > + FIELD(PORT, HOST_MSI_ENABLE, 2, 1) > + FIELD(PORT, PWR_CTRL_PRSNT, 1, 1) > + FIELD(PORT, HUB_PERM_ATTACH, 0, 1) > +REG32(JITTER_ADJUST, 0x38) > + FIELD(JITTER_ADJUST, FLADJ, 0, 6) > +REG32(BIGENDIAN, 0x40) > + FIELD(BIGENDIAN, ENDIAN_GS, 0, 1) > +REG32(COHERENCY, 0x44) > + FIELD(COHERENCY, USB_COHERENCY, 0, 1) > +REG32(XHC_BME, 0x48) > + FIELD(XHC_BME, XHC_BME, 0, 1) > +REG32(REG_CTRL, 0x60) > + FIELD(REG_CTRL, SLVERR_ENABLE, 0, 1) > +REG32(IR_STATUS, 0x64) > + FIELD(IR_STATUS, HOST_SYS_ERR, 1, 1) > + FIELD(IR_STATUS, ADDR_DEC_ERR, 0, 1) > +REG32(IR_MASK, 0x68) > + FIELD(IR_MASK, HOST_SYS_ERR, 1, 1) > + FIELD(IR_MASK, ADDR_DEC_ERR, 0, 1) > +REG32(IR_ENABLE, 0x6c) > + FIELD(IR_ENABLE, HOST_SYS_ERR, 1, 1) > + FIELD(IR_ENABLE, ADDR_DEC_ERR, 0, 1) > +REG32(IR_DISABLE, 0x70) > + FIELD(IR_DISABLE, HOST_SYS_ERR, 1, 1) > + FIELD(IR_DISABLE, ADDR_DEC_ERR, 0, 1) > +REG32(USB3, 0x78) > + > +static void ir_update_irq(VersalUsb2CtrlRegs *s) > +{ > + bool pending = s->regs[R_IR_STATUS] & ~s->regs[R_IR_MASK]; > + qemu_set_irq(s->irq_ir, pending); > +} > + > +static void ir_status_postw(RegisterInfo *reg, uint64_t val64) > +{ > + VersalUsb2CtrlRegs *s = XILINX_VERSAL_USB2_CTRL_REGS(reg->opaque); > + /* > + * TODO: This should also clear USBSTS.HSE field in USB XHCI register. > + * May be combine both the modules. > + */ > + ir_update_irq(s); > +} > + > +static uint64_t ir_enable_prew(RegisterInfo *reg, uint64_t val64) > +{ > + VersalUsb2CtrlRegs *s = XILINX_VERSAL_USB2_CTRL_REGS(reg->opaque); > + uint32_t val = val64; > + > + s->regs[R_IR_MASK] &= ~val; > + ir_update_irq(s); > + return 0; > +} > + > +static uint64_t ir_disable_prew(RegisterInfo *reg, uint64_t val64) > +{ > + VersalUsb2CtrlRegs *s = XILINX_VERSAL_USB2_CTRL_REGS(reg->opaque); > + uint32_t val = val64; > + > + s->regs[R_IR_MASK] |= val; > + ir_update_irq(s); > + return 0; > +} > + > +static const RegisterAccessInfo usb2_regs_regs_info[] = { > + { .name = "BUS_FILTER", .addr = A_BUS_FILTER, > + .rsvd = 0xfffffff0, > + },{ .name = "PORT", .addr = A_PORT, > + .rsvd = 0xffffffe0, > + },{ .name = "JITTER_ADJUST", .addr = A_JITTER_ADJUST, > + .reset = 0x20, > + .rsvd = 0xffffffc0, > + },{ .name = "BIGENDIAN", .addr = A_BIGENDIAN, > + .rsvd = 0xfffffffe, > + },{ .name = "COHERENCY", .addr = A_COHERENCY, > + .rsvd = 0xfffffffe, > + },{ .name = "XHC_BME", .addr = A_XHC_BME, > + .reset = 0x1, > + .rsvd = 0xfffffffe, > + },{ .name = "REG_CTRL", .addr = A_REG_CTRL, > + .rsvd = 0xfffffffe, > + },{ .name = "IR_STATUS", .addr = A_IR_STATUS, > + .rsvd = 0xfffffffc, > + .w1c = 0x3, > + .post_write = ir_status_postw, > + },{ .name = "IR_MASK", .addr = A_IR_MASK, > + .reset = 0x3, > + .rsvd = 0xfffffffc, > + .ro = 0x3, > + },{ .name = "IR_ENABLE", .addr = A_IR_ENABLE, > + .rsvd = 0xfffffffc, > + .pre_write = ir_enable_prew, > + },{ .name = "IR_DISABLE", .addr = A_IR_DISABLE, > + .rsvd = 0xfffffffc, > + .pre_write = ir_disable_prew, > + },{ .name = "USB3", .addr = A_USB3, > + } > +}; > + > +static void usb2_regs_reset(DeviceState *dev) > +{ > + VersalUsb2CtrlRegs *s = XILINX_VERSAL_USB2_CTRL_REGS(dev); > + unsigned int i; > + > + for (i = 0; i < ARRAY_SIZE(s->regs_info); ++i) { > + register_reset(&s->regs_info[i]); > + } > + > + ir_update_irq(s); > +} > + > +static const MemoryRegionOps usb2_regs_ops = { > + .read = register_read_memory, > + .write = register_write_memory, > + .endianness = DEVICE_LITTLE_ENDIAN, > + .valid = { > + .min_access_size = 4, > + .max_access_size = 4, > + }, > +}; > + > +static void usb2_regs_init(Object *obj) > +{ > + VersalUsb2CtrlRegs *s = XILINX_VERSAL_USB2_CTRL_REGS(obj); > + SysBusDevice *sbd = SYS_BUS_DEVICE(obj); > + RegisterInfoArray *reg_array; > + > + memory_region_init(&s->iomem, obj, TYPE_XILINX_VERSAL_USB2_CTRL_REGS, > + USB2_REGS_R_MAX * 4); > + reg_array = > + register_init_block32(DEVICE(obj), usb2_regs_regs_info, > + ARRAY_SIZE(usb2_regs_regs_info), > + s->regs_info, s->regs, > + &usb2_regs_ops, > + XILINX_VERSAL_USB2_CTRL_REGS_ERR_DEBUG, > + USB2_REGS_R_MAX * 4); > + memory_region_add_subregion(&s->iomem, > + 0x0, > + ®_array->mem); > + sysbus_init_mmio(sbd, &s->iomem); > + sysbus_init_irq(sbd, &s->irq_ir); > +} > + > +static const VMStateDescription vmstate_usb2_regs = { > + .name = TYPE_XILINX_VERSAL_USB2_CTRL_REGS, > + .version_id = 1, > + .minimum_version_id = 1, > + .fields = (VMStateField[]) { > + VMSTATE_UINT32_ARRAY(regs, VersalUsb2CtrlRegs, USB2_REGS_R_MAX), > + VMSTATE_END_OF_LIST(), > + } > +}; > + > +static void usb2_regs_class_init(ObjectClass *klass, void *data) > +{ > + DeviceClass *dc = DEVICE_CLASS(klass); > + > + dc->reset = usb2_regs_reset; > + dc->vmsd = &vmstate_usb2_regs; > +} > + > +static const TypeInfo usb2_regs_info = { > + .name = TYPE_XILINX_VERSAL_USB2_CTRL_REGS, > + .parent = TYPE_SYS_BUS_DEVICE, > + .instance_size = sizeof(VersalUsb2CtrlRegs), > + .class_init = usb2_regs_class_init, > + .instance_init = usb2_regs_init, > +}; > + > +static void usb2_regs_register_types(void) > +{ > + type_register_static(&usb2_regs_info); > +} > + > +type_init(usb2_regs_register_types) > diff --git a/include/hw/misc/xlnx-versal-usb2-ctrl-regs.h b/include/hw/misc/xlnx-versal-usb2-ctrl-regs.h > new file mode 100644 > index 0000000..975a717 > --- /dev/null > +++ b/include/hw/misc/xlnx-versal-usb2-ctrl-regs.h > @@ -0,0 +1,45 @@ > +/* > + * QEMU model of the VersalUsb2CtrlRegs Register control/Status block for > + * USB2.0 controller > + * > + * Copyright (c) 2020 Xilinx Inc. Vikram Garhwal <fnu.vikram@xilinx.com> > + * > + * Permission is hereby granted, free of charge, to any person obtaining a copy > + * of this software and associated documentation files (the "Software"), to deal > + * in the Software without restriction, including without limitation the rights > + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell > + * copies of the Software, and to permit persons to whom the Software is > + * furnished to do so, subject to the following conditions: > + * > + * The above copyright notice and this permission notice shall be included in > + * all copies or substantial portions of the Software. > + * > + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR > + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, > + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL > + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER > + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, > + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN > + * THE SOFTWARE. > + */ > + > +#ifndef _XLNX_USB2_REGS_H_ > +#define _XLNX_USB2_REGS_H_ > + > +#define TYPE_XILINX_VERSAL_USB2_CTRL_REGS "xlnx.versal-usb2-ctrl-regs" > + > +#define XILINX_VERSAL_USB2_CTRL_REGS(obj) \ > + OBJECT_CHECK(VersalUsb2CtrlRegs, (obj), TYPE_XILINX_VERSAL_USB2_CTRL_REGS) > + > +#define USB2_REGS_R_MAX ((0x78 / 4) + 1) > + > +typedef struct VersalUsb2CtrlRegs { > + SysBusDevice parent_obj; > + MemoryRegion iomem; > + qemu_irq irq_ir; > + > + uint32_t regs[USB2_REGS_R_MAX]; > + RegisterInfo regs_info[USB2_REGS_R_MAX]; > +} VersalUsb2CtrlRegs; > + > +#endif > -- > 2.7.4 >
Patchew URL: https://patchew.org/QEMU/1601376942-9648-1-git-send-email-sai.pavan.boddu@xilinx.com/ Hi, This series failed the docker-quick@centos7 build test. Please find the testing commands and their output below. If you have Docker installed, you can probably reproduce it locally. === TEST SCRIPT BEGIN === #!/bin/bash make docker-image-centos7 V=1 NETWORK=1 time make docker-test-quick@centos7 SHOW_ENV=1 J=14 NETWORK=1 === TEST SCRIPT END === C linker for the host machine: cc ld.bfd 2.27-43 Host machine cpu family: x86_64 Host machine cpu: x86_64 ../src/meson.build:10: WARNING: Module unstable-keyval has no backwards or forwards compatibility and might not exist in future releases. Program sh found: YES Program python3 found: YES (/usr/bin/python3) Configuring ninjatool using configuration --- Running test qtest-aarch64: tpm-tis-device-test Could not allocate dynamic translator buffer ** ERROR:../src/tests/qtest/tpm-emu.c:97:tpm_emu_ctrl_thread: assertion failed (cmd == CMD_SET_DATAFD): (0 == 16) ERROR qtest-aarch64: tpm-tis-device-test - Bail out! ERROR:../src/tests/qtest/tpm-emu.c:97:tpm_emu_ctrl_thread: assertion failed (cmd == CMD_SET_DATAFD): (0 == 16) ../src/tests/qtest/libqtest.c:166: kill_qemu() tried to terminate QEMU process but encountered exit status 1 (expected 0) make: *** [run-test-160] Error 1 make: *** Waiting for unfinished jobs.... Looking for expected file 'tests/data/acpi/virt/FACP' --- Using expected file 'tests/data/acpi/virt/SPCR' Looking for expected file 'tests/data/acpi/virt/DSDT' Using expected file 'tests/data/acpi/virt/DSDT' ERROR qtest-x86_64: boot-serial-test - Bail out! ERROR:../src/tests/qtest/libqtest.c:301:qtest_init_without_qmp_handshake: assertion failed: (s->fd >= 0 && s->qmp_fd >= 0) socket_accept failed: Resource temporarily unavailable ** ERROR:../src/tests/qtest/libqtest.c:301:qtest_init_without_qmp_handshake: assertion failed: (s->fd >= 0 && s->qmp_fd >= 0) ../src/tests/qtest/libqtest.c:166: kill_qemu() tried to terminate QEMU process but encountered exit status 1 (expected 0) make: *** [run-test-115] Error 1 socket_accept failed: Resource temporarily unavailable ** ERROR:../src/tests/qtest/libqtest.c:301:qtest_init_without_qmp_handshake: assertion failed: (s->fd >= 0 && s->qmp_fd >= 0) ../src/tests/qtest/libqtest.c:166: kill_qemu() tried to terminate QEMU process but encountered exit status 1 (expected 0) ERROR qtest-x86_64: bios-tables-test - Bail out! ERROR:../src/tests/qtest/libqtest.c:301:qtest_init_without_qmp_handshake: assertion failed: (s->fd >= 0 && s->qmp_fd >= 0) make: *** [run-test-138] Error 1 socket_accept failed: Resource temporarily unavailable ** ERROR:../src/tests/qtest/libqtest.c:301:qtest_init_without_qmp_handshake: assertion failed: (s->fd >= 0 && s->qmp_fd >= 0) ../src/tests/qtest/libqtest.c:166: kill_qemu() tried to terminate QEMU process but encountered exit status 1 (expected 0) ERROR qtest-x86_64: vmgenid-test - Bail out! ERROR:../src/tests/qtest/libqtest.c:301:qtest_init_without_qmp_handshake: assertion failed: (s->fd >= 0 && s->qmp_fd >= 0) make: *** [run-test-147] Error 1 socket_accept failed: Resource temporarily unavailable ** ERROR:../src/tests/qtest/libqtest.c:301:qtest_init_without_qmp_handshake: assertion failed: (s->fd >= 0 && s->qmp_fd >= 0) ../src/tests/qtest/libqtest.c:166: kill_qemu() tried to terminate QEMU process but encountered exit status 1 (expected 0) ERROR qtest-x86_64: migration-test - Bail out! ERROR:../src/tests/qtest/libqtest.c:301:qtest_init_without_qmp_handshake: assertion failed: (s->fd >= 0 && s->qmp_fd >= 0) make: *** [run-test-148] Error 1 socket_accept failed: Resource temporarily unavailable ** ERROR:../src/tests/qtest/libqtest.c:301:qtest_init_without_qmp_handshake: assertion failed: (s->fd >= 0 && s->qmp_fd >= 0) ../src/tests/qtest/libqtest.c:166: kill_qemu() tried to terminate QEMU process but encountered exit status 1 (expected 0) ERROR qtest-x86_64: pxe-test - Bail out! ERROR:../src/tests/qtest/libqtest.c:301:qtest_init_without_qmp_handshake: assertion failed: (s->fd >= 0 && s->qmp_fd >= 0) make: *** [run-test-110] Error 1 Looking for expected file 'tests/data/acpi/virt/FACP' Using expected file 'tests/data/acpi/virt/FACP' --- raise CalledProcessError(retcode, cmd) subprocess.CalledProcessError: Command '['sudo', '-n', 'docker', 'run', '--rm', '--label', 'com.qemu.instance.uuid=09b4ebdee3d84ad7bfcf28fcd7d5edff', '-u', '1003', '--security-opt', 'seccomp=unconfined', '-e', 'TARGET_LIST=', '-e', 'EXTRA_CONFIGURE_OPTS=', '-e', 'V=', '-e', 'J=14', '-e', 'DEBUG=', '-e', 'SHOW_ENV=1', '-e', 'CCACHE_DIR=/var/tmp/ccache', '-v', '/home/patchew2/.cache/qemu-docker-ccache:/var/tmp/ccache:z', '-v', '/var/tmp/patchew-tester-tmp-x1t6tm5_/src/docker-src.2020-09-29-11.39.23.8960:/var/tmp/qemu:z,ro', 'qemu/centos7', '/var/tmp/qemu/run', 'test-quick']' returned non-zero exit status 2. filter=--filter=label=com.qemu.instance.uuid=09b4ebdee3d84ad7bfcf28fcd7d5edff make[1]: *** [docker-run] Error 1 make[1]: Leaving directory `/var/tmp/patchew-tester-tmp-x1t6tm5_/src' make: *** [docker-run-test-quick@centos7] Error 2 real 9m51.221s user 0m13.743s The full log is available at http://patchew.org/logs/1601376942-9648-1-git-send-email-sai.pavan.boddu@xilinx.com/testing.docker-quick@centos7/?type=message. --- Email generated automatically by Patchew [https://patchew.org/]. Please send your feedback to patchew-devel@redhat.com
Hi Edgar, Thanks for reviewing this one. On Tue, Sep 29, 2020 at 04:25:47PM +0200, Edgar E. Iglesias wrote: > On Tue, Sep 29, 2020 at 04:25:41PM +0530, Sai Pavan Boddu wrote: > > From: Vikram Garhwal <fnu.vikram@xilinx.com> > > > > This patch adds skeleton model of dwc3 usb controller attached to > > xhci-sysbus device. It defines global register space of DWC3 controller, > > global registers control the AXI/AHB interfaces properties, external FIFO > > support and event count support. All of which are unimplemented at > > present,we are only supporting core reset and read of ID register. > > > > Signed-off-by: Vikram Garhwal <fnu.vikram@xilinx.com> > > Signed-off-by: Sai Pavan Boddu <sai.pavan.boddu@xilinx.com> > > --- > > hw/usb/Kconfig | 6 + > > hw/usb/hcd-dwc3.c | 717 ++++++++++++++++++++++++++++++++++++++++++++++ > > hw/usb/meson.build | 1 + > > include/hw/usb/hcd-dwc3.h | 55 ++++ > > 4 files changed, 779 insertions(+) > > create mode 100644 hw/usb/hcd-dwc3.c > > create mode 100644 include/hw/usb/hcd-dwc3.h > > > > diff --git a/hw/usb/Kconfig b/hw/usb/Kconfig > > index 4dd2ba9..f5762f0 100644 > > --- a/hw/usb/Kconfig > > +++ b/hw/usb/Kconfig > > @@ -116,3 +116,9 @@ config IMX_USBPHY > > bool > > default y > > depends on USB > > + > > +config USB_DWC3 > > + bool > > + default y if USB_XHCI_SYSBUS > > + select USB > > + select REGISTER > > diff --git a/hw/usb/hcd-dwc3.c b/hw/usb/hcd-dwc3.c > > new file mode 100644 > > index 0000000..de8be7a > > --- /dev/null > > +++ b/hw/usb/hcd-dwc3.c > > @@ -0,0 +1,717 @@ > > +/* > > + * QEMU model of the USB DWC3 host controller emulation. > > + * > > + * This model defines global register space of DWC3 controller. Global > > + * registers control the AXI/AHB interfaces properties, external FIFO support > > + * and event count support. All of which are unimplemented at present. We are > > + * only supporting core reset and read of ID register. > > + * > > + * Copyright (c) 2020 Xilinx Inc. Vikram Garhwal<fnu.vikram@xilinx.com> > > + * > > + * Permission is hereby granted, free of charge, to any person obtaining a copy > > + * of this software and associated documentation files (the "Software"), to deal > > + * in the Software without restriction, including without limitation the rights > > + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell > > + * copies of the Software, and to permit persons to whom the Software is > > + * furnished to do so, subject to the following conditions: > > + * > > + * The above copyright notice and this permission notice shall be included in > > + * all copies or substantial portions of the Software. > > + * > > + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR > > + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, > > + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL > > + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER > > + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, > > + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN > > + * THE SOFTWARE. > > + */ > > + > > +#include "qemu/osdep.h" > > +#include "hw/sysbus.h" > > +#include "hw/register.h" > > +#include "qemu/bitops.h" > > +#include "qemu/log.h" > > +#include "qom/object.h" > > +#include "migration/vmstate.h" > > +#include "hw/qdev-properties.h" > > +#include "hw/usb/hcd-dwc3.h" > > +#include "qapi/error.h" > > + > > +#ifndef USB_DWC3_ERR_DEBUG > > +#define USB_DWC3_ERR_DEBUG 0 > > +#endif > > + > > +#define HOST_MODE 1 > > +#define FIFO_LEN 0x1000 > > + > > +REG32(GSBUSCFG0, 0x00) > > + FIELD(GSBUSCFG0, DATRDREQINFO, 28, 4) > > + FIELD(GSBUSCFG0, DESRDREQINFO, 24, 4) > > + FIELD(GSBUSCFG0, DATWRREQINFO, 20, 4) > > + FIELD(GSBUSCFG0, DESWRREQINFO, 16, 4) > > + FIELD(GSBUSCFG0, RESERVED_15_12, 12, 4) > > + FIELD(GSBUSCFG0, DATBIGEND, 11, 1) > > + FIELD(GSBUSCFG0, DESBIGEND, 10, 1) > > + FIELD(GSBUSCFG0, RESERVED_9_8, 8, 2) > > + FIELD(GSBUSCFG0, INCR256BRSTENA, 7, 1) > > + FIELD(GSBUSCFG0, INCR128BRSTENA, 6, 1) > > + FIELD(GSBUSCFG0, INCR64BRSTENA, 5, 1) > > + FIELD(GSBUSCFG0, INCR32BRSTENA, 4, 1) > > + FIELD(GSBUSCFG0, INCR16BRSTENA, 3, 1) > > + FIELD(GSBUSCFG0, INCR8BRSTENA, 2, 1) > > + FIELD(GSBUSCFG0, INCR4BRSTENA, 1, 1) > > + FIELD(GSBUSCFG0, INCRBRSTENA, 0, 1) > > +REG32(GSBUSCFG1, 0x04) > > + FIELD(GSBUSCFG1, RESERVED_31_13, 13, 19) > > + FIELD(GSBUSCFG1, EN1KPAGE, 12, 1) > > + FIELD(GSBUSCFG1, PIPETRANSLIMIT, 8, 4) > > + FIELD(GSBUSCFG1, RESERVED_7_0, 0, 8) > > +REG32(GTXTHRCFG, 0x08) > > + FIELD(GTXTHRCFG, RESERVED_31, 31, 1) > > + FIELD(GTXTHRCFG, RESERVED_30, 30, 1) > > + FIELD(GTXTHRCFG, USBTXPKTCNTSEL, 29, 1) > > + FIELD(GTXTHRCFG, RESERVED_28, 28, 1) > > + FIELD(GTXTHRCFG, USBTXPKTCNT, 24, 4) > > + FIELD(GTXTHRCFG, USBMAXTXBURSTSIZE, 16, 8) > > + FIELD(GTXTHRCFG, RESERVED_15, 15, 1) > > + FIELD(GTXTHRCFG, RESERVED_14, 14, 1) > > + FIELD(GTXTHRCFG, RESERVED_13_11, 11, 3) > > + FIELD(GTXTHRCFG, RESERVED_10_0, 0, 11) > > +REG32(GRXTHRCFG, 0x0c) > > + FIELD(GRXTHRCFG, RESERVED_31_30, 30, 2) > > + FIELD(GRXTHRCFG, USBRXPKTCNTSEL, 29, 1) > > + FIELD(GRXTHRCFG, RESERVED_28, 28, 1) > > + FIELD(GRXTHRCFG, USBRXPKTCNT, 24, 4) > > + FIELD(GRXTHRCFG, USBMAXRXBURSTSIZE, 19, 5) > > + FIELD(GRXTHRCFG, RESERVED_18_16, 16, 3) > > + FIELD(GRXTHRCFG, RESERVED_15, 15, 1) > > + FIELD(GRXTHRCFG, RESERVED_14_13, 13, 2) > > + FIELD(GRXTHRCFG, RESVISOCOUTSPC, 0, 13) > > +REG32(GCTL, 0x10) > > + FIELD(GCTL, PWRDNSCALE, 19, 13) > > + FIELD(GCTL, MASTERFILTBYPASS, 18, 1) > > + FIELD(GCTL, BYPSSETADDR, 17, 1) > > + FIELD(GCTL, U2RSTECN, 16, 1) > > + FIELD(GCTL, FRMSCLDWN, 14, 2) > > + FIELD(GCTL, PRTCAPDIR, 12, 2) > > + FIELD(GCTL, CORESOFTRESET, 11, 1) > > + FIELD(GCTL, U1U2TIMERSCALE, 9, 1) > > + FIELD(GCTL, DEBUGATTACH, 8, 1) > > + FIELD(GCTL, RAMCLKSEL, 6, 2) > > + FIELD(GCTL, SCALEDOWN, 4, 2) > > + FIELD(GCTL, DISSCRAMBLE, 3, 1) > > + FIELD(GCTL, U2EXIT_LFPS, 2, 1) > > + FIELD(GCTL, GBLHIBERNATIONEN, 1, 1) > > + FIELD(GCTL, DSBLCLKGTNG, 0, 1) > > +REG32(GPMSTS, 0x14) > > +REG32(GSTS, 0x18) > > + FIELD(GSTS, CBELT, 20, 12) > > + FIELD(GSTS, RESERVED_19_12, 12, 8) > > + FIELD(GSTS, SSIC_IP, 11, 1) > > + FIELD(GSTS, OTG_IP, 10, 1) > > + FIELD(GSTS, BC_IP, 9, 1) > > + FIELD(GSTS, ADP_IP, 8, 1) > > + FIELD(GSTS, HOST_IP, 7, 1) > > + FIELD(GSTS, DEVICE_IP, 6, 1) > > + FIELD(GSTS, CSRTIMEOUT, 5, 1) > > + FIELD(GSTS, BUSERRADDRVLD, 4, 1) > > + FIELD(GSTS, RESERVED_3_2, 2, 2) > > + FIELD(GSTS, CURMOD, 0, 2) > > +REG32(GUCTL1, 0x1c) > > + FIELD(GUCTL1, RESUME_OPMODE_HS_HOST, 10, 1) > > +REG32(GSNPSID, 0x20) > > +REG32(GGPIO, 0x24) > > + FIELD(GGPIO, GPO, 16, 16) > > + FIELD(GGPIO, GPI, 0, 16) > > +REG32(GUID, 0x28) > > +REG32(GUCTL, 0x2c) > > + FIELD(GUCTL, REFCLKPER, 22, 10) > > + FIELD(GUCTL, NOEXTRDL, 21, 1) > > + FIELD(GUCTL, RESERVED_20_18, 18, 3) > > + FIELD(GUCTL, SPRSCTRLTRANSEN, 17, 1) > > + FIELD(GUCTL, RESBWHSEPS, 16, 1) > > + FIELD(GUCTL, RESERVED_15, 15, 1) > > + FIELD(GUCTL, USBHSTINAUTORETRYEN, 14, 1) > > + FIELD(GUCTL, ENOVERLAPCHK, 13, 1) > > + FIELD(GUCTL, EXTCAPSUPPTEN, 12, 1) > > + FIELD(GUCTL, INSRTEXTRFSBODI, 11, 1) > > + FIELD(GUCTL, DTCT, 9, 2) > > + FIELD(GUCTL, DTFT, 0, 9) > > +REG32(GBUSERRADDRLO, 0x30) > > +REG32(GBUSERRADDRHI, 0x34) > > +REG32(GHWPARAMS0, 0x40) > > + FIELD(GHWPARAMS0, GHWPARAMS0_31_24, 24, 8) > > + FIELD(GHWPARAMS0, GHWPARAMS0_23_16, 16, 8) > > + FIELD(GHWPARAMS0, GHWPARAMS0_15_8, 8, 8) > > + FIELD(GHWPARAMS0, GHWPARAMS0_7_6, 6, 2) > > + FIELD(GHWPARAMS0, GHWPARAMS0_5_3, 3, 3) > > + FIELD(GHWPARAMS0, GHWPARAMS0_2_0, 0, 3) > > +REG32(GHWPARAMS1, 0x44) > > + FIELD(GHWPARAMS1, GHWPARAMS1_31, 31, 1) > > + FIELD(GHWPARAMS1, GHWPARAMS1_30, 30, 1) > > + FIELD(GHWPARAMS1, GHWPARAMS1_29, 29, 1) > > + FIELD(GHWPARAMS1, GHWPARAMS1_28, 28, 1) > > + FIELD(GHWPARAMS1, GHWPARAMS1_27, 27, 1) > > + FIELD(GHWPARAMS1, GHWPARAMS1_26, 26, 1) > > + FIELD(GHWPARAMS1, GHWPARAMS1_25_24, 24, 2) > > + FIELD(GHWPARAMS1, GHWPARAMS1_23, 23, 1) > > + FIELD(GHWPARAMS1, GHWPARAMS1_22_21, 21, 2) > > + FIELD(GHWPARAMS1, GHWPARAMS1_20_15, 15, 6) > > + FIELD(GHWPARAMS1, GHWPARAMS1_14_12, 12, 3) > > + FIELD(GHWPARAMS1, GHWPARAMS1_11_9, 9, 3) > > + FIELD(GHWPARAMS1, GHWPARAMS1_8_6, 6, 3) > > + FIELD(GHWPARAMS1, GHWPARAMS1_5_3, 3, 3) > > + FIELD(GHWPARAMS1, GHWPARAMS1_2_0, 0, 3) > > +REG32(GHWPARAMS2, 0x48) > > +REG32(GHWPARAMS3, 0x4c) > > + FIELD(GHWPARAMS3, GHWPARAMS3_31, 31, 1) > > + FIELD(GHWPARAMS3, GHWPARAMS3_30_23, 23, 8) > > + FIELD(GHWPARAMS3, GHWPARAMS3_22_18, 18, 5) > > + FIELD(GHWPARAMS3, GHWPARAMS3_17_12, 12, 6) > > + FIELD(GHWPARAMS3, GHWPARAMS3_11, 11, 1) > > + FIELD(GHWPARAMS3, GHWPARAMS3_10, 10, 1) > > + FIELD(GHWPARAMS3, GHWPARAMS3_9_8, 8, 2) > > + FIELD(GHWPARAMS3, GHWPARAMS3_7_6, 6, 2) > > + FIELD(GHWPARAMS3, GHWPARAMS3_5_4, 4, 2) > > + FIELD(GHWPARAMS3, GHWPARAMS3_3_2, 2, 2) > > + FIELD(GHWPARAMS3, GHWPARAMS3_1_0, 0, 2) > > +REG32(GHWPARAMS4, 0x50) > > + FIELD(GHWPARAMS4, GHWPARAMS4_31_28, 28, 4) > > + FIELD(GHWPARAMS4, GHWPARAMS4_27_24, 24, 4) > > + FIELD(GHWPARAMS4, GHWPARAMS4_23, 23, 1) > > + FIELD(GHWPARAMS4, GHWPARAMS4_22, 22, 1) > > + FIELD(GHWPARAMS4, GHWPARAMS4_21, 21, 1) > > + FIELD(GHWPARAMS4, GHWPARAMS4_20_17, 17, 4) > > + FIELD(GHWPARAMS4, GHWPARAMS4_16_13, 13, 4) > > + FIELD(GHWPARAMS4, GHWPARAMS4_12, 12, 1) > > + FIELD(GHWPARAMS4, GHWPARAMS4_11, 11, 1) > > + FIELD(GHWPARAMS4, GHWPARAMS4_10_9, 9, 2) > > + FIELD(GHWPARAMS4, GHWPARAMS4_8_7, 7, 2) > > + FIELD(GHWPARAMS4, GHWPARAMS4_6, 6, 1) > > + FIELD(GHWPARAMS4, GHWPARAMS4_5_0, 0, 6) > > +REG32(GHWPARAMS5, 0x54) > > + FIELD(GHWPARAMS5, GHWPARAMS5_31_28, 28, 4) > > + FIELD(GHWPARAMS5, GHWPARAMS5_27_22, 22, 6) > > + FIELD(GHWPARAMS5, GHWPARAMS5_21_16, 16, 6) > > + FIELD(GHWPARAMS5, GHWPARAMS5_15_10, 10, 6) > > + FIELD(GHWPARAMS5, GHWPARAMS5_9_4, 4, 6) > > + FIELD(GHWPARAMS5, GHWPARAMS5_3_0, 0, 4) > > +REG32(GHWPARAMS6, 0x58) > > + FIELD(GHWPARAMS6, GHWPARAMS6_31_16, 16, 16) > > + FIELD(GHWPARAMS6, BUSFLTRSSUPPORT, 15, 1) > > + FIELD(GHWPARAMS6, BCSUPPORT, 14, 1) > > + FIELD(GHWPARAMS6, OTG_SS_SUPPORT, 13, 1) > > + FIELD(GHWPARAMS6, ADPSUPPORT, 12, 1) > > + FIELD(GHWPARAMS6, HNPSUPPORT, 11, 1) > > + FIELD(GHWPARAMS6, SRPSUPPORT, 10, 1) > > + FIELD(GHWPARAMS6, GHWPARAMS6_9_8, 8, 2) > > + FIELD(GHWPARAMS6, GHWPARAMS6_7, 7, 1) > > + FIELD(GHWPARAMS6, GHWPARAMS6_6, 6, 1) > > + FIELD(GHWPARAMS6, GHWPARAMS6_5_0, 0, 6) > > +REG32(GHWPARAMS7, 0x5c) > > + FIELD(GHWPARAMS7, GHWPARAMS7_31_16, 16, 16) > > + FIELD(GHWPARAMS7, GHWPARAMS7_15_0, 0, 16) > > +REG32(GDBGFIFOSPACE, 0x60) > > + FIELD(GDBGFIFOSPACE, SPACE_AVAILABLE, 16, 16) > > + FIELD(GDBGFIFOSPACE, RESERVED_15_9, 9, 7) > > + FIELD(GDBGFIFOSPACE, FIFO_QUEUE_SELECT, 0, 9) > > +REG32(GUCTL2, 0x9c) > > + FIELD(GUCTL2, RESERVED_31_26, 26, 6) > > + FIELD(GUCTL2, EN_HP_PM_TIMER, 19, 7) > > + FIELD(GUCTL2, NOLOWPWRDUR, 15, 4) > > + FIELD(GUCTL2, RST_ACTBITLATER, 14, 1) > > + FIELD(GUCTL2, RESERVED_13, 13, 1) > > + FIELD(GUCTL2, DISABLECFC, 11, 1) > > +REG32(GUSB2PHYCFG, 0x100) > > + FIELD(GUSB2PHYCFG, U2_FREECLK_EXISTS, 30, 1) > > + FIELD(GUSB2PHYCFG, ULPI_LPM_WITH_OPMODE_CHK, 29, 1) > > + FIELD(GUSB2PHYCFG, RESERVED_25, 25, 1) > > + FIELD(GUSB2PHYCFG, LSTRD, 22, 3) > > + FIELD(GUSB2PHYCFG, LSIPD, 19, 3) > > + FIELD(GUSB2PHYCFG, ULPIEXTVBUSINDIACTOR, 18, 1) > > + FIELD(GUSB2PHYCFG, ULPIEXTVBUSDRV, 17, 1) > > + FIELD(GUSB2PHYCFG, RESERVED_16, 16, 1) > > + FIELD(GUSB2PHYCFG, ULPIAUTORES, 15, 1) > > + FIELD(GUSB2PHYCFG, RESERVED_14, 14, 1) > > + FIELD(GUSB2PHYCFG, USBTRDTIM, 10, 4) > > + FIELD(GUSB2PHYCFG, XCVRDLY, 9, 1) > > + FIELD(GUSB2PHYCFG, ENBLSLPM, 8, 1) > > + FIELD(GUSB2PHYCFG, PHYSEL, 7, 1) > > + FIELD(GUSB2PHYCFG, SUSPENDUSB20, 6, 1) > > + FIELD(GUSB2PHYCFG, FSINTF, 5, 1) > > + FIELD(GUSB2PHYCFG, ULPI_UTMI_SEL, 4, 1) > > + FIELD(GUSB2PHYCFG, PHYIF, 3, 1) > > + FIELD(GUSB2PHYCFG, TOUTCAL, 0, 3) > > +REG32(GUSB2I2CCTL, 0x140) > > +REG32(GUSB2PHYACC_ULPI, 0x180) > > + FIELD(GUSB2PHYACC_ULPI, RESERVED_31_27, 27, 5) > > + FIELD(GUSB2PHYACC_ULPI, DISUIPIDRVR, 26, 1) > > + FIELD(GUSB2PHYACC_ULPI, NEWREGREQ, 25, 1) > > + FIELD(GUSB2PHYACC_ULPI, VSTSDONE, 24, 1) > > + FIELD(GUSB2PHYACC_ULPI, VSTSBSY, 23, 1) > > + FIELD(GUSB2PHYACC_ULPI, REGWR, 22, 1) > > + FIELD(GUSB2PHYACC_ULPI, REGADDR, 16, 6) > > + FIELD(GUSB2PHYACC_ULPI, EXTREGADDR, 8, 8) > > + FIELD(GUSB2PHYACC_ULPI, REGDATA, 0, 8) > > +REG32(GTXFIFOSIZ0, 0x200) > > + FIELD(GTXFIFOSIZ0, TXFSTADDR_N, 16, 16) > > + FIELD(GTXFIFOSIZ0, TXFDEP_N, 0, 16) > > +REG32(GTXFIFOSIZ1, 0x204) > > + FIELD(GTXFIFOSIZ1, TXFSTADDR_N, 16, 16) > > + FIELD(GTXFIFOSIZ1, TXFDEP_N, 0, 16) > > +REG32(GTXFIFOSIZ2, 0x208) > > + FIELD(GTXFIFOSIZ2, TXFSTADDR_N, 16, 16) > > + FIELD(GTXFIFOSIZ2, TXFDEP_N, 0, 16) > > +REG32(GTXFIFOSIZ3, 0x20c) > > + FIELD(GTXFIFOSIZ3, TXFSTADDR_N, 16, 16) > > + FIELD(GTXFIFOSIZ3, TXFDEP_N, 0, 16) > > +REG32(GTXFIFOSIZ4, 0x210) > > + FIELD(GTXFIFOSIZ4, TXFSTADDR_N, 16, 16) > > + FIELD(GTXFIFOSIZ4, TXFDEP_N, 0, 16) > > +REG32(GTXFIFOSIZ5, 0x214) > > + FIELD(GTXFIFOSIZ5, TXFSTADDR_N, 16, 16) > > + FIELD(GTXFIFOSIZ5, TXFDEP_N, 0, 16) > > +REG32(GRXFIFOSIZ0, 0x280) > > + FIELD(GRXFIFOSIZ0, RXFSTADDR_N, 16, 16) > > + FIELD(GRXFIFOSIZ0, RXFDEP_N, 0, 16) > > +REG32(GRXFIFOSIZ1, 0x284) > > + FIELD(GRXFIFOSIZ1, RXFSTADDR_N, 16, 16) > > + FIELD(GRXFIFOSIZ1, RXFDEP_N, 0, 16) > > +REG32(GRXFIFOSIZ2, 0x288) > > + FIELD(GRXFIFOSIZ2, RXFSTADDR_N, 16, 16) > > + FIELD(GRXFIFOSIZ2, RXFDEP_N, 0, 16) > > +REG32(GEVNTADRLO_0, 0x300) > > +REG32(GEVNTADRHI_0, 0x304) > > +REG32(GEVNTSIZ_0, 0x308) > > + FIELD(GEVNTSIZ_0, EVNTINTRPTMASK, 31, 1) > > + FIELD(GEVNTSIZ_0, RESERVED_30_16, 16, 15) > > + FIELD(GEVNTSIZ_0, EVENTSIZ, 0, 16) > > +REG32(GEVNTCOUNT_0, 0x30c) > > + FIELD(GEVNTCOUNT_0, EVNT_HANDLER_BUSY, 31, 1) > > + FIELD(GEVNTCOUNT_0, RESERVED_30_16, 16, 15) > > + FIELD(GEVNTCOUNT_0, EVNTCOUNT, 0, 16) > > +REG32(GEVNTADRLO_1, 0x310) > > +REG32(GEVNTADRHI_1, 0x314) > > +REG32(GEVNTSIZ_1, 0x318) > > + FIELD(GEVNTSIZ_1, EVNTINTRPTMASK, 31, 1) > > + FIELD(GEVNTSIZ_1, RESERVED_30_16, 16, 15) > > + FIELD(GEVNTSIZ_1, EVENTSIZ, 0, 16) > > +REG32(GEVNTCOUNT_1, 0x31c) > > + FIELD(GEVNTCOUNT_1, EVNT_HANDLER_BUSY, 31, 1) > > + FIELD(GEVNTCOUNT_1, RESERVED_30_16, 16, 15) > > + FIELD(GEVNTCOUNT_1, EVNTCOUNT, 0, 16) > > +REG32(GEVNTADRLO_2, 0x320) > > +REG32(GEVNTADRHI_2, 0x324) > > +REG32(GEVNTSIZ_2, 0x328) > > + FIELD(GEVNTSIZ_2, EVNTINTRPTMASK, 31, 1) > > + FIELD(GEVNTSIZ_2, RESERVED_30_16, 16, 15) > > + FIELD(GEVNTSIZ_2, EVENTSIZ, 0, 16) > > +REG32(GEVNTCOUNT_2, 0x32c) > > + FIELD(GEVNTCOUNT_2, EVNT_HANDLER_BUSY, 31, 1) > > + FIELD(GEVNTCOUNT_2, RESERVED_30_16, 16, 15) > > + FIELD(GEVNTCOUNT_2, EVNTCOUNT, 0, 16) > > +REG32(GEVNTADRLO_3, 0x330) > > +REG32(GEVNTADRHI_3, 0x334) > > +REG32(GEVNTSIZ_3, 0x338) > > + FIELD(GEVNTSIZ_3, EVNTINTRPTMASK, 31, 1) > > + FIELD(GEVNTSIZ_3, RESERVED_30_16, 16, 15) > > + FIELD(GEVNTSIZ_3, EVENTSIZ, 0, 16) > > +REG32(GEVNTCOUNT_3, 0x33c) > > + FIELD(GEVNTCOUNT_3, EVNT_HANDLER_BUSY, 31, 1) > > + FIELD(GEVNTCOUNT_3, RESERVED_30_16, 16, 15) > > + FIELD(GEVNTCOUNT_3, EVNTCOUNT, 0, 16) > > +REG32(GHWPARAMS8, 0x500) > > +REG32(GTXFIFOPRIDEV, 0x510) > > + FIELD(GTXFIFOPRIDEV, RESERVED_31_N, 6, 26) > > + FIELD(GTXFIFOPRIDEV, GTXFIFOPRIDEV, 0, 6) > > +REG32(GTXFIFOPRIHST, 0x518) > > + FIELD(GTXFIFOPRIHST, RESERVED_31_16, 3, 29) > > + FIELD(GTXFIFOPRIHST, GTXFIFOPRIHST, 0, 3) > > +REG32(GRXFIFOPRIHST, 0x51c) > > + FIELD(GRXFIFOPRIHST, RESERVED_31_16, 3, 29) > > + FIELD(GRXFIFOPRIHST, GRXFIFOPRIHST, 0, 3) > > +REG32(GDMAHLRATIO, 0x524) > > + FIELD(GDMAHLRATIO, RESERVED_31_13, 13, 19) > > + FIELD(GDMAHLRATIO, HSTRXFIFO, 8, 5) > > + FIELD(GDMAHLRATIO, RESERVED_7_5, 5, 3) > > + FIELD(GDMAHLRATIO, HSTTXFIFO, 0, 5) > > +REG32(GFLADJ, 0x530) > > + FIELD(GFLADJ, GFLADJ_REFCLK_240MHZDECR_PLS1, 31, 1) > > + FIELD(GFLADJ, GFLADJ_REFCLK_240MHZ_DECR, 24, 7) > > + FIELD(GFLADJ, GFLADJ_REFCLK_LPM_SEL, 23, 1) > > + FIELD(GFLADJ, RESERVED_22, 22, 1) > > + FIELD(GFLADJ, GFLADJ_REFCLK_FLADJ, 8, 14) > > + FIELD(GFLADJ, GFLADJ_30MHZ_SDBND_SEL, 7, 1) > > + FIELD(GFLADJ, GFLADJ_30MHZ, 0, 6) > > + > > +static void reset_csr(USBDWC3 * s) > > +{ > > + int i = 0; > > + /* > > + * We reset all CSR regs except GCTL, GUCTL, GSTS, GSNPSID, GGPIO, GUID, > > + * GUSB2PHYCFGn registers and GUSB3PIPECTLn registers. We will skip PHY > > + * register as we don't implement them. > > + */ > > + for (i = 0; i < R_GCTL; i++) { > > + register_reset(&s->regs_info[i]); > > + } > > + > > + for (i = R_GCTL; i < R_GBUSERRADDRLO; i++) { > > + if (i == R_GUCTL1 || i == R_GPMSTS) { > > + register_reset(&s->regs_info[i]); > > + } else { > > + continue; > > + } > > + } > > + > > + for (i = R_GBUSERRADDRLO; i < USB_DWC3_R_MAX; i++) { > > + register_reset(&s->regs_info[i]); > > + } > > Can we instead iterate through them all and have a list with the ones > that wont be reset? It'll be easier to understand the code and match > it with the regs that shouldn't reset. > e.g: > > for (i = 0; i < USB_DWC3_R_MAX; i++) { > switch (i) { > case R_GCTL: > case XXX: > /* Should not reset. */ > break; > default: > register_reset(&s->regs_info[i]); > break; > } > } > Added this change for next patch version. > > + > > + xhci_sysbus_reset(DEVICE(&s->sysbus_xhci)); > > +} > > + > > +static void usb_dwc3_gctl_postw(RegisterInfo *reg, uint64_t val64) > > +{ > > + USBDWC3 *s = USB_DWC3(reg->opaque); > > + > > + if (ARRAY_FIELD_EX32(s->regs, GCTL, CORESOFTRESET)) { > > + reset_csr(s); > > + } > > +} > > + > > +static void usb_dwc3_guid_postw(RegisterInfo *reg, uint64_t val64) > > +{ > > + USBDWC3 *s = USB_DWC3(reg->opaque); > > + > > + s->regs[R_GUID] = s->cfg.dwc_usb3_user; > > +} > > This looks strange. Is this register really writeable on real HW? > Looks lite a read-only register that should get it's value from the property... > > Yeah,this is defined as r/w in the host mode. Description: "After power-up, the software can change this value. This register can be used as either a scratch pad or identification register." > > + > > +static void usb_dwc3_unimpl_postw(RegisterInfo *reg, uint64_t val64) > > +{ > > + qemu_log_mask(LOG_UNIMP, "%s not supported\n", reg->access->name); > > +} > > + > > +static uint64_t usb_dwc3_unimpl_postr(RegisterInfo *reg, uint64_t val64) > > +{ > > + qemu_log_mask(LOG_UNIMP, "%s not supported\n", reg->access->name); > > + return val64; > > +} > > We should probably use the regapi .unimp instead of these functions. > Added this in v12. > > + > > +static const RegisterAccessInfo usb_dwc3_regs_info[] = { > > + { .name = "GSBUSCFG0", .addr = A_GSBUSCFG0, > > + .ro = 0xf300, > > + .post_read = usb_dwc3_unimpl_postr, > > + .post_write = usb_dwc3_unimpl_postw, > > + },{ .name = "GSBUSCFG1", .addr = A_GSBUSCFG1, > > + .reset = 0x300, > > + .ro = 0xffffe0ff, > > + .post_read = usb_dwc3_unimpl_postr, > > + .post_write = usb_dwc3_unimpl_postw, > > + },{ .name = "GTXTHRCFG", .addr = A_GTXTHRCFG, > > + .ro = 0xd000ffff, > > + .post_read = usb_dwc3_unimpl_postr, > > + .post_write = usb_dwc3_unimpl_postw, > > + },{ .name = "GRXTHRCFG", .addr = A_GRXTHRCFG, > > + .ro = 0xd007e000, > > + .post_read = usb_dwc3_unimpl_postr, > > + .post_write = usb_dwc3_unimpl_postw, > > + },{ .name = "GCTL", .addr = A_GCTL, > > + .reset = 0x30c13004, .post_write = usb_dwc3_gctl_postw, > > + },{ .name = "GPMSTS", .addr = A_GPMSTS, > > + .ro = 0xfffffff, > > + .post_read = usb_dwc3_unimpl_postr, > > + .post_write = usb_dwc3_unimpl_postw, > > + },{ .name = "GSTS", .addr = A_GSTS, > > + .reset = 0x7e800000, > > + .ro = 0xffffffcf, > > + .w1c = 0x30, > > + .post_read = usb_dwc3_unimpl_postr, > > + .post_write = usb_dwc3_unimpl_postw, > > + },{ .name = "GUCTL1", .addr = A_GUCTL1, > > + .reset = 0x198a, > > + .ro = 0x7800, > > + .post_read = usb_dwc3_unimpl_postr, > > + .post_write = usb_dwc3_unimpl_postw, > > + },{ .name = "GSNPSID", .addr = A_GSNPSID, > > + .reset = 0x5533330a, > > + .ro = 0xffffffff, > > + },{ .name = "GGPIO", .addr = A_GGPIO, > > + .ro = 0xffff, > > + .post_read = usb_dwc3_unimpl_postr, > > + .post_write = usb_dwc3_unimpl_postw, > > + },{ .name = "GUID", .addr = A_GUID, > > + .reset = 0x12345678, .post_write = usb_dwc3_guid_postw, > > + },{ .name = "GUCTL", .addr = A_GUCTL, > > + .reset = 0x0c808010, > > + .ro = 0x1c8000, > > + .post_read = usb_dwc3_unimpl_postr, > > + .post_write = usb_dwc3_unimpl_postw, > > + },{ .name = "GBUSERRADDRLO", .addr = A_GBUSERRADDRLO, > > + .ro = 0xffffffff, > > + .post_read = usb_dwc3_unimpl_postr, > > + },{ .name = "GBUSERRADDRHI", .addr = A_GBUSERRADDRHI, > > + .ro = 0xffffffff, > > + .post_read = usb_dwc3_unimpl_postr, > > + },{ .name = "GHWPARAMS0", .addr = A_GHWPARAMS0, > > + .ro = 0xffffffff, > > + },{ .name = "GHWPARAMS1", .addr = A_GHWPARAMS1, > > + .ro = 0xffffffff, > > + },{ .name = "GHWPARAMS2", .addr = A_GHWPARAMS2, > > + .ro = 0xffffffff, > > + },{ .name = "GHWPARAMS3", .addr = A_GHWPARAMS3, > > + .ro = 0xffffffff, > > + },{ .name = "GHWPARAMS4", .addr = A_GHWPARAMS4, > > + .ro = 0xffffffff, > > + },{ .name = "GHWPARAMS5", .addr = A_GHWPARAMS5, > > + .ro = 0xffffffff, > > + },{ .name = "GHWPARAMS6", .addr = A_GHWPARAMS6, > > + .ro = 0xffffffff, > > + },{ .name = "GHWPARAMS7", .addr = A_GHWPARAMS7, > > + .ro = 0xffffffff, > > + },{ .name = "GDBGFIFOSPACE", .addr = A_GDBGFIFOSPACE, > > + .reset = 0xa0000, > > + .ro = 0xfffffe00, > > + .post_read = usb_dwc3_unimpl_postr, > > + .post_write = usb_dwc3_unimpl_postw, > > + },{ .name = "GUCTL2", .addr = A_GUCTL2, > > + .reset = 0x40d, > > + .ro = 0x2000, > > + .post_read = usb_dwc3_unimpl_postr, > > + .post_write = usb_dwc3_unimpl_postw, > > + },{ .name = "GUSB2PHYCFG", .addr = A_GUSB2PHYCFG, > > + .reset = 0x40102410, > > + .ro = 0x1e014030, > > + .post_read = usb_dwc3_unimpl_postr, > > + .post_write = usb_dwc3_unimpl_postw, > > + },{ .name = "GUSB2I2CCTL", .addr = A_GUSB2I2CCTL, > > + .ro = 0xffffffff, > > + .post_read = usb_dwc3_unimpl_postr, > > + .post_write = usb_dwc3_unimpl_postw, > > + },{ .name = "GUSB2PHYACC_ULPI", .addr = A_GUSB2PHYACC_ULPI, > > + .ro = 0xfd000000, > > + .post_read = usb_dwc3_unimpl_postr, > > + .post_write = usb_dwc3_unimpl_postw, > > + },{ .name = "GTXFIFOSIZ0", .addr = A_GTXFIFOSIZ0, > > + .reset = 0x2c7000a, > > + .post_read = usb_dwc3_unimpl_postr, > > + .post_write = usb_dwc3_unimpl_postw, > > + },{ .name = "GTXFIFOSIZ1", .addr = A_GTXFIFOSIZ1, > > + .reset = 0x2d10103, > > + .post_read = usb_dwc3_unimpl_postr, > > + .post_write = usb_dwc3_unimpl_postw, > > + },{ .name = "GTXFIFOSIZ2", .addr = A_GTXFIFOSIZ2, > > + .reset = 0x3d40103, > > + .post_read = usb_dwc3_unimpl_postr, > > + .post_write = usb_dwc3_unimpl_postw, > > + },{ .name = "GTXFIFOSIZ3", .addr = A_GTXFIFOSIZ3, > > + .reset = 0x4d70083, > > + .post_read = usb_dwc3_unimpl_postr, > > + .post_write = usb_dwc3_unimpl_postw, > > + },{ .name = "GTXFIFOSIZ4", .addr = A_GTXFIFOSIZ4, > > + .reset = 0x55a0083, > > + .post_read = usb_dwc3_unimpl_postr, > > + .post_write = usb_dwc3_unimpl_postw, > > + },{ .name = "GTXFIFOSIZ5", .addr = A_GTXFIFOSIZ5, > > + .reset = 0x5dd0083, > > + .post_read = usb_dwc3_unimpl_postr, > > + .post_write = usb_dwc3_unimpl_postw, > > + },{ .name = "GRXFIFOSIZ0", .addr = A_GRXFIFOSIZ0, > > + .reset = 0x1c20105, > > + .post_read = usb_dwc3_unimpl_postr, > > + .post_write = usb_dwc3_unimpl_postw, > > + },{ .name = "GRXFIFOSIZ1", .addr = A_GRXFIFOSIZ1, > > + .reset = 0x2c70000, > > + .post_read = usb_dwc3_unimpl_postr, > > + .post_write = usb_dwc3_unimpl_postw, > > + },{ .name = "GRXFIFOSIZ2", .addr = A_GRXFIFOSIZ2, > > + .reset = 0x2c70000, > > + .post_read = usb_dwc3_unimpl_postr, > > + .post_write = usb_dwc3_unimpl_postw, > > + },{ .name = "GEVNTADRLO_0", .addr = A_GEVNTADRLO_0, > > + .post_read = usb_dwc3_unimpl_postr, > > + .post_write = usb_dwc3_unimpl_postw, > > + },{ .name = "GEVNTADRHI_0", .addr = A_GEVNTADRHI_0, > > + .post_read = usb_dwc3_unimpl_postr, > > + .post_write = usb_dwc3_unimpl_postw, > > + },{ .name = "GEVNTSIZ_0", .addr = A_GEVNTSIZ_0, > > + .ro = 0x7fff0000, > > + .post_read = usb_dwc3_unimpl_postr, > > + .post_write = usb_dwc3_unimpl_postw, > > + },{ .name = "GEVNTCOUNT_0", .addr = A_GEVNTCOUNT_0, > > + .ro = 0x7fff0000, > > + .post_read = usb_dwc3_unimpl_postr, > > + .post_write = usb_dwc3_unimpl_postw, > > + },{ .name = "GEVNTADRLO_1", .addr = A_GEVNTADRLO_1, > > + .post_read = usb_dwc3_unimpl_postr, > > + .post_write = usb_dwc3_unimpl_postw, > > + },{ .name = "GEVNTADRHI_1", .addr = A_GEVNTADRHI_1, > > + .post_read = usb_dwc3_unimpl_postr, > > + .post_write = usb_dwc3_unimpl_postw, > > + },{ .name = "GEVNTSIZ_1", .addr = A_GEVNTSIZ_1, > > + .ro = 0x7fff0000, > > + .post_read = usb_dwc3_unimpl_postr, > > + .post_write = usb_dwc3_unimpl_postw, > > + },{ .name = "GEVNTCOUNT_1", .addr = A_GEVNTCOUNT_1, > > + .ro = 0x7fff0000, > > + .post_read = usb_dwc3_unimpl_postr, > > + .post_write = usb_dwc3_unimpl_postw, > > + },{ .name = "GEVNTADRLO_2", .addr = A_GEVNTADRLO_2, > > + .post_read = usb_dwc3_unimpl_postr, > > + .post_write = usb_dwc3_unimpl_postw, > > + },{ .name = "GEVNTADRHI_2", .addr = A_GEVNTADRHI_2, > > + .post_read = usb_dwc3_unimpl_postr, > > + .post_write = usb_dwc3_unimpl_postw, > > + },{ .name = "GEVNTSIZ_2", .addr = A_GEVNTSIZ_2, > > + .ro = 0x7fff0000, > > + .post_read = usb_dwc3_unimpl_postr, > > + .post_write = usb_dwc3_unimpl_postw, > > + },{ .name = "GEVNTCOUNT_2", .addr = A_GEVNTCOUNT_2, > > + .ro = 0x7fff0000, > > + .post_read = usb_dwc3_unimpl_postr, > > + .post_write = usb_dwc3_unimpl_postw, > > + },{ .name = "GEVNTADRLO_3", .addr = A_GEVNTADRLO_3, > > + .post_read = usb_dwc3_unimpl_postr, > > + .post_write = usb_dwc3_unimpl_postw, > > + },{ .name = "GEVNTADRHI_3", .addr = A_GEVNTADRHI_3, > > + .post_read = usb_dwc3_unimpl_postr, > > + .post_write = usb_dwc3_unimpl_postw, > > + },{ .name = "GEVNTSIZ_3", .addr = A_GEVNTSIZ_3, > > + .ro = 0x7fff0000, > > + .post_read = usb_dwc3_unimpl_postr, > > + .post_write = usb_dwc3_unimpl_postw, > > + },{ .name = "GEVNTCOUNT_3", .addr = A_GEVNTCOUNT_3, > > + .ro = 0x7fff0000, > > + .post_read = usb_dwc3_unimpl_postr, > > + .post_write = usb_dwc3_unimpl_postw, > > + },{ .name = "GHWPARAMS8", .addr = A_GHWPARAMS8, > > + .ro = 0xffffffff, > > + .post_read = usb_dwc3_unimpl_postr, > > + .post_write = usb_dwc3_unimpl_postw, > > + },{ .name = "GTXFIFOPRIDEV", .addr = A_GTXFIFOPRIDEV, > > + .ro = 0xffffffc0, > > + .post_read = usb_dwc3_unimpl_postr, > > + .post_write = usb_dwc3_unimpl_postw, > > + },{ .name = "GTXFIFOPRIHST", .addr = A_GTXFIFOPRIHST, > > + .ro = 0xfffffff8, > > + .post_read = usb_dwc3_unimpl_postr, > > + .post_write = usb_dwc3_unimpl_postw, > > + },{ .name = "GRXFIFOPRIHST", .addr = A_GRXFIFOPRIHST, > > + .ro = 0xfffffff8, > > + .post_read = usb_dwc3_unimpl_postr, > > + .post_write = usb_dwc3_unimpl_postw, > > + },{ .name = "GDMAHLRATIO", .addr = A_GDMAHLRATIO, > > + .ro = 0xffffe0e0, > > + .post_read = usb_dwc3_unimpl_postr, > > + .post_write = usb_dwc3_unimpl_postw, > > + },{ .name = "GFLADJ", .addr = A_GFLADJ, > > + .reset = 0xc83f020, > > + .rsvd = 0x40, > > + .ro = 0x400040, > > + .post_read = usb_dwc3_unimpl_postr, > > + .post_write = usb_dwc3_unimpl_postw, > > + } > > +}; > > + > > +static void usb_dwc3_reset(DeviceState *dev) > > +{ > > + USBDWC3 *s = USB_DWC3(dev); > > + unsigned int i; > > + > > + for (i = 0; i < ARRAY_SIZE(s->regs_info); ++i) { > > + register_reset(&s->regs_info[i]); > > + } > > + > > + /* > > + * Device Configuration > > + */ > > + s->regs[R_GHWPARAMS0] = 0x40204048 | s->cfg.mode; > > + s->regs[R_GHWPARAMS1] = 0x222493b; > > + s->regs[R_GHWPARAMS2] = 0x12345678; > > + s->regs[R_GHWPARAMS3] = 0x618c088; > > + s->regs[R_GHWPARAMS4] = 0x47822004; > > + s->regs[R_GHWPARAMS5] = 0x4202088; > > + s->regs[R_GHWPARAMS6] = 0x7850c20; > > + s->regs[R_GHWPARAMS7] = 0x0; > > + s->regs[R_GHWPARAMS8] = 0x478; > > Shouldn't these be setup in realize()? We added those manually to keep them at one place. Like most of the mainline models do. > > > + > > + xhci_sysbus_reset(DEVICE(&s->sysbus_xhci)); > > +} > > + > > +static const MemoryRegionOps usb_dwc3_ops = { > > + .read = register_read_memory, > > + .write = register_write_memory, > > + .endianness = DEVICE_LITTLE_ENDIAN, > > + .valid = { > > + .min_access_size = 4, > > + .max_access_size = 4, > > + }, > > +}; > > + > > +static void usb_dwc3_realize(DeviceState *dev, Error **errp) > > +{ > > + USBDWC3 *s = USB_DWC3(dev); > > + Error *err = NULL; > > + > > + sysbus_realize(SYS_BUS_DEVICE(&s->sysbus_xhci), &err); > > + if (err) { > > + error_propagate(errp, err); > > + return; > > + } > > +} > > + > > +static void usb_dwc3_init(Object *obj) > > +{ > > + USBDWC3 *s = USB_DWC3(obj); > > + SysBusDevice *sbd = SYS_BUS_DEVICE(obj); > > + RegisterInfoArray *reg_array; > > + > > + memory_region_init(&s->iomem, obj, TYPE_USB_DWC3, USB_DWC3_R_MAX * 4); > > + reg_array = > > + register_init_block32(DEVICE(obj), usb_dwc3_regs_info, > > + ARRAY_SIZE(usb_dwc3_regs_info), > > + s->regs_info, s->regs, > > + &usb_dwc3_ops, > > + USB_DWC3_ERR_DEBUG, > > + USB_DWC3_R_MAX * 4); > > + memory_region_add_subregion(&s->iomem, > > + 0x0, > > + ®_array->mem); > > + sysbus_init_mmio(sbd, &s->iomem); > > + object_initialize_child(obj, "dwc3-xhci", &s->sysbus_xhci, > > + TYPE_XHCI_SYSBUS); > > + qdev_alias_all_properties(DEVICE(&s->sysbus_xhci), obj); > > + > > + s->cfg.mode = HOST_MODE; > > +} > > + > > +static Property usb_dwc3_properties[] = { > > + DEFINE_PROP_UINT32("DWC_USB3_USERID", USBDWC3, cfg.dwc_usb3_user, > > + 0x12345678), > > + DEFINE_PROP_END_OF_LIST(), > > +}; > > + > > +static void usb_dwc3_class_init(ObjectClass *klass, void *data) > > +{ > > + DeviceClass *dc = DEVICE_CLASS(klass); > > + > > + dc->reset = usb_dwc3_reset; > > + dc->realize = usb_dwc3_realize; > > + device_class_set_props(dc, usb_dwc3_properties); > > +} > > + > > +static const TypeInfo usb_dwc3_info = { > > + .name = TYPE_USB_DWC3, > > + .parent = TYPE_SYS_BUS_DEVICE, > > + .instance_size = sizeof(USBDWC3), > > + .class_init = usb_dwc3_class_init, > > + .instance_init = usb_dwc3_init, > > +}; > > + > > +static void usb_dwc3_register_types(void) > > +{ > > + type_register_static(&usb_dwc3_info); > > +} > > + > > +type_init(usb_dwc3_register_types) > > diff --git a/hw/usb/meson.build b/hw/usb/meson.build > > index 934e4fa..962fbc0 100644 > > --- a/hw/usb/meson.build > > +++ b/hw/usb/meson.build > > @@ -26,6 +26,7 @@ softmmu_ss.add(when: 'CONFIG_USB_XHCI_SYSBUS', if_true: files('hcd-xhci-sysbus.c > > softmmu_ss.add(when: 'CONFIG_USB_XHCI_NEC', if_true: files('hcd-xhci-nec.c')) > > softmmu_ss.add(when: 'CONFIG_USB_MUSB', if_true: files('hcd-musb.c')) > > softmmu_ss.add(when: 'CONFIG_USB_DWC2', if_true: files('hcd-dwc2.c')) > > +softmmu_ss.add(when: 'CONFIG_USB_DWC3', if_true: files('hcd-dwc3.c')) > > > > softmmu_ss.add(when: 'CONFIG_TUSB6010', if_true: files('tusb6010.c')) > > softmmu_ss.add(when: 'CONFIG_IMX', if_true: files('chipidea.c')) > > diff --git a/include/hw/usb/hcd-dwc3.h b/include/hw/usb/hcd-dwc3.h > > new file mode 100644 > > index 0000000..586968d > > --- /dev/null > > +++ b/include/hw/usb/hcd-dwc3.h > > @@ -0,0 +1,55 @@ > > +/* > > + * QEMU model of the USB DWC3 host controller emulation. > > + * > > + * Copyright (c) 2020 Xilinx Inc. > > + * > > + * Written by Vikram Garhwal<fnu.vikram@xilinx.com> > > + * > > + * Permission is hereby granted, free of charge, to any person obtaining a copy > > + * of this software and associated documentation files (the "Software"), to deal > > + * in the Software without restriction, including without limitation the rights > > + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell > > + * copies of the Software, and to permit persons to whom the Software is > > + * furnished to do so, subject to the following conditions: > > + * > > + * The above copyright notice and this permission notice shall be included in > > + * all copies or substantial portions of the Software. > > + * > > + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR > > + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, > > + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL > > + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER > > + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, > > + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN > > + * THE SOFTWARE. > > + */ > > +#ifndef HCD_DWC3_H > > +#define HCD_DWC3_H > > + > > +#include "hw/usb/hcd-xhci.h" > > +#include "hw/usb/hcd-xhci-sysbus.h" > > + > > +#define TYPE_USB_DWC3 "usb_dwc3" > > + > > +#define USB_DWC3(obj) \ > > + OBJECT_CHECK(USBDWC3, (obj), TYPE_USB_DWC3) > > + > > +#define USB_DWC3_R_MAX ((0x530 / 4) + 1) > > + > > +typedef struct USBDWC3 { > > + SysBusDevice parent_obj; > > + MemoryRegion iomem; > > + MemoryRegion fifos; > > + XHCISysbusState sysbus_xhci; > > + > > + uint32_t regs[USB_DWC3_R_MAX]; > > + RegisterInfo regs_info[USB_DWC3_R_MAX]; > > + > > + struct { > > + uint8_t mode; > > + uint32_t dwc_usb3_user; > > + } cfg; > > + > > +} USBDWC3; > > + > > +#endif > > -- > > 2.7.4 > >
Hi Edgar, Sorry for late followup, few comment inline below. > -----Original Message----- > From: Edgar E. Iglesias <edgar.iglesias@xilinx.com> > Sent: Tuesday, September 29, 2020 7:56 PM > To: Sai Pavan Boddu <saipava@xilinx.com> > Cc: Peter Maydell <peter.maydell@linaro.org>; Markus Armbruster > <armbru@redhat.com>; 'Marc-André Lureau' > <marcandre.lureau@redhat.com>; Paolo Bonzini <pbonzini@redhat.com>; > Gerd Hoffmann <kraxel@redhat.com>; Edgar Iglesias <edgari@xilinx.com>; > Francisco Eduardo Iglesias <figlesia@xilinx.com>; qemu-devel@nongnu.org; > Alistair Francis <alistair.francis@wdc.com>; Eduardo Habkost > <ehabkost@redhat.com>; Ying Fang <fangying1@huawei.com>; 'Philippe > Mathieu-Daudé' <philmd@redhat.com>; Vikram Garhwal <fnuv@xilinx.com>; > Paul Zimmerman <pauldzim@gmail.com>; Sai Pavan Boddu > <saipava@xilinx.com> > Subject: Re: [PATCH v11 2/3] usb: Add DWC3 model > > On Tue, Sep 29, 2020 at 04:25:41PM +0530, Sai Pavan Boddu wrote: > > From: Vikram Garhwal <fnu.vikram@xilinx.com> > > > > This patch adds skeleton model of dwc3 usb controller attached to > > xhci-sysbus device. It defines global register space of DWC3 > > controller, global registers control the AXI/AHB interfaces > > properties, external FIFO support and event count support. All of > > which are unimplemented at present,we are only supporting core reset and > read of ID register. > > > > Signed-off-by: Vikram Garhwal <fnu.vikram@xilinx.com> > > Signed-off-by: Sai Pavan Boddu <sai.pavan.boddu@xilinx.com> > > --- > > hw/usb/Kconfig | 6 + > > hw/usb/hcd-dwc3.c | 717 > ++++++++++++++++++++++++++++++++++++++++++++++ > > hw/usb/meson.build | 1 + > > include/hw/usb/hcd-dwc3.h | 55 ++++ > > 4 files changed, 779 insertions(+) > > create mode 100644 hw/usb/hcd-dwc3.c > > create mode 100644 include/hw/usb/hcd-dwc3.h > > > > diff --git a/hw/usb/Kconfig b/hw/usb/Kconfig index 4dd2ba9..f5762f0 > > 100644 > > --- a/hw/usb/Kconfig > > +++ b/hw/usb/Kconfig > > @@ -116,3 +116,9 @@ config IMX_USBPHY > > bool > > default y > > depends on USB > > + > > +config USB_DWC3 > > + bool > > + default y if USB_XHCI_SYSBUS > > + select USB > > + select REGISTER > > diff --git a/hw/usb/hcd-dwc3.c b/hw/usb/hcd-dwc3.c new file mode > > 100644 index 0000000..de8be7a > > --- /dev/null > > +++ b/hw/usb/hcd-dwc3.c > > @@ -0,0 +1,717 @@ > > +/* > > + * QEMU model of the USB DWC3 host controller emulation. > > + * > > + * This model defines global register space of DWC3 controller. > > +Global > > + * registers control the AXI/AHB interfaces properties, external FIFO > > +support > > + * and event count support. All of which are unimplemented at > > +present. We are > > + * only supporting core reset and read of ID register. > > + * > > + * Copyright (c) 2020 Xilinx Inc. Vikram > > +Garhwal<fnu.vikram@xilinx.com> > > + * > > + * Permission is hereby granted, free of charge, to any person > > +obtaining a copy > > + * of this software and associated documentation files (the > > +"Software"), to deal > > + * in the Software without restriction, including without limitation > > +the rights > > + * to use, copy, modify, merge, publish, distribute, sublicense, > > +and/or sell > > + * copies of the Software, and to permit persons to whom the Software > > +is > > + * furnished to do so, subject to the following conditions: > > + * > > + * The above copyright notice and this permission notice shall be > > +included in > > + * all copies or substantial portions of the Software. > > + * > > + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, > > +EXPRESS OR > > + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF > > +MERCHANTABILITY, > > + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO > EVENT > > +SHALL > > + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, > DAMAGES > > +OR OTHER > > + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, > > +ARISING FROM, > > + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER > > +DEALINGS IN > > + * THE SOFTWARE. > > + */ > > + > > +#include "qemu/osdep.h" > > +#include "hw/sysbus.h" > > +#include "hw/register.h" > > +#include "qemu/bitops.h" > > +#include "qemu/log.h" > > +#include "qom/object.h" > > +#include "migration/vmstate.h" > > +#include "hw/qdev-properties.h" > > +#include "hw/usb/hcd-dwc3.h" > > +#include "qapi/error.h" > > + > > +#ifndef USB_DWC3_ERR_DEBUG > > +#define USB_DWC3_ERR_DEBUG 0 > > +#endif > > + > > +#define HOST_MODE 1 > > +#define FIFO_LEN 0x1000 > > + > > +REG32(GSBUSCFG0, 0x00) > > + FIELD(GSBUSCFG0, DATRDREQINFO, 28, 4) > > + FIELD(GSBUSCFG0, DESRDREQINFO, 24, 4) > > + FIELD(GSBUSCFG0, DATWRREQINFO, 20, 4) > > + FIELD(GSBUSCFG0, DESWRREQINFO, 16, 4) > > + FIELD(GSBUSCFG0, RESERVED_15_12, 12, 4) > > + FIELD(GSBUSCFG0, DATBIGEND, 11, 1) > > + FIELD(GSBUSCFG0, DESBIGEND, 10, 1) > > + FIELD(GSBUSCFG0, RESERVED_9_8, 8, 2) > > + FIELD(GSBUSCFG0, INCR256BRSTENA, 7, 1) > > + FIELD(GSBUSCFG0, INCR128BRSTENA, 6, 1) > > + FIELD(GSBUSCFG0, INCR64BRSTENA, 5, 1) > > + FIELD(GSBUSCFG0, INCR32BRSTENA, 4, 1) > > + FIELD(GSBUSCFG0, INCR16BRSTENA, 3, 1) > > + FIELD(GSBUSCFG0, INCR8BRSTENA, 2, 1) > > + FIELD(GSBUSCFG0, INCR4BRSTENA, 1, 1) > > + FIELD(GSBUSCFG0, INCRBRSTENA, 0, 1) REG32(GSBUSCFG1, 0x04) > > + FIELD(GSBUSCFG1, RESERVED_31_13, 13, 19) > > + FIELD(GSBUSCFG1, EN1KPAGE, 12, 1) > > + FIELD(GSBUSCFG1, PIPETRANSLIMIT, 8, 4) > > + FIELD(GSBUSCFG1, RESERVED_7_0, 0, 8) REG32(GTXTHRCFG, 0x08) > > + FIELD(GTXTHRCFG, RESERVED_31, 31, 1) > > + FIELD(GTXTHRCFG, RESERVED_30, 30, 1) > > + FIELD(GTXTHRCFG, USBTXPKTCNTSEL, 29, 1) > > + FIELD(GTXTHRCFG, RESERVED_28, 28, 1) > > + FIELD(GTXTHRCFG, USBTXPKTCNT, 24, 4) > > + FIELD(GTXTHRCFG, USBMAXTXBURSTSIZE, 16, 8) > > + FIELD(GTXTHRCFG, RESERVED_15, 15, 1) > > + FIELD(GTXTHRCFG, RESERVED_14, 14, 1) > > + FIELD(GTXTHRCFG, RESERVED_13_11, 11, 3) > > + FIELD(GTXTHRCFG, RESERVED_10_0, 0, 11) REG32(GRXTHRCFG, 0x0c) > > + FIELD(GRXTHRCFG, RESERVED_31_30, 30, 2) > > + FIELD(GRXTHRCFG, USBRXPKTCNTSEL, 29, 1) > > + FIELD(GRXTHRCFG, RESERVED_28, 28, 1) > > + FIELD(GRXTHRCFG, USBRXPKTCNT, 24, 4) > > + FIELD(GRXTHRCFG, USBMAXRXBURSTSIZE, 19, 5) > > + FIELD(GRXTHRCFG, RESERVED_18_16, 16, 3) > > + FIELD(GRXTHRCFG, RESERVED_15, 15, 1) > > + FIELD(GRXTHRCFG, RESERVED_14_13, 13, 2) > > + FIELD(GRXTHRCFG, RESVISOCOUTSPC, 0, 13) REG32(GCTL, 0x10) > > + FIELD(GCTL, PWRDNSCALE, 19, 13) > > + FIELD(GCTL, MASTERFILTBYPASS, 18, 1) > > + FIELD(GCTL, BYPSSETADDR, 17, 1) > > + FIELD(GCTL, U2RSTECN, 16, 1) > > + FIELD(GCTL, FRMSCLDWN, 14, 2) > > + FIELD(GCTL, PRTCAPDIR, 12, 2) > > + FIELD(GCTL, CORESOFTRESET, 11, 1) > > + FIELD(GCTL, U1U2TIMERSCALE, 9, 1) > > + FIELD(GCTL, DEBUGATTACH, 8, 1) > > + FIELD(GCTL, RAMCLKSEL, 6, 2) > > + FIELD(GCTL, SCALEDOWN, 4, 2) > > + FIELD(GCTL, DISSCRAMBLE, 3, 1) > > + FIELD(GCTL, U2EXIT_LFPS, 2, 1) > > + FIELD(GCTL, GBLHIBERNATIONEN, 1, 1) > > + FIELD(GCTL, DSBLCLKGTNG, 0, 1) > > +REG32(GPMSTS, 0x14) > > +REG32(GSTS, 0x18) > > + FIELD(GSTS, CBELT, 20, 12) > > + FIELD(GSTS, RESERVED_19_12, 12, 8) > > + FIELD(GSTS, SSIC_IP, 11, 1) > > + FIELD(GSTS, OTG_IP, 10, 1) > > + FIELD(GSTS, BC_IP, 9, 1) > > + FIELD(GSTS, ADP_IP, 8, 1) > > + FIELD(GSTS, HOST_IP, 7, 1) > > + FIELD(GSTS, DEVICE_IP, 6, 1) > > + FIELD(GSTS, CSRTIMEOUT, 5, 1) > > + FIELD(GSTS, BUSERRADDRVLD, 4, 1) > > + FIELD(GSTS, RESERVED_3_2, 2, 2) > > + FIELD(GSTS, CURMOD, 0, 2) > > +REG32(GUCTL1, 0x1c) > > + FIELD(GUCTL1, RESUME_OPMODE_HS_HOST, 10, 1) REG32(GSNPSID, > 0x20) > > +REG32(GGPIO, 0x24) > > + FIELD(GGPIO, GPO, 16, 16) > > + FIELD(GGPIO, GPI, 0, 16) > > +REG32(GUID, 0x28) > > +REG32(GUCTL, 0x2c) > > + FIELD(GUCTL, REFCLKPER, 22, 10) > > + FIELD(GUCTL, NOEXTRDL, 21, 1) > > + FIELD(GUCTL, RESERVED_20_18, 18, 3) > > + FIELD(GUCTL, SPRSCTRLTRANSEN, 17, 1) > > + FIELD(GUCTL, RESBWHSEPS, 16, 1) > > + FIELD(GUCTL, RESERVED_15, 15, 1) > > + FIELD(GUCTL, USBHSTINAUTORETRYEN, 14, 1) > > + FIELD(GUCTL, ENOVERLAPCHK, 13, 1) > > + FIELD(GUCTL, EXTCAPSUPPTEN, 12, 1) > > + FIELD(GUCTL, INSRTEXTRFSBODI, 11, 1) > > + FIELD(GUCTL, DTCT, 9, 2) > > + FIELD(GUCTL, DTFT, 0, 9) > > +REG32(GBUSERRADDRLO, 0x30) > > +REG32(GBUSERRADDRHI, 0x34) > > +REG32(GHWPARAMS0, 0x40) > > + FIELD(GHWPARAMS0, GHWPARAMS0_31_24, 24, 8) > > + FIELD(GHWPARAMS0, GHWPARAMS0_23_16, 16, 8) > > + FIELD(GHWPARAMS0, GHWPARAMS0_15_8, 8, 8) > > + FIELD(GHWPARAMS0, GHWPARAMS0_7_6, 6, 2) > > + FIELD(GHWPARAMS0, GHWPARAMS0_5_3, 3, 3) > > + FIELD(GHWPARAMS0, GHWPARAMS0_2_0, 0, 3) REG32(GHWPARAMS1, > 0x44) > > + FIELD(GHWPARAMS1, GHWPARAMS1_31, 31, 1) > > + FIELD(GHWPARAMS1, GHWPARAMS1_30, 30, 1) > > + FIELD(GHWPARAMS1, GHWPARAMS1_29, 29, 1) > > + FIELD(GHWPARAMS1, GHWPARAMS1_28, 28, 1) > > + FIELD(GHWPARAMS1, GHWPARAMS1_27, 27, 1) > > + FIELD(GHWPARAMS1, GHWPARAMS1_26, 26, 1) > > + FIELD(GHWPARAMS1, GHWPARAMS1_25_24, 24, 2) > > + FIELD(GHWPARAMS1, GHWPARAMS1_23, 23, 1) > > + FIELD(GHWPARAMS1, GHWPARAMS1_22_21, 21, 2) > > + FIELD(GHWPARAMS1, GHWPARAMS1_20_15, 15, 6) > > + FIELD(GHWPARAMS1, GHWPARAMS1_14_12, 12, 3) > > + FIELD(GHWPARAMS1, GHWPARAMS1_11_9, 9, 3) > > + FIELD(GHWPARAMS1, GHWPARAMS1_8_6, 6, 3) > > + FIELD(GHWPARAMS1, GHWPARAMS1_5_3, 3, 3) > > + FIELD(GHWPARAMS1, GHWPARAMS1_2_0, 0, 3) REG32(GHWPARAMS2, > 0x48) > > +REG32(GHWPARAMS3, 0x4c) > > + FIELD(GHWPARAMS3, GHWPARAMS3_31, 31, 1) > > + FIELD(GHWPARAMS3, GHWPARAMS3_30_23, 23, 8) > > + FIELD(GHWPARAMS3, GHWPARAMS3_22_18, 18, 5) > > + FIELD(GHWPARAMS3, GHWPARAMS3_17_12, 12, 6) > > + FIELD(GHWPARAMS3, GHWPARAMS3_11, 11, 1) > > + FIELD(GHWPARAMS3, GHWPARAMS3_10, 10, 1) > > + FIELD(GHWPARAMS3, GHWPARAMS3_9_8, 8, 2) > > + FIELD(GHWPARAMS3, GHWPARAMS3_7_6, 6, 2) > > + FIELD(GHWPARAMS3, GHWPARAMS3_5_4, 4, 2) > > + FIELD(GHWPARAMS3, GHWPARAMS3_3_2, 2, 2) > > + FIELD(GHWPARAMS3, GHWPARAMS3_1_0, 0, 2) REG32(GHWPARAMS4, > 0x50) > > + FIELD(GHWPARAMS4, GHWPARAMS4_31_28, 28, 4) > > + FIELD(GHWPARAMS4, GHWPARAMS4_27_24, 24, 4) > > + FIELD(GHWPARAMS4, GHWPARAMS4_23, 23, 1) > > + FIELD(GHWPARAMS4, GHWPARAMS4_22, 22, 1) > > + FIELD(GHWPARAMS4, GHWPARAMS4_21, 21, 1) > > + FIELD(GHWPARAMS4, GHWPARAMS4_20_17, 17, 4) > > + FIELD(GHWPARAMS4, GHWPARAMS4_16_13, 13, 4) > > + FIELD(GHWPARAMS4, GHWPARAMS4_12, 12, 1) > > + FIELD(GHWPARAMS4, GHWPARAMS4_11, 11, 1) > > + FIELD(GHWPARAMS4, GHWPARAMS4_10_9, 9, 2) > > + FIELD(GHWPARAMS4, GHWPARAMS4_8_7, 7, 2) > > + FIELD(GHWPARAMS4, GHWPARAMS4_6, 6, 1) > > + FIELD(GHWPARAMS4, GHWPARAMS4_5_0, 0, 6) REG32(GHWPARAMS5, > 0x54) > > + FIELD(GHWPARAMS5, GHWPARAMS5_31_28, 28, 4) > > + FIELD(GHWPARAMS5, GHWPARAMS5_27_22, 22, 6) > > + FIELD(GHWPARAMS5, GHWPARAMS5_21_16, 16, 6) > > + FIELD(GHWPARAMS5, GHWPARAMS5_15_10, 10, 6) > > + FIELD(GHWPARAMS5, GHWPARAMS5_9_4, 4, 6) > > + FIELD(GHWPARAMS5, GHWPARAMS5_3_0, 0, 4) REG32(GHWPARAMS6, > 0x58) > > + FIELD(GHWPARAMS6, GHWPARAMS6_31_16, 16, 16) > > + FIELD(GHWPARAMS6, BUSFLTRSSUPPORT, 15, 1) > > + FIELD(GHWPARAMS6, BCSUPPORT, 14, 1) > > + FIELD(GHWPARAMS6, OTG_SS_SUPPORT, 13, 1) > > + FIELD(GHWPARAMS6, ADPSUPPORT, 12, 1) > > + FIELD(GHWPARAMS6, HNPSUPPORT, 11, 1) > > + FIELD(GHWPARAMS6, SRPSUPPORT, 10, 1) > > + FIELD(GHWPARAMS6, GHWPARAMS6_9_8, 8, 2) > > + FIELD(GHWPARAMS6, GHWPARAMS6_7, 7, 1) > > + FIELD(GHWPARAMS6, GHWPARAMS6_6, 6, 1) > > + FIELD(GHWPARAMS6, GHWPARAMS6_5_0, 0, 6) REG32(GHWPARAMS7, > 0x5c) > > + FIELD(GHWPARAMS7, GHWPARAMS7_31_16, 16, 16) > > + FIELD(GHWPARAMS7, GHWPARAMS7_15_0, 0, 16) > REG32(GDBGFIFOSPACE, > > +0x60) > > + FIELD(GDBGFIFOSPACE, SPACE_AVAILABLE, 16, 16) > > + FIELD(GDBGFIFOSPACE, RESERVED_15_9, 9, 7) > > + FIELD(GDBGFIFOSPACE, FIFO_QUEUE_SELECT, 0, 9) REG32(GUCTL2, 0x9c) > > + FIELD(GUCTL2, RESERVED_31_26, 26, 6) > > + FIELD(GUCTL2, EN_HP_PM_TIMER, 19, 7) > > + FIELD(GUCTL2, NOLOWPWRDUR, 15, 4) > > + FIELD(GUCTL2, RST_ACTBITLATER, 14, 1) > > + FIELD(GUCTL2, RESERVED_13, 13, 1) > > + FIELD(GUCTL2, DISABLECFC, 11, 1) > > +REG32(GUSB2PHYCFG, 0x100) > > + FIELD(GUSB2PHYCFG, U2_FREECLK_EXISTS, 30, 1) > > + FIELD(GUSB2PHYCFG, ULPI_LPM_WITH_OPMODE_CHK, 29, 1) > > + FIELD(GUSB2PHYCFG, RESERVED_25, 25, 1) > > + FIELD(GUSB2PHYCFG, LSTRD, 22, 3) > > + FIELD(GUSB2PHYCFG, LSIPD, 19, 3) > > + FIELD(GUSB2PHYCFG, ULPIEXTVBUSINDIACTOR, 18, 1) > > + FIELD(GUSB2PHYCFG, ULPIEXTVBUSDRV, 17, 1) > > + FIELD(GUSB2PHYCFG, RESERVED_16, 16, 1) > > + FIELD(GUSB2PHYCFG, ULPIAUTORES, 15, 1) > > + FIELD(GUSB2PHYCFG, RESERVED_14, 14, 1) > > + FIELD(GUSB2PHYCFG, USBTRDTIM, 10, 4) > > + FIELD(GUSB2PHYCFG, XCVRDLY, 9, 1) > > + FIELD(GUSB2PHYCFG, ENBLSLPM, 8, 1) > > + FIELD(GUSB2PHYCFG, PHYSEL, 7, 1) > > + FIELD(GUSB2PHYCFG, SUSPENDUSB20, 6, 1) > > + FIELD(GUSB2PHYCFG, FSINTF, 5, 1) > > + FIELD(GUSB2PHYCFG, ULPI_UTMI_SEL, 4, 1) > > + FIELD(GUSB2PHYCFG, PHYIF, 3, 1) > > + FIELD(GUSB2PHYCFG, TOUTCAL, 0, 3) REG32(GUSB2I2CCTL, 0x140) > > +REG32(GUSB2PHYACC_ULPI, 0x180) > > + FIELD(GUSB2PHYACC_ULPI, RESERVED_31_27, 27, 5) > > + FIELD(GUSB2PHYACC_ULPI, DISUIPIDRVR, 26, 1) > > + FIELD(GUSB2PHYACC_ULPI, NEWREGREQ, 25, 1) > > + FIELD(GUSB2PHYACC_ULPI, VSTSDONE, 24, 1) > > + FIELD(GUSB2PHYACC_ULPI, VSTSBSY, 23, 1) > > + FIELD(GUSB2PHYACC_ULPI, REGWR, 22, 1) > > + FIELD(GUSB2PHYACC_ULPI, REGADDR, 16, 6) > > + FIELD(GUSB2PHYACC_ULPI, EXTREGADDR, 8, 8) > > + FIELD(GUSB2PHYACC_ULPI, REGDATA, 0, 8) REG32(GTXFIFOSIZ0, 0x200) > > + FIELD(GTXFIFOSIZ0, TXFSTADDR_N, 16, 16) > > + FIELD(GTXFIFOSIZ0, TXFDEP_N, 0, 16) REG32(GTXFIFOSIZ1, 0x204) > > + FIELD(GTXFIFOSIZ1, TXFSTADDR_N, 16, 16) > > + FIELD(GTXFIFOSIZ1, TXFDEP_N, 0, 16) REG32(GTXFIFOSIZ2, 0x208) > > + FIELD(GTXFIFOSIZ2, TXFSTADDR_N, 16, 16) > > + FIELD(GTXFIFOSIZ2, TXFDEP_N, 0, 16) REG32(GTXFIFOSIZ3, 0x20c) > > + FIELD(GTXFIFOSIZ3, TXFSTADDR_N, 16, 16) > > + FIELD(GTXFIFOSIZ3, TXFDEP_N, 0, 16) REG32(GTXFIFOSIZ4, 0x210) > > + FIELD(GTXFIFOSIZ4, TXFSTADDR_N, 16, 16) > > + FIELD(GTXFIFOSIZ4, TXFDEP_N, 0, 16) REG32(GTXFIFOSIZ5, 0x214) > > + FIELD(GTXFIFOSIZ5, TXFSTADDR_N, 16, 16) > > + FIELD(GTXFIFOSIZ5, TXFDEP_N, 0, 16) REG32(GRXFIFOSIZ0, 0x280) > > + FIELD(GRXFIFOSIZ0, RXFSTADDR_N, 16, 16) > > + FIELD(GRXFIFOSIZ0, RXFDEP_N, 0, 16) REG32(GRXFIFOSIZ1, 0x284) > > + FIELD(GRXFIFOSIZ1, RXFSTADDR_N, 16, 16) > > + FIELD(GRXFIFOSIZ1, RXFDEP_N, 0, 16) REG32(GRXFIFOSIZ2, 0x288) > > + FIELD(GRXFIFOSIZ2, RXFSTADDR_N, 16, 16) > > + FIELD(GRXFIFOSIZ2, RXFDEP_N, 0, 16) REG32(GEVNTADRLO_0, 0x300) > > +REG32(GEVNTADRHI_0, 0x304) REG32(GEVNTSIZ_0, 0x308) > > + FIELD(GEVNTSIZ_0, EVNTINTRPTMASK, 31, 1) > > + FIELD(GEVNTSIZ_0, RESERVED_30_16, 16, 15) > > + FIELD(GEVNTSIZ_0, EVENTSIZ, 0, 16) REG32(GEVNTCOUNT_0, 0x30c) > > + FIELD(GEVNTCOUNT_0, EVNT_HANDLER_BUSY, 31, 1) > > + FIELD(GEVNTCOUNT_0, RESERVED_30_16, 16, 15) > > + FIELD(GEVNTCOUNT_0, EVNTCOUNT, 0, 16) REG32(GEVNTADRLO_1, > 0x310) > > +REG32(GEVNTADRHI_1, 0x314) REG32(GEVNTSIZ_1, 0x318) > > + FIELD(GEVNTSIZ_1, EVNTINTRPTMASK, 31, 1) > > + FIELD(GEVNTSIZ_1, RESERVED_30_16, 16, 15) > > + FIELD(GEVNTSIZ_1, EVENTSIZ, 0, 16) REG32(GEVNTCOUNT_1, 0x31c) > > + FIELD(GEVNTCOUNT_1, EVNT_HANDLER_BUSY, 31, 1) > > + FIELD(GEVNTCOUNT_1, RESERVED_30_16, 16, 15) > > + FIELD(GEVNTCOUNT_1, EVNTCOUNT, 0, 16) REG32(GEVNTADRLO_2, > 0x320) > > +REG32(GEVNTADRHI_2, 0x324) REG32(GEVNTSIZ_2, 0x328) > > + FIELD(GEVNTSIZ_2, EVNTINTRPTMASK, 31, 1) > > + FIELD(GEVNTSIZ_2, RESERVED_30_16, 16, 15) > > + FIELD(GEVNTSIZ_2, EVENTSIZ, 0, 16) REG32(GEVNTCOUNT_2, 0x32c) > > + FIELD(GEVNTCOUNT_2, EVNT_HANDLER_BUSY, 31, 1) > > + FIELD(GEVNTCOUNT_2, RESERVED_30_16, 16, 15) > > + FIELD(GEVNTCOUNT_2, EVNTCOUNT, 0, 16) REG32(GEVNTADRLO_3, > 0x330) > > +REG32(GEVNTADRHI_3, 0x334) REG32(GEVNTSIZ_3, 0x338) > > + FIELD(GEVNTSIZ_3, EVNTINTRPTMASK, 31, 1) > > + FIELD(GEVNTSIZ_3, RESERVED_30_16, 16, 15) > > + FIELD(GEVNTSIZ_3, EVENTSIZ, 0, 16) REG32(GEVNTCOUNT_3, 0x33c) > > + FIELD(GEVNTCOUNT_3, EVNT_HANDLER_BUSY, 31, 1) > > + FIELD(GEVNTCOUNT_3, RESERVED_30_16, 16, 15) > > + FIELD(GEVNTCOUNT_3, EVNTCOUNT, 0, 16) REG32(GHWPARAMS8, > 0x500) > > +REG32(GTXFIFOPRIDEV, 0x510) > > + FIELD(GTXFIFOPRIDEV, RESERVED_31_N, 6, 26) > > + FIELD(GTXFIFOPRIDEV, GTXFIFOPRIDEV, 0, 6) REG32(GTXFIFOPRIHST, > > +0x518) > > + FIELD(GTXFIFOPRIHST, RESERVED_31_16, 3, 29) > > + FIELD(GTXFIFOPRIHST, GTXFIFOPRIHST, 0, 3) REG32(GRXFIFOPRIHST, > > +0x51c) > > + FIELD(GRXFIFOPRIHST, RESERVED_31_16, 3, 29) > > + FIELD(GRXFIFOPRIHST, GRXFIFOPRIHST, 0, 3) REG32(GDMAHLRATIO, > > +0x524) > > + FIELD(GDMAHLRATIO, RESERVED_31_13, 13, 19) > > + FIELD(GDMAHLRATIO, HSTRXFIFO, 8, 5) > > + FIELD(GDMAHLRATIO, RESERVED_7_5, 5, 3) > > + FIELD(GDMAHLRATIO, HSTTXFIFO, 0, 5) REG32(GFLADJ, 0x530) > > + FIELD(GFLADJ, GFLADJ_REFCLK_240MHZDECR_PLS1, 31, 1) > > + FIELD(GFLADJ, GFLADJ_REFCLK_240MHZ_DECR, 24, 7) > > + FIELD(GFLADJ, GFLADJ_REFCLK_LPM_SEL, 23, 1) > > + FIELD(GFLADJ, RESERVED_22, 22, 1) > > + FIELD(GFLADJ, GFLADJ_REFCLK_FLADJ, 8, 14) > > + FIELD(GFLADJ, GFLADJ_30MHZ_SDBND_SEL, 7, 1) > > + FIELD(GFLADJ, GFLADJ_30MHZ, 0, 6) > > + > > +static void reset_csr(USBDWC3 * s) > > +{ > > + int i = 0; > > + /* > > + * We reset all CSR regs except GCTL, GUCTL, GSTS, GSNPSID, GGPIO, > GUID, > > + * GUSB2PHYCFGn registers and GUSB3PIPECTLn registers. We will skip > PHY > > + * register as we don't implement them. > > + */ > > + for (i = 0; i < R_GCTL; i++) { > > + register_reset(&s->regs_info[i]); > > + } > > + > > + for (i = R_GCTL; i < R_GBUSERRADDRLO; i++) { > > + if (i == R_GUCTL1 || i == R_GPMSTS) { > > + register_reset(&s->regs_info[i]); > > + } else { > > + continue; > > + } > > + } > > + > > + for (i = R_GBUSERRADDRLO; i < USB_DWC3_R_MAX; i++) { > > + register_reset(&s->regs_info[i]); > > + } > > Can we instead iterate through them all and have a list with the ones that wont > be reset? It'll be easier to understand the code and match it with the regs that > shouldn't reset. > e.g: > > for (i = 0; i < USB_DWC3_R_MAX; i++) { > switch (i) { > case R_GCTL: > case XXX: > /* Should not reset. */ > break; > default: > register_reset(&s->regs_info[i]); > break; > } > } > > > + > > + xhci_sysbus_reset(DEVICE(&s->sysbus_xhci)); > > +} > > + > > +static void usb_dwc3_gctl_postw(RegisterInfo *reg, uint64_t val64) { > > + USBDWC3 *s = USB_DWC3(reg->opaque); > > + > > + if (ARRAY_FIELD_EX32(s->regs, GCTL, CORESOFTRESET)) { > > + reset_csr(s); > > + } > > +} > > + > > +static void usb_dwc3_guid_postw(RegisterInfo *reg, uint64_t val64) { > > + USBDWC3 *s = USB_DWC3(reg->opaque); > > + > > + s->regs[R_GUID] = s->cfg.dwc_usb3_user; } > > This looks strange. Is this register really writeable on real HW? > Looks lite a read-only register that should get it's value from the property... [Sai Pavan Boddu] this seems to a r/w register itself. > > > > + > > +static void usb_dwc3_unimpl_postw(RegisterInfo *reg, uint64_t val64) > > +{ > > + qemu_log_mask(LOG_UNIMP, "%s not supported\n", > > +reg->access->name); } > > + > > +static uint64_t usb_dwc3_unimpl_postr(RegisterInfo *reg, uint64_t > > +val64) { > > + qemu_log_mask(LOG_UNIMP, "%s not supported\n", reg->access- > >name); > > + return val64; > > +} > > We should probably use the regapi .unimp instead of these functions. > > > + > > +static const RegisterAccessInfo usb_dwc3_regs_info[] = { > > + { .name = "GSBUSCFG0", .addr = A_GSBUSCFG0, > > + .ro = 0xf300, > > + .post_read = usb_dwc3_unimpl_postr, > > + .post_write = usb_dwc3_unimpl_postw, > > + },{ .name = "GSBUSCFG1", .addr = A_GSBUSCFG1, > > + .reset = 0x300, > > + .ro = 0xffffe0ff, > > + .post_read = usb_dwc3_unimpl_postr, > > + .post_write = usb_dwc3_unimpl_postw, > > + },{ .name = "GTXTHRCFG", .addr = A_GTXTHRCFG, > > + .ro = 0xd000ffff, > > + .post_read = usb_dwc3_unimpl_postr, > > + .post_write = usb_dwc3_unimpl_postw, > > + },{ .name = "GRXTHRCFG", .addr = A_GRXTHRCFG, > > + .ro = 0xd007e000, > > + .post_read = usb_dwc3_unimpl_postr, > > + .post_write = usb_dwc3_unimpl_postw, > > + },{ .name = "GCTL", .addr = A_GCTL, > > + .reset = 0x30c13004, .post_write = usb_dwc3_gctl_postw, > > + },{ .name = "GPMSTS", .addr = A_GPMSTS, > > + .ro = 0xfffffff, > > + .post_read = usb_dwc3_unimpl_postr, > > + .post_write = usb_dwc3_unimpl_postw, > > + },{ .name = "GSTS", .addr = A_GSTS, > > + .reset = 0x7e800000, > > + .ro = 0xffffffcf, > > + .w1c = 0x30, > > + .post_read = usb_dwc3_unimpl_postr, > > + .post_write = usb_dwc3_unimpl_postw, > > + },{ .name = "GUCTL1", .addr = A_GUCTL1, > > + .reset = 0x198a, > > + .ro = 0x7800, > > + .post_read = usb_dwc3_unimpl_postr, > > + .post_write = usb_dwc3_unimpl_postw, > > + },{ .name = "GSNPSID", .addr = A_GSNPSID, > > + .reset = 0x5533330a, > > + .ro = 0xffffffff, > > + },{ .name = "GGPIO", .addr = A_GGPIO, > > + .ro = 0xffff, > > + .post_read = usb_dwc3_unimpl_postr, > > + .post_write = usb_dwc3_unimpl_postw, > > + },{ .name = "GUID", .addr = A_GUID, > > + .reset = 0x12345678, .post_write = usb_dwc3_guid_postw, > > + },{ .name = "GUCTL", .addr = A_GUCTL, > > + .reset = 0x0c808010, > > + .ro = 0x1c8000, > > + .post_read = usb_dwc3_unimpl_postr, > > + .post_write = usb_dwc3_unimpl_postw, > > + },{ .name = "GBUSERRADDRLO", .addr = A_GBUSERRADDRLO, > > + .ro = 0xffffffff, > > + .post_read = usb_dwc3_unimpl_postr, > > + },{ .name = "GBUSERRADDRHI", .addr = A_GBUSERRADDRHI, > > + .ro = 0xffffffff, > > + .post_read = usb_dwc3_unimpl_postr, > > + },{ .name = "GHWPARAMS0", .addr = A_GHWPARAMS0, > > + .ro = 0xffffffff, > > + },{ .name = "GHWPARAMS1", .addr = A_GHWPARAMS1, > > + .ro = 0xffffffff, > > + },{ .name = "GHWPARAMS2", .addr = A_GHWPARAMS2, > > + .ro = 0xffffffff, > > + },{ .name = "GHWPARAMS3", .addr = A_GHWPARAMS3, > > + .ro = 0xffffffff, > > + },{ .name = "GHWPARAMS4", .addr = A_GHWPARAMS4, > > + .ro = 0xffffffff, > > + },{ .name = "GHWPARAMS5", .addr = A_GHWPARAMS5, > > + .ro = 0xffffffff, > > + },{ .name = "GHWPARAMS6", .addr = A_GHWPARAMS6, > > + .ro = 0xffffffff, > > + },{ .name = "GHWPARAMS7", .addr = A_GHWPARAMS7, > > + .ro = 0xffffffff, > > + },{ .name = "GDBGFIFOSPACE", .addr = A_GDBGFIFOSPACE, > > + .reset = 0xa0000, > > + .ro = 0xfffffe00, > > + .post_read = usb_dwc3_unimpl_postr, > > + .post_write = usb_dwc3_unimpl_postw, > > + },{ .name = "GUCTL2", .addr = A_GUCTL2, > > + .reset = 0x40d, > > + .ro = 0x2000, > > + .post_read = usb_dwc3_unimpl_postr, > > + .post_write = usb_dwc3_unimpl_postw, > > + },{ .name = "GUSB2PHYCFG", .addr = A_GUSB2PHYCFG, > > + .reset = 0x40102410, > > + .ro = 0x1e014030, > > + .post_read = usb_dwc3_unimpl_postr, > > + .post_write = usb_dwc3_unimpl_postw, > > + },{ .name = "GUSB2I2CCTL", .addr = A_GUSB2I2CCTL, > > + .ro = 0xffffffff, > > + .post_read = usb_dwc3_unimpl_postr, > > + .post_write = usb_dwc3_unimpl_postw, > > + },{ .name = "GUSB2PHYACC_ULPI", .addr = A_GUSB2PHYACC_ULPI, > > + .ro = 0xfd000000, > > + .post_read = usb_dwc3_unimpl_postr, > > + .post_write = usb_dwc3_unimpl_postw, > > + },{ .name = "GTXFIFOSIZ0", .addr = A_GTXFIFOSIZ0, > > + .reset = 0x2c7000a, > > + .post_read = usb_dwc3_unimpl_postr, > > + .post_write = usb_dwc3_unimpl_postw, > > + },{ .name = "GTXFIFOSIZ1", .addr = A_GTXFIFOSIZ1, > > + .reset = 0x2d10103, > > + .post_read = usb_dwc3_unimpl_postr, > > + .post_write = usb_dwc3_unimpl_postw, > > + },{ .name = "GTXFIFOSIZ2", .addr = A_GTXFIFOSIZ2, > > + .reset = 0x3d40103, > > + .post_read = usb_dwc3_unimpl_postr, > > + .post_write = usb_dwc3_unimpl_postw, > > + },{ .name = "GTXFIFOSIZ3", .addr = A_GTXFIFOSIZ3, > > + .reset = 0x4d70083, > > + .post_read = usb_dwc3_unimpl_postr, > > + .post_write = usb_dwc3_unimpl_postw, > > + },{ .name = "GTXFIFOSIZ4", .addr = A_GTXFIFOSIZ4, > > + .reset = 0x55a0083, > > + .post_read = usb_dwc3_unimpl_postr, > > + .post_write = usb_dwc3_unimpl_postw, > > + },{ .name = "GTXFIFOSIZ5", .addr = A_GTXFIFOSIZ5, > > + .reset = 0x5dd0083, > > + .post_read = usb_dwc3_unimpl_postr, > > + .post_write = usb_dwc3_unimpl_postw, > > + },{ .name = "GRXFIFOSIZ0", .addr = A_GRXFIFOSIZ0, > > + .reset = 0x1c20105, > > + .post_read = usb_dwc3_unimpl_postr, > > + .post_write = usb_dwc3_unimpl_postw, > > + },{ .name = "GRXFIFOSIZ1", .addr = A_GRXFIFOSIZ1, > > + .reset = 0x2c70000, > > + .post_read = usb_dwc3_unimpl_postr, > > + .post_write = usb_dwc3_unimpl_postw, > > + },{ .name = "GRXFIFOSIZ2", .addr = A_GRXFIFOSIZ2, > > + .reset = 0x2c70000, > > + .post_read = usb_dwc3_unimpl_postr, > > + .post_write = usb_dwc3_unimpl_postw, > > + },{ .name = "GEVNTADRLO_0", .addr = A_GEVNTADRLO_0, > > + .post_read = usb_dwc3_unimpl_postr, > > + .post_write = usb_dwc3_unimpl_postw, > > + },{ .name = "GEVNTADRHI_0", .addr = A_GEVNTADRHI_0, > > + .post_read = usb_dwc3_unimpl_postr, > > + .post_write = usb_dwc3_unimpl_postw, > > + },{ .name = "GEVNTSIZ_0", .addr = A_GEVNTSIZ_0, > > + .ro = 0x7fff0000, > > + .post_read = usb_dwc3_unimpl_postr, > > + .post_write = usb_dwc3_unimpl_postw, > > + },{ .name = "GEVNTCOUNT_0", .addr = A_GEVNTCOUNT_0, > > + .ro = 0x7fff0000, > > + .post_read = usb_dwc3_unimpl_postr, > > + .post_write = usb_dwc3_unimpl_postw, > > + },{ .name = "GEVNTADRLO_1", .addr = A_GEVNTADRLO_1, > > + .post_read = usb_dwc3_unimpl_postr, > > + .post_write = usb_dwc3_unimpl_postw, > > + },{ .name = "GEVNTADRHI_1", .addr = A_GEVNTADRHI_1, > > + .post_read = usb_dwc3_unimpl_postr, > > + .post_write = usb_dwc3_unimpl_postw, > > + },{ .name = "GEVNTSIZ_1", .addr = A_GEVNTSIZ_1, > > + .ro = 0x7fff0000, > > + .post_read = usb_dwc3_unimpl_postr, > > + .post_write = usb_dwc3_unimpl_postw, > > + },{ .name = "GEVNTCOUNT_1", .addr = A_GEVNTCOUNT_1, > > + .ro = 0x7fff0000, > > + .post_read = usb_dwc3_unimpl_postr, > > + .post_write = usb_dwc3_unimpl_postw, > > + },{ .name = "GEVNTADRLO_2", .addr = A_GEVNTADRLO_2, > > + .post_read = usb_dwc3_unimpl_postr, > > + .post_write = usb_dwc3_unimpl_postw, > > + },{ .name = "GEVNTADRHI_2", .addr = A_GEVNTADRHI_2, > > + .post_read = usb_dwc3_unimpl_postr, > > + .post_write = usb_dwc3_unimpl_postw, > > + },{ .name = "GEVNTSIZ_2", .addr = A_GEVNTSIZ_2, > > + .ro = 0x7fff0000, > > + .post_read = usb_dwc3_unimpl_postr, > > + .post_write = usb_dwc3_unimpl_postw, > > + },{ .name = "GEVNTCOUNT_2", .addr = A_GEVNTCOUNT_2, > > + .ro = 0x7fff0000, > > + .post_read = usb_dwc3_unimpl_postr, > > + .post_write = usb_dwc3_unimpl_postw, > > + },{ .name = "GEVNTADRLO_3", .addr = A_GEVNTADRLO_3, > > + .post_read = usb_dwc3_unimpl_postr, > > + .post_write = usb_dwc3_unimpl_postw, > > + },{ .name = "GEVNTADRHI_3", .addr = A_GEVNTADRHI_3, > > + .post_read = usb_dwc3_unimpl_postr, > > + .post_write = usb_dwc3_unimpl_postw, > > + },{ .name = "GEVNTSIZ_3", .addr = A_GEVNTSIZ_3, > > + .ro = 0x7fff0000, > > + .post_read = usb_dwc3_unimpl_postr, > > + .post_write = usb_dwc3_unimpl_postw, > > + },{ .name = "GEVNTCOUNT_3", .addr = A_GEVNTCOUNT_3, > > + .ro = 0x7fff0000, > > + .post_read = usb_dwc3_unimpl_postr, > > + .post_write = usb_dwc3_unimpl_postw, > > + },{ .name = "GHWPARAMS8", .addr = A_GHWPARAMS8, > > + .ro = 0xffffffff, > > + .post_read = usb_dwc3_unimpl_postr, > > + .post_write = usb_dwc3_unimpl_postw, > > + },{ .name = "GTXFIFOPRIDEV", .addr = A_GTXFIFOPRIDEV, > > + .ro = 0xffffffc0, > > + .post_read = usb_dwc3_unimpl_postr, > > + .post_write = usb_dwc3_unimpl_postw, > > + },{ .name = "GTXFIFOPRIHST", .addr = A_GTXFIFOPRIHST, > > + .ro = 0xfffffff8, > > + .post_read = usb_dwc3_unimpl_postr, > > + .post_write = usb_dwc3_unimpl_postw, > > + },{ .name = "GRXFIFOPRIHST", .addr = A_GRXFIFOPRIHST, > > + .ro = 0xfffffff8, > > + .post_read = usb_dwc3_unimpl_postr, > > + .post_write = usb_dwc3_unimpl_postw, > > + },{ .name = "GDMAHLRATIO", .addr = A_GDMAHLRATIO, > > + .ro = 0xffffe0e0, > > + .post_read = usb_dwc3_unimpl_postr, > > + .post_write = usb_dwc3_unimpl_postw, > > + },{ .name = "GFLADJ", .addr = A_GFLADJ, > > + .reset = 0xc83f020, > > + .rsvd = 0x40, > > + .ro = 0x400040, > > + .post_read = usb_dwc3_unimpl_postr, > > + .post_write = usb_dwc3_unimpl_postw, > > + } > > +}; > > + > > +static void usb_dwc3_reset(DeviceState *dev) { > > + USBDWC3 *s = USB_DWC3(dev); > > + unsigned int i; > > + > > + for (i = 0; i < ARRAY_SIZE(s->regs_info); ++i) { > > + register_reset(&s->regs_info[i]); > > + } > > + > > + /* > > + * Device Configuration > > + */ > > + s->regs[R_GHWPARAMS0] = 0x40204048 | s->cfg.mode; > > + s->regs[R_GHWPARAMS1] = 0x222493b; > > + s->regs[R_GHWPARAMS2] = 0x12345678; > > + s->regs[R_GHWPARAMS3] = 0x618c088; > > + s->regs[R_GHWPARAMS4] = 0x47822004; > > + s->regs[R_GHWPARAMS5] = 0x4202088; > > + s->regs[R_GHWPARAMS6] = 0x7850c20; > > + s->regs[R_GHWPARAMS7] = 0x0; > > + s->regs[R_GHWPARAMS8] = 0x478; > > Shouldn't these be setup in realize()? [Sai Pavan Boddu] Yes, in that case these also needs to be skipped from reset. I would send V12 addressing all comments above. Regard, Sai Pavan > > > + > > + xhci_sysbus_reset(DEVICE(&s->sysbus_xhci)); > > +} > > + > > +static const MemoryRegionOps usb_dwc3_ops = { > > + .read = register_read_memory, > > + .write = register_write_memory, > > + .endianness = DEVICE_LITTLE_ENDIAN, > > + .valid = { > > + .min_access_size = 4, > > + .max_access_size = 4, > > + }, > > +}; > > + > > +static void usb_dwc3_realize(DeviceState *dev, Error **errp) { > > + USBDWC3 *s = USB_DWC3(dev); > > + Error *err = NULL; > > + > > + sysbus_realize(SYS_BUS_DEVICE(&s->sysbus_xhci), &err); > > + if (err) { > > + error_propagate(errp, err); > > + return; > > + } > > +} > > + > > +static void usb_dwc3_init(Object *obj) { > > + USBDWC3 *s = USB_DWC3(obj); > > + SysBusDevice *sbd = SYS_BUS_DEVICE(obj); > > + RegisterInfoArray *reg_array; > > + > > + memory_region_init(&s->iomem, obj, TYPE_USB_DWC3, > USB_DWC3_R_MAX * 4); > > + reg_array = > > + register_init_block32(DEVICE(obj), usb_dwc3_regs_info, > > + ARRAY_SIZE(usb_dwc3_regs_info), > > + s->regs_info, s->regs, > > + &usb_dwc3_ops, > > + USB_DWC3_ERR_DEBUG, > > + USB_DWC3_R_MAX * 4); > > + memory_region_add_subregion(&s->iomem, > > + 0x0, > > + ®_array->mem); > > + sysbus_init_mmio(sbd, &s->iomem); > > + object_initialize_child(obj, "dwc3-xhci", &s->sysbus_xhci, > > + TYPE_XHCI_SYSBUS); > > + qdev_alias_all_properties(DEVICE(&s->sysbus_xhci), obj); > > + > > + s->cfg.mode = HOST_MODE; > > +} > > + > > +static Property usb_dwc3_properties[] = { > > + DEFINE_PROP_UINT32("DWC_USB3_USERID", USBDWC3, > cfg.dwc_usb3_user, > > + 0x12345678), > > + DEFINE_PROP_END_OF_LIST(), > > +}; > > + > > +static void usb_dwc3_class_init(ObjectClass *klass, void *data) { > > + DeviceClass *dc = DEVICE_CLASS(klass); > > + > > + dc->reset = usb_dwc3_reset; > > + dc->realize = usb_dwc3_realize; > > + device_class_set_props(dc, usb_dwc3_properties); } > > + > > +static const TypeInfo usb_dwc3_info = { > > + .name = TYPE_USB_DWC3, > > + .parent = TYPE_SYS_BUS_DEVICE, > > + .instance_size = sizeof(USBDWC3), > > + .class_init = usb_dwc3_class_init, > > + .instance_init = usb_dwc3_init, > > +}; > > + > > +static void usb_dwc3_register_types(void) { > > + type_register_static(&usb_dwc3_info); > > +} > > + > > +type_init(usb_dwc3_register_types) > > diff --git a/hw/usb/meson.build b/hw/usb/meson.build index > > 934e4fa..962fbc0 100644 > > --- a/hw/usb/meson.build > > +++ b/hw/usb/meson.build > > @@ -26,6 +26,7 @@ softmmu_ss.add(when: 'CONFIG_USB_XHCI_SYSBUS', > > if_true: files('hcd-xhci-sysbus.c > > softmmu_ss.add(when: 'CONFIG_USB_XHCI_NEC', if_true: > > files('hcd-xhci-nec.c')) > > softmmu_ss.add(when: 'CONFIG_USB_MUSB', if_true: files('hcd-musb.c')) > > softmmu_ss.add(when: 'CONFIG_USB_DWC2', if_true: files('hcd-dwc2.c')) > > +softmmu_ss.add(when: 'CONFIG_USB_DWC3', if_true: files('hcd-dwc3.c')) > > > > softmmu_ss.add(when: 'CONFIG_TUSB6010', if_true: files('tusb6010.c')) > > softmmu_ss.add(when: 'CONFIG_IMX', if_true: files('chipidea.c')) diff > > --git a/include/hw/usb/hcd-dwc3.h b/include/hw/usb/hcd-dwc3.h new file > > mode 100644 index 0000000..586968d > > --- /dev/null > > +++ b/include/hw/usb/hcd-dwc3.h > > @@ -0,0 +1,55 @@ > > +/* > > + * QEMU model of the USB DWC3 host controller emulation. > > + * > > + * Copyright (c) 2020 Xilinx Inc. > > + * > > + * Written by Vikram Garhwal<fnu.vikram@xilinx.com> > > + * > > + * Permission is hereby granted, free of charge, to any person > > +obtaining a copy > > + * of this software and associated documentation files (the > > +"Software"), to deal > > + * in the Software without restriction, including without limitation > > +the rights > > + * to use, copy, modify, merge, publish, distribute, sublicense, > > +and/or sell > > + * copies of the Software, and to permit persons to whom the Software > > +is > > + * furnished to do so, subject to the following conditions: > > + * > > + * The above copyright notice and this permission notice shall be > > +included in > > + * all copies or substantial portions of the Software. > > + * > > + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, > > +EXPRESS OR > > + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF > > +MERCHANTABILITY, > > + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO > EVENT > > +SHALL > > + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, > DAMAGES > > +OR OTHER > > + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, > > +ARISING FROM, > > + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER > > +DEALINGS IN > > + * THE SOFTWARE. > > + */ > > +#ifndef HCD_DWC3_H > > +#define HCD_DWC3_H > > + > > +#include "hw/usb/hcd-xhci.h" > > +#include "hw/usb/hcd-xhci-sysbus.h" > > + > > +#define TYPE_USB_DWC3 "usb_dwc3" > > + > > +#define USB_DWC3(obj) \ > > + OBJECT_CHECK(USBDWC3, (obj), TYPE_USB_DWC3) > > + > > +#define USB_DWC3_R_MAX ((0x530 / 4) + 1) > > + > > +typedef struct USBDWC3 { > > + SysBusDevice parent_obj; > > + MemoryRegion iomem; > > + MemoryRegion fifos; > > + XHCISysbusState sysbus_xhci; > > + > > + uint32_t regs[USB_DWC3_R_MAX]; > > + RegisterInfo regs_info[USB_DWC3_R_MAX]; > > + > > + struct { > > + uint8_t mode; > > + uint32_t dwc_usb3_user; > > + } cfg; > > + > > +} USBDWC3; > > + > > +#endif > > -- > > 2.7.4 > >