diff options
| author | Ingo Molnar <mingo@elte.hu> | 2009-03-21 12:37:35 -0400 |
|---|---|---|
| committer | Ingo Molnar <mingo@elte.hu> | 2009-03-21 12:37:35 -0400 |
| commit | 648340dff02eff10cc08fa4e8d20442d7a238768 (patch) | |
| tree | 00837501c137c45910d0199368ff6eb574835ee6 | |
| parent | 1894e36754d682cc049b2b1c3825da8e585967d5 (diff) | |
| parent | 0b3ba0c3ccc7ced2a06fed405e80c8e1c77a3ee7 (diff) | |
Merge branch 'x86/core' of git://git.kernel.org/pub/scm/linux/kernel/git/jaswinder/linux-2.6-tip into x86/cleanups
| -rw-r--r-- | arch/x86/kernel/mpparse.c | 112 |
1 files changed, 60 insertions, 52 deletions
diff --git a/arch/x86/kernel/mpparse.c b/arch/x86/kernel/mpparse.c index 290cb57f4697..dce99dca6cf8 100644 --- a/arch/x86/kernel/mpparse.c +++ b/arch/x86/kernel/mpparse.c | |||
| @@ -282,6 +282,14 @@ static void skip_entry(unsigned char **ptr, int *count, int size) | |||
| 282 | *count += size; | 282 | *count += size; |
| 283 | } | 283 | } |
| 284 | 284 | ||
| 285 | static void __init smp_dump_mptable(struct mpc_table *mpc, unsigned char *mpt) | ||
| 286 | { | ||
| 287 | printk(KERN_ERR "Your mptable is wrong, contact your HW vendor!\n" | ||
| 288 | "type %x\n", *mpt); | ||
| 289 | print_hex_dump(KERN_ERR, " ", DUMP_PREFIX_ADDRESS, 16, | ||
| 290 | 1, mpc, mpc->length, 1); | ||
| 291 | } | ||
| 292 | |||
| 285 | static int __init smp_read_mpc(struct mpc_table *mpc, unsigned early) | 293 | static int __init smp_read_mpc(struct mpc_table *mpc, unsigned early) |
| 286 | { | 294 | { |
| 287 | char str[16]; | 295 | char str[16]; |
| @@ -340,10 +348,7 @@ static int __init smp_read_mpc(struct mpc_table *mpc, unsigned early) | |||
| 340 | break; | 348 | break; |
| 341 | default: | 349 | default: |
| 342 | /* wrong mptable */ | 350 | /* wrong mptable */ |
| 343 | printk(KERN_ERR "Your mptable is wrong, contact your HW vendor!\n"); | 351 | smp_dump_mptable(mpc, mpt); |
| 344 | printk(KERN_ERR "type %x\n", *mpt); | ||
| 345 | print_hex_dump(KERN_ERR, " ", DUMP_PREFIX_ADDRESS, 16, | ||
| 346 | 1, mpc, mpc->length, 1); | ||
| 347 | count = mpc->length; | 352 | count = mpc->length; |
| 348 | break; | 353 | break; |
| 349 | } | 354 | } |
| @@ -550,6 +555,55 @@ static unsigned long __init get_mpc_size(unsigned long physptr) | |||
| 550 | return size; | 555 | return size; |
| 551 | } | 556 | } |
| 552 | 557 | ||
| 558 | static int __init check_physptr(struct mpf_intel *mpf, unsigned int early) | ||
| 559 | { | ||
| 560 | struct mpc_table *mpc; | ||
| 561 | unsigned long size; | ||
| 562 | |||
| 563 | size = get_mpc_size(mpf->physptr); | ||
| 564 | mpc = early_ioremap(mpf->physptr, size); | ||
| 565 | /* | ||
| 566 | * Read the physical hardware table. Anything here will | ||
| 567 | * override the defaults. | ||
| 568 | */ | ||
| 569 | if (!smp_read_mpc(mpc, early)) { | ||
| 570 | #ifdef CONFIG_X86_LOCAL_APIC | ||
| 571 | smp_found_config = 0; | ||
| 572 | #endif | ||
| 573 | printk(KERN_ERR "BIOS bug, MP table errors detected!...\n" | ||
| 574 | "... disabling SMP support. (tell your hw vendor)\n"); | ||
| 575 | early_iounmap(mpc, size); | ||
| 576 | return -1; | ||
| 577 | } | ||
| 578 | early_iounmap(mpc, size); | ||
| 579 | |||
| 580 | if (early) | ||
| 581 | return -1; | ||
| 582 | |||
| 583 | #ifdef CONFIG_X86_IO_APIC | ||
| 584 | /* | ||
| 585 | * If there are no explicit MP IRQ entries, then we are | ||
| 586 | * broken. We set up most of the low 16 IO-APIC pins to | ||
| 587 | * ISA defaults and hope it will work. | ||
| 588 | */ | ||
| 589 | if (!mp_irq_entries) { | ||
| 590 | struct mpc_bus bus; | ||
| 591 | |||
| 592 | printk(KERN_ERR "BIOS bug, no explicit IRQ entries, " | ||
| 593 | "using default mptable. (tell your hw vendor)\n"); | ||
| 594 | |||
| 595 | bus.type = MP_BUS; | ||
| 596 | bus.busid = 0; | ||
| 597 | memcpy(bus.bustype, "ISA ", 6); | ||
| 598 | MP_bus_info(&bus); | ||
| 599 | |||
| 600 | construct_default_ioirq_mptable(0); | ||
| 601 | } | ||
| 602 | #endif | ||
| 603 | |||
| 604 | return 0; | ||
| 605 | } | ||
| 606 | |||
| 553 | /* | 607 | /* |
| 554 | * Scan the memory blocks for an SMP configuration block. | 608 | * Scan the memory blocks for an SMP configuration block. |
| 555 | */ | 609 | */ |
| @@ -603,51 +657,8 @@ static void __init __get_smp_config(unsigned int early) | |||
| 603 | construct_default_ISA_mptable(mpf->feature1); | 657 | construct_default_ISA_mptable(mpf->feature1); |
| 604 | 658 | ||
| 605 | } else if (mpf->physptr) { | 659 | } else if (mpf->physptr) { |
| 606 | struct mpc_table *mpc; | 660 | if (check_physptr(mpf, early)) |
| 607 | unsigned long size; | ||
| 608 | |||
| 609 | size = get_mpc_size(mpf->physptr); | ||
| 610 | mpc = early_ioremap(mpf->physptr, size); | ||
| 611 | /* | ||
| 612 | * Read the physical hardware table. Anything here will | ||
| 613 | * override the defaults. | ||
| 614 | */ | ||
| 615 | if (!smp_read_mpc(mpc, early)) { | ||
| 616 | #ifdef CONFIG_X86_LOCAL_APIC | ||
| 617 | smp_found_config = 0; | ||
| 618 | #endif | ||
| 619 | printk(KERN_ERR | ||
| 620 | "BIOS bug, MP table errors detected!...\n"); | ||
| 621 | printk(KERN_ERR "... disabling SMP support. " | ||
| 622 | "(tell your hw vendor)\n"); | ||
| 623 | early_iounmap(mpc, size); | ||
| 624 | return; | 661 | return; |
| 625 | } | ||
| 626 | early_iounmap(mpc, size); | ||
| 627 | |||
| 628 | if (early) | ||
| 629 | return; | ||
| 630 | #ifdef CONFIG_X86_IO_APIC | ||
| 631 | /* | ||
| 632 | * If there are no explicit MP IRQ entries, then we are | ||
| 633 | * broken. We set up most of the low 16 IO-APIC pins to | ||
| 634 | * ISA defaults and hope it will work. | ||
| 635 | */ | ||
| 636 | if (!mp_irq_entries) { | ||
| 637 | struct mpc_bus bus; | ||
| 638 | |||
| 639 | printk(KERN_ERR "BIOS bug, no explicit IRQ entries, " | ||
| 640 | "using default mptable. " | ||
| 641 | "(tell your hw vendor)\n"); | ||
| 642 | |||
| 643 | bus.type = MP_BUS; | ||
| 644 | bus.busid = 0; | ||
| 645 | memcpy(bus.bustype, "ISA ", 6); | ||
| 646 | MP_bus_info(&bus); | ||
| 647 | |||
| 648 | construct_default_ioirq_mptable(0); | ||
| 649 | } | ||
| 650 | #endif | ||
| 651 | } else | 662 | } else |
| 652 | BUG(); | 663 | BUG(); |
| 653 | 664 | ||
| @@ -910,10 +921,7 @@ static int __init replace_intsrc_all(struct mpc_table *mpc, | |||
| 910 | break; | 921 | break; |
| 911 | default: | 922 | default: |
| 912 | /* wrong mptable */ | 923 | /* wrong mptable */ |
| 913 | printk(KERN_ERR "Your mptable is wrong, contact your HW vendor!\n"); | 924 | smp_dump_mptable(mpc, mpt); |
| 914 | printk(KERN_ERR "type %x\n", *mpt); | ||
| 915 | print_hex_dump(KERN_ERR, " ", DUMP_PREFIX_ADDRESS, 16, | ||
| 916 | 1, mpc, mpc->length, 1); | ||
| 917 | goto out; | 925 | goto out; |
| 918 | } | 926 | } |
| 919 | } | 927 | } |
