pcie_root_port.c 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198
  1. /*
  2. * Base class for PCI Express Root Ports
  3. *
  4. * Copyright (C) 2017 Red Hat Inc
  5. *
  6. * Authors:
  7. * Marcel Apfelbaum <marcel@redhat.com>
  8. *
  9. * Most of the code was migrated from hw/pci-bridge/ioh3420.
  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. #include "qemu/osdep.h"
  15. #include "qapi/error.h"
  16. #include "qemu/module.h"
  17. #include "hw/pci/pcie_port.h"
  18. #include "hw/qdev-properties.h"
  19. static void rp_aer_vector_update(PCIDevice *d)
  20. {
  21. PCIERootPortClass *rpc = PCIE_ROOT_PORT_GET_CLASS(d);
  22. if (rpc->aer_vector) {
  23. pcie_aer_root_set_vector(d, rpc->aer_vector(d));
  24. }
  25. }
  26. static void rp_write_config(PCIDevice *d, uint32_t address,
  27. uint32_t val, int len)
  28. {
  29. uint32_t root_cmd =
  30. pci_get_long(d->config + d->exp.aer_cap + PCI_ERR_ROOT_COMMAND);
  31. uint16_t slt_ctl, slt_sta;
  32. pcie_cap_slot_get(d, &slt_ctl, &slt_sta);
  33. pci_bridge_write_config(d, address, val, len);
  34. rp_aer_vector_update(d);
  35. pcie_cap_slot_write_config(d, slt_ctl, slt_sta, address, val, len);
  36. pcie_aer_write_config(d, address, val, len);
  37. pcie_aer_root_write_config(d, address, val, len, root_cmd);
  38. }
  39. static void rp_reset(DeviceState *qdev)
  40. {
  41. PCIDevice *d = PCI_DEVICE(qdev);
  42. rp_aer_vector_update(d);
  43. pcie_cap_root_reset(d);
  44. pcie_cap_deverr_reset(d);
  45. pcie_cap_slot_reset(d);
  46. pcie_cap_arifwd_reset(d);
  47. pcie_acs_reset(d);
  48. pcie_aer_root_reset(d);
  49. pci_bridge_reset(qdev);
  50. pci_bridge_disable_base_limit(d);
  51. }
  52. static void rp_realize(PCIDevice *d, Error **errp)
  53. {
  54. PCIEPort *p = PCIE_PORT(d);
  55. PCIESlot *s = PCIE_SLOT(d);
  56. PCIDeviceClass *dc = PCI_DEVICE_GET_CLASS(d);
  57. PCIERootPortClass *rpc = PCIE_ROOT_PORT_GET_CLASS(d);
  58. int rc;
  59. pci_config_set_interrupt_pin(d->config, 1);
  60. pci_bridge_initfn(d, TYPE_PCIE_BUS);
  61. pcie_port_init_reg(d);
  62. rc = pci_bridge_ssvid_init(d, rpc->ssvid_offset, dc->vendor_id,
  63. rpc->ssid, errp);
  64. if (rc < 0) {
  65. error_append_hint(errp, "Can't init SSV ID, error %d\n", rc);
  66. goto err_bridge;
  67. }
  68. if (rpc->interrupts_init) {
  69. rc = rpc->interrupts_init(d, errp);
  70. if (rc < 0) {
  71. goto err_bridge;
  72. }
  73. }
  74. rc = pcie_cap_init(d, rpc->exp_offset, PCI_EXP_TYPE_ROOT_PORT,
  75. p->port, errp);
  76. if (rc < 0) {
  77. error_append_hint(errp, "Can't add Root Port capability, "
  78. "error %d\n", rc);
  79. goto err_int;
  80. }
  81. pcie_cap_arifwd_init(d);
  82. pcie_cap_deverr_init(d);
  83. pcie_cap_slot_init(d, s->slot);
  84. pcie_cap_root_init(d);
  85. pcie_chassis_create(s->chassis);
  86. rc = pcie_chassis_add_slot(s);
  87. if (rc < 0) {
  88. error_setg(errp, "Can't add chassis slot, error %d", rc);
  89. goto err_pcie_cap;
  90. }
  91. rc = pcie_aer_init(d, PCI_ERR_VER, rpc->aer_offset,
  92. PCI_ERR_SIZEOF, errp);
  93. if (rc < 0) {
  94. goto err;
  95. }
  96. pcie_aer_root_init(d);
  97. rp_aer_vector_update(d);
  98. if (rpc->acs_offset && !s->disable_acs) {
  99. pcie_acs_init(d, rpc->acs_offset);
  100. }
  101. return;
  102. err:
  103. pcie_chassis_del_slot(s);
  104. err_pcie_cap:
  105. pcie_cap_exit(d);
  106. err_int:
  107. if (rpc->interrupts_uninit) {
  108. rpc->interrupts_uninit(d);
  109. }
  110. err_bridge:
  111. pci_bridge_exitfn(d);
  112. }
  113. static void rp_exit(PCIDevice *d)
  114. {
  115. PCIERootPortClass *rpc = PCIE_ROOT_PORT_GET_CLASS(d);
  116. PCIESlot *s = PCIE_SLOT(d);
  117. pcie_aer_exit(d);
  118. pcie_chassis_del_slot(s);
  119. pcie_cap_exit(d);
  120. if (rpc->interrupts_uninit) {
  121. rpc->interrupts_uninit(d);
  122. }
  123. pci_bridge_exitfn(d);
  124. }
  125. static Property rp_props[] = {
  126. DEFINE_PROP_BIT(COMPAT_PROP_PCP, PCIDevice, cap_present,
  127. QEMU_PCIE_SLTCAP_PCP_BITNR, true),
  128. DEFINE_PROP_BOOL("disable-acs", PCIESlot, disable_acs, false),
  129. DEFINE_PROP_END_OF_LIST()
  130. };
  131. static void rp_instance_post_init(Object *obj)
  132. {
  133. PCIESlot *s = PCIE_SLOT(obj);
  134. if (!s->speed) {
  135. s->speed = QEMU_PCI_EXP_LNK_2_5GT;
  136. }
  137. if (!s->width) {
  138. s->width = QEMU_PCI_EXP_LNK_X1;
  139. }
  140. }
  141. static void rp_class_init(ObjectClass *klass, void *data)
  142. {
  143. DeviceClass *dc = DEVICE_CLASS(klass);
  144. PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
  145. k->is_bridge = true;
  146. k->config_write = rp_write_config;
  147. k->realize = rp_realize;
  148. k->exit = rp_exit;
  149. set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories);
  150. dc->reset = rp_reset;
  151. dc->props = rp_props;
  152. }
  153. static const TypeInfo rp_info = {
  154. .name = TYPE_PCIE_ROOT_PORT,
  155. .parent = TYPE_PCIE_SLOT,
  156. .instance_post_init = rp_instance_post_init,
  157. .class_init = rp_class_init,
  158. .abstract = true,
  159. .class_size = sizeof(PCIERootPortClass),
  160. .interfaces = (InterfaceInfo[]) {
  161. { INTERFACE_PCIE_DEVICE },
  162. { }
  163. },
  164. };
  165. static void rp_register_types(void)
  166. {
  167. type_register_static(&rp_info);
  168. }
  169. type_init(rp_register_types)