]> git.karo-electronics.de Git - mv-sheeva.git/blobdiff - arch/x86/kernel/apic/apic.c
Merge branch 'x86-platform-for-linus' of git://git.kernel.org/pub/scm/linux/kernel...
[mv-sheeva.git] / arch / x86 / kernel / apic / apic.c
index ffbf7c21bbc66d897a0da3d4b0bfb09de49eb270..966673f44141ef1db7d5f8e1ab198fc28b53f6df 100644 (file)
@@ -79,6 +79,15 @@ EXPORT_EARLY_PER_CPU_SYMBOL(x86_cpu_to_apicid);
 EXPORT_EARLY_PER_CPU_SYMBOL(x86_bios_cpu_apicid);
 
 #ifdef CONFIG_X86_32
+
+/*
+ * On x86_32, the mapping between cpu and logical apicid may vary
+ * depending on apic in use.  The following early percpu variable is
+ * used for the mapping.  This is where the behaviors of x86_64 and 32
+ * actually diverge.  Let's keep it ugly for now.
+ */
+DEFINE_EARLY_PER_CPU(int, x86_cpu_to_logical_apicid, BAD_APICID);
+
 /*
  * Knob to control our willingness to enable the local APIC.
  *
@@ -1217,6 +1226,19 @@ void __cpuinit setup_local_APIC(void)
         */
        apic->init_apic_ldr();
 
+#ifdef CONFIG_X86_32
+       /*
+        * APIC LDR is initialized.  If logical_apicid mapping was
+        * initialized during get_smp_config(), make sure it matches the
+        * actual value.
+        */
+       i = early_per_cpu(x86_cpu_to_logical_apicid, cpu);
+       WARN_ON(i != BAD_APICID && i != logical_smp_processor_id());
+       /* always use the value from LDR */
+       early_per_cpu(x86_cpu_to_logical_apicid, cpu) =
+               logical_smp_processor_id();
+#endif
+
        /*
         * Set Task Priority to 'accept all'. We never change this
         * later on.
@@ -1910,17 +1932,6 @@ void __cpuinit generic_processor_info(int apicid, int version)
 {
        int cpu;
 
-       /*
-        * Validate version
-        */
-       if (version == 0x0) {
-               pr_warning("BIOS bug, APIC version is 0 for CPU#%d! "
-                          "fixing up to 0x10. (tell your hw vendor)\n",
-                               version);
-               version = 0x10;
-       }
-       apic_version[apicid] = version;
-
        if (num_processors >= nr_cpu_ids) {
                int max = nr_cpu_ids;
                int thiscpu = max + disabled_cpus;
@@ -1934,22 +1945,34 @@ void __cpuinit generic_processor_info(int apicid, int version)
        }
 
        num_processors++;
-       cpu = cpumask_next_zero(-1, cpu_present_mask);
-
-       if (version != apic_version[boot_cpu_physical_apicid])
-               WARN_ONCE(1,
-                       "ACPI: apic version mismatch, bootcpu: %x cpu %d: %x\n",
-                       apic_version[boot_cpu_physical_apicid], cpu, version);
-
-       physid_set(apicid, phys_cpu_present_map);
        if (apicid == boot_cpu_physical_apicid) {
                /*
                 * x86_bios_cpu_apicid is required to have processors listed
                 * in same order as logical cpu numbers. Hence the first
                 * entry is BSP, and so on.
+                * boot_cpu_init() already hold bit 0 in cpu_present_mask
+                * for BSP.
                 */
                cpu = 0;
+       } else
+               cpu = cpumask_next_zero(-1, cpu_present_mask);
+
+       /*
+        * Validate version
+        */
+       if (version == 0x0) {
+               pr_warning("BIOS bug: APIC version is 0 for CPU %d/0x%x, fixing up to 0x10\n",
+                          cpu, apicid);
+               version = 0x10;
        }
+       apic_version[apicid] = version;
+
+       if (version != apic_version[boot_cpu_physical_apicid]) {
+               pr_warning("BIOS bug: APIC version mismatch, boot CPU: %x, CPU %d: version %x\n",
+                       apic_version[boot_cpu_physical_apicid], cpu, version);
+       }
+
+       physid_set(apicid, phys_cpu_present_map);
        if (apicid > max_physical_apicid)
                max_physical_apicid = apicid;
 
@@ -1957,7 +1980,10 @@ void __cpuinit generic_processor_info(int apicid, int version)
        early_per_cpu(x86_cpu_to_apicid, cpu) = apicid;
        early_per_cpu(x86_bios_cpu_apicid, cpu) = apicid;
 #endif
-
+#ifdef CONFIG_X86_32
+       early_per_cpu(x86_cpu_to_logical_apicid, cpu) =
+               apic->x86_32_early_logical_apicid(cpu);
+#endif
        set_cpu_possible(cpu, true);
        set_cpu_present(cpu, true);
 }
@@ -1978,10 +2004,14 @@ void default_init_apic_ldr(void)
 }
 
 #ifdef CONFIG_X86_32
-int default_apicid_to_node(int logical_apicid)
+int default_x86_32_numa_cpu_node(int cpu)
 {
-#ifdef CONFIG_SMP
-       return apicid_2_node[hard_smp_processor_id()];
+#ifdef CONFIG_NUMA
+       int apicid = early_per_cpu(x86_cpu_to_apicid, cpu);
+
+       if (apicid != BAD_APICID)
+               return __apicid_to_node[apicid];
+       return NUMA_NO_NODE;
 #else
        return 0;
 #endif