summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2020-10-21 21:45:46 +0100
committerPeter Maydell <peter.maydell@linaro.org>2020-10-21 21:45:46 +0100
commit02aa56c4bc409d5822d39e734fc13a2b26cdd171 (patch)
tree0b476a5ed97e67e0dd4656d67caa6ddc151a6e4b
parente06c687fdf24b52358539a52bba184e8f5ff5b35 (diff)
parent66907f3d3b8bfc2de77b82d89253b7b3a8b728ec (diff)
downloadqemu-02aa56c4bc409d5822d39e734fc13a2b26cdd171.zip
Merge remote-tracking branch 'remotes/kraxel/tags/microvm-20201021-pull-request' into staging
microvm: fix PCIe IRQs in APIC table. microvm: add usb support. # gpg: Signature made Wed 21 Oct 2020 15:48:00 BST # gpg: using RSA key 4CB6D8EED3E87138 # gpg: Good signature from "Gerd Hoffmann (work) <kraxel@redhat.com>" [full] # gpg: aka "Gerd Hoffmann <gerd@kraxel.org>" [full] # gpg: aka "Gerd Hoffmann (private) <kraxel@gmail.com>" [full] # Primary key fingerprint: A032 8CFF B93A 17A7 9901 FE7D 4CB6 D8EE D3E8 7138 * remotes/kraxel/tags/microvm-20201021-pull-request: tests/acpi: update expected data files tests/acpi: add microvm rtc test tests/acpi: add microvm usb test tests/acpi: add empty tests/data/acpi/microvm/DSDT.{usb, rtc} files tests/acpi: allow updates for expected data files microvm: add usb support usb/xhci: fixup xhci kconfig deps usb/xhci: add xhci_sysbus_build_aml() helper usb/xhci: add include/hw/usb/xhci.h header file acpi: add aml builder stubs tests/acpi: disallow changes for microvm/APIC.pcie tests/acpi: update expected data files apci: drop has_pci arg for acpi_build_madt microvm: set pci_irq_mask x86: make pci irqs runtime configurable tests/acpi: add empty microvm/APIC.pcie tests/acpi: allow changes for microvm/APIC.pcie Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
-rw-r--r--hw/acpi/aml-build-stub.c14
-rw-r--r--hw/i386/Kconfig1
-rw-r--r--hw/i386/acpi-build.c2
-rw-r--r--hw/i386/acpi-common.c26
-rw-r--r--hw/i386/acpi-common.h3
-rw-r--r--hw/i386/acpi-microvm.c11
-rw-r--r--hw/i386/microvm.c19
-rw-r--r--hw/i386/x86.c1
-rw-r--r--hw/usb/Kconfig6
-rw-r--r--hw/usb/hcd-xhci-nec.c4
-rw-r--r--hw/usb/hcd-xhci-pci.c4
-rw-r--r--hw/usb/hcd-xhci-sysbus.c19
-rw-r--r--hw/usb/hcd-xhci-sysbus.h1
-rw-r--r--hw/usb/hcd-xhci.c34
-rw-r--r--hw/usb/hcd-xhci.h22
-rw-r--r--include/hw/i386/microvm.h5
-rw-r--r--include/hw/i386/x86.h2
-rw-r--r--include/hw/usb/xhci.h21
-rw-r--r--tests/data/acpi/microvm/APIC.pciebin0 -> 110 bytes
-rw-r--r--tests/data/acpi/microvm/DSDT.rtcbin0 -> 404 bytes
-rw-r--r--tests/data/acpi/microvm/DSDT.usbbin0 -> 414 bytes
-rw-r--r--tests/qtest/bios-tables-test.c24
22 files changed, 154 insertions, 65 deletions
diff --git a/hw/acpi/aml-build-stub.c b/hw/acpi/aml-build-stub.c
index 58b2e16227..8d8ad1a314 100644
--- a/hw/acpi/aml-build-stub.c
+++ b/hw/acpi/aml-build-stub.c
@@ -57,6 +57,20 @@ Aml *aml_irq_no_flags(uint8_t irq)
return NULL;
}
+Aml *aml_interrupt(AmlConsumerAndProducer con_and_pro,
+ AmlLevelAndEdge level_and_edge,
+ AmlActiveHighAndLow high_and_low, AmlShared shared,
+ uint32_t *irq_list, uint8_t irq_count)
+{
+ return NULL;
+}
+
+Aml *aml_memory32_fixed(uint32_t addr, uint32_t size,
+ AmlReadAndWrite read_and_write)
+{
+ return NULL;
+}
+
Aml *aml_int(const uint64_t val)
{
return NULL;
diff --git a/hw/i386/Kconfig b/hw/i386/Kconfig
index 32aa15533b..eea059ffef 100644
--- a/hw/i386/Kconfig
+++ b/hw/i386/Kconfig
@@ -105,6 +105,7 @@ config MICROVM
select VIRTIO_MMIO
select ACPI_HW_REDUCED
select PCI_EXPRESS_GENERIC_BRIDGE
+ select USB_XHCI_SYSBUS
config X86_IOMMU
bool
diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
index 45ad2f9533..e3a4bc206c 100644
--- a/hw/i386/acpi-build.c
+++ b/hw/i386/acpi-build.c
@@ -2477,7 +2477,7 @@ void acpi_build(AcpiBuildTables *tables, MachineState *machine)
acpi_add_table(table_offsets, tables_blob);
acpi_build_madt(tables_blob, tables->linker, x86ms,
- ACPI_DEVICE_IF(x86ms->acpi_dev), true);
+ ACPI_DEVICE_IF(x86ms->acpi_dev));
vmgenid_dev = find_vmgenid_dev();
if (vmgenid_dev) {
diff --git a/hw/i386/acpi-common.c b/hw/i386/acpi-common.c
index ab9b00581a..8a76965406 100644
--- a/hw/i386/acpi-common.c
+++ b/hw/i386/acpi-common.c
@@ -72,8 +72,7 @@ void pc_madt_cpu_entry(AcpiDeviceIf *adev, int uid,
}
void acpi_build_madt(GArray *table_data, BIOSLinker *linker,
- X86MachineState *x86ms, AcpiDeviceIf *adev,
- bool has_pci)
+ X86MachineState *x86ms, AcpiDeviceIf *adev)
{
MachineClass *mc = MACHINE_GET_CLASS(x86ms);
const CPUArchIdList *apic_ids = mc->possible_cpu_arch_ids(MACHINE(x86ms));
@@ -113,20 +112,17 @@ void acpi_build_madt(GArray *table_data, BIOSLinker *linker,
intsrcovr->flags = cpu_to_le16(0); /* conforms to bus specifications */
}
- if (has_pci) {
- for (i = 1; i < 16; i++) {
-#define ACPI_BUILD_PCI_IRQS ((1<<5) | (1<<9) | (1<<10) | (1<<11))
- if (!(ACPI_BUILD_PCI_IRQS & (1 << i))) {
- /* No need for a INT source override structure. */
- continue;
- }
- intsrcovr = acpi_data_push(table_data, sizeof *intsrcovr);
- intsrcovr->type = ACPI_APIC_XRUPT_OVERRIDE;
- intsrcovr->length = sizeof(*intsrcovr);
- intsrcovr->source = i;
- intsrcovr->gsi = cpu_to_le32(i);
- intsrcovr->flags = cpu_to_le16(0xd); /* active high, level triggered */
+ for (i = 1; i < 16; i++) {
+ if (!(x86ms->pci_irq_mask & (1 << i))) {
+ /* No need for a INT source override structure. */
+ continue;
}
+ intsrcovr = acpi_data_push(table_data, sizeof *intsrcovr);
+ intsrcovr->type = ACPI_APIC_XRUPT_OVERRIDE;
+ intsrcovr->length = sizeof(*intsrcovr);
+ intsrcovr->source = i;
+ intsrcovr->gsi = cpu_to_le32(i);
+ intsrcovr->flags = cpu_to_le16(0xd); /* active high, level triggered */
}
if (x2apic_mode) {
diff --git a/hw/i386/acpi-common.h b/hw/i386/acpi-common.h
index 9cac18dddf..c30e461f18 100644
--- a/hw/i386/acpi-common.h
+++ b/hw/i386/acpi-common.h
@@ -9,7 +9,6 @@
#define ACPI_BUILD_IOAPIC_ID 0x0
void acpi_build_madt(GArray *table_data, BIOSLinker *linker,
- X86MachineState *x86ms, AcpiDeviceIf *adev,
- bool has_pci);
+ X86MachineState *x86ms, AcpiDeviceIf *adev);
#endif
diff --git a/hw/i386/acpi-microvm.c b/hw/i386/acpi-microvm.c
index f16f231195..d34a301b84 100644
--- a/hw/i386/acpi-microvm.c
+++ b/hw/i386/acpi-microvm.c
@@ -35,6 +35,7 @@
#include "hw/i386/microvm.h"
#include "hw/pci/pci.h"
#include "hw/pci/pcie_host.h"
+#include "hw/usb/xhci.h"
#include "hw/virtio/virtio-mmio.h"
#include "acpi-common.h"
@@ -89,6 +90,13 @@ static void acpi_dsdt_add_virtio(Aml *scope,
}
}
+static void acpi_dsdt_add_xhci(Aml *scope, MicrovmMachineState *mms)
+{
+ if (machine_usb(MACHINE(mms))) {
+ xhci_sysbus_build_aml(scope, MICROVM_XHCI_BASE, MICROVM_XHCI_IRQ);
+ }
+}
+
static void acpi_dsdt_add_pci(Aml *scope, MicrovmMachineState *mms)
{
if (mms->pcie != ON_OFF_AUTO_ON) {
@@ -123,6 +131,7 @@ build_dsdt_microvm(GArray *table_data, BIOSLinker *linker,
GED_MMIO_IRQ, AML_SYSTEM_MEMORY, GED_MMIO_BASE);
acpi_dsdt_add_power_button(sb_scope);
acpi_dsdt_add_virtio(sb_scope, mms);
+ acpi_dsdt_add_xhci(sb_scope, mms);
acpi_dsdt_add_pci(sb_scope, mms);
aml_append(dsdt, sb_scope);
@@ -196,7 +205,7 @@ static void acpi_build_microvm(AcpiBuildTables *tables,
acpi_add_table(table_offsets, tables_blob);
acpi_build_madt(tables_blob, tables->linker, X86_MACHINE(machine),
- ACPI_DEVICE_IF(x86ms->acpi_dev), false);
+ ACPI_DEVICE_IF(x86ms->acpi_dev));
xsdt = tables_blob->len;
build_xsdt(tables_blob, tables->linker, table_offsets, NULL, NULL);
diff --git a/hw/i386/microvm.c b/hw/i386/microvm.c
index 68a7f424ac..5428448b70 100644
--- a/hw/i386/microvm.c
+++ b/hw/i386/microvm.c
@@ -47,6 +47,7 @@
#include "hw/acpi/acpi.h"
#include "hw/acpi/generic_event_device.h"
#include "hw/pci-host/gpex.h"
+#include "hw/usb/xhci.h"
#include "cpu.h"
#include "elf.h"
@@ -197,6 +198,18 @@ static void microvm_devices_init(MicrovmMachineState *mms)
x86ms->acpi_dev = HOTPLUG_HANDLER(dev);
}
+ if (x86_machine_is_acpi_enabled(x86ms) && machine_usb(MACHINE(mms))) {
+ DeviceState *dev = qdev_new(TYPE_XHCI_SYSBUS);
+ qdev_prop_set_uint32(dev, "intrs", 1);
+ qdev_prop_set_uint32(dev, "slots", XHCI_MAXSLOTS);
+ qdev_prop_set_uint32(dev, "p2", 8);
+ qdev_prop_set_uint32(dev, "p3", 8);
+ sysbus_realize(SYS_BUS_DEVICE(dev), &error_fatal);
+ sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, MICROVM_XHCI_BASE);
+ sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0,
+ x86ms->gsi[MICROVM_XHCI_IRQ]);
+ }
+
if (x86_machine_is_acpi_enabled(x86ms) && mms->pcie == ON_OFF_AUTO_ON) {
/* use topmost 25% of the address space available */
hwaddr phys_size = (hwaddr)1 << X86_CPU(first_cpu)->phys_bits;
@@ -210,6 +223,12 @@ static void microvm_devices_init(MicrovmMachineState *mms)
mms->gpex.ecam.size = PCIE_ECAM_SIZE;
mms->gpex.irq = PCIE_IRQ_BASE;
create_gpex(mms);
+ x86ms->pci_irq_mask = ((1 << (PCIE_IRQ_BASE + 0)) |
+ (1 << (PCIE_IRQ_BASE + 1)) |
+ (1 << (PCIE_IRQ_BASE + 2)) |
+ (1 << (PCIE_IRQ_BASE + 3)));
+ } else {
+ x86ms->pci_irq_mask = 0;
}
if (mms->pic == ON_OFF_AUTO_ON || mms->pic == ON_OFF_AUTO_AUTO) {
diff --git a/hw/i386/x86.c b/hw/i386/x86.c
index 3137a20085..5944fc44ed 100644
--- a/hw/i386/x86.c
+++ b/hw/i386/x86.c
@@ -1178,6 +1178,7 @@ static void x86_machine_initfn(Object *obj)
x86ms->smm = ON_OFF_AUTO_AUTO;
x86ms->acpi = ON_OFF_AUTO_AUTO;
x86ms->smp_dies = 1;
+ x86ms->pci_irq_mask = ACPI_BUILD_PCI_IRQS;
}
static void x86_machine_class_init(ObjectClass *oc, void *data)
diff --git a/hw/usb/Kconfig b/hw/usb/Kconfig
index 4dd2ba9630..a674ce4c54 100644
--- a/hw/usb/Kconfig
+++ b/hw/usb/Kconfig
@@ -32,8 +32,6 @@ config USB_EHCI_SYSBUS
config USB_XHCI
bool
- default y if PCI_DEVICES
- depends on PCI
select USB
config USB_XHCI_PCI
@@ -50,8 +48,8 @@ config USB_XHCI_NEC
config USB_XHCI_SYSBUS
bool
- default y if USB_XHCI
- select USB
+ default y
+ select USB_XHCI
config USB_MUSB
bool
diff --git a/hw/usb/hcd-xhci-nec.c b/hw/usb/hcd-xhci-nec.c
index 2efa6fa0f8..5707b2cabd 100644
--- a/hw/usb/hcd-xhci-nec.c
+++ b/hw/usb/hcd-xhci-nec.c
@@ -34,8 +34,8 @@ static Property nec_xhci_properties[] = {
xhci.flags, XHCI_FLAG_SS_FIRST, true),
DEFINE_PROP_BIT("force-pcie-endcap", XHCIPciState, xhci.flags,
XHCI_FLAG_FORCE_PCIE_ENDCAP, false),
- DEFINE_PROP_UINT32("intrs", XHCIPciState, xhci.numintrs, MAXINTRS),
- DEFINE_PROP_UINT32("slots", XHCIPciState, xhci.numslots, MAXSLOTS),
+ DEFINE_PROP_UINT32("intrs", XHCIPciState, xhci.numintrs, XHCI_MAXINTRS),
+ DEFINE_PROP_UINT32("slots", XHCIPciState, xhci.numslots, XHCI_MAXSLOTS),
DEFINE_PROP_END_OF_LIST(),
};
diff --git a/hw/usb/hcd-xhci-pci.c b/hw/usb/hcd-xhci-pci.c
index a6d746e1da..b78fcd2bb2 100644
--- a/hw/usb/hcd-xhci-pci.c
+++ b/hw/usb/hcd-xhci-pci.c
@@ -240,8 +240,8 @@ static void qemu_xhci_instance_init(Object *obj)
s->msi = ON_OFF_AUTO_OFF;
s->msix = ON_OFF_AUTO_AUTO;
- xhci->numintrs = MAXINTRS;
- xhci->numslots = MAXSLOTS;
+ xhci->numintrs = XHCI_MAXINTRS;
+ xhci->numslots = XHCI_MAXSLOTS;
xhci_set_flag(xhci, XHCI_FLAG_SS_FIRST);
}
diff --git a/hw/usb/hcd-xhci-sysbus.c b/hw/usb/hcd-xhci-sysbus.c
index 852ca5103b..29185d2261 100644
--- a/hw/usb/hcd-xhci-sysbus.c
+++ b/hw/usb/hcd-xhci-sysbus.c
@@ -13,6 +13,7 @@
#include "trace.h"
#include "qapi/error.h"
#include "hcd-xhci-sysbus.h"
+#include "hw/acpi/aml-build.h"
#include "hw/irq.h"
static void xhci_sysbus_intr_raise(XHCIState *xhci, int n, bool level)
@@ -68,9 +69,23 @@ static void xhci_sysbus_instance_init(Object *obj)
s->xhci.intr_raise = xhci_sysbus_intr_raise;
}
+void xhci_sysbus_build_aml(Aml *scope, uint32_t mmio, unsigned int irq)
+{
+ Aml *dev = aml_device("XHCI");
+ Aml *crs = aml_resource_template();
+
+ aml_append(crs, aml_memory32_fixed(mmio, XHCI_LEN_REGS, AML_READ_WRITE));
+ aml_append(crs, aml_interrupt(AML_CONSUMER, AML_LEVEL, AML_ACTIVE_HIGH,
+ AML_EXCLUSIVE, &irq, 1));
+
+ aml_append(dev, aml_name_decl("_HID", aml_eisaid("PNP0D10")));
+ aml_append(dev, aml_name_decl("_CRS", crs));
+ aml_append(scope, dev);
+}
+
static Property xhci_sysbus_props[] = {
- DEFINE_PROP_UINT32("intrs", XHCISysbusState, xhci.numintrs, MAXINTRS),
- DEFINE_PROP_UINT32("slots", XHCISysbusState, xhci.numslots, MAXSLOTS),
+ DEFINE_PROP_UINT32("intrs", XHCISysbusState, xhci.numintrs, XHCI_MAXINTRS),
+ DEFINE_PROP_UINT32("slots", XHCISysbusState, xhci.numslots, XHCI_MAXSLOTS),
DEFINE_PROP_END_OF_LIST(),
};
diff --git a/hw/usb/hcd-xhci-sysbus.h b/hw/usb/hcd-xhci-sysbus.h
index a308753ceb..fdfcbbee3b 100644
--- a/hw/usb/hcd-xhci-sysbus.h
+++ b/hw/usb/hcd-xhci-sysbus.h
@@ -15,7 +15,6 @@
#include "hcd-xhci.h"
#include "hw/sysbus.h"
-#define TYPE_XHCI_SYSBUS "sysbus-xhci"
#define XHCI_SYSBUS(obj) \
OBJECT_CHECK(XHCISysbusState, (obj), TYPE_XHCI_SYSBUS)
diff --git a/hw/usb/hcd-xhci.c b/hw/usb/hcd-xhci.c
index 5e8bed9ef9..79ce5c4be6 100644
--- a/hw/usb/hcd-xhci.c
+++ b/hw/usb/hcd-xhci.c
@@ -46,15 +46,13 @@
#define TRANSFER_LIMIT 256
#define LEN_CAP 0x40
-#define LEN_OPER (0x400 + 0x10 * MAXPORTS)
-#define LEN_RUNTIME ((MAXINTRS + 1) * 0x20)
-#define LEN_DOORBELL ((MAXSLOTS + 1) * 0x20)
+#define LEN_OPER (0x400 + 0x10 * XHCI_MAXPORTS)
+#define LEN_RUNTIME ((XHCI_MAXINTRS + 1) * 0x20)
+#define LEN_DOORBELL ((XHCI_MAXSLOTS + 1) * 0x20)
#define OFF_OPER LEN_CAP
#define OFF_RUNTIME 0x1000
#define OFF_DOORBELL 0x2000
-/* must be power of 2 */
-#define LEN_REGS 0x4000
#if (OFF_OPER + LEN_OPER) > OFF_RUNTIME
#error Increase OFF_RUNTIME
@@ -62,8 +60,8 @@
#if (OFF_RUNTIME + LEN_RUNTIME) > OFF_DOORBELL
#error Increase OFF_DOORBELL
#endif
-#if (OFF_DOORBELL + LEN_DOORBELL) > LEN_REGS
-# error Increase LEN_REGS
+#if (OFF_DOORBELL + LEN_DOORBELL) > XHCI_LEN_REGS
+# error Increase XHCI_LEN_REGS
#endif
/* bit definitions */
@@ -3276,11 +3274,11 @@ static void usb_xhci_init(XHCIState *xhci)
xhci->usbsts = USBSTS_HCH;
- if (xhci->numports_2 > MAXPORTS_2) {
- xhci->numports_2 = MAXPORTS_2;
+ if (xhci->numports_2 > XHCI_MAXPORTS_2) {
+ xhci->numports_2 = XHCI_MAXPORTS_2;
}
- if (xhci->numports_3 > MAXPORTS_3) {
- xhci->numports_3 = MAXPORTS_3;
+ if (xhci->numports_3 > XHCI_MAXPORTS_3) {
+ xhci->numports_3 = XHCI_MAXPORTS_3;
}
usbports = MAX(xhci->numports_2, xhci->numports_3);
xhci->numports = xhci->numports_2 + xhci->numports_3;
@@ -3302,7 +3300,7 @@ static void usb_xhci_init(XHCIState *xhci)
USB_SPEED_MASK_LOW |
USB_SPEED_MASK_FULL |
USB_SPEED_MASK_HIGH;
- assert(i < MAXPORTS);
+ assert(i < XHCI_MAXPORTS);
snprintf(port->name, sizeof(port->name), "usb2 port #%d", i+1);
speedmask |= port->speedmask;
}
@@ -3316,7 +3314,7 @@ static void usb_xhci_init(XHCIState *xhci)
}
port->uport = &xhci->uports[i];
port->speedmask = USB_SPEED_MASK_SUPER;
- assert(i < MAXPORTS);
+ assert(i < XHCI_MAXPORTS);
snprintf(port->name, sizeof(port->name), "usb3 port #%d", i+1);
speedmask |= port->speedmask;
}
@@ -3331,8 +3329,8 @@ static void usb_xhci_realize(DeviceState *dev, Error **errp)
XHCIState *xhci = XHCI(dev);
- if (xhci->numintrs > MAXINTRS) {
- xhci->numintrs = MAXINTRS;
+ if (xhci->numintrs > XHCI_MAXINTRS) {
+ xhci->numintrs = XHCI_MAXINTRS;
}
while (xhci->numintrs & (xhci->numintrs - 1)) { /* ! power of 2 */
xhci->numintrs++;
@@ -3340,8 +3338,8 @@ static void usb_xhci_realize(DeviceState *dev, Error **errp)
if (xhci->numintrs < 1) {
xhci->numintrs = 1;
}
- if (xhci->numslots > MAXSLOTS) {
- xhci->numslots = MAXSLOTS;
+ if (xhci->numslots > XHCI_MAXSLOTS) {
+ xhci->numslots = XHCI_MAXSLOTS;
}
if (xhci->numslots < 1) {
xhci->numslots = 1;
@@ -3355,7 +3353,7 @@ static void usb_xhci_realize(DeviceState *dev, Error **errp)
usb_xhci_init(xhci);
xhci->mfwrap_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, xhci_mfwrap_timer, xhci);
- memory_region_init(&xhci->mem, OBJECT(dev), "xhci", LEN_REGS);
+ memory_region_init(&xhci->mem, OBJECT(dev), "xhci", XHCI_LEN_REGS);
memory_region_init_io(&xhci->mem_cap, OBJECT(dev), &xhci_cap_ops, xhci,
"capabilities", LEN_CAP);
memory_region_init_io(&xhci->mem_oper, OBJECT(dev), &xhci_oper_ops, xhci,
diff --git a/hw/usb/hcd-xhci.h b/hw/usb/hcd-xhci.h
index f859a17e73..ccf50ae28b 100644
--- a/hw/usb/hcd-xhci.h
+++ b/hw/usb/hcd-xhci.h
@@ -24,23 +24,13 @@
#include "qom/object.h"
#include "hw/usb.h"
+#include "hw/usb/xhci.h"
#include "sysemu/dma.h"
-#define TYPE_XHCI "base-xhci"
-#define TYPE_NEC_XHCI "nec-usb-xhci"
-#define TYPE_QEMU_XHCI "qemu-xhci"
-
OBJECT_DECLARE_SIMPLE_TYPE(XHCIState, XHCI)
-#define MAXPORTS_2 15
-#define MAXPORTS_3 15
-
-#define MAXPORTS (MAXPORTS_2 + MAXPORTS_3)
-#define MAXSLOTS 64
-#define MAXINTRS 16
-
/* Very pessimistic, let's hope it's enough for all cases */
-#define EV_QUEUE (((3 * 24) + 16) * MAXSLOTS)
+#define EV_QUEUE (((3 * 24) + 16) * XHCI_MAXSLOTS)
typedef struct XHCIStreamContext XHCIStreamContext;
typedef struct XHCIEPContext XHCIEPContext;
@@ -217,15 +207,15 @@ typedef struct XHCIState {
uint32_t dcbaap_high;
uint32_t config;
- USBPort uports[MAX_CONST(MAXPORTS_2, MAXPORTS_3)];
- XHCIPort ports[MAXPORTS];
- XHCISlot slots[MAXSLOTS];
+ USBPort uports[MAX_CONST(XHCI_MAXPORTS_2, XHCI_MAXPORTS_3)];
+ XHCIPort ports[XHCI_MAXPORTS];
+ XHCISlot slots[XHCI_MAXSLOTS];
uint32_t numports;
/* Runtime Registers */
int64_t mfindex_start;
QEMUTimer *mfwrap_timer;
- XHCIInterrupter intr[MAXINTRS];
+ XHCIInterrupter intr[XHCI_MAXINTRS];
XHCIRing cmd_ring;
diff --git a/include/hw/i386/microvm.h b/include/hw/i386/microvm.h
index 91b064575d..0fc2160077 100644
--- a/include/hw/i386/microvm.h
+++ b/include/hw/i386/microvm.h
@@ -41,7 +41,7 @@
* 7 | parallel |
* 8 | rtc | rtc (rtc=on)
* 9 | acpi | acpi (ged)
- * 10 | pci lnk |
+ * 10 | pci lnk | xhci (usb=on)
* 11 | pci lnk |
* 12 | ps2 | pcie
* 13 | fpu | pcie
@@ -60,6 +60,9 @@
#define GED_MMIO_BASE_REGS (GED_MMIO_BASE + 0x200)
#define GED_MMIO_IRQ 9
+#define MICROVM_XHCI_BASE 0xfe900000
+#define MICROVM_XHCI_IRQ 10
+
#define PCIE_MMIO_BASE 0xc0000000
#define PCIE_MMIO_SIZE 0x20000000
#define PCIE_ECAM_BASE 0xe0000000
diff --git a/include/hw/i386/x86.h b/include/hw/i386/x86.h
index d5dcf7a07f..bfa9cb2a25 100644
--- a/include/hw/i386/x86.h
+++ b/include/hw/i386/x86.h
@@ -58,6 +58,7 @@ struct X86MachineState {
/* CPU and apic information: */
bool apic_xrupt_override;
+ unsigned pci_irq_mask;
unsigned apic_id_limit;
uint16_t boot_cpus;
unsigned smp_dies;
@@ -114,6 +115,7 @@ bool x86_machine_is_acpi_enabled(const X86MachineState *x86ms);
/* Global System Interrupts */
#define GSI_NUM_PINS IOAPIC_NUM_PINS
+#define ACPI_BUILD_PCI_IRQS ((1<<5) | (1<<9) | (1<<10) | (1<<11))
typedef struct GSIState {
qemu_irq i8259_irq[ISA_NUM_IRQS];
diff --git a/include/hw/usb/xhci.h b/include/hw/usb/xhci.h
new file mode 100644
index 0000000000..5c90e1373e
--- /dev/null
+++ b/include/hw/usb/xhci.h
@@ -0,0 +1,21 @@
+#ifndef HW_USB_XHCI_H
+#define HW_USB_XHCI_H
+
+#define TYPE_XHCI "base-xhci"
+#define TYPE_NEC_XHCI "nec-usb-xhci"
+#define TYPE_QEMU_XHCI "qemu-xhci"
+#define TYPE_XHCI_SYSBUS "sysbus-xhci"
+
+#define XHCI_MAXPORTS_2 15
+#define XHCI_MAXPORTS_3 15
+
+#define XHCI_MAXPORTS (XHCI_MAXPORTS_2 + XHCI_MAXPORTS_3)
+#define XHCI_MAXSLOTS 64
+#define XHCI_MAXINTRS 16
+
+/* must be power of 2 */
+#define XHCI_LEN_REGS 0x4000
+
+void xhci_sysbus_build_aml(Aml *scope, uint32_t mmio, unsigned int irq);
+
+#endif
diff --git a/tests/data/acpi/microvm/APIC.pcie b/tests/data/acpi/microvm/APIC.pcie
new file mode 100644
index 0000000000..6c51081b50
--- /dev/null
+++ b/tests/data/acpi/microvm/APIC.pcie
Binary files differ
diff --git a/tests/data/acpi/microvm/DSDT.rtc b/tests/data/acpi/microvm/DSDT.rtc
new file mode 100644
index 0000000000..5960d6929a
--- /dev/null
+++ b/tests/data/acpi/microvm/DSDT.rtc
Binary files differ
diff --git a/tests/data/acpi/microvm/DSDT.usb b/tests/data/acpi/microvm/DSDT.usb
new file mode 100644
index 0000000000..14423381ea
--- /dev/null
+++ b/tests/data/acpi/microvm/DSDT.usb
Binary files differ
diff --git a/tests/qtest/bios-tables-test.c b/tests/qtest/bios-tables-test.c
index 5647624492..3830a40d10 100644
--- a/tests/qtest/bios-tables-test.c
+++ b/tests/qtest/bios-tables-test.c
@@ -1110,6 +1110,28 @@ static void test_acpi_microvm_tcg(void)
free_test_data(&data);
}
+static void test_acpi_microvm_usb_tcg(void)
+{
+ test_data data;
+
+ test_acpi_microvm_prepare(&data);
+ data.variant = ".usb";
+ test_acpi_one(" -machine microvm,acpi=on,usb=on,rtc=off",
+ &data);
+ free_test_data(&data);
+}
+
+static void test_acpi_microvm_rtc_tcg(void)
+{
+ test_data data;
+
+ test_acpi_microvm_prepare(&data);
+ data.variant = ".rtc";
+ test_acpi_one(" -machine microvm,acpi=on,rtc=on",
+ &data);
+ free_test_data(&data);
+}
+
static void test_acpi_microvm_pcie_tcg(void)
{
test_data data;
@@ -1246,6 +1268,8 @@ int main(int argc, char *argv[])
qtest_add_func("acpi/piix4/acpihmat", test_acpi_piix4_tcg_acpi_hmat);
qtest_add_func("acpi/q35/acpihmat", test_acpi_q35_tcg_acpi_hmat);
qtest_add_func("acpi/microvm", test_acpi_microvm_tcg);
+ qtest_add_func("acpi/microvm/usb", test_acpi_microvm_usb_tcg);
+ qtest_add_func("acpi/microvm/rtc", test_acpi_microvm_rtc_tcg);
if (strcmp(arch, "x86_64") == 0) {
qtest_add_func("acpi/microvm/pcie", test_acpi_microvm_pcie_tcg);
}