Merge branch 'linus' into cpus4096
[pandora-kernel.git] / arch / x86 / kernel / mpparse.c
index b4a950d..3b25e49 100644 (file)
@@ -49,15 +49,73 @@ static int __init mpf_checksum(unsigned char *mp, int len)
 }
 
 #ifdef CONFIG_X86_NUMAQ
+int found_numaq;
 /*
  * Have to match translation table entries to main table entries by counter
  * hence the mpc_record variable .... can't see a less disgusting way of
  * doing this ....
  */
+struct mpc_config_translation {
+       unsigned char mpc_type;
+       unsigned char trans_len;
+       unsigned char trans_type;
+       unsigned char trans_quad;
+       unsigned char trans_global;
+       unsigned char trans_local;
+       unsigned short trans_reserved;
+};
+
 
 static int mpc_record;
 static struct mpc_config_translation *translation_table[MAX_MPC_ENTRY]
     __cpuinitdata;
+
+static inline int generate_logical_apicid(int quad, int phys_apicid)
+{
+       return (quad << 4) + (phys_apicid ? phys_apicid << 1 : 1);
+}
+
+
+static inline int mpc_apic_id(struct mpc_config_processor *m,
+                       struct mpc_config_translation *translation_record)
+{
+       int quad = translation_record->trans_quad;
+       int logical_apicid = generate_logical_apicid(quad, m->mpc_apicid);
+
+       printk(KERN_DEBUG "Processor #%d %u:%u APIC version %d (quad %d, apic %d)\n",
+              m->mpc_apicid,
+              (m->mpc_cpufeature & CPU_FAMILY_MASK) >> 8,
+              (m->mpc_cpufeature & CPU_MODEL_MASK) >> 4,
+              m->mpc_apicver, quad, logical_apicid);
+       return logical_apicid;
+}
+
+int mp_bus_id_to_node[MAX_MP_BUSSES];
+
+int mp_bus_id_to_local[MAX_MP_BUSSES];
+
+static void mpc_oem_bus_info(struct mpc_config_bus *m, char *name,
+       struct mpc_config_translation *translation)
+{
+       int quad = translation->trans_quad;
+       int local = translation->trans_local;
+
+       mp_bus_id_to_node[m->mpc_busid] = quad;
+       mp_bus_id_to_local[m->mpc_busid] = local;
+       printk(KERN_INFO "Bus #%d is %s (node %d)\n",
+              m->mpc_busid, name, quad);
+}
+
+int quad_local_to_mp_bus_id [NR_CPUS/4][4];
+static void mpc_oem_pci_bus(struct mpc_config_bus *m,
+       struct mpc_config_translation *translation)
+{
+       int quad = translation->trans_quad;
+       int local = translation->trans_local;
+
+       quad_local_to_mp_bus_id[quad][local] = m->mpc_busid;
+}
+
 #endif
 
 static void __cpuinit MP_processor_info(struct mpc_config_processor *m)
@@ -186,7 +244,7 @@ static void __init print_mp_irq_info(struct mp_config_intsrc *mp_irq)
                mp_irq->mp_srcbusirq, mp_irq->mp_dstapic, mp_irq->mp_dstirq);
 }
 
-static void assign_to_mp_irq(struct mpc_config_intsrc *m,
+static void __init assign_to_mp_irq(struct mpc_config_intsrc *m,
                                    struct mp_config_intsrc *mp_irq)
 {
        mp_irq->mp_dstapic = m->mpc_dstapic;
@@ -210,7 +268,7 @@ static void __init assign_to_mpc_intsrc(struct mp_config_intsrc *mp_irq,
        m->mpc_dstirq = mp_irq->mp_dstirq;
 }
 
-static int mp_irq_mpc_intsrc_cmp(struct mp_config_intsrc *mp_irq,
+static int __init mp_irq_mpc_intsrc_cmp(struct mp_config_intsrc *mp_irq,
                                        struct mpc_config_intsrc *m)
 {
        if (mp_irq->mp_dstapic != m->mpc_dstapic)
@@ -231,7 +289,7 @@ static int mp_irq_mpc_intsrc_cmp(struct mp_config_intsrc *mp_irq,
        return 0;
 }
 
-void MP_intsrc_info(struct mpc_config_intsrc *m)
+static void __init MP_intsrc_info(struct mpc_config_intsrc *m)
 {
        int i;
 
@@ -321,11 +379,11 @@ static void __init smp_read_mpc_oem(struct mp_config_oemtable *oemtable,
        }
 }
 
-static inline void mps_oem_check(struct mp_config_table *mpc, char *oem,
+void numaq_mps_oem_check(struct mp_config_table *mpc, char *oem,
                                 char *productid)
 {
        if (strncmp(oem, "IBM NUMA", 8))
-               printk("Warning!  May not be a NUMA-Q system!\n");
+               printk("Warning!  Not a NUMA-Q system!\n");
        else
                found_numaq = 1;
 
@@ -388,7 +446,16 @@ static int __init smp_read_mpc(struct mp_config_table *mpc, unsigned early)
                return 0;
 
 #ifdef CONFIG_X86_32
-       mps_oem_check(mpc, oem, str);
+       /*
+        * need to make sure summit and es7000's mps_oem_check is safe to be
+        * called early via genericarch 's mps_oem_check
+        */
+       if (early) {
+#ifdef CONFIG_X86_NUMAQ
+               numaq_mps_oem_check(mpc, oem, str);
+#endif
+       } else
+               mps_oem_check(mpc, oem, str);
 #endif
 
        /* save the local APIC address, it might be non-default */
@@ -473,6 +540,11 @@ static int __init smp_read_mpc(struct mp_config_table *mpc, unsigned early)
                ++mpc_record;
 #endif
        }
+
+#ifdef CONFIG_X86_GENERICARCH
+       generic_bigsmp_probe();
+#endif
+
        setup_apic_routing();
        if (!num_processors)
                printk(KERN_ERR "MPTABLE: no processors registered!\n");
@@ -653,13 +725,23 @@ static inline void __init construct_default_ISA_mptable(int mpc_default_type)
 
 static struct intel_mp_floating *mpf_found;
 
+/*
+ * Machine specific quirk for finding the SMP config before other setup
+ * activities destroy the table:
+ */
+int (*mach_get_smp_config_quirk)(unsigned int early);
+
 /*
  * Scan the memory blocks for an SMP configuration block.
  */
-static void __init __get_smp_config(unsigned early)
+static void __init __get_smp_config(unsigned int early)
 {
        struct intel_mp_floating *mpf = mpf_found;
 
+       if (mach_get_smp_config_quirk) {
+               if (mach_get_smp_config_quirk(early))
+                       return;
+       }
        if (acpi_lapic && early)
                return;
        /*
@@ -781,12 +863,17 @@ static int __init smp_scan_config(unsigned long base, unsigned long length,
                        smp_found_config = 1;
 #endif
                        mpf_found = mpf;
-#ifdef CONFIG_X86_32
+
                        printk(KERN_INFO "found SMP MP-table at [%p] %08lx\n",
                               mpf, virt_to_phys(mpf));
-                       reserve_bootmem(virt_to_phys(mpf), PAGE_SIZE,
+
+                       if (!reserve)
+                               return 1;
+                       reserve_bootmem_generic(virt_to_phys(mpf), PAGE_SIZE,
                                        BOOTMEM_DEFAULT);
                        if (mpf->mpf_physptr) {
+                               unsigned long size = PAGE_SIZE;
+#ifdef CONFIG_X86_32
                                /*
                                 * We cannot access to MPC table to compute
                                 * table size yet, as only few megabytes from
@@ -796,24 +883,15 @@ static int __init smp_scan_config(unsigned long base, unsigned long length,
                                 * PAGE_SIZE from mpg->mpf_physptr yields BUG()
                                 * in reserve_bootmem.
                                 */
-                               unsigned long size = PAGE_SIZE;
                                unsigned long end = max_low_pfn * PAGE_SIZE;
                                if (mpf->mpf_physptr + size > end)
                                        size = end - mpf->mpf_physptr;
-                               reserve_bootmem(mpf->mpf_physptr, size,
+#endif
+                               reserve_bootmem_generic(mpf->mpf_physptr, size,
                                                BOOTMEM_DEFAULT);
                        }
 
-#else
-                       if (!reserve)
-                               return 1;
-
-                       reserve_bootmem_generic(virt_to_phys(mpf), PAGE_SIZE);
-                       if (mpf->mpf_physptr)
-                               reserve_bootmem_generic(mpf->mpf_physptr,
-                                                       PAGE_SIZE);
-#endif
-               return 1;
+                       return 1;
                }
                bp += 4;
                length -= 16;
@@ -821,10 +899,16 @@ static int __init smp_scan_config(unsigned long base, unsigned long length,
        return 0;
 }
 
-static void __init __find_smp_config(unsigned reserve)
+int (*mach_find_smp_config_quirk)(unsigned int reserve);
+
+static void __init __find_smp_config(unsigned int reserve)
 {
        unsigned int address;
 
+       if (mach_find_smp_config_quirk) {
+               if (mach_find_smp_config_quirk(reserve))
+                       return;
+       }
        /*
         * FIXME: Linux assumes you have 640K of base ram..
         * this continues the error...
@@ -1042,7 +1126,7 @@ out:
        return 0;
 }
 
-int __initdata enable_update_mptable;
+static int __initdata enable_update_mptable;
 
 static int __init update_mptable_setup(char *str)
 {