pci.c (f74e78220dbfec557922eb6e8ec0a78d08743e02) pci.c (a82fe82916432091ca6fcbd7f357cccf35f6e80d)
1/*
2 * Support for generating PCI related ACPI tables and passing them to Guests
3 *
4 * Copyright (C) 2006 Fabrice Bellard
5 * Copyright (C) 2008-2010 Kevin O'Connor <kevin@koconnor.net>
6 * Copyright (C) 2013-2019 Red Hat Inc
7 * Copyright (C) 2019 Intel Corporation
8 *

--- 16 unchanged lines hidden (view full) ---

25
26#include "qemu/osdep.h"
27#include "qemu/error-report.h"
28#include "qom/object_interfaces.h"
29#include "qapi/error.h"
30#include "hw/boards.h"
31#include "hw/acpi/aml-build.h"
32#include "hw/acpi/pci.h"
1/*
2 * Support for generating PCI related ACPI tables and passing them to Guests
3 *
4 * Copyright (C) 2006 Fabrice Bellard
5 * Copyright (C) 2008-2010 Kevin O'Connor <kevin@koconnor.net>
6 * Copyright (C) 2013-2019 Red Hat Inc
7 * Copyright (C) 2019 Intel Corporation
8 *

--- 16 unchanged lines hidden (view full) ---

25
26#include "qemu/osdep.h"
27#include "qemu/error-report.h"
28#include "qom/object_interfaces.h"
29#include "qapi/error.h"
30#include "hw/boards.h"
31#include "hw/acpi/aml-build.h"
32#include "hw/acpi/pci.h"
33#include "hw/pci/pci_bridge.h"
33#include "hw/pci/pci_device.h"
34#include "hw/pci/pcie_host.h"
35
36/*
37 * PCI Firmware Specification, Revision 3.0
38 * 4.1.2 MCFG Table Description.
39 */
40void build_mcfg(GArray *table_data, BIOSLinker *linker, AcpiMcfgInfo *info,

--- 131 unchanged lines hidden (view full) ---

172 /* devfn is constrained in PCI to be 8 bit but storage is an int32_t */
173 assert(devfn >= 0 && devfn < PCI_DEVFN_MAX);
174
175 build_srat_pci_generic_initiator(table_data, gi->node, 0, bus, devfn);
176
177 return 0;
178}
179
34#include "hw/pci/pci_device.h"
35#include "hw/pci/pcie_host.h"
36
37/*
38 * PCI Firmware Specification, Revision 3.0
39 * 4.1.2 MCFG Table Description.
40 */
41void build_mcfg(GArray *table_data, BIOSLinker *linker, AcpiMcfgInfo *info,

--- 131 unchanged lines hidden (view full) ---

173 /* devfn is constrained in PCI to be 8 bit but storage is an int32_t */
174 assert(devfn >= 0 && devfn < PCI_DEVFN_MAX);
175
176 build_srat_pci_generic_initiator(table_data, gi->node, 0, bus, devfn);
177
178 return 0;
179}
180
180void build_srat_generic_pci_initiator(GArray *table_data)
181typedef struct AcpiGenericPort {
182 /* private */
183 Object parent;
184
185 /* public */
186 char *pci_bus;
187 uint32_t node;
188} AcpiGenericPort;
189
190typedef struct AcpiGenericPortClass {
191 ObjectClass parent_class;
192} AcpiGenericPortClass;
193
194#define TYPE_ACPI_GENERIC_PORT "acpi-generic-port"
195
196OBJECT_DEFINE_TYPE_WITH_INTERFACES(AcpiGenericPort, acpi_generic_port,
197 ACPI_GENERIC_PORT, OBJECT,
198 { TYPE_USER_CREATABLE },
199 { NULL })
200
201OBJECT_DECLARE_SIMPLE_TYPE(AcpiGenericPort, ACPI_GENERIC_PORT)
202
203static void acpi_generic_port_init(Object *obj)
181{
204{
205 AcpiGenericPort *gp = ACPI_GENERIC_PORT(obj);
206
207 gp->node = MAX_NODES;
208 gp->pci_bus = NULL;
209}
210
211static void acpi_generic_port_finalize(Object *obj)
212{
213 AcpiGenericPort *gp = ACPI_GENERIC_PORT(obj);
214
215 g_free(gp->pci_bus);
216}
217
218static void acpi_generic_port_set_pci_bus(Object *obj, const char *val,
219 Error **errp)
220{
221 AcpiGenericPort *gp = ACPI_GENERIC_PORT(obj);
222
223 gp->pci_bus = g_strdup(val);
224}
225
226static void acpi_generic_port_set_node(Object *obj, Visitor *v,
227 const char *name, void *opaque,
228 Error **errp)
229{
230 AcpiGenericPort *gp = ACPI_GENERIC_PORT(obj);
231 uint32_t value;
232
233 if (!visit_type_uint32(v, name, &value, errp)) {
234 return;
235 }
236
237 if (value >= MAX_NODES) {
238 error_printf("%s: Invalid NUMA node specified\n",
239 TYPE_ACPI_GENERIC_INITIATOR);
240 exit(1);
241 }
242
243 gp->node = value;
244}
245
246static void acpi_generic_port_class_init(ObjectClass *oc, void *data)
247{
248 object_class_property_add_str(oc, "pci-bus", NULL,
249 acpi_generic_port_set_pci_bus);
250 object_class_property_set_description(oc, "pci-bus",
251 "PCI Bus of the host bridge associated with this GP affinity structure");
252 object_class_property_add(oc, "node", "int", NULL,
253 acpi_generic_port_set_node, NULL, NULL);
254 object_class_property_set_description(oc, "node",
255 "The NUMA node like ID to index HMAT/SLIT NUMA properties involving GP");
256}
257
258static int build_acpi_generic_port(Object *obj, void *opaque)
259{
260 MachineState *ms = MACHINE(qdev_get_machine());
261 const char *hid = "ACPI0016";
262 GArray *table_data = opaque;
263 AcpiGenericPort *gp;
264 uint32_t uid;
265 Object *o;
266
267 if (!object_dynamic_cast(obj, TYPE_ACPI_GENERIC_PORT)) {
268 return 0;
269 }
270
271 gp = ACPI_GENERIC_PORT(obj);
272
273 if (gp->node >= ms->numa_state->num_nodes) {
274 error_printf("%s: node %d is invalid.\n",
275 TYPE_ACPI_GENERIC_PORT, gp->node);
276 exit(1);
277 }
278
279 o = object_resolve_path_type(gp->pci_bus, TYPE_PXB_CXL_BUS, NULL);
280 if (!o) {
281 error_printf("%s: device must be a CXL host bridge.\n",
282 TYPE_ACPI_GENERIC_PORT);
283 exit(1);
284 }
285
286 uid = object_property_get_uint(o, "acpi_uid", &error_fatal);
287 build_srat_acpi_generic_port(table_data, gp->node, hid, uid);
288
289 return 0;
290}
291
292void build_srat_generic_affinity_structures(GArray *table_data)
293{
182 object_child_foreach_recursive(object_get_root(),
183 build_acpi_generic_initiator,
184 table_data);
294 object_child_foreach_recursive(object_get_root(),
295 build_acpi_generic_initiator,
296 table_data);
297 object_child_foreach_recursive(object_get_root(), build_acpi_generic_port,
298 table_data);
185}
299}