2002-10-16 23:04:26

by john stultz

[permalink] [raw]
Subject: [PATCH] linux-2.4.20-pre11_clustered-apic-tweaks_A0

Marcelo, all,

Originally I was going to send a larger patch that had the rest of the
needed changes for summit, but I've gone through and split that up even
more. This is similar to the earlier cleanup I sent you (although this
one compiles & boots on UP properly :), and just moves some code around
in preparation for further changes.

Again, this code originally comes from James Cleverdon's summit patch,
which I have been chopping/crushing/blending up into hopefully more
easily digestible pieces. Thus I deserve none of the credit, and all the
blame for this.

please consider for acceptance.

thanks
-john

diff -Nru a/arch/i386/kernel/apic.c b/arch/i386/kernel/apic.c
--- a/arch/i386/kernel/apic.c Wed Oct 16 15:52:39 2002
+++ b/arch/i386/kernel/apic.c Wed Oct 16 15:52:39 2002
@@ -261,6 +261,14 @@
apic_write_around(APIC_LVT1, value);
}

+static unsigned long calculate_ldr(unsigned long old)
+{
+ unsigned long id;
+
+ id = 1UL << smp_processor_id();
+ return (old & ~APIC_LDR_MASK)|SET_APIC_LOGICAL_ID(id);
+}
+
void __init setup_local_APIC (void)
{
unsigned long value, ver, maxlvt;
@@ -304,9 +312,7 @@
* Set up the logical destination ID.
*/
value = apic_read(APIC_LDR);
- value &= ~APIC_LDR_MASK;
- value |= (1<<(smp_processor_id()+24));
- apic_write_around(APIC_LDR, value);
+ apic_write_around(APIC_LDR, calculate_ldr(value));
}

/*
diff -Nru a/arch/i386/kernel/io_apic.c b/arch/i386/kernel/io_apic.c
--- a/arch/i386/kernel/io_apic.c Wed Oct 16 15:52:39 2002
+++ b/arch/i386/kernel/io_apic.c Wed Oct 16 15:52:39 2002
@@ -1067,7 +1067,7 @@

old_id = mp_ioapics[apic].mpc_apicid;

- if (mp_ioapics[apic].mpc_apicid >= 0xf) {
+ if (mp_ioapics[apic].mpc_apicid >= apic_broadcast_id) {
printk(KERN_ERR "BIOS bug, IO-APIC#%d ID is %d in the MPC table!...\n",
apic, mp_ioapics[apic].mpc_apicid);
printk(KERN_ERR "... fixing up to %d. (tell your hw vendor)\n",
@@ -1086,7 +1086,7 @@
for (i = 0; i < 0xf; i++)
if (!(phys_id_present_map & (1 << i)))
break;
- if (i >= 0xf)
+ if (i >= apic_broadcast_id)
panic("Max APIC ID exceeded!\n");
printk(KERN_ERR "... fixing up to %d. (tell your hw vendor)\n",
i);
diff -Nru a/include/asm-i386/smpboot.h b/include/asm-i386/smpboot.h
--- a/include/asm-i386/smpboot.h Wed Oct 16 15:52:39 2002
+++ b/include/asm-i386/smpboot.h Wed Oct 16 15:52:39 2002
@@ -41,6 +41,9 @@
#endif /* CONFIG_X86_IO_APIC */
#endif /* CONFIG_X86_LOCAL_APIC */

+#define apic_broadcast_id (APIC_BROADCAST_ID_APIC)
+
+
#define TRAMPOLINE_LOW phys_to_virt((clustered_apic_mode == CLUSTERED_APIC_NUMAQ)?0x8:0x467)
#define TRAMPOLINE_HIGH phys_to_virt((clustered_apic_mode == CLUSTERED_APIC_NUMAQ)?0xa:0x469)





2002-10-17 00:07:22

by john stultz

[permalink] [raw]
Subject: [PATCH] linux-2.4.20-pre11_summit_A0 (1/3 - cleanups)

Marcelo, all,

I'm probably pressing my luck w/ this, but since the tree doesn't say
-rc, I might as well send this off. This is the first chunk of the
clustered apic changes needed for summit (all of which comes from James
Cleverdon's summit patch. Thank him, blame me). This patch is mainly
cleanups, but adds some code to setup phys_cpu_present_map more
generally for clustered apic systems. It is also dependent on the
clustered-apic-tweaks_A0 patch I sent out earlier today.

Two more patches should follow.

please consider for acceptance.

thanks
-john

diff -Nru a/arch/i386/kernel/mpparse.c b/arch/i386/kernel/mpparse.c
--- a/arch/i386/kernel/mpparse.c Wed Oct 16 16:55:58 2002
+++ b/arch/i386/kernel/mpparse.c Wed Oct 16 16:55:58 2002
@@ -65,9 +65,12 @@

/* Bitmask of physically existing CPUs */
unsigned long phys_cpu_present_map;
+unsigned long logical_cpu_present_map;

unsigned char esr_disable = 0;

+unsigned char raw_phys_apicid[NR_CPUS] = { [0 ... NR_CPUS-1] = BAD_APICID };
+
/*
* Intel MP BIOS table parsing routines:
*/
@@ -231,11 +234,9 @@
}
ver = m->mpc_apicver;

- if (clustered_apic_mode == CLUSTERED_APIC_NUMAQ) {
- phys_cpu_present_map |= (logical_apicid&0xf) << (4*quad);
- } else {
- phys_cpu_present_map |= 1 << m->mpc_apicid;
- }
+ logical_cpu_present_map |= 1 << (num_processors-1);
+ phys_cpu_present_map |= apicid_to_phys_cpu_present(m->mpc_apicid);
+
/*
* Validate version
*/
@@ -244,6 +245,7 @@
ver = 0x10;
}
apic_version[m->mpc_apicid] = ver;
+ raw_phys_apicid[num_processors - 1] = m->mpc_apicid;
}

static void __init MP_bus_info (struct mpc_config_bus *m)
@@ -511,6 +513,7 @@

if (clustered_apic_mode){
esr_disable = 1;
+ phys_cpu_present_map = logical_cpu_present_map;
}

if (!num_processors)
diff -Nru a/arch/i386/kernel/smpboot.c b/arch/i386/kernel/smpboot.c
--- a/arch/i386/kernel/smpboot.c Wed Oct 16 16:55:58 2002
+++ b/arch/i386/kernel/smpboot.c Wed Oct 16 16:55:58 2002
@@ -525,12 +525,12 @@
int apicid, cpu;

for (apicid = 0; apicid < MAX_APICID; apicid++) {
- physical_apicid_2_cpu[apicid] = -1;
- logical_apicid_2_cpu[apicid] = -1;
+ physical_apicid_2_cpu[apicid] = BAD_APICID;
+ logical_apicid_2_cpu[apicid] = BAD_APICID;
}
for (cpu = 0; cpu < NR_CPUS; cpu++) {
- cpu_2_physical_apicid[cpu] = -1;
- cpu_2_logical_apicid[cpu] = -1;
+ cpu_2_physical_apicid[cpu] = BAD_APICID;
+ cpu_2_logical_apicid[cpu] = BAD_APICID;
}
}

@@ -540,7 +540,7 @@
* else physical apic ids
*/
{
- if (clustered_apic_mode) {
+ if (clustered_apic_mode == CLUSTERED_APIC_NUMAQ) {
logical_apicid_2_cpu[apicid] = cpu;
cpu_2_logical_apicid[cpu] = apicid;
} else {
@@ -555,12 +555,12 @@
* else physical apic ids
*/
{
- if (clustered_apic_mode) {
- logical_apicid_2_cpu[apicid] = -1;
- cpu_2_logical_apicid[cpu] = -1;
+ if (clustered_apic_mode == CLUSTERED_APIC_NUMAQ) {
+ logical_apicid_2_cpu[apicid] = BAD_APICID;
+ cpu_2_logical_apicid[cpu] = BAD_APICID;
} else {
- physical_apicid_2_cpu[apicid] = -1;
- cpu_2_physical_apicid[cpu] = -1;
+ physical_apicid_2_cpu[apicid] = BAD_APICID;
+ cpu_2_physical_apicid[cpu] = BAD_APICID;
}
}

@@ -785,7 +785,7 @@
unsigned long boot_error = 0;
int timeout, cpu;
unsigned long start_eip;
- unsigned short nmi_high, nmi_low;
+ unsigned short nmi_high = 0, nmi_low = 0;

cpu = ++cpucount;
/*
@@ -1111,7 +1111,7 @@
if (apicid == boot_cpu_apicid)
continue;

- if (!(phys_cpu_present_map & (1 << bit)))
+ if (!(phys_cpu_present_map & (1ul << bit)))
continue;
if ((max_cpus >= 0) && (max_cpus <= cpucount+1))
continue;
@@ -1122,9 +1122,9 @@
* Make sure we unmap all failed CPUs
*/
if ((boot_apicid_to_cpu(apicid) == -1) &&
- (phys_cpu_present_map & (1 << bit)))
- printk("CPU #%d not responding - cannot use it.\n",
- apicid);
+ (phys_cpu_present_map & (1ul << bit)))
+ printk("CPU #%d/0x%02x not responding - cannot use it.\n",
+ bit, apicid);
}

/*
diff -Nru a/include/asm-i386/smpboot.h b/include/asm-i386/smpboot.h
--- a/include/asm-i386/smpboot.h Wed Oct 16 16:55:58 2002
+++ b/include/asm-i386/smpboot.h Wed Oct 16 16:55:58 2002
@@ -42,13 +42,15 @@
#endif /* CONFIG_X86_LOCAL_APIC */

#define apic_broadcast_id (APIC_BROADCAST_ID_APIC)
-
+#define BAD_APICID 0xFFu

#define TRAMPOLINE_LOW phys_to_virt((clustered_apic_mode == CLUSTERED_APIC_NUMAQ)?0x8:0x467)
#define TRAMPOLINE_HIGH phys_to_virt((clustered_apic_mode == CLUSTERED_APIC_NUMAQ)?0xa:0x469)

#define boot_cpu_apicid ((clustered_apic_mode == CLUSTERED_APIC_NUMAQ)?boot_cpu_logical_apicid:boot_cpu_physical_apicid)

+extern unsigned char raw_phys_apicid[NR_CPUS];
+
/*
* How to map from the cpu_present_map
*/
@@ -57,6 +59,13 @@
if(clustered_apic_mode == CLUSTERED_APIC_NUMAQ)
return (mps_cpu/4)*16 + (1<<(mps_cpu%4));
return mps_cpu;
+}
+
+static inline unsigned long apicid_to_phys_cpu_present(int apicid)
+{
+ if(clustered_apic_mode)
+ return 1UL << (((apicid >> 4) << 2) + (apicid & 0x3));
+ return 1UL << apicid;
}

#define physical_to_logical_apicid(phys_apic) ( (1ul << (phys_apic & 0x3)) | (phys_apic & 0xF0u) )

2002-10-17 00:42:07

by john stultz

[permalink] [raw]
Subject: [PATCH] linux-2.4.20-pre11_summit_A0 (2/3 - XAPIC code)

Marcelo, all,
Part 2 of James Cleverdon's clustered apic changes for summit. This is
the core addition of code to make summit work. Since nothing sets
clustered_apic_mode to CLUSTERED_APIC_XAPIC yet, this patch shouldn't
affect anything.

please consider for inclusion.

thanks
-john

diff -Nru a/arch/i386/kernel/apic.c b/arch/i386/kernel/apic.c
--- a/arch/i386/kernel/apic.c Wed Oct 16 17:38:49 2002
+++ b/arch/i386/kernel/apic.c Wed Oct 16 17:38:49 2002
@@ -264,8 +264,10 @@
static unsigned long calculate_ldr(unsigned long old)
{
unsigned long id;
-
- id = 1UL << smp_processor_id();
+ if(clustered_apic_mode == CLUSTERED_APIC_XAPIC)
+ id = physical_to_logical_apicid(hard_smp_processor_id());
+ else
+ id = 1UL << smp_processor_id();
return (old & ~APIC_LDR_MASK)|SET_APIC_LOGICAL_ID(id);
}

@@ -306,7 +308,10 @@
* for us. Otherwise put the APIC into clustered or flat
* delivery mode. Must be "all ones" explicitly for 82489DX.
*/
- apic_write_around(APIC_DFR, APIC_DFR_FLAT);
+ if(clustered_apic_mode == CLUSTERED_APIC_XAPIC)
+ apic_write_around(APIC_DFR, APIC_DFR_CLUSTER);
+ else
+ apic_write_around(APIC_DFR, APIC_DFR_FLAT);

/*
* Set up the logical destination ID.
diff -Nru a/arch/i386/kernel/io_apic.c b/arch/i386/kernel/io_apic.c
--- a/arch/i386/kernel/io_apic.c Wed Oct 16 17:38:49 2002
+++ b/arch/i386/kernel/io_apic.c Wed Oct 16 17:38:49 2002
@@ -1079,8 +1079,10 @@
* Sanity check, is the ID really free? Every APIC in a
* system must have a unique ID or we get lots of nice
* 'stuck on smp_invalidate_needed IPI wait' messages.
+ * I/O APIC IDs no longer have any meaning for xAPICs and SAPICs.
*/
- if (phys_id_present_map & (1 << mp_ioapics[apic].mpc_apicid)) {
+ if ((clustered_apic_mode != CLUSTERED_APIC_XAPIC) &&
+ (phys_id_present_map & (1 << mp_ioapics[apic].mpc_apicid))) {
printk(KERN_ERR "BIOS bug, IO-APIC#%d ID %d is already used!...\n",
apic, mp_ioapics[apic].mpc_apicid);
for (i = 0; i < 0xf; i++)
diff -Nru a/arch/i386/kernel/smp.c b/arch/i386/kernel/smp.c
--- a/arch/i386/kernel/smp.c Wed Oct 16 17:38:49 2002
+++ b/arch/i386/kernel/smp.c Wed Oct 16 17:38:49 2002
@@ -214,7 +214,10 @@
/*
* prepare target chip field
*/
- cfg = __prepare_ICR2(cpu_to_logical_apicid(query_cpu));
+ if(clustered_apic_mode == CLUSTERED_APIC_XAPIC)
+ cfg = __prepare_ICR2(cpu_to_physical_apicid(query_cpu));
+ else
+ cfg = __prepare_ICR2(cpu_to_logical_apicid(query_cpu));
apic_write_around(APIC_ICR2, cfg);

/*
diff -Nru a/arch/i386/kernel/smpboot.c b/arch/i386/kernel/smpboot.c
--- a/arch/i386/kernel/smpboot.c Wed Oct 16 17:38:49 2002
+++ b/arch/i386/kernel/smpboot.c Wed Oct 16 17:38:49 2002
@@ -1019,7 +1019,10 @@
* We have the boot CPU online for sure.
*/
set_bit(0, &cpu_online_map);
- boot_cpu_logical_apicid = logical_smp_processor_id();
+ if (clustered_apic_mode == CLUSTERED_APIC_XAPIC)
+ boot_cpu_logical_apicid = physical_to_logical_apicid(boot_cpu_physical_apicid);
+ else
+ boot_cpu_logical_apicid = logical_smp_processor_id();
map_cpu_to_boot_apicid(0, boot_cpu_apicid);

global_irq_holder = 0;
diff -Nru a/include/asm-i386/apicdef.h b/include/asm-i386/apicdef.h
--- a/include/asm-i386/apicdef.h Wed Oct 16 17:38:49 2002
+++ b/include/asm-i386/apicdef.h Wed Oct 16 17:38:49 2002
@@ -32,6 +32,7 @@
#define SET_APIC_LOGICAL_ID(x) (((x)<<24))
#define APIC_ALL_CPUS 0xFF
#define APIC_DFR 0xE0
+#define APIC_DFR_CLUSTER 0x0FFFFFFFul /* Clustered */
#define APIC_DFR_FLAT 0xFFFFFFFFul /* Flat mode */
#define APIC_SPIV 0xF0
#define APIC_SPIV_FOCUS_DISABLED (1<<9)
@@ -58,6 +59,7 @@
#define APIC_INT_LEVELTRIG 0x08000
#define APIC_INT_ASSERT 0x04000
#define APIC_ICR_BUSY 0x01000
+#define APIC_DEST_PHYSICAL 0x00000
#define APIC_DEST_LOGICAL 0x00800
#define APIC_DM_FIXED 0x00000
#define APIC_DM_LOWEST 0x00100
@@ -111,8 +113,10 @@
#define MAX_IO_APICS 8

/*
- * The broadcast ID is 0xF for old APICs.
+ * The broadcast ID is 0xF for old APICs and 0xFF for xAPICs. SAPICs
+ * don't broadcast (yet?), but if they did, they might use 0xFFFF.
*/
+#define APIC_BROADCAST_ID_XAPIC (0xFF)
#define APIC_BROADCAST_ID_APIC (0x0F)

/*
diff -Nru a/include/asm-i386/smpboot.h b/include/asm-i386/smpboot.h
--- a/include/asm-i386/smpboot.h Wed Oct 16 17:38:49 2002
+++ b/include/asm-i386/smpboot.h Wed Oct 16 17:38:49 2002
@@ -56,6 +56,8 @@
*/
static inline int cpu_present_to_apicid(int mps_cpu)
{
+ if (clustered_apic_mode == CLUSTERED_APIC_XAPIC)
+ return raw_phys_apicid[mps_cpu];
if(clustered_apic_mode == CLUSTERED_APIC_NUMAQ)
return (mps_cpu/4)*16 + (1<<(mps_cpu%4));
return mps_cpu;


2002-10-17 03:57:04

by john stultz

[permalink] [raw]
Subject: [PATCH] linux-2.4.20-pre11_summit_A0 (3/3 - Integration)

Marcelo, all,
Better late then never, here is the final patch needed to get the
summit based x440 booting w/ all CPUs. This patch (originally by James
Cleverdon)introduces config options similar to 2.5, enables
autodetection of x440 and NUMAQ hardware, and adds the last bit of
required changes (enlarged MAX_IO_APICS, etc - all wrapped in
CONFIG_X86_CLUSTERED_APIC).

Compiles and boots on:
o NUMAQ
o x440
o SMP
o UP

please consider for inclusion.

thanks
-john


diff -Nru a/Documentation/Configure.help b/Documentation/Configure.help
--- a/Documentation/Configure.help Wed Oct 16 20:38:05 2002
+++ b/Documentation/Configure.help Wed Oct 16 20:38:05 2002
@@ -246,13 +246,21 @@

If unsure, say N.

-Multiquad support for NUMA systems
-CONFIG_MULTIQUAD
+Multiquad support for NUMAQ systems
+CONFIG_X86_NUMAQ
This option is used for getting Linux to run on a (IBM/Sequent) NUMA
multiquad box. This changes the way that processors are bootstrapped,
and uses Clustered Logical APIC addressing mode instead of Flat Logical.
You will need a new lynxer.elf file to flash your firmware with - send
email to [email protected]
+
+Support for IBM Summit (EXA) systems
+CONFIG_X86_SUMMIT
+ This option is needed for IBM systems that use the Summit/EXA chipset.
+ (EXA: Extendable Xseries Architecture)In particular, it is needed for
+ the x440 (even for the 4-CPU model).
+
+ If you don't have this computer, you may safely say N.

IO-APIC support on uniprocessors
CONFIG_X86_UP_IOAPIC
diff -Nru a/arch/i386/config.in b/arch/i386/config.in
--- a/arch/i386/config.in Wed Oct 16 20:38:05 2002
+++ b/arch/i386/config.in Wed Oct 16 20:38:05 2002
@@ -216,7 +216,19 @@
define_bool CONFIG_X86_IO_APIC y
fi
else
- bool 'Multiquad NUMA system' CONFIG_MULTIQUAD
+ bool 'Multi-node NUMA system support' CONFIG_X86_NUMA
+ if [ "$CONFIG_X86_NUMA" = "y" ]; then
+ #Platform Choices
+ bool ' Multiquad (IBM/Sequent) NUMAQ support' CONFIG_X86_NUMAQ
+ if [ "$CONFIG_X86_NUMAQ" = "y" ]; then
+ define_bool CONFIG_X86_CLUSTERED_APIC y
+ define_bool CONFIG_MULTIQUAD y
+ fi
+ bool ' IBM x440 (Summit/EXA) support' CONFIG_X86_SUMMIT
+ if [ "$CONFIG_X86_SUMMIT" = "y" ]; then
+ define_bool CONFIG_X86_CLUSTERED_APIC y
+ fi
+ fi
fi

bool 'Unsynced TSC support' CONFIG_X86_TSC_DISABLE
diff -Nru a/arch/i386/kernel/mpparse.c b/arch/i386/kernel/mpparse.c
--- a/arch/i386/kernel/mpparse.c Wed Oct 16 20:38:05 2002
+++ b/arch/i386/kernel/mpparse.c Wed Oct 16 20:38:05 2002
@@ -67,8 +67,11 @@
unsigned long phys_cpu_present_map;
unsigned long logical_cpu_present_map;

+#ifdef CONFIG_X86_CLUSTERED_APIC
unsigned char esr_disable = 0;
-
+unsigned char clustered_apic_mode = CLUSTERED_APIC_NONE;
+unsigned int apic_broadcast_id = APIC_BROADCAST_ID_APIC;
+#endif
unsigned char raw_phys_apicid[NR_CPUS] = { [0 ... NR_CPUS-1] = BAD_APICID };

/*
@@ -400,7 +403,7 @@

static int __init smp_read_mpc(struct mp_config_table *mpc)
{
- char str[16];
+ char oem[16], prod[14];
int count=sizeof(*mpc);
unsigned char *mpt=((unsigned char *)mpc)+count;

@@ -425,14 +428,16 @@
printk(KERN_ERR "SMP mptable: null local APIC address!\n");
return 0;
}
- memcpy(str,mpc->mpc_oem,8);
- str[8]=0;
- printk("OEM ID: %s ",str);
-
- memcpy(str,mpc->mpc_productid,12);
- str[12]=0;
- printk("Product ID: %s ",str);
+ memcpy(oem,mpc->mpc_oem,8);
+ oem[8]=0;
+ printk("OEM ID: %s ",oem);
+
+ memcpy(prod,mpc->mpc_productid,12);
+ prod[12]=0;
+ printk("Product ID: %s ",prod);

+ detect_clustered_apic(oem, prod);
+
printk("APIC at: 0x%lX\n",mpc->mpc_lapic);

/* save the local APIC address, it might be non-default,
@@ -512,9 +517,18 @@
}

if (clustered_apic_mode){
- esr_disable = 1;
phys_cpu_present_map = logical_cpu_present_map;
}
+
+
+ printk("Enabling APIC mode: ");
+ if(clustered_apic_mode == CLUSTERED_APIC_NUMAQ)
+ printk("Clustered Logical. ");
+ else if(clustered_apic_mode == CLUSTERED_APIC_XAPIC)
+ printk("Physical. ");
+ else
+ printk("Flat. ");
+ printk("Using %d I/O APICs\n",nr_ioapics);

if (!num_processors)
printk(KERN_ERR "SMP mptable: no processors registered!\n");
diff -Nru a/include/asm-i386/apicdef.h b/include/asm-i386/apicdef.h
--- a/include/asm-i386/apicdef.h Wed Oct 16 20:38:05 2002
+++ b/include/asm-i386/apicdef.h Wed Oct 16 20:38:05 2002
@@ -110,7 +110,12 @@

#define APIC_BASE (fix_to_virt(FIX_APIC_BASE))

+#ifdef CONFIG_X86_CLUSTERED_APIC
+#define MAX_IO_APICS 32
+#else
#define MAX_IO_APICS 8
+#endif
+

/*
* The broadcast ID is 0xF for old APICs and 0xFF for xAPICs. SAPICs
diff -Nru a/include/asm-i386/mpspec.h b/include/asm-i386/mpspec.h
--- a/include/asm-i386/mpspec.h Wed Oct 16 20:38:05 2002
+++ b/include/asm-i386/mpspec.h Wed Oct 16 20:38:05 2002
@@ -15,12 +15,13 @@

/*
* a maximum of 16 APICs with the current APIC ID architecture.
+ * xAPICs can have up to 256. SAPICs have 16 ID bits.
*/
-#ifdef CONFIG_MULTIQUAD
+#ifdef CONFIG_X86_CLUSTERED_APIC
#define MAX_APICS 256
-#else /* !CONFIG_MULTIQUAD */
+#else
#define MAX_APICS 16
-#endif /* CONFIG_MULTIQUAD */
+#endif

#define MAX_MPC_ENTRY 1024

diff -Nru a/include/asm-i386/smpboot.h b/include/asm-i386/smpboot.h
--- a/include/asm-i386/smpboot.h Wed Oct 16 20:38:05 2002
+++ b/include/asm-i386/smpboot.h Wed Oct 16 20:38:05 2002
@@ -8,13 +8,9 @@
CLUSTERED_APIC_NUMAQ
};

-#ifdef CONFIG_MULTIQUAD
- #define clustered_apic_mode (CLUSTERED_APIC_NUMAQ)
-#else /* !CONFIG_MULTIQUAD */
- #define clustered_apic_mode (CLUSTERED_APIC_NONE)
-#endif /* CONFIG_MULTIQUAD */
-
-#ifdef CONFIG_X86_LOCAL_APIC
+#ifdef CONFIG_X86_CLUSTERED_APIC
+extern unsigned int apic_broadcast_id;
+extern unsigned char clustered_apic_mode;
extern unsigned char esr_disable;
static inline int target_cpus(void)
{
@@ -26,22 +22,39 @@
}
return cpu_online_map;
}
-#ifdef CONFIG_X86_IO_APIC
extern unsigned char int_delivery_mode;
extern unsigned int int_dest_addr_mode;
+static inline void detect_clustered_apic(char* oem, char* prod)
+{
+ /*
+ * Can't recognize Summit xAPICs at present, so use the OEM ID.
+ */
+ if (!strncmp(oem, "IBM ENSW", 8) && !strncmp(prod, "VIGIL SMP", 9)){
+ clustered_apic_mode = CLUSTERED_APIC_XAPIC;
+ apic_broadcast_id = APIC_BROADCAST_ID_XAPIC;
+ int_dest_addr_mode = APIC_DEST_PHYSICAL;
+ int_delivery_mode = dest_Fixed;
+ esr_disable = 1;
+ }
+ else if (!strncmp(oem, "IBM NUMA", 8)){
+ clustered_apic_mode = CLUSTERED_APIC_NUMAQ;
+ apic_broadcast_id = APIC_BROADCAST_ID_APIC;
+ int_dest_addr_mode = APIC_DEST_LOGICAL;
+ int_delivery_mode = dest_LowestPrio;
+ esr_disable = 1;
+ }
+}
#define INT_DEST_ADDR_MODE (int_dest_addr_mode)
#define INT_DELIVERY_MODE (int_delivery_mode)
-#endif /* CONFIG_X86_IO_APIC */
-#else /* CONFIG_X86_LOCAL_APIC */
+#else /* CONFIG_X86_CLUSTERED_APIC */
+#define apic_broadcast_id (APIC_BROADCAST_ID_APIC)
+#define clustered_apic_mode (CLUSTERED_APIC_NONE)
#define esr_disable (0)
#define target_cpus() (0x01)
-#ifdef CONFIG_X86_IO_APIC
+#define detect_clustered_apic(x,y)
#define INT_DEST_ADDR_MODE (APIC_DEST_LOGICAL) /* logical delivery */
#define INT_DELIVERY_MODE (dest_LowestPrio)
-#endif /* CONFIG_X86_IO_APIC */
-#endif /* CONFIG_X86_LOCAL_APIC */
-
-#define apic_broadcast_id (APIC_BROADCAST_ID_APIC)
+#endif /* CONFIG_X86_CLUSTERED_APIC */
#define BAD_APICID 0xFFu

#define TRAMPOLINE_LOW phys_to_virt((clustered_apic_mode == CLUSTERED_APIC_NUMAQ)?0x8:0x467)