master
c 98 lines 2.74 KB
Raw
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
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 Error *local_err = NULL;
27 uint32_t bsel;
28
29 build_append_pci_bus_devices(scope, sec_bus);
30
31 /*
32 * generate hotplug slots descriptors if
33 * bridge has ACPI PCI hotplug attached,
34 */
35 bsel = object_property_get_uint(OBJECT(sec_bus), ACPI_PCIHP_PROP_BSEL,
36 &local_err);
37
38 if (local_err == NULL && bsel != UINT32_MAX) {
39 build_append_pcihp_slots(scope, sec_bus);
40 }
41
42 error_free(local_err);
43 }
44 }
45
46 Aml *build_pci_bridge_edsm(void)
47 {
48 Aml *method, *ifctx;
49 Aml *zero = aml_int(0);
50 Aml *func = aml_arg(2);
51 Aml *ret = aml_local(0);
52 Aml *aidx = aml_local(1);
53 Aml *params = aml_arg(4);
54
55 method = aml_method("EDSM", 5, AML_SERIALIZED);
56
57 /* get supported functions */
58 ifctx = aml_if(aml_equal(func, zero));
59 {
60 /* 1: have supported functions */
61 /* 7: support for function 7 */
62 const uint8_t caps = 1 | BIT(7);
63 build_append_pci_dsm_func0_common(ifctx, ret);
64 aml_append(ifctx, aml_store(aml_int(caps), aml_index(ret, zero)));
65 aml_append(ifctx, aml_return(ret));
66 }
67 aml_append(method, ifctx);
68
69 /* handle specific functions requests */
70 /*
71 * PCI Firmware Specification 3.1
72 * 4.6.7. _DSM for Naming a PCI or PCI Express Device Under
73 * Operating Systems
74 */
75 ifctx = aml_if(aml_equal(func, aml_int(7)));
76 {
77 Aml *pkg = aml_package(2);
78 aml_append(pkg, zero);
79 /* optional, if not impl. should return null string */
80 aml_append(pkg, aml_string("%s", ""));
81 aml_append(ifctx, aml_store(pkg, ret));
82
83 /*
84 * IASL is fine when initializing Package with computational data,
85 * however it makes guest unhappy /it fails to process such AML/.
86 * So use runtime assignment to set acpi-index after initializer
87 * to make OSPM happy.
88 */
89 aml_append(ifctx,
90 aml_store(aml_derefof(aml_index(params, aml_int(0))), aidx));
91 aml_append(ifctx, aml_store(aidx, aml_index(ret, zero)));
92 aml_append(ifctx, aml_return(ret));
93 }
94 aml_append(method, ifctx);
95
96 return method;
97 }
98