aboutsummaryrefslogtreecommitdiff
path: root/hw
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2020-02-21 16:18:38 +0000
committerPeter Maydell <peter.maydell@linaro.org>2020-02-21 16:18:38 +0000
commit9ac5df20f51fabcba0d902025df4bd7ea987c158 (patch)
treeed11117e803f345aa1e04d050a4c40fb0cc61b85 /hw
parenta8c6af67e1e8d460e2c6e87070807e0a02c0fec2 (diff)
parent9eb4f58918a851fb46895fd9b7ce579afeac9d02 (diff)
downloadqemu-9ac5df20f51fabcba0d902025df4bd7ea987c158.zip
qemu-9ac5df20f51fabcba0d902025df4bd7ea987c158.tar.gz
qemu-9ac5df20f51fabcba0d902025df4bd7ea987c158.tar.bz2
Merge remote-tracking branch 'remotes/pmaydell/tags/pull-target-arm-20200221-1' into staging
target-arm queue: * aspeed/scu: Implement chip ID register * hw/misc/iotkit-secctl: Fix writing to 'PPC Interrupt Clear' register * mainstone: Make providing flash images non-mandatory * z2: Make providing flash images non-mandatory * Fix failures to flush SVE high bits after AdvSIMD INS/ZIP/UZP/TRN/TBL/TBX/EXT * Minor performance improvement: spend less time recalculating hflags values * Code cleanup to isar_feature function tests * Implement ARMv8.1-PMU and ARMv8.4-PMU extensions * Bugfix: correct handling of PMCR_EL0.LC bit * Bugfix: correct definition of PMCRDP * Correctly implement ACTLR2, HACTLR2 * allwinner: Wire up USB ports * Vectorize emulation of USHL, SSHL, PMUL* * xilinx_spips: Correct the number of dummy cycles for the FAST_READ_4 cmd * sh4: Fix PCI ISA IO memory subregion # gpg: Signature made Fri 21 Feb 2020 16:17:37 GMT # gpg: using RSA key E1A5C593CD419DE28E8315CF3C2525ED14360CDE # gpg: issuer "peter.maydell@linaro.org" # gpg: Good signature from "Peter Maydell <peter.maydell@linaro.org>" [ultimate] # gpg: aka "Peter Maydell <pmaydell@gmail.com>" [ultimate] # gpg: aka "Peter Maydell <pmaydell@chiark.greenend.org.uk>" [ultimate] # Primary key fingerprint: E1A5 C593 CD41 9DE2 8E83 15CF 3C25 25ED 1436 0CDE * remotes/pmaydell/tags/pull-target-arm-20200221-1: (46 commits) target/arm: Set MVFR0.FPSP for ARMv5 cpus target/arm: Use isar_feature_aa32_simd_r32 more places target/arm: Rename isar_feature_aa32_simd_r32 sh4: Fix PCI ISA IO memory subregion xilinx_spips: Correct the number of dummy cycles for the FAST_READ_4 cmd target/arm: Convert PMULL.8 to gvec target/arm: Convert PMULL.64 to gvec target/arm: Convert PMUL.8 to gvec target/arm: Vectorize USHL and SSHL arm: allwinner: Wire up USB ports hcd-ehci: Introduce "companion-enable" sysbus property hw: usb: hcd-ohci: Move OHCISysBusState and TYPE_SYSBUS_OHCI to include file target/arm: Correctly implement ACTLR2, HACTLR2 target/arm: Use FIELD_EX32 for testing 32-bit fields target/arm: Use isar_feature function for testing AA32HPD feature target/arm: Test correct register in aa32_pan and aa32_ats1e1 checks target/arm: Correct handling of PMCR_EL0.LC bit target/arm: Correct definition of PMCRDP target/arm: Provide ARMv8.4-PMU in '-cpu max' target/arm: Implement ARMv8.4-PMU extension ... Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'hw')
-rw-r--r--hw/arm/allwinner-a10.c43
-rw-r--r--hw/arm/mainstone.c11
-rw-r--r--hw/arm/z2.c6
-rw-r--r--hw/intc/armv7m_nvic.c10
-rw-r--r--hw/misc/aspeed_scu.c93
-rw-r--r--hw/misc/iotkit-secctl.c2
-rw-r--r--hw/sh4/sh_pci.c11
-rw-r--r--hw/ssi/xilinx_spips.c2
-rw-r--r--hw/usb/hcd-ehci-sysbus.c2
-rw-r--r--hw/usb/hcd-ohci.c15
-rw-r--r--hw/usb/hcd-ohci.h16
11 files changed, 142 insertions, 69 deletions
diff --git a/hw/arm/allwinner-a10.c b/hw/arm/allwinner-a10.c
index 1cde165..2ae9c15 100644
--- a/hw/arm/allwinner-a10.c
+++ b/hw/arm/allwinner-a10.c
@@ -24,11 +24,15 @@
#include "hw/arm/allwinner-a10.h"
#include "hw/misc/unimp.h"
#include "sysemu/sysemu.h"
+#include "hw/boards.h"
+#include "hw/usb/hcd-ohci.h"
#define AW_A10_PIC_REG_BASE 0x01c20400
#define AW_A10_PIT_REG_BASE 0x01c20c00
#define AW_A10_UART0_REG_BASE 0x01c28000
#define AW_A10_EMAC_BASE 0x01c0b000
+#define AW_A10_EHCI_BASE 0x01c14000
+#define AW_A10_OHCI_BASE 0x01c14400
#define AW_A10_SATA_BASE 0x01c18000
static void aw_a10_init(Object *obj)
@@ -49,6 +53,17 @@ static void aw_a10_init(Object *obj)
sysbus_init_child_obj(obj, "sata", &s->sata, sizeof(s->sata),
TYPE_ALLWINNER_AHCI);
+
+ if (machine_usb(current_machine)) {
+ int i;
+
+ for (i = 0; i < AW_A10_NUM_USB; i++) {
+ sysbus_init_child_obj(obj, "ehci[*]", OBJECT(&s->ehci[i]),
+ sizeof(s->ehci[i]), TYPE_PLATFORM_EHCI);
+ sysbus_init_child_obj(obj, "ohci[*]", OBJECT(&s->ohci[i]),
+ sizeof(s->ohci[i]), TYPE_SYSBUS_OHCI);
+ }
+ }
}
static void aw_a10_realize(DeviceState *dev, Error **errp)
@@ -121,6 +136,34 @@ static void aw_a10_realize(DeviceState *dev, Error **errp)
serial_mm_init(get_system_memory(), AW_A10_UART0_REG_BASE, 2,
qdev_get_gpio_in(dev, 1),
115200, serial_hd(0), DEVICE_NATIVE_ENDIAN);
+
+ if (machine_usb(current_machine)) {
+ int i;
+
+ for (i = 0; i < AW_A10_NUM_USB; i++) {
+ char bus[16];
+
+ sprintf(bus, "usb-bus.%d", i);
+
+ object_property_set_bool(OBJECT(&s->ehci[i]), true,
+ "companion-enable", &error_fatal);
+ object_property_set_bool(OBJECT(&s->ehci[i]), true, "realized",
+ &error_fatal);
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->ehci[i]), 0,
+ AW_A10_EHCI_BASE + i * 0x8000);
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->ehci[i]), 0,
+ qdev_get_gpio_in(dev, 39 + i));
+
+ object_property_set_str(OBJECT(&s->ohci[i]), bus, "masterbus",
+ &error_fatal);
+ object_property_set_bool(OBJECT(&s->ohci[i]), true, "realized",
+ &error_fatal);
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->ohci[i]), 0,
+ AW_A10_OHCI_BASE + i * 0x8000);
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->ohci[i]), 0,
+ qdev_get_gpio_in(dev, 64 + i));
+ }
+ }
}
static void aw_a10_class_init(ObjectClass *oc, void *data)
diff --git a/hw/arm/mainstone.c b/hw/arm/mainstone.c
index b01ce3c..6e64dfa 100644
--- a/hw/arm/mainstone.c
+++ b/hw/arm/mainstone.c
@@ -138,19 +138,10 @@ static void mainstone_common_init(MemoryRegion *address_space_mem,
/* There are two 32MiB flash devices on the board */
for (i = 0; i < 2; i ++) {
dinfo = drive_get(IF_PFLASH, 0, i);
- if (!dinfo) {
- if (qtest_enabled()) {
- break;
- }
- error_report("Two flash images must be given with the "
- "'pflash' parameter");
- exit(1);
- }
-
if (!pflash_cfi01_register(mainstone_flash_base[i],
i ? "mainstone.flash1" : "mainstone.flash0",
MAINSTONE_FLASH,
- blk_by_legacy_dinfo(dinfo),
+ dinfo ? blk_by_legacy_dinfo(dinfo) : NULL,
sector_len, 4, 0, 0, 0, 0, be)) {
error_report("Error registering flash memory");
exit(1);
diff --git a/hw/arm/z2.c b/hw/arm/z2.c
index 34794fe..4bb237f 100644
--- a/hw/arm/z2.c
+++ b/hw/arm/z2.c
@@ -314,12 +314,6 @@ static void z2_init(MachineState *machine)
be = 0;
#endif
dinfo = drive_get(IF_PFLASH, 0, 0);
- if (!dinfo && !qtest_enabled()) {
- error_report("Flash image must be given with the "
- "'pflash' parameter");
- exit(1);
- }
-
if (!pflash_cfi01_register(Z2_FLASH_BASE, "z2.flash0", Z2_FLASH_SIZE,
dinfo ? blk_by_legacy_dinfo(dinfo) : NULL,
sector_len, 4, 0, 0, 0, 0, be)) {
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
index f9e0eea..22a43e4 100644
--- a/hw/intc/armv7m_nvic.c
+++ b/hw/intc/armv7m_nvic.c
@@ -1227,17 +1227,17 @@ static uint32_t nvic_readl(NVICState *s, uint32_t offset, MemTxAttrs attrs)
case 0xd44: /* PFR1. */
return cpu->id_pfr1;
case 0xd48: /* DFR0. */
- return cpu->id_dfr0;
+ return cpu->isar.id_dfr0;
case 0xd4c: /* AFR0. */
return cpu->id_afr0;
case 0xd50: /* MMFR0. */
- return cpu->id_mmfr0;
+ return cpu->isar.id_mmfr0;
case 0xd54: /* MMFR1. */
- return cpu->id_mmfr1;
+ return cpu->isar.id_mmfr1;
case 0xd58: /* MMFR2. */
- return cpu->id_mmfr2;
+ return cpu->isar.id_mmfr2;
case 0xd5c: /* MMFR3. */
- return cpu->id_mmfr3;
+ return cpu->isar.id_mmfr3;
case 0xd60: /* ISAR0. */
return cpu->isar.id_isar0;
case 0xd64: /* ISAR1. */
diff --git a/hw/misc/aspeed_scu.c b/hw/misc/aspeed_scu.c
index ce2f956..9d7482a 100644
--- a/hw/misc/aspeed_scu.c
+++ b/hw/misc/aspeed_scu.c
@@ -77,6 +77,8 @@
#define CPU2_BASE_SEG4 TO_REG(0x110)
#define CPU2_BASE_SEG5 TO_REG(0x114)
#define CPU2_CACHE_CTRL TO_REG(0x118)
+#define CHIP_ID0 TO_REG(0x150)
+#define CHIP_ID1 TO_REG(0x154)
#define UART_HPLL_CLK TO_REG(0x160)
#define PCIE_CTRL TO_REG(0x180)
#define BMC_MMIO_CTRL TO_REG(0x184)
@@ -115,6 +117,8 @@
#define AST2600_HW_STRAP2_PROT TO_REG(0x518)
#define AST2600_RNG_CTRL TO_REG(0x524)
#define AST2600_RNG_DATA TO_REG(0x540)
+#define AST2600_CHIP_ID0 TO_REG(0x5B0)
+#define AST2600_CHIP_ID1 TO_REG(0x5B4)
#define AST2600_CLK TO_REG(0x40)
@@ -182,6 +186,8 @@ static const uint32_t ast2500_a1_resets[ASPEED_SCU_NR_REGS] = {
[CPU2_BASE_SEG1] = 0x80000000U,
[CPU2_BASE_SEG4] = 0x1E600000U,
[CPU2_BASE_SEG5] = 0xC0000000U,
+ [CHIP_ID0] = 0x1234ABCDU,
+ [CHIP_ID1] = 0x88884444U,
[UART_HPLL_CLK] = 0x00001903U,
[PCIE_CTRL] = 0x0000007BU,
[BMC_DEV_ID] = 0x00002402U
@@ -232,8 +238,47 @@ static uint64_t aspeed_scu_read(void *opaque, hwaddr offset, unsigned size)
return s->regs[reg];
}
-static void aspeed_scu_write(void *opaque, hwaddr offset, uint64_t data,
- unsigned size)
+static void aspeed_ast2400_scu_write(void *opaque, hwaddr offset,
+ uint64_t data, unsigned size)
+{
+ AspeedSCUState *s = ASPEED_SCU(opaque);
+ int reg = TO_REG(offset);
+
+ if (reg >= ASPEED_SCU_NR_REGS) {
+ qemu_log_mask(LOG_GUEST_ERROR,
+ "%s: Out-of-bounds write at offset 0x%" HWADDR_PRIx "\n",
+ __func__, offset);
+ return;
+ }
+
+ if (reg > PROT_KEY && reg < CPU2_BASE_SEG1 &&
+ !s->regs[PROT_KEY]) {
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: SCU is locked!\n", __func__);
+ }
+
+ trace_aspeed_scu_write(offset, size, data);
+
+ switch (reg) {
+ case PROT_KEY:
+ s->regs[reg] = (data == ASPEED_SCU_PROT_KEY) ? 1 : 0;
+ return;
+ case SILICON_REV:
+ case FREQ_CNTR_EVAL:
+ case VGA_SCRATCH1 ... VGA_SCRATCH8:
+ case RNG_DATA:
+ case FREE_CNTR4:
+ case FREE_CNTR4_EXT:
+ qemu_log_mask(LOG_GUEST_ERROR,
+ "%s: Write to read-only offset 0x%" HWADDR_PRIx "\n",
+ __func__, offset);
+ return;
+ }
+
+ s->regs[reg] = data;
+}
+
+static void aspeed_ast2500_scu_write(void *opaque, hwaddr offset,
+ uint64_t data, unsigned size)
{
AspeedSCUState *s = ASPEED_SCU(opaque);
int reg = TO_REG(offset);
@@ -257,31 +302,19 @@ static void aspeed_scu_write(void *opaque, hwaddr offset, uint64_t data,
case PROT_KEY:
s->regs[reg] = (data == ASPEED_SCU_PROT_KEY) ? 1 : 0;
return;
- case CLK_SEL:
- s->regs[reg] = data;
- break;
case HW_STRAP1:
- if (ASPEED_IS_AST2500(s->regs[SILICON_REV])) {
- s->regs[HW_STRAP1] |= data;
- return;
- }
- /* Jump to assignment below */
- break;
+ s->regs[HW_STRAP1] |= data;
+ return;
case SILICON_REV:
- if (ASPEED_IS_AST2500(s->regs[SILICON_REV])) {
- s->regs[HW_STRAP1] &= ~data;
- } else {
- qemu_log_mask(LOG_GUEST_ERROR,
- "%s: Write to read-only offset 0x%" HWADDR_PRIx "\n",
- __func__, offset);
- }
- /* Avoid assignment below, we've handled everything */
+ s->regs[HW_STRAP1] &= ~data;
return;
case FREQ_CNTR_EVAL:
case VGA_SCRATCH1 ... VGA_SCRATCH8:
case RNG_DATA:
case FREE_CNTR4:
case FREE_CNTR4_EXT:
+ case CHIP_ID0:
+ case CHIP_ID1:
qemu_log_mask(LOG_GUEST_ERROR,
"%s: Write to read-only offset 0x%" HWADDR_PRIx "\n",
__func__, offset);
@@ -291,9 +324,18 @@ static void aspeed_scu_write(void *opaque, hwaddr offset, uint64_t data,
s->regs[reg] = data;
}
-static const MemoryRegionOps aspeed_scu_ops = {
+static const MemoryRegionOps aspeed_ast2400_scu_ops = {
+ .read = aspeed_scu_read,
+ .write = aspeed_ast2400_scu_write,
+ .endianness = DEVICE_LITTLE_ENDIAN,
+ .valid.min_access_size = 4,
+ .valid.max_access_size = 4,
+ .valid.unaligned = false,
+};
+
+static const MemoryRegionOps aspeed_ast2500_scu_ops = {
.read = aspeed_scu_read,
- .write = aspeed_scu_write,
+ .write = aspeed_ast2500_scu_write,
.endianness = DEVICE_LITTLE_ENDIAN,
.valid.min_access_size = 4,
.valid.max_access_size = 4,
@@ -469,7 +511,7 @@ static void aspeed_2400_scu_class_init(ObjectClass *klass, void *data)
asc->calc_hpll = aspeed_2400_scu_calc_hpll;
asc->apb_divider = 2;
asc->nr_regs = ASPEED_SCU_NR_REGS;
- asc->ops = &aspeed_scu_ops;
+ asc->ops = &aspeed_ast2400_scu_ops;
}
static const TypeInfo aspeed_2400_scu_info = {
@@ -489,7 +531,7 @@ static void aspeed_2500_scu_class_init(ObjectClass *klass, void *data)
asc->calc_hpll = aspeed_2500_scu_calc_hpll;
asc->apb_divider = 4;
asc->nr_regs = ASPEED_SCU_NR_REGS;
- asc->ops = &aspeed_scu_ops;
+ asc->ops = &aspeed_ast2500_scu_ops;
}
static const TypeInfo aspeed_2500_scu_info = {
@@ -586,6 +628,8 @@ static void aspeed_ast2600_scu_write(void *opaque, hwaddr offset,
case AST2600_RNG_DATA:
case AST2600_SILICON_REV:
case AST2600_SILICON_REV2:
+ case AST2600_CHIP_ID0:
+ case AST2600_CHIP_ID1:
/* Add read only registers here */
qemu_log_mask(LOG_GUEST_ERROR,
"%s: Write to read-only offset 0x%" HWADDR_PRIx "\n",
@@ -614,6 +658,9 @@ static const uint32_t ast2600_a0_resets[ASPEED_AST2600_SCU_NR_REGS] = {
[AST2600_CLK_STOP_CTRL2] = 0xFFF0FFF0,
[AST2600_SDRAM_HANDSHAKE] = 0x00000040, /* SoC completed DRAM init */
[AST2600_HPLL_PARAM] = 0x1000405F,
+ [AST2600_CHIP_ID0] = 0x1234ABCD,
+ [AST2600_CHIP_ID1] = 0x88884444,
+
};
static void aspeed_ast2600_scu_reset(DeviceState *dev)
diff --git a/hw/misc/iotkit-secctl.c b/hw/misc/iotkit-secctl.c
index 6098698..9fdb820 100644
--- a/hw/misc/iotkit-secctl.c
+++ b/hw/misc/iotkit-secctl.c
@@ -340,7 +340,7 @@ static MemTxResult iotkit_secctl_s_write(void *opaque, hwaddr addr,
qemu_set_irq(s->sec_resp_cfg, s->secrespcfg);
break;
case A_SECPPCINTCLR:
- value &= 0x00f000f3;
+ s->secppcintstat &= ~(value & 0x00f000f3);
foreach_ppc(s, iotkit_secctl_ppc_update_irq_clear);
break;
case A_SECPPCINTEN:
diff --git a/hw/sh4/sh_pci.c b/hw/sh4/sh_pci.c
index 71afd23..08f2fc1 100644
--- a/hw/sh4/sh_pci.c
+++ b/hw/sh4/sh_pci.c
@@ -67,12 +67,8 @@ static void sh_pci_reg_write (void *p, hwaddr addr, uint64_t val,
pcic->mbr = val & 0xff000001;
break;
case 0x1c8:
- if ((val & 0xfffc0000) != (pcic->iobr & 0xfffc0000)) {
- memory_region_del_subregion(get_system_memory(), &pcic->isa);
- pcic->iobr = val & 0xfffc0001;
- memory_region_add_subregion(get_system_memory(),
- pcic->iobr & 0xfffc0000, &pcic->isa);
- }
+ pcic->iobr = val & 0xfffc0001;
+ memory_region_set_alias_offset(&pcic->isa, val & 0xfffc0000);
break;
case 0x220:
pci_data_write(phb->bus, pcic->par, val, 4);
@@ -147,8 +143,7 @@ static void sh_pci_device_realize(DeviceState *dev, Error **errp)
get_system_io(), 0, 0x40000);
sysbus_init_mmio(sbd, &s->memconfig_p4);
sysbus_init_mmio(sbd, &s->memconfig_a7);
- s->iobr = 0xfe240000;
- memory_region_add_subregion(get_system_memory(), s->iobr, &s->isa);
+ memory_region_add_subregion(get_system_memory(), 0xfe240000, &s->isa);
s->dev = pci_create_simple(phb->bus, PCI_DEVFN(0, 0), "sh_pci_host");
}
diff --git a/hw/ssi/xilinx_spips.c b/hw/ssi/xilinx_spips.c
index 6c9ef59..c57850a 100644
--- a/hw/ssi/xilinx_spips.c
+++ b/hw/ssi/xilinx_spips.c
@@ -576,11 +576,11 @@ static int xilinx_spips_num_dummies(XilinxQSPIPS *qs, uint8_t command)
case FAST_READ:
case DOR:
case QOR:
+ case FAST_READ_4:
case DOR_4:
case QOR_4:
return 1;
case DIOR:
- case FAST_READ_4:
case DIOR_4:
return 2;
case QIOR:
diff --git a/hw/usb/hcd-ehci-sysbus.c b/hw/usb/hcd-ehci-sysbus.c
index 8d47385..b22fb25 100644
--- a/hw/usb/hcd-ehci-sysbus.c
+++ b/hw/usb/hcd-ehci-sysbus.c
@@ -33,6 +33,8 @@ static const VMStateDescription vmstate_ehci_sysbus = {
static Property ehci_sysbus_properties[] = {
DEFINE_PROP_UINT32("maxframes", EHCISysBusState, ehci.maxframes, 128),
+ DEFINE_PROP_BOOL("companion-enable", EHCISysBusState, ehci.companion_enable,
+ false),
DEFINE_PROP_END_OF_LIST(),
};
diff --git a/hw/usb/hcd-ohci.c b/hw/usb/hcd-ohci.c
index 8a94bd0..1e6e85e 100644
--- a/hw/usb/hcd-ohci.c
+++ b/hw/usb/hcd-ohci.c
@@ -1870,21 +1870,6 @@ void ohci_sysbus_die(struct OHCIState *ohci)
ohci_bus_stop(ohci);
}
-#define TYPE_SYSBUS_OHCI "sysbus-ohci"
-#define SYSBUS_OHCI(obj) OBJECT_CHECK(OHCISysBusState, (obj), TYPE_SYSBUS_OHCI)
-
-typedef struct {
- /*< private >*/
- SysBusDevice parent_obj;
- /*< public >*/
-
- OHCIState ohci;
- char *masterbus;
- uint32_t num_ports;
- uint32_t firstport;
- dma_addr_t dma_offset;
-} OHCISysBusState;
-
static void ohci_realize_pxa(DeviceState *dev, Error **errp)
{
OHCISysBusState *s = SYSBUS_OHCI(dev);
diff --git a/hw/usb/hcd-ohci.h b/hw/usb/hcd-ohci.h
index 16e3f1e..5c8819a 100644
--- a/hw/usb/hcd-ohci.h
+++ b/hw/usb/hcd-ohci.h
@@ -22,6 +22,7 @@
#define HCD_OHCI_H
#include "sysemu/dma.h"
+#include "hw/usb.h"
/* Number of Downstream Ports on the root hub: */
#define OHCI_MAX_PORTS 15
@@ -90,6 +91,21 @@ typedef struct OHCIState {
void (*ohci_die)(struct OHCIState *ohci);
} OHCIState;
+#define TYPE_SYSBUS_OHCI "sysbus-ohci"
+#define SYSBUS_OHCI(obj) OBJECT_CHECK(OHCISysBusState, (obj), TYPE_SYSBUS_OHCI)
+
+typedef struct {
+ /*< private >*/
+ SysBusDevice parent_obj;
+ /*< public >*/
+
+ OHCIState ohci;
+ char *masterbus;
+ uint32_t num_ports;
+ uint32_t firstport;
+ dma_addr_t dma_offset;
+} OHCISysBusState;
+
extern const VMStateDescription vmstate_ohci_state;
void usb_ohci_init(OHCIState *ohci, DeviceState *dev, uint32_t num_ports,