1 /*
2 * QEMU ACPI PCI bridge
3 *
4 * Copyright (c) 2023 Red Hat, Inc.
5 *
6 * Author:
7 * Igor Mammedov <imammedo@redhat.com>
8 *
9 * SPDX-License-Identifier: GPL-2.0-or-later
10 *
11 * This work is licensed under the terms of the GNU GPL, version 2 or later.
12 * See the COPYING file in the top-level directory.
13 */
14
15 #include "qemu/osdep.h"
16 #include "hw/acpi/pci.h"
17 #include "hw/pci/pci_bridge.h"
18 #include "hw/acpi/pcihp.h"
19
build_pci_bridge_aml(AcpiDevAmlIf * adev,Aml * scope)20 void build_pci_bridge_aml(AcpiDevAmlIf *adev, Aml *scope)
21 {
22 PCIBridge *br = PCI_BRIDGE(adev);
23
24 if (!DEVICE(br)->hotplugged) {
25 PCIBus *sec_bus = pci_bridge_get_sec_bus(br);
26
27 build_append_pci_bus_devices(scope, sec_bus);
28
29 /*
30 * generate hotplug slots descriptors if
31 * bridge has ACPI PCI hotplug attached,
32 */
33 if (object_property_find(OBJECT(sec_bus), ACPI_PCIHP_PROP_BSEL)) {
34 build_append_pcihp_slots(scope, sec_bus);
35 }
36 }
37 }
38
build_pci_bridge_edsm(void)39 Aml *build_pci_bridge_edsm(void)
40 {
41 Aml *method, *ifctx;
42 Aml *zero = aml_int(0);
43 Aml *func = aml_arg(2);
44 Aml *ret = aml_local(0);
45 Aml *aidx = aml_local(1);
46 Aml *params = aml_arg(4);
47
48 method = aml_method("EDSM", 5, AML_SERIALIZED);
49
50 /* get supported functions */
51 ifctx = aml_if(aml_equal(func, zero));
52 {
53 /* 1: have supported functions */
54 /* 7: support for function 7 */
55 const uint8_t caps = 1 | BIT(7);
56 build_append_pci_dsm_func0_common(ifctx, ret);
57 aml_append(ifctx, aml_store(aml_int(caps), aml_index(ret, zero)));
58 aml_append(ifctx, aml_return(ret));
59 }
60 aml_append(method, ifctx);
61
62 /* handle specific functions requests */
63 /*
64 * PCI Firmware Specification 3.1
65 * 4.6.7. _DSM for Naming a PCI or PCI Express Device Under
66 * Operating Systems
67 */
68 ifctx = aml_if(aml_equal(func, aml_int(7)));
69 {
70 Aml *pkg = aml_package(2);
71 aml_append(pkg, zero);
72 /* optional, if not impl. should return null string */
73 aml_append(pkg, aml_string("%s", ""));
74 aml_append(ifctx, aml_store(pkg, ret));
75
76 /*
77 * IASL is fine when initializing Package with computational data,
78 * however it makes guest unhappy /it fails to process such AML/.
79 * So use runtime assignment to set acpi-index after initializer
80 * to make OSPM happy.
81 */
82 aml_append(ifctx,
83 aml_store(aml_derefof(aml_index(params, aml_int(0))), aidx));
84 aml_append(ifctx, aml_store(aidx, aml_index(ret, zero)));
85 aml_append(ifctx, aml_return(ret));
86 }
87 aml_append(method, ifctx);
88
89 return method;
90 }
91
92