0001
0002 #include <linux/init.h>
0003 #include <linux/pci.h>
0004 #include <linux/topology.h>
0005 #include <linux/cpu.h>
0006 #include <linux/range.h>
0007
0008 #include <asm/amd_nb.h>
0009 #include <asm/pci_x86.h>
0010
0011 #include <asm/pci-direct.h>
0012
0013 #include "bus_numa.h"
0014
0015 #define AMD_NB_F0_NODE_ID 0x60
0016 #define AMD_NB_F0_UNIT_ID 0x64
0017 #define AMD_NB_F1_CONFIG_MAP_REG 0xe0
0018
0019 #define RANGE_NUM 16
0020 #define AMD_NB_F1_CONFIG_MAP_RANGES 4
0021
0022 struct amd_hostbridge {
0023 u32 bus;
0024 u32 slot;
0025 u32 device;
0026 };
0027
0028
0029
0030
0031
0032
0033
0034 static struct amd_hostbridge hb_probes[] __initdata = {
0035 { 0, 0x18, 0x1100 },
0036 { 0, 0x18, 0x1200 },
0037 { 0xff, 0, 0x1200 },
0038 { 0, 0x18, 0x1300 },
0039 { 0, 0x18, 0x1600 },
0040 };
0041
0042 static struct pci_root_info __init *find_pci_root_info(int node, int link)
0043 {
0044 struct pci_root_info *info;
0045
0046
0047 list_for_each_entry(info, &pci_root_infos, list)
0048 if (info->node == node && info->link == link)
0049 return info;
0050
0051 return NULL;
0052 }
0053
0054
0055
0056
0057
0058
0059
0060 static int __init early_root_info_init(void)
0061 {
0062 int i;
0063 unsigned bus;
0064 unsigned slot;
0065 int node;
0066 int link;
0067 int def_node;
0068 int def_link;
0069 struct pci_root_info *info;
0070 u32 reg;
0071 u64 start;
0072 u64 end;
0073 struct range range[RANGE_NUM];
0074 u64 val;
0075 u32 address;
0076 bool found;
0077 struct resource fam10h_mmconf_res, *fam10h_mmconf;
0078 u64 fam10h_mmconf_start;
0079 u64 fam10h_mmconf_end;
0080
0081 if (!early_pci_allowed())
0082 return -1;
0083
0084 found = false;
0085 for (i = 0; i < ARRAY_SIZE(hb_probes); i++) {
0086 u32 id;
0087 u16 device;
0088 u16 vendor;
0089
0090 bus = hb_probes[i].bus;
0091 slot = hb_probes[i].slot;
0092 id = read_pci_config(bus, slot, 0, PCI_VENDOR_ID);
0093 vendor = id & 0xffff;
0094 device = (id>>16) & 0xffff;
0095
0096 if (vendor != PCI_VENDOR_ID_AMD &&
0097 vendor != PCI_VENDOR_ID_HYGON)
0098 continue;
0099
0100 if (hb_probes[i].device == device) {
0101 found = true;
0102 break;
0103 }
0104 }
0105
0106 if (!found)
0107 return 0;
0108
0109
0110
0111
0112
0113
0114 for (i = 0; i < AMD_NB_F1_CONFIG_MAP_RANGES; i++) {
0115 int min_bus;
0116 int max_bus;
0117 reg = read_pci_config(bus, slot, 1,
0118 AMD_NB_F1_CONFIG_MAP_REG + (i << 2));
0119
0120
0121 if ((reg & 7) != 3)
0122 continue;
0123
0124 min_bus = (reg >> 16) & 0xff;
0125 max_bus = (reg >> 24) & 0xff;
0126 node = (reg >> 4) & 0x07;
0127 link = (reg >> 8) & 0x03;
0128
0129 alloc_pci_root_info(min_bus, max_bus, node, link);
0130 }
0131
0132
0133
0134
0135
0136
0137
0138
0139
0140 if (boot_cpu_data.x86 > 0x11)
0141 return 0;
0142
0143
0144 reg = read_pci_config(bus, slot, 0, AMD_NB_F0_NODE_ID);
0145 def_node = (reg >> 8) & 0x07;
0146 reg = read_pci_config(bus, slot, 0, AMD_NB_F0_UNIT_ID);
0147 def_link = (reg >> 8) & 0x03;
0148
0149 memset(range, 0, sizeof(range));
0150 add_range(range, RANGE_NUM, 0, 0, 0xffff + 1);
0151
0152 for (i = 0; i < 4; i++) {
0153 reg = read_pci_config(bus, slot, 1, 0xc0 + (i << 3));
0154 if (!(reg & 3))
0155 continue;
0156
0157 start = reg & 0xfff000;
0158 reg = read_pci_config(bus, slot, 1, 0xc4 + (i << 3));
0159 node = reg & 0x07;
0160 link = (reg >> 4) & 0x03;
0161 end = (reg & 0xfff000) | 0xfff;
0162
0163 info = find_pci_root_info(node, link);
0164 if (!info)
0165 continue;
0166
0167 printk(KERN_DEBUG "node %d link %d: io port [%llx, %llx]\n",
0168 node, link, start, end);
0169
0170
0171 if (end > 0xffff)
0172 end = 0xffff;
0173 update_res(info, start, end, IORESOURCE_IO, 1);
0174 subtract_range(range, RANGE_NUM, start, end + 1);
0175 }
0176
0177
0178 info = find_pci_root_info(def_node, def_link);
0179 if (info) {
0180 for (i = 0; i < RANGE_NUM; i++) {
0181 if (!range[i].end)
0182 continue;
0183
0184 update_res(info, range[i].start, range[i].end - 1,
0185 IORESOURCE_IO, 1);
0186 }
0187 }
0188
0189 memset(range, 0, sizeof(range));
0190
0191 end = cap_resource((0xfdULL<<32) - 1);
0192 end++;
0193 add_range(range, RANGE_NUM, 0, 0, end);
0194
0195
0196 address = MSR_K8_TOP_MEM1;
0197 rdmsrl(address, val);
0198 end = (val & 0xffffff800000ULL);
0199 printk(KERN_INFO "TOM: %016llx aka %lldM\n", end, end>>20);
0200 if (end < (1ULL<<32))
0201 subtract_range(range, RANGE_NUM, 0, end);
0202
0203
0204 fam10h_mmconf = amd_get_mmconfig_range(&fam10h_mmconf_res);
0205
0206 if (fam10h_mmconf) {
0207 printk(KERN_DEBUG "Fam 10h mmconf %pR\n", fam10h_mmconf);
0208 fam10h_mmconf_start = fam10h_mmconf->start;
0209 fam10h_mmconf_end = fam10h_mmconf->end;
0210 subtract_range(range, RANGE_NUM, fam10h_mmconf_start,
0211 fam10h_mmconf_end + 1);
0212 } else {
0213 fam10h_mmconf_start = 0;
0214 fam10h_mmconf_end = 0;
0215 }
0216
0217
0218 for (i = 0; i < 8; i++) {
0219 reg = read_pci_config(bus, slot, 1, 0x80 + (i << 3));
0220 if (!(reg & 3))
0221 continue;
0222
0223 start = reg & 0xffffff00;
0224 start <<= 8;
0225 reg = read_pci_config(bus, slot, 1, 0x84 + (i << 3));
0226 node = reg & 0x07;
0227 link = (reg >> 4) & 0x03;
0228 end = (reg & 0xffffff00);
0229 end <<= 8;
0230 end |= 0xffff;
0231
0232 info = find_pci_root_info(node, link);
0233
0234 if (!info)
0235 continue;
0236
0237 printk(KERN_DEBUG "node %d link %d: mmio [%llx, %llx]",
0238 node, link, start, end);
0239
0240
0241
0242
0243 if (fam10h_mmconf_end) {
0244 int changed = 0;
0245 u64 endx = 0;
0246 if (start >= fam10h_mmconf_start &&
0247 start <= fam10h_mmconf_end) {
0248 start = fam10h_mmconf_end + 1;
0249 changed = 1;
0250 }
0251
0252 if (end >= fam10h_mmconf_start &&
0253 end <= fam10h_mmconf_end) {
0254 end = fam10h_mmconf_start - 1;
0255 changed = 1;
0256 }
0257
0258 if (start < fam10h_mmconf_start &&
0259 end > fam10h_mmconf_end) {
0260
0261 endx = fam10h_mmconf_start - 1;
0262 update_res(info, start, endx, IORESOURCE_MEM, 0);
0263 subtract_range(range, RANGE_NUM, start,
0264 endx + 1);
0265 printk(KERN_CONT " ==> [%llx, %llx]", start, endx);
0266 start = fam10h_mmconf_end + 1;
0267 changed = 1;
0268 }
0269 if (changed) {
0270 if (start <= end) {
0271 printk(KERN_CONT " %s [%llx, %llx]", endx ? "and" : "==>", start, end);
0272 } else {
0273 printk(KERN_CONT "%s\n", endx?"":" ==> none");
0274 continue;
0275 }
0276 }
0277 }
0278
0279 update_res(info, cap_resource(start), cap_resource(end),
0280 IORESOURCE_MEM, 1);
0281 subtract_range(range, RANGE_NUM, start, end + 1);
0282 printk(KERN_CONT "\n");
0283 }
0284
0285
0286
0287 address = MSR_AMD64_SYSCFG;
0288 rdmsrl(address, val);
0289
0290 if (val & (1<<21)) {
0291
0292 address = MSR_K8_TOP_MEM2;
0293 rdmsrl(address, val);
0294 end = (val & 0xffffff800000ULL);
0295 printk(KERN_INFO "TOM2: %016llx aka %lldM\n", end, end>>20);
0296 subtract_range(range, RANGE_NUM, 1ULL<<32, end);
0297 }
0298
0299
0300
0301
0302
0303 info = find_pci_root_info(def_node, def_link);
0304 if (info) {
0305 for (i = 0; i < RANGE_NUM; i++) {
0306 if (!range[i].end)
0307 continue;
0308
0309 update_res(info, cap_resource(range[i].start),
0310 cap_resource(range[i].end - 1),
0311 IORESOURCE_MEM, 1);
0312 }
0313 }
0314
0315 list_for_each_entry(info, &pci_root_infos, list) {
0316 int busnum;
0317 struct pci_root_res *root_res;
0318
0319 busnum = info->busn.start;
0320 printk(KERN_DEBUG "bus: %pR on node %x link %x\n",
0321 &info->busn, info->node, info->link);
0322 list_for_each_entry(root_res, &info->resources, list)
0323 printk(KERN_DEBUG "bus: %02x %pR\n",
0324 busnum, &root_res->res);
0325 }
0326
0327 return 0;
0328 }
0329
0330 #define ENABLE_CF8_EXT_CFG (1ULL << 46)
0331
0332 static int amd_bus_cpu_online(unsigned int cpu)
0333 {
0334 u64 reg;
0335
0336 rdmsrl(MSR_AMD64_NB_CFG, reg);
0337 if (!(reg & ENABLE_CF8_EXT_CFG)) {
0338 reg |= ENABLE_CF8_EXT_CFG;
0339 wrmsrl(MSR_AMD64_NB_CFG, reg);
0340 }
0341 return 0;
0342 }
0343
0344 static void __init pci_enable_pci_io_ecs(void)
0345 {
0346 #ifdef CONFIG_AMD_NB
0347 unsigned int i, n;
0348
0349 for (n = i = 0; !n && amd_nb_bus_dev_ranges[i].dev_limit; ++i) {
0350 u8 bus = amd_nb_bus_dev_ranges[i].bus;
0351 u8 slot = amd_nb_bus_dev_ranges[i].dev_base;
0352 u8 limit = amd_nb_bus_dev_ranges[i].dev_limit;
0353
0354 for (; slot < limit; ++slot) {
0355 u32 val = read_pci_config(bus, slot, 3, 0);
0356
0357 if (!early_is_amd_nb(val))
0358 continue;
0359
0360 val = read_pci_config(bus, slot, 3, 0x8c);
0361 if (!(val & (ENABLE_CF8_EXT_CFG >> 32))) {
0362 val |= ENABLE_CF8_EXT_CFG >> 32;
0363 write_pci_config(bus, slot, 3, 0x8c, val);
0364 }
0365 ++n;
0366 }
0367 }
0368 #endif
0369 }
0370
0371 static int __init pci_io_ecs_init(void)
0372 {
0373 int ret;
0374
0375
0376 if (boot_cpu_data.x86 < 0x10)
0377 return 0;
0378
0379
0380 if (early_pci_allowed())
0381 pci_enable_pci_io_ecs();
0382
0383 ret = cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, "pci/amd_bus:online",
0384 amd_bus_cpu_online, NULL);
0385 WARN_ON(ret < 0);
0386
0387 pci_probe |= PCI_HAS_IO_ECS;
0388
0389 return 0;
0390 }
0391
0392 static int __init amd_postcore_init(void)
0393 {
0394 if (boot_cpu_data.x86_vendor != X86_VENDOR_AMD &&
0395 boot_cpu_data.x86_vendor != X86_VENDOR_HYGON)
0396 return 0;
0397
0398 early_root_info_init();
0399 pci_io_ecs_init();
0400
0401 return 0;
0402 }
0403
0404 postcore_initcall(amd_postcore_init);