diff options
Diffstat (limited to 'arch/x86/kernel/acpi/boot.c')
-rw-r--r-- | arch/x86/kernel/acpi/boot.c | 70 |
1 files changed, 70 insertions, 0 deletions
diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c index 977ed5cdeaa3..c49ebcc6c41e 100644 --- a/arch/x86/kernel/acpi/boot.c +++ b/arch/x86/kernel/acpi/boot.c | |||
@@ -771,6 +771,32 @@ static void __init acpi_register_lapic_address(unsigned long address) | |||
771 | boot_cpu_physical_apicid = GET_APIC_ID(read_apic_id()); | 771 | boot_cpu_physical_apicid = GET_APIC_ID(read_apic_id()); |
772 | } | 772 | } |
773 | 773 | ||
774 | static int __init early_acpi_parse_madt_lapic_addr_ovr(void) | ||
775 | { | ||
776 | int count; | ||
777 | |||
778 | if (!cpu_has_apic) | ||
779 | return -ENODEV; | ||
780 | |||
781 | /* | ||
782 | * Note that the LAPIC address is obtained from the MADT (32-bit value) | ||
783 | * and (optionally) overriden by a LAPIC_ADDR_OVR entry (64-bit value). | ||
784 | */ | ||
785 | |||
786 | count = | ||
787 | acpi_table_parse_madt(ACPI_MADT_TYPE_LOCAL_APIC_OVERRIDE, | ||
788 | acpi_parse_lapic_addr_ovr, 0); | ||
789 | if (count < 0) { | ||
790 | printk(KERN_ERR PREFIX | ||
791 | "Error parsing LAPIC address override entry\n"); | ||
792 | return count; | ||
793 | } | ||
794 | |||
795 | acpi_register_lapic_address(acpi_lapic_addr); | ||
796 | |||
797 | return count; | ||
798 | } | ||
799 | |||
774 | static int __init acpi_parse_madt_lapic_entries(void) | 800 | static int __init acpi_parse_madt_lapic_entries(void) |
775 | { | 801 | { |
776 | int count; | 802 | int count; |
@@ -901,6 +927,33 @@ static inline int acpi_parse_madt_ioapic_entries(void) | |||
901 | } | 927 | } |
902 | #endif /* !CONFIG_X86_IO_APIC */ | 928 | #endif /* !CONFIG_X86_IO_APIC */ |
903 | 929 | ||
930 | static void __init early_acpi_process_madt(void) | ||
931 | { | ||
932 | #ifdef CONFIG_X86_LOCAL_APIC | ||
933 | int error; | ||
934 | |||
935 | if (!acpi_table_parse(ACPI_SIG_MADT, acpi_parse_madt)) { | ||
936 | |||
937 | /* | ||
938 | * Parse MADT LAPIC entries | ||
939 | */ | ||
940 | error = early_acpi_parse_madt_lapic_addr_ovr(); | ||
941 | if (!error) { | ||
942 | acpi_lapic = 1; | ||
943 | smp_found_config = 1; | ||
944 | } | ||
945 | if (error == -EINVAL) { | ||
946 | /* | ||
947 | * Dell Precision Workstation 410, 610 come here. | ||
948 | */ | ||
949 | printk(KERN_ERR PREFIX | ||
950 | "Invalid BIOS MADT, disabling ACPI\n"); | ||
951 | disable_acpi(); | ||
952 | } | ||
953 | } | ||
954 | #endif | ||
955 | } | ||
956 | |||
904 | static void __init acpi_process_madt(void) | 957 | static void __init acpi_process_madt(void) |
905 | { | 958 | { |
906 | #ifdef CONFIG_X86_LOCAL_APIC | 959 | #ifdef CONFIG_X86_LOCAL_APIC |
@@ -1233,6 +1286,23 @@ int __init acpi_boot_table_init(void) | |||
1233 | return 0; | 1286 | return 0; |
1234 | } | 1287 | } |
1235 | 1288 | ||
1289 | int __init early_acpi_boot_init(void) | ||
1290 | { | ||
1291 | /* | ||
1292 | * If acpi_disabled, bail out | ||
1293 | * One exception: acpi=ht continues far enough to enumerate LAPICs | ||
1294 | */ | ||
1295 | if (acpi_disabled && !acpi_ht) | ||
1296 | return 1; | ||
1297 | |||
1298 | /* | ||
1299 | * Process the Multiple APIC Description Table (MADT), if present | ||
1300 | */ | ||
1301 | early_acpi_process_madt(); | ||
1302 | |||
1303 | return 0; | ||
1304 | } | ||
1305 | |||
1236 | int __init acpi_boot_init(void) | 1306 | int __init acpi_boot_init(void) |
1237 | { | 1307 | { |
1238 | /* | 1308 | /* |