diff options
Diffstat (limited to 'arch/i386')
-rw-r--r-- | arch/i386/Kconfig | 55 | ||||
-rw-r--r-- | arch/i386/kernel/cpu/centaur.c | 4 | ||||
-rw-r--r-- | arch/i386/kernel/cpu/cpufreq/Kconfig | 1 | ||||
-rw-r--r-- | arch/i386/kernel/cpu/cpufreq/p4-clockmod.c | 9 | ||||
-rw-r--r-- | arch/i386/kernel/cpu/intel_cacheinfo.c | 11 | ||||
-rw-r--r-- | arch/i386/kernel/cpu/mtrr/main.c | 15 | ||||
-rw-r--r-- | arch/i386/kernel/timers/timer_tsc.c | 14 | ||||
-rw-r--r-- | arch/i386/pci/irq.c | 5 | ||||
-rw-r--r-- | arch/i386/pci/mmconfig.c | 15 |
9 files changed, 103 insertions, 26 deletions
diff --git a/arch/i386/Kconfig b/arch/i386/Kconfig index cbde675bc95c..d86c865a7cd2 100644 --- a/arch/i386/Kconfig +++ b/arch/i386/Kconfig | |||
@@ -47,15 +47,6 @@ config DMI | |||
47 | 47 | ||
48 | source "init/Kconfig" | 48 | source "init/Kconfig" |
49 | 49 | ||
50 | config DOUBLEFAULT | ||
51 | default y | ||
52 | bool "Enable doublefault exception handler" if EMBEDDED | ||
53 | help | ||
54 | This option allows trapping of rare doublefault exceptions that | ||
55 | would otherwise cause a system to silently reboot. Disabling this | ||
56 | option saves about 4k and might cause you much additional grey | ||
57 | hair. | ||
58 | |||
59 | menu "Processor type and features" | 50 | menu "Processor type and features" |
60 | 51 | ||
61 | choice | 52 | choice |
@@ -457,6 +448,43 @@ config HIGHMEM64G | |||
457 | 448 | ||
458 | endchoice | 449 | endchoice |
459 | 450 | ||
451 | choice | ||
452 | depends on EXPERIMENTAL && !X86_PAE | ||
453 | prompt "Memory split" | ||
454 | default VMSPLIT_3G | ||
455 | help | ||
456 | Select the desired split between kernel and user memory. | ||
457 | |||
458 | If the address range available to the kernel is less than the | ||
459 | physical memory installed, the remaining memory will be available | ||
460 | as "high memory". Accessing high memory is a little more costly | ||
461 | than low memory, as it needs to be mapped into the kernel first. | ||
462 | Note that increasing the kernel address space limits the range | ||
463 | available to user programs, making the address space there | ||
464 | tighter. Selecting anything other than the default 3G/1G split | ||
465 | will also likely make your kernel incompatible with binary-only | ||
466 | kernel modules. | ||
467 | |||
468 | If you are not absolutely sure what you are doing, leave this | ||
469 | option alone! | ||
470 | |||
471 | config VMSPLIT_3G | ||
472 | bool "3G/1G user/kernel split" | ||
473 | config VMSPLIT_3G_OPT | ||
474 | bool "3G/1G user/kernel split (for full 1G low memory)" | ||
475 | config VMSPLIT_2G | ||
476 | bool "2G/2G user/kernel split" | ||
477 | config VMSPLIT_1G | ||
478 | bool "1G/3G user/kernel split" | ||
479 | endchoice | ||
480 | |||
481 | config PAGE_OFFSET | ||
482 | hex | ||
483 | default 0xB0000000 if VMSPLIT_3G_OPT | ||
484 | default 0x78000000 if VMSPLIT_2G | ||
485 | default 0x40000000 if VMSPLIT_1G | ||
486 | default 0xC0000000 | ||
487 | |||
460 | config HIGHMEM | 488 | config HIGHMEM |
461 | bool | 489 | bool |
462 | depends on HIGHMEM64G || HIGHMEM4G | 490 | depends on HIGHMEM64G || HIGHMEM4G |
@@ -711,6 +739,15 @@ config HOTPLUG_CPU | |||
711 | 739 | ||
712 | Say N. | 740 | Say N. |
713 | 741 | ||
742 | config DOUBLEFAULT | ||
743 | default y | ||
744 | bool "Enable doublefault exception handler" if EMBEDDED | ||
745 | help | ||
746 | This option allows trapping of rare doublefault exceptions that | ||
747 | would otherwise cause a system to silently reboot. Disabling this | ||
748 | option saves about 4k and might cause you much additional grey | ||
749 | hair. | ||
750 | |||
714 | endmenu | 751 | endmenu |
715 | 752 | ||
716 | 753 | ||
diff --git a/arch/i386/kernel/cpu/centaur.c b/arch/i386/kernel/cpu/centaur.c index 394814e57672..0dd92a23d622 100644 --- a/arch/i386/kernel/cpu/centaur.c +++ b/arch/i386/kernel/cpu/centaur.c | |||
@@ -405,10 +405,6 @@ static void __init init_centaur(struct cpuinfo_x86 *c) | |||
405 | winchip2_protect_mcr(); | 405 | winchip2_protect_mcr(); |
406 | #endif | 406 | #endif |
407 | break; | 407 | break; |
408 | case 10: | ||
409 | name="4"; | ||
410 | /* no info on the WC4 yet */ | ||
411 | break; | ||
412 | default: | 408 | default: |
413 | name="??"; | 409 | name="??"; |
414 | } | 410 | } |
diff --git a/arch/i386/kernel/cpu/cpufreq/Kconfig b/arch/i386/kernel/cpu/cpufreq/Kconfig index 0f1eb507233b..26892d2099b0 100644 --- a/arch/i386/kernel/cpu/cpufreq/Kconfig +++ b/arch/i386/kernel/cpu/cpufreq/Kconfig | |||
@@ -96,6 +96,7 @@ config X86_POWERNOW_K8_ACPI | |||
96 | 96 | ||
97 | config X86_GX_SUSPMOD | 97 | config X86_GX_SUSPMOD |
98 | tristate "Cyrix MediaGX/NatSemi Geode Suspend Modulation" | 98 | tristate "Cyrix MediaGX/NatSemi Geode Suspend Modulation" |
99 | depends on PCI | ||
99 | help | 100 | help |
100 | This add the CPUFreq driver for NatSemi Geode processors which | 101 | This add the CPUFreq driver for NatSemi Geode processors which |
101 | support suspend modulation. | 102 | support suspend modulation. |
diff --git a/arch/i386/kernel/cpu/cpufreq/p4-clockmod.c b/arch/i386/kernel/cpu/cpufreq/p4-clockmod.c index 270f2188d68b..cc73a7ae34bc 100644 --- a/arch/i386/kernel/cpu/cpufreq/p4-clockmod.c +++ b/arch/i386/kernel/cpu/cpufreq/p4-clockmod.c | |||
@@ -52,6 +52,7 @@ enum { | |||
52 | 52 | ||
53 | 53 | ||
54 | static int has_N44_O17_errata[NR_CPUS]; | 54 | static int has_N44_O17_errata[NR_CPUS]; |
55 | static int has_N60_errata[NR_CPUS]; | ||
55 | static unsigned int stock_freq; | 56 | static unsigned int stock_freq; |
56 | static struct cpufreq_driver p4clockmod_driver; | 57 | static struct cpufreq_driver p4clockmod_driver; |
57 | static unsigned int cpufreq_p4_get(unsigned int cpu); | 58 | static unsigned int cpufreq_p4_get(unsigned int cpu); |
@@ -226,6 +227,12 @@ static int cpufreq_p4_cpu_init(struct cpufreq_policy *policy) | |||
226 | case 0x0f12: | 227 | case 0x0f12: |
227 | has_N44_O17_errata[policy->cpu] = 1; | 228 | has_N44_O17_errata[policy->cpu] = 1; |
228 | dprintk("has errata -- disabling low frequencies\n"); | 229 | dprintk("has errata -- disabling low frequencies\n"); |
230 | break; | ||
231 | |||
232 | case 0x0f29: | ||
233 | has_N60_errata[policy->cpu] = 1; | ||
234 | dprintk("has errata -- disabling frequencies lower than 2ghz\n"); | ||
235 | break; | ||
229 | } | 236 | } |
230 | 237 | ||
231 | /* get max frequency */ | 238 | /* get max frequency */ |
@@ -237,6 +244,8 @@ static int cpufreq_p4_cpu_init(struct cpufreq_policy *policy) | |||
237 | for (i=1; (p4clockmod_table[i].frequency != CPUFREQ_TABLE_END); i++) { | 244 | for (i=1; (p4clockmod_table[i].frequency != CPUFREQ_TABLE_END); i++) { |
238 | if ((i<2) && (has_N44_O17_errata[policy->cpu])) | 245 | if ((i<2) && (has_N44_O17_errata[policy->cpu])) |
239 | p4clockmod_table[i].frequency = CPUFREQ_ENTRY_INVALID; | 246 | p4clockmod_table[i].frequency = CPUFREQ_ENTRY_INVALID; |
247 | else if (has_N60_errata[policy->cpu] && p4clockmod_table[i].frequency < 2000000) | ||
248 | p4clockmod_table[i].frequency = CPUFREQ_ENTRY_INVALID; | ||
240 | else | 249 | else |
241 | p4clockmod_table[i].frequency = (stock_freq * i)/8; | 250 | p4clockmod_table[i].frequency = (stock_freq * i)/8; |
242 | } | 251 | } |
diff --git a/arch/i386/kernel/cpu/intel_cacheinfo.c b/arch/i386/kernel/cpu/intel_cacheinfo.c index fbfd374aa336..af591c73345f 100644 --- a/arch/i386/kernel/cpu/intel_cacheinfo.c +++ b/arch/i386/kernel/cpu/intel_cacheinfo.c | |||
@@ -43,13 +43,23 @@ static struct _cache_table cache_table[] __cpuinitdata = | |||
43 | { 0x2c, LVL_1_DATA, 32 }, /* 8-way set assoc, 64 byte line size */ | 43 | { 0x2c, LVL_1_DATA, 32 }, /* 8-way set assoc, 64 byte line size */ |
44 | { 0x30, LVL_1_INST, 32 }, /* 8-way set assoc, 64 byte line size */ | 44 | { 0x30, LVL_1_INST, 32 }, /* 8-way set assoc, 64 byte line size */ |
45 | { 0x39, LVL_2, 128 }, /* 4-way set assoc, sectored cache, 64 byte line size */ | 45 | { 0x39, LVL_2, 128 }, /* 4-way set assoc, sectored cache, 64 byte line size */ |
46 | { 0x3a, LVL_2, 192 }, /* 6-way set assoc, sectored cache, 64 byte line size */ | ||
46 | { 0x3b, LVL_2, 128 }, /* 2-way set assoc, sectored cache, 64 byte line size */ | 47 | { 0x3b, LVL_2, 128 }, /* 2-way set assoc, sectored cache, 64 byte line size */ |
47 | { 0x3c, LVL_2, 256 }, /* 4-way set assoc, sectored cache, 64 byte line size */ | 48 | { 0x3c, LVL_2, 256 }, /* 4-way set assoc, sectored cache, 64 byte line size */ |
49 | { 0x3d, LVL_2, 384 }, /* 6-way set assoc, sectored cache, 64 byte line size */ | ||
50 | { 0x3e, LVL_2, 512 }, /* 4-way set assoc, sectored cache, 64 byte line size */ | ||
48 | { 0x41, LVL_2, 128 }, /* 4-way set assoc, 32 byte line size */ | 51 | { 0x41, LVL_2, 128 }, /* 4-way set assoc, 32 byte line size */ |
49 | { 0x42, LVL_2, 256 }, /* 4-way set assoc, 32 byte line size */ | 52 | { 0x42, LVL_2, 256 }, /* 4-way set assoc, 32 byte line size */ |
50 | { 0x43, LVL_2, 512 }, /* 4-way set assoc, 32 byte line size */ | 53 | { 0x43, LVL_2, 512 }, /* 4-way set assoc, 32 byte line size */ |
51 | { 0x44, LVL_2, 1024 }, /* 4-way set assoc, 32 byte line size */ | 54 | { 0x44, LVL_2, 1024 }, /* 4-way set assoc, 32 byte line size */ |
52 | { 0x45, LVL_2, 2048 }, /* 4-way set assoc, 32 byte line size */ | 55 | { 0x45, LVL_2, 2048 }, /* 4-way set assoc, 32 byte line size */ |
56 | { 0x46, LVL_3, 4096 }, /* 4-way set assoc, 64 byte line size */ | ||
57 | { 0x47, LVL_3, 8192 }, /* 8-way set assoc, 64 byte line size */ | ||
58 | { 0x49, LVL_3, 4096 }, /* 16-way set assoc, 64 byte line size */ | ||
59 | { 0x4a, LVL_3, 6144 }, /* 12-way set assoc, 64 byte line size */ | ||
60 | { 0x4b, LVL_3, 8192 }, /* 16-way set assoc, 64 byte line size */ | ||
61 | { 0x4c, LVL_3, 12288 }, /* 12-way set assoc, 64 byte line size */ | ||
62 | { 0x4d, LVL_3, 16384 }, /* 16-way set assoc, 64 byte line size */ | ||
53 | { 0x60, LVL_1_DATA, 16 }, /* 8-way set assoc, sectored cache, 64 byte line size */ | 63 | { 0x60, LVL_1_DATA, 16 }, /* 8-way set assoc, sectored cache, 64 byte line size */ |
54 | { 0x66, LVL_1_DATA, 8 }, /* 4-way set assoc, sectored cache, 64 byte line size */ | 64 | { 0x66, LVL_1_DATA, 8 }, /* 4-way set assoc, sectored cache, 64 byte line size */ |
55 | { 0x67, LVL_1_DATA, 16 }, /* 4-way set assoc, sectored cache, 64 byte line size */ | 65 | { 0x67, LVL_1_DATA, 16 }, /* 4-way set assoc, sectored cache, 64 byte line size */ |
@@ -57,6 +67,7 @@ static struct _cache_table cache_table[] __cpuinitdata = | |||
57 | { 0x70, LVL_TRACE, 12 }, /* 8-way set assoc */ | 67 | { 0x70, LVL_TRACE, 12 }, /* 8-way set assoc */ |
58 | { 0x71, LVL_TRACE, 16 }, /* 8-way set assoc */ | 68 | { 0x71, LVL_TRACE, 16 }, /* 8-way set assoc */ |
59 | { 0x72, LVL_TRACE, 32 }, /* 8-way set assoc */ | 69 | { 0x72, LVL_TRACE, 32 }, /* 8-way set assoc */ |
70 | { 0x73, LVL_TRACE, 64 }, /* 8-way set assoc */ | ||
60 | { 0x78, LVL_2, 1024 }, /* 4-way set assoc, 64 byte line size */ | 71 | { 0x78, LVL_2, 1024 }, /* 4-way set assoc, 64 byte line size */ |
61 | { 0x79, LVL_2, 128 }, /* 8-way set assoc, sectored cache, 64 byte line size */ | 72 | { 0x79, LVL_2, 128 }, /* 8-way set assoc, sectored cache, 64 byte line size */ |
62 | { 0x7a, LVL_2, 256 }, /* 8-way set assoc, sectored cache, 64 byte line size */ | 73 | { 0x7a, LVL_2, 256 }, /* 8-way set assoc, sectored cache, 64 byte line size */ |
diff --git a/arch/i386/kernel/cpu/mtrr/main.c b/arch/i386/kernel/cpu/mtrr/main.c index 1e9db198c440..3b4618bed70d 100644 --- a/arch/i386/kernel/cpu/mtrr/main.c +++ b/arch/i386/kernel/cpu/mtrr/main.c | |||
@@ -44,12 +44,10 @@ | |||
44 | #include <asm/msr.h> | 44 | #include <asm/msr.h> |
45 | #include "mtrr.h" | 45 | #include "mtrr.h" |
46 | 46 | ||
47 | #define MTRR_VERSION "2.0 (20020519)" | ||
48 | |||
49 | u32 num_var_ranges = 0; | 47 | u32 num_var_ranges = 0; |
50 | 48 | ||
51 | unsigned int *usage_table; | 49 | unsigned int *usage_table; |
52 | static DECLARE_MUTEX(main_lock); | 50 | static DECLARE_MUTEX(mtrr_sem); |
53 | 51 | ||
54 | u32 size_or_mask, size_and_mask; | 52 | u32 size_or_mask, size_and_mask; |
55 | 53 | ||
@@ -335,7 +333,7 @@ int mtrr_add_page(unsigned long base, unsigned long size, | |||
335 | /* No CPU hotplug when we change MTRR entries */ | 333 | /* No CPU hotplug when we change MTRR entries */ |
336 | lock_cpu_hotplug(); | 334 | lock_cpu_hotplug(); |
337 | /* Search for existing MTRR */ | 335 | /* Search for existing MTRR */ |
338 | down(&main_lock); | 336 | down(&mtrr_sem); |
339 | for (i = 0; i < num_var_ranges; ++i) { | 337 | for (i = 0; i < num_var_ranges; ++i) { |
340 | mtrr_if->get(i, &lbase, &lsize, <ype); | 338 | mtrr_if->get(i, &lbase, &lsize, <ype); |
341 | if (base >= lbase + lsize) | 339 | if (base >= lbase + lsize) |
@@ -373,7 +371,7 @@ int mtrr_add_page(unsigned long base, unsigned long size, | |||
373 | printk(KERN_INFO "mtrr: no more MTRRs available\n"); | 371 | printk(KERN_INFO "mtrr: no more MTRRs available\n"); |
374 | error = i; | 372 | error = i; |
375 | out: | 373 | out: |
376 | up(&main_lock); | 374 | up(&mtrr_sem); |
377 | unlock_cpu_hotplug(); | 375 | unlock_cpu_hotplug(); |
378 | return error; | 376 | return error; |
379 | } | 377 | } |
@@ -466,7 +464,7 @@ int mtrr_del_page(int reg, unsigned long base, unsigned long size) | |||
466 | max = num_var_ranges; | 464 | max = num_var_ranges; |
467 | /* No CPU hotplug when we change MTRR entries */ | 465 | /* No CPU hotplug when we change MTRR entries */ |
468 | lock_cpu_hotplug(); | 466 | lock_cpu_hotplug(); |
469 | down(&main_lock); | 467 | down(&mtrr_sem); |
470 | if (reg < 0) { | 468 | if (reg < 0) { |
471 | /* Search for existing MTRR */ | 469 | /* Search for existing MTRR */ |
472 | for (i = 0; i < max; ++i) { | 470 | for (i = 0; i < max; ++i) { |
@@ -505,7 +503,7 @@ int mtrr_del_page(int reg, unsigned long base, unsigned long size) | |||
505 | set_mtrr(reg, 0, 0, 0); | 503 | set_mtrr(reg, 0, 0, 0); |
506 | error = reg; | 504 | error = reg; |
507 | out: | 505 | out: |
508 | up(&main_lock); | 506 | up(&mtrr_sem); |
509 | unlock_cpu_hotplug(); | 507 | unlock_cpu_hotplug(); |
510 | return error; | 508 | return error; |
511 | } | 509 | } |
@@ -671,7 +669,6 @@ void __init mtrr_bp_init(void) | |||
671 | break; | 669 | break; |
672 | } | 670 | } |
673 | } | 671 | } |
674 | printk(KERN_INFO "mtrr: v%s\n",MTRR_VERSION); | ||
675 | 672 | ||
676 | if (mtrr_if) { | 673 | if (mtrr_if) { |
677 | set_num_var_ranges(); | 674 | set_num_var_ranges(); |
@@ -688,7 +685,7 @@ void mtrr_ap_init(void) | |||
688 | if (!mtrr_if || !use_intel()) | 685 | if (!mtrr_if || !use_intel()) |
689 | return; | 686 | return; |
690 | /* | 687 | /* |
691 | * Ideally we should hold main_lock here to avoid mtrr entries changed, | 688 | * Ideally we should hold mtrr_sem here to avoid mtrr entries changed, |
692 | * but this routine will be called in cpu boot time, holding the lock | 689 | * but this routine will be called in cpu boot time, holding the lock |
693 | * breaks it. This routine is called in two cases: 1.very earily time | 690 | * breaks it. This routine is called in two cases: 1.very earily time |
694 | * of software resume, when there absolutely isn't mtrr entry changes; | 691 | * of software resume, when there absolutely isn't mtrr entry changes; |
diff --git a/arch/i386/kernel/timers/timer_tsc.c b/arch/i386/kernel/timers/timer_tsc.c index 47675bbbb316..7c86e3c5f1c1 100644 --- a/arch/i386/kernel/timers/timer_tsc.c +++ b/arch/i386/kernel/timers/timer_tsc.c | |||
@@ -45,6 +45,15 @@ static unsigned long last_tsc_high; /* msb 32 bits of Time Stamp Counter */ | |||
45 | static unsigned long long monotonic_base; | 45 | static unsigned long long monotonic_base; |
46 | static seqlock_t monotonic_lock = SEQLOCK_UNLOCKED; | 46 | static seqlock_t monotonic_lock = SEQLOCK_UNLOCKED; |
47 | 47 | ||
48 | /* Avoid compensating for lost ticks before TSCs are synched */ | ||
49 | static int detect_lost_ticks; | ||
50 | static int __init start_lost_tick_compensation(void) | ||
51 | { | ||
52 | detect_lost_ticks = 1; | ||
53 | return 0; | ||
54 | } | ||
55 | late_initcall(start_lost_tick_compensation); | ||
56 | |||
48 | /* convert from cycles(64bits) => nanoseconds (64bits) | 57 | /* convert from cycles(64bits) => nanoseconds (64bits) |
49 | * basic equation: | 58 | * basic equation: |
50 | * ns = cycles / (freq / ns_per_sec) | 59 | * ns = cycles / (freq / ns_per_sec) |
@@ -196,7 +205,8 @@ static void mark_offset_tsc_hpet(void) | |||
196 | 205 | ||
197 | /* lost tick compensation */ | 206 | /* lost tick compensation */ |
198 | offset = hpet_readl(HPET_T0_CMP) - hpet_tick; | 207 | offset = hpet_readl(HPET_T0_CMP) - hpet_tick; |
199 | if (unlikely(((offset - hpet_last) > hpet_tick) && (hpet_last != 0))) { | 208 | if (unlikely(((offset - hpet_last) > hpet_tick) && (hpet_last != 0)) |
209 | && detect_lost_ticks) { | ||
200 | int lost_ticks = (offset - hpet_last) / hpet_tick; | 210 | int lost_ticks = (offset - hpet_last) / hpet_tick; |
201 | jiffies_64 += lost_ticks; | 211 | jiffies_64 += lost_ticks; |
202 | } | 212 | } |
@@ -421,7 +431,7 @@ static void mark_offset_tsc(void) | |||
421 | delta += delay_at_last_interrupt; | 431 | delta += delay_at_last_interrupt; |
422 | lost = delta/(1000000/HZ); | 432 | lost = delta/(1000000/HZ); |
423 | delay = delta%(1000000/HZ); | 433 | delay = delta%(1000000/HZ); |
424 | if (lost >= 2) { | 434 | if (lost >= 2 && detect_lost_ticks) { |
425 | jiffies_64 += lost-1; | 435 | jiffies_64 += lost-1; |
426 | 436 | ||
427 | /* sanity check to ensure we're not always losing ticks */ | 437 | /* sanity check to ensure we're not always losing ticks */ |
diff --git a/arch/i386/pci/irq.c b/arch/i386/pci/irq.c index e715aa930036..3ca59cad05f3 100644 --- a/arch/i386/pci/irq.c +++ b/arch/i386/pci/irq.c | |||
@@ -539,6 +539,11 @@ static __init int intel_router_probe(struct irq_router *r, struct pci_dev *route | |||
539 | case PCI_DEVICE_ID_INTEL_ICH7_30: | 539 | case PCI_DEVICE_ID_INTEL_ICH7_30: |
540 | case PCI_DEVICE_ID_INTEL_ICH7_31: | 540 | case PCI_DEVICE_ID_INTEL_ICH7_31: |
541 | case PCI_DEVICE_ID_INTEL_ESB2_0: | 541 | case PCI_DEVICE_ID_INTEL_ESB2_0: |
542 | case PCI_DEVICE_ID_INTEL_ICH8_0: | ||
543 | case PCI_DEVICE_ID_INTEL_ICH8_1: | ||
544 | case PCI_DEVICE_ID_INTEL_ICH8_2: | ||
545 | case PCI_DEVICE_ID_INTEL_ICH8_3: | ||
546 | case PCI_DEVICE_ID_INTEL_ICH8_4: | ||
542 | r->name = "PIIX/ICH"; | 547 | r->name = "PIIX/ICH"; |
543 | r->get = pirq_piix_get; | 548 | r->get = pirq_piix_get; |
544 | r->set = pirq_piix_set; | 549 | r->set = pirq_piix_set; |
diff --git a/arch/i386/pci/mmconfig.c b/arch/i386/pci/mmconfig.c index 4bb4d4b0f73a..0ee8a983708c 100644 --- a/arch/i386/pci/mmconfig.c +++ b/arch/i386/pci/mmconfig.c | |||
@@ -36,8 +36,7 @@ static u32 get_base_addr(unsigned int seg, int bus, unsigned devfn) | |||
36 | while (1) { | 36 | while (1) { |
37 | ++cfg_num; | 37 | ++cfg_num; |
38 | if (cfg_num >= pci_mmcfg_config_num) { | 38 | if (cfg_num >= pci_mmcfg_config_num) { |
39 | /* Not found - fallback to type 1 */ | 39 | break; |
40 | return 0; | ||
41 | } | 40 | } |
42 | cfg = &pci_mmcfg_config[cfg_num]; | 41 | cfg = &pci_mmcfg_config[cfg_num]; |
43 | if (cfg->pci_segment_group_number != seg) | 42 | if (cfg->pci_segment_group_number != seg) |
@@ -46,6 +45,18 @@ static u32 get_base_addr(unsigned int seg, int bus, unsigned devfn) | |||
46 | (cfg->end_bus_number >= bus)) | 45 | (cfg->end_bus_number >= bus)) |
47 | return cfg->base_address; | 46 | return cfg->base_address; |
48 | } | 47 | } |
48 | |||
49 | /* Handle more broken MCFG tables on Asus etc. | ||
50 | They only contain a single entry for bus 0-0. Assume | ||
51 | this applies to all busses. */ | ||
52 | cfg = &pci_mmcfg_config[0]; | ||
53 | if (pci_mmcfg_config_num == 1 && | ||
54 | cfg->pci_segment_group_number == 0 && | ||
55 | (cfg->start_bus_number | cfg->end_bus_number) == 0) | ||
56 | return cfg->base_address; | ||
57 | |||
58 | /* Fall back to type 0 */ | ||
59 | return 0; | ||
49 | } | 60 | } |
50 | 61 | ||
51 | static inline void pci_exp_set_dev_base(unsigned int base, int bus, int devfn) | 62 | static inline void pci_exp_set_dev_base(unsigned int base, int bus, int devfn) |