]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - arch/x86/kernel/apic_32.c
x86: add testcases for RODATA and NX protections/attributes
[linux-2.6-omap-h63xx.git] / arch / x86 / kernel / apic_32.c
index 56352c11a896633a126e0cbd9f4858353152c5b2..35a568ea8400269f4fde96377e76e1013fc5c3e3 100644 (file)
@@ -46,7 +46,7 @@
 /*
  * Sanity check
  */
-#if (SPURIOUS_APIC_VECTOR & 0x0F) != 0x0F
+#if ((SPURIOUS_APIC_VECTOR & 0x0F) != 0x0F)
 # error SPURIOUS_APIC_VECTOR definition error
 #endif
 
@@ -55,7 +55,7 @@
  *
  * -1=force-disable, +1=force-enable
  */
-static int enable_local_apic __initdata = 0;
+static int enable_local_apic __initdata;
 
 /* Local APIC timer verification ok */
 static int local_apic_timer_verify_ok;
@@ -99,6 +99,8 @@ static DEFINE_PER_CPU(struct clock_event_device, lapic_events);
 /* Local APIC was disabled by the BIOS and enabled by the kernel */
 static int enabled_via_apicbase;
 
+static unsigned long apic_phys;
+
 /*
  * Get the LAPIC version
  */
@@ -108,7 +110,7 @@ static inline int lapic_get_version(void)
 }
 
 /*
- * Check, if the APIC is integrated or a seperate chip
+ * Check, if the APIC is integrated or a separate chip
  */
 static inline int lapic_is_integrated(void)
 {
@@ -152,7 +154,7 @@ u32 safe_apic_wait_icr_idle(void)
 /**
  * enable_NMI_through_LVT0 - enable NMI through local vector table 0
  */
-void enable_NMI_through_LVT0 (void * dummy)
+void __cpuinit enable_NMI_through_LVT0(void)
 {
        unsigned int v = APIC_DM_NMI;
 
@@ -377,8 +379,10 @@ void __init setup_boot_APIC_clock(void)
         */
        if (local_apic_timer_disabled) {
                /* No broadcast on UP ! */
-               if (num_possible_cpus() > 1)
+               if (num_possible_cpus() > 1) {
+                       lapic_clockevent.mult = 1;
                        setup_APIC_timer();
+               }
                return;
        }
 
@@ -432,7 +436,7 @@ void __init setup_boot_APIC_clock(void)
                               "with PM Timer: %ldms instead of 100ms\n",
                               (long)res);
                        /* Correct the lapic counter value */
-                       res = (((u64) delta ) * pm_100ms);
+                       res = (((u64) delta) * pm_100ms);
                        do_div(res, deltapm);
                        printk(KERN_INFO "APIC delta adjusted to PM-Timer: "
                               "%lu (%ld)\n", (unsigned long) res, delta);
@@ -470,6 +474,19 @@ void __init setup_boot_APIC_clock(void)
 
        local_apic_timer_verify_ok = 1;
 
+       /*
+        * Do a sanity check on the APIC calibration result
+        */
+       if (calibration_result < (1000000 / HZ)) {
+               local_irq_enable();
+               printk(KERN_WARNING
+                      "APIC frequency too slow, disabling apic timer\n");
+               /* No broadcast on UP ! */
+               if (num_possible_cpus() > 1)
+                       setup_APIC_timer();
+               return;
+       }
+
        /* We trust the pm timer based calibration */
        if (!pm_referenced) {
                apic_printk(APIC_VERBOSE, "... verify APIC timer\n");
@@ -577,8 +594,7 @@ static void local_apic_timer_interrupt(void)
  * [ if a single-CPU system runs an SMP kernel then we call the local
  *   interrupt as well. Thus we cannot inline the local irq ... ]
  */
-
-void fastcall smp_apic_timer_interrupt(struct pt_regs *regs)
+void smp_apic_timer_interrupt(struct pt_regs *regs)
 {
        struct pt_regs *old_regs = set_irq_regs(regs);
 
@@ -617,9 +633,14 @@ int setup_profiling_timer(unsigned int multiplier)
  */
 void clear_local_APIC(void)
 {
-       int maxlvt = lapic_get_maxlvt();
+       int maxlvt;
        u32 v;
 
+       /* APIC hasn't been mapped yet */
+       if (!apic_phys)
+               return;
+
+       maxlvt = lapic_get_maxlvt();
        /*
         * Masking an LVT entry can trigger a local APIC error
         * if the vector is zero. Mask LVTERR first to prevent this.
@@ -977,7 +998,8 @@ void __cpuinit setup_local_APIC(void)
                value |= APIC_LVT_LEVEL_TRIGGER;
        apic_write_around(APIC_LVT1, value);
 
-       if (integrated && !esr_disable) {               /* !82489DX */
+       if (integrated && !esr_disable) {
+               /* !82489DX */
                maxlvt = lapic_get_maxlvt();
                if (maxlvt > 3)         /* Due to the Pentium erratum 3AP. */
                        apic_write(APIC_ESR, 0);
@@ -1021,7 +1043,7 @@ void __cpuinit setup_local_APIC(void)
 /*
  * Detect and initialize APIC
  */
-static int __init detect_init_APIC (void)
+static int __init detect_init_APIC(void)
 {
        u32 h, l, features;
 
@@ -1078,7 +1100,7 @@ static int __init detect_init_APIC (void)
                printk(KERN_WARNING "Could not enable APIC!\n");
                return -1;
        }
-       set_bit(X86_FEATURE_APIC, boot_cpu_data.x86_capability);
+       set_cpu_cap(&boot_cpu_data, X86_FEATURE_APIC);
        mp_lapic_addr = APIC_DEFAULT_PHYS_BASE;
 
        /* The BIOS may have set up the APIC at some other address */
@@ -1105,8 +1127,6 @@ no_apic:
  */
 void __init init_apic_mappings(void)
 {
-       unsigned long apic_phys;
-
        /*
         * If no local APIC can be found then set up a fake all
         * zeroes page to simulate the local APIC and another
@@ -1165,10 +1185,10 @@ fake_ioapic_page:
  * This initializes the IO-APIC and APIC hardware if this is
  * a UP kernel.
  */
-int __init APIC_init_uniprocessor (void)
+int __init APIC_init_uniprocessor(void)
 {
        if (enable_local_apic < 0)
-               clear_bit(X86_FEATURE_APIC, boot_cpu_data.x86_capability);
+               clear_cpu_cap(&boot_cpu_data, X86_FEATURE_APIC);
 
        if (!smp_found_config && !cpu_has_apic)
                return -1;
@@ -1180,7 +1200,7 @@ int __init APIC_init_uniprocessor (void)
            APIC_INTEGRATED(apic_version[boot_cpu_physical_apicid])) {
                printk(KERN_ERR "BIOS bug, local APIC #%d not detected!...\n",
                       boot_cpu_physical_apicid);
-               clear_bit(X86_FEATURE_APIC, boot_cpu_data.x86_capability);
+               clear_cpu_cap(&boot_cpu_data, X86_FEATURE_APIC);
                return -1;
        }
 
@@ -1263,7 +1283,7 @@ void smp_error_interrupt(struct pt_regs *regs)
           6: Received illegal vector
           7: Illegal register address
        */
-       printk (KERN_DEBUG "APIC error on CPU%d: %02lx(%02lx)\n",
+       printk(KERN_DEBUG "APIC error on CPU%d: %02lx(%02lx)\n",
                smp_processor_id(), v , v1);
        irq_exit();
 }
@@ -1350,7 +1370,7 @@ void disconnect_bsp_APIC(int virt_wire_setup)
                        value = apic_read(APIC_LVT0);
                        value &= ~(APIC_MODE_MASK | APIC_SEND_PENDING |
                                APIC_INPUT_POLARITY | APIC_LVT_REMOTE_IRR |
-                               APIC_LVT_LEVEL_TRIGGER | APIC_LVT_MASKED );
+                               APIC_LVT_LEVEL_TRIGGER | APIC_LVT_MASKED);
                        value |= APIC_LVT_REMOTE_IRR | APIC_SEND_PENDING;
                        value = SET_APIC_DELIVERY_MODE(value, APIC_MODE_EXTINT);
                        apic_write_around(APIC_LVT0, value);
@@ -1536,7 +1556,7 @@ early_param("lapic", parse_lapic);
 static int __init parse_nolapic(char *arg)
 {
        enable_local_apic = -1;
-       clear_bit(X86_FEATURE_APIC, boot_cpu_data.x86_capability);
+       clear_cpu_cap(&boot_cpu_data, X86_FEATURE_APIC);
        return 0;
 }
 early_param("nolapic", parse_nolapic);