mmconfig.c 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  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 <linux/bitmap.h>
  11. #include <asm/e820.h>
  12. #include "pci.h"
  13. /* aperture is up to 256MB but BIOS may reserve less */
  14. #define MMCONFIG_APER_MIN (2 * 1024*1024)
  15. #define MMCONFIG_APER_MAX (256 * 1024*1024)
  16. /* Verify the first 16 busses. We assume that systems with more busses
  17. get MCFG right. */
  18. #define PCI_MMCFG_MAX_CHECK_BUS 16
  19. /* Static virtual mapping of the MMCONFIG aperture */
  20. struct mmcfg_virt {
  21. struct acpi_mcfg_allocation *cfg;
  22. char __iomem *virt;
  23. };
  24. static struct mmcfg_virt *pci_mmcfg_virt;
  25. static char __iomem *get_virt(unsigned int seg, unsigned bus)
  26. {
  27. int cfg_num = -1;
  28. struct acpi_mcfg_allocation *cfg;
  29. while (1) {
  30. ++cfg_num;
  31. if (cfg_num >= pci_mmcfg_config_num)
  32. break;
  33. cfg = pci_mmcfg_virt[cfg_num].cfg;
  34. if (cfg->pci_segment != seg)
  35. continue;
  36. if ((cfg->start_bus_number <= bus) &&
  37. (cfg->end_bus_number >= bus))
  38. return pci_mmcfg_virt[cfg_num].virt;
  39. }
  40. /* Fall back to type 0 */
  41. return NULL;
  42. }
  43. static char __iomem *pci_dev_base(unsigned int seg, unsigned int bus, unsigned int devfn)
  44. {
  45. char __iomem *addr;
  46. if (seg == 0 && bus < PCI_MMCFG_MAX_CHECK_BUS &&
  47. test_bit(32*bus + PCI_SLOT(devfn), pci_mmcfg_fallback_slots))
  48. return NULL;
  49. addr = get_virt(seg, bus);
  50. if (!addr)
  51. return NULL;
  52. return addr + ((bus << 20) | (devfn << 12));
  53. }
  54. static int pci_mmcfg_read(unsigned int seg, unsigned int bus,
  55. unsigned int devfn, int reg, int len, u32 *value)
  56. {
  57. char __iomem *addr;
  58. /* Why do we have this when nobody checks it. How about a BUG()!? -AK */
  59. if (unlikely((bus > 255) || (devfn > 255) || (reg > 4095))) {
  60. *value = -1;
  61. return -EINVAL;
  62. }
  63. addr = pci_dev_base(seg, bus, devfn);
  64. if (!addr)
  65. return pci_conf1_read(seg,bus,devfn,reg,len,value);
  66. switch (len) {
  67. case 1:
  68. *value = readb(addr + reg);
  69. break;
  70. case 2:
  71. *value = readw(addr + reg);
  72. break;
  73. case 4:
  74. *value = readl(addr + reg);
  75. break;
  76. }
  77. return 0;
  78. }
  79. static int pci_mmcfg_write(unsigned int seg, unsigned int bus,
  80. unsigned int devfn, int reg, int len, u32 value)
  81. {
  82. char __iomem *addr;
  83. /* Why do we have this when nobody checks it. How about a BUG()!? -AK */
  84. if (unlikely((bus > 255) || (devfn > 255) || (reg > 4095)))
  85. return -EINVAL;
  86. addr = pci_dev_base(seg, bus, devfn);
  87. if (!addr)
  88. return pci_conf1_write(seg,bus,devfn,reg,len,value);
  89. switch (len) {
  90. case 1:
  91. writeb(value, addr + reg);
  92. break;
  93. case 2:
  94. writew(value, addr + reg);
  95. break;
  96. case 4:
  97. writel(value, addr + reg);
  98. break;
  99. }
  100. return 0;
  101. }
  102. static struct pci_raw_ops pci_mmcfg = {
  103. .read = pci_mmcfg_read,
  104. .write = pci_mmcfg_write,
  105. };
  106. static void __iomem * __init mcfg_ioremap(struct acpi_mcfg_allocation *cfg)
  107. {
  108. void __iomem *addr;
  109. u32 size;
  110. size = (cfg->end_bus_number + 1) << 20;
  111. addr = ioremap_nocache(cfg->address, size);
  112. if (addr) {
  113. printk(KERN_INFO "PCI: Using MMCONFIG at %Lx - %Lx\n",
  114. cfg->address, cfg->address + size - 1);
  115. }
  116. return addr;
  117. }
  118. int __init pci_mmcfg_arch_init(void)
  119. {
  120. int i;
  121. pci_mmcfg_virt = kmalloc(sizeof(*pci_mmcfg_virt) *
  122. pci_mmcfg_config_num, GFP_KERNEL);
  123. if (pci_mmcfg_virt == NULL) {
  124. printk(KERN_ERR "PCI: Can not allocate memory for mmconfig structures\n");
  125. return 0;
  126. }
  127. for (i = 0; i < pci_mmcfg_config_num; ++i) {
  128. pci_mmcfg_virt[i].cfg = &pci_mmcfg_config[i];
  129. pci_mmcfg_virt[i].virt = mcfg_ioremap(&pci_mmcfg_config[i]);
  130. if (!pci_mmcfg_virt[i].virt) {
  131. printk(KERN_ERR "PCI: Cannot map mmconfig aperture for "
  132. "segment %d\n",
  133. pci_mmcfg_config[i].pci_segment);
  134. return 0;
  135. }
  136. }
  137. raw_pci_ops = &pci_mmcfg;
  138. return 1;
  139. }