1 /*
2 * PCI Expander Bridge Device Emulation
3 *
4 * Copyright (C) 2015 Red Hat Inc
5 *
6 * Authors:
7 * Marcel Apfelbaum <marcel@redhat.com>
8 *
9 * This work is licensed under the terms of the GNU GPL, version 2 or later.
10 * See the COPYING file in the top-level directory.
11 */
12
13 #include "qemu/osdep.h"
14 #include "qapi/error.h"
15 #include "hw/pci/pci.h"
16 #include "hw/pci/pci_bus.h"
17 #include "hw/pci/pci_host.h"
18 #include "hw/pci/pcie_port.h"
19 #include "hw/qdev-properties.h"
20 #include "hw/pci/pci_bridge.h"
21 #include "hw/pci-bridge/pci_expander_bridge.h"
22 #include "hw/cxl/cxl.h"
23 #include "qemu/range.h"
24 #include "qemu/error-report.h"
25 #include "qemu/module.h"
26 #include "sysemu/numa.h"
27 #include "hw/boards.h"
28 #include "qom/object.h"
29
30 enum BusType { PCI, PCIE, CXL };
31
32 #define TYPE_PXB_BUS "pxb-bus"
33 typedef struct PXBBus PXBBus;
34 DECLARE_INSTANCE_CHECKER(PXBBus, PXB_BUS,
35 TYPE_PXB_BUS)
36
37 #define TYPE_PXB_PCIE_BUS "pxb-pcie-bus"
38 DECLARE_INSTANCE_CHECKER(PXBBus, PXB_PCIE_BUS,
39 TYPE_PXB_PCIE_BUS)
40
41 DECLARE_INSTANCE_CHECKER(PXBBus, PXB_CXL_BUS,
42 TYPE_PXB_CXL_BUS)
43
44 struct PXBBus {
45 /*< private >*/
46 PCIBus parent_obj;
47 /*< public >*/
48
49 char bus_path[8];
50 };
51
52 #define TYPE_PXB_PCIE_DEV "pxb-pcie"
OBJECT_DECLARE_SIMPLE_TYPE(PXBPCIEDev,PXB_PCIE_DEV)53 OBJECT_DECLARE_SIMPLE_TYPE(PXBPCIEDev, PXB_PCIE_DEV)
54
55 static GList *pxb_dev_list;
56
57 #define TYPE_PXB_HOST "pxb-host"
58
59 CXLComponentState *cxl_get_hb_cstate(PCIHostState *hb)
60 {
61 CXLHost *host = PXB_CXL_HOST(hb);
62
63 return &host->cxl_cstate;
64 }
65
cxl_get_hb_passthrough(PCIHostState * hb)66 bool cxl_get_hb_passthrough(PCIHostState *hb)
67 {
68 CXLHost *host = PXB_CXL_HOST(hb);
69
70 return host->passthrough;
71 }
72
pxb_bus_num(PCIBus * bus)73 static int pxb_bus_num(PCIBus *bus)
74 {
75 PXBDev *pxb = PXB_DEV(bus->parent_dev);
76
77 return pxb->bus_nr;
78 }
79
pxb_bus_numa_node(PCIBus * bus)80 static uint16_t pxb_bus_numa_node(PCIBus *bus)
81 {
82 PXBDev *pxb = PXB_DEV(bus->parent_dev);
83
84 return pxb->numa_node;
85 }
86
prop_pxb_uid_get(Object * obj,Visitor * v,const char * name,void * opaque,Error ** errp)87 static void prop_pxb_uid_get(Object *obj, Visitor *v, const char *name,
88 void *opaque, Error **errp)
89 {
90 uint32_t uid = pci_bus_num(PCI_BUS(obj));
91
92 visit_type_uint32(v, name, &uid, errp);
93 }
94
pxb_bus_class_init(ObjectClass * class,void * data)95 static void pxb_bus_class_init(ObjectClass *class, void *data)
96 {
97 PCIBusClass *pbc = PCI_BUS_CLASS(class);
98
99 pbc->bus_num = pxb_bus_num;
100 pbc->numa_node = pxb_bus_numa_node;
101
102 object_class_property_add(class, "acpi_uid", "uint32",
103 prop_pxb_uid_get, NULL, NULL, NULL);
104 object_class_property_set_description(class, "acpi_uid",
105 "ACPI Unique ID used to distinguish this PCI Host Bridge / ACPI00016");
106 }
107
108 static const TypeInfo pxb_bus_info = {
109 .name = TYPE_PXB_BUS,
110 .parent = TYPE_PCI_BUS,
111 .instance_size = sizeof(PXBBus),
112 .class_init = pxb_bus_class_init,
113 };
114
115 static const TypeInfo pxb_pcie_bus_info = {
116 .name = TYPE_PXB_PCIE_BUS,
117 .parent = TYPE_PCIE_BUS,
118 .instance_size = sizeof(PXBBus),
119 .class_init = pxb_bus_class_init,
120 };
121
122 static const TypeInfo pxb_cxl_bus_info = {
123 .name = TYPE_PXB_CXL_BUS,
124 .parent = TYPE_CXL_BUS,
125 .instance_size = sizeof(PXBBus),
126 .class_init = pxb_bus_class_init,
127 };
128
pxb_host_root_bus_path(PCIHostState * host_bridge,PCIBus * rootbus)129 static const char *pxb_host_root_bus_path(PCIHostState *host_bridge,
130 PCIBus *rootbus)
131 {
132 PXBBus *bus = pci_bus_is_cxl(rootbus) ?
133 PXB_CXL_BUS(rootbus) :
134 pci_bus_is_express(rootbus) ? PXB_PCIE_BUS(rootbus) :
135 PXB_BUS(rootbus);
136
137 snprintf(bus->bus_path, 8, "0000:%02x", pxb_bus_num(rootbus));
138 return bus->bus_path;
139 }
140
pxb_host_ofw_unit_address(const SysBusDevice * dev)141 static char *pxb_host_ofw_unit_address(const SysBusDevice *dev)
142 {
143 const PCIHostState *pxb_host;
144 const PCIBus *pxb_bus;
145 const PXBDev *pxb_dev;
146 int position;
147 const DeviceState *pxb_dev_base;
148 const PCIHostState *main_host;
149 const SysBusDevice *main_host_sbd;
150
151 pxb_host = PCI_HOST_BRIDGE(dev);
152 pxb_bus = pxb_host->bus;
153 pxb_dev = PXB_DEV(pxb_bus->parent_dev);
154 position = g_list_index(pxb_dev_list, pxb_dev);
155 assert(position >= 0);
156
157 pxb_dev_base = DEVICE(pxb_dev);
158 main_host = PCI_HOST_BRIDGE(pxb_dev_base->parent_bus->parent);
159 main_host_sbd = SYS_BUS_DEVICE(main_host);
160
161 if (main_host_sbd->num_mmio > 0) {
162 return g_strdup_printf(HWADDR_FMT_plx ",%x",
163 main_host_sbd->mmio[0].addr, position + 1);
164 }
165 if (main_host_sbd->num_pio > 0) {
166 return g_strdup_printf("i%04x,%x",
167 main_host_sbd->pio[0], position + 1);
168 }
169 return NULL;
170 }
171
pxb_host_class_init(ObjectClass * class,void * data)172 static void pxb_host_class_init(ObjectClass *class, void *data)
173 {
174 DeviceClass *dc = DEVICE_CLASS(class);
175 SysBusDeviceClass *sbc = SYS_BUS_DEVICE_CLASS(class);
176 PCIHostBridgeClass *hc = PCI_HOST_BRIDGE_CLASS(class);
177
178 dc->fw_name = "pci";
179 /* Reason: Internal part of the pxb/pxb-pcie device, not usable by itself */
180 dc->user_creatable = false;
181 sbc->explicit_ofw_unit_address = pxb_host_ofw_unit_address;
182 hc->root_bus_path = pxb_host_root_bus_path;
183 }
184
185 static const TypeInfo pxb_host_info = {
186 .name = TYPE_PXB_HOST,
187 .parent = TYPE_PCI_HOST_BRIDGE,
188 .class_init = pxb_host_class_init,
189 };
190
pxb_cxl_realize(DeviceState * dev,Error ** errp)191 static void pxb_cxl_realize(DeviceState *dev, Error **errp)
192 {
193 SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
194 CXLHost *cxl = PXB_CXL_HOST(dev);
195 CXLComponentState *cxl_cstate = &cxl->cxl_cstate;
196 struct MemoryRegion *mr = &cxl_cstate->crb.component_registers;
197
198 cxl_component_register_block_init(OBJECT(dev), cxl_cstate,
199 TYPE_PXB_CXL_HOST);
200 sysbus_init_mmio(sbd, mr);
201 }
202
203 /*
204 * Host bridge realization has no means of knowning state associated
205 * with a particular machine. As such, it is nececssary to delay
206 * final setup of the host bridge register space until later in the
207 * machine bring up.
208 */
pxb_cxl_hook_up_registers(CXLState * cxl_state,PCIBus * bus,Error ** errp)209 void pxb_cxl_hook_up_registers(CXLState *cxl_state, PCIBus *bus, Error **errp)
210 {
211 PXBCXLDev *pxb = PXB_CXL_DEV(pci_bridge_get_device(bus));
212 CXLHost *cxl = pxb->cxl_host_bridge;
213 CXLComponentState *cxl_cstate = &cxl->cxl_cstate;
214 struct MemoryRegion *mr = &cxl_cstate->crb.component_registers;
215 hwaddr offset;
216
217 offset = memory_region_size(mr) * cxl_state->next_mr_idx;
218 if (offset > memory_region_size(&cxl_state->host_mr)) {
219 error_setg(errp, "Insufficient space for pxb cxl host register space");
220 return;
221 }
222
223 memory_region_add_subregion(&cxl_state->host_mr, offset, mr);
224 cxl_state->next_mr_idx++;
225 }
226
pxb_cxl_host_class_init(ObjectClass * class,void * data)227 static void pxb_cxl_host_class_init(ObjectClass *class, void *data)
228 {
229 DeviceClass *dc = DEVICE_CLASS(class);
230 PCIHostBridgeClass *hc = PCI_HOST_BRIDGE_CLASS(class);
231
232 hc->root_bus_path = pxb_host_root_bus_path;
233 dc->fw_name = "cxl";
234 dc->realize = pxb_cxl_realize;
235 /* Reason: Internal part of the pxb/pxb-pcie device, not usable by itself */
236 dc->user_creatable = false;
237 }
238
239 /*
240 * This is a device to handle the MMIO for a CXL host bridge. It does nothing
241 * else.
242 */
243 static const TypeInfo cxl_host_info = {
244 .name = TYPE_PXB_CXL_HOST,
245 .parent = TYPE_PCI_HOST_BRIDGE,
246 .instance_size = sizeof(CXLHost),
247 .class_init = pxb_cxl_host_class_init,
248 };
249
250 /*
251 * Registers the PXB bus as a child of pci host root bus.
252 */
pxb_register_bus(PCIDevice * dev,PCIBus * pxb_bus,Error ** errp)253 static void pxb_register_bus(PCIDevice *dev, PCIBus *pxb_bus, Error **errp)
254 {
255 PCIBus *bus = pci_get_bus(dev);
256 int pxb_bus_num = pci_bus_num(pxb_bus);
257
258 if (bus->parent_dev) {
259 error_setg(errp, "PXB devices can be attached only to root bus");
260 return;
261 }
262
263 QLIST_FOREACH(bus, &bus->child, sibling) {
264 if (pci_bus_num(bus) == pxb_bus_num) {
265 error_setg(errp, "Bus %d is already in use", pxb_bus_num);
266 return;
267 }
268 }
269 QLIST_INSERT_HEAD(&pci_get_bus(dev)->child, pxb_bus, sibling);
270 }
271
pxb_map_irq_fn(PCIDevice * pci_dev,int pin)272 static int pxb_map_irq_fn(PCIDevice *pci_dev, int pin)
273 {
274 PCIDevice *pxb = pci_get_bus(pci_dev)->parent_dev;
275
276 /*
277 * First carry out normal swizzle to handle
278 * multiple root ports on a pxb instance.
279 */
280 pin = pci_swizzle_map_irq_fn(pci_dev, pin);
281
282 /*
283 * The bios does not index the pxb slot number when
284 * it computes the IRQ because it resides on bus 0
285 * and not on the current bus.
286 * However QEMU routes the irq through bus 0 and adds
287 * the pxb slot to the IRQ computation of the PXB
288 * device.
289 *
290 * Synchronize between bios and QEMU by canceling
291 * pxb's effect.
292 */
293 return pin - PCI_SLOT(pxb->devfn);
294 }
295
pxb_cxl_dev_reset(DeviceState * dev)296 static void pxb_cxl_dev_reset(DeviceState *dev)
297 {
298 CXLHost *cxl = PXB_CXL_DEV(dev)->cxl_host_bridge;
299 CXLComponentState *cxl_cstate = &cxl->cxl_cstate;
300 PCIHostState *hb = PCI_HOST_BRIDGE(cxl);
301 uint32_t *reg_state = cxl_cstate->crb.cache_mem_registers;
302 uint32_t *write_msk = cxl_cstate->crb.cache_mem_regs_write_mask;
303 int dsp_count = 0;
304
305 cxl_component_register_init_common(reg_state, write_msk, CXL2_RC);
306 /*
307 * The CXL specification allows for host bridges with no HDM decoders
308 * if they only have a single root port.
309 */
310 if (!PXB_CXL_DEV(dev)->hdm_for_passthrough) {
311 dsp_count = pcie_count_ds_ports(hb->bus);
312 }
313 /* Initial reset will have 0 dsp so wait until > 0 */
314 if (dsp_count == 1) {
315 cxl->passthrough = true;
316 /* Set Capability ID in header to NONE */
317 ARRAY_FIELD_DP32(reg_state, CXL_HDM_CAPABILITY_HEADER, ID, 0);
318 } else {
319 ARRAY_FIELD_DP32(reg_state, CXL_HDM_DECODER_CAPABILITY, TARGET_COUNT,
320 8);
321 }
322 }
323
pxb_compare(gconstpointer a,gconstpointer b)324 static gint pxb_compare(gconstpointer a, gconstpointer b)
325 {
326 const PXBDev *pxb_a = a, *pxb_b = b;
327
328 return pxb_a->bus_nr < pxb_b->bus_nr ? -1 :
329 pxb_a->bus_nr > pxb_b->bus_nr ? 1 :
330 0;
331 }
332
pxb_dev_realize_common(PCIDevice * dev,enum BusType type,Error ** errp)333 static bool pxb_dev_realize_common(PCIDevice *dev, enum BusType type,
334 Error **errp)
335 {
336 PXBDev *pxb = PXB_DEV(dev);
337 DeviceState *ds, *bds = NULL;
338 PCIBus *bus;
339 const char *dev_name = NULL;
340 Error *local_err = NULL;
341 MachineState *ms = MACHINE(qdev_get_machine());
342
343 if (ms->numa_state == NULL) {
344 error_setg(errp, "NUMA is not supported by this machine-type");
345 return false;
346 }
347
348 if (pxb->numa_node != NUMA_NODE_UNASSIGNED &&
349 pxb->numa_node >= ms->numa_state->num_nodes) {
350 error_setg(errp, "Illegal numa node %d", pxb->numa_node);
351 return false;
352 }
353
354 if (dev->qdev.id && *dev->qdev.id) {
355 dev_name = dev->qdev.id;
356 }
357
358 ds = qdev_new(type == CXL ? TYPE_PXB_CXL_HOST : TYPE_PXB_HOST);
359 if (type == PCIE) {
360 bus = pci_root_bus_new(ds, dev_name, NULL, NULL, 0, TYPE_PXB_PCIE_BUS);
361 } else if (type == CXL) {
362 bus = pci_root_bus_new(ds, dev_name, NULL, NULL, 0, TYPE_PXB_CXL_BUS);
363 bus->flags |= PCI_BUS_CXL;
364 PXB_CXL_DEV(dev)->cxl_host_bridge = PXB_CXL_HOST(ds);
365 } else {
366 bus = pci_root_bus_new(ds, "pxb-internal", NULL, NULL, 0, TYPE_PXB_BUS);
367 bds = qdev_new("pci-bridge");
368 bds->id = g_strdup(dev_name);
369 qdev_prop_set_uint8(bds, PCI_BRIDGE_DEV_PROP_CHASSIS_NR, pxb->bus_nr);
370 qdev_prop_set_bit(bds, PCI_BRIDGE_DEV_PROP_SHPC, false);
371 }
372
373 bus->parent_dev = dev;
374 bus->address_space_mem = pci_get_bus(dev)->address_space_mem;
375 bus->address_space_io = pci_get_bus(dev)->address_space_io;
376 bus->map_irq = pxb_map_irq_fn;
377
378 PCI_HOST_BRIDGE(ds)->bus = bus;
379 PCI_HOST_BRIDGE(ds)->bypass_iommu = pxb->bypass_iommu;
380
381 pxb_register_bus(dev, bus, &local_err);
382 if (local_err) {
383 error_propagate(errp, local_err);
384 goto err_register_bus;
385 }
386
387 sysbus_realize_and_unref(SYS_BUS_DEVICE(ds), &error_fatal);
388 if (bds) {
389 qdev_realize_and_unref(bds, &bus->qbus, &error_fatal);
390 }
391
392 pci_word_test_and_set_mask(dev->config + PCI_STATUS,
393 PCI_STATUS_66MHZ | PCI_STATUS_FAST_BACK);
394 pci_config_set_class(dev->config, PCI_CLASS_BRIDGE_HOST);
395
396 pxb_dev_list = g_list_insert_sorted(pxb_dev_list, pxb, pxb_compare);
397 return true;
398
399 err_register_bus:
400 object_unref(OBJECT(bds));
401 object_unparent(OBJECT(bus));
402 object_unref(OBJECT(ds));
403 return false;
404 }
405
pxb_dev_realize(PCIDevice * dev,Error ** errp)406 static void pxb_dev_realize(PCIDevice *dev, Error **errp)
407 {
408 if (pci_bus_is_express(pci_get_bus(dev))) {
409 error_setg(errp, "pxb devices cannot reside on a PCIe bus");
410 return;
411 }
412
413 pxb_dev_realize_common(dev, PCI, errp);
414 }
415
pxb_dev_exitfn(PCIDevice * pci_dev)416 static void pxb_dev_exitfn(PCIDevice *pci_dev)
417 {
418 PXBDev *pxb = PXB_DEV(pci_dev);
419
420 pxb_dev_list = g_list_remove(pxb_dev_list, pxb);
421 }
422
423 static Property pxb_dev_properties[] = {
424 /* Note: 0 is not a legal PXB bus number. */
425 DEFINE_PROP_UINT8("bus_nr", PXBDev, bus_nr, 0),
426 DEFINE_PROP_UINT16("numa_node", PXBDev, numa_node, NUMA_NODE_UNASSIGNED),
427 DEFINE_PROP_BOOL("bypass_iommu", PXBDev, bypass_iommu, false),
428 DEFINE_PROP_END_OF_LIST(),
429 };
430
pxb_dev_class_init(ObjectClass * klass,void * data)431 static void pxb_dev_class_init(ObjectClass *klass, void *data)
432 {
433 DeviceClass *dc = DEVICE_CLASS(klass);
434 PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
435
436 k->realize = pxb_dev_realize;
437 k->exit = pxb_dev_exitfn;
438 k->vendor_id = PCI_VENDOR_ID_REDHAT;
439 k->device_id = PCI_DEVICE_ID_REDHAT_PXB;
440 k->class_id = PCI_CLASS_BRIDGE_HOST;
441
442 dc->desc = "PCI Expander Bridge";
443 device_class_set_props(dc, pxb_dev_properties);
444 dc->hotpluggable = false;
445 set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories);
446 }
447
448 static const TypeInfo pxb_dev_info = {
449 .name = TYPE_PXB_DEV,
450 .parent = TYPE_PCI_DEVICE,
451 .instance_size = sizeof(PXBDev),
452 .class_init = pxb_dev_class_init,
453 .interfaces = (InterfaceInfo[]) {
454 { INTERFACE_CONVENTIONAL_PCI_DEVICE },
455 { },
456 },
457 };
458
pxb_pcie_dev_realize(PCIDevice * dev,Error ** errp)459 static void pxb_pcie_dev_realize(PCIDevice *dev, Error **errp)
460 {
461 if (!pci_bus_is_express(pci_get_bus(dev))) {
462 error_setg(errp, "pxb-pcie devices cannot reside on a PCI bus");
463 return;
464 }
465
466 pxb_dev_realize_common(dev, PCIE, errp);
467 }
468
pxb_pcie_dev_class_init(ObjectClass * klass,void * data)469 static void pxb_pcie_dev_class_init(ObjectClass *klass, void *data)
470 {
471 DeviceClass *dc = DEVICE_CLASS(klass);
472 PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
473
474 k->realize = pxb_pcie_dev_realize;
475 k->exit = pxb_dev_exitfn;
476 k->vendor_id = PCI_VENDOR_ID_REDHAT;
477 k->device_id = PCI_DEVICE_ID_REDHAT_PXB_PCIE;
478 k->class_id = PCI_CLASS_BRIDGE_HOST;
479
480 dc->desc = "PCI Express Expander Bridge";
481 dc->hotpluggable = false;
482 set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories);
483 }
484
485 static const TypeInfo pxb_pcie_dev_info = {
486 .name = TYPE_PXB_PCIE_DEV,
487 .parent = TYPE_PXB_DEV,
488 .instance_size = sizeof(PXBPCIEDev),
489 .class_init = pxb_pcie_dev_class_init,
490 .interfaces = (InterfaceInfo[]) {
491 { INTERFACE_CONVENTIONAL_PCI_DEVICE },
492 { },
493 },
494 };
495
pxb_cxl_dev_realize(PCIDevice * dev,Error ** errp)496 static void pxb_cxl_dev_realize(PCIDevice *dev, Error **errp)
497 {
498 /* A CXL PXB's parent bus is still PCIe */
499 if (!pci_bus_is_express(pci_get_bus(dev))) {
500 error_setg(errp, "pxb-cxl devices cannot reside on a PCI bus");
501 return;
502 }
503
504 if (!pxb_dev_realize_common(dev, CXL, errp)) {
505 return;
506 }
507 pxb_cxl_dev_reset(DEVICE(dev));
508 }
509
510 static Property pxb_cxl_dev_properties[] = {
511 DEFINE_PROP_BOOL("hdm_for_passthrough", PXBCXLDev, hdm_for_passthrough, false),
512 DEFINE_PROP_END_OF_LIST(),
513 };
514
pxb_cxl_dev_class_init(ObjectClass * klass,void * data)515 static void pxb_cxl_dev_class_init(ObjectClass *klass, void *data)
516 {
517 DeviceClass *dc = DEVICE_CLASS(klass);
518 PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
519
520 k->realize = pxb_cxl_dev_realize;
521 k->exit = pxb_dev_exitfn;
522 /*
523 * XXX: These types of bridges don't actually show up in the hierarchy so
524 * vendor, device, class, etc. ids are intentionally left out.
525 */
526
527 dc->desc = "CXL Host Bridge";
528 device_class_set_props(dc, pxb_cxl_dev_properties);
529 set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories);
530
531 /* Host bridges aren't hotpluggable. FIXME: spec reference */
532 dc->hotpluggable = false;
533 device_class_set_legacy_reset(dc, pxb_cxl_dev_reset);
534 }
535
536 static const TypeInfo pxb_cxl_dev_info = {
537 .name = TYPE_PXB_CXL_DEV,
538 .parent = TYPE_PXB_PCIE_DEV,
539 .instance_size = sizeof(PXBCXLDev),
540 .class_init = pxb_cxl_dev_class_init,
541 .interfaces =
542 (InterfaceInfo[]){
543 { INTERFACE_CONVENTIONAL_PCI_DEVICE },
544 {},
545 },
546 };
547
pxb_register_types(void)548 static void pxb_register_types(void)
549 {
550 type_register_static(&pxb_bus_info);
551 type_register_static(&pxb_pcie_bus_info);
552 type_register_static(&pxb_cxl_bus_info);
553 type_register_static(&pxb_host_info);
554 type_register_static(&cxl_host_info);
555 type_register_static(&pxb_dev_info);
556 type_register_static(&pxb_pcie_dev_info);
557 type_register_static(&pxb_cxl_dev_info);
558 }
559
560 type_init(pxb_register_types)
561