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> |
1da177e4 LT |
19 | |
20 | #include <asm/smp.h> | |
21 | #include <asm/ipi.h> | |
00f1ea69 | 22 | #include <asm/genapic.h> |
1da177e4 | 23 | |
07c7c474 | 24 | #ifdef CONFIG_ACPI |
90660ec3 JD |
25 | #include <acpi/acpi_bus.h> |
26 | #endif | |
27 | ||
ac23d4ee | 28 | DEFINE_PER_CPU(int, x2apic_extra_bits); |
1da177e4 | 29 | |
f18d397e | 30 | struct genapic __read_mostly *genapic = &apic_flat; |
1da177e4 | 31 | |
ae261868 JS |
32 | static enum uv_system_type uv_system_type; |
33 | ||
1da177e4 LT |
34 | /* |
35 | * Check the APIC IDs in bios_cpu_apicid and choose the APIC mode. | |
36 | */ | |
3c43f039 | 37 | void __init setup_apic_routing(void) |
1da177e4 | 38 | { |
ac23d4ee JS |
39 | if (uv_system_type == UV_NON_UNIQUE_APIC) |
40 | genapic = &apic_x2apic_uv_x; | |
41 | else | |
f18d397e | 42 | #ifdef CONFIG_ACPI |
90660ec3 | 43 | /* |
07c7c474 IM |
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). | |
90660ec3 | 47 | */ |
07c7c474 IM |
48 | if (acpi_gbl_FADT.header.revision > FADT2_REVISION_ID && |
49 | (acpi_gbl_FADT.flags & ACPI_FADT_APIC_PHYSICAL)) | |
50 | genapic = &apic_physflat; | |
3c43f039 | 51 | else |
90660ec3 JD |
52 | #endif |
53 | ||
7c04e64a | 54 | if (num_possible_cpus() <= 8) |
1da177e4 | 55 | genapic = &apic_flat; |
f18d397e | 56 | else |
07c7c474 | 57 | genapic = &apic_physflat; |
1da177e4 | 58 | |
1da177e4 LT |
59 | printk(KERN_INFO "Setting APIC routing to %s\n", genapic->name); |
60 | } | |
61 | ||
07c7c474 | 62 | /* Same for both flat and physical. */ |
1da177e4 LT |
63 | |
64 | void send_IPI_self(int vector) | |
65 | { | |
66 | __send_IPI_shortcut(APIC_DEST_SELF, vector, APIC_DEST_PHYSICAL); | |
67 | } | |
ae261868 JS |
68 | |
69 | int __init acpi_madt_oem_check(char *oem_id, char *oem_table_id) | |
70 | { | |
71 | if (!strcmp(oem_id, "SGI")) { | |
72 | if (!strcmp(oem_table_id, "UVL")) | |
73 | uv_system_type = UV_LEGACY_APIC; | |
74 | else if (!strcmp(oem_table_id, "UVX")) | |
75 | uv_system_type = UV_X2APIC; | |
76 | else if (!strcmp(oem_table_id, "UVH")) | |
77 | uv_system_type = UV_NON_UNIQUE_APIC; | |
78 | } | |
79 | return 0; | |
80 | } | |
81 | ||
ac23d4ee JS |
82 | unsigned int read_apic_id(void) |
83 | { | |
84 | unsigned int id; | |
85 | ||
f6c133f7 | 86 | WARN_ON(preemptible() && num_online_cpus() > 1); |
ac23d4ee JS |
87 | id = apic_read(APIC_ID); |
88 | if (uv_system_type >= UV_X2APIC) | |
89 | id |= __get_cpu_var(x2apic_extra_bits); | |
ac23d4ee JS |
90 | return id; |
91 | } | |
92 | ||
ae261868 JS |
93 | enum uv_system_type get_uv_system_type(void) |
94 | { | |
95 | return uv_system_type; | |
96 | } | |
97 | ||
98 | int is_uv_system(void) | |
99 | { | |
100 | return uv_system_type != UV_NONE; | |
101 | } |