x86, apic: move remaining APIC drivers to arch/x86/kernel/apic/*
authorIngo Molnar <mingo@elte.hu>
Tue, 17 Feb 2009 19:35:16 +0000 (20:35 +0100)
committerIngo Molnar <mingo@elte.hu>
Tue, 17 Feb 2009 19:35:47 +0000 (20:35 +0100)
Move the 32-bit extended-arch APIC drivers to arch/x86/kernel/apic/
too, and rename apic_64.c to probe_64.c.

Signed-off-by: Ingo Molnar <mingo@elte.hu>
14 files changed:
arch/x86/kernel/Makefile
arch/x86/kernel/apic/Makefile
arch/x86/kernel/apic/apic_64.c [deleted file]
arch/x86/kernel/apic/bigsmp_32.c [new file with mode: 0644]
arch/x86/kernel/apic/es7000_32.c [new file with mode: 0644]
arch/x86/kernel/apic/numaq_32.c [new file with mode: 0644]
arch/x86/kernel/apic/probe_32.c [new file with mode: 0644]
arch/x86/kernel/apic/probe_64.c [new file with mode: 0644]
arch/x86/kernel/apic/summit_32.c [new file with mode: 0644]
arch/x86/kernel/bigsmp_32.c [deleted file]
arch/x86/kernel/es7000_32.c [deleted file]
arch/x86/kernel/numaq_32.c [deleted file]
arch/x86/kernel/probe_32.c [deleted file]
arch/x86/kernel/summit_32.c [deleted file]

index 9139ff69471c5a10ad232c65c93dcecd1a524711..c70537d8c1561d4176ca37b046749a4e50f0315a 100644 (file)
@@ -30,7 +30,7 @@ obj-y                 += traps.o irq.o irq_$(BITS).o dumpstack_$(BITS).o
 obj-y                  += time_$(BITS).o ioport.o ldt.o dumpstack.o
 obj-y                  += setup.o i8259.o irqinit_$(BITS).o
 obj-$(CONFIG_X86_VISWS)        += visws_quirks.o
-obj-$(CONFIG_X86_32)   += probe_32.o probe_roms_32.o
+obj-$(CONFIG_X86_32)   += probe_roms_32.o
 obj-$(CONFIG_X86_32)   += sys_i386_32.o i386_ksyms_32.o
 obj-$(CONFIG_X86_64)   += sys_x86_64.o x8664_ksyms_64.o
 obj-$(CONFIG_X86_64)   += syscall_64.o vsyscall_64.o
@@ -70,10 +70,6 @@ obj-$(CONFIG_FUNCTION_GRAPH_TRACER)  += ftrace.o
 obj-$(CONFIG_KEXEC)            += machine_kexec_$(BITS).o
 obj-$(CONFIG_KEXEC)            += relocate_kernel_$(BITS).o crash.o
 obj-$(CONFIG_CRASH_DUMP)       += crash_dump_$(BITS).o
-obj-$(CONFIG_X86_BIGSMP)       += bigsmp_32.o
-obj-$(CONFIG_X86_NUMAQ)                += numaq_32.o
-obj-$(CONFIG_X86_ES7000)       += es7000_32.o
-obj-$(CONFIG_X86_SUMMIT)       += summit_32.o
 obj-y                          += vsmp_64.o
 obj-$(CONFIG_KPROBES)          += kprobes.o
 obj-$(CONFIG_MODULES)          += module_$(BITS).o
index da20b70c400071cb36e8bb89b4d143d5ea58d4fd..97f558db5c31825d45b909d000df35a5b7d01b01 100644 (file)
@@ -2,14 +2,19 @@
 # Makefile for local APIC drivers and for the IO-APIC code
 #
 
-obj-y                          := apic.o ipi.o nmi.o
+obj-y                          := apic.o probe_$(BITS).o ipi.o nmi.o
 obj-$(CONFIG_X86_IO_APIC)      += io_apic.o
 obj-$(CONFIG_SMP)              += ipi.o
+obj-$
 
 ifeq ($(CONFIG_X86_64),y)
-obj-y                          += apic_64.o apic_flat_64.o
+obj-y                          += apic_flat_64.o
 obj-$(CONFIG_X86_X2APIC)       += x2apic_cluster.o
 obj-$(CONFIG_X86_X2APIC)       += x2apic_phys.o
 obj-$(CONFIG_X86_UV)           += x2apic_uv_x.o
 endif
 
+obj-$(CONFIG_X86_BIGSMP)       += bigsmp_32.o
+obj-$(CONFIG_X86_NUMAQ)                += numaq_32.o
+obj-$(CONFIG_X86_ES7000)       += es7000_32.o
+obj-$(CONFIG_X86_SUMMIT)       += summit_32.o
diff --git a/arch/x86/kernel/apic/apic_64.c b/arch/x86/kernel/apic/apic_64.c
deleted file mode 100644 (file)
index 70935dd..0000000
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * Copyright 2004 James Cleverdon, IBM.
- * Subject to the GNU Public License, v.2
- *
- * Generic APIC sub-arch probe layer.
- *
- * Hacked for x86-64 by James Cleverdon from i386 architecture code by
- * Martin Bligh, Andi Kleen, James Bottomley, John Stultz, and
- * James Cleverdon.
- */
-#include <linux/threads.h>
-#include <linux/cpumask.h>
-#include <linux/string.h>
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/ctype.h>
-#include <linux/init.h>
-#include <linux/hardirq.h>
-#include <linux/dmar.h>
-
-#include <asm/smp.h>
-#include <asm/apic.h>
-#include <asm/ipi.h>
-#include <asm/setup.h>
-
-extern struct apic apic_flat;
-extern struct apic apic_physflat;
-extern struct apic apic_x2xpic_uv_x;
-extern struct apic apic_x2apic_phys;
-extern struct apic apic_x2apic_cluster;
-
-struct apic __read_mostly *apic = &apic_flat;
-EXPORT_SYMBOL_GPL(apic);
-
-static struct apic *apic_probe[] __initdata = {
-#ifdef CONFIG_X86_UV
-       &apic_x2apic_uv_x,
-#endif
-#ifdef CONFIG_X86_X2APIC
-       &apic_x2apic_phys,
-       &apic_x2apic_cluster,
-#endif
-       &apic_physflat,
-       NULL,
-};
-
-/*
- * Check the APIC IDs in bios_cpu_apicid and choose the APIC mode.
- */
-void __init default_setup_apic_routing(void)
-{
-#ifdef CONFIG_X86_X2APIC
-       if (apic == &apic_x2apic_phys || apic == &apic_x2apic_cluster) {
-               if (!intr_remapping_enabled)
-                       apic = &apic_flat;
-       }
-#endif
-
-       if (apic == &apic_flat) {
-               if (max_physical_apicid >= 8)
-                       apic = &apic_physflat;
-               printk(KERN_INFO "Setting APIC routing to %s\n", apic->name);
-       }
-
-       if (x86_quirks->update_apic)
-               x86_quirks->update_apic();
-}
-
-/* Same for both flat and physical. */
-
-void apic_send_IPI_self(int vector)
-{
-       __default_send_IPI_shortcut(APIC_DEST_SELF, vector, APIC_DEST_PHYSICAL);
-}
-
-int __init default_acpi_madt_oem_check(char *oem_id, char *oem_table_id)
-{
-       int i;
-
-       for (i = 0; apic_probe[i]; ++i) {
-               if (apic_probe[i]->acpi_madt_oem_check(oem_id, oem_table_id)) {
-                       apic = apic_probe[i];
-                       printk(KERN_INFO "Setting APIC routing to %s.\n",
-                               apic->name);
-                       return 1;
-               }
-       }
-       return 0;
-}
diff --git a/arch/x86/kernel/apic/bigsmp_32.c b/arch/x86/kernel/apic/bigsmp_32.c
new file mode 100644 (file)
index 0000000..0b10933
--- /dev/null
@@ -0,0 +1,274 @@
+/*
+ * APIC driver for "bigsmp" xAPIC machines with more than 8 virtual CPUs.
+ *
+ * Drives the local APIC in "clustered mode".
+ */
+#include <linux/threads.h>
+#include <linux/cpumask.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/dmi.h>
+#include <linux/smp.h>
+
+#include <asm/apicdef.h>
+#include <asm/fixmap.h>
+#include <asm/mpspec.h>
+#include <asm/apic.h>
+#include <asm/ipi.h>
+
+static inline unsigned bigsmp_get_apic_id(unsigned long x)
+{
+       return (x >> 24) & 0xFF;
+}
+
+static inline int bigsmp_apic_id_registered(void)
+{
+       return 1;
+}
+
+static inline const cpumask_t *bigsmp_target_cpus(void)
+{
+#ifdef CONFIG_SMP
+       return &cpu_online_map;
+#else
+       return &cpumask_of_cpu(0);
+#endif
+}
+
+static inline unsigned long
+bigsmp_check_apicid_used(physid_mask_t bitmap, int apicid)
+{
+       return 0;
+}
+
+static inline unsigned long bigsmp_check_apicid_present(int bit)
+{
+       return 1;
+}
+
+static inline unsigned long calculate_ldr(int cpu)
+{
+       unsigned long val, id;
+
+       val = apic_read(APIC_LDR) & ~APIC_LDR_MASK;
+       id = per_cpu(x86_bios_cpu_apicid, cpu);
+       val |= SET_APIC_LOGICAL_ID(id);
+
+       return val;
+}
+
+/*
+ * Set up the logical destination ID.
+ *
+ * Intel recommends to set DFR, LDR and TPR before enabling
+ * an APIC.  See e.g. "AP-388 82489DX User's Manual" (Intel
+ * document number 292116).  So here it goes...
+ */
+static inline void bigsmp_init_apic_ldr(void)
+{
+       unsigned long val;
+       int cpu = smp_processor_id();
+
+       apic_write(APIC_DFR, APIC_DFR_FLAT);
+       val = calculate_ldr(cpu);
+       apic_write(APIC_LDR, val);
+}
+
+static inline void bigsmp_setup_apic_routing(void)
+{
+       printk(KERN_INFO
+               "Enabling APIC mode:  Physflat.  Using %d I/O APICs\n",
+               nr_ioapics);
+}
+
+static inline int bigsmp_apicid_to_node(int logical_apicid)
+{
+       return apicid_2_node[hard_smp_processor_id()];
+}
+
+static inline int bigsmp_cpu_present_to_apicid(int mps_cpu)
+{
+       if (mps_cpu < nr_cpu_ids)
+               return (int) per_cpu(x86_bios_cpu_apicid, mps_cpu);
+
+       return BAD_APICID;
+}
+
+static inline physid_mask_t bigsmp_apicid_to_cpu_present(int phys_apicid)
+{
+       return physid_mask_of_physid(phys_apicid);
+}
+
+/* Mapping from cpu number to logical apicid */
+static inline int bigsmp_cpu_to_logical_apicid(int cpu)
+{
+       if (cpu >= nr_cpu_ids)
+               return BAD_APICID;
+       return cpu_physical_id(cpu);
+}
+
+static inline physid_mask_t bigsmp_ioapic_phys_id_map(physid_mask_t phys_map)
+{
+       /* For clustered we don't have a good way to do this yet - hack */
+       return physids_promote(0xFFL);
+}
+
+static inline void bigsmp_setup_portio_remap(void)
+{
+}
+
+static inline int bigsmp_check_phys_apicid_present(int boot_cpu_physical_apicid)
+{
+       return 1;
+}
+
+/* As we are using single CPU as destination, pick only one CPU here */
+static inline unsigned int bigsmp_cpu_mask_to_apicid(const cpumask_t *cpumask)
+{
+       return bigsmp_cpu_to_logical_apicid(first_cpu(*cpumask));
+}
+
+static inline unsigned int
+bigsmp_cpu_mask_to_apicid_and(const struct cpumask *cpumask,
+                             const struct cpumask *andmask)
+{
+       int cpu;
+
+       /*
+        * We're using fixed IRQ delivery, can only return one phys APIC ID.
+        * May as well be the first.
+        */
+       for_each_cpu_and(cpu, cpumask, andmask) {
+               if (cpumask_test_cpu(cpu, cpu_online_mask))
+                       break;
+       }
+       if (cpu < nr_cpu_ids)
+               return bigsmp_cpu_to_logical_apicid(cpu);
+
+       return BAD_APICID;
+}
+
+static inline int bigsmp_phys_pkg_id(int cpuid_apic, int index_msb)
+{
+       return cpuid_apic >> index_msb;
+}
+
+static inline void bigsmp_send_IPI_mask(const struct cpumask *mask, int vector)
+{
+       default_send_IPI_mask_sequence_phys(mask, vector);
+}
+
+static inline void bigsmp_send_IPI_allbutself(int vector)
+{
+       default_send_IPI_mask_allbutself_phys(cpu_online_mask, vector);
+}
+
+static inline void bigsmp_send_IPI_all(int vector)
+{
+       bigsmp_send_IPI_mask(cpu_online_mask, vector);
+}
+
+static int dmi_bigsmp; /* can be set by dmi scanners */
+
+static int hp_ht_bigsmp(const struct dmi_system_id *d)
+{
+       printk(KERN_NOTICE "%s detected: force use of apic=bigsmp\n", d->ident);
+       dmi_bigsmp = 1;
+
+       return 0;
+}
+
+
+static const struct dmi_system_id bigsmp_dmi_table[] = {
+       { hp_ht_bigsmp, "HP ProLiant DL760 G2",
+               {       DMI_MATCH(DMI_BIOS_VENDOR, "HP"),
+                       DMI_MATCH(DMI_BIOS_VERSION, "P44-"),
+               }
+       },
+
+       { hp_ht_bigsmp, "HP ProLiant DL740",
+               {       DMI_MATCH(DMI_BIOS_VENDOR, "HP"),
+                       DMI_MATCH(DMI_BIOS_VERSION, "P47-"),
+               }
+       },
+       { } /* NULL entry stops DMI scanning */
+};
+
+static void bigsmp_vector_allocation_domain(int cpu, cpumask_t *retmask)
+{
+       cpus_clear(*retmask);
+       cpu_set(cpu, *retmask);
+}
+
+static int probe_bigsmp(void)
+{
+       if (def_to_bigsmp)
+               dmi_bigsmp = 1;
+       else
+               dmi_check_system(bigsmp_dmi_table);
+
+       return dmi_bigsmp;
+}
+
+struct apic apic_bigsmp = {
+
+       .name                           = "bigsmp",
+       .probe                          = probe_bigsmp,
+       .acpi_madt_oem_check            = NULL,
+       .apic_id_registered             = bigsmp_apic_id_registered,
+
+       .irq_delivery_mode              = dest_Fixed,
+       /* phys delivery to target CPU: */
+       .irq_dest_mode                  = 0,
+
+       .target_cpus                    = bigsmp_target_cpus,
+       .disable_esr                    = 1,
+       .dest_logical                   = 0,
+       .check_apicid_used              = bigsmp_check_apicid_used,
+       .check_apicid_present           = bigsmp_check_apicid_present,
+
+       .vector_allocation_domain       = bigsmp_vector_allocation_domain,
+       .init_apic_ldr                  = bigsmp_init_apic_ldr,
+
+       .ioapic_phys_id_map             = bigsmp_ioapic_phys_id_map,
+       .setup_apic_routing             = bigsmp_setup_apic_routing,
+       .multi_timer_check              = NULL,
+       .apicid_to_node                 = bigsmp_apicid_to_node,
+       .cpu_to_logical_apicid          = bigsmp_cpu_to_logical_apicid,
+       .cpu_present_to_apicid          = bigsmp_cpu_present_to_apicid,
+       .apicid_to_cpu_present          = bigsmp_apicid_to_cpu_present,
+       .setup_portio_remap             = NULL,
+       .check_phys_apicid_present      = bigsmp_check_phys_apicid_present,
+       .enable_apic_mode               = NULL,
+       .phys_pkg_id                    = bigsmp_phys_pkg_id,
+       .mps_oem_check                  = NULL,
+
+       .get_apic_id                    = bigsmp_get_apic_id,
+       .set_apic_id                    = NULL,
+       .apic_id_mask                   = 0xFF << 24,
+
+       .cpu_mask_to_apicid             = bigsmp_cpu_mask_to_apicid,
+       .cpu_mask_to_apicid_and         = bigsmp_cpu_mask_to_apicid_and,
+
+       .send_IPI_mask                  = bigsmp_send_IPI_mask,
+       .send_IPI_mask_allbutself       = NULL,
+       .send_IPI_allbutself            = bigsmp_send_IPI_allbutself,
+       .send_IPI_all                   = bigsmp_send_IPI_all,
+       .send_IPI_self                  = default_send_IPI_self,
+
+       .wakeup_cpu                     = NULL,
+       .trampoline_phys_low            = DEFAULT_TRAMPOLINE_PHYS_LOW,
+       .trampoline_phys_high           = DEFAULT_TRAMPOLINE_PHYS_HIGH,
+
+       .wait_for_init_deassert         = default_wait_for_init_deassert,
+
+       .smp_callin_clear_local_apic    = NULL,
+       .inquire_remote_apic            = default_inquire_remote_apic,
+
+       .read                           = native_apic_mem_read,
+       .write                          = native_apic_mem_write,
+       .icr_read                       = native_apic_icr_read,
+       .icr_write                      = native_apic_icr_write,
+       .wait_icr_idle                  = native_apic_wait_icr_idle,
+       .safe_wait_icr_idle             = native_safe_apic_wait_icr_idle,
+};
diff --git a/arch/x86/kernel/apic/es7000_32.c b/arch/x86/kernel/apic/es7000_32.c
new file mode 100644 (file)
index 0000000..320f2d2
--- /dev/null
@@ -0,0 +1,757 @@
+/*
+ * Written by: Garry Forsgren, Unisys Corporation
+ *             Natalie Protasevich, Unisys Corporation
+ *
+ * This file contains the code to configure and interface
+ * with Unisys ES7000 series hardware system manager.
+ *
+ * Copyright (c) 2003 Unisys Corporation.
+ * Copyright (C) 2009, Red Hat, Inc., Ingo Molnar
+ *
+ *   All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it would be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write the Free Software Foundation, Inc., 59
+ * Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * Contact information: Unisys Corporation, Township Line & Union Meeting
+ * Roads-A, Unisys Way, Blue Bell, Pennsylvania, 19424, or:
+ *
+ * http://www.unisys.com
+ */
+#include <linux/notifier.h>
+#include <linux/spinlock.h>
+#include <linux/cpumask.h>
+#include <linux/threads.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/reboot.h>
+#include <linux/string.h>
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/acpi.h>
+#include <linux/init.h>
+#include <linux/nmi.h>
+#include <linux/smp.h>
+#include <linux/io.h>
+
+#include <asm/apicdef.h>
+#include <asm/atomic.h>
+#include <asm/fixmap.h>
+#include <asm/mpspec.h>
+#include <asm/setup.h>
+#include <asm/apic.h>
+#include <asm/ipi.h>
+
+/*
+ * ES7000 chipsets
+ */
+
+#define NON_UNISYS                     0
+#define ES7000_CLASSIC                 1
+#define ES7000_ZORRO                   2
+
+#define        MIP_REG                         1
+#define        MIP_PSAI_REG                    4
+
+#define        MIP_BUSY                        1
+#define        MIP_SPIN                        0xf0000
+#define        MIP_VALID                       0x0100000000000000ULL
+#define        MIP_SW_APIC                     0x1020b
+
+#define        MIP_PORT(val)                   ((val >> 32) & 0xffff)
+
+#define        MIP_RD_LO(val)                  (val & 0xffffffff)
+
+struct mip_reg {
+       unsigned long long              off_0x00;
+       unsigned long long              off_0x08;
+       unsigned long long              off_0x10;
+       unsigned long long              off_0x18;
+       unsigned long long              off_0x20;
+       unsigned long long              off_0x28;
+       unsigned long long              off_0x30;
+       unsigned long long              off_0x38;
+};
+
+struct mip_reg_info {
+       unsigned long long              mip_info;
+       unsigned long long              delivery_info;
+       unsigned long long              host_reg;
+       unsigned long long              mip_reg;
+};
+
+struct psai {
+       unsigned long long              entry_type;
+       unsigned long long              addr;
+       unsigned long long              bep_addr;
+};
+
+#ifdef CONFIG_ACPI
+
+struct es7000_oem_table {
+       struct acpi_table_header        Header;
+       u32                             OEMTableAddr;
+       u32                             OEMTableSize;
+};
+
+static unsigned long                   oem_addrX;
+static unsigned long                   oem_size;
+
+#endif
+
+/*
+ * ES7000 Globals
+ */
+
+static volatile unsigned long          *psai;
+static struct mip_reg                  *mip_reg;
+static struct mip_reg                  *host_reg;
+static int                             mip_port;
+static unsigned long                   mip_addr;
+static unsigned long                   host_addr;
+
+int                                    es7000_plat;
+
+/*
+ * GSI override for ES7000 platforms.
+ */
+
+static unsigned int                    base;
+
+static int
+es7000_rename_gsi(int ioapic, int gsi)
+{
+       if (es7000_plat == ES7000_ZORRO)
+               return gsi;
+
+       if (!base) {
+               int i;
+               for (i = 0; i < nr_ioapics; i++)
+                       base += nr_ioapic_registers[i];
+       }
+
+       if (!ioapic && (gsi < 16))
+               gsi += base;
+
+       return gsi;
+}
+
+static int wakeup_secondary_cpu_via_mip(int cpu, unsigned long eip)
+{
+       unsigned long vect = 0, psaival = 0;
+
+       if (psai == NULL)
+               return -1;
+
+       vect = ((unsigned long)__pa(eip)/0x1000) << 16;
+       psaival = (0x1000000 | vect | cpu);
+
+       while (*psai & 0x1000000)
+               ;
+
+       *psai = psaival;
+
+       return 0;
+}
+
+static int __init es7000_update_apic(void)
+{
+       apic->wakeup_cpu = wakeup_secondary_cpu_via_mip;
+
+       /* MPENTIUMIII */
+       if (boot_cpu_data.x86 == 6 &&
+           (boot_cpu_data.x86_model >= 7 || boot_cpu_data.x86_model <= 11)) {
+               es7000_update_apic_to_cluster();
+               apic->wait_for_init_deassert = NULL;
+               apic->wakeup_cpu = wakeup_secondary_cpu_via_mip;
+       }
+
+       return 0;
+}
+
+static void __init setup_unisys(void)
+{
+       /*
+        * Determine the generation of the ES7000 currently running.
+        *
+        * es7000_plat = 1 if the machine is a 5xx ES7000 box
+        * es7000_plat = 2 if the machine is a x86_64 ES7000 box
+        *
+        */
+       if (!(boot_cpu_data.x86 <= 15 && boot_cpu_data.x86_model <= 2))
+               es7000_plat = ES7000_ZORRO;
+       else
+               es7000_plat = ES7000_CLASSIC;
+       ioapic_renumber_irq = es7000_rename_gsi;
+
+       x86_quirks->update_apic = es7000_update_apic;
+}
+
+/*
+ * Parse the OEM Table:
+ */
+static int __init parse_unisys_oem(char *oemptr)
+{
+       int                     i;
+       int                     success = 0;
+       unsigned char           type, size;
+       unsigned long           val;
+       char                    *tp = NULL;
+       struct psai             *psaip = NULL;
+       struct mip_reg_info     *mi;
+       struct mip_reg          *host, *mip;
+
+       tp = oemptr;
+
+       tp += 8;
+
+       for (i = 0; i <= 6; i++) {
+               type = *tp++;
+               size = *tp++;
+               tp -= 2;
+               switch (type) {
+               case MIP_REG:
+                       mi = (struct mip_reg_info *)tp;
+                       val = MIP_RD_LO(mi->host_reg);
+                       host_addr = val;
+                       host = (struct mip_reg *)val;
+                       host_reg = __va(host);
+                       val = MIP_RD_LO(mi->mip_reg);
+                       mip_port = MIP_PORT(mi->mip_info);
+                       mip_addr = val;
+                       mip = (struct mip_reg *)val;
+                       mip_reg = __va(mip);
+                       pr_debug("es7000_mipcfg: host_reg = 0x%lx \n",
+                                (unsigned long)host_reg);
+                       pr_debug("es7000_mipcfg: mip_reg = 0x%lx \n",
+                                (unsigned long)mip_reg);
+                       success++;
+                       break;
+               case MIP_PSAI_REG:
+                       psaip = (struct psai *)tp;
+                       if (tp != NULL) {
+                               if (psaip->addr)
+                                       psai = __va(psaip->addr);
+                               else
+                                       psai = NULL;
+                               success++;
+                       }
+                       break;
+               default:
+                       break;
+               }
+               tp += size;
+       }
+
+       if (success < 2)
+               es7000_plat = NON_UNISYS;
+       else
+               setup_unisys();
+
+       return es7000_plat;
+}
+
+#ifdef CONFIG_ACPI
+static int __init find_unisys_acpi_oem_table(unsigned long *oem_addr)
+{
+       struct acpi_table_header *header = NULL;
+       struct es7000_oem_table *table;
+       acpi_size tbl_size;
+       acpi_status ret;
+       int i = 0;
+
+       for (;;) {
+               ret = acpi_get_table_with_size("OEM1", i++, &header, &tbl_size);
+               if (!ACPI_SUCCESS(ret))
+                       return -1;
+
+               if (!memcmp((char *) &header->oem_id, "UNISYS", 6))
+                       break;
+
+               early_acpi_os_unmap_memory(header, tbl_size);
+       }
+
+       table = (void *)header;
+
+       oem_addrX       = table->OEMTableAddr;
+       oem_size        = table->OEMTableSize;
+
+       early_acpi_os_unmap_memory(header, tbl_size);
+
+       *oem_addr       = (unsigned long)__acpi_map_table(oem_addrX, oem_size);
+
+       return 0;
+}
+
+static void __init unmap_unisys_acpi_oem_table(unsigned long oem_addr)
+{
+       if (!oem_addr)
+               return;
+
+       __acpi_unmap_table((char *)oem_addr, oem_size);
+}
+
+static int es7000_check_dsdt(void)
+{
+       struct acpi_table_header header;
+
+       if (ACPI_SUCCESS(acpi_get_table_header(ACPI_SIG_DSDT, 0, &header)) &&
+           !strncmp(header.oem_id, "UNISYS", 6))
+               return 1;
+       return 0;
+}
+
+/* Hook from generic ACPI tables.c */
+static int __init es7000_acpi_madt_oem_check(char *oem_id, char *oem_table_id)
+{
+       unsigned long oem_addr = 0;
+       int check_dsdt;
+       int ret = 0;
+
+       /* check dsdt at first to avoid clear fix_map for oem_addr */
+       check_dsdt = es7000_check_dsdt();
+
+       if (!find_unisys_acpi_oem_table(&oem_addr)) {
+               if (check_dsdt) {
+                       ret = parse_unisys_oem((char *)oem_addr);
+               } else {
+                       setup_unisys();
+                       ret = 1;
+               }
+               /*
+                * we need to unmap it
+                */
+               unmap_unisys_acpi_oem_table(oem_addr);
+       }
+       return ret;
+}
+#else /* !CONFIG_ACPI: */
+static int __init es7000_acpi_madt_oem_check(char *oem_id, char *oem_table_id)
+{
+       return 0;
+}
+#endif /* !CONFIG_ACPI */
+
+static void es7000_spin(int n)
+{
+       int i = 0;
+
+       while (i++ < n)
+               rep_nop();
+}
+
+static int __init
+es7000_mip_write(struct mip_reg *mip_reg)
+{
+       int status = 0;
+       int spin;
+
+       spin = MIP_SPIN;
+       while ((host_reg->off_0x38 & MIP_VALID) != 0) {
+               if (--spin <= 0) {
+                       WARN(1, "Timeout waiting for Host Valid Flag\n");
+                       return -1;
+               }
+               es7000_spin(MIP_SPIN);
+       }
+
+       memcpy(host_reg, mip_reg, sizeof(struct mip_reg));
+       outb(1, mip_port);
+
+       spin = MIP_SPIN;
+
+       while ((mip_reg->off_0x38 & MIP_VALID) == 0) {
+               if (--spin <= 0) {
+                       WARN(1, "Timeout waiting for MIP Valid Flag\n");
+                       return -1;
+               }
+               es7000_spin(MIP_SPIN);
+       }
+
+       status = (mip_reg->off_0x00 & 0xffff0000000000ULL) >> 48;
+       mip_reg->off_0x38 &= ~MIP_VALID;
+
+       return status;
+}
+
+static void __init es7000_enable_apic_mode(void)
+{
+       struct mip_reg es7000_mip_reg;
+       int mip_status;
+
+       if (!es7000_plat)
+               return;
+
+       printk(KERN_INFO "ES7000: Enabling APIC mode.\n");
+       memset(&es7000_mip_reg, 0, sizeof(struct mip_reg));
+       es7000_mip_reg.off_0x00 = MIP_SW_APIC;
+       es7000_mip_reg.off_0x38 = MIP_VALID;
+
+       while ((mip_status = es7000_mip_write(&es7000_mip_reg)) != 0)
+               WARN(1, "Command failed, status = %x\n", mip_status);
+}
+
+static void es7000_vector_allocation_domain(int cpu, cpumask_t *retmask)
+{
+       /* Careful. Some cpus do not strictly honor the set of cpus
+        * specified in the interrupt destination when using lowest
+        * priority interrupt delivery mode.
+        *
+        * In particular there was a hyperthreading cpu observed to
+        * deliver interrupts to the wrong hyperthread when only one
+        * hyperthread was specified in the interrupt desitination.
+        */
+       *retmask = (cpumask_t){ { [0] = APIC_ALL_CPUS, } };
+}
+
+
+static void es7000_wait_for_init_deassert(atomic_t *deassert)
+{
+#ifndef CONFIG_ES7000_CLUSTERED_APIC
+       while (!atomic_read(deassert))
+               cpu_relax();
+#endif
+       return;
+}
+
+static unsigned int es7000_get_apic_id(unsigned long x)
+{
+       return (x >> 24) & 0xFF;
+}
+
+static void es7000_send_IPI_mask(const struct cpumask *mask, int vector)
+{
+       default_send_IPI_mask_sequence_phys(mask, vector);
+}
+
+static void es7000_send_IPI_allbutself(int vector)
+{
+       default_send_IPI_mask_allbutself_phys(cpu_online_mask, vector);
+}
+
+static void es7000_send_IPI_all(int vector)
+{
+       es7000_send_IPI_mask(cpu_online_mask, vector);
+}
+
+static int es7000_apic_id_registered(void)
+{
+       return 1;
+}
+
+static const cpumask_t *target_cpus_cluster(void)
+{
+       return &CPU_MASK_ALL;
+}
+
+static const cpumask_t *es7000_target_cpus(void)
+{
+       return &cpumask_of_cpu(smp_processor_id());
+}
+
+static unsigned long
+es7000_check_apicid_used(physid_mask_t bitmap, int apicid)
+{
+       return 0;
+}
+static unsigned long es7000_check_apicid_present(int bit)
+{
+       return physid_isset(bit, phys_cpu_present_map);
+}
+
+static unsigned long calculate_ldr(int cpu)
+{
+       unsigned long id = per_cpu(x86_bios_cpu_apicid, cpu);
+
+       return SET_APIC_LOGICAL_ID(id);
+}
+
+/*
+ * Set up the logical destination ID.
+ *
+ * Intel recommends to set DFR, LdR and TPR before enabling
+ * an APIC.  See e.g. "AP-388 82489DX User's Manual" (Intel
+ * document number 292116).  So here it goes...
+ */
+static void es7000_init_apic_ldr_cluster(void)
+{
+       unsigned long val;
+       int cpu = smp_processor_id();
+
+       apic_write(APIC_DFR, APIC_DFR_CLUSTER);
+       val = calculate_ldr(cpu);
+       apic_write(APIC_LDR, val);
+}
+
+static void es7000_init_apic_ldr(void)
+{
+       unsigned long val;
+       int cpu = smp_processor_id();
+
+       apic_write(APIC_DFR, APIC_DFR_FLAT);
+       val = calculate_ldr(cpu);
+       apic_write(APIC_LDR, val);
+}
+
+static void es7000_setup_apic_routing(void)
+{
+       int apic = per_cpu(x86_bios_cpu_apicid, smp_processor_id());
+
+       printk(KERN_INFO
+         "Enabling APIC mode:  %s. Using %d I/O APICs, target cpus %lx\n",
+               (apic_version[apic] == 0x14) ?
+                       "Physical Cluster" : "Logical Cluster",
+               nr_ioapics, cpus_addr(*es7000_target_cpus())[0]);
+}
+
+static int es7000_apicid_to_node(int logical_apicid)
+{
+       return 0;
+}
+
+
+static int es7000_cpu_present_to_apicid(int mps_cpu)
+{
+       if (!mps_cpu)
+               return boot_cpu_physical_apicid;
+       else if (mps_cpu < nr_cpu_ids)
+               return per_cpu(x86_bios_cpu_apicid, mps_cpu);
+       else
+               return BAD_APICID;
+}
+
+static int cpu_id;
+
+static physid_mask_t es7000_apicid_to_cpu_present(int phys_apicid)
+{
+       physid_mask_t mask;
+
+       mask = physid_mask_of_physid(cpu_id);
+       ++cpu_id;
+
+       return mask;
+}
+
+/* Mapping from cpu number to logical apicid */
+static int es7000_cpu_to_logical_apicid(int cpu)
+{
+#ifdef CONFIG_SMP
+       if (cpu >= nr_cpu_ids)
+               return BAD_APICID;
+       return cpu_2_logical_apicid[cpu];
+#else
+       return logical_smp_processor_id();
+#endif
+}
+
+static physid_mask_t es7000_ioapic_phys_id_map(physid_mask_t phys_map)
+{
+       /* For clustered we don't have a good way to do this yet - hack */
+       return physids_promote(0xff);
+}
+
+static int es7000_check_phys_apicid_present(int cpu_physical_apicid)
+{
+       boot_cpu_physical_apicid = read_apic_id();
+       return 1;
+}
+
+static unsigned int
+es7000_cpu_mask_to_apicid_cluster(const struct cpumask *cpumask)
+{
+       int cpus_found = 0;
+       int num_bits_set;
+       int apicid;
+       int cpu;
+
+       num_bits_set = cpumask_weight(cpumask);
+       /* Return id to all */
+       if (num_bits_set == nr_cpu_ids)
+               return 0xFF;
+       /*
+        * The cpus in the mask must all be on the apic cluster.  If are not
+        * on the same apicid cluster return default value of target_cpus():
+        */
+       cpu = cpumask_first(cpumask);
+       apicid = es7000_cpu_to_logical_apicid(cpu);
+
+       while (cpus_found < num_bits_set) {
+               if (cpumask_test_cpu(cpu, cpumask)) {
+                       int new_apicid = es7000_cpu_to_logical_apicid(cpu);
+
+                       if (APIC_CLUSTER(apicid) != APIC_CLUSTER(new_apicid)) {
+                               WARN(1, "Not a valid mask!");
+
+                               return 0xFF;
+                       }
+                       apicid = new_apicid;
+                       cpus_found++;
+               }
+               cpu++;
+       }
+       return apicid;
+}
+
+static unsigned int es7000_cpu_mask_to_apicid(const cpumask_t *cpumask)
+{
+       int cpus_found = 0;
+       int num_bits_set;
+       int apicid;
+       int cpu;
+
+       num_bits_set = cpus_weight(*cpumask);
+       /* Return id to all */
+       if (num_bits_set == nr_cpu_ids)
+               return es7000_cpu_to_logical_apicid(0);
+       /*
+        * The cpus in the mask must all be on the apic cluster.  If are not
+        * on the same apicid cluster return default value of target_cpus():
+        */
+       cpu = first_cpu(*cpumask);
+       apicid = es7000_cpu_to_logical_apicid(cpu);
+       while (cpus_found < num_bits_set) {
+               if (cpu_isset(cpu, *cpumask)) {
+                       int new_apicid = es7000_cpu_to_logical_apicid(cpu);
+
+                       if (APIC_CLUSTER(apicid) != APIC_CLUSTER(new_apicid)) {
+                               printk("%s: Not a valid mask!\n", __func__);
+
+                               return es7000_cpu_to_logical_apicid(0);
+                       }
+                       apicid = new_apicid;
+                       cpus_found++;
+               }
+               cpu++;
+       }
+       return apicid;
+}
+
+static unsigned int
+es7000_cpu_mask_to_apicid_and(const struct cpumask *inmask,
+                             const struct cpumask *andmask)
+{
+       int apicid = es7000_cpu_to_logical_apicid(0);
+       cpumask_var_t cpumask;
+
+       if (!alloc_cpumask_var(&cpumask, GFP_ATOMIC))
+               return apicid;
+
+       cpumask_and(cpumask, inmask, andmask);
+       cpumask_and(cpumask, cpumask, cpu_online_mask);
+       apicid = es7000_cpu_mask_to_apicid(cpumask);
+
+       free_cpumask_var(cpumask);
+
+       return apicid;
+}
+
+static int es7000_phys_pkg_id(int cpuid_apic, int index_msb)
+{
+       return cpuid_apic >> index_msb;
+}
+
+void __init es7000_update_apic_to_cluster(void)
+{
+       apic->target_cpus = target_cpus_cluster;
+       apic->irq_delivery_mode = dest_LowestPrio;
+       /* logical delivery broadcast to all procs: */
+       apic->irq_dest_mode = 1;
+
+       apic->init_apic_ldr = es7000_init_apic_ldr_cluster;
+
+       apic->cpu_mask_to_apicid = es7000_cpu_mask_to_apicid_cluster;
+}
+
+static int probe_es7000(void)
+{
+       /* probed later in mptable/ACPI hooks */
+       return 0;
+}
+
+static __init int
+es7000_mps_oem_check(struct mpc_table *mpc, char *oem, char *productid)
+{
+       if (mpc->oemptr) {
+               struct mpc_oemtable *oem_table =
+                       (struct mpc_oemtable *)mpc->oemptr;
+
+               if (!strncmp(oem, "UNISYS", 6))
+                       return parse_unisys_oem((char *)oem_table);
+       }
+       return 0;
+}
+
+
+struct apic apic_es7000 = {
+
+       .name                           = "es7000",
+       .probe                          = probe_es7000,
+       .acpi_madt_oem_check            = es7000_acpi_madt_oem_check,
+       .apic_id_registered             = es7000_apic_id_registered,
+
+       .irq_delivery_mode              = dest_Fixed,
+       /* phys delivery to target CPUs: */
+       .irq_dest_mode                  = 0,
+
+       .target_cpus                    = es7000_target_cpus,
+       .disable_esr                    = 1,
+       .dest_logical                   = 0,
+       .check_apicid_used              = es7000_check_apicid_used,
+       .check_apicid_present           = es7000_check_apicid_present,
+
+       .vector_allocation_domain       = es7000_vector_allocation_domain,
+       .init_apic_ldr                  = es7000_init_apic_ldr,
+
+       .ioapic_phys_id_map             = es7000_ioapic_phys_id_map,
+       .setup_apic_routing             = es7000_setup_apic_routing,
+       .multi_timer_check              = NULL,
+       .apicid_to_node                 = es7000_apicid_to_node,
+       .cpu_to_logical_apicid          = es7000_cpu_to_logical_apicid,
+       .cpu_present_to_apicid          = es7000_cpu_present_to_apicid,
+       .apicid_to_cpu_present          = es7000_apicid_to_cpu_present,
+       .setup_portio_remap             = NULL,
+       .check_phys_apicid_present      = es7000_check_phys_apicid_present,
+       .enable_apic_mode               = es7000_enable_apic_mode,
+       .phys_pkg_id                    = es7000_phys_pkg_id,
+       .mps_oem_check                  = es7000_mps_oem_check,
+
+       .get_apic_id                    = es7000_get_apic_id,
+       .set_apic_id                    = NULL,
+       .apic_id_mask                   = 0xFF << 24,
+
+       .cpu_mask_to_apicid             = es7000_cpu_mask_to_apicid,
+       .cpu_mask_to_apicid_and         = es7000_cpu_mask_to_apicid_and,
+
+       .send_IPI_mask                  = es7000_send_IPI_mask,
+       .send_IPI_mask_allbutself       = NULL,
+       .send_IPI_allbutself            = es7000_send_IPI_allbutself,
+       .send_IPI_all                   = es7000_send_IPI_all,
+       .send_IPI_self                  = default_send_IPI_self,
+
+       .wakeup_cpu                     = NULL,
+
+       .trampoline_phys_low            = 0x467,
+       .trampoline_phys_high           = 0x469,
+
+       .wait_for_init_deassert         = es7000_wait_for_init_deassert,
+
+       /* Nothing to do for most platforms, since cleared by the INIT cycle: */
+       .smp_callin_clear_local_apic    = NULL,
+       .inquire_remote_apic            = default_inquire_remote_apic,
+
+       .read                           = native_apic_mem_read,
+       .write                          = native_apic_mem_write,
+       .icr_read                       = native_apic_icr_read,
+       .icr_write                      = native_apic_icr_write,
+       .wait_icr_idle                  = native_apic_wait_icr_idle,
+       .safe_wait_icr_idle             = native_safe_apic_wait_icr_idle,
+};
diff --git a/arch/x86/kernel/apic/numaq_32.c b/arch/x86/kernel/apic/numaq_32.c
new file mode 100644 (file)
index 0000000..d9d6d61
--- /dev/null
@@ -0,0 +1,565 @@
+/*
+ * Written by: Patricia Gaughen, IBM Corporation
+ *
+ * Copyright (C) 2002, IBM Corp.
+ * Copyright (C) 2009, Red Hat, Inc., Ingo Molnar
+ *
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
+ * NON INFRINGEMENT.  See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * Send feedback to <gone@us.ibm.com>
+ */
+#include <linux/nodemask.h>
+#include <linux/topology.h>
+#include <linux/bootmem.h>
+#include <linux/threads.h>
+#include <linux/cpumask.h>
+#include <linux/kernel.h>
+#include <linux/mmzone.h>
+#include <linux/module.h>
+#include <linux/string.h>
+#include <linux/init.h>
+#include <linux/numa.h>
+#include <linux/smp.h>
+#include <linux/io.h>
+#include <linux/mm.h>
+
+#include <asm/processor.h>
+#include <asm/fixmap.h>
+#include <asm/mpspec.h>
+#include <asm/numaq.h>
+#include <asm/setup.h>
+#include <asm/apic.h>
+#include <asm/e820.h>
+#include <asm/ipi.h>
+
+#define        MB_TO_PAGES(addr)               ((addr) << (20 - PAGE_SHIFT))
+
+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_trans {
+       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;
+};
+
+/* x86_quirks member */
+static int                             mpc_record;
+
+static __cpuinitdata struct mpc_trans  *translation_table[MAX_MPC_ENTRY];
+
+int                                    mp_bus_id_to_node[MAX_MP_BUSSES];
+int                                    mp_bus_id_to_local[MAX_MP_BUSSES];
+int                                    quad_local_to_mp_bus_id[NR_CPUS/4][4];
+
+
+static inline void numaq_register_node(int node, struct sys_cfg_data *scd)
+{
+       struct eachquadmem *eq = scd->eq + node;
+
+       node_set_online(node);
+
+       /* Convert to pages */
+       node_start_pfn[node] =
+                MB_TO_PAGES(eq->hi_shrd_mem_start - eq->priv_mem_size);
+
+       node_end_pfn[node] =
+                MB_TO_PAGES(eq->hi_shrd_mem_start + eq->hi_shrd_mem_size);
+
+       e820_register_active_regions(node, node_start_pfn[node],
+                                               node_end_pfn[node]);
+
+       memory_present(node, node_start_pfn[node], node_end_pfn[node]);
+
+       node_remap_size[node] = node_memmap_size_bytes(node,
+                                       node_start_pfn[node],
+                                       node_end_pfn[node]);
+}
+
+/*
+ * Function: smp_dump_qct()
+ *
+ * Description: gets memory layout from the quad config table.  This
+ * function also updates node_online_map with the nodes (quads) present.
+ */
+static void __init smp_dump_qct(void)
+{
+       struct sys_cfg_data *scd;
+       int node;
+
+       scd = (void *)__va(SYS_CFG_DATA_PRIV_ADDR);
+
+       nodes_clear(node_online_map);
+       for_each_node(node) {
+               if (scd->quads_present31_0 & (1 << node))
+                       numaq_register_node(node, scd);
+       }
+}
+
+void __cpuinit numaq_tsc_disable(void)
+{
+       if (!found_numaq)
+               return;
+
+       if (num_online_nodes() > 1) {
+               printk(KERN_DEBUG "NUMAQ: disabling TSC\n");
+               setup_clear_cpu_cap(X86_FEATURE_TSC);
+       }
+}
+
+static int __init numaq_pre_time_init(void)
+{
+       numaq_tsc_disable();
+       return 0;
+}
+
+static inline int generate_logical_apicid(int quad, int phys_apicid)
+{
+       return (quad << 4) + (phys_apicid ? phys_apicid << 1 : 1);
+}
+
+/* x86_quirks member */
+static int mpc_apic_id(struct mpc_cpu *m)
+{
+       int quad = translation_table[mpc_record]->trans_quad;
+       int logical_apicid = generate_logical_apicid(quad, m->apicid);
+
+       printk(KERN_DEBUG
+               "Processor #%d %u:%u APIC version %d (quad %d, apic %d)\n",
+                m->apicid, (m->cpufeature & CPU_FAMILY_MASK) >> 8,
+               (m->cpufeature & CPU_MODEL_MASK) >> 4,
+                m->apicver, quad, logical_apicid);
+
+       return logical_apicid;
+}
+
+/* x86_quirks member */
+static void mpc_oem_bus_info(struct mpc_bus *m, char *name)
+{
+       int quad = translation_table[mpc_record]->trans_quad;
+       int local = translation_table[mpc_record]->trans_local;
+
+       mp_bus_id_to_node[m->busid] = quad;
+       mp_bus_id_to_local[m->busid] = local;
+
+       printk(KERN_INFO "Bus #%d is %s (node %d)\n", m->busid, name, quad);
+}
+
+/* x86_quirks member */
+static void mpc_oem_pci_bus(struct mpc_bus *m)
+{
+       int quad = translation_table[mpc_record]->trans_quad;
+       int local = translation_table[mpc_record]->trans_local;
+
+       quad_local_to_mp_bus_id[quad][local] = m->busid;
+}
+
+static void __init MP_translation_info(struct mpc_trans *m)
+{
+       printk(KERN_INFO
+           "Translation: record %d, type %d, quad %d, global %d, local %d\n",
+              mpc_record, m->trans_type, m->trans_quad, m->trans_global,
+              m->trans_local);
+
+       if (mpc_record >= MAX_MPC_ENTRY)
+               printk(KERN_ERR "MAX_MPC_ENTRY exceeded!\n");
+       else
+               translation_table[mpc_record] = m; /* stash this for later */
+
+       if (m->trans_quad < MAX_NUMNODES && !node_online(m->trans_quad))
+               node_set_online(m->trans_quad);
+}
+
+static int __init mpf_checksum(unsigned char *mp, int len)
+{
+       int sum = 0;
+
+       while (len--)
+               sum += *mp++;
+
+       return sum & 0xFF;
+}
+
+/*
+ * Read/parse the MPC oem tables
+ */
+static void __init
+ smp_read_mpc_oem(struct mpc_oemtable *oemtable, unsigned short oemsize)
+{
+       int count = sizeof(*oemtable);  /* the header size */
+       unsigned char *oemptr = ((unsigned char *)oemtable) + count;
+
+       mpc_record = 0;
+       printk(KERN_INFO
+               "Found an OEM MPC table at %8p - parsing it ... \n", oemtable);
+
+       if (memcmp(oemtable->signature, MPC_OEM_SIGNATURE, 4)) {
+               printk(KERN_WARNING
+                      "SMP mpc oemtable: bad signature [%c%c%c%c]!\n",
+                      oemtable->signature[0], oemtable->signature[1],
+                      oemtable->signature[2], oemtable->signature[3]);
+               return;
+       }
+
+       if (mpf_checksum((unsigned char *)oemtable, oemtable->length)) {
+               printk(KERN_WARNING "SMP oem mptable: checksum error!\n");
+               return;
+       }
+
+       while (count < oemtable->length) {
+               switch (*oemptr) {
+               case MP_TRANSLATION:
+                       {
+                               struct mpc_trans *m = (void *)oemptr;
+
+                               MP_translation_info(m);
+                               oemptr += sizeof(*m);
+                               count += sizeof(*m);
+                               ++mpc_record;
+                               break;
+                       }
+               default:
+                       printk(KERN_WARNING
+                              "Unrecognised OEM table entry type! - %d\n",
+                              (int)*oemptr);
+                       return;
+               }
+       }
+}
+
+static int __init numaq_setup_ioapic_ids(void)
+{
+       /* so can skip it */
+       return 1;
+}
+
+static int __init numaq_update_apic(void)
+{
+       apic->wakeup_cpu = wakeup_secondary_cpu_via_nmi;
+
+       return 0;
+}
+
+static struct x86_quirks numaq_x86_quirks __initdata = {
+       .arch_pre_time_init             = numaq_pre_time_init,
+       .arch_time_init                 = NULL,
+       .arch_pre_intr_init             = NULL,
+       .arch_memory_setup              = NULL,
+       .arch_intr_init                 = NULL,
+       .arch_trap_init                 = NULL,
+       .mach_get_smp_config            = NULL,
+       .mach_find_smp_config           = NULL,
+       .mpc_record                     = &mpc_record,
+       .mpc_apic_id                    = mpc_apic_id,
+       .mpc_oem_bus_info               = mpc_oem_bus_info,
+       .mpc_oem_pci_bus                = mpc_oem_pci_bus,
+       .smp_read_mpc_oem               = smp_read_mpc_oem,
+       .setup_ioapic_ids               = numaq_setup_ioapic_ids,
+       .update_apic                    = numaq_update_apic,
+};
+
+static __init void early_check_numaq(void)
+{
+       /*
+        * Find possible boot-time SMP configuration:
+        */
+       early_find_smp_config();
+
+       /*
+        * get boot-time SMP configuration:
+        */
+       if (smp_found_config)
+               early_get_smp_config();
+
+       if (found_numaq)
+               x86_quirks = &numaq_x86_quirks;
+}
+
+int __init get_memcfg_numaq(void)
+{
+       early_check_numaq();
+       if (!found_numaq)
+               return 0;
+       smp_dump_qct();
+
+       return 1;
+}
+
+#define NUMAQ_APIC_DFR_VALUE   (APIC_DFR_CLUSTER)
+
+static inline unsigned int numaq_get_apic_id(unsigned long x)
+{
+       return (x >> 24) & 0x0F;
+}
+
+static inline void numaq_send_IPI_mask(const struct cpumask *mask, int vector)
+{
+       default_send_IPI_mask_sequence_logical(mask, vector);
+}
+
+static inline void numaq_send_IPI_allbutself(int vector)
+{
+       default_send_IPI_mask_allbutself_logical(cpu_online_mask, vector);
+}
+
+static inline void numaq_send_IPI_all(int vector)
+{
+       numaq_send_IPI_mask(cpu_online_mask, vector);
+}
+
+#define NUMAQ_TRAMPOLINE_PHYS_LOW      (0x8)
+#define NUMAQ_TRAMPOLINE_PHYS_HIGH     (0xa)
+
+/*
+ * Because we use NMIs rather than the INIT-STARTUP sequence to
+ * bootstrap the CPUs, the APIC may be in a weird state. Kick it:
+ */
+static inline void numaq_smp_callin_clear_local_apic(void)
+{
+       clear_local_APIC();
+}
+
+static inline const cpumask_t *numaq_target_cpus(void)
+{
+       return &CPU_MASK_ALL;
+}
+
+static inline unsigned long
+numaq_check_apicid_used(physid_mask_t bitmap, int apicid)
+{
+       return physid_isset(apicid, bitmap);
+}
+
+static inline unsigned long numaq_check_apicid_present(int bit)
+{
+       return physid_isset(bit, phys_cpu_present_map);
+}
+
+static inline int numaq_apic_id_registered(void)
+{
+       return 1;
+}
+
+static inline void numaq_init_apic_ldr(void)
+{
+       /* Already done in NUMA-Q firmware */
+}
+
+static inline void numaq_setup_apic_routing(void)
+{
+       printk(KERN_INFO
+               "Enabling APIC mode:  NUMA-Q.  Using %d I/O APICs\n",
+               nr_ioapics);
+}
+
+/*
+ * Skip adding the timer int on secondary nodes, which causes
+ * a small but painful rift in the time-space continuum.
+ */
+static inline int numaq_multi_timer_check(int apic, int irq)
+{
+       return apic != 0 && irq == 0;
+}
+
+static inline physid_mask_t numaq_ioapic_phys_id_map(physid_mask_t phys_map)
+{
+       /* We don't have a good way to do this yet - hack */
+       return physids_promote(0xFUL);
+}
+
+static inline int numaq_cpu_to_logical_apicid(int cpu)
+{
+       if (cpu >= nr_cpu_ids)
+               return BAD_APICID;
+       return cpu_2_logical_apicid[cpu];
+}
+
+/*
+ * Supporting over 60 cpus on NUMA-Q requires a locality-dependent
+ * cpu to APIC ID relation to properly interact with the intelligent
+ * mode of the cluster controller.
+ */
+static inline int numaq_cpu_present_to_apicid(int mps_cpu)
+{
+       if (mps_cpu < 60)
+               return ((mps_cpu >> 2) << 4) | (1 << (mps_cpu & 0x3));
+       else
+               return BAD_APICID;
+}
+
+static inline int numaq_apicid_to_node(int logical_apicid)
+{
+       return logical_apicid >> 4;
+}
+
+static inline physid_mask_t numaq_apicid_to_cpu_present(int logical_apicid)
+{
+       int node = numaq_apicid_to_node(logical_apicid);
+       int cpu = __ffs(logical_apicid & 0xf);
+
+       return physid_mask_of_physid(cpu + 4*node);
+}
+
+/* Where the IO area was mapped on multiquad, always 0 otherwise */
+void *xquad_portio;
+
+static inline int numaq_check_phys_apicid_present(int boot_cpu_physical_apicid)
+{
+       return 1;
+}
+
+/*
+ * We use physical apicids here, not logical, so just return the default
+ * physical broadcast to stop people from breaking us
+ */
+static inline unsigned int numaq_cpu_mask_to_apicid(const cpumask_t *cpumask)
+{
+       return 0x0F;
+}
+
+static inline unsigned int
+numaq_cpu_mask_to_apicid_and(const struct cpumask *cpumask,
+                            const struct cpumask *andmask)
+{
+       return 0x0F;
+}
+
+/* No NUMA-Q box has a HT CPU, but it can't hurt to use the default code. */
+static inline int numaq_phys_pkg_id(int cpuid_apic, int index_msb)
+{
+       return cpuid_apic >> index_msb;
+}
+
+static int
+numaq_mps_oem_check(struct mpc_table *mpc, char *oem, char *productid)
+{
+       if (strncmp(oem, "IBM NUMA", 8))
+               printk(KERN_ERR "Warning! Not a NUMA-Q system!\n");
+       else
+               found_numaq = 1;
+
+       return found_numaq;
+}
+
+static int probe_numaq(void)
+{
+       /* already know from get_memcfg_numaq() */
+       return found_numaq;
+}
+
+static void numaq_vector_allocation_domain(int cpu, cpumask_t *retmask)
+{
+       /* Careful. Some cpus do not strictly honor the set of cpus
+        * specified in the interrupt destination when using lowest
+        * priority interrupt delivery mode.
+        *
+        * In particular there was a hyperthreading cpu observed to
+        * deliver interrupts to the wrong hyperthread when only one
+        * hyperthread was specified in the interrupt desitination.
+        */
+       *retmask = (cpumask_t){ { [0] = APIC_ALL_CPUS, } };
+}
+
+static void numaq_setup_portio_remap(void)
+{
+       int num_quads = num_online_nodes();
+
+       if (num_quads <= 1)
+               return;
+
+       printk(KERN_INFO
+               "Remapping cross-quad port I/O for %d quads\n", num_quads);
+
+       xquad_portio = ioremap(XQUAD_PORTIO_BASE, num_quads*XQUAD_PORTIO_QUAD);
+
+       printk(KERN_INFO
+               "xquad_portio vaddr 0x%08lx, len %08lx\n",
+               (u_long) xquad_portio, (u_long) num_quads*XQUAD_PORTIO_QUAD);
+}
+
+struct apic apic_numaq = {
+
+       .name                           = "NUMAQ",
+       .probe                          = probe_numaq,
+       .acpi_madt_oem_check            = NULL,
+       .apic_id_registered             = numaq_apic_id_registered,
+
+       .irq_delivery_mode              = dest_LowestPrio,
+       /* physical delivery on LOCAL quad: */
+       .irq_dest_mode                  = 0,
+
+       .target_cpus                    = numaq_target_cpus,
+       .disable_esr                    = 1,
+       .dest_logical                   = APIC_DEST_LOGICAL,
+       .check_apicid_used              = numaq_check_apicid_used,
+       .check_apicid_present           = numaq_check_apicid_present,
+
+       .vector_allocation_domain       = numaq_vector_allocation_domain,
+       .init_apic_ldr                  = numaq_init_apic_ldr,
+
+       .ioapic_phys_id_map             = numaq_ioapic_phys_id_map,
+       .setup_apic_routing             = numaq_setup_apic_routing,
+       .multi_timer_check              = numaq_multi_timer_check,
+       .apicid_to_node                 = numaq_apicid_to_node,
+       .cpu_to_logical_apicid          = numaq_cpu_to_logical_apicid,
+       .cpu_present_to_apicid          = numaq_cpu_present_to_apicid,
+       .apicid_to_cpu_present          = numaq_apicid_to_cpu_present,
+       .setup_portio_remap             = numaq_setup_portio_remap,
+       .check_phys_apicid_present      = numaq_check_phys_apicid_present,
+       .enable_apic_mode               = NULL,
+       .phys_pkg_id                    = numaq_phys_pkg_id,
+       .mps_oem_check                  = numaq_mps_oem_check,
+
+       .get_apic_id                    = numaq_get_apic_id,
+       .set_apic_id                    = NULL,
+       .apic_id_mask                   = 0x0F << 24,
+
+       .cpu_mask_to_apicid             = numaq_cpu_mask_to_apicid,
+       .cpu_mask_to_apicid_and         = numaq_cpu_mask_to_apicid_and,
+
+       .send_IPI_mask                  = numaq_send_IPI_mask,
+       .send_IPI_mask_allbutself       = NULL,
+       .send_IPI_allbutself            = numaq_send_IPI_allbutself,
+       .send_IPI_all                   = numaq_send_IPI_all,
+       .send_IPI_self                  = default_send_IPI_self,
+
+       .wakeup_cpu                     = NULL,
+       .trampoline_phys_low            = NUMAQ_TRAMPOLINE_PHYS_LOW,
+       .trampoline_phys_high           = NUMAQ_TRAMPOLINE_PHYS_HIGH,
+
+       /* We don't do anything here because we use NMI's to boot instead */
+       .wait_for_init_deassert         = NULL,
+
+       .smp_callin_clear_local_apic    = numaq_smp_callin_clear_local_apic,
+       .inquire_remote_apic            = NULL,
+
+       .read                           = native_apic_mem_read,
+       .write                          = native_apic_mem_write,
+       .icr_read                       = native_apic_icr_read,
+       .icr_write                      = native_apic_icr_write,
+       .wait_icr_idle                  = native_apic_wait_icr_idle,
+       .safe_wait_icr_idle             = native_safe_apic_wait_icr_idle,
+};
diff --git a/arch/x86/kernel/apic/probe_32.c b/arch/x86/kernel/apic/probe_32.c
new file mode 100644 (file)
index 0000000..5fa4833
--- /dev/null
@@ -0,0 +1,424 @@
+/*
+ * Default generic APIC driver. This handles up to 8 CPUs.
+ *
+ * Copyright 2003 Andi Kleen, SuSE Labs.
+ * Subject to the GNU Public License, v.2
+ *
+ * Generic x86 APIC driver probe layer.
+ */
+#include <linux/threads.h>
+#include <linux/cpumask.h>
+#include <linux/module.h>
+#include <linux/string.h>
+#include <linux/kernel.h>
+#include <linux/ctype.h>
+#include <linux/init.h>
+#include <linux/errno.h>
+#include <asm/fixmap.h>
+#include <asm/mpspec.h>
+#include <asm/apicdef.h>
+#include <asm/apic.h>
+#include <asm/setup.h>
+
+#include <linux/threads.h>
+#include <linux/cpumask.h>
+#include <asm/mpspec.h>
+#include <asm/fixmap.h>
+#include <asm/apicdef.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/smp.h>
+#include <linux/init.h>
+#include <asm/ipi.h>
+
+#include <linux/smp.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <asm/acpi.h>
+#include <asm/arch_hooks.h>
+#include <asm/e820.h>
+#include <asm/setup.h>
+
+#ifdef CONFIG_HOTPLUG_CPU
+#define DEFAULT_SEND_IPI       (1)
+#else
+#define DEFAULT_SEND_IPI       (0)
+#endif
+
+int no_broadcast = DEFAULT_SEND_IPI;
+
+#ifdef CONFIG_X86_LOCAL_APIC
+
+void default_setup_apic_routing(void)
+{
+#ifdef CONFIG_X86_IO_APIC
+       printk(KERN_INFO
+               "Enabling APIC mode:  Flat.  Using %d I/O APICs\n",
+               nr_ioapics);
+#endif
+}
+
+static void default_vector_allocation_domain(int cpu, struct cpumask *retmask)
+{
+       /*
+        * Careful. Some cpus do not strictly honor the set of cpus
+        * specified in the interrupt destination when using lowest
+        * priority interrupt delivery mode.
+        *
+        * In particular there was a hyperthreading cpu observed to
+        * deliver interrupts to the wrong hyperthread when only one
+        * hyperthread was specified in the interrupt desitination.
+        */
+       *retmask = (cpumask_t) { { [0] = APIC_ALL_CPUS } };
+}
+
+/* should be called last. */
+static int probe_default(void)
+{
+       return 1;
+}
+
+struct apic apic_default = {
+
+       .name                           = "default",
+       .probe                          = probe_default,
+       .acpi_madt_oem_check            = NULL,
+       .apic_id_registered             = default_apic_id_registered,
+
+       .irq_delivery_mode              = dest_LowestPrio,
+       /* logical delivery broadcast to all CPUs: */
+       .irq_dest_mode                  = 1,
+
+       .target_cpus                    = default_target_cpus,
+       .disable_esr                    = 0,
+       .dest_logical                   = APIC_DEST_LOGICAL,
+       .check_apicid_used              = default_check_apicid_used,
+       .check_apicid_present           = default_check_apicid_present,
+
+       .vector_allocation_domain       = default_vector_allocation_domain,
+       .init_apic_ldr                  = default_init_apic_ldr,
+
+       .ioapic_phys_id_map             = default_ioapic_phys_id_map,
+       .setup_apic_routing             = default_setup_apic_routing,
+       .multi_timer_check              = NULL,
+       .apicid_to_node                 = default_apicid_to_node,
+       .cpu_to_logical_apicid          = default_cpu_to_logical_apicid,
+       .cpu_present_to_apicid          = default_cpu_present_to_apicid,
+       .apicid_to_cpu_present          = default_apicid_to_cpu_present,
+       .setup_portio_remap             = NULL,
+       .check_phys_apicid_present      = default_check_phys_apicid_present,
+       .enable_apic_mode               = NULL,
+       .phys_pkg_id                    = default_phys_pkg_id,
+       .mps_oem_check                  = NULL,
+
+       .get_apic_id                    = default_get_apic_id,
+       .set_apic_id                    = NULL,
+       .apic_id_mask                   = 0x0F << 24,
+
+       .cpu_mask_to_apicid             = default_cpu_mask_to_apicid,
+       .cpu_mask_to_apicid_and         = default_cpu_mask_to_apicid_and,
+
+       .send_IPI_mask                  = default_send_IPI_mask_logical,
+       .send_IPI_mask_allbutself       = default_send_IPI_mask_allbutself_logical,
+       .send_IPI_allbutself            = default_send_IPI_allbutself,
+       .send_IPI_all                   = default_send_IPI_all,
+       .send_IPI_self                  = default_send_IPI_self,
+
+       .wakeup_cpu                     = NULL,
+       .trampoline_phys_low            = DEFAULT_TRAMPOLINE_PHYS_LOW,
+       .trampoline_phys_high           = DEFAULT_TRAMPOLINE_PHYS_HIGH,
+
+       .wait_for_init_deassert         = default_wait_for_init_deassert,
+
+       .smp_callin_clear_local_apic    = NULL,
+       .inquire_remote_apic            = default_inquire_remote_apic,
+
+       .read                           = native_apic_mem_read,
+       .write                          = native_apic_mem_write,
+       .icr_read                       = native_apic_icr_read,
+       .icr_write                      = native_apic_icr_write,
+       .wait_icr_idle                  = native_apic_wait_icr_idle,
+       .safe_wait_icr_idle             = native_safe_apic_wait_icr_idle,
+};
+
+extern struct apic apic_numaq;
+extern struct apic apic_summit;
+extern struct apic apic_bigsmp;
+extern struct apic apic_es7000;
+extern struct apic apic_default;
+
+struct apic *apic = &apic_default;
+EXPORT_SYMBOL_GPL(apic);
+
+static struct apic *apic_probe[] __initdata = {
+#ifdef CONFIG_X86_NUMAQ
+       &apic_numaq,
+#endif
+#ifdef CONFIG_X86_SUMMIT
+       &apic_summit,
+#endif
+#ifdef CONFIG_X86_BIGSMP
+       &apic_bigsmp,
+#endif
+#ifdef CONFIG_X86_ES7000
+       &apic_es7000,
+#endif
+       &apic_default,  /* must be last */
+       NULL,
+};
+
+static int cmdline_apic __initdata;
+static int __init parse_apic(char *arg)
+{
+       int i;
+
+       if (!arg)
+               return -EINVAL;
+
+       for (i = 0; apic_probe[i]; i++) {
+               if (!strcmp(apic_probe[i]->name, arg)) {
+                       apic = apic_probe[i];
+                       cmdline_apic = 1;
+                       return 0;
+               }
+       }
+
+       if (x86_quirks->update_apic)
+               x86_quirks->update_apic();
+
+       /* Parsed again by __setup for debug/verbose */
+       return 0;
+}
+early_param("apic", parse_apic);
+
+void __init generic_bigsmp_probe(void)
+{
+#ifdef CONFIG_X86_BIGSMP
+       /*
+        * This routine is used to switch to bigsmp mode when
+        * - There is no apic= option specified by the user
+        * - generic_apic_probe() has chosen apic_default as the sub_arch
+        * - we find more than 8 CPUs in acpi LAPIC listing with xAPIC support
+        */
+
+       if (!cmdline_apic && apic == &apic_default) {
+               if (apic_bigsmp.probe()) {
+                       apic = &apic_bigsmp;
+                       if (x86_quirks->update_apic)
+                               x86_quirks->update_apic();
+                       printk(KERN_INFO "Overriding APIC driver with %s\n",
+                              apic->name);
+               }
+       }
+#endif
+}
+
+void __init generic_apic_probe(void)
+{
+       if (!cmdline_apic) {
+               int i;
+               for (i = 0; apic_probe[i]; i++) {
+                       if (apic_probe[i]->probe()) {
+                               apic = apic_probe[i];
+                               break;
+                       }
+               }
+               /* Not visible without early console */
+               if (!apic_probe[i])
+                       panic("Didn't find an APIC driver");
+
+               if (x86_quirks->update_apic)
+                       x86_quirks->update_apic();
+       }
+       printk(KERN_INFO "Using APIC driver %s\n", apic->name);
+}
+
+/* These functions can switch the APIC even after the initial ->probe() */
+
+int __init
+generic_mps_oem_check(struct mpc_table *mpc, char *oem, char *productid)
+{
+       int i;
+
+       for (i = 0; apic_probe[i]; ++i) {
+               if (!apic_probe[i]->mps_oem_check)
+                       continue;
+               if (!apic_probe[i]->mps_oem_check(mpc, oem, productid))
+                       continue;
+
+               if (!cmdline_apic) {
+                       apic = apic_probe[i];
+                       if (x86_quirks->update_apic)
+                               x86_quirks->update_apic();
+                       printk(KERN_INFO "Switched to APIC driver `%s'.\n",
+                              apic->name);
+               }
+               return 1;
+       }
+       return 0;
+}
+
+int __init default_acpi_madt_oem_check(char *oem_id, char *oem_table_id)
+{
+       int i;
+
+       for (i = 0; apic_probe[i]; ++i) {
+               if (!apic_probe[i]->acpi_madt_oem_check)
+                       continue;
+               if (!apic_probe[i]->acpi_madt_oem_check(oem_id, oem_table_id))
+                       continue;
+
+               if (!cmdline_apic) {
+                       apic = apic_probe[i];
+                       if (x86_quirks->update_apic)
+                               x86_quirks->update_apic();
+                       printk(KERN_INFO "Switched to APIC driver `%s'.\n",
+                              apic->name);
+               }
+               return 1;
+       }
+       return 0;
+}
+
+#endif /* CONFIG_X86_LOCAL_APIC */
+
+/**
+ * pre_intr_init_hook - initialisation prior to setting up interrupt vectors
+ *
+ * Description:
+ *     Perform any necessary interrupt initialisation prior to setting up
+ *     the "ordinary" interrupt call gates.  For legacy reasons, the ISA
+ *     interrupts should be initialised here if the machine emulates a PC
+ *     in any way.
+ **/
+void __init pre_intr_init_hook(void)
+{
+       if (x86_quirks->arch_pre_intr_init) {
+               if (x86_quirks->arch_pre_intr_init())
+                       return;
+       }
+       init_ISA_irqs();
+}
+
+/**
+ * intr_init_hook - post gate setup interrupt initialisation
+ *
+ * Description:
+ *     Fill in any interrupts that may have been left out by the general
+ *     init_IRQ() routine.  interrupts having to do with the machine rather
+ *     than the devices on the I/O bus (like APIC interrupts in intel MP
+ *     systems) are started here.
+ **/
+void __init intr_init_hook(void)
+{
+       if (x86_quirks->arch_intr_init) {
+               if (x86_quirks->arch_intr_init())
+                       return;
+       }
+}
+
+/**
+ * pre_setup_arch_hook - hook called prior to any setup_arch() execution
+ *
+ * Description:
+ *     generally used to activate any machine specific identification
+ *     routines that may be needed before setup_arch() runs.  On Voyager
+ *     this is used to get the board revision and type.
+ **/
+void __init pre_setup_arch_hook(void)
+{
+}
+
+/**
+ * trap_init_hook - initialise system specific traps
+ *
+ * Description:
+ *     Called as the final act of trap_init().  Used in VISWS to initialise
+ *     the various board specific APIC traps.
+ **/
+void __init trap_init_hook(void)
+{
+       if (x86_quirks->arch_trap_init) {
+               if (x86_quirks->arch_trap_init())
+                       return;
+       }
+}
+
+static struct irqaction irq0  = {
+       .handler = timer_interrupt,
+       .flags = IRQF_DISABLED | IRQF_NOBALANCING | IRQF_IRQPOLL,
+       .mask = CPU_MASK_NONE,
+       .name = "timer"
+};
+
+/**
+ * pre_time_init_hook - do any specific initialisations before.
+ *
+ **/
+void __init pre_time_init_hook(void)
+{
+       if (x86_quirks->arch_pre_time_init)
+               x86_quirks->arch_pre_time_init();
+}
+
+/**
+ * time_init_hook - do any specific initialisations for the system timer.
+ *
+ * Description:
+ *     Must plug the system timer interrupt source at HZ into the IRQ listed
+ *     in irq_vectors.h:TIMER_IRQ
+ **/
+void __init time_init_hook(void)
+{
+       if (x86_quirks->arch_time_init) {
+               /*
+                * A nonzero return code does not mean failure, it means
+                * that the architecture quirk does not want any
+                * generic (timer) setup to be performed after this:
+                */
+               if (x86_quirks->arch_time_init())
+                       return;
+       }
+
+       irq0.mask = cpumask_of_cpu(0);
+       setup_irq(0, &irq0);
+}
+
+#ifdef CONFIG_MCA
+/**
+ * mca_nmi_hook - hook into MCA specific NMI chain
+ *
+ * Description:
+ *     The MCA (Microchannel Architecture) has an NMI chain for NMI sources
+ *     along the MCA bus.  Use this to hook into that chain if you will need
+ *     it.
+ **/
+void mca_nmi_hook(void)
+{
+       /*
+        * If I recall correctly, there's a whole bunch of other things that
+        * we can do to check for NMI problems, but that's all I know about
+        * at the moment.
+        */
+       pr_warning("NMI generated from unknown source!\n");
+}
+#endif
+
+static __init int no_ipi_broadcast(char *str)
+{
+       get_option(&str, &no_broadcast);
+       pr_info("Using %s mode\n",
+               no_broadcast ? "No IPI Broadcast" : "IPI Broadcast");
+       return 1;
+}
+__setup("no_ipi_broadcast=", no_ipi_broadcast);
+
+static int __init print_ipi_mode(void)
+{
+       pr_info("Using IPI %s mode\n",
+               no_broadcast ? "No-Shortcut" : "Shortcut");
+       return 0;
+}
+
+late_initcall(print_ipi_mode);
+
diff --git a/arch/x86/kernel/apic/probe_64.c b/arch/x86/kernel/apic/probe_64.c
new file mode 100644 (file)
index 0000000..70935dd
--- /dev/null
@@ -0,0 +1,89 @@
+/*
+ * Copyright 2004 James Cleverdon, IBM.
+ * Subject to the GNU Public License, v.2
+ *
+ * Generic APIC sub-arch probe layer.
+ *
+ * Hacked for x86-64 by James Cleverdon from i386 architecture code by
+ * Martin Bligh, Andi Kleen, James Bottomley, John Stultz, and
+ * James Cleverdon.
+ */
+#include <linux/threads.h>
+#include <linux/cpumask.h>
+#include <linux/string.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/ctype.h>
+#include <linux/init.h>
+#include <linux/hardirq.h>
+#include <linux/dmar.h>
+
+#include <asm/smp.h>
+#include <asm/apic.h>
+#include <asm/ipi.h>
+#include <asm/setup.h>
+
+extern struct apic apic_flat;
+extern struct apic apic_physflat;
+extern struct apic apic_x2xpic_uv_x;
+extern struct apic apic_x2apic_phys;
+extern struct apic apic_x2apic_cluster;
+
+struct apic __read_mostly *apic = &apic_flat;
+EXPORT_SYMBOL_GPL(apic);
+
+static struct apic *apic_probe[] __initdata = {
+#ifdef CONFIG_X86_UV
+       &apic_x2apic_uv_x,
+#endif
+#ifdef CONFIG_X86_X2APIC
+       &apic_x2apic_phys,
+       &apic_x2apic_cluster,
+#endif
+       &apic_physflat,
+       NULL,
+};
+
+/*
+ * Check the APIC IDs in bios_cpu_apicid and choose the APIC mode.
+ */
+void __init default_setup_apic_routing(void)
+{
+#ifdef CONFIG_X86_X2APIC
+       if (apic == &apic_x2apic_phys || apic == &apic_x2apic_cluster) {
+               if (!intr_remapping_enabled)
+                       apic = &apic_flat;
+       }
+#endif
+
+       if (apic == &apic_flat) {
+               if (max_physical_apicid >= 8)
+                       apic = &apic_physflat;
+               printk(KERN_INFO "Setting APIC routing to %s\n", apic->name);
+       }
+
+       if (x86_quirks->update_apic)
+               x86_quirks->update_apic();
+}
+
+/* Same for both flat and physical. */
+
+void apic_send_IPI_self(int vector)
+{
+       __default_send_IPI_shortcut(APIC_DEST_SELF, vector, APIC_DEST_PHYSICAL);
+}
+
+int __init default_acpi_madt_oem_check(char *oem_id, char *oem_table_id)
+{
+       int i;
+
+       for (i = 0; apic_probe[i]; ++i) {
+               if (apic_probe[i]->acpi_madt_oem_check(oem_id, oem_table_id)) {
+                       apic = apic_probe[i];
+                       printk(KERN_INFO "Setting APIC routing to %s.\n",
+                               apic->name);
+                       return 1;
+               }
+       }
+       return 0;
+}
diff --git a/arch/x86/kernel/apic/summit_32.c b/arch/x86/kernel/apic/summit_32.c
new file mode 100644 (file)
index 0000000..cfe7b09
--- /dev/null
@@ -0,0 +1,601 @@
+/*
+ * IBM Summit-Specific Code
+ *
+ * Written By: Matthew Dobson, IBM Corporation
+ *
+ * Copyright (c) 2003 IBM Corp.
+ *
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at
+ * your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
+ * NON INFRINGEMENT.  See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * Send feedback to <colpatch@us.ibm.com>
+ *
+ */
+
+#include <linux/mm.h>
+#include <linux/init.h>
+#include <asm/io.h>
+#include <asm/bios_ebda.h>
+
+/*
+ * APIC driver for the IBM "Summit" chipset.
+ */
+#include <linux/threads.h>
+#include <linux/cpumask.h>
+#include <asm/mpspec.h>
+#include <asm/apic.h>
+#include <asm/smp.h>
+#include <asm/fixmap.h>
+#include <asm/apicdef.h>
+#include <asm/ipi.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/init.h>
+#include <linux/gfp.h>
+#include <linux/smp.h>
+
+static inline unsigned summit_get_apic_id(unsigned long x)
+{
+       return (x >> 24) & 0xFF;
+}
+
+static inline void summit_send_IPI_mask(const cpumask_t *mask, int vector)
+{
+       default_send_IPI_mask_sequence_logical(mask, vector);
+}
+
+static inline void summit_send_IPI_allbutself(int vector)
+{
+       cpumask_t mask = cpu_online_map;
+       cpu_clear(smp_processor_id(), mask);
+
+       if (!cpus_empty(mask))
+               summit_send_IPI_mask(&mask, vector);
+}
+
+static inline void summit_send_IPI_all(int vector)
+{
+       summit_send_IPI_mask(&cpu_online_map, vector);
+}
+
+#include <asm/tsc.h>
+
+extern int use_cyclone;
+
+#ifdef CONFIG_X86_SUMMIT_NUMA
+extern void setup_summit(void);
+#else
+#define setup_summit() {}
+#endif
+
+static inline int
+summit_mps_oem_check(struct mpc_table *mpc, char *oem, char *productid)
+{
+       if (!strncmp(oem, "IBM ENSW", 8) &&
+                       (!strncmp(productid, "VIGIL SMP", 9)
+                        || !strncmp(productid, "EXA", 3)
+                        || !strncmp(productid, "RUTHLESS SMP", 12))){
+               mark_tsc_unstable("Summit based system");
+               use_cyclone = 1; /*enable cyclone-timer*/
+               setup_summit();
+               return 1;
+       }
+       return 0;
+}
+
+/* Hook from generic ACPI tables.c */
+static inline int summit_acpi_madt_oem_check(char *oem_id, char *oem_table_id)
+{
+       if (!strncmp(oem_id, "IBM", 3) &&
+           (!strncmp(oem_table_id, "SERVIGIL", 8)
+            || !strncmp(oem_table_id, "EXA", 3))){
+               mark_tsc_unstable("Summit based system");
+               use_cyclone = 1; /*enable cyclone-timer*/
+               setup_summit();
+               return 1;
+       }
+       return 0;
+}
+
+struct rio_table_hdr {
+       unsigned char version;      /* Version number of this data structure           */
+                                   /* Version 3 adds chassis_num & WP_index           */
+       unsigned char num_scal_dev; /* # of Scalability devices (Twisters for Vigil)   */
+       unsigned char num_rio_dev;  /* # of RIO I/O devices (Cyclones and Winnipegs)   */
+} __attribute__((packed));
+
+struct scal_detail {
+       unsigned char node_id;      /* Scalability Node ID                             */
+       unsigned long CBAR;         /* Address of 1MB register space                   */
+       unsigned char port0node;    /* Node ID port connected to: 0xFF=None            */
+       unsigned char port0port;    /* Port num port connected to: 0,1,2, or 0xFF=None */
+       unsigned char port1node;    /* Node ID port connected to: 0xFF = None          */
+       unsigned char port1port;    /* Port num port connected to: 0,1,2, or 0xFF=None */
+       unsigned char port2node;    /* Node ID port connected to: 0xFF = None          */
+       unsigned char port2port;    /* Port num port connected to: 0,1,2, or 0xFF=None */
+       unsigned char chassis_num;  /* 1 based Chassis number (1 = boot node)          */
+} __attribute__((packed));
+
+struct rio_detail {
+       unsigned char node_id;      /* RIO Node ID                                     */
+       unsigned long BBAR;         /* Address of 1MB register space                   */
+       unsigned char type;         /* Type of device                                  */
+       unsigned char owner_id;     /* For WPEG: Node ID of Cyclone that owns this WPEG*/
+                                   /* For CYC:  Node ID of Twister that owns this CYC */
+       unsigned char port0node;    /* Node ID port connected to: 0xFF=None            */
+       unsigned char port0port;    /* Port num port connected to: 0,1,2, or 0xFF=None */
+       unsigned char port1node;    /* Node ID port connected to: 0xFF=None            */
+       unsigned char port1port;    /* Port num port connected to: 0,1,2, or 0xFF=None */
+       unsigned char first_slot;   /* For WPEG: Lowest slot number below this WPEG    */
+                                   /* For CYC:  0                                     */
+       unsigned char status;       /* For WPEG: Bit 0 = 1 : the XAPIC is used         */
+                                   /*                 = 0 : the XAPIC is not used, ie:*/
+                                   /*                     ints fwded to another XAPIC */
+                                   /*           Bits1:7 Reserved                      */
+                                   /* For CYC:  Bits0:7 Reserved                      */
+       unsigned char WP_index;     /* For WPEG: WPEG instance index - lower ones have */
+                                   /*           lower slot numbers/PCI bus numbers    */
+                                   /* For CYC:  No meaning                            */
+       unsigned char chassis_num;  /* 1 based Chassis number                          */
+                                   /* For LookOut WPEGs this field indicates the      */
+                                   /* Expansion Chassis #, enumerated from Boot       */
+                                   /* Node WPEG external port, then Boot Node CYC     */
+                                   /* external port, then Next Vigil chassis WPEG     */
+                                   /* external port, etc.                             */
+                                   /* Shared Lookouts have only 1 chassis number (the */
+                                   /* first one assigned)                             */
+} __attribute__((packed));
+
+
+typedef enum {
+       CompatTwister = 0,  /* Compatibility Twister               */
+       AltTwister    = 1,  /* Alternate Twister of internal 8-way */
+       CompatCyclone = 2,  /* Compatibility Cyclone               */
+       AltCyclone    = 3,  /* Alternate Cyclone of internal 8-way */
+       CompatWPEG    = 4,  /* Compatibility WPEG                  */
+       AltWPEG       = 5,  /* Second Planar WPEG                  */
+       LookOutAWPEG  = 6,  /* LookOut WPEG                        */
+       LookOutBWPEG  = 7,  /* LookOut WPEG                        */
+} node_type;
+
+static inline int is_WPEG(struct rio_detail *rio){
+       return (rio->type == CompatWPEG || rio->type == AltWPEG ||
+               rio->type == LookOutAWPEG || rio->type == LookOutBWPEG);
+}
+
+
+/* In clustered mode, the high nibble of APIC ID is a cluster number.
+ * The low nibble is a 4-bit bitmap. */
+#define XAPIC_DEST_CPUS_SHIFT  4
+#define XAPIC_DEST_CPUS_MASK   ((1u << XAPIC_DEST_CPUS_SHIFT) - 1)
+#define XAPIC_DEST_CLUSTER_MASK        (XAPIC_DEST_CPUS_MASK << XAPIC_DEST_CPUS_SHIFT)
+
+#define SUMMIT_APIC_DFR_VALUE  (APIC_DFR_CLUSTER)
+
+static inline const cpumask_t *summit_target_cpus(void)
+{
+       /* CPU_MASK_ALL (0xff) has undefined behaviour with
+        * dest_LowestPrio mode logical clustered apic interrupt routing
+        * Just start on cpu 0.  IRQ balancing will spread load
+        */
+       return &cpumask_of_cpu(0);
+}
+
+static inline unsigned long
+summit_check_apicid_used(physid_mask_t bitmap, int apicid)
+{
+       return 0;
+}
+
+/* we don't use the phys_cpu_present_map to indicate apicid presence */
+static inline unsigned long summit_check_apicid_present(int bit)
+{
+       return 1;
+}
+
+static inline void summit_init_apic_ldr(void)
+{
+       unsigned long val, id;
+       int count = 0;
+       u8 my_id = (u8)hard_smp_processor_id();
+       u8 my_cluster = APIC_CLUSTER(my_id);
+#ifdef CONFIG_SMP
+       u8 lid;
+       int i;
+
+       /* Create logical APIC IDs by counting CPUs already in cluster. */
+       for (count = 0, i = nr_cpu_ids; --i >= 0; ) {
+               lid = cpu_2_logical_apicid[i];
+               if (lid != BAD_APICID && APIC_CLUSTER(lid) == my_cluster)
+                       ++count;
+       }
+#endif
+       /* We only have a 4 wide bitmap in cluster mode.  If a deranged
+        * BIOS puts 5 CPUs in one APIC cluster, we're hosed. */
+       BUG_ON(count >= XAPIC_DEST_CPUS_SHIFT);
+       id = my_cluster | (1UL << count);
+       apic_write(APIC_DFR, SUMMIT_APIC_DFR_VALUE);
+       val = apic_read(APIC_LDR) & ~APIC_LDR_MASK;
+       val |= SET_APIC_LOGICAL_ID(id);
+       apic_write(APIC_LDR, val);
+}
+
+static inline int summit_apic_id_registered(void)
+{
+       return 1;
+}
+
+static inline void summit_setup_apic_routing(void)
+{
+       printk("Enabling APIC mode:  Summit.  Using %d I/O APICs\n",
+                                               nr_ioapics);
+}
+
+static inline int summit_apicid_to_node(int logical_apicid)
+{
+#ifdef CONFIG_SMP
+       return apicid_2_node[hard_smp_processor_id()];
+#else
+       return 0;
+#endif
+}
+
+/* Mapping from cpu number to logical apicid */
+static inline int summit_cpu_to_logical_apicid(int cpu)
+{
+#ifdef CONFIG_SMP
+       if (cpu >= nr_cpu_ids)
+               return BAD_APICID;
+       return cpu_2_logical_apicid[cpu];
+#else
+       return logical_smp_processor_id();
+#endif
+}
+
+static inline int summit_cpu_present_to_apicid(int mps_cpu)
+{
+       if (mps_cpu < nr_cpu_ids)
+               return (int)per_cpu(x86_bios_cpu_apicid, mps_cpu);
+       else
+               return BAD_APICID;
+}
+
+static inline physid_mask_t
+summit_ioapic_phys_id_map(physid_mask_t phys_id_map)
+{
+       /* For clustered we don't have a good way to do this yet - hack */
+       return physids_promote(0x0F);
+}
+
+static inline physid_mask_t summit_apicid_to_cpu_present(int apicid)
+{
+       return physid_mask_of_physid(0);
+}
+
+static inline void summit_setup_portio_remap(void)
+{
+}
+
+static inline int summit_check_phys_apicid_present(int boot_cpu_physical_apicid)
+{
+       return 1;
+}
+
+static inline unsigned int summit_cpu_mask_to_apicid(const cpumask_t *cpumask)
+{
+       int cpus_found = 0;
+       int num_bits_set;
+       int apicid;
+       int cpu;
+
+       num_bits_set = cpus_weight(*cpumask);
+       /* Return id to all */
+       if (num_bits_set >= nr_cpu_ids)
+               return 0xFF;
+       /*
+        * The cpus in the mask must all be on the apic cluster.  If are not
+        * on the same apicid cluster return default value of target_cpus():
+        */
+       cpu = first_cpu(*cpumask);
+       apicid = summit_cpu_to_logical_apicid(cpu);
+
+       while (cpus_found < num_bits_set) {
+               if (cpu_isset(cpu, *cpumask)) {
+                       int new_apicid = summit_cpu_to_logical_apicid(cpu);
+
+                       if (APIC_CLUSTER(apicid) != APIC_CLUSTER(new_apicid)) {
+                               printk ("%s: Not a valid mask!\n", __func__);
+
+                               return 0xFF;
+                       }
+                       apicid = apicid | new_apicid;
+                       cpus_found++;
+               }
+               cpu++;
+       }
+       return apicid;
+}
+
+static inline unsigned int
+summit_cpu_mask_to_apicid_and(const struct cpumask *inmask,
+                             const struct cpumask *andmask)
+{
+       int apicid = summit_cpu_to_logical_apicid(0);
+       cpumask_var_t cpumask;
+
+       if (!alloc_cpumask_var(&cpumask, GFP_ATOMIC))
+               return apicid;
+
+       cpumask_and(cpumask, inmask, andmask);
+       cpumask_and(cpumask, cpumask, cpu_online_mask);
+       apicid = summit_cpu_mask_to_apicid(cpumask);
+
+       free_cpumask_var(cpumask);
+
+       return apicid;
+}
+
+/*
+ * cpuid returns the value latched in the HW at reset, not the APIC ID
+ * register's value.  For any box whose BIOS changes APIC IDs, like
+ * clustered APIC systems, we must use hard_smp_processor_id.
+ *
+ * See Intel's IA-32 SW Dev's Manual Vol2 under CPUID.
+ */
+static inline int summit_phys_pkg_id(int cpuid_apic, int index_msb)
+{
+       return hard_smp_processor_id() >> index_msb;
+}
+
+static int probe_summit(void)
+{
+       /* probed later in mptable/ACPI hooks */
+       return 0;
+}
+
+static void summit_vector_allocation_domain(int cpu, cpumask_t *retmask)
+{
+       /* Careful. Some cpus do not strictly honor the set of cpus
+        * specified in the interrupt destination when using lowest
+        * priority interrupt delivery mode.
+        *
+        * In particular there was a hyperthreading cpu observed to
+        * deliver interrupts to the wrong hyperthread when only one
+        * hyperthread was specified in the interrupt desitination.
+        */
+       *retmask = (cpumask_t){ { [0] = APIC_ALL_CPUS, } };
+}
+
+#ifdef CONFIG_X86_SUMMIT_NUMA
+static struct rio_table_hdr *rio_table_hdr __initdata;
+static struct scal_detail   *scal_devs[MAX_NUMNODES] __initdata;
+static struct rio_detail    *rio_devs[MAX_NUMNODES*4] __initdata;
+
+#ifndef CONFIG_X86_NUMAQ
+static int mp_bus_id_to_node[MAX_MP_BUSSES] __initdata;
+#endif
+
+static int __init setup_pci_node_map_for_wpeg(int wpeg_num, int last_bus)
+{
+       int twister = 0, node = 0;
+       int i, bus, num_buses;
+
+       for (i = 0; i < rio_table_hdr->num_rio_dev; i++) {
+               if (rio_devs[i]->node_id == rio_devs[wpeg_num]->owner_id) {
+                       twister = rio_devs[i]->owner_id;
+                       break;
+               }
+       }
+       if (i == rio_table_hdr->num_rio_dev) {
+               printk(KERN_ERR "%s: Couldn't find owner Cyclone for Winnipeg!\n", __func__);
+               return last_bus;
+       }
+
+       for (i = 0; i < rio_table_hdr->num_scal_dev; i++) {
+               if (scal_devs[i]->node_id == twister) {
+                       node = scal_devs[i]->node_id;
+                       break;
+               }
+       }
+       if (i == rio_table_hdr->num_scal_dev) {
+               printk(KERN_ERR "%s: Couldn't find owner Twister for Cyclone!\n", __func__);
+               return last_bus;
+       }
+
+       switch (rio_devs[wpeg_num]->type) {
+       case CompatWPEG:
+               /*
+                * The Compatibility Winnipeg controls the 2 legacy buses,
+                * the 66MHz PCI bus [2 slots] and the 2 "extra" buses in case
+                * a PCI-PCI bridge card is used in either slot: total 5 buses.
+                */
+               num_buses = 5;
+               break;
+       case AltWPEG:
+               /*
+                * The Alternate Winnipeg controls the 2 133MHz buses [1 slot
+                * each], their 2 "extra" buses, the 100MHz bus [2 slots] and
+                * the "extra" buses for each of those slots: total 7 buses.
+                */
+               num_buses = 7;
+               break;
+       case LookOutAWPEG:
+       case LookOutBWPEG:
+               /*
+                * A Lookout Winnipeg controls 3 100MHz buses [2 slots each]
+                * & the "extra" buses for each of those slots: total 9 buses.
+                */
+               num_buses = 9;
+               break;
+       default:
+               printk(KERN_INFO "%s: Unsupported Winnipeg type!\n", __func__);
+               return last_bus;
+       }
+
+       for (bus = last_bus; bus < last_bus + num_buses; bus++)
+               mp_bus_id_to_node[bus] = node;
+       return bus;
+}
+
+static int __init build_detail_arrays(void)
+{
+       unsigned long ptr;
+       int i, scal_detail_size, rio_detail_size;
+
+       if (rio_table_hdr->num_scal_dev > MAX_NUMNODES) {
+               printk(KERN_WARNING "%s: MAX_NUMNODES too low!  Defined as %d, but system has %d nodes.\n", __func__, MAX_NUMNODES, rio_table_hdr->num_scal_dev);
+               return 0;
+       }
+
+       switch (rio_table_hdr->version) {
+       default:
+               printk(KERN_WARNING "%s: Invalid Rio Grande Table Version: %d\n", __func__, rio_table_hdr->version);
+               return 0;
+       case 2:
+               scal_detail_size = 11;
+               rio_detail_size = 13;
+               break;
+       case 3:
+               scal_detail_size = 12;
+               rio_detail_size = 15;
+               break;
+       }
+
+       ptr = (unsigned long)rio_table_hdr + 3;
+       for (i = 0; i < rio_table_hdr->num_scal_dev; i++, ptr += scal_detail_size)
+               scal_devs[i] = (struct scal_detail *)ptr;
+
+       for (i = 0; i < rio_table_hdr->num_rio_dev; i++, ptr += rio_detail_size)
+               rio_devs[i] = (struct rio_detail *)ptr;
+
+       return 1;
+}
+
+void __init setup_summit(void)
+{
+       unsigned long           ptr;
+       unsigned short          offset;
+       int                     i, next_wpeg, next_bus = 0;
+
+       /* The pointer to the EBDA is stored in the word @ phys 0x40E(40:0E) */
+       ptr = get_bios_ebda();
+       ptr = (unsigned long)phys_to_virt(ptr);
+
+       rio_table_hdr = NULL;
+       offset = 0x180;
+       while (offset) {
+               /* The block id is stored in the 2nd word */
+               if (*((unsigned short *)(ptr + offset + 2)) == 0x4752) {
+                       /* set the pointer past the offset & block id */
+                       rio_table_hdr = (struct rio_table_hdr *)(ptr + offset + 4);
+                       break;
+               }
+               /* The next offset is stored in the 1st word.  0 means no more */
+               offset = *((unsigned short *)(ptr + offset));
+       }
+       if (!rio_table_hdr) {
+               printk(KERN_ERR "%s: Unable to locate Rio Grande Table in EBDA - bailing!\n", __func__);
+               return;
+       }
+
+       if (!build_detail_arrays())
+               return;
+
+       /* The first Winnipeg we're looking for has an index of 0 */
+       next_wpeg = 0;
+       do {
+               for (i = 0; i < rio_table_hdr->num_rio_dev; i++) {
+                       if (is_WPEG(rio_devs[i]) && rio_devs[i]->WP_index == next_wpeg) {
+                               /* It's the Winnipeg we're looking for! */
+                               next_bus = setup_pci_node_map_for_wpeg(i, next_bus);
+                               next_wpeg++;
+                               break;
+                       }
+               }
+               /*
+                * If we go through all Rio devices and don't find one with
+                * the next index, it means we've found all the Winnipegs,
+                * and thus all the PCI buses.
+                */
+               if (i == rio_table_hdr->num_rio_dev)
+                       next_wpeg = 0;
+       } while (next_wpeg != 0);
+}
+#endif
+
+struct apic apic_summit = {
+
+       .name                           = "summit",
+       .probe                          = probe_summit,
+       .acpi_madt_oem_check            = summit_acpi_madt_oem_check,
+       .apic_id_registered             = summit_apic_id_registered,
+
+       .irq_delivery_mode              = dest_LowestPrio,
+       /* logical delivery broadcast to all CPUs: */
+       .irq_dest_mode                  = 1,
+
+       .target_cpus                    = summit_target_cpus,
+       .disable_esr                    = 1,
+       .dest_logical                   = APIC_DEST_LOGICAL,
+       .check_apicid_used              = summit_check_apicid_used,
+       .check_apicid_present           = summit_check_apicid_present,
+
+       .vector_allocation_domain       = summit_vector_allocation_domain,
+       .init_apic_ldr                  = summit_init_apic_ldr,
+
+       .ioapic_phys_id_map             = summit_ioapic_phys_id_map,
+       .setup_apic_routing             = summit_setup_apic_routing,
+       .multi_timer_check              = NULL,
+       .apicid_to_node                 = summit_apicid_to_node,
+       .cpu_to_logical_apicid          = summit_cpu_to_logical_apicid,
+       .cpu_present_to_apicid          = summit_cpu_present_to_apicid,
+       .apicid_to_cpu_present          = summit_apicid_to_cpu_present,
+       .setup_portio_remap             = NULL,
+       .check_phys_apicid_present      = summit_check_phys_apicid_present,
+       .enable_apic_mode               = NULL,
+       .phys_pkg_id                    = summit_phys_pkg_id,
+       .mps_oem_check                  = summit_mps_oem_check,
+
+       .get_apic_id                    = summit_get_apic_id,
+       .set_apic_id                    = NULL,
+       .apic_id_mask                   = 0xFF << 24,
+
+       .cpu_mask_to_apicid             = summit_cpu_mask_to_apicid,
+       .cpu_mask_to_apicid_and         = summit_cpu_mask_to_apicid_and,
+
+       .send_IPI_mask                  = summit_send_IPI_mask,
+       .send_IPI_mask_allbutself       = NULL,
+       .send_IPI_allbutself            = summit_send_IPI_allbutself,
+       .send_IPI_all                   = summit_send_IPI_all,
+       .send_IPI_self                  = default_send_IPI_self,
+
+       .wakeup_cpu                     = NULL,
+       .trampoline_phys_low            = DEFAULT_TRAMPOLINE_PHYS_LOW,
+       .trampoline_phys_high           = DEFAULT_TRAMPOLINE_PHYS_HIGH,
+
+       .wait_for_init_deassert         = default_wait_for_init_deassert,
+
+       .smp_callin_clear_local_apic    = NULL,
+       .inquire_remote_apic            = default_inquire_remote_apic,
+
+       .read                           = native_apic_mem_read,
+       .write                          = native_apic_mem_write,
+       .icr_read                       = native_apic_icr_read,
+       .icr_write                      = native_apic_icr_write,
+       .wait_icr_idle                  = native_apic_wait_icr_idle,
+       .safe_wait_icr_idle             = native_safe_apic_wait_icr_idle,
+};
diff --git a/arch/x86/kernel/bigsmp_32.c b/arch/x86/kernel/bigsmp_32.c
deleted file mode 100644 (file)
index 0b10933..0000000
+++ /dev/null
@@ -1,274 +0,0 @@
-/*
- * APIC driver for "bigsmp" xAPIC machines with more than 8 virtual CPUs.
- *
- * Drives the local APIC in "clustered mode".
- */
-#include <linux/threads.h>
-#include <linux/cpumask.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/dmi.h>
-#include <linux/smp.h>
-
-#include <asm/apicdef.h>
-#include <asm/fixmap.h>
-#include <asm/mpspec.h>
-#include <asm/apic.h>
-#include <asm/ipi.h>
-
-static inline unsigned bigsmp_get_apic_id(unsigned long x)
-{
-       return (x >> 24) & 0xFF;
-}
-
-static inline int bigsmp_apic_id_registered(void)
-{
-       return 1;
-}
-
-static inline const cpumask_t *bigsmp_target_cpus(void)
-{
-#ifdef CONFIG_SMP
-       return &cpu_online_map;
-#else
-       return &cpumask_of_cpu(0);
-#endif
-}
-
-static inline unsigned long
-bigsmp_check_apicid_used(physid_mask_t bitmap, int apicid)
-{
-       return 0;
-}
-
-static inline unsigned long bigsmp_check_apicid_present(int bit)
-{
-       return 1;
-}
-
-static inline unsigned long calculate_ldr(int cpu)
-{
-       unsigned long val, id;
-
-       val = apic_read(APIC_LDR) & ~APIC_LDR_MASK;
-       id = per_cpu(x86_bios_cpu_apicid, cpu);
-       val |= SET_APIC_LOGICAL_ID(id);
-
-       return val;
-}
-
-/*
- * Set up the logical destination ID.
- *
- * Intel recommends to set DFR, LDR and TPR before enabling
- * an APIC.  See e.g. "AP-388 82489DX User's Manual" (Intel
- * document number 292116).  So here it goes...
- */
-static inline void bigsmp_init_apic_ldr(void)
-{
-       unsigned long val;
-       int cpu = smp_processor_id();
-
-       apic_write(APIC_DFR, APIC_DFR_FLAT);
-       val = calculate_ldr(cpu);
-       apic_write(APIC_LDR, val);
-}
-
-static inline void bigsmp_setup_apic_routing(void)
-{
-       printk(KERN_INFO
-               "Enabling APIC mode:  Physflat.  Using %d I/O APICs\n",
-               nr_ioapics);
-}
-
-static inline int bigsmp_apicid_to_node(int logical_apicid)
-{
-       return apicid_2_node[hard_smp_processor_id()];
-}
-
-static inline int bigsmp_cpu_present_to_apicid(int mps_cpu)
-{
-       if (mps_cpu < nr_cpu_ids)
-               return (int) per_cpu(x86_bios_cpu_apicid, mps_cpu);
-
-       return BAD_APICID;
-}
-
-static inline physid_mask_t bigsmp_apicid_to_cpu_present(int phys_apicid)
-{
-       return physid_mask_of_physid(phys_apicid);
-}
-
-/* Mapping from cpu number to logical apicid */
-static inline int bigsmp_cpu_to_logical_apicid(int cpu)
-{
-       if (cpu >= nr_cpu_ids)
-               return BAD_APICID;
-       return cpu_physical_id(cpu);
-}
-
-static inline physid_mask_t bigsmp_ioapic_phys_id_map(physid_mask_t phys_map)
-{
-       /* For clustered we don't have a good way to do this yet - hack */
-       return physids_promote(0xFFL);
-}
-
-static inline void bigsmp_setup_portio_remap(void)
-{
-}
-
-static inline int bigsmp_check_phys_apicid_present(int boot_cpu_physical_apicid)
-{
-       return 1;
-}
-
-/* As we are using single CPU as destination, pick only one CPU here */
-static inline unsigned int bigsmp_cpu_mask_to_apicid(const cpumask_t *cpumask)
-{
-       return bigsmp_cpu_to_logical_apicid(first_cpu(*cpumask));
-}
-
-static inline unsigned int
-bigsmp_cpu_mask_to_apicid_and(const struct cpumask *cpumask,
-                             const struct cpumask *andmask)
-{
-       int cpu;
-
-       /*
-        * We're using fixed IRQ delivery, can only return one phys APIC ID.
-        * May as well be the first.
-        */
-       for_each_cpu_and(cpu, cpumask, andmask) {
-               if (cpumask_test_cpu(cpu, cpu_online_mask))
-                       break;
-       }
-       if (cpu < nr_cpu_ids)
-               return bigsmp_cpu_to_logical_apicid(cpu);
-
-       return BAD_APICID;
-}
-
-static inline int bigsmp_phys_pkg_id(int cpuid_apic, int index_msb)
-{
-       return cpuid_apic >> index_msb;
-}
-
-static inline void bigsmp_send_IPI_mask(const struct cpumask *mask, int vector)
-{
-       default_send_IPI_mask_sequence_phys(mask, vector);
-}
-
-static inline void bigsmp_send_IPI_allbutself(int vector)
-{
-       default_send_IPI_mask_allbutself_phys(cpu_online_mask, vector);
-}
-
-static inline void bigsmp_send_IPI_all(int vector)
-{
-       bigsmp_send_IPI_mask(cpu_online_mask, vector);
-}
-
-static int dmi_bigsmp; /* can be set by dmi scanners */
-
-static int hp_ht_bigsmp(const struct dmi_system_id *d)
-{
-       printk(KERN_NOTICE "%s detected: force use of apic=bigsmp\n", d->ident);
-       dmi_bigsmp = 1;
-
-       return 0;
-}
-
-
-static const struct dmi_system_id bigsmp_dmi_table[] = {
-       { hp_ht_bigsmp, "HP ProLiant DL760 G2",
-               {       DMI_MATCH(DMI_BIOS_VENDOR, "HP"),
-                       DMI_MATCH(DMI_BIOS_VERSION, "P44-"),
-               }
-       },
-
-       { hp_ht_bigsmp, "HP ProLiant DL740",
-               {       DMI_MATCH(DMI_BIOS_VENDOR, "HP"),
-                       DMI_MATCH(DMI_BIOS_VERSION, "P47-"),
-               }
-       },
-       { } /* NULL entry stops DMI scanning */
-};
-
-static void bigsmp_vector_allocation_domain(int cpu, cpumask_t *retmask)
-{
-       cpus_clear(*retmask);
-       cpu_set(cpu, *retmask);
-}
-
-static int probe_bigsmp(void)
-{
-       if (def_to_bigsmp)
-               dmi_bigsmp = 1;
-       else
-               dmi_check_system(bigsmp_dmi_table);
-
-       return dmi_bigsmp;
-}
-
-struct apic apic_bigsmp = {
-
-       .name                           = "bigsmp",
-       .probe                          = probe_bigsmp,
-       .acpi_madt_oem_check            = NULL,
-       .apic_id_registered             = bigsmp_apic_id_registered,
-
-       .irq_delivery_mode              = dest_Fixed,
-       /* phys delivery to target CPU: */
-       .irq_dest_mode                  = 0,
-
-       .target_cpus                    = bigsmp_target_cpus,
-       .disable_esr                    = 1,
-       .dest_logical                   = 0,
-       .check_apicid_used              = bigsmp_check_apicid_used,
-       .check_apicid_present           = bigsmp_check_apicid_present,
-
-       .vector_allocation_domain       = bigsmp_vector_allocation_domain,
-       .init_apic_ldr                  = bigsmp_init_apic_ldr,
-
-       .ioapic_phys_id_map             = bigsmp_ioapic_phys_id_map,
-       .setup_apic_routing             = bigsmp_setup_apic_routing,
-       .multi_timer_check              = NULL,
-       .apicid_to_node                 = bigsmp_apicid_to_node,
-       .cpu_to_logical_apicid          = bigsmp_cpu_to_logical_apicid,
-       .cpu_present_to_apicid          = bigsmp_cpu_present_to_apicid,
-       .apicid_to_cpu_present          = bigsmp_apicid_to_cpu_present,
-       .setup_portio_remap             = NULL,
-       .check_phys_apicid_present      = bigsmp_check_phys_apicid_present,
-       .enable_apic_mode               = NULL,
-       .phys_pkg_id                    = bigsmp_phys_pkg_id,
-       .mps_oem_check                  = NULL,
-
-       .get_apic_id                    = bigsmp_get_apic_id,
-       .set_apic_id                    = NULL,
-       .apic_id_mask                   = 0xFF << 24,
-
-       .cpu_mask_to_apicid             = bigsmp_cpu_mask_to_apicid,
-       .cpu_mask_to_apicid_and         = bigsmp_cpu_mask_to_apicid_and,
-
-       .send_IPI_mask                  = bigsmp_send_IPI_mask,
-       .send_IPI_mask_allbutself       = NULL,
-       .send_IPI_allbutself            = bigsmp_send_IPI_allbutself,
-       .send_IPI_all                   = bigsmp_send_IPI_all,
-       .send_IPI_self                  = default_send_IPI_self,
-
-       .wakeup_cpu                     = NULL,
-       .trampoline_phys_low            = DEFAULT_TRAMPOLINE_PHYS_LOW,
-       .trampoline_phys_high           = DEFAULT_TRAMPOLINE_PHYS_HIGH,
-
-       .wait_for_init_deassert         = default_wait_for_init_deassert,
-
-       .smp_callin_clear_local_apic    = NULL,
-       .inquire_remote_apic            = default_inquire_remote_apic,
-
-       .read                           = native_apic_mem_read,
-       .write                          = native_apic_mem_write,
-       .icr_read                       = native_apic_icr_read,
-       .icr_write                      = native_apic_icr_write,
-       .wait_icr_idle                  = native_apic_wait_icr_idle,
-       .safe_wait_icr_idle             = native_safe_apic_wait_icr_idle,
-};
diff --git a/arch/x86/kernel/es7000_32.c b/arch/x86/kernel/es7000_32.c
deleted file mode 100644 (file)
index 320f2d2..0000000
+++ /dev/null
@@ -1,757 +0,0 @@
-/*
- * Written by: Garry Forsgren, Unisys Corporation
- *             Natalie Protasevich, Unisys Corporation
- *
- * This file contains the code to configure and interface
- * with Unisys ES7000 series hardware system manager.
- *
- * Copyright (c) 2003 Unisys Corporation.
- * Copyright (C) 2009, Red Hat, Inc., Ingo Molnar
- *
- *   All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * Contact information: Unisys Corporation, Township Line & Union Meeting
- * Roads-A, Unisys Way, Blue Bell, Pennsylvania, 19424, or:
- *
- * http://www.unisys.com
- */
-#include <linux/notifier.h>
-#include <linux/spinlock.h>
-#include <linux/cpumask.h>
-#include <linux/threads.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/reboot.h>
-#include <linux/string.h>
-#include <linux/types.h>
-#include <linux/errno.h>
-#include <linux/acpi.h>
-#include <linux/init.h>
-#include <linux/nmi.h>
-#include <linux/smp.h>
-#include <linux/io.h>
-
-#include <asm/apicdef.h>
-#include <asm/atomic.h>
-#include <asm/fixmap.h>
-#include <asm/mpspec.h>
-#include <asm/setup.h>
-#include <asm/apic.h>
-#include <asm/ipi.h>
-
-/*
- * ES7000 chipsets
- */
-
-#define NON_UNISYS                     0
-#define ES7000_CLASSIC                 1
-#define ES7000_ZORRO                   2
-
-#define        MIP_REG                         1
-#define        MIP_PSAI_REG                    4
-
-#define        MIP_BUSY                        1
-#define        MIP_SPIN                        0xf0000
-#define        MIP_VALID                       0x0100000000000000ULL
-#define        MIP_SW_APIC                     0x1020b
-
-#define        MIP_PORT(val)                   ((val >> 32) & 0xffff)
-
-#define        MIP_RD_LO(val)                  (val & 0xffffffff)
-
-struct mip_reg {
-       unsigned long long              off_0x00;
-       unsigned long long              off_0x08;
-       unsigned long long              off_0x10;
-       unsigned long long              off_0x18;
-       unsigned long long              off_0x20;
-       unsigned long long              off_0x28;
-       unsigned long long              off_0x30;
-       unsigned long long              off_0x38;
-};
-
-struct mip_reg_info {
-       unsigned long long              mip_info;
-       unsigned long long              delivery_info;
-       unsigned long long              host_reg;
-       unsigned long long              mip_reg;
-};
-
-struct psai {
-       unsigned long long              entry_type;
-       unsigned long long              addr;
-       unsigned long long              bep_addr;
-};
-
-#ifdef CONFIG_ACPI
-
-struct es7000_oem_table {
-       struct acpi_table_header        Header;
-       u32                             OEMTableAddr;
-       u32                             OEMTableSize;
-};
-
-static unsigned long                   oem_addrX;
-static unsigned long                   oem_size;
-
-#endif
-
-/*
- * ES7000 Globals
- */
-
-static volatile unsigned long          *psai;
-static struct mip_reg                  *mip_reg;
-static struct mip_reg                  *host_reg;
-static int                             mip_port;
-static unsigned long                   mip_addr;
-static unsigned long                   host_addr;
-
-int                                    es7000_plat;
-
-/*
- * GSI override for ES7000 platforms.
- */
-
-static unsigned int                    base;
-
-static int
-es7000_rename_gsi(int ioapic, int gsi)
-{
-       if (es7000_plat == ES7000_ZORRO)
-               return gsi;
-
-       if (!base) {
-               int i;
-               for (i = 0; i < nr_ioapics; i++)
-                       base += nr_ioapic_registers[i];
-       }
-
-       if (!ioapic && (gsi < 16))
-               gsi += base;
-
-       return gsi;
-}
-
-static int wakeup_secondary_cpu_via_mip(int cpu, unsigned long eip)
-{
-       unsigned long vect = 0, psaival = 0;
-
-       if (psai == NULL)
-               return -1;
-
-       vect = ((unsigned long)__pa(eip)/0x1000) << 16;
-       psaival = (0x1000000 | vect | cpu);
-
-       while (*psai & 0x1000000)
-               ;
-
-       *psai = psaival;
-
-       return 0;
-}
-
-static int __init es7000_update_apic(void)
-{
-       apic->wakeup_cpu = wakeup_secondary_cpu_via_mip;
-
-       /* MPENTIUMIII */
-       if (boot_cpu_data.x86 == 6 &&
-           (boot_cpu_data.x86_model >= 7 || boot_cpu_data.x86_model <= 11)) {
-               es7000_update_apic_to_cluster();
-               apic->wait_for_init_deassert = NULL;
-               apic->wakeup_cpu = wakeup_secondary_cpu_via_mip;
-       }
-
-       return 0;
-}
-
-static void __init setup_unisys(void)
-{
-       /*
-        * Determine the generation of the ES7000 currently running.
-        *
-        * es7000_plat = 1 if the machine is a 5xx ES7000 box
-        * es7000_plat = 2 if the machine is a x86_64 ES7000 box
-        *
-        */
-       if (!(boot_cpu_data.x86 <= 15 && boot_cpu_data.x86_model <= 2))
-               es7000_plat = ES7000_ZORRO;
-       else
-               es7000_plat = ES7000_CLASSIC;
-       ioapic_renumber_irq = es7000_rename_gsi;
-
-       x86_quirks->update_apic = es7000_update_apic;
-}
-
-/*
- * Parse the OEM Table:
- */
-static int __init parse_unisys_oem(char *oemptr)
-{
-       int                     i;
-       int                     success = 0;
-       unsigned char           type, size;
-       unsigned long           val;
-       char                    *tp = NULL;
-       struct psai             *psaip = NULL;
-       struct mip_reg_info     *mi;
-       struct mip_reg          *host, *mip;
-
-       tp = oemptr;
-
-       tp += 8;
-
-       for (i = 0; i <= 6; i++) {
-               type = *tp++;
-               size = *tp++;
-               tp -= 2;
-               switch (type) {
-               case MIP_REG:
-                       mi = (struct mip_reg_info *)tp;
-                       val = MIP_RD_LO(mi->host_reg);
-                       host_addr = val;
-                       host = (struct mip_reg *)val;
-                       host_reg = __va(host);
-                       val = MIP_RD_LO(mi->mip_reg);
-                       mip_port = MIP_PORT(mi->mip_info);
-                       mip_addr = val;
-                       mip = (struct mip_reg *)val;
-                       mip_reg = __va(mip);
-                       pr_debug("es7000_mipcfg: host_reg = 0x%lx \n",
-                                (unsigned long)host_reg);
-                       pr_debug("es7000_mipcfg: mip_reg = 0x%lx \n",
-                                (unsigned long)mip_reg);
-                       success++;
-                       break;
-               case MIP_PSAI_REG:
-                       psaip = (struct psai *)tp;
-                       if (tp != NULL) {
-                               if (psaip->addr)
-                                       psai = __va(psaip->addr);
-                               else
-                                       psai = NULL;
-                               success++;
-                       }
-                       break;
-               default:
-                       break;
-               }
-               tp += size;
-       }
-
-       if (success < 2)
-               es7000_plat = NON_UNISYS;
-       else
-               setup_unisys();
-
-       return es7000_plat;
-}
-
-#ifdef CONFIG_ACPI
-static int __init find_unisys_acpi_oem_table(unsigned long *oem_addr)
-{
-       struct acpi_table_header *header = NULL;
-       struct es7000_oem_table *table;
-       acpi_size tbl_size;
-       acpi_status ret;
-       int i = 0;
-
-       for (;;) {
-               ret = acpi_get_table_with_size("OEM1", i++, &header, &tbl_size);
-               if (!ACPI_SUCCESS(ret))
-                       return -1;
-
-               if (!memcmp((char *) &header->oem_id, "UNISYS", 6))
-                       break;
-
-               early_acpi_os_unmap_memory(header, tbl_size);
-       }
-
-       table = (void *)header;
-
-       oem_addrX       = table->OEMTableAddr;
-       oem_size        = table->OEMTableSize;
-
-       early_acpi_os_unmap_memory(header, tbl_size);
-
-       *oem_addr       = (unsigned long)__acpi_map_table(oem_addrX, oem_size);
-
-       return 0;
-}
-
-static void __init unmap_unisys_acpi_oem_table(unsigned long oem_addr)
-{
-       if (!oem_addr)
-               return;
-
-       __acpi_unmap_table((char *)oem_addr, oem_size);
-}
-
-static int es7000_check_dsdt(void)
-{
-       struct acpi_table_header header;
-
-       if (ACPI_SUCCESS(acpi_get_table_header(ACPI_SIG_DSDT, 0, &header)) &&
-           !strncmp(header.oem_id, "UNISYS", 6))
-               return 1;
-       return 0;
-}
-
-/* Hook from generic ACPI tables.c */
-static int __init es7000_acpi_madt_oem_check(char *oem_id, char *oem_table_id)
-{
-       unsigned long oem_addr = 0;
-       int check_dsdt;
-       int ret = 0;
-
-       /* check dsdt at first to avoid clear fix_map for oem_addr */
-       check_dsdt = es7000_check_dsdt();
-
-       if (!find_unisys_acpi_oem_table(&oem_addr)) {
-               if (check_dsdt) {
-                       ret = parse_unisys_oem((char *)oem_addr);
-               } else {
-                       setup_unisys();
-                       ret = 1;
-               }
-               /*
-                * we need to unmap it
-                */
-               unmap_unisys_acpi_oem_table(oem_addr);
-       }
-       return ret;
-}
-#else /* !CONFIG_ACPI: */
-static int __init es7000_acpi_madt_oem_check(char *oem_id, char *oem_table_id)
-{
-       return 0;
-}
-#endif /* !CONFIG_ACPI */
-
-static void es7000_spin(int n)
-{
-       int i = 0;
-
-       while (i++ < n)
-               rep_nop();
-}
-
-static int __init
-es7000_mip_write(struct mip_reg *mip_reg)
-{
-       int status = 0;
-       int spin;
-
-       spin = MIP_SPIN;
-       while ((host_reg->off_0x38 & MIP_VALID) != 0) {
-               if (--spin <= 0) {
-                       WARN(1, "Timeout waiting for Host Valid Flag\n");
-                       return -1;
-               }
-               es7000_spin(MIP_SPIN);
-       }
-
-       memcpy(host_reg, mip_reg, sizeof(struct mip_reg));
-       outb(1, mip_port);
-
-       spin = MIP_SPIN;
-
-       while ((mip_reg->off_0x38 & MIP_VALID) == 0) {
-               if (--spin <= 0) {
-                       WARN(1, "Timeout waiting for MIP Valid Flag\n");
-                       return -1;
-               }
-               es7000_spin(MIP_SPIN);
-       }
-
-       status = (mip_reg->off_0x00 & 0xffff0000000000ULL) >> 48;
-       mip_reg->off_0x38 &= ~MIP_VALID;
-
-       return status;
-}
-
-static void __init es7000_enable_apic_mode(void)
-{
-       struct mip_reg es7000_mip_reg;
-       int mip_status;
-
-       if (!es7000_plat)
-               return;
-
-       printk(KERN_INFO "ES7000: Enabling APIC mode.\n");
-       memset(&es7000_mip_reg, 0, sizeof(struct mip_reg));
-       es7000_mip_reg.off_0x00 = MIP_SW_APIC;
-       es7000_mip_reg.off_0x38 = MIP_VALID;
-
-       while ((mip_status = es7000_mip_write(&es7000_mip_reg)) != 0)
-               WARN(1, "Command failed, status = %x\n", mip_status);
-}
-
-static void es7000_vector_allocation_domain(int cpu, cpumask_t *retmask)
-{
-       /* Careful. Some cpus do not strictly honor the set of cpus
-        * specified in the interrupt destination when using lowest
-        * priority interrupt delivery mode.
-        *
-        * In particular there was a hyperthreading cpu observed to
-        * deliver interrupts to the wrong hyperthread when only one
-        * hyperthread was specified in the interrupt desitination.
-        */
-       *retmask = (cpumask_t){ { [0] = APIC_ALL_CPUS, } };
-}
-
-
-static void es7000_wait_for_init_deassert(atomic_t *deassert)
-{
-#ifndef CONFIG_ES7000_CLUSTERED_APIC
-       while (!atomic_read(deassert))
-               cpu_relax();
-#endif
-       return;
-}
-
-static unsigned int es7000_get_apic_id(unsigned long x)
-{
-       return (x >> 24) & 0xFF;
-}
-
-static void es7000_send_IPI_mask(const struct cpumask *mask, int vector)
-{
-       default_send_IPI_mask_sequence_phys(mask, vector);
-}
-
-static void es7000_send_IPI_allbutself(int vector)
-{
-       default_send_IPI_mask_allbutself_phys(cpu_online_mask, vector);
-}
-
-static void es7000_send_IPI_all(int vector)
-{
-       es7000_send_IPI_mask(cpu_online_mask, vector);
-}
-
-static int es7000_apic_id_registered(void)
-{
-       return 1;
-}
-
-static const cpumask_t *target_cpus_cluster(void)
-{
-       return &CPU_MASK_ALL;
-}
-
-static const cpumask_t *es7000_target_cpus(void)
-{
-       return &cpumask_of_cpu(smp_processor_id());
-}
-
-static unsigned long
-es7000_check_apicid_used(physid_mask_t bitmap, int apicid)
-{
-       return 0;
-}
-static unsigned long es7000_check_apicid_present(int bit)
-{
-       return physid_isset(bit, phys_cpu_present_map);
-}
-
-static unsigned long calculate_ldr(int cpu)
-{
-       unsigned long id = per_cpu(x86_bios_cpu_apicid, cpu);
-
-       return SET_APIC_LOGICAL_ID(id);
-}
-
-/*
- * Set up the logical destination ID.
- *
- * Intel recommends to set DFR, LdR and TPR before enabling
- * an APIC.  See e.g. "AP-388 82489DX User's Manual" (Intel
- * document number 292116).  So here it goes...
- */
-static void es7000_init_apic_ldr_cluster(void)
-{
-       unsigned long val;
-       int cpu = smp_processor_id();
-
-       apic_write(APIC_DFR, APIC_DFR_CLUSTER);
-       val = calculate_ldr(cpu);
-       apic_write(APIC_LDR, val);
-}
-
-static void es7000_init_apic_ldr(void)
-{
-       unsigned long val;
-       int cpu = smp_processor_id();
-
-       apic_write(APIC_DFR, APIC_DFR_FLAT);
-       val = calculate_ldr(cpu);
-       apic_write(APIC_LDR, val);
-}
-
-static void es7000_setup_apic_routing(void)
-{
-       int apic = per_cpu(x86_bios_cpu_apicid, smp_processor_id());
-
-       printk(KERN_INFO
-         "Enabling APIC mode:  %s. Using %d I/O APICs, target cpus %lx\n",
-               (apic_version[apic] == 0x14) ?
-                       "Physical Cluster" : "Logical Cluster",
-               nr_ioapics, cpus_addr(*es7000_target_cpus())[0]);
-}
-
-static int es7000_apicid_to_node(int logical_apicid)
-{
-       return 0;
-}
-
-
-static int es7000_cpu_present_to_apicid(int mps_cpu)
-{
-       if (!mps_cpu)
-               return boot_cpu_physical_apicid;
-       else if (mps_cpu < nr_cpu_ids)
-               return per_cpu(x86_bios_cpu_apicid, mps_cpu);
-       else
-               return BAD_APICID;
-}
-
-static int cpu_id;
-
-static physid_mask_t es7000_apicid_to_cpu_present(int phys_apicid)
-{
-       physid_mask_t mask;
-
-       mask = physid_mask_of_physid(cpu_id);
-       ++cpu_id;
-
-       return mask;
-}
-
-/* Mapping from cpu number to logical apicid */
-static int es7000_cpu_to_logical_apicid(int cpu)
-{
-#ifdef CONFIG_SMP
-       if (cpu >= nr_cpu_ids)
-               return BAD_APICID;
-       return cpu_2_logical_apicid[cpu];
-#else
-       return logical_smp_processor_id();
-#endif
-}
-
-static physid_mask_t es7000_ioapic_phys_id_map(physid_mask_t phys_map)
-{
-       /* For clustered we don't have a good way to do this yet - hack */
-       return physids_promote(0xff);
-}
-
-static int es7000_check_phys_apicid_present(int cpu_physical_apicid)
-{
-       boot_cpu_physical_apicid = read_apic_id();
-       return 1;
-}
-
-static unsigned int
-es7000_cpu_mask_to_apicid_cluster(const struct cpumask *cpumask)
-{
-       int cpus_found = 0;
-       int num_bits_set;
-       int apicid;
-       int cpu;
-
-       num_bits_set = cpumask_weight(cpumask);
-       /* Return id to all */
-       if (num_bits_set == nr_cpu_ids)
-               return 0xFF;
-       /*
-        * The cpus in the mask must all be on the apic cluster.  If are not
-        * on the same apicid cluster return default value of target_cpus():
-        */
-       cpu = cpumask_first(cpumask);
-       apicid = es7000_cpu_to_logical_apicid(cpu);
-
-       while (cpus_found < num_bits_set) {
-               if (cpumask_test_cpu(cpu, cpumask)) {
-                       int new_apicid = es7000_cpu_to_logical_apicid(cpu);
-
-                       if (APIC_CLUSTER(apicid) != APIC_CLUSTER(new_apicid)) {
-                               WARN(1, "Not a valid mask!");
-
-                               return 0xFF;
-                       }
-                       apicid = new_apicid;
-                       cpus_found++;
-               }
-               cpu++;
-       }
-       return apicid;
-}
-
-static unsigned int es7000_cpu_mask_to_apicid(const cpumask_t *cpumask)
-{
-       int cpus_found = 0;
-       int num_bits_set;
-       int apicid;
-       int cpu;
-
-       num_bits_set = cpus_weight(*cpumask);
-       /* Return id to all */
-       if (num_bits_set == nr_cpu_ids)
-               return es7000_cpu_to_logical_apicid(0);
-       /*
-        * The cpus in the mask must all be on the apic cluster.  If are not
-        * on the same apicid cluster return default value of target_cpus():
-        */
-       cpu = first_cpu(*cpumask);
-       apicid = es7000_cpu_to_logical_apicid(cpu);
-       while (cpus_found < num_bits_set) {
-               if (cpu_isset(cpu, *cpumask)) {
-                       int new_apicid = es7000_cpu_to_logical_apicid(cpu);
-
-                       if (APIC_CLUSTER(apicid) != APIC_CLUSTER(new_apicid)) {
-                               printk("%s: Not a valid mask!\n", __func__);
-
-                               return es7000_cpu_to_logical_apicid(0);
-                       }
-                       apicid = new_apicid;
-                       cpus_found++;
-               }
-               cpu++;
-       }
-       return apicid;
-}
-
-static unsigned int
-es7000_cpu_mask_to_apicid_and(const struct cpumask *inmask,
-                             const struct cpumask *andmask)
-{
-       int apicid = es7000_cpu_to_logical_apicid(0);
-       cpumask_var_t cpumask;
-
-       if (!alloc_cpumask_var(&cpumask, GFP_ATOMIC))
-               return apicid;
-
-       cpumask_and(cpumask, inmask, andmask);
-       cpumask_and(cpumask, cpumask, cpu_online_mask);
-       apicid = es7000_cpu_mask_to_apicid(cpumask);
-
-       free_cpumask_var(cpumask);
-
-       return apicid;
-}
-
-static int es7000_phys_pkg_id(int cpuid_apic, int index_msb)
-{
-       return cpuid_apic >> index_msb;
-}
-
-void __init es7000_update_apic_to_cluster(void)
-{
-       apic->target_cpus = target_cpus_cluster;
-       apic->irq_delivery_mode = dest_LowestPrio;
-       /* logical delivery broadcast to all procs: */
-       apic->irq_dest_mode = 1;
-
-       apic->init_apic_ldr = es7000_init_apic_ldr_cluster;
-
-       apic->cpu_mask_to_apicid = es7000_cpu_mask_to_apicid_cluster;
-}
-
-static int probe_es7000(void)
-{
-       /* probed later in mptable/ACPI hooks */
-       return 0;
-}
-
-static __init int
-es7000_mps_oem_check(struct mpc_table *mpc, char *oem, char *productid)
-{
-       if (mpc->oemptr) {
-               struct mpc_oemtable *oem_table =
-                       (struct mpc_oemtable *)mpc->oemptr;
-
-               if (!strncmp(oem, "UNISYS", 6))
-                       return parse_unisys_oem((char *)oem_table);
-       }
-       return 0;
-}
-
-
-struct apic apic_es7000 = {
-
-       .name                           = "es7000",
-       .probe                          = probe_es7000,
-       .acpi_madt_oem_check            = es7000_acpi_madt_oem_check,
-       .apic_id_registered             = es7000_apic_id_registered,
-
-       .irq_delivery_mode              = dest_Fixed,
-       /* phys delivery to target CPUs: */
-       .irq_dest_mode                  = 0,
-
-       .target_cpus                    = es7000_target_cpus,
-       .disable_esr                    = 1,
-       .dest_logical                   = 0,
-       .check_apicid_used              = es7000_check_apicid_used,
-       .check_apicid_present           = es7000_check_apicid_present,
-
-       .vector_allocation_domain       = es7000_vector_allocation_domain,
-       .init_apic_ldr                  = es7000_init_apic_ldr,
-
-       .ioapic_phys_id_map             = es7000_ioapic_phys_id_map,
-       .setup_apic_routing             = es7000_setup_apic_routing,
-       .multi_timer_check              = NULL,
-       .apicid_to_node                 = es7000_apicid_to_node,
-       .cpu_to_logical_apicid          = es7000_cpu_to_logical_apicid,
-       .cpu_present_to_apicid          = es7000_cpu_present_to_apicid,
-       .apicid_to_cpu_present          = es7000_apicid_to_cpu_present,
-       .setup_portio_remap             = NULL,
-       .check_phys_apicid_present      = es7000_check_phys_apicid_present,
-       .enable_apic_mode               = es7000_enable_apic_mode,
-       .phys_pkg_id                    = es7000_phys_pkg_id,
-       .mps_oem_check                  = es7000_mps_oem_check,
-
-       .get_apic_id                    = es7000_get_apic_id,
-       .set_apic_id                    = NULL,
-       .apic_id_mask                   = 0xFF << 24,
-
-       .cpu_mask_to_apicid             = es7000_cpu_mask_to_apicid,
-       .cpu_mask_to_apicid_and         = es7000_cpu_mask_to_apicid_and,
-
-       .send_IPI_mask                  = es7000_send_IPI_mask,
-       .send_IPI_mask_allbutself       = NULL,
-       .send_IPI_allbutself            = es7000_send_IPI_allbutself,
-       .send_IPI_all                   = es7000_send_IPI_all,
-       .send_IPI_self                  = default_send_IPI_self,
-
-       .wakeup_cpu                     = NULL,
-
-       .trampoline_phys_low            = 0x467,
-       .trampoline_phys_high           = 0x469,
-
-       .wait_for_init_deassert         = es7000_wait_for_init_deassert,
-
-       /* Nothing to do for most platforms, since cleared by the INIT cycle: */
-       .smp_callin_clear_local_apic    = NULL,
-       .inquire_remote_apic            = default_inquire_remote_apic,
-
-       .read                           = native_apic_mem_read,
-       .write                          = native_apic_mem_write,
-       .icr_read                       = native_apic_icr_read,
-       .icr_write                      = native_apic_icr_write,
-       .wait_icr_idle                  = native_apic_wait_icr_idle,
-       .safe_wait_icr_idle             = native_safe_apic_wait_icr_idle,
-};
diff --git a/arch/x86/kernel/numaq_32.c b/arch/x86/kernel/numaq_32.c
deleted file mode 100644 (file)
index d9d6d61..0000000
+++ /dev/null
@@ -1,565 +0,0 @@
-/*
- * Written by: Patricia Gaughen, IBM Corporation
- *
- * Copyright (C) 2002, IBM Corp.
- * Copyright (C) 2009, Red Hat, Inc., Ingo Molnar
- *
- * All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
- * NON INFRINGEMENT.  See the GNU General Public License for more
- * details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * Send feedback to <gone@us.ibm.com>
- */
-#include <linux/nodemask.h>
-#include <linux/topology.h>
-#include <linux/bootmem.h>
-#include <linux/threads.h>
-#include <linux/cpumask.h>
-#include <linux/kernel.h>
-#include <linux/mmzone.h>
-#include <linux/module.h>
-#include <linux/string.h>
-#include <linux/init.h>
-#include <linux/numa.h>
-#include <linux/smp.h>
-#include <linux/io.h>
-#include <linux/mm.h>
-
-#include <asm/processor.h>
-#include <asm/fixmap.h>
-#include <asm/mpspec.h>
-#include <asm/numaq.h>
-#include <asm/setup.h>
-#include <asm/apic.h>
-#include <asm/e820.h>
-#include <asm/ipi.h>
-
-#define        MB_TO_PAGES(addr)               ((addr) << (20 - PAGE_SHIFT))
-
-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_trans {
-       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;
-};
-
-/* x86_quirks member */
-static int                             mpc_record;
-
-static __cpuinitdata struct mpc_trans  *translation_table[MAX_MPC_ENTRY];
-
-int                                    mp_bus_id_to_node[MAX_MP_BUSSES];
-int                                    mp_bus_id_to_local[MAX_MP_BUSSES];
-int                                    quad_local_to_mp_bus_id[NR_CPUS/4][4];
-
-
-static inline void numaq_register_node(int node, struct sys_cfg_data *scd)
-{
-       struct eachquadmem *eq = scd->eq + node;
-
-       node_set_online(node);
-
-       /* Convert to pages */
-       node_start_pfn[node] =
-                MB_TO_PAGES(eq->hi_shrd_mem_start - eq->priv_mem_size);
-
-       node_end_pfn[node] =
-                MB_TO_PAGES(eq->hi_shrd_mem_start + eq->hi_shrd_mem_size);
-
-       e820_register_active_regions(node, node_start_pfn[node],
-                                               node_end_pfn[node]);
-
-       memory_present(node, node_start_pfn[node], node_end_pfn[node]);
-
-       node_remap_size[node] = node_memmap_size_bytes(node,
-                                       node_start_pfn[node],
-                                       node_end_pfn[node]);
-}
-
-/*
- * Function: smp_dump_qct()
- *
- * Description: gets memory layout from the quad config table.  This
- * function also updates node_online_map with the nodes (quads) present.
- */
-static void __init smp_dump_qct(void)
-{
-       struct sys_cfg_data *scd;
-       int node;
-
-       scd = (void *)__va(SYS_CFG_DATA_PRIV_ADDR);
-
-       nodes_clear(node_online_map);
-       for_each_node(node) {
-               if (scd->quads_present31_0 & (1 << node))
-                       numaq_register_node(node, scd);
-       }
-}
-
-void __cpuinit numaq_tsc_disable(void)
-{
-       if (!found_numaq)
-               return;
-
-       if (num_online_nodes() > 1) {
-               printk(KERN_DEBUG "NUMAQ: disabling TSC\n");
-               setup_clear_cpu_cap(X86_FEATURE_TSC);
-       }
-}
-
-static int __init numaq_pre_time_init(void)
-{
-       numaq_tsc_disable();
-       return 0;
-}
-
-static inline int generate_logical_apicid(int quad, int phys_apicid)
-{
-       return (quad << 4) + (phys_apicid ? phys_apicid << 1 : 1);
-}
-
-/* x86_quirks member */
-static int mpc_apic_id(struct mpc_cpu *m)
-{
-       int quad = translation_table[mpc_record]->trans_quad;
-       int logical_apicid = generate_logical_apicid(quad, m->apicid);
-
-       printk(KERN_DEBUG
-               "Processor #%d %u:%u APIC version %d (quad %d, apic %d)\n",
-                m->apicid, (m->cpufeature & CPU_FAMILY_MASK) >> 8,
-               (m->cpufeature & CPU_MODEL_MASK) >> 4,
-                m->apicver, quad, logical_apicid);
-
-       return logical_apicid;
-}
-
-/* x86_quirks member */
-static void mpc_oem_bus_info(struct mpc_bus *m, char *name)
-{
-       int quad = translation_table[mpc_record]->trans_quad;
-       int local = translation_table[mpc_record]->trans_local;
-
-       mp_bus_id_to_node[m->busid] = quad;
-       mp_bus_id_to_local[m->busid] = local;
-
-       printk(KERN_INFO "Bus #%d is %s (node %d)\n", m->busid, name, quad);
-}
-
-/* x86_quirks member */
-static void mpc_oem_pci_bus(struct mpc_bus *m)
-{
-       int quad = translation_table[mpc_record]->trans_quad;
-       int local = translation_table[mpc_record]->trans_local;
-
-       quad_local_to_mp_bus_id[quad][local] = m->busid;
-}
-
-static void __init MP_translation_info(struct mpc_trans *m)
-{
-       printk(KERN_INFO
-           "Translation: record %d, type %d, quad %d, global %d, local %d\n",
-              mpc_record, m->trans_type, m->trans_quad, m->trans_global,
-              m->trans_local);
-
-       if (mpc_record >= MAX_MPC_ENTRY)
-               printk(KERN_ERR "MAX_MPC_ENTRY exceeded!\n");
-       else
-               translation_table[mpc_record] = m; /* stash this for later */
-
-       if (m->trans_quad < MAX_NUMNODES && !node_online(m->trans_quad))
-               node_set_online(m->trans_quad);
-}
-
-static int __init mpf_checksum(unsigned char *mp, int len)
-{
-       int sum = 0;
-
-       while (len--)
-               sum += *mp++;
-
-       return sum & 0xFF;
-}
-
-/*
- * Read/parse the MPC oem tables
- */
-static void __init
- smp_read_mpc_oem(struct mpc_oemtable *oemtable, unsigned short oemsize)
-{
-       int count = sizeof(*oemtable);  /* the header size */
-       unsigned char *oemptr = ((unsigned char *)oemtable) + count;
-
-       mpc_record = 0;
-       printk(KERN_INFO
-               "Found an OEM MPC table at %8p - parsing it ... \n", oemtable);
-
-       if (memcmp(oemtable->signature, MPC_OEM_SIGNATURE, 4)) {
-               printk(KERN_WARNING
-                      "SMP mpc oemtable: bad signature [%c%c%c%c]!\n",
-                      oemtable->signature[0], oemtable->signature[1],
-                      oemtable->signature[2], oemtable->signature[3]);
-               return;
-       }
-
-       if (mpf_checksum((unsigned char *)oemtable, oemtable->length)) {
-               printk(KERN_WARNING "SMP oem mptable: checksum error!\n");
-               return;
-       }
-
-       while (count < oemtable->length) {
-               switch (*oemptr) {
-               case MP_TRANSLATION:
-                       {
-                               struct mpc_trans *m = (void *)oemptr;
-
-                               MP_translation_info(m);
-                               oemptr += sizeof(*m);
-                               count += sizeof(*m);
-                               ++mpc_record;
-                               break;
-                       }
-               default:
-                       printk(KERN_WARNING
-                              "Unrecognised OEM table entry type! - %d\n",
-                              (int)*oemptr);
-                       return;
-               }
-       }
-}
-
-static int __init numaq_setup_ioapic_ids(void)
-{
-       /* so can skip it */
-       return 1;
-}
-
-static int __init numaq_update_apic(void)
-{
-       apic->wakeup_cpu = wakeup_secondary_cpu_via_nmi;
-
-       return 0;
-}
-
-static struct x86_quirks numaq_x86_quirks __initdata = {
-       .arch_pre_time_init             = numaq_pre_time_init,
-       .arch_time_init                 = NULL,
-       .arch_pre_intr_init             = NULL,
-       .arch_memory_setup              = NULL,
-       .arch_intr_init                 = NULL,
-       .arch_trap_init                 = NULL,
-       .mach_get_smp_config            = NULL,
-       .mach_find_smp_config           = NULL,
-       .mpc_record                     = &mpc_record,
-       .mpc_apic_id                    = mpc_apic_id,
-       .mpc_oem_bus_info               = mpc_oem_bus_info,
-       .mpc_oem_pci_bus                = mpc_oem_pci_bus,
-       .smp_read_mpc_oem               = smp_read_mpc_oem,
-       .setup_ioapic_ids               = numaq_setup_ioapic_ids,
-       .update_apic                    = numaq_update_apic,
-};
-
-static __init void early_check_numaq(void)
-{
-       /*
-        * Find possible boot-time SMP configuration:
-        */
-       early_find_smp_config();
-
-       /*
-        * get boot-time SMP configuration:
-        */
-       if (smp_found_config)
-               early_get_smp_config();
-
-       if (found_numaq)
-               x86_quirks = &numaq_x86_quirks;
-}
-
-int __init get_memcfg_numaq(void)
-{
-       early_check_numaq();
-       if (!found_numaq)
-               return 0;
-       smp_dump_qct();
-
-       return 1;
-}
-
-#define NUMAQ_APIC_DFR_VALUE   (APIC_DFR_CLUSTER)
-
-static inline unsigned int numaq_get_apic_id(unsigned long x)
-{
-       return (x >> 24) & 0x0F;
-}
-
-static inline void numaq_send_IPI_mask(const struct cpumask *mask, int vector)
-{
-       default_send_IPI_mask_sequence_logical(mask, vector);
-}
-
-static inline void numaq_send_IPI_allbutself(int vector)
-{
-       default_send_IPI_mask_allbutself_logical(cpu_online_mask, vector);
-}
-
-static inline void numaq_send_IPI_all(int vector)
-{
-       numaq_send_IPI_mask(cpu_online_mask, vector);
-}
-
-#define NUMAQ_TRAMPOLINE_PHYS_LOW      (0x8)
-#define NUMAQ_TRAMPOLINE_PHYS_HIGH     (0xa)
-
-/*
- * Because we use NMIs rather than the INIT-STARTUP sequence to
- * bootstrap the CPUs, the APIC may be in a weird state. Kick it:
- */
-static inline void numaq_smp_callin_clear_local_apic(void)
-{
-       clear_local_APIC();
-}
-
-static inline const cpumask_t *numaq_target_cpus(void)
-{
-       return &CPU_MASK_ALL;
-}
-
-static inline unsigned long
-numaq_check_apicid_used(physid_mask_t bitmap, int apicid)
-{
-       return physid_isset(apicid, bitmap);
-}
-
-static inline unsigned long numaq_check_apicid_present(int bit)
-{
-       return physid_isset(bit, phys_cpu_present_map);
-}
-
-static inline int numaq_apic_id_registered(void)
-{
-       return 1;
-}
-
-static inline void numaq_init_apic_ldr(void)
-{
-       /* Already done in NUMA-Q firmware */
-}
-
-static inline void numaq_setup_apic_routing(void)
-{
-       printk(KERN_INFO
-               "Enabling APIC mode:  NUMA-Q.  Using %d I/O APICs\n",
-               nr_ioapics);
-}
-
-/*
- * Skip adding the timer int on secondary nodes, which causes
- * a small but painful rift in the time-space continuum.
- */
-static inline int numaq_multi_timer_check(int apic, int irq)
-{
-       return apic != 0 && irq == 0;
-}
-
-static inline physid_mask_t numaq_ioapic_phys_id_map(physid_mask_t phys_map)
-{
-       /* We don't have a good way to do this yet - hack */
-       return physids_promote(0xFUL);
-}
-
-static inline int numaq_cpu_to_logical_apicid(int cpu)
-{
-       if (cpu >= nr_cpu_ids)
-               return BAD_APICID;
-       return cpu_2_logical_apicid[cpu];
-}
-
-/*
- * Supporting over 60 cpus on NUMA-Q requires a locality-dependent
- * cpu to APIC ID relation to properly interact with the intelligent
- * mode of the cluster controller.
- */
-static inline int numaq_cpu_present_to_apicid(int mps_cpu)
-{
-       if (mps_cpu < 60)
-               return ((mps_cpu >> 2) << 4) | (1 << (mps_cpu & 0x3));
-       else
-               return BAD_APICID;
-}
-
-static inline int numaq_apicid_to_node(int logical_apicid)
-{
-       return logical_apicid >> 4;
-}
-
-static inline physid_mask_t numaq_apicid_to_cpu_present(int logical_apicid)
-{
-       int node = numaq_apicid_to_node(logical_apicid);
-       int cpu = __ffs(logical_apicid & 0xf);
-
-       return physid_mask_of_physid(cpu + 4*node);
-}
-
-/* Where the IO area was mapped on multiquad, always 0 otherwise */
-void *xquad_portio;
-
-static inline int numaq_check_phys_apicid_present(int boot_cpu_physical_apicid)
-{
-       return 1;
-}
-
-/*
- * We use physical apicids here, not logical, so just return the default
- * physical broadcast to stop people from breaking us
- */
-static inline unsigned int numaq_cpu_mask_to_apicid(const cpumask_t *cpumask)
-{
-       return 0x0F;
-}
-
-static inline unsigned int
-numaq_cpu_mask_to_apicid_and(const struct cpumask *cpumask,
-                            const struct cpumask *andmask)
-{
-       return 0x0F;
-}
-
-/* No NUMA-Q box has a HT CPU, but it can't hurt to use the default code. */
-static inline int numaq_phys_pkg_id(int cpuid_apic, int index_msb)
-{
-       return cpuid_apic >> index_msb;
-}
-
-static int
-numaq_mps_oem_check(struct mpc_table *mpc, char *oem, char *productid)
-{
-       if (strncmp(oem, "IBM NUMA", 8))
-               printk(KERN_ERR "Warning! Not a NUMA-Q system!\n");
-       else
-               found_numaq = 1;
-
-       return found_numaq;
-}
-
-static int probe_numaq(void)
-{
-       /* already know from get_memcfg_numaq() */
-       return found_numaq;
-}
-
-static void numaq_vector_allocation_domain(int cpu, cpumask_t *retmask)
-{
-       /* Careful. Some cpus do not strictly honor the set of cpus
-        * specified in the interrupt destination when using lowest
-        * priority interrupt delivery mode.
-        *
-        * In particular there was a hyperthreading cpu observed to
-        * deliver interrupts to the wrong hyperthread when only one
-        * hyperthread was specified in the interrupt desitination.
-        */
-       *retmask = (cpumask_t){ { [0] = APIC_ALL_CPUS, } };
-}
-
-static void numaq_setup_portio_remap(void)
-{
-       int num_quads = num_online_nodes();
-
-       if (num_quads <= 1)
-               return;
-
-       printk(KERN_INFO
-               "Remapping cross-quad port I/O for %d quads\n", num_quads);
-
-       xquad_portio = ioremap(XQUAD_PORTIO_BASE, num_quads*XQUAD_PORTIO_QUAD);
-
-       printk(KERN_INFO
-               "xquad_portio vaddr 0x%08lx, len %08lx\n",
-               (u_long) xquad_portio, (u_long) num_quads*XQUAD_PORTIO_QUAD);
-}
-
-struct apic apic_numaq = {
-
-       .name                           = "NUMAQ",
-       .probe                          = probe_numaq,
-       .acpi_madt_oem_check            = NULL,
-       .apic_id_registered             = numaq_apic_id_registered,
-
-       .irq_delivery_mode              = dest_LowestPrio,
-       /* physical delivery on LOCAL quad: */
-       .irq_dest_mode                  = 0,
-
-       .target_cpus                    = numaq_target_cpus,
-       .disable_esr                    = 1,
-       .dest_logical                   = APIC_DEST_LOGICAL,
-       .check_apicid_used              = numaq_check_apicid_used,
-       .check_apicid_present           = numaq_check_apicid_present,
-
-       .vector_allocation_domain       = numaq_vector_allocation_domain,
-       .init_apic_ldr                  = numaq_init_apic_ldr,
-
-       .ioapic_phys_id_map             = numaq_ioapic_phys_id_map,
-       .setup_apic_routing             = numaq_setup_apic_routing,
-       .multi_timer_check              = numaq_multi_timer_check,
-       .apicid_to_node                 = numaq_apicid_to_node,
-       .cpu_to_logical_apicid          = numaq_cpu_to_logical_apicid,
-       .cpu_present_to_apicid          = numaq_cpu_present_to_apicid,
-       .apicid_to_cpu_present          = numaq_apicid_to_cpu_present,
-       .setup_portio_remap             = numaq_setup_portio_remap,
-       .check_phys_apicid_present      = numaq_check_phys_apicid_present,
-       .enable_apic_mode               = NULL,
-       .phys_pkg_id                    = numaq_phys_pkg_id,
-       .mps_oem_check                  = numaq_mps_oem_check,
-
-       .get_apic_id                    = numaq_get_apic_id,
-       .set_apic_id                    = NULL,
-       .apic_id_mask                   = 0x0F << 24,
-
-       .cpu_mask_to_apicid             = numaq_cpu_mask_to_apicid,
-       .cpu_mask_to_apicid_and         = numaq_cpu_mask_to_apicid_and,
-
-       .send_IPI_mask                  = numaq_send_IPI_mask,
-       .send_IPI_mask_allbutself       = NULL,
-       .send_IPI_allbutself            = numaq_send_IPI_allbutself,
-       .send_IPI_all                   = numaq_send_IPI_all,
-       .send_IPI_self                  = default_send_IPI_self,
-
-       .wakeup_cpu                     = NULL,
-       .trampoline_phys_low            = NUMAQ_TRAMPOLINE_PHYS_LOW,
-       .trampoline_phys_high           = NUMAQ_TRAMPOLINE_PHYS_HIGH,
-
-       /* We don't do anything here because we use NMI's to boot instead */
-       .wait_for_init_deassert         = NULL,
-
-       .smp_callin_clear_local_apic    = numaq_smp_callin_clear_local_apic,
-       .inquire_remote_apic            = NULL,
-
-       .read                           = native_apic_mem_read,
-       .write                          = native_apic_mem_write,
-       .icr_read                       = native_apic_icr_read,
-       .icr_write                      = native_apic_icr_write,
-       .wait_icr_idle                  = native_apic_wait_icr_idle,
-       .safe_wait_icr_idle             = native_safe_apic_wait_icr_idle,
-};
diff --git a/arch/x86/kernel/probe_32.c b/arch/x86/kernel/probe_32.c
deleted file mode 100644 (file)
index 5fa4833..0000000
+++ /dev/null
@@ -1,424 +0,0 @@
-/*
- * Default generic APIC driver. This handles up to 8 CPUs.
- *
- * Copyright 2003 Andi Kleen, SuSE Labs.
- * Subject to the GNU Public License, v.2
- *
- * Generic x86 APIC driver probe layer.
- */
-#include <linux/threads.h>
-#include <linux/cpumask.h>
-#include <linux/module.h>
-#include <linux/string.h>
-#include <linux/kernel.h>
-#include <linux/ctype.h>
-#include <linux/init.h>
-#include <linux/errno.h>
-#include <asm/fixmap.h>
-#include <asm/mpspec.h>
-#include <asm/apicdef.h>
-#include <asm/apic.h>
-#include <asm/setup.h>
-
-#include <linux/threads.h>
-#include <linux/cpumask.h>
-#include <asm/mpspec.h>
-#include <asm/fixmap.h>
-#include <asm/apicdef.h>
-#include <linux/kernel.h>
-#include <linux/string.h>
-#include <linux/smp.h>
-#include <linux/init.h>
-#include <asm/ipi.h>
-
-#include <linux/smp.h>
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <asm/acpi.h>
-#include <asm/arch_hooks.h>
-#include <asm/e820.h>
-#include <asm/setup.h>
-
-#ifdef CONFIG_HOTPLUG_CPU
-#define DEFAULT_SEND_IPI       (1)
-#else
-#define DEFAULT_SEND_IPI       (0)
-#endif
-
-int no_broadcast = DEFAULT_SEND_IPI;
-
-#ifdef CONFIG_X86_LOCAL_APIC
-
-void default_setup_apic_routing(void)
-{
-#ifdef CONFIG_X86_IO_APIC
-       printk(KERN_INFO
-               "Enabling APIC mode:  Flat.  Using %d I/O APICs\n",
-               nr_ioapics);
-#endif
-}
-
-static void default_vector_allocation_domain(int cpu, struct cpumask *retmask)
-{
-       /*
-        * Careful. Some cpus do not strictly honor the set of cpus
-        * specified in the interrupt destination when using lowest
-        * priority interrupt delivery mode.
-        *
-        * In particular there was a hyperthreading cpu observed to
-        * deliver interrupts to the wrong hyperthread when only one
-        * hyperthread was specified in the interrupt desitination.
-        */
-       *retmask = (cpumask_t) { { [0] = APIC_ALL_CPUS } };
-}
-
-/* should be called last. */
-static int probe_default(void)
-{
-       return 1;
-}
-
-struct apic apic_default = {
-
-       .name                           = "default",
-       .probe                          = probe_default,
-       .acpi_madt_oem_check            = NULL,
-       .apic_id_registered             = default_apic_id_registered,
-
-       .irq_delivery_mode              = dest_LowestPrio,
-       /* logical delivery broadcast to all CPUs: */
-       .irq_dest_mode                  = 1,
-
-       .target_cpus                    = default_target_cpus,
-       .disable_esr                    = 0,
-       .dest_logical                   = APIC_DEST_LOGICAL,
-       .check_apicid_used              = default_check_apicid_used,
-       .check_apicid_present           = default_check_apicid_present,
-
-       .vector_allocation_domain       = default_vector_allocation_domain,
-       .init_apic_ldr                  = default_init_apic_ldr,
-
-       .ioapic_phys_id_map             = default_ioapic_phys_id_map,
-       .setup_apic_routing             = default_setup_apic_routing,
-       .multi_timer_check              = NULL,
-       .apicid_to_node                 = default_apicid_to_node,
-       .cpu_to_logical_apicid          = default_cpu_to_logical_apicid,
-       .cpu_present_to_apicid          = default_cpu_present_to_apicid,
-       .apicid_to_cpu_present          = default_apicid_to_cpu_present,
-       .setup_portio_remap             = NULL,
-       .check_phys_apicid_present      = default_check_phys_apicid_present,
-       .enable_apic_mode               = NULL,
-       .phys_pkg_id                    = default_phys_pkg_id,
-       .mps_oem_check                  = NULL,
-
-       .get_apic_id                    = default_get_apic_id,
-       .set_apic_id                    = NULL,
-       .apic_id_mask                   = 0x0F << 24,
-
-       .cpu_mask_to_apicid             = default_cpu_mask_to_apicid,
-       .cpu_mask_to_apicid_and         = default_cpu_mask_to_apicid_and,
-
-       .send_IPI_mask                  = default_send_IPI_mask_logical,
-       .send_IPI_mask_allbutself       = default_send_IPI_mask_allbutself_logical,
-       .send_IPI_allbutself            = default_send_IPI_allbutself,
-       .send_IPI_all                   = default_send_IPI_all,
-       .send_IPI_self                  = default_send_IPI_self,
-
-       .wakeup_cpu                     = NULL,
-       .trampoline_phys_low            = DEFAULT_TRAMPOLINE_PHYS_LOW,
-       .trampoline_phys_high           = DEFAULT_TRAMPOLINE_PHYS_HIGH,
-
-       .wait_for_init_deassert         = default_wait_for_init_deassert,
-
-       .smp_callin_clear_local_apic    = NULL,
-       .inquire_remote_apic            = default_inquire_remote_apic,
-
-       .read                           = native_apic_mem_read,
-       .write                          = native_apic_mem_write,
-       .icr_read                       = native_apic_icr_read,
-       .icr_write                      = native_apic_icr_write,
-       .wait_icr_idle                  = native_apic_wait_icr_idle,
-       .safe_wait_icr_idle             = native_safe_apic_wait_icr_idle,
-};
-
-extern struct apic apic_numaq;
-extern struct apic apic_summit;
-extern struct apic apic_bigsmp;
-extern struct apic apic_es7000;
-extern struct apic apic_default;
-
-struct apic *apic = &apic_default;
-EXPORT_SYMBOL_GPL(apic);
-
-static struct apic *apic_probe[] __initdata = {
-#ifdef CONFIG_X86_NUMAQ
-       &apic_numaq,
-#endif
-#ifdef CONFIG_X86_SUMMIT
-       &apic_summit,
-#endif
-#ifdef CONFIG_X86_BIGSMP
-       &apic_bigsmp,
-#endif
-#ifdef CONFIG_X86_ES7000
-       &apic_es7000,
-#endif
-       &apic_default,  /* must be last */
-       NULL,
-};
-
-static int cmdline_apic __initdata;
-static int __init parse_apic(char *arg)
-{
-       int i;
-
-       if (!arg)
-               return -EINVAL;
-
-       for (i = 0; apic_probe[i]; i++) {
-               if (!strcmp(apic_probe[i]->name, arg)) {
-                       apic = apic_probe[i];
-                       cmdline_apic = 1;
-                       return 0;
-               }
-       }
-
-       if (x86_quirks->update_apic)
-               x86_quirks->update_apic();
-
-       /* Parsed again by __setup for debug/verbose */
-       return 0;
-}
-early_param("apic", parse_apic);
-
-void __init generic_bigsmp_probe(void)
-{
-#ifdef CONFIG_X86_BIGSMP
-       /*
-        * This routine is used to switch to bigsmp mode when
-        * - There is no apic= option specified by the user
-        * - generic_apic_probe() has chosen apic_default as the sub_arch
-        * - we find more than 8 CPUs in acpi LAPIC listing with xAPIC support
-        */
-
-       if (!cmdline_apic && apic == &apic_default) {
-               if (apic_bigsmp.probe()) {
-                       apic = &apic_bigsmp;
-                       if (x86_quirks->update_apic)
-                               x86_quirks->update_apic();
-                       printk(KERN_INFO "Overriding APIC driver with %s\n",
-                              apic->name);
-               }
-       }
-#endif
-}
-
-void __init generic_apic_probe(void)
-{
-       if (!cmdline_apic) {
-               int i;
-               for (i = 0; apic_probe[i]; i++) {
-                       if (apic_probe[i]->probe()) {
-                               apic = apic_probe[i];
-                               break;
-                       }
-               }
-               /* Not visible without early console */
-               if (!apic_probe[i])
-                       panic("Didn't find an APIC driver");
-
-               if (x86_quirks->update_apic)
-                       x86_quirks->update_apic();
-       }
-       printk(KERN_INFO "Using APIC driver %s\n", apic->name);
-}
-
-/* These functions can switch the APIC even after the initial ->probe() */
-
-int __init
-generic_mps_oem_check(struct mpc_table *mpc, char *oem, char *productid)
-{
-       int i;
-
-       for (i = 0; apic_probe[i]; ++i) {
-               if (!apic_probe[i]->mps_oem_check)
-                       continue;
-               if (!apic_probe[i]->mps_oem_check(mpc, oem, productid))
-                       continue;
-
-               if (!cmdline_apic) {
-                       apic = apic_probe[i];
-                       if (x86_quirks->update_apic)
-                               x86_quirks->update_apic();
-                       printk(KERN_INFO "Switched to APIC driver `%s'.\n",
-                              apic->name);
-               }
-               return 1;
-       }
-       return 0;
-}
-
-int __init default_acpi_madt_oem_check(char *oem_id, char *oem_table_id)
-{
-       int i;
-
-       for (i = 0; apic_probe[i]; ++i) {
-               if (!apic_probe[i]->acpi_madt_oem_check)
-                       continue;
-               if (!apic_probe[i]->acpi_madt_oem_check(oem_id, oem_table_id))
-                       continue;
-
-               if (!cmdline_apic) {
-                       apic = apic_probe[i];
-                       if (x86_quirks->update_apic)
-                               x86_quirks->update_apic();
-                       printk(KERN_INFO "Switched to APIC driver `%s'.\n",
-                              apic->name);
-               }
-               return 1;
-       }
-       return 0;
-}
-
-#endif /* CONFIG_X86_LOCAL_APIC */
-
-/**
- * pre_intr_init_hook - initialisation prior to setting up interrupt vectors
- *
- * Description:
- *     Perform any necessary interrupt initialisation prior to setting up
- *     the "ordinary" interrupt call gates.  For legacy reasons, the ISA
- *     interrupts should be initialised here if the machine emulates a PC
- *     in any way.
- **/
-void __init pre_intr_init_hook(void)
-{
-       if (x86_quirks->arch_pre_intr_init) {
-               if (x86_quirks->arch_pre_intr_init())
-                       return;
-       }
-       init_ISA_irqs();
-}
-
-/**
- * intr_init_hook - post gate setup interrupt initialisation
- *
- * Description:
- *     Fill in any interrupts that may have been left out by the general
- *     init_IRQ() routine.  interrupts having to do with the machine rather
- *     than the devices on the I/O bus (like APIC interrupts in intel MP
- *     systems) are started here.
- **/
-void __init intr_init_hook(void)
-{
-       if (x86_quirks->arch_intr_init) {
-               if (x86_quirks->arch_intr_init())
-                       return;
-       }
-}
-
-/**
- * pre_setup_arch_hook - hook called prior to any setup_arch() execution
- *
- * Description:
- *     generally used to activate any machine specific identification
- *     routines that may be needed before setup_arch() runs.  On Voyager
- *     this is used to get the board revision and type.
- **/
-void __init pre_setup_arch_hook(void)
-{
-}
-
-/**
- * trap_init_hook - initialise system specific traps
- *
- * Description:
- *     Called as the final act of trap_init().  Used in VISWS to initialise
- *     the various board specific APIC traps.
- **/
-void __init trap_init_hook(void)
-{
-       if (x86_quirks->arch_trap_init) {
-               if (x86_quirks->arch_trap_init())
-                       return;
-       }
-}
-
-static struct irqaction irq0  = {
-       .handler = timer_interrupt,
-       .flags = IRQF_DISABLED | IRQF_NOBALANCING | IRQF_IRQPOLL,
-       .mask = CPU_MASK_NONE,
-       .name = "timer"
-};
-
-/**
- * pre_time_init_hook - do any specific initialisations before.
- *
- **/
-void __init pre_time_init_hook(void)
-{
-       if (x86_quirks->arch_pre_time_init)
-               x86_quirks->arch_pre_time_init();
-}
-
-/**
- * time_init_hook - do any specific initialisations for the system timer.
- *
- * Description:
- *     Must plug the system timer interrupt source at HZ into the IRQ listed
- *     in irq_vectors.h:TIMER_IRQ
- **/
-void __init time_init_hook(void)
-{
-       if (x86_quirks->arch_time_init) {
-               /*
-                * A nonzero return code does not mean failure, it means
-                * that the architecture quirk does not want any
-                * generic (timer) setup to be performed after this:
-                */
-               if (x86_quirks->arch_time_init())
-                       return;
-       }
-
-       irq0.mask = cpumask_of_cpu(0);
-       setup_irq(0, &irq0);
-}
-
-#ifdef CONFIG_MCA
-/**
- * mca_nmi_hook - hook into MCA specific NMI chain
- *
- * Description:
- *     The MCA (Microchannel Architecture) has an NMI chain for NMI sources
- *     along the MCA bus.  Use this to hook into that chain if you will need
- *     it.
- **/
-void mca_nmi_hook(void)
-{
-       /*
-        * If I recall correctly, there's a whole bunch of other things that
-        * we can do to check for NMI problems, but that's all I know about
-        * at the moment.
-        */
-       pr_warning("NMI generated from unknown source!\n");
-}
-#endif
-
-static __init int no_ipi_broadcast(char *str)
-{
-       get_option(&str, &no_broadcast);
-       pr_info("Using %s mode\n",
-               no_broadcast ? "No IPI Broadcast" : "IPI Broadcast");
-       return 1;
-}
-__setup("no_ipi_broadcast=", no_ipi_broadcast);
-
-static int __init print_ipi_mode(void)
-{
-       pr_info("Using IPI %s mode\n",
-               no_broadcast ? "No-Shortcut" : "Shortcut");
-       return 0;
-}
-
-late_initcall(print_ipi_mode);
-
diff --git a/arch/x86/kernel/summit_32.c b/arch/x86/kernel/summit_32.c
deleted file mode 100644 (file)
index cfe7b09..0000000
+++ /dev/null
@@ -1,601 +0,0 @@
-/*
- * IBM Summit-Specific Code
- *
- * Written By: Matthew Dobson, IBM Corporation
- *
- * Copyright (c) 2003 IBM Corp.
- *
- * All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or (at
- * your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
- * NON INFRINGEMENT.  See the GNU General Public License for more
- * details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * Send feedback to <colpatch@us.ibm.com>
- *
- */
-
-#include <linux/mm.h>
-#include <linux/init.h>
-#include <asm/io.h>
-#include <asm/bios_ebda.h>
-
-/*
- * APIC driver for the IBM "Summit" chipset.
- */
-#include <linux/threads.h>
-#include <linux/cpumask.h>
-#include <asm/mpspec.h>
-#include <asm/apic.h>
-#include <asm/smp.h>
-#include <asm/fixmap.h>
-#include <asm/apicdef.h>
-#include <asm/ipi.h>
-#include <linux/kernel.h>
-#include <linux/string.h>
-#include <linux/init.h>
-#include <linux/gfp.h>
-#include <linux/smp.h>
-
-static inline unsigned summit_get_apic_id(unsigned long x)
-{
-       return (x >> 24) & 0xFF;
-}
-
-static inline void summit_send_IPI_mask(const cpumask_t *mask, int vector)
-{
-       default_send_IPI_mask_sequence_logical(mask, vector);
-}
-
-static inline void summit_send_IPI_allbutself(int vector)
-{
-       cpumask_t mask = cpu_online_map;
-       cpu_clear(smp_processor_id(), mask);
-
-       if (!cpus_empty(mask))
-               summit_send_IPI_mask(&mask, vector);
-}
-
-static inline void summit_send_IPI_all(int vector)
-{
-       summit_send_IPI_mask(&cpu_online_map, vector);
-}
-
-#include <asm/tsc.h>
-
-extern int use_cyclone;
-
-#ifdef CONFIG_X86_SUMMIT_NUMA
-extern void setup_summit(void);
-#else
-#define setup_summit() {}
-#endif
-
-static inline int
-summit_mps_oem_check(struct mpc_table *mpc, char *oem, char *productid)
-{
-       if (!strncmp(oem, "IBM ENSW", 8) &&
-                       (!strncmp(productid, "VIGIL SMP", 9)
-                        || !strncmp(productid, "EXA", 3)
-                        || !strncmp(productid, "RUTHLESS SMP", 12))){
-               mark_tsc_unstable("Summit based system");
-               use_cyclone = 1; /*enable cyclone-timer*/
-               setup_summit();
-               return 1;
-       }
-       return 0;
-}
-
-/* Hook from generic ACPI tables.c */
-static inline int summit_acpi_madt_oem_check(char *oem_id, char *oem_table_id)
-{
-       if (!strncmp(oem_id, "IBM", 3) &&
-           (!strncmp(oem_table_id, "SERVIGIL", 8)
-            || !strncmp(oem_table_id, "EXA", 3))){
-               mark_tsc_unstable("Summit based system");
-               use_cyclone = 1; /*enable cyclone-timer*/
-               setup_summit();
-               return 1;
-       }
-       return 0;
-}
-
-struct rio_table_hdr {
-       unsigned char version;      /* Version number of this data structure           */
-                                   /* Version 3 adds chassis_num & WP_index           */
-       unsigned char num_scal_dev; /* # of Scalability devices (Twisters for Vigil)   */
-       unsigned char num_rio_dev;  /* # of RIO I/O devices (Cyclones and Winnipegs)   */
-} __attribute__((packed));
-
-struct scal_detail {
-       unsigned char node_id;      /* Scalability Node ID                             */
-       unsigned long CBAR;         /* Address of 1MB register space                   */
-       unsigned char port0node;    /* Node ID port connected to: 0xFF=None            */
-       unsigned char port0port;    /* Port num port connected to: 0,1,2, or 0xFF=None */
-       unsigned char port1node;    /* Node ID port connected to: 0xFF = None          */
-       unsigned char port1port;    /* Port num port connected to: 0,1,2, or 0xFF=None */
-       unsigned char port2node;    /* Node ID port connected to: 0xFF = None          */
-       unsigned char port2port;    /* Port num port connected to: 0,1,2, or 0xFF=None */
-       unsigned char chassis_num;  /* 1 based Chassis number (1 = boot node)          */
-} __attribute__((packed));
-
-struct rio_detail {
-       unsigned char node_id;      /* RIO Node ID                                     */
-       unsigned long BBAR;         /* Address of 1MB register space                   */
-       unsigned char type;         /* Type of device                                  */
-       unsigned char owner_id;     /* For WPEG: Node ID of Cyclone that owns this WPEG*/
-                                   /* For CYC:  Node ID of Twister that owns this CYC */
-       unsigned char port0node;    /* Node ID port connected to: 0xFF=None            */
-       unsigned char port0port;    /* Port num port connected to: 0,1,2, or 0xFF=None */
-       unsigned char port1node;    /* Node ID port connected to: 0xFF=None            */
-       unsigned char port1port;    /* Port num port connected to: 0,1,2, or 0xFF=None */
-       unsigned char first_slot;   /* For WPEG: Lowest slot number below this WPEG    */
-                                   /* For CYC:  0                                     */
-       unsigned char status;       /* For WPEG: Bit 0 = 1 : the XAPIC is used         */
-                                   /*                 = 0 : the XAPIC is not used, ie:*/
-                                   /*                     ints fwded to another XAPIC */
-                                   /*           Bits1:7 Reserved                      */
-                                   /* For CYC:  Bits0:7 Reserved                      */
-       unsigned char WP_index;     /* For WPEG: WPEG instance index - lower ones have */
-                                   /*           lower slot numbers/PCI bus numbers    */
-                                   /* For CYC:  No meaning                            */
-       unsigned char chassis_num;  /* 1 based Chassis number                          */
-                                   /* For LookOut WPEGs this field indicates the      */
-                                   /* Expansion Chassis #, enumerated from Boot       */
-                                   /* Node WPEG external port, then Boot Node CYC     */
-                                   /* external port, then Next Vigil chassis WPEG     */
-                                   /* external port, etc.                             */
-                                   /* Shared Lookouts have only 1 chassis number (the */
-                                   /* first one assigned)                             */
-} __attribute__((packed));
-
-
-typedef enum {
-       CompatTwister = 0,  /* Compatibility Twister               */
-       AltTwister    = 1,  /* Alternate Twister of internal 8-way */
-       CompatCyclone = 2,  /* Compatibility Cyclone               */
-       AltCyclone    = 3,  /* Alternate Cyclone of internal 8-way */
-       CompatWPEG    = 4,  /* Compatibility WPEG                  */
-       AltWPEG       = 5,  /* Second Planar WPEG                  */
-       LookOutAWPEG  = 6,  /* LookOut WPEG                        */
-       LookOutBWPEG  = 7,  /* LookOut WPEG                        */
-} node_type;
-
-static inline int is_WPEG(struct rio_detail *rio){
-       return (rio->type == CompatWPEG || rio->type == AltWPEG ||
-               rio->type == LookOutAWPEG || rio->type == LookOutBWPEG);
-}
-
-
-/* In clustered mode, the high nibble of APIC ID is a cluster number.
- * The low nibble is a 4-bit bitmap. */
-#define XAPIC_DEST_CPUS_SHIFT  4
-#define XAPIC_DEST_CPUS_MASK   ((1u << XAPIC_DEST_CPUS_SHIFT) - 1)
-#define XAPIC_DEST_CLUSTER_MASK        (XAPIC_DEST_CPUS_MASK << XAPIC_DEST_CPUS_SHIFT)
-
-#define SUMMIT_APIC_DFR_VALUE  (APIC_DFR_CLUSTER)
-
-static inline const cpumask_t *summit_target_cpus(void)
-{
-       /* CPU_MASK_ALL (0xff) has undefined behaviour with
-        * dest_LowestPrio mode logical clustered apic interrupt routing
-        * Just start on cpu 0.  IRQ balancing will spread load
-        */
-       return &cpumask_of_cpu(0);
-}
-
-static inline unsigned long
-summit_check_apicid_used(physid_mask_t bitmap, int apicid)
-{
-       return 0;
-}
-
-/* we don't use the phys_cpu_present_map to indicate apicid presence */
-static inline unsigned long summit_check_apicid_present(int bit)
-{
-       return 1;
-}
-
-static inline void summit_init_apic_ldr(void)
-{
-       unsigned long val, id;
-       int count = 0;
-       u8 my_id = (u8)hard_smp_processor_id();
-       u8 my_cluster = APIC_CLUSTER(my_id);
-#ifdef CONFIG_SMP
-       u8 lid;
-       int i;
-
-       /* Create logical APIC IDs by counting CPUs already in cluster. */
-       for (count = 0, i = nr_cpu_ids; --i >= 0; ) {
-               lid = cpu_2_logical_apicid[i];
-               if (lid != BAD_APICID && APIC_CLUSTER(lid) == my_cluster)
-                       ++count;
-       }
-#endif
-       /* We only have a 4 wide bitmap in cluster mode.  If a deranged
-        * BIOS puts 5 CPUs in one APIC cluster, we're hosed. */
-       BUG_ON(count >= XAPIC_DEST_CPUS_SHIFT);
-       id = my_cluster | (1UL << count);
-       apic_write(APIC_DFR, SUMMIT_APIC_DFR_VALUE);
-       val = apic_read(APIC_LDR) & ~APIC_LDR_MASK;
-       val |= SET_APIC_LOGICAL_ID(id);
-       apic_write(APIC_LDR, val);
-}
-
-static inline int summit_apic_id_registered(void)
-{
-       return 1;
-}
-
-static inline void summit_setup_apic_routing(void)
-{
-       printk("Enabling APIC mode:  Summit.  Using %d I/O APICs\n",
-                                               nr_ioapics);
-}
-
-static inline int summit_apicid_to_node(int logical_apicid)
-{
-#ifdef CONFIG_SMP
-       return apicid_2_node[hard_smp_processor_id()];
-#else
-       return 0;
-#endif
-}
-
-/* Mapping from cpu number to logical apicid */
-static inline int summit_cpu_to_logical_apicid(int cpu)
-{
-#ifdef CONFIG_SMP
-       if (cpu >= nr_cpu_ids)
-               return BAD_APICID;
-       return cpu_2_logical_apicid[cpu];
-#else
-       return logical_smp_processor_id();
-#endif
-}
-
-static inline int summit_cpu_present_to_apicid(int mps_cpu)
-{
-       if (mps_cpu < nr_cpu_ids)
-               return (int)per_cpu(x86_bios_cpu_apicid, mps_cpu);
-       else
-               return BAD_APICID;
-}
-
-static inline physid_mask_t
-summit_ioapic_phys_id_map(physid_mask_t phys_id_map)
-{
-       /* For clustered we don't have a good way to do this yet - hack */
-       return physids_promote(0x0F);
-}
-
-static inline physid_mask_t summit_apicid_to_cpu_present(int apicid)
-{
-       return physid_mask_of_physid(0);
-}
-
-static inline void summit_setup_portio_remap(void)
-{
-}
-
-static inline int summit_check_phys_apicid_present(int boot_cpu_physical_apicid)
-{
-       return 1;
-}
-
-static inline unsigned int summit_cpu_mask_to_apicid(const cpumask_t *cpumask)
-{
-       int cpus_found = 0;
-       int num_bits_set;
-       int apicid;
-       int cpu;
-
-       num_bits_set = cpus_weight(*cpumask);
-       /* Return id to all */
-       if (num_bits_set >= nr_cpu_ids)
-               return 0xFF;
-       /*
-        * The cpus in the mask must all be on the apic cluster.  If are not
-        * on the same apicid cluster return default value of target_cpus():
-        */
-       cpu = first_cpu(*cpumask);
-       apicid = summit_cpu_to_logical_apicid(cpu);
-
-       while (cpus_found < num_bits_set) {
-               if (cpu_isset(cpu, *cpumask)) {
-                       int new_apicid = summit_cpu_to_logical_apicid(cpu);
-
-                       if (APIC_CLUSTER(apicid) != APIC_CLUSTER(new_apicid)) {
-                               printk ("%s: Not a valid mask!\n", __func__);
-
-                               return 0xFF;
-                       }
-                       apicid = apicid | new_apicid;
-                       cpus_found++;
-               }
-               cpu++;
-       }
-       return apicid;
-}
-
-static inline unsigned int
-summit_cpu_mask_to_apicid_and(const struct cpumask *inmask,
-                             const struct cpumask *andmask)
-{
-       int apicid = summit_cpu_to_logical_apicid(0);
-       cpumask_var_t cpumask;
-
-       if (!alloc_cpumask_var(&cpumask, GFP_ATOMIC))
-               return apicid;
-
-       cpumask_and(cpumask, inmask, andmask);
-       cpumask_and(cpumask, cpumask, cpu_online_mask);
-       apicid = summit_cpu_mask_to_apicid(cpumask);
-
-       free_cpumask_var(cpumask);
-
-       return apicid;
-}
-
-/*
- * cpuid returns the value latched in the HW at reset, not the APIC ID
- * register's value.  For any box whose BIOS changes APIC IDs, like
- * clustered APIC systems, we must use hard_smp_processor_id.
- *
- * See Intel's IA-32 SW Dev's Manual Vol2 under CPUID.
- */
-static inline int summit_phys_pkg_id(int cpuid_apic, int index_msb)
-{
-       return hard_smp_processor_id() >> index_msb;
-}
-
-static int probe_summit(void)
-{
-       /* probed later in mptable/ACPI hooks */
-       return 0;
-}
-
-static void summit_vector_allocation_domain(int cpu, cpumask_t *retmask)
-{
-       /* Careful. Some cpus do not strictly honor the set of cpus
-        * specified in the interrupt destination when using lowest
-        * priority interrupt delivery mode.
-        *
-        * In particular there was a hyperthreading cpu observed to
-        * deliver interrupts to the wrong hyperthread when only one
-        * hyperthread was specified in the interrupt desitination.
-        */
-       *retmask = (cpumask_t){ { [0] = APIC_ALL_CPUS, } };
-}
-
-#ifdef CONFIG_X86_SUMMIT_NUMA
-static struct rio_table_hdr *rio_table_hdr __initdata;
-static struct scal_detail   *scal_devs[MAX_NUMNODES] __initdata;
-static struct rio_detail    *rio_devs[MAX_NUMNODES*4] __initdata;
-
-#ifndef CONFIG_X86_NUMAQ
-static int mp_bus_id_to_node[MAX_MP_BUSSES] __initdata;
-#endif
-
-static int __init setup_pci_node_map_for_wpeg(int wpeg_num, int last_bus)
-{
-       int twister = 0, node = 0;
-       int i, bus, num_buses;
-
-       for (i = 0; i < rio_table_hdr->num_rio_dev; i++) {
-               if (rio_devs[i]->node_id == rio_devs[wpeg_num]->owner_id) {
-                       twister = rio_devs[i]->owner_id;
-                       break;
-               }
-       }
-       if (i == rio_table_hdr->num_rio_dev) {
-               printk(KERN_ERR "%s: Couldn't find owner Cyclone for Winnipeg!\n", __func__);
-               return last_bus;
-       }
-
-       for (i = 0; i < rio_table_hdr->num_scal_dev; i++) {
-               if (scal_devs[i]->node_id == twister) {
-                       node = scal_devs[i]->node_id;
-                       break;
-               }
-       }
-       if (i == rio_table_hdr->num_scal_dev) {
-               printk(KERN_ERR "%s: Couldn't find owner Twister for Cyclone!\n", __func__);
-               return last_bus;
-       }
-
-       switch (rio_devs[wpeg_num]->type) {
-       case CompatWPEG:
-               /*
-                * The Compatibility Winnipeg controls the 2 legacy buses,
-                * the 66MHz PCI bus [2 slots] and the 2 "extra" buses in case
-                * a PCI-PCI bridge card is used in either slot: total 5 buses.
-                */
-               num_buses = 5;
-               break;
-       case AltWPEG:
-               /*
-                * The Alternate Winnipeg controls the 2 133MHz buses [1 slot
-                * each], their 2 "extra" buses, the 100MHz bus [2 slots] and
-                * the "extra" buses for each of those slots: total 7 buses.
-                */
-               num_buses = 7;
-               break;
-       case LookOutAWPEG:
-       case LookOutBWPEG:
-               /*
-                * A Lookout Winnipeg controls 3 100MHz buses [2 slots each]
-                * & the "extra" buses for each of those slots: total 9 buses.
-                */
-               num_buses = 9;
-               break;
-       default:
-               printk(KERN_INFO "%s: Unsupported Winnipeg type!\n", __func__);
-               return last_bus;
-       }
-
-       for (bus = last_bus; bus < last_bus + num_buses; bus++)
-               mp_bus_id_to_node[bus] = node;
-       return bus;
-}
-
-static int __init build_detail_arrays(void)
-{
-       unsigned long ptr;
-       int i, scal_detail_size, rio_detail_size;
-
-       if (rio_table_hdr->num_scal_dev > MAX_NUMNODES) {
-               printk(KERN_WARNING "%s: MAX_NUMNODES too low!  Defined as %d, but system has %d nodes.\n", __func__, MAX_NUMNODES, rio_table_hdr->num_scal_dev);
-               return 0;
-       }
-
-       switch (rio_table_hdr->version) {
-       default:
-               printk(KERN_WARNING "%s: Invalid Rio Grande Table Version: %d\n", __func__, rio_table_hdr->version);
-               return 0;
-       case 2:
-               scal_detail_size = 11;
-               rio_detail_size = 13;
-               break;
-       case 3:
-               scal_detail_size = 12;
-               rio_detail_size = 15;
-               break;
-       }
-
-       ptr = (unsigned long)rio_table_hdr + 3;
-       for (i = 0; i < rio_table_hdr->num_scal_dev; i++, ptr += scal_detail_size)
-               scal_devs[i] = (struct scal_detail *)ptr;
-
-       for (i = 0; i < rio_table_hdr->num_rio_dev; i++, ptr += rio_detail_size)
-               rio_devs[i] = (struct rio_detail *)ptr;
-
-       return 1;
-}
-
-void __init setup_summit(void)
-{
-       unsigned long           ptr;
-       unsigned short          offset;
-       int                     i, next_wpeg, next_bus = 0;
-
-       /* The pointer to the EBDA is stored in the word @ phys 0x40E(40:0E) */
-       ptr = get_bios_ebda();
-       ptr = (unsigned long)phys_to_virt(ptr);
-
-       rio_table_hdr = NULL;
-       offset = 0x180;
-       while (offset) {
-               /* The block id is stored in the 2nd word */
-               if (*((unsigned short *)(ptr + offset + 2)) == 0x4752) {
-                       /* set the pointer past the offset & block id */
-                       rio_table_hdr = (struct rio_table_hdr *)(ptr + offset + 4);
-                       break;
-               }
-               /* The next offset is stored in the 1st word.  0 means no more */
-               offset = *((unsigned short *)(ptr + offset));
-       }
-       if (!rio_table_hdr) {
-               printk(KERN_ERR "%s: Unable to locate Rio Grande Table in EBDA - bailing!\n", __func__);
-               return;
-       }
-
-       if (!build_detail_arrays())
-               return;
-
-       /* The first Winnipeg we're looking for has an index of 0 */
-       next_wpeg = 0;
-       do {
-               for (i = 0; i < rio_table_hdr->num_rio_dev; i++) {
-                       if (is_WPEG(rio_devs[i]) && rio_devs[i]->WP_index == next_wpeg) {
-                               /* It's the Winnipeg we're looking for! */
-                               next_bus = setup_pci_node_map_for_wpeg(i, next_bus);
-                               next_wpeg++;
-                               break;
-                       }
-               }
-               /*
-                * If we go through all Rio devices and don't find one with
-                * the next index, it means we've found all the Winnipegs,
-                * and thus all the PCI buses.
-                */
-               if (i == rio_table_hdr->num_rio_dev)
-                       next_wpeg = 0;
-       } while (next_wpeg != 0);
-}
-#endif
-
-struct apic apic_summit = {
-
-       .name                           = "summit",
-       .probe                          = probe_summit,
-       .acpi_madt_oem_check            = summit_acpi_madt_oem_check,
-       .apic_id_registered             = summit_apic_id_registered,
-
-       .irq_delivery_mode              = dest_LowestPrio,
-       /* logical delivery broadcast to all CPUs: */
-       .irq_dest_mode                  = 1,
-
-       .target_cpus                    = summit_target_cpus,
-       .disable_esr                    = 1,
-       .dest_logical                   = APIC_DEST_LOGICAL,
-       .check_apicid_used              = summit_check_apicid_used,
-       .check_apicid_present           = summit_check_apicid_present,
-
-       .vector_allocation_domain       = summit_vector_allocation_domain,
-       .init_apic_ldr                  = summit_init_apic_ldr,
-
-       .ioapic_phys_id_map             = summit_ioapic_phys_id_map,
-       .setup_apic_routing             = summit_setup_apic_routing,
-       .multi_timer_check              = NULL,
-       .apicid_to_node                 = summit_apicid_to_node,
-       .cpu_to_logical_apicid          = summit_cpu_to_logical_apicid,
-       .cpu_present_to_apicid          = summit_cpu_present_to_apicid,
-       .apicid_to_cpu_present          = summit_apicid_to_cpu_present,
-       .setup_portio_remap             = NULL,
-       .check_phys_apicid_present      = summit_check_phys_apicid_present,
-       .enable_apic_mode               = NULL,
-       .phys_pkg_id                    = summit_phys_pkg_id,
-       .mps_oem_check                  = summit_mps_oem_check,
-
-       .get_apic_id                    = summit_get_apic_id,
-       .set_apic_id                    = NULL,
-       .apic_id_mask                   = 0xFF << 24,
-
-       .cpu_mask_to_apicid             = summit_cpu_mask_to_apicid,
-       .cpu_mask_to_apicid_and         = summit_cpu_mask_to_apicid_and,
-
-       .send_IPI_mask                  = summit_send_IPI_mask,
-       .send_IPI_mask_allbutself       = NULL,
-       .send_IPI_allbutself            = summit_send_IPI_allbutself,
-       .send_IPI_all                   = summit_send_IPI_all,
-       .send_IPI_self                  = default_send_IPI_self,
-
-       .wakeup_cpu                     = NULL,
-       .trampoline_phys_low            = DEFAULT_TRAMPOLINE_PHYS_LOW,
-       .trampoline_phys_high           = DEFAULT_TRAMPOLINE_PHYS_HIGH,
-
-       .wait_for_init_deassert         = default_wait_for_init_deassert,
-
-       .smp_callin_clear_local_apic    = NULL,
-       .inquire_remote_apic            = default_inquire_remote_apic,
-
-       .read                           = native_apic_mem_read,
-       .write                          = native_apic_mem_write,
-       .icr_read                       = native_apic_icr_read,
-       .icr_write                      = native_apic_icr_write,
-       .wait_icr_idle                  = native_apic_wait_icr_idle,
-       .safe_wait_icr_idle             = native_safe_apic_wait_icr_idle,
-};