diff options
Diffstat (limited to 'arch/x86/kernel/apic_64.c')
-rw-r--r-- | arch/x86/kernel/apic_64.c | 68 |
1 files changed, 29 insertions, 39 deletions
diff --git a/arch/x86/kernel/apic_64.c b/arch/x86/kernel/apic_64.c index 0633cfd0dc29..1e3d32e27c14 100644 --- a/arch/x86/kernel/apic_64.c +++ b/arch/x86/kernel/apic_64.c | |||
@@ -43,7 +43,7 @@ | |||
43 | #include <mach_ipi.h> | 43 | #include <mach_ipi.h> |
44 | #include <mach_apic.h> | 44 | #include <mach_apic.h> |
45 | 45 | ||
46 | int disable_apic_timer __cpuinitdata; | 46 | static int disable_apic_timer __cpuinitdata; |
47 | static int apic_calibrate_pmtmr __initdata; | 47 | static int apic_calibrate_pmtmr __initdata; |
48 | int disable_apic; | 48 | int disable_apic; |
49 | 49 | ||
@@ -56,6 +56,9 @@ EXPORT_SYMBOL_GPL(local_apic_timer_c2_ok); | |||
56 | */ | 56 | */ |
57 | int apic_verbosity; | 57 | int apic_verbosity; |
58 | 58 | ||
59 | /* Have we found an MP table */ | ||
60 | int smp_found_config; | ||
61 | |||
59 | static struct resource lapic_resource = { | 62 | static struct resource lapic_resource = { |
60 | .name = "Local APIC", | 63 | .name = "Local APIC", |
61 | .flags = IORESOURCE_MEM | IORESOURCE_BUSY, | 64 | .flags = IORESOURCE_MEM | IORESOURCE_BUSY, |
@@ -87,9 +90,6 @@ static unsigned long apic_phys; | |||
87 | 90 | ||
88 | unsigned long mp_lapic_addr; | 91 | unsigned long mp_lapic_addr; |
89 | 92 | ||
90 | DEFINE_PER_CPU(u16, x86_bios_cpu_apicid) = BAD_APICID; | ||
91 | EXPORT_PER_CPU_SYMBOL(x86_bios_cpu_apicid); | ||
92 | |||
93 | unsigned int __cpuinitdata maxcpus = NR_CPUS; | 93 | unsigned int __cpuinitdata maxcpus = NR_CPUS; |
94 | /* | 94 | /* |
95 | * Get the LAPIC version | 95 | * Get the LAPIC version |
@@ -417,37 +417,13 @@ void __init setup_boot_APIC_clock(void) | |||
417 | lapic_clockevent.features &= ~CLOCK_EVT_FEAT_DUMMY; | 417 | lapic_clockevent.features &= ~CLOCK_EVT_FEAT_DUMMY; |
418 | else | 418 | else |
419 | printk(KERN_WARNING "APIC timer registered as dummy," | 419 | printk(KERN_WARNING "APIC timer registered as dummy," |
420 | " due to nmi_watchdog=1!\n"); | 420 | " due to nmi_watchdog=%d!\n", nmi_watchdog); |
421 | 421 | ||
422 | setup_APIC_timer(); | 422 | setup_APIC_timer(); |
423 | } | 423 | } |
424 | 424 | ||
425 | /* | ||
426 | * AMD C1E enabled CPUs have a real nasty problem: Some BIOSes set the | ||
427 | * C1E flag only in the secondary CPU, so when we detect the wreckage | ||
428 | * we already have enabled the boot CPU local apic timer. Check, if | ||
429 | * disable_apic_timer is set and the DUMMY flag is cleared. If yes, | ||
430 | * set the DUMMY flag again and force the broadcast mode in the | ||
431 | * clockevents layer. | ||
432 | */ | ||
433 | static void __cpuinit check_boot_apic_timer_broadcast(void) | ||
434 | { | ||
435 | if (!disable_apic_timer || | ||
436 | (lapic_clockevent.features & CLOCK_EVT_FEAT_DUMMY)) | ||
437 | return; | ||
438 | |||
439 | printk(KERN_INFO "AMD C1E detected late. Force timer broadcast.\n"); | ||
440 | lapic_clockevent.features |= CLOCK_EVT_FEAT_DUMMY; | ||
441 | |||
442 | local_irq_enable(); | ||
443 | clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_FORCE, | ||
444 | &boot_cpu_physical_apicid); | ||
445 | local_irq_disable(); | ||
446 | } | ||
447 | |||
448 | void __cpuinit setup_secondary_APIC_clock(void) | 425 | void __cpuinit setup_secondary_APIC_clock(void) |
449 | { | 426 | { |
450 | check_boot_apic_timer_broadcast(); | ||
451 | setup_APIC_timer(); | 427 | setup_APIC_timer(); |
452 | } | 428 | } |
453 | 429 | ||
@@ -850,7 +826,6 @@ static void __cpuinit lapic_setup_esr(void) | |||
850 | void __cpuinit end_local_APIC_setup(void) | 826 | void __cpuinit end_local_APIC_setup(void) |
851 | { | 827 | { |
852 | lapic_setup_esr(); | 828 | lapic_setup_esr(); |
853 | nmi_watchdog_default(); | ||
854 | setup_apic_nmi_watchdog(NULL); | 829 | setup_apic_nmi_watchdog(NULL); |
855 | apic_pm_activate(); | 830 | apic_pm_activate(); |
856 | } | 831 | } |
@@ -875,7 +850,7 @@ static int __init detect_init_APIC(void) | |||
875 | 850 | ||
876 | void __init early_init_lapic_mapping(void) | 851 | void __init early_init_lapic_mapping(void) |
877 | { | 852 | { |
878 | unsigned long apic_phys; | 853 | unsigned long phys_addr; |
879 | 854 | ||
880 | /* | 855 | /* |
881 | * If no local APIC can be found then go out | 856 | * If no local APIC can be found then go out |
@@ -884,11 +859,11 @@ void __init early_init_lapic_mapping(void) | |||
884 | if (!smp_found_config) | 859 | if (!smp_found_config) |
885 | return; | 860 | return; |
886 | 861 | ||
887 | apic_phys = mp_lapic_addr; | 862 | phys_addr = mp_lapic_addr; |
888 | 863 | ||
889 | set_fixmap_nocache(FIX_APIC_BASE, apic_phys); | 864 | set_fixmap_nocache(FIX_APIC_BASE, phys_addr); |
890 | apic_printk(APIC_VERBOSE, "mapped APIC to %16lx (%16lx)\n", | 865 | apic_printk(APIC_VERBOSE, "mapped APIC to %16lx (%16lx)\n", |
891 | APIC_BASE, apic_phys); | 866 | APIC_BASE, phys_addr); |
892 | 867 | ||
893 | /* | 868 | /* |
894 | * Fetch the APIC ID of the BSP in case we have a | 869 | * Fetch the APIC ID of the BSP in case we have a |
@@ -942,7 +917,9 @@ int __init APIC_init_uniprocessor(void) | |||
942 | 917 | ||
943 | verify_local_APIC(); | 918 | verify_local_APIC(); |
944 | 919 | ||
945 | phys_cpu_present_map = physid_mask_of_physid(boot_cpu_physical_apicid); | 920 | connect_bsp_APIC(); |
921 | |||
922 | physid_set_mask_of_physid(boot_cpu_physical_apicid, &phys_cpu_present_map); | ||
946 | apic_write(APIC_ID, SET_APIC_ID(boot_cpu_physical_apicid)); | 923 | apic_write(APIC_ID, SET_APIC_ID(boot_cpu_physical_apicid)); |
947 | 924 | ||
948 | setup_local_APIC(); | 925 | setup_local_APIC(); |
@@ -954,6 +931,8 @@ int __init APIC_init_uniprocessor(void) | |||
954 | if (!skip_ioapic_setup && nr_ioapics) | 931 | if (!skip_ioapic_setup && nr_ioapics) |
955 | enable_IO_APIC(); | 932 | enable_IO_APIC(); |
956 | 933 | ||
934 | if (!smp_found_config || skip_ioapic_setup || !nr_ioapics) | ||
935 | localise_nmi_watchdog(); | ||
957 | end_local_APIC_setup(); | 936 | end_local_APIC_setup(); |
958 | 937 | ||
959 | if (smp_found_config && !skip_ioapic_setup && nr_ioapics) | 938 | if (smp_found_config && !skip_ioapic_setup && nr_ioapics) |
@@ -1021,6 +1000,14 @@ asmlinkage void smp_error_interrupt(void) | |||
1021 | irq_exit(); | 1000 | irq_exit(); |
1022 | } | 1001 | } |
1023 | 1002 | ||
1003 | /** | ||
1004 | * * connect_bsp_APIC - attach the APIC to the interrupt system | ||
1005 | * */ | ||
1006 | void __init connect_bsp_APIC(void) | ||
1007 | { | ||
1008 | enable_apic_mode(); | ||
1009 | } | ||
1010 | |||
1024 | void disconnect_bsp_APIC(int virt_wire_setup) | 1011 | void disconnect_bsp_APIC(int virt_wire_setup) |
1025 | { | 1012 | { |
1026 | /* Go back to Virtual Wire compatibility mode */ | 1013 | /* Go back to Virtual Wire compatibility mode */ |
@@ -1090,10 +1077,13 @@ void __cpuinit generic_processor_info(int apicid, int version) | |||
1090 | */ | 1077 | */ |
1091 | cpu = 0; | 1078 | cpu = 0; |
1092 | } | 1079 | } |
1080 | if (apicid > max_physical_apicid) | ||
1081 | max_physical_apicid = apicid; | ||
1082 | |||
1093 | /* are we being called early in kernel startup? */ | 1083 | /* are we being called early in kernel startup? */ |
1094 | if (x86_cpu_to_apicid_early_ptr) { | 1084 | if (early_per_cpu_ptr(x86_cpu_to_apicid)) { |
1095 | u16 *cpu_to_apicid = x86_cpu_to_apicid_early_ptr; | 1085 | u16 *cpu_to_apicid = early_per_cpu_ptr(x86_cpu_to_apicid); |
1096 | u16 *bios_cpu_apicid = x86_bios_cpu_apicid_early_ptr; | 1086 | u16 *bios_cpu_apicid = early_per_cpu_ptr(x86_bios_cpu_apicid); |
1097 | 1087 | ||
1098 | cpu_to_apicid[cpu] = apicid; | 1088 | cpu_to_apicid[cpu] = apicid; |
1099 | bios_cpu_apicid[cpu] = apicid; | 1089 | bios_cpu_apicid[cpu] = apicid; |
@@ -1269,7 +1259,7 @@ __cpuinit int apic_is_clustered_box(void) | |||
1269 | if ((boot_cpu_data.x86_vendor == X86_VENDOR_AMD) && !is_vsmp_box()) | 1259 | if ((boot_cpu_data.x86_vendor == X86_VENDOR_AMD) && !is_vsmp_box()) |
1270 | return 0; | 1260 | return 0; |
1271 | 1261 | ||
1272 | bios_cpu_apicid = x86_bios_cpu_apicid_early_ptr; | 1262 | bios_cpu_apicid = early_per_cpu_ptr(x86_bios_cpu_apicid); |
1273 | bitmap_zero(clustermap, NUM_APIC_CLUSTERS); | 1263 | bitmap_zero(clustermap, NUM_APIC_CLUSTERS); |
1274 | 1264 | ||
1275 | for (i = 0; i < NR_CPUS; i++) { | 1265 | for (i = 0; i < NR_CPUS; i++) { |