2
0

pci_expander_bridge.c 10 KB

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