aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel/apic_64.c
diff options
context:
space:
mode:
authorIngo Molnar <mingo@elte.hu>2008-07-18 15:13:20 -0400
committerIngo Molnar <mingo@elte.hu>2008-07-18 15:13:20 -0400
commitf6dc8ccaab6d8f63cbae1e6c73fe972b26f5376c (patch)
treec5643fcdc884a8d0bfc3f1bc28039cab7394e5bc /arch/x86/kernel/apic_64.c
parent323ec001c6bb98eeabb5abbdbb8c8055d9496554 (diff)
parent5b664cb235e97afbf34db9c4d77f08ebd725335e (diff)
Merge branch 'linus' into core/generic-dma-coherent
Conflicts: kernel/Makefile Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'arch/x86/kernel/apic_64.c')
-rw-r--r--arch/x86/kernel/apic_64.c68
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
46int disable_apic_timer __cpuinitdata; 46static int disable_apic_timer __cpuinitdata;
47static int apic_calibrate_pmtmr __initdata; 47static int apic_calibrate_pmtmr __initdata;
48int disable_apic; 48int disable_apic;
49 49
@@ -56,6 +56,9 @@ EXPORT_SYMBOL_GPL(local_apic_timer_c2_ok);
56 */ 56 */
57int apic_verbosity; 57int apic_verbosity;
58 58
59/* Have we found an MP table */
60int smp_found_config;
61
59static struct resource lapic_resource = { 62static 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
88unsigned long mp_lapic_addr; 91unsigned long mp_lapic_addr;
89 92
90DEFINE_PER_CPU(u16, x86_bios_cpu_apicid) = BAD_APICID;
91EXPORT_PER_CPU_SYMBOL(x86_bios_cpu_apicid);
92
93unsigned int __cpuinitdata maxcpus = NR_CPUS; 93unsigned 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 */
433static 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
448void __cpuinit setup_secondary_APIC_clock(void) 425void __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)
850void __cpuinit end_local_APIC_setup(void) 826void __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
876void __init early_init_lapic_mapping(void) 851void __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 * */
1006void __init connect_bsp_APIC(void)
1007{
1008 enable_apic_mode();
1009}
1010
1024void disconnect_bsp_APIC(int virt_wire_setup) 1011void 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++) {