]> git.proxmox.com Git - mirror_ubuntu-zesty-kernel.git/blame - arch/x86_64/kernel/genapic.c
Merge master.kernel.org:/pub/scm/linux/kernel/git/herbert/crypto-2.6
[mirror_ubuntu-zesty-kernel.git] / arch / x86_64 / kernel / genapic.c
CommitLineData
1da177e4
LT
1/*
2 * Copyright 2004 James Cleverdon, IBM.
3 * Subject to the GNU Public License, v.2
4 *
5 * Generic APIC sub-arch probe layer.
6 *
7 * Hacked for x86-64 by James Cleverdon from i386 architecture code by
8 * Martin Bligh, Andi Kleen, James Bottomley, John Stultz, and
9 * James Cleverdon.
10 */
11#include <linux/config.h>
12#include <linux/threads.h>
13#include <linux/cpumask.h>
14#include <linux/string.h>
15#include <linux/kernel.h>
16#include <linux/ctype.h>
17#include <linux/init.h>
18#include <linux/module.h>
19
20#include <asm/smp.h>
21#include <asm/ipi.h>
22
76f58584 23#if defined(CONFIG_ACPI)
90660ec3
JD
24#include <acpi/acpi_bus.h>
25#endif
26
1da177e4 27/* which logical CPU number maps to which CPU (physical APIC ID) */
6c231b7b 28u8 x86_cpu_to_apicid[NR_CPUS] __read_mostly = { [0 ... NR_CPUS-1] = BAD_APICID };
1da177e4
LT
29EXPORT_SYMBOL(x86_cpu_to_apicid);
30u8 x86_cpu_to_log_apicid[NR_CPUS] = { [0 ... NR_CPUS-1] = BAD_APICID };
31
32extern struct genapic apic_cluster;
33extern struct genapic apic_flat;
f8d31193 34extern struct genapic apic_physflat;
1da177e4
LT
35
36struct genapic *genapic = &apic_flat;
37
38
39/*
40 * Check the APIC IDs in bios_cpu_apicid and choose the APIC mode.
41 */
42void __init clustered_apic_check(void)
43{
44 long i;
45 u8 clusters, max_cluster;
46 u8 id;
47 u8 cluster_cnt[NUM_APIC_CLUSTERS];
70556463 48 int max_apic = 0;
1da177e4 49
76f58584 50#if defined(CONFIG_ACPI)
90660ec3
JD
51 /*
52 * Some x86_64 machines use physical APIC mode regardless of how many
53 * procs/clusters are present (x86_64 ES7000 is an example).
54 */
55 if (acpi_fadt.revision > FADT2_REVISION_ID)
56 if (acpi_fadt.force_apic_physical_destination_mode) {
57 genapic = &apic_cluster;
58 goto print;
59 }
60#endif
61
1da177e4 62 memset(cluster_cnt, 0, sizeof(cluster_cnt));
1da177e4
LT
63 for (i = 0; i < NR_CPUS; i++) {
64 id = bios_cpu_apicid[i];
f8d31193
AK
65 if (id == BAD_APICID)
66 continue;
70556463
AK
67 if (id > max_apic)
68 max_apic = id;
f8d31193 69 cluster_cnt[APIC_CLUSTERID(id)]++;
1da177e4
LT
70 }
71
f8d31193
AK
72 /* Don't use clustered mode on AMD platforms. */
73 if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD) {
74 genapic = &apic_physflat;
016102de 75#ifndef CONFIG_HOTPLUG_CPU
f8d31193
AK
76 /* In the CPU hotplug case we cannot use broadcast mode
77 because that opens a race when a CPU is removed.
78 Stay at physflat mode in this case.
79 It is bad to do this unconditionally though. Once
80 we have ACPI platform support for CPU hotplug
81 we should detect hotplug capablity from ACPI tables and
82 only do this when really needed. -AK */
70556463 83 if (max_apic <= 8)
f8d31193
AK
84 genapic = &apic_flat;
85#endif
86 goto print;
87 }
88
1da177e4
LT
89 clusters = 0;
90 max_cluster = 0;
f8d31193 91
1da177e4
LT
92 for (i = 0; i < NUM_APIC_CLUSTERS; i++) {
93 if (cluster_cnt[i] > 0) {
94 ++clusters;
95 if (cluster_cnt[i] > max_cluster)
96 max_cluster = cluster_cnt[i];
97 }
98 }
99
100 /*
101 * If we have clusters <= 1 and CPUs <= 8 in cluster 0, then flat mode,
102 * else if max_cluster <= 4 and cluster_cnt[15] == 0, clustered logical
103 * else physical mode.
104 * (We don't use lowest priority delivery + HW APIC IRQ steering, so
105 * can ignore the clustered logical case and go straight to physical.)
106 */
5bf97e01
AK
107 if (clusters <= 1 && max_cluster <= 8 && cluster_cnt[0] == max_cluster) {
108#ifdef CONFIG_HOTPLUG_CPU
109 /* Don't use APIC shortcuts in CPU hotplug to avoid races */
110 genapic = &apic_physflat;
111#else
1da177e4 112 genapic = &apic_flat;
5bf97e01
AK
113#endif
114 } else
1da177e4
LT
115 genapic = &apic_cluster;
116
117print:
118 printk(KERN_INFO "Setting APIC routing to %s\n", genapic->name);
119}
120
121/* Same for both flat and clustered. */
122
123void send_IPI_self(int vector)
124{
125 __send_IPI_shortcut(APIC_DEST_SELF, vector, APIC_DEST_PHYSICAL);
126}