@@ -40,7 +40,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 |
* 13 | fpu |
@@ -59,6 +59,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
+
/* Machine type options */
#define MICROVM_MACHINE_PIT "pit"
#define MICROVM_MACHINE_PIC "pic"
@@ -87,6 +87,25 @@ static void acpi_dsdt_add_virtio(Aml *scope,
}
}
+static void acpi_dsdt_add_xhci(Aml *scope, MicrovmMachineState *mms)
+{
+ if (!machine_usb(MACHINE(mms))) {
+ return;
+ }
+
+ Aml *dev = aml_device("XHCI");
+ aml_append(dev, aml_name_decl("_HID", aml_eisaid("PNP0D10")));
+
+ uint32_t irq = MICROVM_XHCI_IRQ;
+ Aml *crs = aml_resource_template();
+ aml_append(crs, aml_memory32_fixed(MICROVM_XHCI_BASE, 0x4000,
+ 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("_CRS", crs));
+ aml_append(scope, dev);
+}
+
static void
build_dsdt_microvm(GArray *table_data, BIOSLinker *linker,
MicrovmMachineState *mms)
@@ -112,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);
aml_append(dsdt, sb_scope);
/* ACPI 5.0: Table 7-209 System State Package */
@@ -147,6 +147,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("sysbus-xhci");
+ qdev_prop_set_uint32(dev, "intrs", 1);
+ qdev_prop_set_uint32(dev, "slots", 64); /* 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 (mms->pic == ON_OFF_AUTO_ON || mms->pic == ON_OFF_AUTO_AUTO) {
qemu_irq *i8259;
Wire up "usb=on" machine option. When enabled add a sysbus xhci controller with 8 ports. Declare it in the ACPI DSDT table so the guest OS finds it. Signed-off-by: Gerd Hoffmann <kraxel@redhat.com> --- include/hw/i386/microvm.h | 5 ++++- hw/i386/acpi-microvm.c | 20 ++++++++++++++++++++ hw/i386/microvm.c | 12 ++++++++++++ 3 files changed, 36 insertions(+), 1 deletion(-)