mmconfig.c 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. /*
  2. * mmconfig.c - Low-level direct PCI config space access via MMCONFIG
  3. *
  4. * This is an 64bit optimized version that always keeps the full mmconfig
  5. * space mapped. This allows lockless config space operation.
  6. */
  7. #include <linux/pci.h>
  8. #include <linux/init.h>
  9. #include <linux/acpi.h>
  10. #include "pci.h"
  11. #define MMCONFIG_APER_SIZE (256*1024*1024)
  12. /* Static virtual mapping of the MMCONFIG aperture */
  13. struct mmcfg_virt {
  14. struct acpi_table_mcfg_config *cfg;
  15. char *virt;
  16. };
  17. static struct mmcfg_virt *pci_mmcfg_virt;
  18. static char *get_virt(unsigned int seg, unsigned bus)
  19. {
  20. int cfg_num = -1;
  21. struct acpi_table_mcfg_config *cfg;
  22. while (1) {
  23. ++cfg_num;
  24. if (cfg_num >= pci_mmcfg_config_num) {
  25. /* Not found - fall back to type 1. This happens
  26. e.g. on the internal devices of a K8 northbridge. */
  27. return NULL;
  28. }
  29. cfg = pci_mmcfg_virt[cfg_num].cfg;
  30. if (cfg->pci_segment_group_number != seg)
  31. continue;
  32. if ((cfg->start_bus_number <= bus) &&
  33. (cfg->end_bus_number >= bus))
  34. return pci_mmcfg_virt[cfg_num].virt;
  35. }
  36. }
  37. static inline char *pci_dev_base(unsigned int seg, unsigned int bus, unsigned int devfn)
  38. {
  39. char *addr = get_virt(seg, bus);
  40. if (!addr)
  41. return NULL;
  42. return addr + ((bus << 20) | (devfn << 12));
  43. }
  44. static int pci_mmcfg_read(unsigned int seg, unsigned int bus,
  45. unsigned int devfn, int reg, int len, u32 *value)
  46. {
  47. char *addr;
  48. /* Why do we have this when nobody checks it. How about a BUG()!? -AK */
  49. if (unlikely(!value || (bus > 255) || (devfn > 255) || (reg > 4095)))
  50. return -EINVAL;
  51. addr = pci_dev_base(seg, bus, devfn);
  52. if (!addr)
  53. return pci_conf1_read(seg,bus,devfn,reg,len,value);
  54. switch (len) {
  55. case 1:
  56. *value = readb(addr + reg);
  57. break;
  58. case 2:
  59. *value = readw(addr + reg);
  60. break;
  61. case 4:
  62. *value = readl(addr + reg);
  63. break;
  64. }
  65. return 0;
  66. }
  67. static int pci_mmcfg_write(unsigned int seg, unsigned int bus,
  68. unsigned int devfn, int reg, int len, u32 value)
  69. {
  70. char *addr;
  71. /* Why do we have this when nobody checks it. How about a BUG()!? -AK */
  72. if (unlikely((bus > 255) || (devfn > 255) || (reg > 4095)))
  73. return -EINVAL;
  74. addr = pci_dev_base(seg, bus, devfn);
  75. if (!addr)
  76. return pci_conf1_write(seg,bus,devfn,reg,len,value);
  77. switch (len) {
  78. case 1:
  79. writeb(value, addr + reg);
  80. break;
  81. case 2:
  82. writew(value, addr + reg);
  83. break;
  84. case 4:
  85. writel(value, addr + reg);
  86. break;
  87. }
  88. return 0;
  89. }
  90. static struct pci_raw_ops pci_mmcfg = {
  91. .read = pci_mmcfg_read,
  92. .write = pci_mmcfg_write,
  93. };
  94. static int __init pci_mmcfg_init(void)
  95. {
  96. int i;
  97. if ((pci_probe & PCI_PROBE_MMCONF) == 0)
  98. return 0;
  99. acpi_table_parse(ACPI_MCFG, acpi_parse_mcfg);
  100. if ((pci_mmcfg_config_num == 0) ||
  101. (pci_mmcfg_config == NULL) ||
  102. (pci_mmcfg_config[0].base_address == 0))
  103. return 0;
  104. /* RED-PEN i386 doesn't do _nocache right now */
  105. pci_mmcfg_virt = kmalloc(sizeof(*pci_mmcfg_virt) * pci_mmcfg_config_num, GFP_KERNEL);
  106. if (pci_mmcfg_virt == NULL) {
  107. printk("PCI: Can not allocate memory for mmconfig structures\n");
  108. return 0;
  109. }
  110. for (i = 0; i < pci_mmcfg_config_num; ++i) {
  111. pci_mmcfg_virt[i].cfg = &pci_mmcfg_config[i];
  112. pci_mmcfg_virt[i].virt = ioremap_nocache(pci_mmcfg_config[i].base_address, MMCONFIG_APER_SIZE);
  113. if (!pci_mmcfg_virt[i].virt) {
  114. printk("PCI: Cannot map mmconfig aperture for segment %d\n",
  115. pci_mmcfg_config[i].pci_segment_group_number);
  116. return 0;
  117. }
  118. printk(KERN_INFO "PCI: Using MMCONFIG at %x\n", pci_mmcfg_config[i].base_address);
  119. }
  120. raw_pci_ops = &pci_mmcfg;
  121. pci_probe = (pci_probe & ~PCI_PROBE_MASK) | PCI_PROBE_MMCONF;
  122. return 0;
  123. }
  124. arch_initcall(pci_mmcfg_init);