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