ioh3420.c 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. /*
  2. * ioh3420.c
  3. * Intel X58 north bridge IOH
  4. * PCI Express root port device id 3420
  5. *
  6. * Copyright (c) 2010 Isaku Yamahata <yamahata at valinux co jp>
  7. * VA Linux Systems Japan K.K.
  8. *
  9. * This program is free software; you can redistribute it and/or modify
  10. * it under the terms of the GNU General Public License as published by
  11. * the Free Software Foundation; either version 2 of the License, or
  12. * (at your option) any later version.
  13. *
  14. * This program is distributed in the hope that it will be useful,
  15. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  17. * GNU General Public License for more details.
  18. *
  19. * You should have received a copy of the GNU General Public License along
  20. * with this program; if not, see <http://www.gnu.org/licenses/>.
  21. */
  22. #include "qemu/osdep.h"
  23. #include "hw/pci/pci_ids.h"
  24. #include "hw/pci/msi.h"
  25. #include "hw/pci/pcie.h"
  26. #include "hw/pci/pcie_port.h"
  27. #include "migration/vmstate.h"
  28. #include "qemu/module.h"
  29. #define PCI_DEVICE_ID_IOH_EPORT 0x3420 /* D0:F0 express mode */
  30. #define PCI_DEVICE_ID_IOH_REV 0x2
  31. #define IOH_EP_SSVID_OFFSET 0x40
  32. #define IOH_EP_SSVID_SVID PCI_VENDOR_ID_INTEL
  33. #define IOH_EP_SSVID_SSID 0
  34. #define IOH_EP_MSI_OFFSET 0x60
  35. #define IOH_EP_MSI_SUPPORTED_FLAGS PCI_MSI_FLAGS_MASKBIT
  36. #define IOH_EP_MSI_NR_VECTOR 2
  37. #define IOH_EP_EXP_OFFSET 0x90
  38. #define IOH_EP_AER_OFFSET 0x100
  39. /*
  40. * If two MSI vector are allocated, Advanced Error Interrupt Message Number
  41. * is 1. otherwise 0.
  42. * 17.12.5.10 RPERRSTS, 32:27 bit Advanced Error Interrupt Message Number.
  43. */
  44. static uint8_t ioh3420_aer_vector(const PCIDevice *d)
  45. {
  46. switch (msi_nr_vectors_allocated(d)) {
  47. case 1:
  48. return 0;
  49. case 2:
  50. return 1;
  51. case 4:
  52. case 8:
  53. case 16:
  54. case 32:
  55. default:
  56. break;
  57. }
  58. abort();
  59. return 0;
  60. }
  61. static int ioh3420_interrupts_init(PCIDevice *d, Error **errp)
  62. {
  63. int rc;
  64. rc = msi_init(d, IOH_EP_MSI_OFFSET, IOH_EP_MSI_NR_VECTOR,
  65. IOH_EP_MSI_SUPPORTED_FLAGS & PCI_MSI_FLAGS_64BIT,
  66. IOH_EP_MSI_SUPPORTED_FLAGS & PCI_MSI_FLAGS_MASKBIT,
  67. errp);
  68. if (rc < 0) {
  69. assert(rc == -ENOTSUP);
  70. }
  71. return rc;
  72. }
  73. static void ioh3420_interrupts_uninit(PCIDevice *d)
  74. {
  75. msi_uninit(d);
  76. }
  77. static const VMStateDescription vmstate_ioh3420 = {
  78. .name = "ioh-3240-express-root-port",
  79. .priority = MIG_PRI_PCI_BUS,
  80. .version_id = 1,
  81. .minimum_version_id = 1,
  82. .post_load = pcie_cap_slot_post_load,
  83. .fields = (VMStateField[]) {
  84. VMSTATE_PCI_DEVICE(parent_obj.parent_obj.parent_obj, PCIESlot),
  85. VMSTATE_STRUCT(parent_obj.parent_obj.parent_obj.exp.aer_log,
  86. PCIESlot, 0, vmstate_pcie_aer_log, PCIEAERLog),
  87. VMSTATE_END_OF_LIST()
  88. }
  89. };
  90. static void ioh3420_class_init(ObjectClass *klass, void *data)
  91. {
  92. DeviceClass *dc = DEVICE_CLASS(klass);
  93. PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
  94. PCIERootPortClass *rpc = PCIE_ROOT_PORT_CLASS(klass);
  95. k->vendor_id = PCI_VENDOR_ID_INTEL;
  96. k->device_id = PCI_DEVICE_ID_IOH_EPORT;
  97. k->revision = PCI_DEVICE_ID_IOH_REV;
  98. dc->desc = "Intel IOH device id 3420 PCIE Root Port";
  99. dc->vmsd = &vmstate_ioh3420;
  100. rpc->aer_vector = ioh3420_aer_vector;
  101. rpc->interrupts_init = ioh3420_interrupts_init;
  102. rpc->interrupts_uninit = ioh3420_interrupts_uninit;
  103. rpc->exp_offset = IOH_EP_EXP_OFFSET;
  104. rpc->aer_offset = IOH_EP_AER_OFFSET;
  105. rpc->ssvid_offset = IOH_EP_SSVID_OFFSET;
  106. rpc->ssid = IOH_EP_SSVID_SSID;
  107. }
  108. static const TypeInfo ioh3420_info = {
  109. .name = "ioh3420",
  110. .parent = TYPE_PCIE_ROOT_PORT,
  111. .class_init = ioh3420_class_init,
  112. };
  113. static void ioh3420_register_types(void)
  114. {
  115. type_register_static(&ioh3420_info);
  116. }
  117. type_init(ioh3420_register_types)