aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel/aperture_64.c
diff options
context:
space:
mode:
authorYinghai Lu <yhlu.kernel.send@gmail.com>2008-04-19 04:31:11 -0400
committerIngo Molnar <mingo@elte.hu>2008-05-12 15:28:10 -0400
commit55c0d721df80dcc505dc888e85d4ca51ea150ce9 (patch)
tree1e379491918af6719067a2bb417672a25ce24a6d /arch/x86/kernel/aperture_64.c
parent7677b2ef6c0c4fddc84f6473f3863f40eb71821b (diff)
x86: clean up aperture_64.c
1. use symbolic register names where appropriate. 2. num to bus or slot changing 3. handle for new opteron for bus other than 0 Signed-off-by: Yinghai Lu <yhlu.kernel@gmail.com> Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'arch/x86/kernel/aperture_64.c')
-rw-r--r--arch/x86/kernel/aperture_64.c230
1 files changed, 139 insertions, 91 deletions
diff --git a/arch/x86/kernel/aperture_64.c b/arch/x86/kernel/aperture_64.c
index c63f8d9fad3e..02f4dbaa4df4 100644
--- a/arch/x86/kernel/aperture_64.c
+++ b/arch/x86/kernel/aperture_64.c
@@ -35,6 +35,18 @@ int fallback_aper_force __initdata;
35 35
36int fix_aperture __initdata = 1; 36int fix_aperture __initdata = 1;
37 37
38struct bus_dev_range {
39 int bus;
40 int dev_base;
41 int dev_limit;
42};
43
44static struct bus_dev_range bus_dev_ranges[] __initdata = {
45 { 0x00, 0x18, 0x20},
46 { 0xff, 0x00, 0x20},
47 { 0xfe, 0x00, 0x20}
48};
49
38static struct resource gart_resource = { 50static struct resource gart_resource = {
39 .name = "GART", 51 .name = "GART",
40 .flags = IORESOURCE_MEM, 52 .flags = IORESOURCE_MEM,
@@ -120,33 +132,33 @@ static int __init aperture_valid(u64 aper_base, u32 aper_size, u32 min_size)
120} 132}
121 133
122/* Find a PCI capability */ 134/* Find a PCI capability */
123static __u32 __init find_cap(int num, int slot, int func, int cap) 135static __u32 __init find_cap(int bus, int slot, int func, int cap)
124{ 136{
125 int bytes; 137 int bytes;
126 u8 pos; 138 u8 pos;
127 139
128 if (!(read_pci_config_16(num, slot, func, PCI_STATUS) & 140 if (!(read_pci_config_16(bus, slot, func, PCI_STATUS) &
129 PCI_STATUS_CAP_LIST)) 141 PCI_STATUS_CAP_LIST))
130 return 0; 142 return 0;
131 143
132 pos = read_pci_config_byte(num, slot, func, PCI_CAPABILITY_LIST); 144 pos = read_pci_config_byte(bus, slot, func, PCI_CAPABILITY_LIST);
133 for (bytes = 0; bytes < 48 && pos >= 0x40; bytes++) { 145 for (bytes = 0; bytes < 48 && pos >= 0x40; bytes++) {
134 u8 id; 146 u8 id;
135 147
136 pos &= ~3; 148 pos &= ~3;
137 id = read_pci_config_byte(num, slot, func, pos+PCI_CAP_LIST_ID); 149 id = read_pci_config_byte(bus, slot, func, pos+PCI_CAP_LIST_ID);
138 if (id == 0xff) 150 if (id == 0xff)
139 break; 151 break;
140 if (id == cap) 152 if (id == cap)
141 return pos; 153 return pos;
142 pos = read_pci_config_byte(num, slot, func, 154 pos = read_pci_config_byte(bus, slot, func,
143 pos+PCI_CAP_LIST_NEXT); 155 pos+PCI_CAP_LIST_NEXT);
144 } 156 }
145 return 0; 157 return 0;
146} 158}
147 159
148/* Read a standard AGPv3 bridge header */ 160/* Read a standard AGPv3 bridge header */
149static __u32 __init read_agp(int num, int slot, int func, int cap, u32 *order) 161static __u32 __init read_agp(int bus, int slot, int func, int cap, u32 *order)
150{ 162{
151 u32 apsize; 163 u32 apsize;
152 u32 apsizereg; 164 u32 apsizereg;
@@ -155,8 +167,8 @@ static __u32 __init read_agp(int num, int slot, int func, int cap, u32 *order)
155 u64 aper; 167 u64 aper;
156 u32 old_order; 168 u32 old_order;
157 169
158 printk(KERN_INFO "AGP bridge at %02x:%02x:%02x\n", num, slot, func); 170 printk(KERN_INFO "AGP bridge at %02x:%02x:%02x\n", bus, slot, func);
159 apsizereg = read_pci_config_16(num, slot, func, cap + 0x14); 171 apsizereg = read_pci_config_16(bus, slot, func, cap + 0x14);
160 if (apsizereg == 0xffffffff) { 172 if (apsizereg == 0xffffffff) {
161 printk(KERN_ERR "APSIZE in AGP bridge unreadable\n"); 173 printk(KERN_ERR "APSIZE in AGP bridge unreadable\n");
162 return 0; 174 return 0;
@@ -174,8 +186,8 @@ static __u32 __init read_agp(int num, int slot, int func, int cap, u32 *order)
174 if ((int)*order < 0) /* < 32MB */ 186 if ((int)*order < 0) /* < 32MB */
175 *order = 0; 187 *order = 0;
176 188
177 aper_low = read_pci_config(num, slot, func, 0x10); 189 aper_low = read_pci_config(bus, slot, func, 0x10);
178 aper_hi = read_pci_config(num, slot, func, 0x14); 190 aper_hi = read_pci_config(bus, slot, func, 0x14);
179 aper = (aper_low & ~((1<<22)-1)) | ((u64)aper_hi << 32); 191 aper = (aper_low & ~((1<<22)-1)) | ((u64)aper_hi << 32);
180 192
181 /* 193 /*
@@ -213,15 +225,15 @@ static __u32 __init read_agp(int num, int slot, int func, int cap, u32 *order)
213 */ 225 */
214static __u32 __init search_agp_bridge(u32 *order, int *valid_agp) 226static __u32 __init search_agp_bridge(u32 *order, int *valid_agp)
215{ 227{
216 int num, slot, func; 228 int bus, slot, func;
217 229
218 /* Poor man's PCI discovery */ 230 /* Poor man's PCI discovery */
219 for (num = 0; num < 256; num++) { 231 for (bus = 0; bus < 256; bus++) {
220 for (slot = 0; slot < 32; slot++) { 232 for (slot = 0; slot < 32; slot++) {
221 for (func = 0; func < 8; func++) { 233 for (func = 0; func < 8; func++) {
222 u32 class, cap; 234 u32 class, cap;
223 u8 type; 235 u8 type;
224 class = read_pci_config(num, slot, func, 236 class = read_pci_config(bus, slot, func,
225 PCI_CLASS_REVISION); 237 PCI_CLASS_REVISION);
226 if (class == 0xffffffff) 238 if (class == 0xffffffff)
227 break; 239 break;
@@ -230,17 +242,17 @@ static __u32 __init search_agp_bridge(u32 *order, int *valid_agp)
230 case PCI_CLASS_BRIDGE_HOST: 242 case PCI_CLASS_BRIDGE_HOST:
231 case PCI_CLASS_BRIDGE_OTHER: /* needed? */ 243 case PCI_CLASS_BRIDGE_OTHER: /* needed? */
232 /* AGP bridge? */ 244 /* AGP bridge? */
233 cap = find_cap(num, slot, func, 245 cap = find_cap(bus, slot, func,
234 PCI_CAP_ID_AGP); 246 PCI_CAP_ID_AGP);
235 if (!cap) 247 if (!cap)
236 break; 248 break;
237 *valid_agp = 1; 249 *valid_agp = 1;
238 return read_agp(num, slot, func, cap, 250 return read_agp(bus, slot, func, cap,
239 order); 251 order);
240 } 252 }
241 253
242 /* No multi-function device? */ 254 /* No multi-function device? */
243 type = read_pci_config_byte(num, slot, func, 255 type = read_pci_config_byte(bus, slot, func,
244 PCI_HEADER_TYPE); 256 PCI_HEADER_TYPE);
245 if (!(type & 0x80)) 257 if (!(type & 0x80))
246 break; 258 break;
@@ -280,38 +292,49 @@ void __init early_gart_iommu_check(void)
280 * or BIOS forget to put that in reserved. 292 * or BIOS forget to put that in reserved.
281 * try to update e820 to make that region as reserved. 293 * try to update e820 to make that region as reserved.
282 */ 294 */
283 int fix, num; 295 int fix, slot;
284 u32 ctl; 296 u32 ctl;
285 u32 aper_size = 0, aper_order = 0, last_aper_order = 0; 297 u32 aper_size = 0, aper_order = 0, last_aper_order = 0;
286 u64 aper_base = 0, last_aper_base = 0; 298 u64 aper_base = 0, last_aper_base = 0;
287 int aper_enabled = 0, last_aper_enabled = 0; 299 int aper_enabled = 0, last_aper_enabled = 0;
300 int i;
288 301
289 if (!early_pci_allowed()) 302 if (!early_pci_allowed())
290 return; 303 return;
291 304
292 fix = 0; 305 fix = 0;
293 for (num = 24; num < 32; num++) { 306 for (i = 0; i < ARRAY_SIZE(bus_dev_ranges); i++) {
294 if (!early_is_k8_nb(read_pci_config(0, num, 3, 0x00))) 307 int bus;
295 continue; 308 int dev_base, dev_limit;
296 309
297 ctl = read_pci_config(0, num, 3, 0x90); 310 bus = bus_dev_ranges[i].bus;
298 aper_enabled = ctl & 1; 311 dev_base = bus_dev_ranges[i].dev_base;
299 aper_order = (ctl >> 1) & 7; 312 dev_limit = bus_dev_ranges[i].dev_limit;
300 aper_size = (32 * 1024 * 1024) << aper_order; 313
301 aper_base = read_pci_config(0, num, 3, 0x94) & 0x7fff; 314 for (slot = dev_base; slot < dev_limit; slot++) {
302 aper_base <<= 25; 315 if (!early_is_k8_nb(read_pci_config(bus, slot, 3, 0x00)))
303 316 continue;
304 if ((last_aper_order && aper_order != last_aper_order) || 317
305 (last_aper_base && aper_base != last_aper_base) || 318 ctl = read_pci_config(bus, slot, 3, AMD64_GARTAPERTURECTL);
306 (last_aper_enabled && aper_enabled != last_aper_enabled)) { 319 aper_enabled = ctl & AMD64_GARTEN;
307 fix = 1; 320 aper_order = (ctl >> 1) & 7;
308 break; 321 aper_size = (32 * 1024 * 1024) << aper_order;
322 aper_base = read_pci_config(bus, slot, 3, AMD64_GARTAPERTUREBASE) & 0x7fff;
323 aper_base <<= 25;
324
325 if ((last_aper_order && aper_order != last_aper_order) ||
326 (last_aper_base && aper_base != last_aper_base) ||
327 (last_aper_enabled && aper_enabled != last_aper_enabled)) {
328 fix = 1;
329 goto out;
330 }
331 last_aper_order = aper_order;
332 last_aper_base = aper_base;
333 last_aper_enabled = aper_enabled;
309 } 334 }
310 last_aper_order = aper_order;
311 last_aper_base = aper_base;
312 last_aper_enabled = aper_enabled;
313 } 335 }
314 336
337out:
315 if (!fix && !aper_enabled) 338 if (!fix && !aper_enabled)
316 return; 339 return;
317 340
@@ -330,13 +353,22 @@ void __init early_gart_iommu_check(void)
330 } 353 }
331 354
332 /* different nodes have different setting, disable them all at first*/ 355 /* different nodes have different setting, disable them all at first*/
333 for (num = 24; num < 32; num++) { 356 for (i = 0; i < ARRAY_SIZE(bus_dev_ranges); i++) {
334 if (!early_is_k8_nb(read_pci_config(0, num, 3, 0x00))) 357 int bus;
335 continue; 358 int dev_base, dev_limit;
359
360 bus = bus_dev_ranges[i].bus;
361 dev_base = bus_dev_ranges[i].dev_base;
362 dev_limit = bus_dev_ranges[i].dev_limit;
336 363
337 ctl = read_pci_config(0, num, 3, 0x90); 364 for (slot = dev_base; slot < dev_limit; slot++) {
338 ctl &= ~1; 365 if (!early_is_k8_nb(read_pci_config(bus, slot, 3, 0x00)))
339 write_pci_config(0, num, 3, 0x90, ctl); 366 continue;
367
368 ctl = read_pci_config(bus, slot, 3, AMD64_GARTAPERTURECTL);
369 ctl &= ~AMD64_GARTEN;
370 write_pci_config(bus, slot, 3, AMD64_GARTAPERTURECTL, ctl);
371 }
340 } 372 }
341 373
342} 374}
@@ -348,8 +380,8 @@ void __init gart_iommu_hole_init(void)
348 u32 agp_aper_base = 0, agp_aper_order = 0; 380 u32 agp_aper_base = 0, agp_aper_order = 0;
349 u32 aper_size, aper_alloc = 0, aper_order = 0, last_aper_order = 0; 381 u32 aper_size, aper_alloc = 0, aper_order = 0, last_aper_order = 0;
350 u64 aper_base, last_aper_base = 0; 382 u64 aper_base, last_aper_base = 0;
351 int fix, num, valid_agp = 0; 383 int fix, slot, valid_agp = 0;
352 int node; 384 int i, node;
353 385
354 if (gart_iommu_aperture_disabled || !fix_aperture || 386 if (gart_iommu_aperture_disabled || !fix_aperture ||
355 !early_pci_allowed()) 387 !early_pci_allowed())
@@ -362,48 +394,58 @@ void __init gart_iommu_hole_init(void)
362 394
363 fix = 0; 395 fix = 0;
364 node = 0; 396 node = 0;
365 for (num = 24; num < 32; num++) { 397 for (i = 0; i < ARRAY_SIZE(bus_dev_ranges); i++) {
366 if (!early_is_k8_nb(read_pci_config(0, num, 3, 0x00))) 398 int bus;
367 continue; 399 int dev_base, dev_limit;
368 400
369 iommu_detected = 1; 401 bus = bus_dev_ranges[i].bus;
370 gart_iommu_aperture = 1; 402 dev_base = bus_dev_ranges[i].dev_base;
371 403 dev_limit = bus_dev_ranges[i].dev_limit;
372 aper_order = (read_pci_config(0, num, 3, 0x90) >> 1) & 7; 404
373 aper_size = (32 * 1024 * 1024) << aper_order; 405 for (slot = dev_base; slot < dev_limit; slot++) {
374 aper_base = read_pci_config(0, num, 3, 0x94) & 0x7fff; 406 if (!early_is_k8_nb(read_pci_config(bus, slot, 3, 0x00)))
375 aper_base <<= 25; 407 continue;
376 408
377 printk(KERN_INFO "Node %d: aperture @ %Lx size %u MB\n", 409 iommu_detected = 1;
378 node, aper_base, aper_size >> 20); 410 gart_iommu_aperture = 1;
379 node++; 411
380 412 aper_order = (read_pci_config(bus, slot, 3, AMD64_GARTAPERTURECTL) >> 1) & 7;
381 if (!aperture_valid(aper_base, aper_size, 64<<20)) { 413 aper_size = (32 * 1024 * 1024) << aper_order;
382 if (valid_agp && agp_aper_base && 414 aper_base = read_pci_config(bus, slot, 3, AMD64_GARTAPERTUREBASE) & 0x7fff;
383 agp_aper_base == aper_base && 415 aper_base <<= 25;
384 agp_aper_order == aper_order) { 416
385 /* the same between two setting from NB and agp */ 417 printk(KERN_INFO "Node %d: aperture @ %Lx size %u MB\n",
386 if (!no_iommu && end_pfn > MAX_DMA32_PFN && !printed_gart_size_msg) { 418 node, aper_base, aper_size >> 20);
387 printk(KERN_ERR "you are using iommu with agp, but GART size is less than 64M\n"); 419 node++;
388 printk(KERN_ERR "please increase GART size in your BIOS setup\n"); 420
389 printk(KERN_ERR "if BIOS doesn't have that option, contact your HW vendor!\n"); 421 if (!aperture_valid(aper_base, aper_size, 64<<20)) {
390 printed_gart_size_msg = 1; 422 if (valid_agp && agp_aper_base &&
423 agp_aper_base == aper_base &&
424 agp_aper_order == aper_order) {
425 /* the same between two setting from NB and agp */
426 if (!no_iommu && end_pfn > MAX_DMA32_PFN && !printed_gart_size_msg) {
427 printk(KERN_ERR "you are using iommu with agp, but GART size is less than 64M\n");
428 printk(KERN_ERR "please increase GART size in your BIOS setup\n");
429 printk(KERN_ERR "if BIOS doesn't have that option, contact your HW vendor!\n");
430 printed_gart_size_msg = 1;
431 }
432 } else {
433 fix = 1;
434 goto out;
391 } 435 }
392 } else {
393 fix = 1;
394 break;
395 } 436 }
396 }
397 437
398 if ((last_aper_order && aper_order != last_aper_order) || 438 if ((last_aper_order && aper_order != last_aper_order) ||
399 (last_aper_base && aper_base != last_aper_base)) { 439 (last_aper_base && aper_base != last_aper_base)) {
400 fix = 1; 440 fix = 1;
401 break; 441 goto out;
442 }
443 last_aper_order = aper_order;
444 last_aper_base = aper_base;
402 } 445 }
403 last_aper_order = aper_order;
404 last_aper_base = aper_base;
405 } 446 }
406 447
448out:
407 if (!fix && !fallback_aper_force) { 449 if (!fix && !fallback_aper_force) {
408 if (last_aper_base) { 450 if (last_aper_base) {
409 unsigned long n = (32 * 1024 * 1024) << last_aper_order; 451 unsigned long n = (32 * 1024 * 1024) << last_aper_order;
@@ -452,16 +494,22 @@ void __init gart_iommu_hole_init(void)
452 } 494 }
453 495
454 /* Fix up the north bridges */ 496 /* Fix up the north bridges */
455 for (num = 24; num < 32; num++) { 497 for (i = 0; i < ARRAY_SIZE(bus_dev_ranges); i++) {
456 if (!early_is_k8_nb(read_pci_config(0, num, 3, 0x00))) 498 int bus;
457 continue; 499 int dev_base, dev_limit;
458 500
459 /* 501 bus = bus_dev_ranges[i].bus;
460 * Don't enable translation yet. That is done later. 502 dev_base = bus_dev_ranges[i].dev_base;
461 * Assume this BIOS didn't initialise the GART so 503 dev_limit = bus_dev_ranges[i].dev_limit;
462 * just overwrite all previous bits 504 for (slot = dev_base; slot < dev_limit; slot++) {
463 */ 505 if (!early_is_k8_nb(read_pci_config(bus, slot, 3, 0x00)))
464 write_pci_config(0, num, 3, 0x90, aper_order<<1); 506 continue;
465 write_pci_config(0, num, 3, 0x94, aper_alloc>>25); 507
508 /* Don't enable translation yet. That is done later.
509 Assume this BIOS didn't initialise the GART so
510 just overwrite all previous bits */
511 write_pci_config(bus, slot, 3, AMD64_GARTAPERTURECTL, aper_order << 1);
512 write_pci_config(bus, slot, 3, AMD64_GARTAPERTUREBASE, aper_alloc >> 25);
513 }
466 } 514 }
467} 515}