2
0

pci_expander_bridge.c 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375
  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. #include "qemu/osdep.h"
  13. #include "qapi/error.h"
  14. #include "hw/pci/pci.h"
  15. #include "hw/pci/pci_bus.h"
  16. #include "hw/pci/pci_host.h"
  17. #include "hw/qdev-properties.h"
  18. #include "hw/pci/pci_bridge.h"
  19. #include "qemu/range.h"
  20. #include "qemu/error-report.h"
  21. #include "qemu/module.h"
  22. #include "sysemu/numa.h"
  23. #include "hw/boards.h"
  24. #define TYPE_PXB_BUS "pxb-bus"
  25. #define PXB_BUS(obj) OBJECT_CHECK(PXBBus, (obj), TYPE_PXB_BUS)
  26. #define TYPE_PXB_PCIE_BUS "pxb-pcie-bus"
  27. #define PXB_PCIE_BUS(obj) OBJECT_CHECK(PXBBus, (obj), TYPE_PXB_PCIE_BUS)
  28. typedef struct PXBBus {
  29. /*< private >*/
  30. PCIBus parent_obj;
  31. /*< public >*/
  32. char bus_path[8];
  33. } PXBBus;
  34. #define TYPE_PXB_DEVICE "pxb"
  35. #define PXB_DEV(obj) OBJECT_CHECK(PXBDev, (obj), TYPE_PXB_DEVICE)
  36. #define TYPE_PXB_PCIE_DEVICE "pxb-pcie"
  37. #define PXB_PCIE_DEV(obj) OBJECT_CHECK(PXBDev, (obj), TYPE_PXB_PCIE_DEVICE)
  38. typedef struct PXBDev {
  39. /*< private >*/
  40. PCIDevice parent_obj;
  41. /*< public >*/
  42. uint8_t bus_nr;
  43. uint16_t numa_node;
  44. } PXBDev;
  45. static PXBDev *convert_to_pxb(PCIDevice *dev)
  46. {
  47. return pci_bus_is_express(pci_get_bus(dev))
  48. ? PXB_PCIE_DEV(dev) : PXB_DEV(dev);
  49. }
  50. static GList *pxb_dev_list;
  51. #define TYPE_PXB_HOST "pxb-host"
  52. static int pxb_bus_num(PCIBus *bus)
  53. {
  54. PXBDev *pxb = convert_to_pxb(bus->parent_dev);
  55. return pxb->bus_nr;
  56. }
  57. static uint16_t pxb_bus_numa_node(PCIBus *bus)
  58. {
  59. PXBDev *pxb = convert_to_pxb(bus->parent_dev);
  60. return pxb->numa_node;
  61. }
  62. static void pxb_bus_class_init(ObjectClass *class, void *data)
  63. {
  64. PCIBusClass *pbc = PCI_BUS_CLASS(class);
  65. pbc->bus_num = pxb_bus_num;
  66. pbc->numa_node = pxb_bus_numa_node;
  67. }
  68. static const TypeInfo pxb_bus_info = {
  69. .name = TYPE_PXB_BUS,
  70. .parent = TYPE_PCI_BUS,
  71. .instance_size = sizeof(PXBBus),
  72. .class_init = pxb_bus_class_init,
  73. };
  74. static const TypeInfo pxb_pcie_bus_info = {
  75. .name = TYPE_PXB_PCIE_BUS,
  76. .parent = TYPE_PCIE_BUS,
  77. .instance_size = sizeof(PXBBus),
  78. .class_init = pxb_bus_class_init,
  79. };
  80. static const char *pxb_host_root_bus_path(PCIHostState *host_bridge,
  81. PCIBus *rootbus)
  82. {
  83. PXBBus *bus = pci_bus_is_express(rootbus) ?
  84. PXB_PCIE_BUS(rootbus) : PXB_BUS(rootbus);
  85. snprintf(bus->bus_path, 8, "0000:%02x", pxb_bus_num(rootbus));
  86. return bus->bus_path;
  87. }
  88. static char *pxb_host_ofw_unit_address(const SysBusDevice *dev)
  89. {
  90. const PCIHostState *pxb_host;
  91. const PCIBus *pxb_bus;
  92. const PXBDev *pxb_dev;
  93. int position;
  94. const DeviceState *pxb_dev_base;
  95. const PCIHostState *main_host;
  96. const SysBusDevice *main_host_sbd;
  97. pxb_host = PCI_HOST_BRIDGE(dev);
  98. pxb_bus = pxb_host->bus;
  99. pxb_dev = convert_to_pxb(pxb_bus->parent_dev);
  100. position = g_list_index(pxb_dev_list, pxb_dev);
  101. assert(position >= 0);
  102. pxb_dev_base = DEVICE(pxb_dev);
  103. main_host = PCI_HOST_BRIDGE(pxb_dev_base->parent_bus->parent);
  104. main_host_sbd = SYS_BUS_DEVICE(main_host);
  105. if (main_host_sbd->num_mmio > 0) {
  106. return g_strdup_printf(TARGET_FMT_plx ",%x",
  107. main_host_sbd->mmio[0].addr, position + 1);
  108. }
  109. if (main_host_sbd->num_pio > 0) {
  110. return g_strdup_printf("i%04x,%x",
  111. main_host_sbd->pio[0], position + 1);
  112. }
  113. return NULL;
  114. }
  115. static void pxb_host_class_init(ObjectClass *class, void *data)
  116. {
  117. DeviceClass *dc = DEVICE_CLASS(class);
  118. SysBusDeviceClass *sbc = SYS_BUS_DEVICE_CLASS(class);
  119. PCIHostBridgeClass *hc = PCI_HOST_BRIDGE_CLASS(class);
  120. dc->fw_name = "pci";
  121. /* Reason: Internal part of the pxb/pxb-pcie device, not usable by itself */
  122. dc->user_creatable = false;
  123. sbc->explicit_ofw_unit_address = pxb_host_ofw_unit_address;
  124. hc->root_bus_path = pxb_host_root_bus_path;
  125. }
  126. static const TypeInfo pxb_host_info = {
  127. .name = TYPE_PXB_HOST,
  128. .parent = TYPE_PCI_HOST_BRIDGE,
  129. .class_init = pxb_host_class_init,
  130. };
  131. /*
  132. * Registers the PXB bus as a child of pci host root bus.
  133. */
  134. static void pxb_register_bus(PCIDevice *dev, PCIBus *pxb_bus, Error **errp)
  135. {
  136. PCIBus *bus = pci_get_bus(dev);
  137. int pxb_bus_num = pci_bus_num(pxb_bus);
  138. if (bus->parent_dev) {
  139. error_setg(errp, "PXB devices can be attached only to root bus");
  140. return;
  141. }
  142. QLIST_FOREACH(bus, &bus->child, sibling) {
  143. if (pci_bus_num(bus) == pxb_bus_num) {
  144. error_setg(errp, "Bus %d is already in use", pxb_bus_num);
  145. return;
  146. }
  147. }
  148. QLIST_INSERT_HEAD(&pci_get_bus(dev)->child, pxb_bus, sibling);
  149. }
  150. static int pxb_map_irq_fn(PCIDevice *pci_dev, int pin)
  151. {
  152. PCIDevice *pxb = pci_get_bus(pci_dev)->parent_dev;
  153. /*
  154. * The bios does not index the pxb slot number when
  155. * it computes the IRQ because it resides on bus 0
  156. * and not on the current bus.
  157. * However QEMU routes the irq through bus 0 and adds
  158. * the pxb slot to the IRQ computation of the PXB
  159. * device.
  160. *
  161. * Synchronize between bios and QEMU by canceling
  162. * pxb's effect.
  163. */
  164. return pin - PCI_SLOT(pxb->devfn);
  165. }
  166. static gint pxb_compare(gconstpointer a, gconstpointer b)
  167. {
  168. const PXBDev *pxb_a = a, *pxb_b = b;
  169. return pxb_a->bus_nr < pxb_b->bus_nr ? -1 :
  170. pxb_a->bus_nr > pxb_b->bus_nr ? 1 :
  171. 0;
  172. }
  173. static void pxb_dev_realize_common(PCIDevice *dev, bool pcie, Error **errp)
  174. {
  175. PXBDev *pxb = convert_to_pxb(dev);
  176. DeviceState *ds, *bds = NULL;
  177. PCIBus *bus;
  178. const char *dev_name = NULL;
  179. Error *local_err = NULL;
  180. MachineState *ms = MACHINE(qdev_get_machine());
  181. if (ms->numa_state == NULL) {
  182. error_setg(errp, "NUMA is not supported by this machine-type");
  183. return;
  184. }
  185. if (pxb->numa_node != NUMA_NODE_UNASSIGNED &&
  186. pxb->numa_node >= ms->numa_state->num_nodes) {
  187. error_setg(errp, "Illegal numa node %d", pxb->numa_node);
  188. return;
  189. }
  190. if (dev->qdev.id && *dev->qdev.id) {
  191. dev_name = dev->qdev.id;
  192. }
  193. ds = qdev_create(NULL, TYPE_PXB_HOST);
  194. if (pcie) {
  195. bus = pci_root_bus_new(ds, dev_name, NULL, NULL, 0, TYPE_PXB_PCIE_BUS);
  196. } else {
  197. bus = pci_root_bus_new(ds, "pxb-internal", NULL, NULL, 0, TYPE_PXB_BUS);
  198. bds = qdev_create(BUS(bus), "pci-bridge");
  199. bds->id = dev_name;
  200. qdev_prop_set_uint8(bds, PCI_BRIDGE_DEV_PROP_CHASSIS_NR, pxb->bus_nr);
  201. qdev_prop_set_bit(bds, PCI_BRIDGE_DEV_PROP_SHPC, false);
  202. }
  203. bus->parent_dev = dev;
  204. bus->address_space_mem = pci_get_bus(dev)->address_space_mem;
  205. bus->address_space_io = pci_get_bus(dev)->address_space_io;
  206. bus->map_irq = pxb_map_irq_fn;
  207. PCI_HOST_BRIDGE(ds)->bus = bus;
  208. pxb_register_bus(dev, bus, &local_err);
  209. if (local_err) {
  210. error_propagate(errp, local_err);
  211. goto err_register_bus;
  212. }
  213. qdev_init_nofail(ds);
  214. if (bds) {
  215. qdev_init_nofail(bds);
  216. }
  217. pci_word_test_and_set_mask(dev->config + PCI_STATUS,
  218. PCI_STATUS_66MHZ | PCI_STATUS_FAST_BACK);
  219. pci_config_set_class(dev->config, PCI_CLASS_BRIDGE_HOST);
  220. pxb_dev_list = g_list_insert_sorted(pxb_dev_list, pxb, pxb_compare);
  221. return;
  222. err_register_bus:
  223. object_unref(OBJECT(bds));
  224. object_unparent(OBJECT(bus));
  225. object_unref(OBJECT(ds));
  226. }
  227. static void pxb_dev_realize(PCIDevice *dev, Error **errp)
  228. {
  229. if (pci_bus_is_express(pci_get_bus(dev))) {
  230. error_setg(errp, "pxb devices cannot reside on a PCIe bus");
  231. return;
  232. }
  233. pxb_dev_realize_common(dev, false, errp);
  234. }
  235. static void pxb_dev_exitfn(PCIDevice *pci_dev)
  236. {
  237. PXBDev *pxb = convert_to_pxb(pci_dev);
  238. pxb_dev_list = g_list_remove(pxb_dev_list, pxb);
  239. }
  240. static Property pxb_dev_properties[] = {
  241. /* Note: 0 is not a legal PXB bus number. */
  242. DEFINE_PROP_UINT8("bus_nr", PXBDev, bus_nr, 0),
  243. DEFINE_PROP_UINT16("numa_node", PXBDev, numa_node, NUMA_NODE_UNASSIGNED),
  244. DEFINE_PROP_END_OF_LIST(),
  245. };
  246. static void pxb_dev_class_init(ObjectClass *klass, void *data)
  247. {
  248. DeviceClass *dc = DEVICE_CLASS(klass);
  249. PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
  250. k->realize = pxb_dev_realize;
  251. k->exit = pxb_dev_exitfn;
  252. k->vendor_id = PCI_VENDOR_ID_REDHAT;
  253. k->device_id = PCI_DEVICE_ID_REDHAT_PXB;
  254. k->class_id = PCI_CLASS_BRIDGE_HOST;
  255. dc->desc = "PCI Expander Bridge";
  256. dc->props = pxb_dev_properties;
  257. dc->hotpluggable = false;
  258. set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories);
  259. }
  260. static const TypeInfo pxb_dev_info = {
  261. .name = TYPE_PXB_DEVICE,
  262. .parent = TYPE_PCI_DEVICE,
  263. .instance_size = sizeof(PXBDev),
  264. .class_init = pxb_dev_class_init,
  265. .interfaces = (InterfaceInfo[]) {
  266. { INTERFACE_CONVENTIONAL_PCI_DEVICE },
  267. { },
  268. },
  269. };
  270. static void pxb_pcie_dev_realize(PCIDevice *dev, Error **errp)
  271. {
  272. if (!pci_bus_is_express(pci_get_bus(dev))) {
  273. error_setg(errp, "pxb-pcie devices cannot reside on a PCI bus");
  274. return;
  275. }
  276. pxb_dev_realize_common(dev, true, errp);
  277. }
  278. static void pxb_pcie_dev_class_init(ObjectClass *klass, void *data)
  279. {
  280. DeviceClass *dc = DEVICE_CLASS(klass);
  281. PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
  282. k->realize = pxb_pcie_dev_realize;
  283. k->exit = pxb_dev_exitfn;
  284. k->vendor_id = PCI_VENDOR_ID_REDHAT;
  285. k->device_id = PCI_DEVICE_ID_REDHAT_PXB_PCIE;
  286. k->class_id = PCI_CLASS_BRIDGE_HOST;
  287. dc->desc = "PCI Express Expander Bridge";
  288. dc->props = pxb_dev_properties;
  289. dc->hotpluggable = false;
  290. set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories);
  291. }
  292. static const TypeInfo pxb_pcie_dev_info = {
  293. .name = TYPE_PXB_PCIE_DEVICE,
  294. .parent = TYPE_PCI_DEVICE,
  295. .instance_size = sizeof(PXBDev),
  296. .class_init = pxb_pcie_dev_class_init,
  297. .interfaces = (InterfaceInfo[]) {
  298. { INTERFACE_CONVENTIONAL_PCI_DEVICE },
  299. { },
  300. },
  301. };
  302. static void pxb_register_types(void)
  303. {
  304. type_register_static(&pxb_bus_info);
  305. type_register_static(&pxb_pcie_bus_info);
  306. type_register_static(&pxb_host_info);
  307. type_register_static(&pxb_dev_info);
  308. type_register_static(&pxb_pcie_dev_info);
  309. }
  310. type_init(pxb_register_types)