]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blob - arch/x86/kernel/probe_32.c
x86: remove subarchitecture support code
[mirror_ubuntu-bionic-kernel.git] / arch / x86 / kernel / probe_32.c
1 /*
2 * Default generic APIC driver. This handles up to 8 CPUs.
3 *
4 * Copyright 2003 Andi Kleen, SuSE Labs.
5 * Subject to the GNU Public License, v.2
6 *
7 * Generic x86 APIC driver probe layer.
8 */
9 #include <linux/threads.h>
10 #include <linux/cpumask.h>
11 #include <linux/string.h>
12 #include <linux/kernel.h>
13 #include <linux/ctype.h>
14 #include <linux/init.h>
15 #include <linux/errno.h>
16 #include <asm/fixmap.h>
17 #include <asm/mpspec.h>
18 #include <asm/apicdef.h>
19 #include <asm/genapic.h>
20 #include <asm/setup.h>
21
22 #include <linux/threads.h>
23 #include <linux/cpumask.h>
24 #include <asm/mpspec.h>
25 #include <asm/genapic.h>
26 #include <asm/fixmap.h>
27 #include <asm/apicdef.h>
28 #include <linux/kernel.h>
29 #include <linux/string.h>
30 #include <linux/smp.h>
31 #include <linux/init.h>
32 #include <asm/genapic.h>
33 #include <asm/ipi.h>
34
35 static void default_vector_allocation_domain(int cpu, struct cpumask *retmask)
36 {
37 /*
38 * Careful. Some cpus do not strictly honor the set of cpus
39 * specified in the interrupt destination when using lowest
40 * priority interrupt delivery mode.
41 *
42 * In particular there was a hyperthreading cpu observed to
43 * deliver interrupts to the wrong hyperthread when only one
44 * hyperthread was specified in the interrupt desitination.
45 */
46 *retmask = (cpumask_t) { { [0] = APIC_ALL_CPUS } };
47 }
48
49 /* should be called last. */
50 static int probe_default(void)
51 {
52 return 1;
53 }
54
55 struct genapic apic_default = {
56
57 .name = "default",
58 .probe = probe_default,
59 .acpi_madt_oem_check = NULL,
60 .apic_id_registered = default_apic_id_registered,
61
62 .irq_delivery_mode = dest_LowestPrio,
63 /* logical delivery broadcast to all CPUs: */
64 .irq_dest_mode = 1,
65
66 .target_cpus = default_target_cpus,
67 .disable_esr = 0,
68 .dest_logical = APIC_DEST_LOGICAL,
69 .check_apicid_used = default_check_apicid_used,
70 .check_apicid_present = default_check_apicid_present,
71
72 .vector_allocation_domain = default_vector_allocation_domain,
73 .init_apic_ldr = default_init_apic_ldr,
74
75 .ioapic_phys_id_map = default_ioapic_phys_id_map,
76 .setup_apic_routing = default_setup_apic_routing,
77 .multi_timer_check = NULL,
78 .apicid_to_node = default_apicid_to_node,
79 .cpu_to_logical_apicid = default_cpu_to_logical_apicid,
80 .cpu_present_to_apicid = default_cpu_present_to_apicid,
81 .apicid_to_cpu_present = default_apicid_to_cpu_present,
82 .setup_portio_remap = NULL,
83 .check_phys_apicid_present = default_check_phys_apicid_present,
84 .enable_apic_mode = NULL,
85 .phys_pkg_id = default_phys_pkg_id,
86 .mps_oem_check = NULL,
87
88 .get_apic_id = default_get_apic_id,
89 .set_apic_id = NULL,
90 .apic_id_mask = 0x0F << 24,
91
92 .cpu_mask_to_apicid = default_cpu_mask_to_apicid,
93 .cpu_mask_to_apicid_and = default_cpu_mask_to_apicid_and,
94
95 .send_IPI_mask = default_send_IPI_mask,
96 .send_IPI_mask_allbutself = NULL,
97 .send_IPI_allbutself = default_send_IPI_allbutself,
98 .send_IPI_all = default_send_IPI_all,
99 .send_IPI_self = NULL,
100
101 .wakeup_cpu = NULL,
102 .trampoline_phys_low = DEFAULT_TRAMPOLINE_PHYS_LOW,
103 .trampoline_phys_high = DEFAULT_TRAMPOLINE_PHYS_HIGH,
104
105 .wait_for_init_deassert = default_wait_for_init_deassert,
106
107 .smp_callin_clear_local_apic = NULL,
108 .store_NMI_vector = NULL,
109 .inquire_remote_apic = default_inquire_remote_apic,
110 };
111
112 extern struct genapic apic_numaq;
113 extern struct genapic apic_summit;
114 extern struct genapic apic_bigsmp;
115 extern struct genapic apic_es7000;
116 extern struct genapic apic_default;
117
118 struct genapic *apic = &apic_default;
119
120 static struct genapic *apic_probe[] __initdata = {
121 #ifdef CONFIG_X86_NUMAQ
122 &apic_numaq,
123 #endif
124 #ifdef CONFIG_X86_SUMMIT
125 &apic_summit,
126 #endif
127 #ifdef CONFIG_X86_BIGSMP
128 &apic_bigsmp,
129 #endif
130 #ifdef CONFIG_X86_ES7000
131 &apic_es7000,
132 #endif
133 &apic_default, /* must be last */
134 NULL,
135 };
136
137 static int cmdline_apic __initdata;
138 static int __init parse_apic(char *arg)
139 {
140 int i;
141
142 if (!arg)
143 return -EINVAL;
144
145 for (i = 0; apic_probe[i]; i++) {
146 if (!strcmp(apic_probe[i]->name, arg)) {
147 apic = apic_probe[i];
148 cmdline_apic = 1;
149 return 0;
150 }
151 }
152
153 if (x86_quirks->update_genapic)
154 x86_quirks->update_genapic();
155
156 /* Parsed again by __setup for debug/verbose */
157 return 0;
158 }
159 early_param("apic", parse_apic);
160
161 void __init generic_bigsmp_probe(void)
162 {
163 #ifdef CONFIG_X86_BIGSMP
164 /*
165 * This routine is used to switch to bigsmp mode when
166 * - There is no apic= option specified by the user
167 * - generic_apic_probe() has chosen apic_default as the sub_arch
168 * - we find more than 8 CPUs in acpi LAPIC listing with xAPIC support
169 */
170
171 if (!cmdline_apic && apic == &apic_default) {
172 if (apic_bigsmp.probe()) {
173 apic = &apic_bigsmp;
174 if (x86_quirks->update_genapic)
175 x86_quirks->update_genapic();
176 printk(KERN_INFO "Overriding APIC driver with %s\n",
177 apic->name);
178 }
179 }
180 #endif
181 }
182
183 void __init generic_apic_probe(void)
184 {
185 if (!cmdline_apic) {
186 int i;
187 for (i = 0; apic_probe[i]; i++) {
188 if (apic_probe[i]->probe()) {
189 apic = apic_probe[i];
190 break;
191 }
192 }
193 /* Not visible without early console */
194 if (!apic_probe[i])
195 panic("Didn't find an APIC driver");
196
197 if (x86_quirks->update_genapic)
198 x86_quirks->update_genapic();
199 }
200 printk(KERN_INFO "Using APIC driver %s\n", apic->name);
201 }
202
203 /* These functions can switch the APIC even after the initial ->probe() */
204
205 int __init
206 generic_mps_oem_check(struct mpc_table *mpc, char *oem, char *productid)
207 {
208 int i;
209
210 for (i = 0; apic_probe[i]; ++i) {
211 if (!apic_probe[i]->mps_oem_check)
212 continue;
213 if (!apic_probe[i]->mps_oem_check(mpc, oem, productid))
214 continue;
215
216 if (!cmdline_apic) {
217 apic = apic_probe[i];
218 if (x86_quirks->update_genapic)
219 x86_quirks->update_genapic();
220 printk(KERN_INFO "Switched to APIC driver `%s'.\n",
221 apic->name);
222 }
223 return 1;
224 }
225 return 0;
226 }
227
228 int __init default_acpi_madt_oem_check(char *oem_id, char *oem_table_id)
229 {
230 int i;
231
232 for (i = 0; apic_probe[i]; ++i) {
233 if (!apic_probe[i]->acpi_madt_oem_check)
234 continue;
235 if (!apic_probe[i]->acpi_madt_oem_check(oem_id, oem_table_id))
236 continue;
237
238 if (!cmdline_apic) {
239 apic = apic_probe[i];
240 if (x86_quirks->update_genapic)
241 x86_quirks->update_genapic();
242 printk(KERN_INFO "Switched to APIC driver `%s'.\n",
243 apic->name);
244 }
245 return 1;
246 }
247 return 0;
248 }