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 <[email protected]> --- include/hw/i386/microvm.h | 5 ++++- hw/i386/acpi-microvm.c | 20 ++++++++++++++++++++ hw/i386/microvm.c | 12 ++++++++++++ 3 files changed, 36 insertions(+), 1 deletion(-) diff --git a/include/hw/i386/microvm.h b/include/hw/i386/microvm.h index 27eadd6c535c..e255e787b6d5 100644 --- a/include/hw/i386/microvm.h +++ b/include/hw/i386/microvm.h @@ -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" diff --git a/hw/i386/acpi-microvm.c b/hw/i386/acpi-microvm.c index df39c5d3bd90..a2b6c4478f3b 100644 --- a/hw/i386/acpi-microvm.c +++ b/hw/i386/acpi-microvm.c @@ -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 */ diff --git a/hw/i386/microvm.c b/hw/i386/microvm.c index 60d32722301f..592dc51ce7bf 100644 --- a/hw/i386/microvm.c +++ b/hw/i386/microvm.c @@ -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; -- 2.27.0
