Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/arch/x86/kernel/aperture_64.c
10817 views
1
/*
2
* Firmware replacement code.
3
*
4
* Work around broken BIOSes that don't set an aperture, only set the
5
* aperture in the AGP bridge, or set too small aperture.
6
*
7
* If all fails map the aperture over some low memory. This is cheaper than
8
* doing bounce buffering. The memory is lost. This is done at early boot
9
* because only the bootmem allocator can allocate 32+MB.
10
*
11
* Copyright 2002 Andi Kleen, SuSE Labs.
12
*/
13
#include <linux/kernel.h>
14
#include <linux/types.h>
15
#include <linux/init.h>
16
#include <linux/memblock.h>
17
#include <linux/mmzone.h>
18
#include <linux/pci_ids.h>
19
#include <linux/pci.h>
20
#include <linux/bitops.h>
21
#include <linux/ioport.h>
22
#include <linux/suspend.h>
23
#include <linux/kmemleak.h>
24
#include <asm/e820.h>
25
#include <asm/io.h>
26
#include <asm/iommu.h>
27
#include <asm/gart.h>
28
#include <asm/pci-direct.h>
29
#include <asm/dma.h>
30
#include <asm/amd_nb.h>
31
#include <asm/x86_init.h>
32
33
/*
34
* Using 512M as goal, in case kexec will load kernel_big
35
* that will do the on-position decompress, and could overlap with
36
* with the gart aperture that is used.
37
* Sequence:
38
* kernel_small
39
* ==> kexec (with kdump trigger path or gart still enabled)
40
* ==> kernel_small (gart area become e820_reserved)
41
* ==> kexec (with kdump trigger path or gart still enabled)
42
* ==> kerne_big (uncompressed size will be big than 64M or 128M)
43
* So don't use 512M below as gart iommu, leave the space for kernel
44
* code for safe.
45
*/
46
#define GART_MIN_ADDR (512ULL << 20)
47
#define GART_MAX_ADDR (1ULL << 32)
48
49
int gart_iommu_aperture;
50
int gart_iommu_aperture_disabled __initdata;
51
int gart_iommu_aperture_allowed __initdata;
52
53
int fallback_aper_order __initdata = 1; /* 64MB */
54
int fallback_aper_force __initdata;
55
56
int fix_aperture __initdata = 1;
57
58
static struct resource gart_resource = {
59
.name = "GART",
60
.flags = IORESOURCE_MEM,
61
};
62
63
static void __init insert_aperture_resource(u32 aper_base, u32 aper_size)
64
{
65
gart_resource.start = aper_base;
66
gart_resource.end = aper_base + aper_size - 1;
67
insert_resource(&iomem_resource, &gart_resource);
68
}
69
70
/* This code runs before the PCI subsystem is initialized, so just
71
access the northbridge directly. */
72
73
static u32 __init allocate_aperture(void)
74
{
75
u32 aper_size;
76
unsigned long addr;
77
78
/* aper_size should <= 1G */
79
if (fallback_aper_order > 5)
80
fallback_aper_order = 5;
81
aper_size = (32 * 1024 * 1024) << fallback_aper_order;
82
83
/*
84
* Aperture has to be naturally aligned. This means a 2GB aperture
85
* won't have much chance of finding a place in the lower 4GB of
86
* memory. Unfortunately we cannot move it up because that would
87
* make the IOMMU useless.
88
*/
89
addr = memblock_find_in_range(GART_MIN_ADDR, GART_MAX_ADDR,
90
aper_size, aper_size);
91
if (addr == MEMBLOCK_ERROR || addr + aper_size > GART_MAX_ADDR) {
92
printk(KERN_ERR
93
"Cannot allocate aperture memory hole (%lx,%uK)\n",
94
addr, aper_size>>10);
95
return 0;
96
}
97
memblock_x86_reserve_range(addr, addr + aper_size, "aperture64");
98
/*
99
* Kmemleak should not scan this block as it may not be mapped via the
100
* kernel direct mapping.
101
*/
102
kmemleak_ignore(phys_to_virt(addr));
103
printk(KERN_INFO "Mapping aperture over %d KB of RAM @ %lx\n",
104
aper_size >> 10, addr);
105
insert_aperture_resource((u32)addr, aper_size);
106
register_nosave_region(addr >> PAGE_SHIFT,
107
(addr+aper_size) >> PAGE_SHIFT);
108
109
return (u32)addr;
110
}
111
112
113
/* Find a PCI capability */
114
static u32 __init find_cap(int bus, int slot, int func, int cap)
115
{
116
int bytes;
117
u8 pos;
118
119
if (!(read_pci_config_16(bus, slot, func, PCI_STATUS) &
120
PCI_STATUS_CAP_LIST))
121
return 0;
122
123
pos = read_pci_config_byte(bus, slot, func, PCI_CAPABILITY_LIST);
124
for (bytes = 0; bytes < 48 && pos >= 0x40; bytes++) {
125
u8 id;
126
127
pos &= ~3;
128
id = read_pci_config_byte(bus, slot, func, pos+PCI_CAP_LIST_ID);
129
if (id == 0xff)
130
break;
131
if (id == cap)
132
return pos;
133
pos = read_pci_config_byte(bus, slot, func,
134
pos+PCI_CAP_LIST_NEXT);
135
}
136
return 0;
137
}
138
139
/* Read a standard AGPv3 bridge header */
140
static u32 __init read_agp(int bus, int slot, int func, int cap, u32 *order)
141
{
142
u32 apsize;
143
u32 apsizereg;
144
int nbits;
145
u32 aper_low, aper_hi;
146
u64 aper;
147
u32 old_order;
148
149
printk(KERN_INFO "AGP bridge at %02x:%02x:%02x\n", bus, slot, func);
150
apsizereg = read_pci_config_16(bus, slot, func, cap + 0x14);
151
if (apsizereg == 0xffffffff) {
152
printk(KERN_ERR "APSIZE in AGP bridge unreadable\n");
153
return 0;
154
}
155
156
/* old_order could be the value from NB gart setting */
157
old_order = *order;
158
159
apsize = apsizereg & 0xfff;
160
/* Some BIOS use weird encodings not in the AGPv3 table. */
161
if (apsize & 0xff)
162
apsize |= 0xf00;
163
nbits = hweight16(apsize);
164
*order = 7 - nbits;
165
if ((int)*order < 0) /* < 32MB */
166
*order = 0;
167
168
aper_low = read_pci_config(bus, slot, func, 0x10);
169
aper_hi = read_pci_config(bus, slot, func, 0x14);
170
aper = (aper_low & ~((1<<22)-1)) | ((u64)aper_hi << 32);
171
172
/*
173
* On some sick chips, APSIZE is 0. It means it wants 4G
174
* so let double check that order, and lets trust AMD NB settings:
175
*/
176
printk(KERN_INFO "Aperture from AGP @ %Lx old size %u MB\n",
177
aper, 32 << old_order);
178
if (aper + (32ULL<<(20 + *order)) > 0x100000000ULL) {
179
printk(KERN_INFO "Aperture size %u MB (APSIZE %x) is not right, using settings from NB\n",
180
32 << *order, apsizereg);
181
*order = old_order;
182
}
183
184
printk(KERN_INFO "Aperture from AGP @ %Lx size %u MB (APSIZE %x)\n",
185
aper, 32 << *order, apsizereg);
186
187
if (!aperture_valid(aper, (32*1024*1024) << *order, 32<<20))
188
return 0;
189
return (u32)aper;
190
}
191
192
/*
193
* Look for an AGP bridge. Windows only expects the aperture in the
194
* AGP bridge and some BIOS forget to initialize the Northbridge too.
195
* Work around this here.
196
*
197
* Do an PCI bus scan by hand because we're running before the PCI
198
* subsystem.
199
*
200
* All AMD AGP bridges are AGPv3 compliant, so we can do this scan
201
* generically. It's probably overkill to always scan all slots because
202
* the AGP bridges should be always an own bus on the HT hierarchy,
203
* but do it here for future safety.
204
*/
205
static u32 __init search_agp_bridge(u32 *order, int *valid_agp)
206
{
207
int bus, slot, func;
208
209
/* Poor man's PCI discovery */
210
for (bus = 0; bus < 256; bus++) {
211
for (slot = 0; slot < 32; slot++) {
212
for (func = 0; func < 8; func++) {
213
u32 class, cap;
214
u8 type;
215
class = read_pci_config(bus, slot, func,
216
PCI_CLASS_REVISION);
217
if (class == 0xffffffff)
218
break;
219
220
switch (class >> 16) {
221
case PCI_CLASS_BRIDGE_HOST:
222
case PCI_CLASS_BRIDGE_OTHER: /* needed? */
223
/* AGP bridge? */
224
cap = find_cap(bus, slot, func,
225
PCI_CAP_ID_AGP);
226
if (!cap)
227
break;
228
*valid_agp = 1;
229
return read_agp(bus, slot, func, cap,
230
order);
231
}
232
233
/* No multi-function device? */
234
type = read_pci_config_byte(bus, slot, func,
235
PCI_HEADER_TYPE);
236
if (!(type & 0x80))
237
break;
238
}
239
}
240
}
241
printk(KERN_INFO "No AGP bridge found\n");
242
243
return 0;
244
}
245
246
static int gart_fix_e820 __initdata = 1;
247
248
static int __init parse_gart_mem(char *p)
249
{
250
if (!p)
251
return -EINVAL;
252
253
if (!strncmp(p, "off", 3))
254
gart_fix_e820 = 0;
255
else if (!strncmp(p, "on", 2))
256
gart_fix_e820 = 1;
257
258
return 0;
259
}
260
early_param("gart_fix_e820", parse_gart_mem);
261
262
void __init early_gart_iommu_check(void)
263
{
264
/*
265
* in case it is enabled before, esp for kexec/kdump,
266
* previous kernel already enable that. memset called
267
* by allocate_aperture/__alloc_bootmem_nopanic cause restart.
268
* or second kernel have different position for GART hole. and new
269
* kernel could use hole as RAM that is still used by GART set by
270
* first kernel
271
* or BIOS forget to put that in reserved.
272
* try to update e820 to make that region as reserved.
273
*/
274
u32 agp_aper_order = 0;
275
int i, fix, slot, valid_agp = 0;
276
u32 ctl;
277
u32 aper_size = 0, aper_order = 0, last_aper_order = 0;
278
u64 aper_base = 0, last_aper_base = 0;
279
int aper_enabled = 0, last_aper_enabled = 0, last_valid = 0;
280
281
if (!early_pci_allowed())
282
return;
283
284
/* This is mostly duplicate of iommu_hole_init */
285
search_agp_bridge(&agp_aper_order, &valid_agp);
286
287
fix = 0;
288
for (i = 0; amd_nb_bus_dev_ranges[i].dev_limit; i++) {
289
int bus;
290
int dev_base, dev_limit;
291
292
bus = amd_nb_bus_dev_ranges[i].bus;
293
dev_base = amd_nb_bus_dev_ranges[i].dev_base;
294
dev_limit = amd_nb_bus_dev_ranges[i].dev_limit;
295
296
for (slot = dev_base; slot < dev_limit; slot++) {
297
if (!early_is_amd_nb(read_pci_config(bus, slot, 3, 0x00)))
298
continue;
299
300
ctl = read_pci_config(bus, slot, 3, AMD64_GARTAPERTURECTL);
301
aper_enabled = ctl & GARTEN;
302
aper_order = (ctl >> 1) & 7;
303
aper_size = (32 * 1024 * 1024) << aper_order;
304
aper_base = read_pci_config(bus, slot, 3, AMD64_GARTAPERTUREBASE) & 0x7fff;
305
aper_base <<= 25;
306
307
if (last_valid) {
308
if ((aper_order != last_aper_order) ||
309
(aper_base != last_aper_base) ||
310
(aper_enabled != last_aper_enabled)) {
311
fix = 1;
312
break;
313
}
314
}
315
316
last_aper_order = aper_order;
317
last_aper_base = aper_base;
318
last_aper_enabled = aper_enabled;
319
last_valid = 1;
320
}
321
}
322
323
if (!fix && !aper_enabled)
324
return;
325
326
if (!aper_base || !aper_size || aper_base + aper_size > 0x100000000UL)
327
fix = 1;
328
329
if (gart_fix_e820 && !fix && aper_enabled) {
330
if (e820_any_mapped(aper_base, aper_base + aper_size,
331
E820_RAM)) {
332
/* reserve it, so we can reuse it in second kernel */
333
printk(KERN_INFO "update e820 for GART\n");
334
e820_add_region(aper_base, aper_size, E820_RESERVED);
335
update_e820();
336
}
337
}
338
339
if (valid_agp)
340
return;
341
342
/* disable them all at first */
343
for (i = 0; i < amd_nb_bus_dev_ranges[i].dev_limit; i++) {
344
int bus;
345
int dev_base, dev_limit;
346
347
bus = amd_nb_bus_dev_ranges[i].bus;
348
dev_base = amd_nb_bus_dev_ranges[i].dev_base;
349
dev_limit = amd_nb_bus_dev_ranges[i].dev_limit;
350
351
for (slot = dev_base; slot < dev_limit; slot++) {
352
if (!early_is_amd_nb(read_pci_config(bus, slot, 3, 0x00)))
353
continue;
354
355
ctl = read_pci_config(bus, slot, 3, AMD64_GARTAPERTURECTL);
356
ctl &= ~GARTEN;
357
write_pci_config(bus, slot, 3, AMD64_GARTAPERTURECTL, ctl);
358
}
359
}
360
361
}
362
363
static int __initdata printed_gart_size_msg;
364
365
int __init gart_iommu_hole_init(void)
366
{
367
u32 agp_aper_base = 0, agp_aper_order = 0;
368
u32 aper_size, aper_alloc = 0, aper_order = 0, last_aper_order = 0;
369
u64 aper_base, last_aper_base = 0;
370
int fix, slot, valid_agp = 0;
371
int i, node;
372
373
if (gart_iommu_aperture_disabled || !fix_aperture ||
374
!early_pci_allowed())
375
return -ENODEV;
376
377
printk(KERN_INFO "Checking aperture...\n");
378
379
if (!fallback_aper_force)
380
agp_aper_base = search_agp_bridge(&agp_aper_order, &valid_agp);
381
382
fix = 0;
383
node = 0;
384
for (i = 0; i < amd_nb_bus_dev_ranges[i].dev_limit; i++) {
385
int bus;
386
int dev_base, dev_limit;
387
u32 ctl;
388
389
bus = amd_nb_bus_dev_ranges[i].bus;
390
dev_base = amd_nb_bus_dev_ranges[i].dev_base;
391
dev_limit = amd_nb_bus_dev_ranges[i].dev_limit;
392
393
for (slot = dev_base; slot < dev_limit; slot++) {
394
if (!early_is_amd_nb(read_pci_config(bus, slot, 3, 0x00)))
395
continue;
396
397
iommu_detected = 1;
398
gart_iommu_aperture = 1;
399
x86_init.iommu.iommu_init = gart_iommu_init;
400
401
ctl = read_pci_config(bus, slot, 3,
402
AMD64_GARTAPERTURECTL);
403
404
/*
405
* Before we do anything else disable the GART. It may
406
* still be enabled if we boot into a crash-kernel here.
407
* Reconfiguring the GART while it is enabled could have
408
* unknown side-effects.
409
*/
410
ctl &= ~GARTEN;
411
write_pci_config(bus, slot, 3, AMD64_GARTAPERTURECTL, ctl);
412
413
aper_order = (ctl >> 1) & 7;
414
aper_size = (32 * 1024 * 1024) << aper_order;
415
aper_base = read_pci_config(bus, slot, 3, AMD64_GARTAPERTUREBASE) & 0x7fff;
416
aper_base <<= 25;
417
418
printk(KERN_INFO "Node %d: aperture @ %Lx size %u MB\n",
419
node, aper_base, aper_size >> 20);
420
node++;
421
422
if (!aperture_valid(aper_base, aper_size, 64<<20)) {
423
if (valid_agp && agp_aper_base &&
424
agp_aper_base == aper_base &&
425
agp_aper_order == aper_order) {
426
/* the same between two setting from NB and agp */
427
if (!no_iommu &&
428
max_pfn > MAX_DMA32_PFN &&
429
!printed_gart_size_msg) {
430
printk(KERN_ERR "you are using iommu with agp, but GART size is less than 64M\n");
431
printk(KERN_ERR "please increase GART size in your BIOS setup\n");
432
printk(KERN_ERR "if BIOS doesn't have that option, contact your HW vendor!\n");
433
printed_gart_size_msg = 1;
434
}
435
} else {
436
fix = 1;
437
goto out;
438
}
439
}
440
441
if ((last_aper_order && aper_order != last_aper_order) ||
442
(last_aper_base && aper_base != last_aper_base)) {
443
fix = 1;
444
goto out;
445
}
446
last_aper_order = aper_order;
447
last_aper_base = aper_base;
448
}
449
}
450
451
out:
452
if (!fix && !fallback_aper_force) {
453
if (last_aper_base) {
454
unsigned long n = (32 * 1024 * 1024) << last_aper_order;
455
456
insert_aperture_resource((u32)last_aper_base, n);
457
return 1;
458
}
459
return 0;
460
}
461
462
if (!fallback_aper_force) {
463
aper_alloc = agp_aper_base;
464
aper_order = agp_aper_order;
465
}
466
467
if (aper_alloc) {
468
/* Got the aperture from the AGP bridge */
469
} else if ((!no_iommu && max_pfn > MAX_DMA32_PFN) ||
470
force_iommu ||
471
valid_agp ||
472
fallback_aper_force) {
473
printk(KERN_INFO
474
"Your BIOS doesn't leave a aperture memory hole\n");
475
printk(KERN_INFO
476
"Please enable the IOMMU option in the BIOS setup\n");
477
printk(KERN_INFO
478
"This costs you %d MB of RAM\n",
479
32 << fallback_aper_order);
480
481
aper_order = fallback_aper_order;
482
aper_alloc = allocate_aperture();
483
if (!aper_alloc) {
484
/*
485
* Could disable AGP and IOMMU here, but it's
486
* probably not worth it. But the later users
487
* cannot deal with bad apertures and turning
488
* on the aperture over memory causes very
489
* strange problems, so it's better to panic
490
* early.
491
*/
492
panic("Not enough memory for aperture");
493
}
494
} else {
495
return 0;
496
}
497
498
/* Fix up the north bridges */
499
for (i = 0; i < amd_nb_bus_dev_ranges[i].dev_limit; i++) {
500
int bus, dev_base, dev_limit;
501
502
/*
503
* Don't enable translation yet but enable GART IO and CPU
504
* accesses and set DISTLBWALKPRB since GART table memory is UC.
505
*/
506
u32 ctl = aper_order << 1;
507
508
bus = amd_nb_bus_dev_ranges[i].bus;
509
dev_base = amd_nb_bus_dev_ranges[i].dev_base;
510
dev_limit = amd_nb_bus_dev_ranges[i].dev_limit;
511
for (slot = dev_base; slot < dev_limit; slot++) {
512
if (!early_is_amd_nb(read_pci_config(bus, slot, 3, 0x00)))
513
continue;
514
515
write_pci_config(bus, slot, 3, AMD64_GARTAPERTURECTL, ctl);
516
write_pci_config(bus, slot, 3, AMD64_GARTAPERTUREBASE, aper_alloc >> 25);
517
}
518
}
519
520
set_up_gart_resume(aper_order, aper_alloc);
521
522
return 1;
523
}
524
525