Commit | Line | Data |
---|---|---|
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 | */ | |
1da177e4 LT |
11 | #include <linux/threads.h> |
12 | #include <linux/cpumask.h> | |
13 | #include <linux/string.h> | |
07c7c474 | 14 | #include <linux/module.h> |
1da177e4 LT |
15 | #include <linux/kernel.h> |
16 | #include <linux/ctype.h> | |
17 | #include <linux/init.h> | |
ac23d4ee | 18 | #include <linux/hardirq.h> |
6e1cb38a | 19 | #include <linux/dmar.h> |
1da177e4 LT |
20 | |
21 | #include <asm/smp.h> | |
22 | #include <asm/ipi.h> | |
00f1ea69 | 23 | #include <asm/genapic.h> |
1da177e4 | 24 | |
07c7c474 | 25 | #ifdef CONFIG_ACPI |
90660ec3 JD |
26 | #include <acpi/acpi_bus.h> |
27 | #endif | |
28 | ||
ac23d4ee | 29 | DEFINE_PER_CPU(int, x2apic_extra_bits); |
1da177e4 | 30 | |
f18d397e | 31 | struct genapic __read_mostly *genapic = &apic_flat; |
1da177e4 | 32 | |
2d9579a1 SS |
33 | static int x2apic_phys = 0; |
34 | ||
35 | static int set_x2apic_phys_mode(char *arg) | |
36 | { | |
37 | x2apic_phys = 1; | |
38 | return 0; | |
39 | } | |
40 | early_param("x2apic_phys", set_x2apic_phys_mode); | |
41 | ||
ae261868 JS |
42 | static enum uv_system_type uv_system_type; |
43 | ||
1da177e4 LT |
44 | /* |
45 | * Check the APIC IDs in bios_cpu_apicid and choose the APIC mode. | |
46 | */ | |
3c43f039 | 47 | void __init setup_apic_routing(void) |
1da177e4 | 48 | { |
ac23d4ee JS |
49 | if (uv_system_type == UV_NON_UNIQUE_APIC) |
50 | genapic = &apic_x2apic_uv_x; | |
2d9579a1 SS |
51 | else if (cpu_has_x2apic && intr_remapping_enabled) { |
52 | if (x2apic_phys) | |
53 | genapic = &apic_x2apic_phys; | |
54 | else | |
55 | genapic = &apic_x2apic_cluster; | |
56 | } else | |
f18d397e | 57 | #ifdef CONFIG_ACPI |
90660ec3 | 58 | /* |
07c7c474 IM |
59 | * Quirk: some x86_64 machines can only use physical APIC mode |
60 | * regardless of how many processors are present (x86_64 ES7000 | |
61 | * is an example). | |
90660ec3 | 62 | */ |
07c7c474 IM |
63 | if (acpi_gbl_FADT.header.revision > FADT2_REVISION_ID && |
64 | (acpi_gbl_FADT.flags & ACPI_FADT_APIC_PHYSICAL)) | |
65 | genapic = &apic_physflat; | |
3c43f039 | 66 | else |
90660ec3 JD |
67 | #endif |
68 | ||
e0da3364 | 69 | if (max_physical_apicid < 8) |
1da177e4 | 70 | genapic = &apic_flat; |
f18d397e | 71 | else |
07c7c474 | 72 | genapic = &apic_physflat; |
1da177e4 | 73 | |
1da177e4 LT |
74 | printk(KERN_INFO "Setting APIC routing to %s\n", genapic->name); |
75 | } | |
76 | ||
07c7c474 | 77 | /* Same for both flat and physical. */ |
1da177e4 | 78 | |
cff73a6f | 79 | void apic_send_IPI_self(int vector) |
1da177e4 LT |
80 | { |
81 | __send_IPI_shortcut(APIC_DEST_SELF, vector, APIC_DEST_PHYSICAL); | |
82 | } | |
ae261868 JS |
83 | |
84 | int __init acpi_madt_oem_check(char *oem_id, char *oem_table_id) | |
85 | { | |
86 | if (!strcmp(oem_id, "SGI")) { | |
87 | if (!strcmp(oem_table_id, "UVL")) | |
88 | uv_system_type = UV_LEGACY_APIC; | |
89 | else if (!strcmp(oem_table_id, "UVX")) | |
90 | uv_system_type = UV_X2APIC; | |
91 | else if (!strcmp(oem_table_id, "UVH")) | |
92 | uv_system_type = UV_NON_UNIQUE_APIC; | |
93 | } | |
94 | return 0; | |
95 | } | |
96 | ||
97 | enum uv_system_type get_uv_system_type(void) | |
98 | { | |
99 | return uv_system_type; | |
100 | } | |
101 | ||
102 | int is_uv_system(void) | |
103 | { | |
104 | return uv_system_type != UV_NONE; | |
105 | } |