From 3711add393127a2d22a157a46c5588140bb33be4 Mon Sep 17 00:00:00 2001 From: lzw_29107 <2910729822@qq.com> Date: Tue, 10 Sep 2024 23:02:09 +0800 Subject: [PATCH] Make xHCI optional --- docs/system/arm/virt.rst | 3 +++ hw/arm/virt-acpi-build.c | 24 +++++++++++++++++++- hw/arm/virt.c | 49 ++++++++++++++++++++++++++++++++++------ include/hw/arm/virt.h | 6 ++--- include/hw/usb/xhci.h | 2 +- 5 files changed, 71 insertions(+), 13 deletions(-) diff --git a/docs/system/arm/virt.rst b/docs/system/arm/virt.rst index 2c8d32eff889..0fa3ec7258df 100644 --- a/docs/system/arm/virt.rst +++ b/docs/system/arm/virt.rst @@ -190,6 +190,9 @@ pci madt Set ``on``/``off`` to enable/disable ACPI MADT (Multiple APIC Description Table). The default is ``on`` +madt + Set ``on``/``off`` to use xHCI as the USB host controller instead of EHCI. The default is ``off`` + force_el3 Set ``on``/``off`` to enable/disable EL3 without secure. The default is ``off`` diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c index 44dae3c3ba36..9cdeacab43ae 100644 --- a/hw/arm/virt-acpi-build.c +++ b/hw/arm/virt-acpi-build.c @@ -121,6 +121,24 @@ static void acpi_dsdt_add_flash(Aml *scope, const MemMapEntry *flash_memmap) aml_append(scope, dev); } +static void acpi_dsdt_add_ehci(Aml *scope, const MemMapEntry *ehci_memmap, + uint32_t ehci_irq) +{ + Aml *dev = aml_device("USB0"); + aml_append(dev, aml_name_decl("_HID", aml_string("PNP0D20"))); + aml_append(dev, aml_name_decl("_UID", aml_int(0))); + + Aml *crs = aml_resource_template(); + aml_append(crs, + aml_memory32_fixed(ehci_memmap->base, + ehci_memmap->size, AML_READ_WRITE)); + aml_append(crs, + aml_interrupt(AML_CONSUMER, AML_LEVEL, AML_ACTIVE_HIGH, + AML_EXCLUSIVE, &ehci_irq, 1)); + aml_append(dev, aml_name_decl("_CRS", crs)); + aml_append(scope, dev); +} + static void acpi_dsdt_add_xhci(Aml *scope, const MemMapEntry *xhci_memmap, uint32_t xhci_irq) { @@ -921,7 +939,11 @@ build_dsdt(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms) if (vms->pci) { acpi_dsdt_add_pci(scope, memmap, irqmap[VIRT_PCIE] + ARM_SPI_BASE, vms); } - acpi_dsdt_add_xhci(scope, &memmap[VIRT_XHCI], irqmap[VIRT_XHCI] + ARM_SPI_BASE); + if (vms->xhci) { + acpi_dsdt_add_xhci(scope, &memmap[VIRT_EHCI_XHCI], irqmap[VIRT_EHCI_XHCI] + ARM_SPI_BASE); + } else { + acpi_dsdt_add_ehci(scope, &memmap[VIRT_EHCI_XHCI], irqmap[VIRT_EHCI_XHCI] + ARM_SPI_BASE); + } acpi_dsdt_add_mmci(scope, &memmap[VIRT_SDHCI], irqmap[VIRT_SDHCI] + ARM_SPI_BASE); if (vms->acpi_dev) { build_ged_aml(scope, "\\_SB."GED_DEVICE, diff --git a/hw/arm/virt.c b/hw/arm/virt.c index 8e5d9d3b7323..67467636cace 100644 --- a/hw/arm/virt.c +++ b/hw/arm/virt.c @@ -182,7 +182,7 @@ static const MemMapEntry base_memmap[] = { [VIRT_NVDIMM_ACPI] = { 0x09090000, NVDIMM_ACPI_IO_LEN}, [VIRT_PVTIME] = { 0x090a0000, 0x00010000 }, [VIRT_SECURE_GPIO] = { 0x090b0000, 0x00001000 }, - [VIRT_XHCI] = { 0x090c0000, XHCI_LEN_REGS }, + [VIRT_EHCI_XHCI] = { 0x090c0000, XHCI_LEN_REGS }, [VIRT_SDHCI] = { 0x090d0000, 0x00010000 }, [VIRT_MMIO] = { 0x0a000000, 0x00000200 }, /* ...repeating for a total of NUM_VIRTIO_TRANSPORTS, each of that size */ @@ -226,7 +226,7 @@ static const int a15irqmap[] = { [VIRT_GPIO] = 7, [VIRT_UART1] = 8, [VIRT_ACPI_GED] = 9, - [VIRT_XHCI] = 11, + [VIRT_EHCI_XHCI] = 11, [VIRT_SDHCI] = 12, [VIRT_MMIO] = 16, /* ...to 16 + NUM_VIRTIO_TRANSPORTS - 1 */ [VIRT_GIC_V2M] = 48, /* ...to 48 + NUM_GICV2M_SPIS - 1 */ @@ -1426,10 +1426,19 @@ static void sdhci_attach_drive(DeviceState *sdhci, DriveInfo *dinfo, bool emmc) &error_fatal); } +static void create_ehci(const VirtMachineState *vms) +{ + hwaddr base = vms->memmap[VIRT_EHCI_XHCI].base; + int irq = vms->irqmap[VIRT_EHCI_XHCI]; + + sysbus_create_simple("platform-ehci-usb", base, + qdev_get_gpio_in(vms->gic, irq)); +} + static void create_xhci(const VirtMachineState *vms) { - hwaddr base = vms->memmap[VIRT_XHCI].base; - int irq = vms->irqmap[VIRT_XHCI]; + hwaddr base = vms->memmap[VIRT_EHCI_XHCI].base; + int irq = vms->irqmap[VIRT_EHCI_XHCI]; DeviceState *dev = qdev_new(TYPE_XHCI_SYSBUS); qdev_prop_set_uint32(dev, "slots", XHCI_MAXSLOTS); @@ -2460,8 +2469,12 @@ static void machvirt_init(MachineState *machine) */ create_virtio_devices(vms); - /* Create platform XHCI controller device */ - create_xhci(vms); + /* Create platform EHCI/XHCI controller device */ + if (vms->xhci) { + create_xhci(vms); + } else { + create_ehci(vms); + } /* Create platform SD host controller device */ create_sdhci(vms); @@ -2830,6 +2843,20 @@ static void virt_set_madt(Object *obj, bool value, Error **errp) vms->madt = value; } +static bool virt_get_xhci(Object *obj, Error **errp) +{ + VirtMachineState *vms = VIRT_MACHINE(obj); + + return vms->xhci; +} + +static void virt_set_xhci(Object *obj, bool value, Error **errp) +{ + VirtMachineState *vms = VIRT_MACHINE(obj); + + vms->xhci = value; +} + static bool virt_get_force_el3(Object *obj, Error **errp) { VirtMachineState *vms = VIRT_MACHINE(obj); @@ -3355,7 +3382,14 @@ static void virt_machine_class_init(ObjectClass *oc, void *data) "Enable ACPI MADT (Multiple APIC Description Table)"); - object_class_property_add_bool(oc, "force-el3", + object_class_property_add_bool(oc, "xhci", + virt_get_xhci, + virt_set_xhci); + object_class_property_set_description(oc, "xhci", + "Use xHCI as the USB host controller instead of EHCI"); + + + object_class_property_add_bool(oc, "force-el3", virt_get_force_el3, virt_set_force_el3); object_class_property_set_description(oc, "force-el3", @@ -3429,6 +3463,7 @@ static void virt_instance_init(Object *obj) vms->pci = true; vms->madt = true; + vms->xhci = false; vms->force_el3 = false; vms->force_psci = false; } diff --git a/include/hw/arm/virt.h b/include/hw/arm/virt.h index f8be90a6f37c..8163663ead4e 100644 --- a/include/hw/arm/virt.h +++ b/include/hw/arm/virt.h @@ -63,7 +63,7 @@ enum { VIRT_GIC_REDIST, VIRT_SMMU, VIRT_UART0, - VIRT_XHCI, + VIRT_EHCI_XHCI, VIRT_SDHCI, VIRT_MMIO, VIRT_RTC, @@ -160,6 +160,7 @@ struct VirtMachineState { bool second_ns_uart_present; bool pci; bool madt; + bool xhci; bool force_el3; bool force_psci; OnOffAuto acpi; @@ -193,9 +194,6 @@ struct VirtMachineState { #define VIRT_SDHCI_CAPABILITIES 0x180028073ff8ffbf -#undef XHCI_LEN_REGS -#define XHCI_LEN_REGS 0x10000 - #define TYPE_VIRT_MACHINE MACHINE_TYPE_NAME("virt") OBJECT_DECLARE_TYPE(VirtMachineState, VirtMachineClass, VIRT_MACHINE) diff --git a/include/hw/usb/xhci.h b/include/hw/usb/xhci.h index 5c90e1373e55..249d1b1f785d 100644 --- a/include/hw/usb/xhci.h +++ b/include/hw/usb/xhci.h @@ -14,7 +14,7 @@ #define XHCI_MAXINTRS 16 /* must be power of 2 */ -#define XHCI_LEN_REGS 0x4000 +#define XHCI_LEN_REGS 0x10000 void xhci_sysbus_build_aml(Aml *scope, uint32_t mmio, unsigned int irq);