Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/arch/x86/pci/mmconfig-shared.c
26424 views
1
// SPDX-License-Identifier: GPL-2.0
2
/*
3
* Low-level direct PCI config space access via ECAM - common code between
4
* i386 and x86-64.
5
*
6
* This code does:
7
* - known chipset handling
8
* - ACPI decoding and validation
9
*
10
* Per-architecture code takes care of the mappings and accesses
11
* themselves.
12
*/
13
14
#define pr_fmt(fmt) "PCI: " fmt
15
16
#include <linux/acpi.h>
17
#include <linux/efi.h>
18
#include <linux/pci.h>
19
#include <linux/init.h>
20
#include <linux/bitmap.h>
21
#include <linux/dmi.h>
22
#include <linux/slab.h>
23
#include <linux/mutex.h>
24
#include <linux/rculist.h>
25
#include <asm/acpi.h>
26
#include <asm/e820/api.h>
27
#include <asm/msr.h>
28
#include <asm/pci_x86.h>
29
30
/* Indicate if the ECAM resources have been placed into the resource table */
31
static bool pci_mmcfg_running_state;
32
static bool pci_mmcfg_arch_init_failed;
33
static DEFINE_MUTEX(pci_mmcfg_lock);
34
#define pci_mmcfg_lock_held() lock_is_held(&(pci_mmcfg_lock).dep_map)
35
36
LIST_HEAD(pci_mmcfg_list);
37
38
static void __init pci_mmconfig_remove(struct pci_mmcfg_region *cfg)
39
{
40
if (cfg->res.parent)
41
release_resource(&cfg->res);
42
list_del(&cfg->list);
43
kfree(cfg);
44
}
45
46
static void __init free_all_mmcfg(void)
47
{
48
struct pci_mmcfg_region *cfg, *tmp;
49
50
pci_mmcfg_arch_free();
51
list_for_each_entry_safe(cfg, tmp, &pci_mmcfg_list, list)
52
pci_mmconfig_remove(cfg);
53
}
54
55
static void list_add_sorted(struct pci_mmcfg_region *new)
56
{
57
struct pci_mmcfg_region *cfg;
58
59
/* keep list sorted by segment and starting bus number */
60
list_for_each_entry_rcu(cfg, &pci_mmcfg_list, list, pci_mmcfg_lock_held()) {
61
if (cfg->segment > new->segment ||
62
(cfg->segment == new->segment &&
63
cfg->start_bus >= new->start_bus)) {
64
list_add_tail_rcu(&new->list, &cfg->list);
65
return;
66
}
67
}
68
list_add_tail_rcu(&new->list, &pci_mmcfg_list);
69
}
70
71
static struct pci_mmcfg_region *pci_mmconfig_alloc(int segment, int start,
72
int end, u64 addr)
73
{
74
struct pci_mmcfg_region *new;
75
struct resource *res;
76
77
if (addr == 0)
78
return NULL;
79
80
new = kzalloc(sizeof(*new), GFP_KERNEL);
81
if (!new)
82
return NULL;
83
84
new->address = addr;
85
new->segment = segment;
86
new->start_bus = start;
87
new->end_bus = end;
88
89
res = &new->res;
90
res->start = addr + PCI_MMCFG_BUS_OFFSET(start);
91
res->end = addr + PCI_MMCFG_BUS_OFFSET(end + 1) - 1;
92
res->flags = IORESOURCE_MEM | IORESOURCE_BUSY;
93
snprintf(new->name, PCI_MMCFG_RESOURCE_NAME_LEN,
94
"PCI ECAM %04x [bus %02x-%02x]", segment, start, end);
95
res->name = new->name;
96
97
return new;
98
}
99
100
struct pci_mmcfg_region *__init pci_mmconfig_add(int segment, int start,
101
int end, u64 addr)
102
{
103
struct pci_mmcfg_region *new;
104
105
new = pci_mmconfig_alloc(segment, start, end, addr);
106
if (!new)
107
return NULL;
108
109
mutex_lock(&pci_mmcfg_lock);
110
list_add_sorted(new);
111
mutex_unlock(&pci_mmcfg_lock);
112
113
pr_info("ECAM %pR (base %#lx) for domain %04x [bus %02x-%02x]\n",
114
&new->res, (unsigned long)addr, segment, start, end);
115
116
return new;
117
}
118
119
struct pci_mmcfg_region *pci_mmconfig_lookup(int segment, int bus)
120
{
121
struct pci_mmcfg_region *cfg;
122
123
list_for_each_entry_rcu(cfg, &pci_mmcfg_list, list, pci_mmcfg_lock_held())
124
if (cfg->segment == segment &&
125
cfg->start_bus <= bus && bus <= cfg->end_bus)
126
return cfg;
127
128
return NULL;
129
}
130
131
static const char *__init pci_mmcfg_e7520(void)
132
{
133
u32 win;
134
raw_pci_ops->read(0, 0, PCI_DEVFN(0, 0), 0xce, 2, &win);
135
136
win = win & 0xf000;
137
if (win == 0x0000 || win == 0xf000)
138
return NULL;
139
140
if (pci_mmconfig_add(0, 0, 255, win << 16) == NULL)
141
return NULL;
142
143
return "Intel Corporation E7520 Memory Controller Hub";
144
}
145
146
static const char *__init pci_mmcfg_intel_945(void)
147
{
148
u32 pciexbar, mask = 0, len = 0;
149
150
raw_pci_ops->read(0, 0, PCI_DEVFN(0, 0), 0x48, 4, &pciexbar);
151
152
/* Enable bit */
153
if (!(pciexbar & 1))
154
return NULL;
155
156
/* Size bits */
157
switch ((pciexbar >> 1) & 3) {
158
case 0:
159
mask = 0xf0000000U;
160
len = 0x10000000U;
161
break;
162
case 1:
163
mask = 0xf8000000U;
164
len = 0x08000000U;
165
break;
166
case 2:
167
mask = 0xfc000000U;
168
len = 0x04000000U;
169
break;
170
default:
171
return NULL;
172
}
173
174
/* Errata #2, things break when not aligned on a 256Mb boundary */
175
/* Can only happen in 64M/128M mode */
176
177
if ((pciexbar & mask) & 0x0fffffffU)
178
return NULL;
179
180
/* Don't hit the APIC registers and their friends */
181
if ((pciexbar & mask) >= 0xf0000000U)
182
return NULL;
183
184
if (pci_mmconfig_add(0, 0, (len >> 20) - 1, pciexbar & mask) == NULL)
185
return NULL;
186
187
return "Intel Corporation 945G/GZ/P/PL Express Memory Controller Hub";
188
}
189
190
static const char *__init pci_mmcfg_amd_fam10h(void)
191
{
192
u32 low, high, address;
193
u64 base, msr;
194
int i;
195
unsigned segnbits = 0, busnbits, end_bus;
196
197
if (!(pci_probe & PCI_CHECK_ENABLE_AMD_MMCONF))
198
return NULL;
199
200
address = MSR_FAM10H_MMIO_CONF_BASE;
201
if (rdmsr_safe(address, &low, &high))
202
return NULL;
203
204
msr = high;
205
msr <<= 32;
206
msr |= low;
207
208
/* ECAM is not enabled */
209
if (!(msr & FAM10H_MMIO_CONF_ENABLE))
210
return NULL;
211
212
base = msr & (FAM10H_MMIO_CONF_BASE_MASK<<FAM10H_MMIO_CONF_BASE_SHIFT);
213
214
busnbits = (msr >> FAM10H_MMIO_CONF_BUSRANGE_SHIFT) &
215
FAM10H_MMIO_CONF_BUSRANGE_MASK;
216
217
/*
218
* only handle bus 0 ?
219
* need to skip it
220
*/
221
if (!busnbits)
222
return NULL;
223
224
if (busnbits > 8) {
225
segnbits = busnbits - 8;
226
busnbits = 8;
227
}
228
229
end_bus = (1 << busnbits) - 1;
230
for (i = 0; i < (1 << segnbits); i++)
231
if (pci_mmconfig_add(i, 0, end_bus,
232
base + (1<<28) * i) == NULL) {
233
free_all_mmcfg();
234
return NULL;
235
}
236
237
return "AMD Family 10h NB";
238
}
239
240
static bool __initdata mcp55_checked;
241
static const char *__init pci_mmcfg_nvidia_mcp55(void)
242
{
243
int bus;
244
int mcp55_mmconf_found = 0;
245
246
static const u32 extcfg_regnum __initconst = 0x90;
247
static const u32 extcfg_regsize __initconst = 4;
248
static const u32 extcfg_enable_mask __initconst = 1 << 31;
249
static const u32 extcfg_start_mask __initconst = 0xff << 16;
250
static const int extcfg_start_shift __initconst = 16;
251
static const u32 extcfg_size_mask __initconst = 0x3 << 28;
252
static const int extcfg_size_shift __initconst = 28;
253
static const int extcfg_sizebus[] __initconst = {
254
0x100, 0x80, 0x40, 0x20
255
};
256
static const u32 extcfg_base_mask[] __initconst = {
257
0x7ff8, 0x7ffc, 0x7ffe, 0x7fff
258
};
259
static const int extcfg_base_lshift __initconst = 25;
260
261
/*
262
* do check if amd fam10h already took over
263
*/
264
if (!acpi_disabled || !list_empty(&pci_mmcfg_list) || mcp55_checked)
265
return NULL;
266
267
mcp55_checked = true;
268
for (bus = 0; bus < 256; bus++) {
269
u64 base;
270
u32 l, extcfg;
271
u16 vendor, device;
272
int start, size_index, end;
273
274
raw_pci_ops->read(0, bus, PCI_DEVFN(0, 0), 0, 4, &l);
275
vendor = l & 0xffff;
276
device = (l >> 16) & 0xffff;
277
278
if (PCI_VENDOR_ID_NVIDIA != vendor || 0x0369 != device)
279
continue;
280
281
raw_pci_ops->read(0, bus, PCI_DEVFN(0, 0), extcfg_regnum,
282
extcfg_regsize, &extcfg);
283
284
if (!(extcfg & extcfg_enable_mask))
285
continue;
286
287
size_index = (extcfg & extcfg_size_mask) >> extcfg_size_shift;
288
base = extcfg & extcfg_base_mask[size_index];
289
/* base could > 4G */
290
base <<= extcfg_base_lshift;
291
start = (extcfg & extcfg_start_mask) >> extcfg_start_shift;
292
end = start + extcfg_sizebus[size_index] - 1;
293
if (pci_mmconfig_add(0, start, end, base) == NULL)
294
continue;
295
mcp55_mmconf_found++;
296
}
297
298
if (!mcp55_mmconf_found)
299
return NULL;
300
301
return "nVidia MCP55";
302
}
303
304
struct pci_mmcfg_hostbridge_probe {
305
u32 bus;
306
u32 devfn;
307
u32 vendor;
308
u32 device;
309
const char *(*probe)(void);
310
};
311
312
static const struct pci_mmcfg_hostbridge_probe pci_mmcfg_probes[] __initconst = {
313
{ 0, PCI_DEVFN(0, 0), PCI_VENDOR_ID_INTEL,
314
PCI_DEVICE_ID_INTEL_E7520_MCH, pci_mmcfg_e7520 },
315
{ 0, PCI_DEVFN(0, 0), PCI_VENDOR_ID_INTEL,
316
PCI_DEVICE_ID_INTEL_82945G_HB, pci_mmcfg_intel_945 },
317
{ 0, PCI_DEVFN(0x18, 0), PCI_VENDOR_ID_AMD,
318
0x1200, pci_mmcfg_amd_fam10h },
319
{ 0xff, PCI_DEVFN(0, 0), PCI_VENDOR_ID_AMD,
320
0x1200, pci_mmcfg_amd_fam10h },
321
{ 0, PCI_DEVFN(0, 0), PCI_VENDOR_ID_NVIDIA,
322
0x0369, pci_mmcfg_nvidia_mcp55 },
323
};
324
325
static void __init pci_mmcfg_check_end_bus_number(void)
326
{
327
struct pci_mmcfg_region *cfg, *cfgx;
328
329
/* Fixup overlaps */
330
list_for_each_entry(cfg, &pci_mmcfg_list, list) {
331
if (cfg->end_bus < cfg->start_bus)
332
cfg->end_bus = 255;
333
334
/* Don't access the list head ! */
335
if (cfg->list.next == &pci_mmcfg_list)
336
break;
337
338
cfgx = list_entry(cfg->list.next, typeof(*cfg), list);
339
if (cfg->end_bus >= cfgx->start_bus)
340
cfg->end_bus = cfgx->start_bus - 1;
341
}
342
}
343
344
static int __init pci_mmcfg_check_hostbridge(void)
345
{
346
u32 l;
347
u32 bus, devfn;
348
u16 vendor, device;
349
int i;
350
const char *name;
351
352
if (!raw_pci_ops)
353
return 0;
354
355
free_all_mmcfg();
356
357
for (i = 0; i < ARRAY_SIZE(pci_mmcfg_probes); i++) {
358
bus = pci_mmcfg_probes[i].bus;
359
devfn = pci_mmcfg_probes[i].devfn;
360
raw_pci_ops->read(0, bus, devfn, 0, 4, &l);
361
vendor = l & 0xffff;
362
device = (l >> 16) & 0xffff;
363
364
name = NULL;
365
if (pci_mmcfg_probes[i].vendor == vendor &&
366
pci_mmcfg_probes[i].device == device)
367
name = pci_mmcfg_probes[i].probe();
368
369
if (name)
370
pr_info("%s with ECAM support\n", name);
371
}
372
373
/* some end_bus_number is crazy, fix it */
374
pci_mmcfg_check_end_bus_number();
375
376
return !list_empty(&pci_mmcfg_list);
377
}
378
379
static acpi_status check_mcfg_resource(struct acpi_resource *res, void *data)
380
{
381
struct resource *mcfg_res = data;
382
struct acpi_resource_address64 address;
383
acpi_status status;
384
385
if (res->type == ACPI_RESOURCE_TYPE_FIXED_MEMORY32) {
386
struct acpi_resource_fixed_memory32 *fixmem32 =
387
&res->data.fixed_memory32;
388
if (!fixmem32)
389
return AE_OK;
390
if ((mcfg_res->start >= fixmem32->address) &&
391
(mcfg_res->end < (fixmem32->address +
392
fixmem32->address_length))) {
393
mcfg_res->flags = 1;
394
return AE_CTRL_TERMINATE;
395
}
396
}
397
if ((res->type != ACPI_RESOURCE_TYPE_ADDRESS32) &&
398
(res->type != ACPI_RESOURCE_TYPE_ADDRESS64))
399
return AE_OK;
400
401
status = acpi_resource_to_address64(res, &address);
402
if (ACPI_FAILURE(status) ||
403
(address.address.address_length <= 0) ||
404
(address.resource_type != ACPI_MEMORY_RANGE))
405
return AE_OK;
406
407
if ((mcfg_res->start >= address.address.minimum) &&
408
(mcfg_res->end < (address.address.minimum + address.address.address_length))) {
409
mcfg_res->flags = 1;
410
return AE_CTRL_TERMINATE;
411
}
412
return AE_OK;
413
}
414
415
static acpi_status find_mboard_resource(acpi_handle handle, u32 lvl,
416
void *context, void **rv)
417
{
418
struct resource *mcfg_res = context;
419
420
acpi_walk_resources(handle, METHOD_NAME__CRS,
421
check_mcfg_resource, context);
422
423
if (mcfg_res->flags)
424
return AE_CTRL_TERMINATE;
425
426
return AE_OK;
427
}
428
429
static bool is_acpi_reserved(u64 start, u64 end, enum e820_type not_used)
430
{
431
struct resource mcfg_res;
432
433
mcfg_res.start = start;
434
mcfg_res.end = end - 1;
435
mcfg_res.flags = 0;
436
437
acpi_get_devices("PNP0C01", find_mboard_resource, &mcfg_res, NULL);
438
439
if (!mcfg_res.flags)
440
acpi_get_devices("PNP0C02", find_mboard_resource, &mcfg_res,
441
NULL);
442
443
return mcfg_res.flags;
444
}
445
446
static bool is_efi_mmio(struct resource *res)
447
{
448
#ifdef CONFIG_EFI
449
u64 start = res->start;
450
u64 end = res->start + resource_size(res);
451
efi_memory_desc_t *md;
452
u64 size, mmio_start, mmio_end;
453
454
for_each_efi_memory_desc(md) {
455
if (md->type == EFI_MEMORY_MAPPED_IO) {
456
size = md->num_pages << EFI_PAGE_SHIFT;
457
mmio_start = md->phys_addr;
458
mmio_end = mmio_start + size;
459
460
if (mmio_start <= start && end <= mmio_end)
461
return true;
462
}
463
}
464
#endif
465
466
return false;
467
}
468
469
typedef bool (*check_reserved_t)(u64 start, u64 end, enum e820_type type);
470
471
static bool __ref is_mmconf_reserved(check_reserved_t is_reserved,
472
struct pci_mmcfg_region *cfg,
473
struct device *dev, const char *method)
474
{
475
u64 addr = cfg->res.start;
476
u64 size = resource_size(&cfg->res);
477
u64 old_size = size;
478
int num_buses;
479
480
while (!is_reserved(addr, addr + size, E820_TYPE_RESERVED)) {
481
size >>= 1;
482
if (size < (16UL<<20))
483
break;
484
}
485
486
if (size < (16UL<<20) && size != old_size)
487
return false;
488
489
if (dev)
490
dev_info(dev, "ECAM %pR reserved as %s\n",
491
&cfg->res, method);
492
else
493
pr_info("ECAM %pR reserved as %s\n", &cfg->res, method);
494
495
if (old_size != size) {
496
/* update end_bus */
497
cfg->end_bus = cfg->start_bus + ((size>>20) - 1);
498
num_buses = cfg->end_bus - cfg->start_bus + 1;
499
cfg->res.end = cfg->res.start +
500
PCI_MMCFG_BUS_OFFSET(num_buses) - 1;
501
snprintf(cfg->name, PCI_MMCFG_RESOURCE_NAME_LEN,
502
"PCI ECAM %04x [bus %02x-%02x]",
503
cfg->segment, cfg->start_bus, cfg->end_bus);
504
505
if (dev)
506
dev_info(dev, "ECAM %pR (base %#lx) (size reduced!)\n",
507
&cfg->res, (unsigned long) cfg->address);
508
else
509
pr_info("ECAM %pR (base %#lx) for %04x [bus%02x-%02x] (size reduced!)\n",
510
&cfg->res, (unsigned long) cfg->address,
511
cfg->segment, cfg->start_bus, cfg->end_bus);
512
}
513
514
return true;
515
}
516
517
static bool __ref pci_mmcfg_reserved(struct device *dev,
518
struct pci_mmcfg_region *cfg, int early)
519
{
520
struct resource *conflict;
521
522
if (early) {
523
524
/*
525
* Don't try to do this check unless configuration type 1
526
* is available. How about type 2?
527
*/
528
529
/*
530
* 946f2ee5c731 ("Check that MCFG points to an e820
531
* reserved area") added this E820 check in 2006 to work
532
* around BIOS defects.
533
*
534
* Per PCI Firmware r3.3, sec 4.1.2, ECAM space must be
535
* reserved by a PNP0C02 resource, but it need not be
536
* mentioned in E820. Before the ACPI interpreter is
537
* available, we can't check for PNP0C02 resources, so
538
* there's no reliable way to verify the region in this
539
* early check. Keep it only for the old machines that
540
* motivated 946f2ee5c731.
541
*/
542
if (dmi_get_bios_year() < 2016 && raw_pci_ops)
543
return is_mmconf_reserved(e820__mapped_all, cfg, dev,
544
"E820 entry");
545
546
return true;
547
}
548
549
if (!acpi_disabled) {
550
if (is_mmconf_reserved(is_acpi_reserved, cfg, dev,
551
"ACPI motherboard resource"))
552
return true;
553
554
if (dev)
555
dev_info(dev, FW_INFO "ECAM %pR not reserved in ACPI motherboard resources\n",
556
&cfg->res);
557
else
558
pr_info(FW_INFO "ECAM %pR not reserved in ACPI motherboard resources\n",
559
&cfg->res);
560
561
if (is_efi_mmio(&cfg->res)) {
562
pr_info("ECAM %pR is EfiMemoryMappedIO; assuming valid\n",
563
&cfg->res);
564
conflict = insert_resource_conflict(&iomem_resource,
565
&cfg->res);
566
if (conflict)
567
pr_warn("ECAM %pR conflicts with %s %pR\n",
568
&cfg->res, conflict->name, conflict);
569
else
570
pr_info("ECAM %pR reserved to work around lack of ACPI motherboard _CRS\n",
571
&cfg->res);
572
return true;
573
}
574
}
575
576
/*
577
* e820__mapped_all() is marked as __init.
578
* All entries from ACPI MCFG table have been checked at boot time.
579
* For MCFG information constructed from hotpluggable host bridge's
580
* _CBA method, just assume it's reserved.
581
*/
582
return pci_mmcfg_running_state;
583
}
584
585
static void __init pci_mmcfg_reject_broken(int early)
586
{
587
struct pci_mmcfg_region *cfg;
588
589
list_for_each_entry(cfg, &pci_mmcfg_list, list) {
590
if (!pci_mmcfg_reserved(NULL, cfg, early)) {
591
pr_info("not using ECAM (%pR not reserved)\n",
592
&cfg->res);
593
free_all_mmcfg();
594
return;
595
}
596
}
597
}
598
599
static bool __init acpi_mcfg_valid_entry(struct acpi_table_mcfg *mcfg,
600
struct acpi_mcfg_allocation *cfg)
601
{
602
if (cfg->address < 0xFFFFFFFF)
603
return true;
604
605
if (!strncmp(mcfg->header.oem_id, "SGI", 3))
606
return true;
607
608
if ((mcfg->header.revision >= 1) && (dmi_get_bios_year() >= 2010))
609
return true;
610
611
pr_err("ECAM at %#llx for %04x [bus %02x-%02x] is above 4GB, ignored\n",
612
cfg->address, cfg->pci_segment, cfg->start_bus_number,
613
cfg->end_bus_number);
614
return false;
615
}
616
617
static int __init pci_parse_mcfg(struct acpi_table_header *header)
618
{
619
struct acpi_table_mcfg *mcfg;
620
struct acpi_mcfg_allocation *cfg_table, *cfg;
621
unsigned long i;
622
int entries;
623
624
if (!header)
625
return -EINVAL;
626
627
mcfg = (struct acpi_table_mcfg *)header;
628
629
/* how many config structures do we have */
630
free_all_mmcfg();
631
entries = 0;
632
i = header->length - sizeof(struct acpi_table_mcfg);
633
while (i >= sizeof(struct acpi_mcfg_allocation)) {
634
entries++;
635
i -= sizeof(struct acpi_mcfg_allocation);
636
}
637
if (entries == 0) {
638
pr_err("MCFG has no entries\n");
639
return -ENODEV;
640
}
641
642
cfg_table = (struct acpi_mcfg_allocation *) &mcfg[1];
643
for (i = 0; i < entries; i++) {
644
cfg = &cfg_table[i];
645
if (!acpi_mcfg_valid_entry(mcfg, cfg)) {
646
free_all_mmcfg();
647
return -ENODEV;
648
}
649
650
if (pci_mmconfig_add(cfg->pci_segment, cfg->start_bus_number,
651
cfg->end_bus_number, cfg->address) == NULL) {
652
pr_warn("no memory for MCFG entries\n");
653
free_all_mmcfg();
654
return -ENOMEM;
655
}
656
}
657
658
return 0;
659
}
660
661
#ifdef CONFIG_ACPI_APEI
662
extern int (*arch_apei_filter_addr)(int (*func)(__u64 start, __u64 size,
663
void *data), void *data);
664
665
static int pci_mmcfg_for_each_region(int (*func)(__u64 start, __u64 size,
666
void *data), void *data)
667
{
668
struct pci_mmcfg_region *cfg;
669
int rc;
670
671
if (list_empty(&pci_mmcfg_list))
672
return 0;
673
674
list_for_each_entry(cfg, &pci_mmcfg_list, list) {
675
rc = func(cfg->res.start, resource_size(&cfg->res), data);
676
if (rc)
677
return rc;
678
}
679
680
return 0;
681
}
682
#define set_apei_filter() (arch_apei_filter_addr = pci_mmcfg_for_each_region)
683
#else
684
#define set_apei_filter()
685
#endif
686
687
static void __init __pci_mmcfg_init(int early)
688
{
689
pr_debug("%s(%s)\n", __func__, early ? "early" : "late");
690
691
pci_mmcfg_reject_broken(early);
692
if (list_empty(&pci_mmcfg_list))
693
return;
694
695
if (pcibios_last_bus < 0) {
696
const struct pci_mmcfg_region *cfg;
697
698
list_for_each_entry(cfg, &pci_mmcfg_list, list) {
699
if (cfg->segment)
700
break;
701
pcibios_last_bus = cfg->end_bus;
702
}
703
}
704
705
if (pci_mmcfg_arch_init())
706
pci_probe = (pci_probe & ~PCI_PROBE_MASK) | PCI_PROBE_MMCONF;
707
else {
708
free_all_mmcfg();
709
pci_mmcfg_arch_init_failed = true;
710
}
711
}
712
713
static int __initdata known_bridge;
714
715
void __init pci_mmcfg_early_init(void)
716
{
717
pr_debug("%s() pci_probe %#x\n", __func__, pci_probe);
718
719
if (pci_probe & PCI_PROBE_MMCONF) {
720
if (pci_mmcfg_check_hostbridge())
721
known_bridge = 1;
722
else
723
acpi_table_parse(ACPI_SIG_MCFG, pci_parse_mcfg);
724
__pci_mmcfg_init(1);
725
726
set_apei_filter();
727
}
728
}
729
730
void __init pci_mmcfg_late_init(void)
731
{
732
pr_debug("%s() pci_probe %#x\n", __func__, pci_probe);
733
734
/* ECAM disabled */
735
if ((pci_probe & PCI_PROBE_MMCONF) == 0)
736
return;
737
738
if (known_bridge)
739
return;
740
741
/* ECAM hasn't been enabled yet, try again */
742
if (pci_probe & PCI_PROBE_MASK & ~PCI_PROBE_MMCONF) {
743
acpi_table_parse(ACPI_SIG_MCFG, pci_parse_mcfg);
744
__pci_mmcfg_init(0);
745
}
746
}
747
748
static int __init pci_mmcfg_late_insert_resources(void)
749
{
750
struct pci_mmcfg_region *cfg;
751
752
pci_mmcfg_running_state = true;
753
754
pr_debug("%s() pci_probe %#x\n", __func__, pci_probe);
755
756
/* If we are not using ECAM, don't insert the resources. */
757
if ((pci_probe & PCI_PROBE_MMCONF) == 0)
758
return 1;
759
760
/*
761
* Attempt to insert the mmcfg resources but not with the busy flag
762
* marked so it won't cause request errors when __request_region is
763
* called.
764
*/
765
list_for_each_entry(cfg, &pci_mmcfg_list, list) {
766
if (!cfg->res.parent) {
767
pr_debug("%s() insert %pR\n", __func__, &cfg->res);
768
insert_resource(&iomem_resource, &cfg->res);
769
}
770
}
771
772
return 0;
773
}
774
775
/*
776
* Perform ECAM resource insertion after PCI initialization to allow for
777
* misprogrammed MCFG tables that state larger sizes but actually conflict
778
* with other system resources.
779
*/
780
late_initcall(pci_mmcfg_late_insert_resources);
781
782
/* Add ECAM information for host bridges */
783
int pci_mmconfig_insert(struct device *dev, u16 seg, u8 start, u8 end,
784
phys_addr_t addr)
785
{
786
int rc;
787
struct resource *tmp = NULL;
788
struct pci_mmcfg_region *cfg;
789
790
dev_dbg(dev, "%s(%04x [bus %02x-%02x])\n", __func__, seg, start, end);
791
792
if (!(pci_probe & PCI_PROBE_MMCONF) || pci_mmcfg_arch_init_failed)
793
return -ENODEV;
794
795
if (start > end)
796
return -EINVAL;
797
798
mutex_lock(&pci_mmcfg_lock);
799
cfg = pci_mmconfig_lookup(seg, start);
800
if (cfg) {
801
if (cfg->end_bus < end)
802
dev_info(dev, FW_INFO "ECAM %pR for domain %04x [bus %02x-%02x] only partially covers this bridge\n",
803
&cfg->res, cfg->segment, cfg->start_bus,
804
cfg->end_bus);
805
mutex_unlock(&pci_mmcfg_lock);
806
return -EEXIST;
807
}
808
809
/*
810
* Don't move earlier; we must return -EEXIST, not -EINVAL, if
811
* pci_mmconfig_lookup() finds something
812
*/
813
if (!addr) {
814
mutex_unlock(&pci_mmcfg_lock);
815
return -EINVAL;
816
}
817
818
rc = -EBUSY;
819
cfg = pci_mmconfig_alloc(seg, start, end, addr);
820
if (cfg == NULL) {
821
dev_warn(dev, "fail to add ECAM (out of memory)\n");
822
rc = -ENOMEM;
823
} else if (!pci_mmcfg_reserved(dev, cfg, 0)) {
824
dev_warn(dev, FW_BUG "ECAM %pR isn't reserved\n",
825
&cfg->res);
826
} else {
827
/* Insert resource if it's not in boot stage */
828
if (pci_mmcfg_running_state)
829
tmp = insert_resource_conflict(&iomem_resource,
830
&cfg->res);
831
832
if (tmp) {
833
dev_warn(dev, "ECAM %pR conflicts with %s %pR\n",
834
&cfg->res, tmp->name, tmp);
835
} else if (pci_mmcfg_arch_map(cfg)) {
836
dev_warn(dev, "fail to map ECAM %pR\n", &cfg->res);
837
} else {
838
list_add_sorted(cfg);
839
dev_info(dev, "ECAM %pR (base %#lx)\n",
840
&cfg->res, (unsigned long)addr);
841
cfg = NULL;
842
rc = 0;
843
}
844
}
845
846
if (cfg) {
847
if (cfg->res.parent)
848
release_resource(&cfg->res);
849
kfree(cfg);
850
}
851
852
mutex_unlock(&pci_mmcfg_lock);
853
854
return rc;
855
}
856
857
/* Delete ECAM information for host bridges */
858
int pci_mmconfig_delete(u16 seg, u8 start, u8 end)
859
{
860
struct pci_mmcfg_region *cfg;
861
862
mutex_lock(&pci_mmcfg_lock);
863
list_for_each_entry_rcu(cfg, &pci_mmcfg_list, list)
864
if (cfg->segment == seg && cfg->start_bus == start &&
865
cfg->end_bus == end) {
866
list_del_rcu(&cfg->list);
867
synchronize_rcu();
868
pci_mmcfg_arch_unmap(cfg);
869
if (cfg->res.parent)
870
release_resource(&cfg->res);
871
mutex_unlock(&pci_mmcfg_lock);
872
kfree(cfg);
873
return 0;
874
}
875
mutex_unlock(&pci_mmcfg_lock);
876
877
return -ENOENT;
878
}
879
880