]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
x86: Add apic->x86_32_early_logical_apicid()
authorTejun Heo <tj@kernel.org>
Sun, 23 Jan 2011 13:37:33 +0000 (14:37 +0100)
committerIngo Molnar <mingo@elte.hu>
Fri, 28 Jan 2011 13:54:06 +0000 (14:54 +0100)
On x86_32, the mapping between cpu and logical apic ID differs
depending on the specific apic implementation in use.  The
mapping is initialized while bringing up CPUs; however, this
makes early inits ignore memory topology.

Add a x86_32 specific apic->x86_32_early_logical_apicid() which
is called early during boot to query the mapping.  The mapping
is later verified against the result of init_apic_ldr().  The
method is allowed to return BAD_APICID if it can't be determined
early.

noop variant which always returns BAD_APICID is implemented and
added to all x86_32 apic implementations.

Signed-off-by: Tejun Heo <tj@kernel.org>
Cc: eric.dumazet@gmail.com
Cc: yinghai@kernel.org
Cc: brgerst@gmail.com
Cc: gorcunov@gmail.com
Cc: penberg@kernel.org
Cc: shaohui.zheng@intel.com
Cc: rientjes@google.com
LKML-Reference: <1295789862-25482-8-git-send-email-tj@kernel.org>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
arch/x86/include/asm/apic.h
arch/x86/kernel/apic/apic.c
arch/x86/kernel/apic/apic_noop.c
arch/x86/kernel/apic/bigsmp_32.c
arch/x86/kernel/apic/es7000_32.c
arch/x86/kernel/apic/numaq_32.c
arch/x86/kernel/apic/probe_32.c
arch/x86/kernel/apic/summit_32.c

index d1aa0c3e7a5caca54dcc0e9e6bfc347a458bfe55..efb073b5c7436add18ead4c56550dc80a03df07d 100644 (file)
@@ -354,6 +354,20 @@ struct apic {
        void (*icr_write)(u32 low, u32 high);
        void (*wait_icr_idle)(void);
        u32 (*safe_wait_icr_idle)(void);
+
+#ifdef CONFIG_X86_32
+       /*
+        * Called very early during boot from get_smp_config().  It should
+        * return the logical apicid.  x86_[bios]_cpu_to_apicid is
+        * initialized before this function is called.
+        *
+        * If logical apicid can't be determined that early, the function
+        * may return BAD_APICID.  Logical apicid will be configured after
+        * init_apic_ldr() while bringing up CPUs.  Note that NUMA affinity
+        * won't be applied properly during early boot in this case.
+        */
+       int (*x86_32_early_logical_apicid)(int cpu);
+#endif
 };
 
 /*
@@ -501,6 +515,11 @@ extern struct apic apic_noop;
 
 extern struct apic apic_default;
 
+static inline int noop_x86_32_early_logical_apicid(int cpu)
+{
+       return BAD_APICID;
+}
+
 /*
  * Set up the logical destination ID.
  *
index ae08246f320c426c3f6aeea147c7168cf0b1143d..3127079628e86f54f74426b68e0a6b7dd2bc8ef5 100644 (file)
@@ -1250,8 +1250,13 @@ void __cpuinit setup_local_APIC(void)
 
 #ifdef CONFIG_X86_32
        /*
-        * APIC LDR is initialized.  Fetch and store logical_apic_id.
+        * 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
@@ -1991,7 +1996,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);
 }
index f3d19b2426ab1c9f71ab599701bf2d2f9f4bfb30..0309c58d96bc91b152de84fe2f7d429def38333c 100644 (file)
@@ -191,4 +191,8 @@ struct apic apic_noop = {
        .icr_write                      = noop_apic_icr_write,
        .wait_icr_idle                  = noop_apic_wait_icr_idle,
        .safe_wait_icr_idle             = noop_safe_apic_wait_icr_idle,
+
+#ifdef CONFIG_X86_32
+       .x86_32_early_logical_apicid    = noop_x86_32_early_logical_apicid,
+#endif
 };
index 4c62592d6869fa7c6e81f9c379f03e2a1521a299..dd32a9b78a87f8cbb730a84407278344ca7ad69a 100644 (file)
@@ -251,4 +251,6 @@ struct apic apic_bigsmp = {
        .icr_write                      = native_apic_icr_write,
        .wait_icr_idle                  = native_apic_wait_icr_idle,
        .safe_wait_icr_idle             = native_safe_apic_wait_icr_idle,
+
+       .x86_32_early_logical_apicid    = noop_x86_32_early_logical_apicid,
 };
index 6840681a3f147d2a9f1034a9706024009b793ca5..0ffc1eca577729c746b9bdadd25e5721a81ae2c9 100644 (file)
@@ -682,6 +682,8 @@ struct apic __refdata apic_es7000_cluster = {
        .icr_write                      = native_apic_icr_write,
        .wait_icr_idle                  = native_apic_wait_icr_idle,
        .safe_wait_icr_idle             = native_safe_apic_wait_icr_idle,
+
+       .x86_32_early_logical_apicid    = noop_x86_32_early_logical_apicid,
 };
 
 struct apic __refdata apic_es7000 = {
@@ -744,4 +746,6 @@ struct apic __refdata apic_es7000 = {
        .icr_write                      = native_apic_icr_write,
        .wait_icr_idle                  = native_apic_wait_icr_idle,
        .safe_wait_icr_idle             = native_safe_apic_wait_icr_idle,
+
+       .x86_32_early_logical_apicid    = noop_x86_32_early_logical_apicid,
 };
index 2b434d579e158e3b39155ff41cb9262607dc81cc..f1a8b120c49d9511714949c26e87c66abff74da5 100644 (file)
@@ -539,4 +539,6 @@ struct apic __refdata apic_numaq = {
        .icr_write                      = native_apic_icr_write,
        .wait_icr_idle                  = native_apic_wait_icr_idle,
        .safe_wait_icr_idle             = native_safe_apic_wait_icr_idle,
+
+       .x86_32_early_logical_apicid    = noop_x86_32_early_logical_apicid,
 };
index 24a68281101b3d96089ee8cbb4a4f8c0c5dddef6..40be7c3cdfeb6f24f7ae57d0aefdaa209d13711b 100644 (file)
@@ -166,6 +166,8 @@ struct apic apic_default = {
        .icr_write                      = native_apic_icr_write,
        .wait_icr_idle                  = native_apic_wait_icr_idle,
        .safe_wait_icr_idle             = native_safe_apic_wait_icr_idle,
+
+       .x86_32_early_logical_apicid    = noop_x86_32_early_logical_apicid,
 };
 
 extern struct apic apic_numaq;
index 1ef4c14f4d6b942d3b2e8901b5ea2ced83c53723..172c498e888f65ff7f9b76e9636f314475e49bcb 100644 (file)
@@ -552,4 +552,6 @@ struct apic apic_summit = {
        .icr_write                      = native_apic_icr_write,
        .wait_icr_idle                  = native_apic_wait_icr_idle,
        .safe_wait_icr_idle             = native_safe_apic_wait_icr_idle,
+
+       .x86_32_early_logical_apicid    = noop_x86_32_early_logical_apicid,
 };