/* * QEMU ACPI PCI bridge * * Copyright (c) 2023 Red Hat, Inc. * * Author: * Igor Mammedov * * SPDX-License-Identifier: GPL-2.0-or-later * * This work is licensed under the terms of the GNU GPL, version 2 or later. * See the COPYING file in the top-level directory. */ #include "qemu/osdep.h" #include "hw/acpi/pci.h" #include "hw/pci/pci_bridge.h" #include "hw/acpi/pcihp.h" void build_pci_bridge_aml(AcpiDevAmlIf *adev, Aml *scope) { PCIBridge *br = PCI_BRIDGE(adev); if (!DEVICE(br)->hotplugged) { PCIBus *sec_bus = pci_bridge_get_sec_bus(br); build_append_pci_bus_devices(scope, sec_bus); /* * generate hotplug slots descriptors if * bridge has ACPI PCI hotplug attached, */ if (object_property_find(OBJECT(sec_bus), ACPI_PCIHP_PROP_BSEL)) { build_append_pcihp_slots(scope, sec_bus); } } } Aml *build_pci_bridge_edsm(void) { Aml *method, *ifctx; Aml *zero = aml_int(0); Aml *func = aml_arg(2); Aml *ret = aml_local(0); Aml *aidx = aml_local(1); Aml *params = aml_arg(4); method = aml_method("EDSM", 5, AML_SERIALIZED); /* get supported functions */ ifctx = aml_if(aml_equal(func, zero)); { /* 1: have supported functions */ /* 7: support for function 7 */ const uint8_t caps = 1 | BIT(7); build_append_pci_dsm_func0_common(ifctx, ret); aml_append(ifctx, aml_store(aml_int(caps), aml_index(ret, zero))); aml_append(ifctx, aml_return(ret)); } aml_append(method, ifctx); /* handle specific functions requests */ /* * PCI Firmware Specification 3.1 * 4.6.7. _DSM for Naming a PCI or PCI Express Device Under * Operating Systems */ ifctx = aml_if(aml_equal(func, aml_int(7))); { Aml *pkg = aml_package(2); aml_append(pkg, zero); /* optional, if not impl. should return null string */ aml_append(pkg, aml_string("%s", "")); aml_append(ifctx, aml_store(pkg, ret)); /* * IASL is fine when initializing Package with computational data, * however it makes guest unhappy /it fails to process such AML/. * So use runtime assignment to set acpi-index after initializer * to make OSPM happy. */ aml_append(ifctx, aml_store(aml_derefof(aml_index(params, aml_int(0))), aidx)); aml_append(ifctx, aml_store(aidx, aml_index(ret, zero))); aml_append(ifctx, aml_return(ret)); } aml_append(method, ifctx); return method; }