Skip to content

Commit

Permalink
x86: pci: acpi: consolidate PCI slots creation
Browse files Browse the repository at this point in the history
No functional changes nor AML bytecode changes.
Consolidate code that generates empty and populated slot
descriptors. Besides eliminating duplication,
it helps consolidate conditions for generating
parts of Device{} desriptor in one place, which makes
code more compact and easier to read.

Signed-off-by: Igor Mammedov <imammedo@redhat.com>
Message-Id: <20220701133515.137890-18-imammedo@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
  • Loading branch information
Igor Mammedov authored and mstsirkin committed Oct 9, 2022
1 parent 1ccd222 commit 3216ab2
Showing 1 changed file with 54 additions and 57 deletions.
111 changes: 54 additions & 57 deletions hw/i386/acpi-build.c
Expand Up @@ -427,60 +427,53 @@ static void build_append_pci_bus_devices(Aml *parent_scope, PCIBus *bus,
int func = PCI_FUNC(devfn);
/* ACPI spec: 1.0b: Table 6-2 _ADR Object Bus Types, PCI type */
int adr = slot << 16 | func;
bool hotplug_enabled_dev;
bool bridge_in_acpi;
bool cold_plugged_bridge;
bool hotpluggbale_slot = false;
bool bridge_in_acpi = false;
bool cold_plugged_bridge = false;
bool is_vga = false;

if (pdev) {
pc = PCI_DEVICE_GET_CLASS(pdev);
dc = DEVICE_GET_CLASS(pdev);

if (pc->class_id == PCI_CLASS_BRIDGE_ISA) {
continue;
}

is_vga = pc->class_id == PCI_CLASS_DISPLAY_VGA;

if (!pdev) {
/*
* add hotplug slots for non present devices.
* Cold plugged bridges aren't themselves hot-pluggable.
* Hotplugged bridges *are* hot-pluggable.
*/
cold_plugged_bridge = pc->is_bridge && !DEVICE(pdev)->hotplugged;
bridge_in_acpi = cold_plugged_bridge && pcihp_bridge_en;

hotpluggbale_slot = bsel && dc->hotpluggable &&
!cold_plugged_bridge;

/*
* allow describing coldplugged bridges in ACPI even if they are not
* on function 0, as they are not unpluggable, for all other devices
* generate description only for function 0 per slot
*/
if (func && !bridge_in_acpi) {
continue;
}
} else {
/*
* hotplug is supported only for non-multifunction device
* so generate device description only for function 0
*/
if (bsel && !func) {
if (pci_bus_is_express(bus) && slot > 0) {
break;
}
dev = aml_device("S%.02X", devfn);
aml_append(dev, aml_name_decl("_ADR", aml_int(adr)));
aml_append(dev, aml_name_decl("ASUN", aml_int(slot)));
aml_append(dev, aml_pci_device_dsm());
aml_append(dev, aml_name_decl("_SUN", aml_int(slot)));
method = aml_method("_EJ0", 1, AML_NOTSERIALIZED);
aml_append(method,
aml_call2("PCEJ", aml_name("BSEL"), aml_name("_SUN"))
);
aml_append(dev, method);
aml_append(parent_scope, dev);

build_append_pcihp_notify_entry(notify_method, slot);
/* mark it as empty hotpluggable slot */
hotpluggbale_slot = true;
} else {
continue;
}
continue;
}

pc = PCI_DEVICE_GET_CLASS(pdev);
dc = DEVICE_GET_CLASS(pdev);

/*
* Cold plugged bridges aren't themselves hot-pluggable.
* Hotplugged bridges *are* hot-pluggable.
*/
cold_plugged_bridge = pc->is_bridge && !DEVICE(pdev)->hotplugged;
bridge_in_acpi = cold_plugged_bridge && pcihp_bridge_en;

hotplug_enabled_dev = bsel && dc->hotpluggable && !cold_plugged_bridge;

if (pc->class_id == PCI_CLASS_BRIDGE_ISA) {
continue;
}

/*
* allow describing coldplugged bridges in ACPI even if they are not
* on function 0, as they are not unpluggable, for all other devices
* generate description only for function 0 per slot
*/
if (func && !bridge_in_acpi) {
continue;
}

/* start to compose PCI device descriptor */
Expand All @@ -496,7 +489,7 @@ static void build_append_pci_bus_devices(Aml *parent_scope, PCIBus *bus,
aml_append(dev, aml_pci_device_dsm());
}

if (pc->class_id == PCI_CLASS_DISPLAY_VGA) {
if (is_vga) {
/* add VGA specific AML methods */
int s3d;

Expand All @@ -517,19 +510,10 @@ static void build_append_pci_bus_devices(Aml *parent_scope, PCIBus *bus,
method = aml_method("_S3D", 0, AML_NOTSERIALIZED);
aml_append(method, aml_return(aml_int(s3d)));
aml_append(dev, method);
} else if (hotplug_enabled_dev) {
aml_append(dev, aml_name_decl("_SUN", aml_int(slot)));
/* add _EJ0 to make slot hotpluggable */
method = aml_method("_EJ0", 1, AML_NOTSERIALIZED);
aml_append(method,
aml_call2("PCEJ", aml_name("BSEL"), aml_name("_SUN"))
);
aml_append(dev, method);
}

if (bsel) {
build_append_pcihp_notify_entry(notify_method, slot);
}
} else if (bridge_in_acpi) {
bridge_in_acpi = cold_plugged_bridge && pcihp_bridge_en;
if (bridge_in_acpi) {
/*
* device is coldplugged bridge,
* add child device descriptions into its scope
Expand All @@ -538,6 +522,19 @@ static void build_append_pci_bus_devices(Aml *parent_scope, PCIBus *bus,

build_append_pci_bus_devices(dev, sec_bus, pcihp_bridge_en);
}

if (hotpluggbale_slot) {
aml_append(dev, aml_name_decl("_SUN", aml_int(slot)));
/* add _EJ0 to make slot hotpluggable */
method = aml_method("_EJ0", 1, AML_NOTSERIALIZED);
aml_append(method,
aml_call2("PCEJ", aml_name("BSEL"), aml_name("_SUN"))
);
aml_append(dev, method);

build_append_pcihp_notify_entry(notify_method, slot);
}

/* device descriptor has been composed, add it into parent context */
aml_append(parent_scope, dev);
}
Expand Down

0 comments on commit 3216ab2

Please sign in to comment.