diff options
author | Keir Fraser <keir.fraser@citrix.com> | 2009-09-07 08:46:46 +0100 |
---|---|---|
committer | Keir Fraser <keir.fraser@citrix.com> | 2009-09-07 08:46:46 +0100 |
commit | b8fae2f7774ee716e2aa6eda67624fc61ab31bce (patch) | |
tree | 6ff77dff87e2cd10b3cae847b1c58725cb25bb38 /xen/arch/x86/genapic | |
parent | 5c53154b6190af523ec097dbb76c41685052dddd (diff) | |
download | xen-b8fae2f7774ee716e2aa6eda67624fc61ab31bce.tar.gz xen-b8fae2f7774ee716e2aa6eda67624fc61ab31bce.tar.bz2 xen-b8fae2f7774ee716e2aa6eda67624fc61ab31bce.zip |
Add the support of x2apic logical cluster mode.
Add a xen boolean parameter 'x2apic'.
Add a xen boolean parameter 'x2apic_phys'(by default, we use logical
cluster mode).
Signed-off-by: Dexuan Cui <dexuan.cui@intel.com>
Diffstat (limited to 'xen/arch/x86/genapic')
-rw-r--r-- | xen/arch/x86/genapic/x2apic.c | 62 |
1 files changed, 52 insertions, 10 deletions
diff --git a/xen/arch/x86/genapic/x2apic.c b/xen/arch/x86/genapic/x2apic.c index 40d54e4d22..c57a66eeac 100644 --- a/xen/arch/x86/genapic/x2apic.c +++ b/xen/arch/x86/genapic/x2apic.c @@ -23,25 +23,46 @@ #include <xen/smp.h> #include <asm/mach-default/mach_mpparse.h> -__init int probe_x2apic(void) +static int x2apic = 1; +boolean_param("x2apic", x2apic); + +static int x2apic_phys = 0; /* By default we use logical cluster mode. */ +boolean_param("x2apic_phys", x2apic_phys); + +__init int probe_x2apic_phys(void) +{ + return x2apic && x2apic_phys && x2apic_is_available() && + iommu_supports_eim(); +} + +__init int probe_x2apic_cluster(void) { - return x2apic_is_available(); + return x2apic && !x2apic_phys && x2apic_is_available() && + iommu_supports_eim(); } -struct genapic apic_x2apic= { - APIC_INIT("x2apic", probe_x2apic), - GENAPIC_X2APIC +struct genapic apic_x2apic_phys= { + APIC_INIT("x2apic_phys", probe_x2apic_phys), + GENAPIC_X2APIC_PHYS +}; + +struct genapic apic_x2apic_cluster= { + APIC_INIT("x2apic_cluster", probe_x2apic_cluster), + GENAPIC_X2APIC_CLUSTER }; -void init_apic_ldr_x2apic(void) +void init_apic_ldr_x2apic_phys(void) { - /* We only use physical delivery mode. */ return; } +void init_apic_ldr_x2apic_cluster(void) +{ + int cpu = smp_processor_id(); + cpu_2_logical_apicid[cpu] = apic_read(APIC_LDR); +} void clustered_apic_check_x2apic(void) { - /* We only use physical delivery mode. */ return; } @@ -55,12 +76,17 @@ cpumask_t vector_allocation_domain_x2apic(int cpu) return cpumask_of_cpu(cpu); } -unsigned int cpu_mask_to_apicid_x2apic(cpumask_t cpumask) +unsigned int cpu_mask_to_apicid_x2apic_phys(cpumask_t cpumask) { return cpu_physical_id(first_cpu(cpumask)); } -void send_IPI_mask_x2apic(const cpumask_t *cpumask, int vector) +unsigned int cpu_mask_to_apicid_x2apic_cluster(cpumask_t cpumask) +{ + return cpu_2_logical_apicid[first_cpu(cpumask)]; +} + +void send_IPI_mask_x2apic_phys(const cpumask_t *cpumask, int vector) { unsigned int cpu, cfg; unsigned long flags; @@ -87,3 +113,19 @@ void send_IPI_mask_x2apic(const cpumask_t *cpumask, int vector) local_irq_restore(flags); } +void send_IPI_mask_x2apic_cluster(const cpumask_t *cpumask, int vector) +{ + unsigned int cpu, cfg; + unsigned long flags; + + mb(); /* see the comment in send_IPI_mask_x2apic_phys() */ + + local_irq_save(flags); + + cfg = APIC_DM_FIXED | 0 /* no shorthand */ | APIC_DEST_LOGICAL | vector; + for_each_cpu_mask ( cpu, *cpumask ) + if ( cpu != smp_processor_id() ) + apic_wrmsr(APIC_ICR, cfg, cpu_2_logical_apicid[cpu]); + + local_irq_restore(flags); +} |