aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86/kernel')
-rw-r--r--arch/x86/kernel/acpi/boot.c12
-rw-r--r--arch/x86/kernel/apic/Makefile3
-rw-r--r--arch/x86/kernel/apic/apic.c1
-rw-r--r--arch/x86/kernel/apic/es7000_32.c738
-rw-r--r--arch/x86/kernel/apic/numaq_32.c524
-rw-r--r--arch/x86/kernel/apic/summit_32.c550
-rw-r--r--arch/x86/kernel/cpu/intel.c4
-rw-r--r--arch/x86/kernel/setup.c1
8 files changed, 0 insertions, 1833 deletions
diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c
index 8e61d23b8f64..86281ffb96d6 100644
--- a/arch/x86/kernel/acpi/boot.c
+++ b/arch/x86/kernel/acpi/boot.c
@@ -903,10 +903,6 @@ static int __init acpi_parse_madt_lapic_entries(void)
903#ifdef CONFIG_X86_IO_APIC 903#ifdef CONFIG_X86_IO_APIC
904#define MP_ISA_BUS 0 904#define MP_ISA_BUS 0
905 905
906#ifdef CONFIG_X86_ES7000
907extern int es7000_plat;
908#endif
909
910void __init mp_override_legacy_irq(u8 bus_irq, u8 polarity, u8 trigger, u32 gsi) 906void __init mp_override_legacy_irq(u8 bus_irq, u8 polarity, u8 trigger, u32 gsi)
911{ 907{
912 int ioapic; 908 int ioapic;
@@ -956,14 +952,6 @@ void __init mp_config_acpi_legacy_irqs(void)
956 set_bit(MP_ISA_BUS, mp_bus_not_pci); 952 set_bit(MP_ISA_BUS, mp_bus_not_pci);
957 pr_debug("Bus #%d is ISA\n", MP_ISA_BUS); 953 pr_debug("Bus #%d is ISA\n", MP_ISA_BUS);
958 954
959#ifdef CONFIG_X86_ES7000
960 /*
961 * Older generations of ES7000 have no legacy identity mappings
962 */
963 if (es7000_plat == 1)
964 return;
965#endif
966
967 /* 955 /*
968 * Use the default configuration for the IRQs 0-15. Unless 956 * Use the default configuration for the IRQs 0-15. Unless
969 * overridden by (MADT) interrupt source override entries. 957 * overridden by (MADT) interrupt source override entries.
diff --git a/arch/x86/kernel/apic/Makefile b/arch/x86/kernel/apic/Makefile
index 0ae0323b1f9c..dcb5b15401ce 100644
--- a/arch/x86/kernel/apic/Makefile
+++ b/arch/x86/kernel/apic/Makefile
@@ -18,10 +18,7 @@ obj-y += apic_flat_64.o
18endif 18endif
19 19
20# APIC probe will depend on the listing order here 20# APIC probe will depend on the listing order here
21obj-$(CONFIG_X86_NUMAQ) += numaq_32.o
22obj-$(CONFIG_X86_SUMMIT) += summit_32.o
23obj-$(CONFIG_X86_BIGSMP) += bigsmp_32.o 21obj-$(CONFIG_X86_BIGSMP) += bigsmp_32.o
24obj-$(CONFIG_X86_ES7000) += es7000_32.o
25 22
26# For 32bit, probe_32 need to be listed last 23# For 32bit, probe_32 need to be listed last
27obj-$(CONFIG_X86_LOCAL_APIC) += probe_$(BITS).o 24obj-$(CONFIG_X86_LOCAL_APIC) += probe_$(BITS).o
diff --git a/arch/x86/kernel/apic/apic.c b/arch/x86/kernel/apic/apic.c
index 53e20531470e..481ae38f6a44 100644
--- a/arch/x86/kernel/apic/apic.c
+++ b/arch/x86/kernel/apic/apic.c
@@ -2136,7 +2136,6 @@ int generic_processor_info(int apicid, int version)
2136 * 2136 *
2137 * - arch/x86/kernel/mpparse.c: MP_processor_info() 2137 * - arch/x86/kernel/mpparse.c: MP_processor_info()
2138 * - arch/x86/mm/amdtopology.c: amd_numa_init() 2138 * - arch/x86/mm/amdtopology.c: amd_numa_init()
2139 * - arch/x86/platform/visws/visws_quirks.c: MP_processor_info()
2140 * 2139 *
2141 * This function is executed with the modified 2140 * This function is executed with the modified
2142 * boot_cpu_physical_apicid. So, disabled_cpu_apicid kernel 2141 * boot_cpu_physical_apicid. So, disabled_cpu_apicid kernel
diff --git a/arch/x86/kernel/apic/es7000_32.c b/arch/x86/kernel/apic/es7000_32.c
deleted file mode 100644
index 6f8f8b348a39..000000000000
--- a/arch/x86/kernel/apic/es7000_32.c
+++ /dev/null
@@ -1,738 +0,0 @@
1/*
2 * Written by: Garry Forsgren, Unisys Corporation
3 * Natalie Protasevich, Unisys Corporation
4 *
5 * This file contains the code to configure and interface
6 * with Unisys ES7000 series hardware system manager.
7 *
8 * Copyright (c) 2003 Unisys Corporation.
9 * Copyright (C) 2009, Red Hat, Inc., Ingo Molnar
10 *
11 * All Rights Reserved.
12 *
13 * This program is free software; you can redistribute it and/or modify it
14 * under the terms of version 2 of the GNU General Public License as
15 * published by the Free Software Foundation.
16 *
17 * This program is distributed in the hope that it would be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
20 *
21 * You should have received a copy of the GNU General Public License along
22 * with this program; if not, write the Free Software Foundation, Inc., 59
23 * Temple Place - Suite 330, Boston MA 02111-1307, USA.
24 *
25 * Contact information: Unisys Corporation, Township Line & Union Meeting
26 * Roads-A, Unisys Way, Blue Bell, Pennsylvania, 19424, or:
27 *
28 * http://www.unisys.com
29 */
30
31#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
32
33#include <linux/notifier.h>
34#include <linux/spinlock.h>
35#include <linux/cpumask.h>
36#include <linux/threads.h>
37#include <linux/kernel.h>
38#include <linux/module.h>
39#include <linux/reboot.h>
40#include <linux/string.h>
41#include <linux/types.h>
42#include <linux/errno.h>
43#include <linux/acpi.h>
44#include <linux/init.h>
45#include <linux/gfp.h>
46#include <linux/nmi.h>
47#include <linux/smp.h>
48#include <linux/io.h>
49
50#include <asm/apicdef.h>
51#include <linux/atomic.h>
52#include <asm/fixmap.h>
53#include <asm/mpspec.h>
54#include <asm/setup.h>
55#include <asm/apic.h>
56#include <asm/ipi.h>
57
58/*
59 * ES7000 chipsets
60 */
61
62#define NON_UNISYS 0
63#define ES7000_CLASSIC 1
64#define ES7000_ZORRO 2
65
66#define MIP_REG 1
67#define MIP_PSAI_REG 4
68
69#define MIP_BUSY 1
70#define MIP_SPIN 0xf0000
71#define MIP_VALID 0x0100000000000000ULL
72#define MIP_SW_APIC 0x1020b
73
74#define MIP_PORT(val) ((val >> 32) & 0xffff)
75
76#define MIP_RD_LO(val) (val & 0xffffffff)
77
78struct mip_reg {
79 unsigned long long off_0x00;
80 unsigned long long off_0x08;
81 unsigned long long off_0x10;
82 unsigned long long off_0x18;
83 unsigned long long off_0x20;
84 unsigned long long off_0x28;
85 unsigned long long off_0x30;
86 unsigned long long off_0x38;
87};
88
89struct mip_reg_info {
90 unsigned long long mip_info;
91 unsigned long long delivery_info;
92 unsigned long long host_reg;
93 unsigned long long mip_reg;
94};
95
96struct psai {
97 unsigned long long entry_type;
98 unsigned long long addr;
99 unsigned long long bep_addr;
100};
101
102#ifdef CONFIG_ACPI
103
104struct es7000_oem_table {
105 struct acpi_table_header Header;
106 u32 OEMTableAddr;
107 u32 OEMTableSize;
108};
109
110static unsigned long oem_addrX;
111static unsigned long oem_size;
112
113#endif
114
115/*
116 * ES7000 Globals
117 */
118
119static volatile unsigned long *psai;
120static struct mip_reg *mip_reg;
121static struct mip_reg *host_reg;
122static int mip_port;
123static unsigned long mip_addr;
124static unsigned long host_addr;
125
126int es7000_plat;
127
128/*
129 * GSI override for ES7000 platforms.
130 */
131
132
133static int wakeup_secondary_cpu_via_mip(int cpu, unsigned long eip)
134{
135 unsigned long vect = 0, psaival = 0;
136
137 if (psai == NULL)
138 return -1;
139
140 vect = ((unsigned long)__pa(eip)/0x1000) << 16;
141 psaival = (0x1000000 | vect | cpu);
142
143 while (*psai & 0x1000000)
144 ;
145
146 *psai = psaival;
147
148 return 0;
149}
150
151static int es7000_apic_is_cluster(void)
152{
153 /* MPENTIUMIII */
154 if (boot_cpu_data.x86 == 6 &&
155 (boot_cpu_data.x86_model >= 7 && boot_cpu_data.x86_model <= 11))
156 return 1;
157
158 return 0;
159}
160
161static void setup_unisys(void)
162{
163 /*
164 * Determine the generation of the ES7000 currently running.
165 *
166 * es7000_plat = 1 if the machine is a 5xx ES7000 box
167 * es7000_plat = 2 if the machine is a x86_64 ES7000 box
168 *
169 */
170 if (!(boot_cpu_data.x86 <= 15 && boot_cpu_data.x86_model <= 2))
171 es7000_plat = ES7000_ZORRO;
172 else
173 es7000_plat = ES7000_CLASSIC;
174}
175
176/*
177 * Parse the OEM Table:
178 */
179static int parse_unisys_oem(char *oemptr)
180{
181 int i;
182 int success = 0;
183 unsigned char type, size;
184 unsigned long val;
185 char *tp = NULL;
186 struct psai *psaip = NULL;
187 struct mip_reg_info *mi;
188 struct mip_reg *host, *mip;
189
190 tp = oemptr;
191
192 tp += 8;
193
194 for (i = 0; i <= 6; i++) {
195 type = *tp++;
196 size = *tp++;
197 tp -= 2;
198 switch (type) {
199 case MIP_REG:
200 mi = (struct mip_reg_info *)tp;
201 val = MIP_RD_LO(mi->host_reg);
202 host_addr = val;
203 host = (struct mip_reg *)val;
204 host_reg = __va(host);
205 val = MIP_RD_LO(mi->mip_reg);
206 mip_port = MIP_PORT(mi->mip_info);
207 mip_addr = val;
208 mip = (struct mip_reg *)val;
209 mip_reg = __va(mip);
210 pr_debug("host_reg = 0x%lx\n",
211 (unsigned long)host_reg);
212 pr_debug("mip_reg = 0x%lx\n",
213 (unsigned long)mip_reg);
214 success++;
215 break;
216 case MIP_PSAI_REG:
217 psaip = (struct psai *)tp;
218 if (tp != NULL) {
219 if (psaip->addr)
220 psai = __va(psaip->addr);
221 else
222 psai = NULL;
223 success++;
224 }
225 break;
226 default:
227 break;
228 }
229 tp += size;
230 }
231
232 if (success < 2)
233 es7000_plat = NON_UNISYS;
234 else
235 setup_unisys();
236
237 return es7000_plat;
238}
239
240#ifdef CONFIG_ACPI
241static int __init find_unisys_acpi_oem_table(unsigned long *oem_addr)
242{
243 struct acpi_table_header *header = NULL;
244 struct es7000_oem_table *table;
245 acpi_size tbl_size;
246 acpi_status ret;
247 int i = 0;
248
249 for (;;) {
250 ret = acpi_get_table_with_size("OEM1", i++, &header, &tbl_size);
251 if (!ACPI_SUCCESS(ret))
252 return -1;
253
254 if (!memcmp((char *) &header->oem_id, "UNISYS", 6))
255 break;
256
257 early_acpi_os_unmap_memory(header, tbl_size);
258 }
259
260 table = (void *)header;
261
262 oem_addrX = table->OEMTableAddr;
263 oem_size = table->OEMTableSize;
264
265 early_acpi_os_unmap_memory(header, tbl_size);
266
267 *oem_addr = (unsigned long)__acpi_map_table(oem_addrX, oem_size);
268
269 return 0;
270}
271
272static void __init unmap_unisys_acpi_oem_table(unsigned long oem_addr)
273{
274 if (!oem_addr)
275 return;
276
277 __acpi_unmap_table((char *)oem_addr, oem_size);
278}
279
280static int es7000_check_dsdt(void)
281{
282 struct acpi_table_header header;
283
284 if (ACPI_SUCCESS(acpi_get_table_header(ACPI_SIG_DSDT, 0, &header)) &&
285 !strncmp(header.oem_id, "UNISYS", 6))
286 return 1;
287 return 0;
288}
289
290static int es7000_acpi_ret;
291
292/* Hook from generic ACPI tables.c */
293static int __init es7000_acpi_madt_oem_check(char *oem_id, char *oem_table_id)
294{
295 unsigned long oem_addr = 0;
296 int check_dsdt;
297 int ret = 0;
298
299 /* check dsdt at first to avoid clear fix_map for oem_addr */
300 check_dsdt = es7000_check_dsdt();
301
302 if (!find_unisys_acpi_oem_table(&oem_addr)) {
303 if (check_dsdt) {
304 ret = parse_unisys_oem((char *)oem_addr);
305 } else {
306 setup_unisys();
307 ret = 1;
308 }
309 /*
310 * we need to unmap it
311 */
312 unmap_unisys_acpi_oem_table(oem_addr);
313 }
314
315 es7000_acpi_ret = ret;
316
317 return ret && !es7000_apic_is_cluster();
318}
319
320static int es7000_acpi_madt_oem_check_cluster(char *oem_id, char *oem_table_id)
321{
322 int ret = es7000_acpi_ret;
323
324 return ret && es7000_apic_is_cluster();
325}
326
327#else /* !CONFIG_ACPI: */
328static int es7000_acpi_madt_oem_check(char *oem_id, char *oem_table_id)
329{
330 return 0;
331}
332
333static int es7000_acpi_madt_oem_check_cluster(char *oem_id, char *oem_table_id)
334{
335 return 0;
336}
337#endif /* !CONFIG_ACPI */
338
339static void es7000_spin(int n)
340{
341 int i = 0;
342
343 while (i++ < n)
344 rep_nop();
345}
346
347static int es7000_mip_write(struct mip_reg *mip_reg)
348{
349 int status = 0;
350 int spin;
351
352 spin = MIP_SPIN;
353 while ((host_reg->off_0x38 & MIP_VALID) != 0) {
354 if (--spin <= 0) {
355 WARN(1, "Timeout waiting for Host Valid Flag\n");
356 return -1;
357 }
358 es7000_spin(MIP_SPIN);
359 }
360
361 memcpy(host_reg, mip_reg, sizeof(struct mip_reg));
362 outb(1, mip_port);
363
364 spin = MIP_SPIN;
365
366 while ((mip_reg->off_0x38 & MIP_VALID) == 0) {
367 if (--spin <= 0) {
368 WARN(1, "Timeout waiting for MIP Valid Flag\n");
369 return -1;
370 }
371 es7000_spin(MIP_SPIN);
372 }
373
374 status = (mip_reg->off_0x00 & 0xffff0000000000ULL) >> 48;
375 mip_reg->off_0x38 &= ~MIP_VALID;
376
377 return status;
378}
379
380static void es7000_enable_apic_mode(void)
381{
382 struct mip_reg es7000_mip_reg;
383 int mip_status;
384
385 if (!es7000_plat)
386 return;
387
388 pr_info("Enabling APIC mode.\n");
389 memset(&es7000_mip_reg, 0, sizeof(struct mip_reg));
390 es7000_mip_reg.off_0x00 = MIP_SW_APIC;
391 es7000_mip_reg.off_0x38 = MIP_VALID;
392
393 while ((mip_status = es7000_mip_write(&es7000_mip_reg)) != 0)
394 WARN(1, "Command failed, status = %x\n", mip_status);
395}
396
397static unsigned int es7000_get_apic_id(unsigned long x)
398{
399 return (x >> 24) & 0xFF;
400}
401
402static void es7000_send_IPI_mask(const struct cpumask *mask, int vector)
403{
404 default_send_IPI_mask_sequence_phys(mask, vector);
405}
406
407static void es7000_send_IPI_allbutself(int vector)
408{
409 default_send_IPI_mask_allbutself_phys(cpu_online_mask, vector);
410}
411
412static void es7000_send_IPI_all(int vector)
413{
414 es7000_send_IPI_mask(cpu_online_mask, vector);
415}
416
417static int es7000_apic_id_registered(void)
418{
419 return 1;
420}
421
422static const struct cpumask *target_cpus_cluster(void)
423{
424 return cpu_all_mask;
425}
426
427static const struct cpumask *es7000_target_cpus(void)
428{
429 return cpumask_of(smp_processor_id());
430}
431
432static unsigned long es7000_check_apicid_used(physid_mask_t *map, int apicid)
433{
434 return 0;
435}
436
437static unsigned long es7000_check_apicid_present(int bit)
438{
439 return physid_isset(bit, phys_cpu_present_map);
440}
441
442static int es7000_early_logical_apicid(int cpu)
443{
444 /* on es7000, logical apicid is the same as physical */
445 return early_per_cpu(x86_bios_cpu_apicid, cpu);
446}
447
448static unsigned long calculate_ldr(int cpu)
449{
450 unsigned long id = per_cpu(x86_bios_cpu_apicid, cpu);
451
452 return SET_APIC_LOGICAL_ID(id);
453}
454
455/*
456 * Set up the logical destination ID.
457 *
458 * Intel recommends to set DFR, LdR and TPR before enabling
459 * an APIC. See e.g. "AP-388 82489DX User's Manual" (Intel
460 * document number 292116). So here it goes...
461 */
462static void es7000_init_apic_ldr_cluster(void)
463{
464 unsigned long val;
465 int cpu = smp_processor_id();
466
467 apic_write(APIC_DFR, APIC_DFR_CLUSTER);
468 val = calculate_ldr(cpu);
469 apic_write(APIC_LDR, val);
470}
471
472static void es7000_init_apic_ldr(void)
473{
474 unsigned long val;
475 int cpu = smp_processor_id();
476
477 apic_write(APIC_DFR, APIC_DFR_FLAT);
478 val = calculate_ldr(cpu);
479 apic_write(APIC_LDR, val);
480}
481
482static void es7000_setup_apic_routing(void)
483{
484 int apic = per_cpu(x86_bios_cpu_apicid, smp_processor_id());
485
486 pr_info("Enabling APIC mode: %s. Using %d I/O APICs, target cpus %lx\n",
487 (apic_version[apic] == 0x14) ?
488 "Physical Cluster" : "Logical Cluster",
489 nr_ioapics, cpumask_bits(es7000_target_cpus())[0]);
490}
491
492static int es7000_cpu_present_to_apicid(int mps_cpu)
493{
494 if (!mps_cpu)
495 return boot_cpu_physical_apicid;
496 else if (mps_cpu < nr_cpu_ids)
497 return per_cpu(x86_bios_cpu_apicid, mps_cpu);
498 else
499 return BAD_APICID;
500}
501
502static int cpu_id;
503
504static void es7000_apicid_to_cpu_present(int phys_apicid, physid_mask_t *retmap)
505{
506 physid_set_mask_of_physid(cpu_id, retmap);
507 ++cpu_id;
508}
509
510static void es7000_ioapic_phys_id_map(physid_mask_t *phys_map, physid_mask_t *retmap)
511{
512 /* For clustered we don't have a good way to do this yet - hack */
513 physids_promote(0xFFL, retmap);
514}
515
516static int es7000_check_phys_apicid_present(int cpu_physical_apicid)
517{
518 boot_cpu_physical_apicid = read_apic_id();
519 return 1;
520}
521
522static inline int
523es7000_cpu_mask_to_apicid(const struct cpumask *cpumask, unsigned int *dest_id)
524{
525 unsigned int round = 0;
526 unsigned int cpu, uninitialized_var(apicid);
527
528 /*
529 * The cpus in the mask must all be on the apic cluster.
530 */
531 for_each_cpu_and(cpu, cpumask, cpu_online_mask) {
532 int new_apicid = early_per_cpu(x86_cpu_to_logical_apicid, cpu);
533
534 if (round && APIC_CLUSTER(apicid) != APIC_CLUSTER(new_apicid)) {
535 WARN(1, "Not a valid mask!");
536
537 return -EINVAL;
538 }
539 apicid |= new_apicid;
540 round++;
541 }
542 if (!round)
543 return -EINVAL;
544 *dest_id = apicid;
545 return 0;
546}
547
548static int
549es7000_cpu_mask_to_apicid_and(const struct cpumask *inmask,
550 const struct cpumask *andmask,
551 unsigned int *apicid)
552{
553 cpumask_var_t cpumask;
554 *apicid = early_per_cpu(x86_cpu_to_logical_apicid, 0);
555
556 if (!alloc_cpumask_var(&cpumask, GFP_ATOMIC))
557 return 0;
558
559 cpumask_and(cpumask, inmask, andmask);
560 es7000_cpu_mask_to_apicid(cpumask, apicid);
561
562 free_cpumask_var(cpumask);
563
564 return 0;
565}
566
567static int es7000_phys_pkg_id(int cpuid_apic, int index_msb)
568{
569 return cpuid_apic >> index_msb;
570}
571
572static int probe_es7000(void)
573{
574 /* probed later in mptable/ACPI hooks */
575 return 0;
576}
577
578static int es7000_mps_ret;
579static int es7000_mps_oem_check(struct mpc_table *mpc, char *oem,
580 char *productid)
581{
582 int ret = 0;
583
584 if (mpc->oemptr) {
585 struct mpc_oemtable *oem_table =
586 (struct mpc_oemtable *)mpc->oemptr;
587
588 if (!strncmp(oem, "UNISYS", 6))
589 ret = parse_unisys_oem((char *)oem_table);
590 }
591
592 es7000_mps_ret = ret;
593
594 return ret && !es7000_apic_is_cluster();
595}
596
597static int es7000_mps_oem_check_cluster(struct mpc_table *mpc, char *oem,
598 char *productid)
599{
600 int ret = es7000_mps_ret;
601
602 return ret && es7000_apic_is_cluster();
603}
604
605/* We've been warned by a false positive warning.Use __refdata to keep calm. */
606static struct apic __refdata apic_es7000_cluster = {
607
608 .name = "es7000",
609 .probe = probe_es7000,
610 .acpi_madt_oem_check = es7000_acpi_madt_oem_check_cluster,
611 .apic_id_valid = default_apic_id_valid,
612 .apic_id_registered = es7000_apic_id_registered,
613
614 .irq_delivery_mode = dest_LowestPrio,
615 /* logical delivery broadcast to all procs: */
616 .irq_dest_mode = 1,
617
618 .target_cpus = target_cpus_cluster,
619 .disable_esr = 1,
620 .dest_logical = 0,
621 .check_apicid_used = es7000_check_apicid_used,
622 .check_apicid_present = es7000_check_apicid_present,
623
624 .vector_allocation_domain = flat_vector_allocation_domain,
625 .init_apic_ldr = es7000_init_apic_ldr_cluster,
626
627 .ioapic_phys_id_map = es7000_ioapic_phys_id_map,
628 .setup_apic_routing = es7000_setup_apic_routing,
629 .multi_timer_check = NULL,
630 .cpu_present_to_apicid = es7000_cpu_present_to_apicid,
631 .apicid_to_cpu_present = es7000_apicid_to_cpu_present,
632 .setup_portio_remap = NULL,
633 .check_phys_apicid_present = es7000_check_phys_apicid_present,
634 .enable_apic_mode = es7000_enable_apic_mode,
635 .phys_pkg_id = es7000_phys_pkg_id,
636 .mps_oem_check = es7000_mps_oem_check_cluster,
637
638 .get_apic_id = es7000_get_apic_id,
639 .set_apic_id = NULL,
640 .apic_id_mask = 0xFF << 24,
641
642 .cpu_mask_to_apicid_and = es7000_cpu_mask_to_apicid_and,
643
644 .send_IPI_mask = es7000_send_IPI_mask,
645 .send_IPI_mask_allbutself = NULL,
646 .send_IPI_allbutself = es7000_send_IPI_allbutself,
647 .send_IPI_all = es7000_send_IPI_all,
648 .send_IPI_self = default_send_IPI_self,
649
650 .wakeup_secondary_cpu = wakeup_secondary_cpu_via_mip,
651
652 .trampoline_phys_low = 0x467,
653 .trampoline_phys_high = 0x469,
654
655 .wait_for_init_deassert = false,
656 /* Nothing to do for most platforms, since cleared by the INIT cycle: */
657 .smp_callin_clear_local_apic = NULL,
658 .inquire_remote_apic = default_inquire_remote_apic,
659
660 .read = native_apic_mem_read,
661 .write = native_apic_mem_write,
662 .eoi_write = native_apic_mem_write,
663 .icr_read = native_apic_icr_read,
664 .icr_write = native_apic_icr_write,
665 .wait_icr_idle = native_apic_wait_icr_idle,
666 .safe_wait_icr_idle = native_safe_apic_wait_icr_idle,
667
668 .x86_32_early_logical_apicid = es7000_early_logical_apicid,
669};
670
671static struct apic __refdata apic_es7000 = {
672
673 .name = "es7000",
674 .probe = probe_es7000,
675 .acpi_madt_oem_check = es7000_acpi_madt_oem_check,
676 .apic_id_valid = default_apic_id_valid,
677 .apic_id_registered = es7000_apic_id_registered,
678
679 .irq_delivery_mode = dest_Fixed,
680 /* phys delivery to target CPUs: */
681 .irq_dest_mode = 0,
682
683 .target_cpus = es7000_target_cpus,
684 .disable_esr = 1,
685 .dest_logical = 0,
686 .check_apicid_used = es7000_check_apicid_used,
687 .check_apicid_present = es7000_check_apicid_present,
688
689 .vector_allocation_domain = flat_vector_allocation_domain,
690 .init_apic_ldr = es7000_init_apic_ldr,
691
692 .ioapic_phys_id_map = es7000_ioapic_phys_id_map,
693 .setup_apic_routing = es7000_setup_apic_routing,
694 .multi_timer_check = NULL,
695 .cpu_present_to_apicid = es7000_cpu_present_to_apicid,
696 .apicid_to_cpu_present = es7000_apicid_to_cpu_present,
697 .setup_portio_remap = NULL,
698 .check_phys_apicid_present = es7000_check_phys_apicid_present,
699 .enable_apic_mode = es7000_enable_apic_mode,
700 .phys_pkg_id = es7000_phys_pkg_id,
701 .mps_oem_check = es7000_mps_oem_check,
702
703 .get_apic_id = es7000_get_apic_id,
704 .set_apic_id = NULL,
705 .apic_id_mask = 0xFF << 24,
706
707 .cpu_mask_to_apicid_and = es7000_cpu_mask_to_apicid_and,
708
709 .send_IPI_mask = es7000_send_IPI_mask,
710 .send_IPI_mask_allbutself = NULL,
711 .send_IPI_allbutself = es7000_send_IPI_allbutself,
712 .send_IPI_all = es7000_send_IPI_all,
713 .send_IPI_self = default_send_IPI_self,
714
715 .trampoline_phys_low = 0x467,
716 .trampoline_phys_high = 0x469,
717
718 .wait_for_init_deassert = true,
719 /* Nothing to do for most platforms, since cleared by the INIT cycle: */
720 .smp_callin_clear_local_apic = NULL,
721 .inquire_remote_apic = default_inquire_remote_apic,
722
723 .read = native_apic_mem_read,
724 .write = native_apic_mem_write,
725 .eoi_write = native_apic_mem_write,
726 .icr_read = native_apic_icr_read,
727 .icr_write = native_apic_icr_write,
728 .wait_icr_idle = native_apic_wait_icr_idle,
729 .safe_wait_icr_idle = native_safe_apic_wait_icr_idle,
730
731 .x86_32_early_logical_apicid = es7000_early_logical_apicid,
732};
733
734/*
735 * Need to check for es7000 followed by es7000_cluster, so this order
736 * in apic_drivers is important.
737 */
738apic_drivers(apic_es7000, apic_es7000_cluster);
diff --git a/arch/x86/kernel/apic/numaq_32.c b/arch/x86/kernel/apic/numaq_32.c
deleted file mode 100644
index 030ea1c04f72..000000000000
--- a/arch/x86/kernel/apic/numaq_32.c
+++ /dev/null
@@ -1,524 +0,0 @@
1/*
2 * Written by: Patricia Gaughen, IBM Corporation
3 *
4 * Copyright (C) 2002, IBM Corp.
5 * Copyright (C) 2009, Red Hat, Inc., Ingo Molnar
6 *
7 * All rights reserved.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
17 * NON INFRINGEMENT. See the GNU General Public License for more
18 * details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 *
24 * Send feedback to <gone@us.ibm.com>
25 */
26#include <linux/nodemask.h>
27#include <linux/topology.h>
28#include <linux/bootmem.h>
29#include <linux/memblock.h>
30#include <linux/threads.h>
31#include <linux/cpumask.h>
32#include <linux/kernel.h>
33#include <linux/mmzone.h>
34#include <linux/module.h>
35#include <linux/string.h>
36#include <linux/init.h>
37#include <linux/numa.h>
38#include <linux/smp.h>
39#include <linux/io.h>
40#include <linux/mm.h>
41
42#include <asm/processor.h>
43#include <asm/fixmap.h>
44#include <asm/mpspec.h>
45#include <asm/numaq.h>
46#include <asm/setup.h>
47#include <asm/apic.h>
48#include <asm/e820.h>
49#include <asm/ipi.h>
50
51int found_numaq;
52
53/*
54 * Have to match translation table entries to main table entries by counter
55 * hence the mpc_record variable .... can't see a less disgusting way of
56 * doing this ....
57 */
58struct mpc_trans {
59 unsigned char mpc_type;
60 unsigned char trans_len;
61 unsigned char trans_type;
62 unsigned char trans_quad;
63 unsigned char trans_global;
64 unsigned char trans_local;
65 unsigned short trans_reserved;
66};
67
68static int mpc_record;
69
70static struct mpc_trans *translation_table[MAX_MPC_ENTRY];
71
72int mp_bus_id_to_node[MAX_MP_BUSSES];
73int mp_bus_id_to_local[MAX_MP_BUSSES];
74int quad_local_to_mp_bus_id[NR_CPUS/4][4];
75
76
77static inline void numaq_register_node(int node, struct sys_cfg_data *scd)
78{
79 struct eachquadmem *eq = scd->eq + node;
80 u64 start = (u64)(eq->hi_shrd_mem_start - eq->priv_mem_size) << 20;
81 u64 end = (u64)(eq->hi_shrd_mem_start + eq->hi_shrd_mem_size) << 20;
82 int ret;
83
84 node_set(node, numa_nodes_parsed);
85 ret = numa_add_memblk(node, start, end);
86 BUG_ON(ret < 0);
87}
88
89/*
90 * Function: smp_dump_qct()
91 *
92 * Description: gets memory layout from the quad config table. This
93 * function also updates numa_nodes_parsed with the nodes (quads) present.
94 */
95static void __init smp_dump_qct(void)
96{
97 struct sys_cfg_data *scd;
98 int node;
99
100 scd = (void *)__va(SYS_CFG_DATA_PRIV_ADDR);
101
102 for_each_node(node) {
103 if (scd->quads_present31_0 & (1 << node))
104 numaq_register_node(node, scd);
105 }
106}
107
108void numaq_tsc_disable(void)
109{
110 if (!found_numaq)
111 return;
112
113 if (num_online_nodes() > 1) {
114 printk(KERN_DEBUG "NUMAQ: disabling TSC\n");
115 setup_clear_cpu_cap(X86_FEATURE_TSC);
116 }
117}
118
119static void __init numaq_tsc_init(void)
120{
121 numaq_tsc_disable();
122}
123
124static inline int generate_logical_apicid(int quad, int phys_apicid)
125{
126 return (quad << 4) + (phys_apicid ? phys_apicid << 1 : 1);
127}
128
129/* x86_quirks member */
130static int mpc_apic_id(struct mpc_cpu *m)
131{
132 int quad = translation_table[mpc_record]->trans_quad;
133 int logical_apicid = generate_logical_apicid(quad, m->apicid);
134
135 printk(KERN_DEBUG
136 "Processor #%d %u:%u APIC version %d (quad %d, apic %d)\n",
137 m->apicid, (m->cpufeature & CPU_FAMILY_MASK) >> 8,
138 (m->cpufeature & CPU_MODEL_MASK) >> 4,
139 m->apicver, quad, logical_apicid);
140
141 return logical_apicid;
142}
143
144/* x86_quirks member */
145static void mpc_oem_bus_info(struct mpc_bus *m, char *name)
146{
147 int quad = translation_table[mpc_record]->trans_quad;
148 int local = translation_table[mpc_record]->trans_local;
149
150 mp_bus_id_to_node[m->busid] = quad;
151 mp_bus_id_to_local[m->busid] = local;
152
153 printk(KERN_INFO "Bus #%d is %s (node %d)\n", m->busid, name, quad);
154}
155
156/* x86_quirks member */
157static void mpc_oem_pci_bus(struct mpc_bus *m)
158{
159 int quad = translation_table[mpc_record]->trans_quad;
160 int local = translation_table[mpc_record]->trans_local;
161
162 quad_local_to_mp_bus_id[quad][local] = m->busid;
163}
164
165/*
166 * Called from mpparse code.
167 * mode = 0: prescan
168 * mode = 1: one mpc entry scanned
169 */
170static void numaq_mpc_record(unsigned int mode)
171{
172 if (!mode)
173 mpc_record = 0;
174 else
175 mpc_record++;
176}
177
178static void __init MP_translation_info(struct mpc_trans *m)
179{
180 printk(KERN_INFO
181 "Translation: record %d, type %d, quad %d, global %d, local %d\n",
182 mpc_record, m->trans_type, m->trans_quad, m->trans_global,
183 m->trans_local);
184
185 if (mpc_record >= MAX_MPC_ENTRY)
186 printk(KERN_ERR "MAX_MPC_ENTRY exceeded!\n");
187 else
188 translation_table[mpc_record] = m; /* stash this for later */
189
190 if (m->trans_quad < MAX_NUMNODES && !node_online(m->trans_quad))
191 node_set_online(m->trans_quad);
192}
193
194static int __init mpf_checksum(unsigned char *mp, int len)
195{
196 int sum = 0;
197
198 while (len--)
199 sum += *mp++;
200
201 return sum & 0xFF;
202}
203
204/*
205 * Read/parse the MPC oem tables
206 */
207static void __init smp_read_mpc_oem(struct mpc_table *mpc)
208{
209 struct mpc_oemtable *oemtable = (void *)(long)mpc->oemptr;
210 int count = sizeof(*oemtable); /* the header size */
211 unsigned char *oemptr = ((unsigned char *)oemtable) + count;
212
213 mpc_record = 0;
214 printk(KERN_INFO
215 "Found an OEM MPC table at %8p - parsing it...\n", oemtable);
216
217 if (memcmp(oemtable->signature, MPC_OEM_SIGNATURE, 4)) {
218 printk(KERN_WARNING
219 "SMP mpc oemtable: bad signature [%c%c%c%c]!\n",
220 oemtable->signature[0], oemtable->signature[1],
221 oemtable->signature[2], oemtable->signature[3]);
222 return;
223 }
224
225 if (mpf_checksum((unsigned char *)oemtable, oemtable->length)) {
226 printk(KERN_WARNING "SMP oem mptable: checksum error!\n");
227 return;
228 }
229
230 while (count < oemtable->length) {
231 switch (*oemptr) {
232 case MP_TRANSLATION:
233 {
234 struct mpc_trans *m = (void *)oemptr;
235
236 MP_translation_info(m);
237 oemptr += sizeof(*m);
238 count += sizeof(*m);
239 ++mpc_record;
240 break;
241 }
242 default:
243 printk(KERN_WARNING
244 "Unrecognised OEM table entry type! - %d\n",
245 (int)*oemptr);
246 return;
247 }
248 }
249}
250
251static __init void early_check_numaq(void)
252{
253 /*
254 * get boot-time SMP configuration:
255 */
256 if (smp_found_config)
257 early_get_smp_config();
258
259 if (found_numaq) {
260 x86_init.mpparse.mpc_record = numaq_mpc_record;
261 x86_init.mpparse.setup_ioapic_ids = x86_init_noop;
262 x86_init.mpparse.mpc_apic_id = mpc_apic_id;
263 x86_init.mpparse.smp_read_mpc_oem = smp_read_mpc_oem;
264 x86_init.mpparse.mpc_oem_pci_bus = mpc_oem_pci_bus;
265 x86_init.mpparse.mpc_oem_bus_info = mpc_oem_bus_info;
266 x86_init.timers.tsc_pre_init = numaq_tsc_init;
267 x86_init.pci.init = pci_numaq_init;
268 }
269}
270
271int __init numaq_numa_init(void)
272{
273 early_check_numaq();
274 if (!found_numaq)
275 return -ENOENT;
276 smp_dump_qct();
277
278 return 0;
279}
280
281#define NUMAQ_APIC_DFR_VALUE (APIC_DFR_CLUSTER)
282
283static inline unsigned int numaq_get_apic_id(unsigned long x)
284{
285 return (x >> 24) & 0x0F;
286}
287
288static inline void numaq_send_IPI_mask(const struct cpumask *mask, int vector)
289{
290 default_send_IPI_mask_sequence_logical(mask, vector);
291}
292
293static inline void numaq_send_IPI_allbutself(int vector)
294{
295 default_send_IPI_mask_allbutself_logical(cpu_online_mask, vector);
296}
297
298static inline void numaq_send_IPI_all(int vector)
299{
300 numaq_send_IPI_mask(cpu_online_mask, vector);
301}
302
303#define NUMAQ_TRAMPOLINE_PHYS_LOW (0x8)
304#define NUMAQ_TRAMPOLINE_PHYS_HIGH (0xa)
305
306/*
307 * Because we use NMIs rather than the INIT-STARTUP sequence to
308 * bootstrap the CPUs, the APIC may be in a weird state. Kick it:
309 */
310static inline void numaq_smp_callin_clear_local_apic(void)
311{
312 clear_local_APIC();
313}
314
315static inline const struct cpumask *numaq_target_cpus(void)
316{
317 return cpu_all_mask;
318}
319
320static unsigned long numaq_check_apicid_used(physid_mask_t *map, int apicid)
321{
322 return physid_isset(apicid, *map);
323}
324
325static inline unsigned long numaq_check_apicid_present(int bit)
326{
327 return physid_isset(bit, phys_cpu_present_map);
328}
329
330static inline int numaq_apic_id_registered(void)
331{
332 return 1;
333}
334
335static inline void numaq_init_apic_ldr(void)
336{
337 /* Already done in NUMA-Q firmware */
338}
339
340static inline void numaq_setup_apic_routing(void)
341{
342 printk(KERN_INFO
343 "Enabling APIC mode: NUMA-Q. Using %d I/O APICs\n",
344 nr_ioapics);
345}
346
347/*
348 * Skip adding the timer int on secondary nodes, which causes
349 * a small but painful rift in the time-space continuum.
350 */
351static inline int numaq_multi_timer_check(int apic, int irq)
352{
353 return apic != 0 && irq == 0;
354}
355
356static inline void numaq_ioapic_phys_id_map(physid_mask_t *phys_map, physid_mask_t *retmap)
357{
358 /* We don't have a good way to do this yet - hack */
359 return physids_promote(0xFUL, retmap);
360}
361
362/*
363 * Supporting over 60 cpus on NUMA-Q requires a locality-dependent
364 * cpu to APIC ID relation to properly interact with the intelligent
365 * mode of the cluster controller.
366 */
367static inline int numaq_cpu_present_to_apicid(int mps_cpu)
368{
369 if (mps_cpu < 60)
370 return ((mps_cpu >> 2) << 4) | (1 << (mps_cpu & 0x3));
371 else
372 return BAD_APICID;
373}
374
375static inline int numaq_apicid_to_node(int logical_apicid)
376{
377 return logical_apicid >> 4;
378}
379
380static int numaq_numa_cpu_node(int cpu)
381{
382 int logical_apicid = early_per_cpu(x86_cpu_to_logical_apicid, cpu);
383
384 if (logical_apicid != BAD_APICID)
385 return numaq_apicid_to_node(logical_apicid);
386 return NUMA_NO_NODE;
387}
388
389static void numaq_apicid_to_cpu_present(int logical_apicid, physid_mask_t *retmap)
390{
391 int node = numaq_apicid_to_node(logical_apicid);
392 int cpu = __ffs(logical_apicid & 0xf);
393
394 physid_set_mask_of_physid(cpu + 4*node, retmap);
395}
396
397/* Where the IO area was mapped on multiquad, always 0 otherwise */
398void *xquad_portio;
399
400static inline int numaq_check_phys_apicid_present(int phys_apicid)
401{
402 return 1;
403}
404
405/*
406 * We use physical apicids here, not logical, so just return the default
407 * physical broadcast to stop people from breaking us
408 */
409static int
410numaq_cpu_mask_to_apicid_and(const struct cpumask *cpumask,
411 const struct cpumask *andmask,
412 unsigned int *apicid)
413{
414 *apicid = 0x0F;
415 return 0;
416}
417
418/* No NUMA-Q box has a HT CPU, but it can't hurt to use the default code. */
419static inline int numaq_phys_pkg_id(int cpuid_apic, int index_msb)
420{
421 return cpuid_apic >> index_msb;
422}
423
424static int
425numaq_mps_oem_check(struct mpc_table *mpc, char *oem, char *productid)
426{
427 if (strncmp(oem, "IBM NUMA", 8))
428 printk(KERN_ERR "Warning! Not a NUMA-Q system!\n");
429 else
430 found_numaq = 1;
431
432 return found_numaq;
433}
434
435static int probe_numaq(void)
436{
437 /* already know from get_memcfg_numaq() */
438 return found_numaq;
439}
440
441static void numaq_setup_portio_remap(void)
442{
443 int num_quads = num_online_nodes();
444
445 if (num_quads <= 1)
446 return;
447
448 printk(KERN_INFO
449 "Remapping cross-quad port I/O for %d quads\n", num_quads);
450
451 xquad_portio = ioremap(XQUAD_PORTIO_BASE, num_quads*XQUAD_PORTIO_QUAD);
452
453 printk(KERN_INFO
454 "xquad_portio vaddr 0x%08lx, len %08lx\n",
455 (u_long) xquad_portio, (u_long) num_quads*XQUAD_PORTIO_QUAD);
456}
457
458/* Use __refdata to keep false positive warning calm. */
459static struct apic __refdata apic_numaq = {
460
461 .name = "NUMAQ",
462 .probe = probe_numaq,
463 .acpi_madt_oem_check = NULL,
464 .apic_id_valid = default_apic_id_valid,
465 .apic_id_registered = numaq_apic_id_registered,
466
467 .irq_delivery_mode = dest_LowestPrio,
468 /* physical delivery on LOCAL quad: */
469 .irq_dest_mode = 0,
470
471 .target_cpus = numaq_target_cpus,
472 .disable_esr = 1,
473 .dest_logical = APIC_DEST_LOGICAL,
474 .check_apicid_used = numaq_check_apicid_used,
475 .check_apicid_present = numaq_check_apicid_present,
476
477 .vector_allocation_domain = flat_vector_allocation_domain,
478 .init_apic_ldr = numaq_init_apic_ldr,
479
480 .ioapic_phys_id_map = numaq_ioapic_phys_id_map,
481 .setup_apic_routing = numaq_setup_apic_routing,
482 .multi_timer_check = numaq_multi_timer_check,
483 .cpu_present_to_apicid = numaq_cpu_present_to_apicid,
484 .apicid_to_cpu_present = numaq_apicid_to_cpu_present,
485 .setup_portio_remap = numaq_setup_portio_remap,
486 .check_phys_apicid_present = numaq_check_phys_apicid_present,
487 .enable_apic_mode = NULL,
488 .phys_pkg_id = numaq_phys_pkg_id,
489 .mps_oem_check = numaq_mps_oem_check,
490
491 .get_apic_id = numaq_get_apic_id,
492 .set_apic_id = NULL,
493 .apic_id_mask = 0x0F << 24,
494
495 .cpu_mask_to_apicid_and = numaq_cpu_mask_to_apicid_and,
496
497 .send_IPI_mask = numaq_send_IPI_mask,
498 .send_IPI_mask_allbutself = NULL,
499 .send_IPI_allbutself = numaq_send_IPI_allbutself,
500 .send_IPI_all = numaq_send_IPI_all,
501 .send_IPI_self = default_send_IPI_self,
502
503 .wakeup_secondary_cpu = wakeup_secondary_cpu_via_nmi,
504 .trampoline_phys_low = NUMAQ_TRAMPOLINE_PHYS_LOW,
505 .trampoline_phys_high = NUMAQ_TRAMPOLINE_PHYS_HIGH,
506
507 /* We don't do anything here because we use NMI's to boot instead */
508 .wait_for_init_deassert = false,
509 .smp_callin_clear_local_apic = numaq_smp_callin_clear_local_apic,
510 .inquire_remote_apic = NULL,
511
512 .read = native_apic_mem_read,
513 .write = native_apic_mem_write,
514 .eoi_write = native_apic_mem_write,
515 .icr_read = native_apic_icr_read,
516 .icr_write = native_apic_icr_write,
517 .wait_icr_idle = native_apic_wait_icr_idle,
518 .safe_wait_icr_idle = native_safe_apic_wait_icr_idle,
519
520 .x86_32_early_logical_apicid = noop_x86_32_early_logical_apicid,
521 .x86_32_numa_cpu_node = numaq_numa_cpu_node,
522};
523
524apic_driver(apic_numaq);
diff --git a/arch/x86/kernel/apic/summit_32.c b/arch/x86/kernel/apic/summit_32.c
deleted file mode 100644
index b656128611cd..000000000000
--- a/arch/x86/kernel/apic/summit_32.c
+++ /dev/null
@@ -1,550 +0,0 @@
1/*
2 * IBM Summit-Specific Code
3 *
4 * Written By: Matthew Dobson, IBM Corporation
5 *
6 * Copyright (c) 2003 IBM Corp.
7 *
8 * All rights reserved.
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or (at
13 * your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful, but
16 * WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
18 * NON INFRINGEMENT. See the GNU General Public License for more
19 * details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 *
25 * Send feedback to <colpatch@us.ibm.com>
26 *
27 */
28
29#define pr_fmt(fmt) "summit: %s: " fmt, __func__
30
31#include <linux/mm.h>
32#include <asm/io.h>
33#include <asm/bios_ebda.h>
34
35/*
36 * APIC driver for the IBM "Summit" chipset.
37 */
38#include <linux/threads.h>
39#include <linux/cpumask.h>
40#include <asm/mpspec.h>
41#include <asm/apic.h>
42#include <asm/smp.h>
43#include <asm/fixmap.h>
44#include <asm/apicdef.h>
45#include <asm/ipi.h>
46#include <linux/kernel.h>
47#include <linux/string.h>
48#include <linux/gfp.h>
49#include <linux/smp.h>
50
51static unsigned summit_get_apic_id(unsigned long x)
52{
53 return (x >> 24) & 0xFF;
54}
55
56static inline void summit_send_IPI_mask(const struct cpumask *mask, int vector)
57{
58 default_send_IPI_mask_sequence_logical(mask, vector);
59}
60
61static void summit_send_IPI_allbutself(int vector)
62{
63 default_send_IPI_mask_allbutself_logical(cpu_online_mask, vector);
64}
65
66static void summit_send_IPI_all(int vector)
67{
68 summit_send_IPI_mask(cpu_online_mask, vector);
69}
70
71#include <asm/tsc.h>
72
73extern int use_cyclone;
74
75#ifdef CONFIG_X86_SUMMIT_NUMA
76static void setup_summit(void);
77#else
78static inline void setup_summit(void) {}
79#endif
80
81static int summit_mps_oem_check(struct mpc_table *mpc, char *oem,
82 char *productid)
83{
84 if (!strncmp(oem, "IBM ENSW", 8) &&
85 (!strncmp(productid, "VIGIL SMP", 9)
86 || !strncmp(productid, "EXA", 3)
87 || !strncmp(productid, "RUTHLESS SMP", 12))){
88 mark_tsc_unstable("Summit based system");
89 use_cyclone = 1; /*enable cyclone-timer*/
90 setup_summit();
91 return 1;
92 }
93 return 0;
94}
95
96/* Hook from generic ACPI tables.c */
97static int summit_acpi_madt_oem_check(char *oem_id, char *oem_table_id)
98{
99 if (!strncmp(oem_id, "IBM", 3) &&
100 (!strncmp(oem_table_id, "SERVIGIL", 8)
101 || !strncmp(oem_table_id, "EXA", 3))){
102 mark_tsc_unstable("Summit based system");
103 use_cyclone = 1; /*enable cyclone-timer*/
104 setup_summit();
105 return 1;
106 }
107 return 0;
108}
109
110struct rio_table_hdr {
111 unsigned char version; /* Version number of this data structure */
112 /* Version 3 adds chassis_num & WP_index */
113 unsigned char num_scal_dev; /* # of Scalability devices (Twisters for Vigil) */
114 unsigned char num_rio_dev; /* # of RIO I/O devices (Cyclones and Winnipegs) */
115} __attribute__((packed));
116
117struct scal_detail {
118 unsigned char node_id; /* Scalability Node ID */
119 unsigned long CBAR; /* Address of 1MB register space */
120 unsigned char port0node; /* Node ID port connected to: 0xFF=None */
121 unsigned char port0port; /* Port num port connected to: 0,1,2, or 0xFF=None */
122 unsigned char port1node; /* Node ID port connected to: 0xFF = None */
123 unsigned char port1port; /* Port num port connected to: 0,1,2, or 0xFF=None */
124 unsigned char port2node; /* Node ID port connected to: 0xFF = None */
125 unsigned char port2port; /* Port num port connected to: 0,1,2, or 0xFF=None */
126 unsigned char chassis_num; /* 1 based Chassis number (1 = boot node) */
127} __attribute__((packed));
128
129struct rio_detail {
130 unsigned char node_id; /* RIO Node ID */
131 unsigned long BBAR; /* Address of 1MB register space */
132 unsigned char type; /* Type of device */
133 unsigned char owner_id; /* For WPEG: Node ID of Cyclone that owns this WPEG*/
134 /* For CYC: Node ID of Twister that owns this CYC */
135 unsigned char port0node; /* Node ID port connected to: 0xFF=None */
136 unsigned char port0port; /* Port num port connected to: 0,1,2, or 0xFF=None */
137 unsigned char port1node; /* Node ID port connected to: 0xFF=None */
138 unsigned char port1port; /* Port num port connected to: 0,1,2, or 0xFF=None */
139 unsigned char first_slot; /* For WPEG: Lowest slot number below this WPEG */
140 /* For CYC: 0 */
141 unsigned char status; /* For WPEG: Bit 0 = 1 : the XAPIC is used */
142 /* = 0 : the XAPIC is not used, ie:*/
143 /* ints fwded to another XAPIC */
144 /* Bits1:7 Reserved */
145 /* For CYC: Bits0:7 Reserved */
146 unsigned char WP_index; /* For WPEG: WPEG instance index - lower ones have */
147 /* lower slot numbers/PCI bus numbers */
148 /* For CYC: No meaning */
149 unsigned char chassis_num; /* 1 based Chassis number */
150 /* For LookOut WPEGs this field indicates the */
151 /* Expansion Chassis #, enumerated from Boot */
152 /* Node WPEG external port, then Boot Node CYC */
153 /* external port, then Next Vigil chassis WPEG */
154 /* external port, etc. */
155 /* Shared Lookouts have only 1 chassis number (the */
156 /* first one assigned) */
157} __attribute__((packed));
158
159
160typedef enum {
161 CompatTwister = 0, /* Compatibility Twister */
162 AltTwister = 1, /* Alternate Twister of internal 8-way */
163 CompatCyclone = 2, /* Compatibility Cyclone */
164 AltCyclone = 3, /* Alternate Cyclone of internal 8-way */
165 CompatWPEG = 4, /* Compatibility WPEG */
166 AltWPEG = 5, /* Second Planar WPEG */
167 LookOutAWPEG = 6, /* LookOut WPEG */
168 LookOutBWPEG = 7, /* LookOut WPEG */
169} node_type;
170
171static inline int is_WPEG(struct rio_detail *rio){
172 return (rio->type == CompatWPEG || rio->type == AltWPEG ||
173 rio->type == LookOutAWPEG || rio->type == LookOutBWPEG);
174}
175
176#define SUMMIT_APIC_DFR_VALUE (APIC_DFR_CLUSTER)
177
178static const struct cpumask *summit_target_cpus(void)
179{
180 /* CPU_MASK_ALL (0xff) has undefined behaviour with
181 * dest_LowestPrio mode logical clustered apic interrupt routing
182 * Just start on cpu 0. IRQ balancing will spread load
183 */
184 return cpumask_of(0);
185}
186
187static unsigned long summit_check_apicid_used(physid_mask_t *map, int apicid)
188{
189 return 0;
190}
191
192/* we don't use the phys_cpu_present_map to indicate apicid presence */
193static unsigned long summit_check_apicid_present(int bit)
194{
195 return 1;
196}
197
198static int summit_early_logical_apicid(int cpu)
199{
200 int count = 0;
201 u8 my_id = early_per_cpu(x86_cpu_to_apicid, cpu);
202 u8 my_cluster = APIC_CLUSTER(my_id);
203#ifdef CONFIG_SMP
204 u8 lid;
205 int i;
206
207 /* Create logical APIC IDs by counting CPUs already in cluster. */
208 for (count = 0, i = nr_cpu_ids; --i >= 0; ) {
209 lid = early_per_cpu(x86_cpu_to_logical_apicid, i);
210 if (lid != BAD_APICID && APIC_CLUSTER(lid) == my_cluster)
211 ++count;
212 }
213#endif
214 /* We only have a 4 wide bitmap in cluster mode. If a deranged
215 * BIOS puts 5 CPUs in one APIC cluster, we're hosed. */
216 BUG_ON(count >= XAPIC_DEST_CPUS_SHIFT);
217 return my_cluster | (1UL << count);
218}
219
220static void summit_init_apic_ldr(void)
221{
222 int cpu = smp_processor_id();
223 unsigned long id = early_per_cpu(x86_cpu_to_logical_apicid, cpu);
224 unsigned long val;
225
226 apic_write(APIC_DFR, SUMMIT_APIC_DFR_VALUE);
227 val = apic_read(APIC_LDR) & ~APIC_LDR_MASK;
228 val |= SET_APIC_LOGICAL_ID(id);
229 apic_write(APIC_LDR, val);
230}
231
232static int summit_apic_id_registered(void)
233{
234 return 1;
235}
236
237static void summit_setup_apic_routing(void)
238{
239 pr_info("Enabling APIC mode: Summit. Using %d I/O APICs\n",
240 nr_ioapics);
241}
242
243static int summit_cpu_present_to_apicid(int mps_cpu)
244{
245 if (mps_cpu < nr_cpu_ids)
246 return (int)per_cpu(x86_bios_cpu_apicid, mps_cpu);
247 else
248 return BAD_APICID;
249}
250
251static void summit_ioapic_phys_id_map(physid_mask_t *phys_id_map, physid_mask_t *retmap)
252{
253 /* For clustered we don't have a good way to do this yet - hack */
254 physids_promote(0x0FL, retmap);
255}
256
257static void summit_apicid_to_cpu_present(int apicid, physid_mask_t *retmap)
258{
259 physid_set_mask_of_physid(0, retmap);
260}
261
262static int summit_check_phys_apicid_present(int physical_apicid)
263{
264 return 1;
265}
266
267static inline int
268summit_cpu_mask_to_apicid(const struct cpumask *cpumask, unsigned int *dest_id)
269{
270 unsigned int round = 0;
271 unsigned int cpu, apicid = 0;
272
273 /*
274 * The cpus in the mask must all be on the apic cluster.
275 */
276 for_each_cpu_and(cpu, cpumask, cpu_online_mask) {
277 int new_apicid = early_per_cpu(x86_cpu_to_logical_apicid, cpu);
278
279 if (round && APIC_CLUSTER(apicid) != APIC_CLUSTER(new_apicid)) {
280 pr_err("Not a valid mask!\n");
281 return -EINVAL;
282 }
283 apicid |= new_apicid;
284 round++;
285 }
286 if (!round)
287 return -EINVAL;
288 *dest_id = apicid;
289 return 0;
290}
291
292static int
293summit_cpu_mask_to_apicid_and(const struct cpumask *inmask,
294 const struct cpumask *andmask,
295 unsigned int *apicid)
296{
297 cpumask_var_t cpumask;
298 *apicid = early_per_cpu(x86_cpu_to_logical_apicid, 0);
299
300 if (!alloc_cpumask_var(&cpumask, GFP_ATOMIC))
301 return 0;
302
303 cpumask_and(cpumask, inmask, andmask);
304 summit_cpu_mask_to_apicid(cpumask, apicid);
305
306 free_cpumask_var(cpumask);
307
308 return 0;
309}
310
311/*
312 * cpuid returns the value latched in the HW at reset, not the APIC ID
313 * register's value. For any box whose BIOS changes APIC IDs, like
314 * clustered APIC systems, we must use hard_smp_processor_id.
315 *
316 * See Intel's IA-32 SW Dev's Manual Vol2 under CPUID.
317 */
318static int summit_phys_pkg_id(int cpuid_apic, int index_msb)
319{
320 return hard_smp_processor_id() >> index_msb;
321}
322
323static int probe_summit(void)
324{
325 /* probed later in mptable/ACPI hooks */
326 return 0;
327}
328
329#ifdef CONFIG_X86_SUMMIT_NUMA
330static struct rio_table_hdr *rio_table_hdr;
331static struct scal_detail *scal_devs[MAX_NUMNODES];
332static struct rio_detail *rio_devs[MAX_NUMNODES*4];
333
334#ifndef CONFIG_X86_NUMAQ
335static int mp_bus_id_to_node[MAX_MP_BUSSES];
336#endif
337
338static int setup_pci_node_map_for_wpeg(int wpeg_num, int last_bus)
339{
340 int twister = 0, node = 0;
341 int i, bus, num_buses;
342
343 for (i = 0; i < rio_table_hdr->num_rio_dev; i++) {
344 if (rio_devs[i]->node_id == rio_devs[wpeg_num]->owner_id) {
345 twister = rio_devs[i]->owner_id;
346 break;
347 }
348 }
349 if (i == rio_table_hdr->num_rio_dev) {
350 pr_err("Couldn't find owner Cyclone for Winnipeg!\n");
351 return last_bus;
352 }
353
354 for (i = 0; i < rio_table_hdr->num_scal_dev; i++) {
355 if (scal_devs[i]->node_id == twister) {
356 node = scal_devs[i]->node_id;
357 break;
358 }
359 }
360 if (i == rio_table_hdr->num_scal_dev) {
361 pr_err("Couldn't find owner Twister for Cyclone!\n");
362 return last_bus;
363 }
364
365 switch (rio_devs[wpeg_num]->type) {
366 case CompatWPEG:
367 /*
368 * The Compatibility Winnipeg controls the 2 legacy buses,
369 * the 66MHz PCI bus [2 slots] and the 2 "extra" buses in case
370 * a PCI-PCI bridge card is used in either slot: total 5 buses.
371 */
372 num_buses = 5;
373 break;
374 case AltWPEG:
375 /*
376 * The Alternate Winnipeg controls the 2 133MHz buses [1 slot
377 * each], their 2 "extra" buses, the 100MHz bus [2 slots] and
378 * the "extra" buses for each of those slots: total 7 buses.
379 */
380 num_buses = 7;
381 break;
382 case LookOutAWPEG:
383 case LookOutBWPEG:
384 /*
385 * A Lookout Winnipeg controls 3 100MHz buses [2 slots each]
386 * & the "extra" buses for each of those slots: total 9 buses.
387 */
388 num_buses = 9;
389 break;
390 default:
391 pr_info("Unsupported Winnipeg type!\n");
392 return last_bus;
393 }
394
395 for (bus = last_bus; bus < last_bus + num_buses; bus++)
396 mp_bus_id_to_node[bus] = node;
397 return bus;
398}
399
400static int build_detail_arrays(void)
401{
402 unsigned long ptr;
403 int i, scal_detail_size, rio_detail_size;
404
405 if (rio_table_hdr->num_scal_dev > MAX_NUMNODES) {
406 pr_warn("MAX_NUMNODES too low! Defined as %d, but system has %d nodes\n",
407 MAX_NUMNODES, rio_table_hdr->num_scal_dev);
408 return 0;
409 }
410
411 switch (rio_table_hdr->version) {
412 default:
413 pr_warn("Invalid Rio Grande Table Version: %d\n",
414 rio_table_hdr->version);
415 return 0;
416 case 2:
417 scal_detail_size = 11;
418 rio_detail_size = 13;
419 break;
420 case 3:
421 scal_detail_size = 12;
422 rio_detail_size = 15;
423 break;
424 }
425
426 ptr = (unsigned long)rio_table_hdr + 3;
427 for (i = 0; i < rio_table_hdr->num_scal_dev; i++, ptr += scal_detail_size)
428 scal_devs[i] = (struct scal_detail *)ptr;
429
430 for (i = 0; i < rio_table_hdr->num_rio_dev; i++, ptr += rio_detail_size)
431 rio_devs[i] = (struct rio_detail *)ptr;
432
433 return 1;
434}
435
436void setup_summit(void)
437{
438 unsigned long ptr;
439 unsigned short offset;
440 int i, next_wpeg, next_bus = 0;
441
442 /* The pointer to the EBDA is stored in the word @ phys 0x40E(40:0E) */
443 ptr = get_bios_ebda();
444 ptr = (unsigned long)phys_to_virt(ptr);
445
446 rio_table_hdr = NULL;
447 offset = 0x180;
448 while (offset) {
449 /* The block id is stored in the 2nd word */
450 if (*((unsigned short *)(ptr + offset + 2)) == 0x4752) {
451 /* set the pointer past the offset & block id */
452 rio_table_hdr = (struct rio_table_hdr *)(ptr + offset + 4);
453 break;
454 }
455 /* The next offset is stored in the 1st word. 0 means no more */
456 offset = *((unsigned short *)(ptr + offset));
457 }
458 if (!rio_table_hdr) {
459 pr_err("Unable to locate Rio Grande Table in EBDA - bailing!\n");
460 return;
461 }
462
463 if (!build_detail_arrays())
464 return;
465
466 /* The first Winnipeg we're looking for has an index of 0 */
467 next_wpeg = 0;
468 do {
469 for (i = 0; i < rio_table_hdr->num_rio_dev; i++) {
470 if (is_WPEG(rio_devs[i]) && rio_devs[i]->WP_index == next_wpeg) {
471 /* It's the Winnipeg we're looking for! */
472 next_bus = setup_pci_node_map_for_wpeg(i, next_bus);
473 next_wpeg++;
474 break;
475 }
476 }
477 /*
478 * If we go through all Rio devices and don't find one with
479 * the next index, it means we've found all the Winnipegs,
480 * and thus all the PCI buses.
481 */
482 if (i == rio_table_hdr->num_rio_dev)
483 next_wpeg = 0;
484 } while (next_wpeg != 0);
485}
486#endif
487
488static struct apic apic_summit = {
489
490 .name = "summit",
491 .probe = probe_summit,
492 .acpi_madt_oem_check = summit_acpi_madt_oem_check,
493 .apic_id_valid = default_apic_id_valid,
494 .apic_id_registered = summit_apic_id_registered,
495
496 .irq_delivery_mode = dest_LowestPrio,
497 /* logical delivery broadcast to all CPUs: */
498 .irq_dest_mode = 1,
499
500 .target_cpus = summit_target_cpus,
501 .disable_esr = 1,
502 .dest_logical = APIC_DEST_LOGICAL,
503 .check_apicid_used = summit_check_apicid_used,
504 .check_apicid_present = summit_check_apicid_present,
505
506 .vector_allocation_domain = flat_vector_allocation_domain,
507 .init_apic_ldr = summit_init_apic_ldr,
508
509 .ioapic_phys_id_map = summit_ioapic_phys_id_map,
510 .setup_apic_routing = summit_setup_apic_routing,
511 .multi_timer_check = NULL,
512 .cpu_present_to_apicid = summit_cpu_present_to_apicid,
513 .apicid_to_cpu_present = summit_apicid_to_cpu_present,
514 .setup_portio_remap = NULL,
515 .check_phys_apicid_present = summit_check_phys_apicid_present,
516 .enable_apic_mode = NULL,
517 .phys_pkg_id = summit_phys_pkg_id,
518 .mps_oem_check = summit_mps_oem_check,
519
520 .get_apic_id = summit_get_apic_id,
521 .set_apic_id = NULL,
522 .apic_id_mask = 0xFF << 24,
523
524 .cpu_mask_to_apicid_and = summit_cpu_mask_to_apicid_and,
525
526 .send_IPI_mask = summit_send_IPI_mask,
527 .send_IPI_mask_allbutself = NULL,
528 .send_IPI_allbutself = summit_send_IPI_allbutself,
529 .send_IPI_all = summit_send_IPI_all,
530 .send_IPI_self = default_send_IPI_self,
531
532 .trampoline_phys_low = DEFAULT_TRAMPOLINE_PHYS_LOW,
533 .trampoline_phys_high = DEFAULT_TRAMPOLINE_PHYS_HIGH,
534
535 .wait_for_init_deassert = true,
536 .smp_callin_clear_local_apic = NULL,
537 .inquire_remote_apic = default_inquire_remote_apic,
538
539 .read = native_apic_mem_read,
540 .write = native_apic_mem_write,
541 .eoi_write = native_apic_mem_write,
542 .icr_read = native_apic_icr_read,
543 .icr_write = native_apic_icr_write,
544 .wait_icr_idle = native_apic_wait_icr_idle,
545 .safe_wait_icr_idle = native_safe_apic_wait_icr_idle,
546
547 .x86_32_early_logical_apicid = summit_early_logical_apicid,
548};
549
550apic_driver(apic_summit);
diff --git a/arch/x86/kernel/cpu/intel.c b/arch/x86/kernel/cpu/intel.c
index 897d6201ef10..a80029035bf2 100644
--- a/arch/x86/kernel/cpu/intel.c
+++ b/arch/x86/kernel/cpu/intel.c
@@ -274,10 +274,6 @@ static void intel_workarounds(struct cpuinfo_x86 *c)
274 } 274 }
275#endif 275#endif
276 276
277#ifdef CONFIG_X86_NUMAQ
278 numaq_tsc_disable();
279#endif
280
281 intel_smp_check(c); 277 intel_smp_check(c);
282} 278}
283#else 279#else
diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
index fa511acff7e6..09c76d265550 100644
--- a/arch/x86/kernel/setup.c
+++ b/arch/x86/kernel/setup.c
@@ -869,7 +869,6 @@ void __init setup_arch(char **cmdline_p)
869 869
870#ifdef CONFIG_X86_32 870#ifdef CONFIG_X86_32
871 memcpy(&boot_cpu_data, &new_cpu_data, sizeof(new_cpu_data)); 871 memcpy(&boot_cpu_data, &new_cpu_data, sizeof(new_cpu_data));
872 visws_early_detect();
873 872
874 /* 873 /*
875 * copy kernel address range established so far and switch 874 * copy kernel address range established so far and switch