blob: 394a9194799969276285ef178ec66ef970a11725 [file] [log] [blame]
/*
* QEMU ACPI PCI bridge
*
* Copyright (c) 2023 Red Hat, Inc.
*
* Author:
* Igor Mammedov <imammedo@redhat.com>
*
* 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;
}