aboutsummaryrefslogtreecommitdiffstats
path: root/xen/arch/x86/genapic
diff options
context:
space:
mode:
authorKeir Fraser <keir.fraser@citrix.com>2008-05-01 11:34:56 +0100
committerKeir Fraser <keir.fraser@citrix.com>2008-05-01 11:34:56 +0100
commitb81f8a02e719ea650d3f87edd4c75cdb686df728 (patch)
tree6f714cabc7890ed7fe662ecbeb75be0640e59677 /xen/arch/x86/genapic
parent6176d3cd0bab4b90736e73da2db80e8aeb7f5e1d (diff)
downloadxen-b81f8a02e719ea650d3f87edd4c75cdb686df728.tar.gz
xen-b81f8a02e719ea650d3f87edd4c75cdb686df728.tar.bz2
xen-b81f8a02e719ea650d3f87edd4c75cdb686df728.zip
x86: Support x2APIC mode.
Signed-off-by: Dexuan Cui <dexuan.cui@intel.com>
Diffstat (limited to 'xen/arch/x86/genapic')
-rw-r--r--xen/arch/x86/genapic/Makefile1
-rw-r--r--xen/arch/x86/genapic/delivery.c2
-rw-r--r--xen/arch/x86/genapic/probe.c2
-rw-r--r--xen/arch/x86/genapic/x2apic.c79
4 files changed, 83 insertions, 1 deletions
diff --git a/xen/arch/x86/genapic/Makefile b/xen/arch/x86/genapic/Makefile
index 83e406d4f7..d6a8717d87 100644
--- a/xen/arch/x86/genapic/Makefile
+++ b/xen/arch/x86/genapic/Makefile
@@ -1,4 +1,5 @@
obj-y += bigsmp.o
+obj-y += x2apic.o
obj-y += default.o
obj-y += delivery.o
obj-y += probe.o
diff --git a/xen/arch/x86/genapic/delivery.c b/xen/arch/x86/genapic/delivery.c
index e343220f73..6327f1c029 100644
--- a/xen/arch/x86/genapic/delivery.c
+++ b/xen/arch/x86/genapic/delivery.c
@@ -17,7 +17,7 @@ void init_apic_ldr_flat(void)
apic_write_around(APIC_DFR, APIC_DFR_FLAT);
val = apic_read(APIC_LDR) & ~APIC_LDR_MASK;
- val |= SET_APIC_LOGICAL_ID(1UL << smp_processor_id());
+ val |= SET_xAPIC_LOGICAL_ID(1UL << smp_processor_id());
apic_write_around(APIC_LDR, val);
}
diff --git a/xen/arch/x86/genapic/probe.c b/xen/arch/x86/genapic/probe.c
index eaf1df24c7..295037e8cf 100644
--- a/xen/arch/x86/genapic/probe.c
+++ b/xen/arch/x86/genapic/probe.c
@@ -14,6 +14,7 @@
#include <asm/apicdef.h>
#include <asm/genapic.h>
+extern struct genapic apic_x2apic;
extern struct genapic apic_summit;
extern struct genapic apic_bigsmp;
extern struct genapic apic_default;
@@ -21,6 +22,7 @@ extern struct genapic apic_default;
struct genapic *genapic;
struct genapic *apic_probe[] __initdata = {
+ &apic_x2apic,
&apic_summit,
&apic_bigsmp,
&apic_default, /* must be last */
diff --git a/xen/arch/x86/genapic/x2apic.c b/xen/arch/x86/genapic/x2apic.c
new file mode 100644
index 0000000000..bfd3a286e3
--- /dev/null
+++ b/xen/arch/x86/genapic/x2apic.c
@@ -0,0 +1,79 @@
+/*
+ * x2APIC driver.
+ *
+ * Copyright (c) 2008, Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. 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., 59 Temple
+ * Place - Suite 330, Boston, MA 02111-1307 USA.
+ */
+
+#include <xen/cpumask.h>
+#include <asm/apicdef.h>
+#include <asm/genapic.h>
+#include <xen/smp.h>
+#include <asm/mach-default/mach_mpparse.h>
+
+__init int probe_x2apic(void)
+{
+ return x2apic_is_available();
+}
+
+struct genapic apic_x2apic= {
+ APIC_INIT("x2apic", probe_x2apic),
+ GENAPIC_X2APIC
+};
+
+void init_apic_ldr_x2apic(void)
+{
+ /* We only use physical delivery mode. */
+ return;
+}
+
+void clustered_apic_check_x2apic(void)
+{
+ /* We only use physical delivery mode. */
+ return;
+}
+
+cpumask_t target_cpus_x2apic(void)
+{
+ /* Deliver interrupts only to CPU0 for now */
+ return cpumask_of_cpu(0);
+}
+
+unsigned int cpu_mask_to_apicid_x2apic(cpumask_t cpumask)
+{
+ return cpu_physical_id(first_cpu(cpumask));
+}
+
+void send_IPI_mask_x2apic(cpumask_t cpumask, int vector)
+{
+ unsigned int query_cpu;
+ u32 cfg, dest;
+ unsigned long flags;
+
+ ASSERT(cpus_subset(cpumask, cpu_online_map));
+ ASSERT(!cpus_empty(cpumask));
+
+ local_irq_save(flags);
+
+ cfg = APIC_DM_FIXED | 0 /* no shorthand */ | APIC_DEST_PHYSICAL | vector;
+ for_each_cpu_mask(query_cpu, cpumask)
+ {
+ dest = cpu_physical_id(query_cpu);
+ apic_icr_write(cfg, dest);
+ }
+
+ local_irq_restore(flags);
+}
+