diff options
Diffstat (limited to 'arch/x86/kernel/acpi')
-rw-r--r-- | arch/x86/kernel/acpi/boot.c | 63 |
1 files changed, 59 insertions, 4 deletions
diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c index 7678f10c4568..565e70c7ca93 100644 --- a/arch/x86/kernel/acpi/boot.c +++ b/arch/x86/kernel/acpi/boot.c | |||
@@ -260,6 +260,35 @@ static void __cpuinit acpi_register_lapic(int id, u8 enabled) | |||
260 | } | 260 | } |
261 | 261 | ||
262 | static int __init | 262 | static int __init |
263 | acpi_parse_x2apic(struct acpi_subtable_header *header, const unsigned long end) | ||
264 | { | ||
265 | struct acpi_madt_local_x2apic *processor = NULL; | ||
266 | |||
267 | processor = (struct acpi_madt_local_x2apic *)header; | ||
268 | |||
269 | if (BAD_MADT_ENTRY(processor, end)) | ||
270 | return -EINVAL; | ||
271 | |||
272 | acpi_table_print_madt_entry(header); | ||
273 | |||
274 | #ifdef CONFIG_X86_X2APIC | ||
275 | /* | ||
276 | * We need to register disabled CPU as well to permit | ||
277 | * counting disabled CPUs. This allows us to size | ||
278 | * cpus_possible_map more accurately, to permit | ||
279 | * to not preallocating memory for all NR_CPUS | ||
280 | * when we use CPU hotplug. | ||
281 | */ | ||
282 | acpi_register_lapic(processor->local_apic_id, /* APIC ID */ | ||
283 | processor->lapic_flags & ACPI_MADT_ENABLED); | ||
284 | #else | ||
285 | printk(KERN_WARNING PREFIX "x2apic entry ignored\n"); | ||
286 | #endif | ||
287 | |||
288 | return 0; | ||
289 | } | ||
290 | |||
291 | static int __init | ||
263 | acpi_parse_lapic(struct acpi_subtable_header * header, const unsigned long end) | 292 | acpi_parse_lapic(struct acpi_subtable_header * header, const unsigned long end) |
264 | { | 293 | { |
265 | struct acpi_madt_local_apic *processor = NULL; | 294 | struct acpi_madt_local_apic *processor = NULL; |
@@ -319,6 +348,25 @@ acpi_parse_lapic_addr_ovr(struct acpi_subtable_header * header, | |||
319 | } | 348 | } |
320 | 349 | ||
321 | static int __init | 350 | static int __init |
351 | acpi_parse_x2apic_nmi(struct acpi_subtable_header *header, | ||
352 | const unsigned long end) | ||
353 | { | ||
354 | struct acpi_madt_local_x2apic_nmi *x2apic_nmi = NULL; | ||
355 | |||
356 | x2apic_nmi = (struct acpi_madt_local_x2apic_nmi *)header; | ||
357 | |||
358 | if (BAD_MADT_ENTRY(x2apic_nmi, end)) | ||
359 | return -EINVAL; | ||
360 | |||
361 | acpi_table_print_madt_entry(header); | ||
362 | |||
363 | if (x2apic_nmi->lint != 1) | ||
364 | printk(KERN_WARNING PREFIX "NMI not connected to LINT 1!\n"); | ||
365 | |||
366 | return 0; | ||
367 | } | ||
368 | |||
369 | static int __init | ||
322 | acpi_parse_lapic_nmi(struct acpi_subtable_header * header, const unsigned long end) | 370 | acpi_parse_lapic_nmi(struct acpi_subtable_header * header, const unsigned long end) |
323 | { | 371 | { |
324 | struct acpi_madt_local_apic_nmi *lapic_nmi = NULL; | 372 | struct acpi_madt_local_apic_nmi *lapic_nmi = NULL; |
@@ -823,6 +871,7 @@ static int __init early_acpi_parse_madt_lapic_addr_ovr(void) | |||
823 | static int __init acpi_parse_madt_lapic_entries(void) | 871 | static int __init acpi_parse_madt_lapic_entries(void) |
824 | { | 872 | { |
825 | int count; | 873 | int count; |
874 | int x2count = 0; | ||
826 | 875 | ||
827 | if (!cpu_has_apic) | 876 | if (!cpu_has_apic) |
828 | return -ENODEV; | 877 | return -ENODEV; |
@@ -846,22 +895,28 @@ static int __init acpi_parse_madt_lapic_entries(void) | |||
846 | count = acpi_table_parse_madt(ACPI_MADT_TYPE_LOCAL_SAPIC, | 895 | count = acpi_table_parse_madt(ACPI_MADT_TYPE_LOCAL_SAPIC, |
847 | acpi_parse_sapic, MAX_APICS); | 896 | acpi_parse_sapic, MAX_APICS); |
848 | 897 | ||
849 | if (!count) | 898 | if (!count) { |
899 | x2count = acpi_table_parse_madt(ACPI_MADT_TYPE_LOCAL_X2APIC, | ||
900 | acpi_parse_x2apic, MAX_APICS); | ||
850 | count = acpi_table_parse_madt(ACPI_MADT_TYPE_LOCAL_APIC, | 901 | count = acpi_table_parse_madt(ACPI_MADT_TYPE_LOCAL_APIC, |
851 | acpi_parse_lapic, MAX_APICS); | 902 | acpi_parse_lapic, MAX_APICS); |
852 | if (!count) { | 903 | } |
904 | if (!count && !x2count) { | ||
853 | printk(KERN_ERR PREFIX "No LAPIC entries present\n"); | 905 | printk(KERN_ERR PREFIX "No LAPIC entries present\n"); |
854 | /* TBD: Cleanup to allow fallback to MPS */ | 906 | /* TBD: Cleanup to allow fallback to MPS */ |
855 | return -ENODEV; | 907 | return -ENODEV; |
856 | } else if (count < 0) { | 908 | } else if (count < 0 || x2count < 0) { |
857 | printk(KERN_ERR PREFIX "Error parsing LAPIC entry\n"); | 909 | printk(KERN_ERR PREFIX "Error parsing LAPIC entry\n"); |
858 | /* TBD: Cleanup to allow fallback to MPS */ | 910 | /* TBD: Cleanup to allow fallback to MPS */ |
859 | return count; | 911 | return count; |
860 | } | 912 | } |
861 | 913 | ||
914 | x2count = | ||
915 | acpi_table_parse_madt(ACPI_MADT_TYPE_LOCAL_X2APIC_NMI, | ||
916 | acpi_parse_x2apic_nmi, 0); | ||
862 | count = | 917 | count = |
863 | acpi_table_parse_madt(ACPI_MADT_TYPE_LOCAL_APIC_NMI, acpi_parse_lapic_nmi, 0); | 918 | acpi_table_parse_madt(ACPI_MADT_TYPE_LOCAL_APIC_NMI, acpi_parse_lapic_nmi, 0); |
864 | if (count < 0) { | 919 | if (count < 0 || x2count < 0) { |
865 | printk(KERN_ERR PREFIX "Error parsing LAPIC NMI entry\n"); | 920 | printk(KERN_ERR PREFIX "Error parsing LAPIC NMI entry\n"); |
866 | /* TBD: Cleanup to allow fallback to MPS */ | 921 | /* TBD: Cleanup to allow fallback to MPS */ |
867 | return count; | 922 | return count; |