aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel/genapic_64.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86/kernel/genapic_64.c')
-rw-r--r--arch/x86/kernel/genapic_64.c83
1 files changed, 27 insertions, 56 deletions
diff --git a/arch/x86/kernel/genapic_64.c b/arch/x86/kernel/genapic_64.c
index 1fa8be5bd217..b3ba969c50d2 100644
--- a/arch/x86/kernel/genapic_64.c
+++ b/arch/x86/kernel/genapic_64.c
@@ -21,81 +21,52 @@
21#include <asm/ipi.h> 21#include <asm/ipi.h>
22#include <asm/genapic.h> 22#include <asm/genapic.h>
23 23
24#ifdef CONFIG_ACPI 24extern struct genapic apic_flat;
25#include <acpi/acpi_bus.h> 25extern struct genapic apic_physflat;
26#endif 26extern struct genapic apic_x2xpic_uv_x;
27 27extern struct genapic apic_x2apic_phys;
28DEFINE_PER_CPU(int, x2apic_extra_bits); 28extern struct genapic apic_x2apic_cluster;
29 29
30struct genapic __read_mostly *genapic = &apic_flat; 30struct genapic __read_mostly *genapic = &apic_flat;
31 31
32static enum uv_system_type uv_system_type; 32static struct genapic *apic_probe[] __initdata = {
33 &apic_x2apic_uv_x,
34 &apic_x2apic_phys,
35 &apic_x2apic_cluster,
36 &apic_physflat,
37 NULL,
38};
33 39
34/* 40/*
35 * Check the APIC IDs in bios_cpu_apicid and choose the APIC mode. 41 * Check the APIC IDs in bios_cpu_apicid and choose the APIC mode.
36 */ 42 */
37void __init setup_apic_routing(void) 43void __init setup_apic_routing(void)
38{ 44{
39 if (uv_system_type == UV_NON_UNIQUE_APIC) 45 if (genapic == &apic_flat) {
40 genapic = &apic_x2apic_uv_x; 46 if (max_physical_apicid >= 8)
41 else 47 genapic = &apic_physflat;
42#ifdef CONFIG_ACPI 48 printk(KERN_INFO "Setting APIC routing to %s\n", genapic->name);
43 /* 49 }
44 * Quirk: some x86_64 machines can only use physical APIC mode
45 * regardless of how many processors are present (x86_64 ES7000
46 * is an example).
47 */
48 if (acpi_gbl_FADT.header.revision > FADT2_REVISION_ID &&
49 (acpi_gbl_FADT.flags & ACPI_FADT_APIC_PHYSICAL))
50 genapic = &apic_physflat;
51 else
52#endif
53
54 if (max_physical_apicid < 8)
55 genapic = &apic_flat;
56 else
57 genapic = &apic_physflat;
58
59 printk(KERN_INFO "Setting APIC routing to %s\n", genapic->name);
60} 50}
61 51
62/* Same for both flat and physical. */ 52/* Same for both flat and physical. */
63 53
64void send_IPI_self(int vector) 54void apic_send_IPI_self(int vector)
65{ 55{
66 __send_IPI_shortcut(APIC_DEST_SELF, vector, APIC_DEST_PHYSICAL); 56 __send_IPI_shortcut(APIC_DEST_SELF, vector, APIC_DEST_PHYSICAL);
67} 57}
68 58
69int __init acpi_madt_oem_check(char *oem_id, char *oem_table_id) 59int __init acpi_madt_oem_check(char *oem_id, char *oem_table_id)
70{ 60{
71 if (!strcmp(oem_id, "SGI")) { 61 int i;
72 if (!strcmp(oem_table_id, "UVL")) 62
73 uv_system_type = UV_LEGACY_APIC; 63 for (i = 0; apic_probe[i]; ++i) {
74 else if (!strcmp(oem_table_id, "UVX")) 64 if (apic_probe[i]->acpi_madt_oem_check(oem_id, oem_table_id)) {
75 uv_system_type = UV_X2APIC; 65 genapic = apic_probe[i];
76 else if (!strcmp(oem_table_id, "UVH")) 66 printk(KERN_INFO "Setting APIC routing to %s.\n",
77 uv_system_type = UV_NON_UNIQUE_APIC; 67 genapic->name);
68 return 1;
69 }
78 } 70 }
79 return 0; 71 return 0;
80} 72}
81
82unsigned int read_apic_id(void)
83{
84 unsigned int id;
85
86 WARN_ON(preemptible() && num_online_cpus() > 1);
87 id = apic_read(APIC_ID);
88 if (uv_system_type >= UV_X2APIC)
89 id |= __get_cpu_var(x2apic_extra_bits);
90 return id;
91}
92
93enum uv_system_type get_uv_system_type(void)
94{
95 return uv_system_type;
96}
97
98int is_uv_system(void)
99{
100 return uv_system_type != UV_NONE;
101}