mmconfig-shared.c 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315
  1. /*
  2. * mmconfig-shared.c - Low-level direct PCI config space access via
  3. * MMCONFIG - common code between i386 and x86-64.
  4. *
  5. * This code does:
  6. * - known chipset handling
  7. * - ACPI decoding and validation
  8. *
  9. * Per-architecture code takes care of the mappings and accesses
  10. * themselves.
  11. */
  12. #include <linux/pci.h>
  13. #include <linux/init.h>
  14. #include <linux/acpi.h>
  15. #include <linux/bitmap.h>
  16. #include <asm/e820.h>
  17. #include "pci.h"
  18. /* aperture is up to 256MB but BIOS may reserve less */
  19. #define MMCONFIG_APER_MIN (2 * 1024*1024)
  20. #define MMCONFIG_APER_MAX (256 * 1024*1024)
  21. DECLARE_BITMAP(pci_mmcfg_fallback_slots, 32*PCI_MMCFG_MAX_CHECK_BUS);
  22. /* Indicate if the mmcfg resources have been placed into the resource table. */
  23. static int __initdata pci_mmcfg_resources_inserted;
  24. /* K8 systems have some devices (typically in the builtin northbridge)
  25. that are only accessible using type1
  26. Normally this can be expressed in the MCFG by not listing them
  27. and assigning suitable _SEGs, but this isn't implemented in some BIOS.
  28. Instead try to discover all devices on bus 0 that are unreachable using MM
  29. and fallback for them. */
  30. static void __init unreachable_devices(void)
  31. {
  32. int i, bus;
  33. /* Use the max bus number from ACPI here? */
  34. for (bus = 0; bus < PCI_MMCFG_MAX_CHECK_BUS; bus++) {
  35. for (i = 0; i < 32; i++) {
  36. unsigned int devfn = PCI_DEVFN(i, 0);
  37. u32 val1, val2;
  38. pci_conf1_read(0, bus, devfn, 0, 4, &val1);
  39. if (val1 == 0xffffffff)
  40. continue;
  41. if (pci_mmcfg_arch_reachable(0, bus, devfn)) {
  42. raw_pci_ops->read(0, bus, devfn, 0, 4, &val2);
  43. if (val1 == val2)
  44. continue;
  45. }
  46. set_bit(i + 32 * bus, pci_mmcfg_fallback_slots);
  47. printk(KERN_NOTICE "PCI: No mmconfig possible on device"
  48. " %02x:%02x\n", bus, i);
  49. }
  50. }
  51. }
  52. static const char __init *pci_mmcfg_e7520(void)
  53. {
  54. u32 win;
  55. pci_conf1_read(0, 0, PCI_DEVFN(0,0), 0xce, 2, &win);
  56. win = win & 0xf000;
  57. if(win == 0x0000 || win == 0xf000)
  58. pci_mmcfg_config_num = 0;
  59. else {
  60. pci_mmcfg_config_num = 1;
  61. pci_mmcfg_config = kzalloc(sizeof(pci_mmcfg_config[0]), GFP_KERNEL);
  62. if (!pci_mmcfg_config)
  63. return NULL;
  64. pci_mmcfg_config[0].address = win << 16;
  65. pci_mmcfg_config[0].pci_segment = 0;
  66. pci_mmcfg_config[0].start_bus_number = 0;
  67. pci_mmcfg_config[0].end_bus_number = 255;
  68. }
  69. return "Intel Corporation E7520 Memory Controller Hub";
  70. }
  71. static const char __init *pci_mmcfg_intel_945(void)
  72. {
  73. u32 pciexbar, mask = 0, len = 0;
  74. pci_mmcfg_config_num = 1;
  75. pci_conf1_read(0, 0, PCI_DEVFN(0,0), 0x48, 4, &pciexbar);
  76. /* Enable bit */
  77. if (!(pciexbar & 1))
  78. pci_mmcfg_config_num = 0;
  79. /* Size bits */
  80. switch ((pciexbar >> 1) & 3) {
  81. case 0:
  82. mask = 0xf0000000U;
  83. len = 0x10000000U;
  84. break;
  85. case 1:
  86. mask = 0xf8000000U;
  87. len = 0x08000000U;
  88. break;
  89. case 2:
  90. mask = 0xfc000000U;
  91. len = 0x04000000U;
  92. break;
  93. default:
  94. pci_mmcfg_config_num = 0;
  95. }
  96. /* Errata #2, things break when not aligned on a 256Mb boundary */
  97. /* Can only happen in 64M/128M mode */
  98. if ((pciexbar & mask) & 0x0fffffffU)
  99. pci_mmcfg_config_num = 0;
  100. /* Don't hit the APIC registers and their friends */
  101. if ((pciexbar & mask) >= 0xf0000000U)
  102. pci_mmcfg_config_num = 0;
  103. if (pci_mmcfg_config_num) {
  104. pci_mmcfg_config = kzalloc(sizeof(pci_mmcfg_config[0]), GFP_KERNEL);
  105. if (!pci_mmcfg_config)
  106. return NULL;
  107. pci_mmcfg_config[0].address = pciexbar & mask;
  108. pci_mmcfg_config[0].pci_segment = 0;
  109. pci_mmcfg_config[0].start_bus_number = 0;
  110. pci_mmcfg_config[0].end_bus_number = (len >> 20) - 1;
  111. }
  112. return "Intel Corporation 945G/GZ/P/PL Express Memory Controller Hub";
  113. }
  114. struct pci_mmcfg_hostbridge_probe {
  115. u32 vendor;
  116. u32 device;
  117. const char *(*probe)(void);
  118. };
  119. static struct pci_mmcfg_hostbridge_probe pci_mmcfg_probes[] __initdata = {
  120. { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_E7520_MCH, pci_mmcfg_e7520 },
  121. { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82945G_HB, pci_mmcfg_intel_945 },
  122. };
  123. static int __init pci_mmcfg_check_hostbridge(void)
  124. {
  125. u32 l;
  126. u16 vendor, device;
  127. int i;
  128. const char *name;
  129. pci_conf1_read(0, 0, PCI_DEVFN(0,0), 0, 4, &l);
  130. vendor = l & 0xffff;
  131. device = (l >> 16) & 0xffff;
  132. pci_mmcfg_config_num = 0;
  133. pci_mmcfg_config = NULL;
  134. name = NULL;
  135. for (i = 0; !name && i < ARRAY_SIZE(pci_mmcfg_probes); i++) {
  136. if (pci_mmcfg_probes[i].vendor == vendor &&
  137. pci_mmcfg_probes[i].device == device)
  138. name = pci_mmcfg_probes[i].probe();
  139. }
  140. if (name) {
  141. printk(KERN_INFO "PCI: Found %s %s MMCONFIG support.\n",
  142. name, pci_mmcfg_config_num ? "with" : "without");
  143. }
  144. return name != NULL;
  145. }
  146. static void __init pci_mmcfg_insert_resources(unsigned long resource_flags)
  147. {
  148. #define PCI_MMCFG_RESOURCE_NAME_LEN 19
  149. int i;
  150. struct resource *res;
  151. char *names;
  152. unsigned num_buses;
  153. res = kcalloc(PCI_MMCFG_RESOURCE_NAME_LEN + sizeof(*res),
  154. pci_mmcfg_config_num, GFP_KERNEL);
  155. if (!res) {
  156. printk(KERN_ERR "PCI: Unable to allocate MMCONFIG resources\n");
  157. return;
  158. }
  159. names = (void *)&res[pci_mmcfg_config_num];
  160. for (i = 0; i < pci_mmcfg_config_num; i++, res++) {
  161. struct acpi_mcfg_allocation *cfg = &pci_mmcfg_config[i];
  162. num_buses = cfg->end_bus_number - cfg->start_bus_number + 1;
  163. res->name = names;
  164. snprintf(names, PCI_MMCFG_RESOURCE_NAME_LEN, "PCI MMCONFIG %u",
  165. cfg->pci_segment);
  166. res->start = cfg->address;
  167. res->end = res->start + (num_buses << 20) - 1;
  168. res->flags = IORESOURCE_MEM | resource_flags;
  169. insert_resource(&iomem_resource, res);
  170. names += PCI_MMCFG_RESOURCE_NAME_LEN;
  171. }
  172. /* Mark that the resources have been inserted. */
  173. pci_mmcfg_resources_inserted = 1;
  174. }
  175. static void __init pci_mmcfg_reject_broken(int type)
  176. {
  177. typeof(pci_mmcfg_config[0]) *cfg;
  178. if ((pci_mmcfg_config_num == 0) ||
  179. (pci_mmcfg_config == NULL) ||
  180. (pci_mmcfg_config[0].address == 0))
  181. return;
  182. cfg = &pci_mmcfg_config[0];
  183. /*
  184. * Handle more broken MCFG tables on Asus etc.
  185. * They only contain a single entry for bus 0-0.
  186. */
  187. if (pci_mmcfg_config_num == 1 &&
  188. cfg->pci_segment == 0 &&
  189. (cfg->start_bus_number | cfg->end_bus_number) == 0) {
  190. printk(KERN_ERR "PCI: start and end of bus number is 0. "
  191. "Rejected as broken MCFG.\n");
  192. goto reject;
  193. }
  194. /*
  195. * Only do this check when type 1 works. If it doesn't work
  196. * assume we run on a Mac and always use MCFG
  197. */
  198. if (type == 1 && !e820_all_mapped(cfg->address,
  199. cfg->address + MMCONFIG_APER_MIN,
  200. E820_RESERVED)) {
  201. printk(KERN_ERR "PCI: BIOS Bug: MCFG area at %Lx is not"
  202. " E820-reserved\n", cfg->address);
  203. goto reject;
  204. }
  205. return;
  206. reject:
  207. printk(KERN_ERR "PCI: Not using MMCONFIG.\n");
  208. kfree(pci_mmcfg_config);
  209. pci_mmcfg_config = NULL;
  210. pci_mmcfg_config_num = 0;
  211. }
  212. void __init pci_mmcfg_init(int type)
  213. {
  214. int known_bridge = 0;
  215. if ((pci_probe & PCI_PROBE_MMCONF) == 0)
  216. return;
  217. if (type == 1 && pci_mmcfg_check_hostbridge())
  218. known_bridge = 1;
  219. if (!known_bridge) {
  220. acpi_table_parse(ACPI_SIG_MCFG, acpi_parse_mcfg);
  221. pci_mmcfg_reject_broken(type);
  222. }
  223. if ((pci_mmcfg_config_num == 0) ||
  224. (pci_mmcfg_config == NULL) ||
  225. (pci_mmcfg_config[0].address == 0))
  226. return;
  227. if (pci_mmcfg_arch_init()) {
  228. if (type == 1)
  229. unreachable_devices();
  230. if (known_bridge)
  231. pci_mmcfg_insert_resources(IORESOURCE_BUSY);
  232. pci_probe = (pci_probe & ~PCI_PROBE_MASK) | PCI_PROBE_MMCONF;
  233. } else {
  234. /*
  235. * Signal not to attempt to insert mmcfg resources because
  236. * the architecture mmcfg setup could not initialize.
  237. */
  238. pci_mmcfg_resources_inserted = 1;
  239. }
  240. }
  241. static int __init pci_mmcfg_late_insert_resources(void)
  242. {
  243. /*
  244. * If resources are already inserted or we are not using MMCONFIG,
  245. * don't insert the resources.
  246. */
  247. if ((pci_mmcfg_resources_inserted == 1) ||
  248. (pci_probe & PCI_PROBE_MMCONF) == 0 ||
  249. (pci_mmcfg_config_num == 0) ||
  250. (pci_mmcfg_config == NULL) ||
  251. (pci_mmcfg_config[0].address == 0))
  252. return 1;
  253. /*
  254. * Attempt to insert the mmcfg resources but not with the busy flag
  255. * marked so it won't cause request errors when __request_region is
  256. * called.
  257. */
  258. pci_mmcfg_insert_resources(0);
  259. return 0;
  260. }
  261. /*
  262. * Perform MMCONFIG resource insertion after PCI initialization to allow for
  263. * misprogrammed MCFG tables that state larger sizes but actually conflict
  264. * with other system resources.
  265. */
  266. late_initcall(pci_mmcfg_late_insert_resources);