diff options
Diffstat (limited to 'arch/x86/kernel/genx2apic_cluster.c')
-rw-r--r-- | arch/x86/kernel/genx2apic_cluster.c | 133 |
1 files changed, 86 insertions, 47 deletions
diff --git a/arch/x86/kernel/genx2apic_cluster.c b/arch/x86/kernel/genx2apic_cluster.c index 6ce497cc372d..7c87156b6411 100644 --- a/arch/x86/kernel/genx2apic_cluster.c +++ b/arch/x86/kernel/genx2apic_cluster.c | |||
@@ -36,8 +36,8 @@ static void x2apic_vector_allocation_domain(int cpu, struct cpumask *retmask) | |||
36 | cpumask_set_cpu(cpu, retmask); | 36 | cpumask_set_cpu(cpu, retmask); |
37 | } | 37 | } |
38 | 38 | ||
39 | static void __x2apic_send_IPI_dest(unsigned int apicid, int vector, | 39 | static void |
40 | unsigned int dest) | 40 | __x2apic_send_IPI_dest(unsigned int apicid, int vector, unsigned int dest) |
41 | { | 41 | { |
42 | unsigned long cfg; | 42 | unsigned long cfg; |
43 | 43 | ||
@@ -57,45 +57,50 @@ static void __x2apic_send_IPI_dest(unsigned int apicid, int vector, | |||
57 | */ | 57 | */ |
58 | static void x2apic_send_IPI_mask(const struct cpumask *mask, int vector) | 58 | static void x2apic_send_IPI_mask(const struct cpumask *mask, int vector) |
59 | { | 59 | { |
60 | unsigned long flags; | ||
61 | unsigned long query_cpu; | 60 | unsigned long query_cpu; |
61 | unsigned long flags; | ||
62 | 62 | ||
63 | local_irq_save(flags); | 63 | local_irq_save(flags); |
64 | for_each_cpu(query_cpu, mask) | 64 | for_each_cpu(query_cpu, mask) { |
65 | __x2apic_send_IPI_dest( | 65 | __x2apic_send_IPI_dest( |
66 | per_cpu(x86_cpu_to_logical_apicid, query_cpu), | 66 | per_cpu(x86_cpu_to_logical_apicid, query_cpu), |
67 | vector, APIC_DEST_LOGICAL); | 67 | vector, apic->dest_logical); |
68 | } | ||
68 | local_irq_restore(flags); | 69 | local_irq_restore(flags); |
69 | } | 70 | } |
70 | 71 | ||
71 | static void x2apic_send_IPI_mask_allbutself(const struct cpumask *mask, | 72 | static void |
72 | int vector) | 73 | x2apic_send_IPI_mask_allbutself(const struct cpumask *mask, int vector) |
73 | { | 74 | { |
74 | unsigned long flags; | ||
75 | unsigned long query_cpu; | ||
76 | unsigned long this_cpu = smp_processor_id(); | 75 | unsigned long this_cpu = smp_processor_id(); |
76 | unsigned long query_cpu; | ||
77 | unsigned long flags; | ||
77 | 78 | ||
78 | local_irq_save(flags); | 79 | local_irq_save(flags); |
79 | for_each_cpu(query_cpu, mask) | 80 | for_each_cpu(query_cpu, mask) { |
80 | if (query_cpu != this_cpu) | 81 | if (query_cpu == this_cpu) |
81 | __x2apic_send_IPI_dest( | 82 | continue; |
83 | __x2apic_send_IPI_dest( | ||
82 | per_cpu(x86_cpu_to_logical_apicid, query_cpu), | 84 | per_cpu(x86_cpu_to_logical_apicid, query_cpu), |
83 | vector, APIC_DEST_LOGICAL); | 85 | vector, apic->dest_logical); |
86 | } | ||
84 | local_irq_restore(flags); | 87 | local_irq_restore(flags); |
85 | } | 88 | } |
86 | 89 | ||
87 | static void x2apic_send_IPI_allbutself(int vector) | 90 | static void x2apic_send_IPI_allbutself(int vector) |
88 | { | 91 | { |
89 | unsigned long flags; | ||
90 | unsigned long query_cpu; | ||
91 | unsigned long this_cpu = smp_processor_id(); | 92 | unsigned long this_cpu = smp_processor_id(); |
93 | unsigned long query_cpu; | ||
94 | unsigned long flags; | ||
92 | 95 | ||
93 | local_irq_save(flags); | 96 | local_irq_save(flags); |
94 | for_each_online_cpu(query_cpu) | 97 | for_each_online_cpu(query_cpu) { |
95 | if (query_cpu != this_cpu) | 98 | if (query_cpu == this_cpu) |
96 | __x2apic_send_IPI_dest( | 99 | continue; |
100 | __x2apic_send_IPI_dest( | ||
97 | per_cpu(x86_cpu_to_logical_apicid, query_cpu), | 101 | per_cpu(x86_cpu_to_logical_apicid, query_cpu), |
98 | vector, APIC_DEST_LOGICAL); | 102 | vector, apic->dest_logical); |
103 | } | ||
99 | local_irq_restore(flags); | 104 | local_irq_restore(flags); |
100 | } | 105 | } |
101 | 106 | ||
@@ -111,21 +116,21 @@ static int x2apic_apic_id_registered(void) | |||
111 | 116 | ||
112 | static unsigned int x2apic_cpu_mask_to_apicid(const struct cpumask *cpumask) | 117 | static unsigned int x2apic_cpu_mask_to_apicid(const struct cpumask *cpumask) |
113 | { | 118 | { |
114 | int cpu; | ||
115 | |||
116 | /* | 119 | /* |
117 | * We're using fixed IRQ delivery, can only return one logical APIC ID. | 120 | * We're using fixed IRQ delivery, can only return one logical APIC ID. |
118 | * May as well be the first. | 121 | * May as well be the first. |
119 | */ | 122 | */ |
120 | cpu = cpumask_first(cpumask); | 123 | int cpu = cpumask_first(cpumask); |
124 | |||
121 | if ((unsigned)cpu < nr_cpu_ids) | 125 | if ((unsigned)cpu < nr_cpu_ids) |
122 | return per_cpu(x86_cpu_to_logical_apicid, cpu); | 126 | return per_cpu(x86_cpu_to_logical_apicid, cpu); |
123 | else | 127 | else |
124 | return BAD_APICID; | 128 | return BAD_APICID; |
125 | } | 129 | } |
126 | 130 | ||
127 | static unsigned int x2apic_cpu_mask_to_apicid_and(const struct cpumask *cpumask, | 131 | static unsigned int |
128 | const struct cpumask *andmask) | 132 | x2apic_cpu_mask_to_apicid_and(const struct cpumask *cpumask, |
133 | const struct cpumask *andmask) | ||
129 | { | 134 | { |
130 | int cpu; | 135 | int cpu; |
131 | 136 | ||
@@ -133,15 +138,18 @@ static unsigned int x2apic_cpu_mask_to_apicid_and(const struct cpumask *cpumask, | |||
133 | * We're using fixed IRQ delivery, can only return one logical APIC ID. | 138 | * We're using fixed IRQ delivery, can only return one logical APIC ID. |
134 | * May as well be the first. | 139 | * May as well be the first. |
135 | */ | 140 | */ |
136 | for_each_cpu_and(cpu, cpumask, andmask) | 141 | for_each_cpu_and(cpu, cpumask, andmask) { |
137 | if (cpumask_test_cpu(cpu, cpu_online_mask)) | 142 | if (cpumask_test_cpu(cpu, cpu_online_mask)) |
138 | break; | 143 | break; |
144 | } | ||
145 | |||
139 | if (cpu < nr_cpu_ids) | 146 | if (cpu < nr_cpu_ids) |
140 | return per_cpu(x86_cpu_to_logical_apicid, cpu); | 147 | return per_cpu(x86_cpu_to_logical_apicid, cpu); |
148 | |||
141 | return BAD_APICID; | 149 | return BAD_APICID; |
142 | } | 150 | } |
143 | 151 | ||
144 | static unsigned int get_apic_id(unsigned long x) | 152 | static unsigned int x2apic_cluster_phys_get_apic_id(unsigned long x) |
145 | { | 153 | { |
146 | unsigned int id; | 154 | unsigned int id; |
147 | 155 | ||
@@ -157,7 +165,7 @@ static unsigned long set_apic_id(unsigned int id) | |||
157 | return x; | 165 | return x; |
158 | } | 166 | } |
159 | 167 | ||
160 | static unsigned int phys_pkg_id(int index_msb) | 168 | static int x2apic_cluster_phys_pkg_id(int initial_apicid, int index_msb) |
161 | { | 169 | { |
162 | return current_cpu_data.initial_apicid >> index_msb; | 170 | return current_cpu_data.initial_apicid >> index_msb; |
163 | } | 171 | } |
@@ -172,27 +180,58 @@ static void init_x2apic_ldr(void) | |||
172 | int cpu = smp_processor_id(); | 180 | int cpu = smp_processor_id(); |
173 | 181 | ||
174 | per_cpu(x86_cpu_to_logical_apicid, cpu) = apic_read(APIC_LDR); | 182 | per_cpu(x86_cpu_to_logical_apicid, cpu) = apic_read(APIC_LDR); |
175 | return; | ||
176 | } | 183 | } |
177 | 184 | ||
178 | struct genapic apic_x2apic_cluster = { | 185 | struct genapic apic_x2apic_cluster = { |
179 | .name = "cluster x2apic", | 186 | |
180 | .acpi_madt_oem_check = x2apic_acpi_madt_oem_check, | 187 | .name = "cluster x2apic", |
181 | .int_delivery_mode = dest_LowestPrio, | 188 | .probe = NULL, |
182 | .int_dest_mode = (APIC_DEST_LOGICAL != 0), | 189 | .acpi_madt_oem_check = x2apic_acpi_madt_oem_check, |
183 | .target_cpus = x2apic_target_cpus, | 190 | .apic_id_registered = x2apic_apic_id_registered, |
184 | .vector_allocation_domain = x2apic_vector_allocation_domain, | 191 | |
185 | .apic_id_registered = x2apic_apic_id_registered, | 192 | .irq_delivery_mode = dest_LowestPrio, |
186 | .init_apic_ldr = init_x2apic_ldr, | 193 | .irq_dest_mode = 1, /* logical */ |
187 | .send_IPI_all = x2apic_send_IPI_all, | 194 | |
188 | .send_IPI_allbutself = x2apic_send_IPI_allbutself, | 195 | .target_cpus = x2apic_target_cpus, |
189 | .send_IPI_mask = x2apic_send_IPI_mask, | 196 | .disable_esr = 0, |
190 | .send_IPI_mask_allbutself = x2apic_send_IPI_mask_allbutself, | 197 | .dest_logical = APIC_DEST_LOGICAL, |
191 | .send_IPI_self = x2apic_send_IPI_self, | 198 | .check_apicid_used = NULL, |
192 | .cpu_mask_to_apicid = x2apic_cpu_mask_to_apicid, | 199 | .check_apicid_present = NULL, |
193 | .cpu_mask_to_apicid_and = x2apic_cpu_mask_to_apicid_and, | 200 | |
194 | .phys_pkg_id = phys_pkg_id, | 201 | .vector_allocation_domain = x2apic_vector_allocation_domain, |
195 | .get_apic_id = get_apic_id, | 202 | .init_apic_ldr = init_x2apic_ldr, |
196 | .set_apic_id = set_apic_id, | 203 | |
197 | .apic_id_mask = (0xFFFFFFFFu), | 204 | .ioapic_phys_id_map = NULL, |
205 | .setup_apic_routing = NULL, | ||
206 | .multi_timer_check = NULL, | ||
207 | .apicid_to_node = NULL, | ||
208 | .cpu_to_logical_apicid = NULL, | ||
209 | .cpu_present_to_apicid = default_cpu_present_to_apicid, | ||
210 | .apicid_to_cpu_present = NULL, | ||
211 | .setup_portio_remap = NULL, | ||
212 | .check_phys_apicid_present = default_check_phys_apicid_present, | ||
213 | .enable_apic_mode = NULL, | ||
214 | .phys_pkg_id = x2apic_cluster_phys_pkg_id, | ||
215 | .mps_oem_check = NULL, | ||
216 | |||
217 | .get_apic_id = x2apic_cluster_phys_get_apic_id, | ||
218 | .set_apic_id = set_apic_id, | ||
219 | .apic_id_mask = 0xFFFFFFFFu, | ||
220 | |||
221 | .cpu_mask_to_apicid = x2apic_cpu_mask_to_apicid, | ||
222 | .cpu_mask_to_apicid_and = x2apic_cpu_mask_to_apicid_and, | ||
223 | |||
224 | .send_IPI_mask = x2apic_send_IPI_mask, | ||
225 | .send_IPI_mask_allbutself = x2apic_send_IPI_mask_allbutself, | ||
226 | .send_IPI_allbutself = x2apic_send_IPI_allbutself, | ||
227 | .send_IPI_all = x2apic_send_IPI_all, | ||
228 | .send_IPI_self = x2apic_send_IPI_self, | ||
229 | |||
230 | .wakeup_cpu = NULL, | ||
231 | .trampoline_phys_low = DEFAULT_TRAMPOLINE_PHYS_LOW, | ||
232 | .trampoline_phys_high = DEFAULT_TRAMPOLINE_PHYS_HIGH, | ||
233 | .wait_for_init_deassert = NULL, | ||
234 | .smp_callin_clear_local_apic = NULL, | ||
235 | .store_NMI_vector = NULL, | ||
236 | .inquire_remote_apic = NULL, | ||
198 | }; | 237 | }; |