diff options
author | H. Peter Anvin <hpa@linux.intel.com> | 2014-02-25 15:14:06 -0500 |
---|---|---|
committer | H. Peter Anvin <hpa@linux.intel.com> | 2014-02-27 11:07:39 -0500 |
commit | b5660ba76b41af69a0c09d434927bb4b4cadd4b1 (patch) | |
tree | 82cf802311ed7423cb527ba4ec2c6b166cad76e5 | |
parent | c5f9ee3d665a7660b296aa1e91949ae3376f0d07 (diff) |
x86, platforms: Remove NUMAQ
The NUMAQ support seems to be unmaintained, remove it.
Cc: Paul Gortmaker <paul.gortmaker@windriver.com>
Cc: David Rientjes <rientjes@google.com>
Acked-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
Signed-off-by: H. Peter Anvin <hpa@linux.intel.com>
Link: http://lkml.kernel.org/r/n/530CFD6C.7040705@zytor.com
-rw-r--r-- | arch/x86/Kconfig | 36 | ||||
-rw-r--r-- | arch/x86/Kconfig.cpu | 2 | ||||
-rw-r--r-- | arch/x86/include/asm/mmzone_32.h | 3 | ||||
-rw-r--r-- | arch/x86/include/asm/mpspec.h | 6 | ||||
-rw-r--r-- | arch/x86/include/asm/numaq.h | 171 | ||||
-rw-r--r-- | arch/x86/kernel/apic/Makefile | 1 | ||||
-rw-r--r-- | arch/x86/kernel/apic/numaq_32.c | 524 | ||||
-rw-r--r-- | arch/x86/kernel/cpu/intel.c | 4 | ||||
-rw-r--r-- | arch/x86/mm/numa.c | 4 | ||||
-rw-r--r-- | arch/x86/pci/Makefile | 1 | ||||
-rw-r--r-- | arch/x86/pci/numaq_32.c | 165 |
11 files changed, 9 insertions, 908 deletions
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index 3c7f6dbf8498..e1d0c9ac2b56 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig | |||
@@ -346,7 +346,6 @@ config X86_EXTENDED_PLATFORM | |||
346 | for the following (non-PC) 32 bit x86 platforms: | 346 | for the following (non-PC) 32 bit x86 platforms: |
347 | Goldfish (Android emulator) | 347 | Goldfish (Android emulator) |
348 | AMD Elan | 348 | AMD Elan |
349 | NUMAQ (IBM/Sequent) | ||
350 | RDC R-321x SoC | 349 | RDC R-321x SoC |
351 | SGI 320/540 (Visual Workstation) | 350 | SGI 320/540 (Visual Workstation) |
352 | STA2X11-based (e.g. Northville) | 351 | STA2X11-based (e.g. Northville) |
@@ -487,32 +486,18 @@ config X86_32_NON_STANDARD | |||
487 | depends on X86_32 && SMP | 486 | depends on X86_32 && SMP |
488 | depends on X86_EXTENDED_PLATFORM | 487 | depends on X86_EXTENDED_PLATFORM |
489 | ---help--- | 488 | ---help--- |
490 | This option compiles in the NUMAQ, bigsmp, and STA2X11 default | 489 | This option compiles in the bigsmp and STA2X11 default |
491 | subarchitectures. It is intended for a generic binary kernel. If you | 490 | subarchitectures. It is intended for a generic binary |
492 | select them all, kernel will probe it one by one and will fallback to | 491 | kernel. If you select them all, kernel will probe it one by |
493 | default. | 492 | one and will fallback to default. |
494 | 493 | ||
495 | # Alphabetically sorted list of Non standard 32 bit platforms | 494 | # Alphabetically sorted list of Non standard 32 bit platforms |
496 | 495 | ||
497 | config X86_NUMAQ | ||
498 | bool "NUMAQ (IBM/Sequent)" | ||
499 | depends on X86_32_NON_STANDARD | ||
500 | depends on PCI | ||
501 | select NUMA | ||
502 | select X86_MPPARSE | ||
503 | ---help--- | ||
504 | This option is used for getting Linux to run on a NUMAQ (IBM/Sequent) | ||
505 | NUMA multiquad box. This changes the way that processors are | ||
506 | bootstrapped, and uses Clustered Logical APIC addressing mode instead | ||
507 | of Flat Logical. You will need a new lynxer.elf file to flash your | ||
508 | firmware with - send email to <Martin.Bligh@us.ibm.com>. | ||
509 | |||
510 | config X86_SUPPORTS_MEMORY_FAILURE | 496 | config X86_SUPPORTS_MEMORY_FAILURE |
511 | def_bool y | 497 | def_bool y |
512 | # MCE code calls memory_failure(): | 498 | # MCE code calls memory_failure(): |
513 | depends on X86_MCE | 499 | depends on X86_MCE |
514 | # On 32-bit this adds too big of NODES_SHIFT and we run out of page flags: | 500 | # On 32-bit this adds too big of NODES_SHIFT and we run out of page flags: |
515 | depends on !X86_NUMAQ | ||
516 | # On 32-bit SPARSEMEM adds too big of SECTIONS_WIDTH: | 501 | # On 32-bit SPARSEMEM adds too big of SECTIONS_WIDTH: |
517 | depends on X86_64 || !SPARSEMEM | 502 | depends on X86_64 || !SPARSEMEM |
518 | select ARCH_SUPPORTS_MEMORY_FAILURE | 503 | select ARCH_SUPPORTS_MEMORY_FAILURE |
@@ -783,7 +768,7 @@ config NR_CPUS | |||
783 | range 2 8192 if SMP && !MAXSMP && CPUMASK_OFFSTACK && X86_64 | 768 | range 2 8192 if SMP && !MAXSMP && CPUMASK_OFFSTACK && X86_64 |
784 | default "1" if !SMP | 769 | default "1" if !SMP |
785 | default "8192" if MAXSMP | 770 | default "8192" if MAXSMP |
786 | default "32" if SMP && (X86_NUMAQ || X86_BIGSMP) | 771 | default "32" if SMP && X86_BIGSMP |
787 | default "8" if SMP | 772 | default "8" if SMP |
788 | ---help--- | 773 | ---help--- |
789 | This allows you to specify the maximum number of CPUs which this | 774 | This allows you to specify the maximum number of CPUs which this |
@@ -1064,13 +1049,11 @@ config X86_CPUID | |||
1064 | 1049 | ||
1065 | choice | 1050 | choice |
1066 | prompt "High Memory Support" | 1051 | prompt "High Memory Support" |
1067 | default HIGHMEM64G if X86_NUMAQ | ||
1068 | default HIGHMEM4G | 1052 | default HIGHMEM4G |
1069 | depends on X86_32 | 1053 | depends on X86_32 |
1070 | 1054 | ||
1071 | config NOHIGHMEM | 1055 | config NOHIGHMEM |
1072 | bool "off" | 1056 | bool "off" |
1073 | depends on !X86_NUMAQ | ||
1074 | ---help--- | 1057 | ---help--- |
1075 | Linux can use up to 64 Gigabytes of physical memory on x86 systems. | 1058 | Linux can use up to 64 Gigabytes of physical memory on x86 systems. |
1076 | However, the address space of 32-bit x86 processors is only 4 | 1059 | However, the address space of 32-bit x86 processors is only 4 |
@@ -1107,7 +1090,6 @@ config NOHIGHMEM | |||
1107 | 1090 | ||
1108 | config HIGHMEM4G | 1091 | config HIGHMEM4G |
1109 | bool "4GB" | 1092 | bool "4GB" |
1110 | depends on !X86_NUMAQ | ||
1111 | ---help--- | 1093 | ---help--- |
1112 | Select this if you have a 32-bit processor and between 1 and 4 | 1094 | Select this if you have a 32-bit processor and between 1 and 4 |
1113 | gigabytes of physical RAM. | 1095 | gigabytes of physical RAM. |
@@ -1199,8 +1181,8 @@ config DIRECT_GBPAGES | |||
1199 | config NUMA | 1181 | config NUMA |
1200 | bool "Numa Memory Allocation and Scheduler Support" | 1182 | bool "Numa Memory Allocation and Scheduler Support" |
1201 | depends on SMP | 1183 | depends on SMP |
1202 | depends on X86_64 || (X86_32 && HIGHMEM64G && (X86_NUMAQ || X86_BIGSMP)) | 1184 | depends on X86_64 || (X86_32 && HIGHMEM64G && X86_BIGSMP) |
1203 | default y if (X86_NUMAQ || X86_BIGSMP) | 1185 | default y if X86_BIGSMP |
1204 | ---help--- | 1186 | ---help--- |
1205 | Enable NUMA (Non Uniform Memory Access) support. | 1187 | Enable NUMA (Non Uniform Memory Access) support. |
1206 | 1188 | ||
@@ -1211,8 +1193,7 @@ config NUMA | |||
1211 | For 64-bit this is recommended if the system is Intel Core i7 | 1193 | For 64-bit this is recommended if the system is Intel Core i7 |
1212 | (or later), AMD Opteron, or EM64T NUMA. | 1194 | (or later), AMD Opteron, or EM64T NUMA. |
1213 | 1195 | ||
1214 | For 32-bit this is only needed on (rare) 32-bit-only platforms | 1196 | For 32-bit this is only needed if you boot a 32-bit |
1215 | that support NUMA topologies, such as NUMAQ, or if you boot a 32-bit | ||
1216 | kernel on a 64-bit NUMA platform. | 1197 | kernel on a 64-bit NUMA platform. |
1217 | 1198 | ||
1218 | Otherwise, you should say N. | 1199 | Otherwise, you should say N. |
@@ -1258,7 +1239,6 @@ config NODES_SHIFT | |||
1258 | range 1 10 | 1239 | range 1 10 |
1259 | default "10" if MAXSMP | 1240 | default "10" if MAXSMP |
1260 | default "6" if X86_64 | 1241 | default "6" if X86_64 |
1261 | default "4" if X86_NUMAQ | ||
1262 | default "3" | 1242 | default "3" |
1263 | depends on NEED_MULTIPLE_NODES | 1243 | depends on NEED_MULTIPLE_NODES |
1264 | ---help--- | 1244 | ---help--- |
diff --git a/arch/x86/Kconfig.cpu b/arch/x86/Kconfig.cpu index c026cca5602c..3c6b17b08a18 100644 --- a/arch/x86/Kconfig.cpu +++ b/arch/x86/Kconfig.cpu | |||
@@ -363,7 +363,7 @@ config X86_P6_NOP | |||
363 | 363 | ||
364 | config X86_TSC | 364 | config X86_TSC |
365 | def_bool y | 365 | def_bool y |
366 | depends on ((MWINCHIP3D || MCRUSOE || MEFFICEON || MCYRIXIII || MK7 || MK6 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || MK8 || MVIAC3_2 || MVIAC7 || MGEODEGX1 || MGEODE_LX || MCORE2 || MATOM) && !X86_NUMAQ) || X86_64 | 366 | depends on (MWINCHIP3D || MCRUSOE || MEFFICEON || MCYRIXIII || MK7 || MK6 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || MK8 || MVIAC3_2 || MVIAC7 || MGEODEGX1 || MGEODE_LX || MCORE2 || MATOM) || X86_64 |
367 | 367 | ||
368 | config X86_CMPXCHG64 | 368 | config X86_CMPXCHG64 |
369 | def_bool y | 369 | def_bool y |
diff --git a/arch/x86/include/asm/mmzone_32.h b/arch/x86/include/asm/mmzone_32.h index 8a9b3e288cb4..1ec990bd7dc0 100644 --- a/arch/x86/include/asm/mmzone_32.h +++ b/arch/x86/include/asm/mmzone_32.h | |||
@@ -11,9 +11,6 @@ | |||
11 | #ifdef CONFIG_NUMA | 11 | #ifdef CONFIG_NUMA |
12 | extern struct pglist_data *node_data[]; | 12 | extern struct pglist_data *node_data[]; |
13 | #define NODE_DATA(nid) (node_data[nid]) | 13 | #define NODE_DATA(nid) (node_data[nid]) |
14 | |||
15 | #include <asm/numaq.h> | ||
16 | |||
17 | #endif /* CONFIG_NUMA */ | 14 | #endif /* CONFIG_NUMA */ |
18 | 15 | ||
19 | #ifdef CONFIG_DISCONTIGMEM | 16 | #ifdef CONFIG_DISCONTIGMEM |
diff --git a/arch/x86/include/asm/mpspec.h b/arch/x86/include/asm/mpspec.h index 3e6b4920ef5d..f5a617956735 100644 --- a/arch/x86/include/asm/mpspec.h +++ b/arch/x86/include/asm/mpspec.h | |||
@@ -25,12 +25,6 @@ extern int pic_mode; | |||
25 | 25 | ||
26 | extern unsigned int def_to_bigsmp; | 26 | extern unsigned int def_to_bigsmp; |
27 | 27 | ||
28 | #ifdef CONFIG_X86_NUMAQ | ||
29 | extern int mp_bus_id_to_node[MAX_MP_BUSSES]; | ||
30 | extern int mp_bus_id_to_local[MAX_MP_BUSSES]; | ||
31 | extern int quad_local_to_mp_bus_id [NR_CPUS/4][4]; | ||
32 | #endif | ||
33 | |||
34 | #else /* CONFIG_X86_64: */ | 28 | #else /* CONFIG_X86_64: */ |
35 | 29 | ||
36 | #define MAX_MP_BUSSES 256 | 30 | #define MAX_MP_BUSSES 256 |
diff --git a/arch/x86/include/asm/numaq.h b/arch/x86/include/asm/numaq.h deleted file mode 100644 index c3b3c322fd87..000000000000 --- a/arch/x86/include/asm/numaq.h +++ /dev/null | |||
@@ -1,171 +0,0 @@ | |||
1 | /* | ||
2 | * Written by: Patricia Gaughen, IBM Corporation | ||
3 | * | ||
4 | * Copyright (C) 2002, IBM Corp. | ||
5 | * | ||
6 | * All rights reserved. | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License as published by | ||
10 | * the Free Software Foundation; either version 2 of the License, or | ||
11 | * (at your option) any later version. | ||
12 | * | ||
13 | * This program is distributed in the hope that it will be useful, but | ||
14 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
15 | * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or | ||
16 | * NON INFRINGEMENT. See the GNU General Public License for more | ||
17 | * details. | ||
18 | * | ||
19 | * You should have received a copy of the GNU General Public License | ||
20 | * along with this program; if not, write to the Free Software | ||
21 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
22 | * | ||
23 | * Send feedback to <gone@us.ibm.com> | ||
24 | */ | ||
25 | |||
26 | #ifndef _ASM_X86_NUMAQ_H | ||
27 | #define _ASM_X86_NUMAQ_H | ||
28 | |||
29 | #ifdef CONFIG_X86_NUMAQ | ||
30 | |||
31 | extern int found_numaq; | ||
32 | extern int numaq_numa_init(void); | ||
33 | extern int pci_numaq_init(void); | ||
34 | |||
35 | extern void *xquad_portio; | ||
36 | |||
37 | #define XQUAD_PORTIO_BASE 0xfe400000 | ||
38 | #define XQUAD_PORTIO_QUAD 0x40000 /* 256k per quad. */ | ||
39 | #define XQUAD_PORT_ADDR(port, quad) (xquad_portio + (XQUAD_PORTIO_QUAD*quad) + port) | ||
40 | |||
41 | /* | ||
42 | * SYS_CFG_DATA_PRIV_ADDR, struct eachquadmem, and struct sys_cfg_data are the | ||
43 | */ | ||
44 | #define SYS_CFG_DATA_PRIV_ADDR 0x0009d000 /* place for scd in private | ||
45 | quad space */ | ||
46 | |||
47 | /* | ||
48 | * Communication area for each processor on lynxer-processor tests. | ||
49 | * | ||
50 | * NOTE: If you change the size of this eachproc structure you need | ||
51 | * to change the definition for EACH_QUAD_SIZE. | ||
52 | */ | ||
53 | struct eachquadmem { | ||
54 | unsigned int priv_mem_start; /* Starting address of this */ | ||
55 | /* quad's private memory. */ | ||
56 | /* This is always 0. */ | ||
57 | /* In MB. */ | ||
58 | unsigned int priv_mem_size; /* Size of this quad's */ | ||
59 | /* private memory. */ | ||
60 | /* In MB. */ | ||
61 | unsigned int low_shrd_mem_strp_start;/* Starting address of this */ | ||
62 | /* quad's low shared block */ | ||
63 | /* (untranslated). */ | ||
64 | /* In MB. */ | ||
65 | unsigned int low_shrd_mem_start; /* Starting address of this */ | ||
66 | /* quad's low shared memory */ | ||
67 | /* (untranslated). */ | ||
68 | /* In MB. */ | ||
69 | unsigned int low_shrd_mem_size; /* Size of this quad's low */ | ||
70 | /* shared memory. */ | ||
71 | /* In MB. */ | ||
72 | unsigned int lmmio_copb_start; /* Starting address of this */ | ||
73 | /* quad's local memory */ | ||
74 | /* mapped I/O in the */ | ||
75 | /* compatibility OPB. */ | ||
76 | /* In MB. */ | ||
77 | unsigned int lmmio_copb_size; /* Size of this quad's local */ | ||
78 | /* memory mapped I/O in the */ | ||
79 | /* compatibility OPB. */ | ||
80 | /* In MB. */ | ||
81 | unsigned int lmmio_nopb_start; /* Starting address of this */ | ||
82 | /* quad's local memory */ | ||
83 | /* mapped I/O in the */ | ||
84 | /* non-compatibility OPB. */ | ||
85 | /* In MB. */ | ||
86 | unsigned int lmmio_nopb_size; /* Size of this quad's local */ | ||
87 | /* memory mapped I/O in the */ | ||
88 | /* non-compatibility OPB. */ | ||
89 | /* In MB. */ | ||
90 | unsigned int io_apic_0_start; /* Starting address of I/O */ | ||
91 | /* APIC 0. */ | ||
92 | unsigned int io_apic_0_sz; /* Size I/O APIC 0. */ | ||
93 | unsigned int io_apic_1_start; /* Starting address of I/O */ | ||
94 | /* APIC 1. */ | ||
95 | unsigned int io_apic_1_sz; /* Size I/O APIC 1. */ | ||
96 | unsigned int hi_shrd_mem_start; /* Starting address of this */ | ||
97 | /* quad's high shared memory.*/ | ||
98 | /* In MB. */ | ||
99 | unsigned int hi_shrd_mem_size; /* Size of this quad's high */ | ||
100 | /* shared memory. */ | ||
101 | /* In MB. */ | ||
102 | unsigned int mps_table_addr; /* Address of this quad's */ | ||
103 | /* MPS tables from BIOS, */ | ||
104 | /* in system space.*/ | ||
105 | unsigned int lcl_MDC_pio_addr; /* Port-I/O address for */ | ||
106 | /* local access of MDC. */ | ||
107 | unsigned int rmt_MDC_mmpio_addr; /* MM-Port-I/O address for */ | ||
108 | /* remote access of MDC. */ | ||
109 | unsigned int mm_port_io_start; /* Starting address of this */ | ||
110 | /* quad's memory mapped Port */ | ||
111 | /* I/O space. */ | ||
112 | unsigned int mm_port_io_size; /* Size of this quad's memory*/ | ||
113 | /* mapped Port I/O space. */ | ||
114 | unsigned int mm_rmt_io_apic_start; /* Starting address of this */ | ||
115 | /* quad's memory mapped */ | ||
116 | /* remote I/O APIC space. */ | ||
117 | unsigned int mm_rmt_io_apic_size; /* Size of this quad's memory*/ | ||
118 | /* mapped remote I/O APIC */ | ||
119 | /* space. */ | ||
120 | unsigned int mm_isa_start; /* Starting address of this */ | ||
121 | /* quad's memory mapped ISA */ | ||
122 | /* space (contains MDC */ | ||
123 | /* memory space). */ | ||
124 | unsigned int mm_isa_size; /* Size of this quad's memory*/ | ||
125 | /* mapped ISA space (contains*/ | ||
126 | /* MDC memory space). */ | ||
127 | unsigned int rmt_qmi_addr; /* Remote addr to access QMI.*/ | ||
128 | unsigned int lcl_qmi_addr; /* Local addr to access QMI. */ | ||
129 | }; | ||
130 | |||
131 | /* | ||
132 | * Note: This structure must be NOT be changed unless the multiproc and | ||
133 | * OS are changed to reflect the new structure. | ||
134 | */ | ||
135 | struct sys_cfg_data { | ||
136 | unsigned int quad_id; | ||
137 | unsigned int bsp_proc_id; /* Boot Strap Processor in this quad. */ | ||
138 | unsigned int scd_version; /* Version number of this table. */ | ||
139 | unsigned int first_quad_id; | ||
140 | unsigned int quads_present31_0; /* 1 bit for each quad */ | ||
141 | unsigned int quads_present63_32; /* 1 bit for each quad */ | ||
142 | unsigned int config_flags; | ||
143 | unsigned int boot_flags; | ||
144 | unsigned int csr_start_addr; /* Absolute value (not in MB) */ | ||
145 | unsigned int csr_size; /* Absolute value (not in MB) */ | ||
146 | unsigned int lcl_apic_start_addr; /* Absolute value (not in MB) */ | ||
147 | unsigned int lcl_apic_size; /* Absolute value (not in MB) */ | ||
148 | unsigned int low_shrd_mem_base; /* 0 or 512MB or 1GB */ | ||
149 | unsigned int low_shrd_mem_quad_offset; /* 0,128M,256M,512M,1G */ | ||
150 | /* may not be totally populated */ | ||
151 | unsigned int split_mem_enbl; /* 0 for no low shared memory */ | ||
152 | unsigned int mmio_sz; /* Size of total system memory mapped I/O */ | ||
153 | /* (in MB). */ | ||
154 | unsigned int quad_spin_lock; /* Spare location used for quad */ | ||
155 | /* bringup. */ | ||
156 | unsigned int nonzero55; /* For checksumming. */ | ||
157 | unsigned int nonzeroaa; /* For checksumming. */ | ||
158 | unsigned int scd_magic_number; | ||
159 | unsigned int system_type; | ||
160 | unsigned int checksum; | ||
161 | /* | ||
162 | * memory configuration area for each quad | ||
163 | */ | ||
164 | struct eachquadmem eq[MAX_NUMNODES]; /* indexed by quad id */ | ||
165 | }; | ||
166 | |||
167 | void numaq_tsc_disable(void); | ||
168 | |||
169 | #endif /* CONFIG_X86_NUMAQ */ | ||
170 | #endif /* _ASM_X86_NUMAQ_H */ | ||
171 | |||
diff --git a/arch/x86/kernel/apic/Makefile b/arch/x86/kernel/apic/Makefile index 70e141520ad7..dcb5b15401ce 100644 --- a/arch/x86/kernel/apic/Makefile +++ b/arch/x86/kernel/apic/Makefile | |||
@@ -18,7 +18,6 @@ obj-y += apic_flat_64.o | |||
18 | endif | 18 | endif |
19 | 19 | ||
20 | # APIC probe will depend on the listing order here | 20 | # APIC probe will depend on the listing order here |
21 | obj-$(CONFIG_X86_NUMAQ) += numaq_32.o | ||
22 | obj-$(CONFIG_X86_BIGSMP) += bigsmp_32.o | 21 | obj-$(CONFIG_X86_BIGSMP) += bigsmp_32.o |
23 | 22 | ||
24 | # For 32bit, probe_32 need to be listed last | 23 | # For 32bit, probe_32 need to be listed last |
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 | |||
51 | int 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 | */ | ||
58 | struct 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 | |||
68 | static int mpc_record; | ||
69 | |||
70 | static struct mpc_trans *translation_table[MAX_MPC_ENTRY]; | ||
71 | |||
72 | int mp_bus_id_to_node[MAX_MP_BUSSES]; | ||
73 | int mp_bus_id_to_local[MAX_MP_BUSSES]; | ||
74 | int quad_local_to_mp_bus_id[NR_CPUS/4][4]; | ||
75 | |||
76 | |||
77 | static 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 | */ | ||
95 | static 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 | |||
108 | void 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 | |||
119 | static void __init numaq_tsc_init(void) | ||
120 | { | ||
121 | numaq_tsc_disable(); | ||
122 | } | ||
123 | |||
124 | static 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 */ | ||
130 | static 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 */ | ||
145 | static 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 */ | ||
157 | static 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 | */ | ||
170 | static void numaq_mpc_record(unsigned int mode) | ||
171 | { | ||
172 | if (!mode) | ||
173 | mpc_record = 0; | ||
174 | else | ||
175 | mpc_record++; | ||
176 | } | ||
177 | |||
178 | static 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 | |||
194 | static 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 | */ | ||
207 | static 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 | |||
251 | static __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 | |||
271 | int __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 | |||
283 | static inline unsigned int numaq_get_apic_id(unsigned long x) | ||
284 | { | ||
285 | return (x >> 24) & 0x0F; | ||
286 | } | ||
287 | |||
288 | static inline void numaq_send_IPI_mask(const struct cpumask *mask, int vector) | ||
289 | { | ||
290 | default_send_IPI_mask_sequence_logical(mask, vector); | ||
291 | } | ||
292 | |||
293 | static inline void numaq_send_IPI_allbutself(int vector) | ||
294 | { | ||
295 | default_send_IPI_mask_allbutself_logical(cpu_online_mask, vector); | ||
296 | } | ||
297 | |||
298 | static 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 | */ | ||
310 | static inline void numaq_smp_callin_clear_local_apic(void) | ||
311 | { | ||
312 | clear_local_APIC(); | ||
313 | } | ||
314 | |||
315 | static inline const struct cpumask *numaq_target_cpus(void) | ||
316 | { | ||
317 | return cpu_all_mask; | ||
318 | } | ||
319 | |||
320 | static unsigned long numaq_check_apicid_used(physid_mask_t *map, int apicid) | ||
321 | { | ||
322 | return physid_isset(apicid, *map); | ||
323 | } | ||
324 | |||
325 | static inline unsigned long numaq_check_apicid_present(int bit) | ||
326 | { | ||
327 | return physid_isset(bit, phys_cpu_present_map); | ||
328 | } | ||
329 | |||
330 | static inline int numaq_apic_id_registered(void) | ||
331 | { | ||
332 | return 1; | ||
333 | } | ||
334 | |||
335 | static inline void numaq_init_apic_ldr(void) | ||
336 | { | ||
337 | /* Already done in NUMA-Q firmware */ | ||
338 | } | ||
339 | |||
340 | static 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 | */ | ||
351 | static inline int numaq_multi_timer_check(int apic, int irq) | ||
352 | { | ||
353 | return apic != 0 && irq == 0; | ||
354 | } | ||
355 | |||
356 | static 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 | */ | ||
367 | static 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 | |||
375 | static inline int numaq_apicid_to_node(int logical_apicid) | ||
376 | { | ||
377 | return logical_apicid >> 4; | ||
378 | } | ||
379 | |||
380 | static 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 | |||
389 | static 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 */ | ||
398 | void *xquad_portio; | ||
399 | |||
400 | static 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 | */ | ||
409 | static int | ||
410 | numaq_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. */ | ||
419 | static inline int numaq_phys_pkg_id(int cpuid_apic, int index_msb) | ||
420 | { | ||
421 | return cpuid_apic >> index_msb; | ||
422 | } | ||
423 | |||
424 | static int | ||
425 | numaq_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 | |||
435 | static int probe_numaq(void) | ||
436 | { | ||
437 | /* already know from get_memcfg_numaq() */ | ||
438 | return found_numaq; | ||
439 | } | ||
440 | |||
441 | static 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. */ | ||
459 | static 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 | |||
524 | apic_driver(apic_numaq); | ||
diff --git a/arch/x86/kernel/cpu/intel.c b/arch/x86/kernel/cpu/intel.c index 5cd9bfabd645..ea56e7c9abe6 100644 --- a/arch/x86/kernel/cpu/intel.c +++ b/arch/x86/kernel/cpu/intel.c | |||
@@ -267,10 +267,6 @@ static void intel_workarounds(struct cpuinfo_x86 *c) | |||
267 | } | 267 | } |
268 | #endif | 268 | #endif |
269 | 269 | ||
270 | #ifdef CONFIG_X86_NUMAQ | ||
271 | numaq_tsc_disable(); | ||
272 | #endif | ||
273 | |||
274 | intel_smp_check(c); | 270 | intel_smp_check(c); |
275 | } | 271 | } |
276 | #else | 272 | #else |
diff --git a/arch/x86/mm/numa.c b/arch/x86/mm/numa.c index 27aa0455fab3..1d045f9c390f 100644 --- a/arch/x86/mm/numa.c +++ b/arch/x86/mm/numa.c | |||
@@ -687,10 +687,6 @@ static int __init dummy_numa_init(void) | |||
687 | void __init x86_numa_init(void) | 687 | void __init x86_numa_init(void) |
688 | { | 688 | { |
689 | if (!numa_off) { | 689 | if (!numa_off) { |
690 | #ifdef CONFIG_X86_NUMAQ | ||
691 | if (!numa_init(numaq_numa_init)) | ||
692 | return; | ||
693 | #endif | ||
694 | #ifdef CONFIG_ACPI_NUMA | 690 | #ifdef CONFIG_ACPI_NUMA |
695 | if (!numa_init(x86_acpi_numa_init)) | 691 | if (!numa_init(x86_acpi_numa_init)) |
696 | return; | 692 | return; |
diff --git a/arch/x86/pci/Makefile b/arch/x86/pci/Makefile index 758b8272c821..5c6fc3577a49 100644 --- a/arch/x86/pci/Makefile +++ b/arch/x86/pci/Makefile | |||
@@ -13,7 +13,6 @@ obj-y += legacy.o irq.o | |||
13 | 13 | ||
14 | obj-$(CONFIG_STA2X11) += sta2x11-fixup.o | 14 | obj-$(CONFIG_STA2X11) += sta2x11-fixup.o |
15 | 15 | ||
16 | obj-$(CONFIG_X86_NUMAQ) += numaq_32.o | ||
17 | obj-$(CONFIG_X86_NUMACHIP) += numachip.o | 16 | obj-$(CONFIG_X86_NUMACHIP) += numachip.o |
18 | 17 | ||
19 | obj-$(CONFIG_X86_INTEL_MID) += intel_mid_pci.o | 18 | obj-$(CONFIG_X86_INTEL_MID) += intel_mid_pci.o |
diff --git a/arch/x86/pci/numaq_32.c b/arch/x86/pci/numaq_32.c deleted file mode 100644 index 72c229f9ebcf..000000000000 --- a/arch/x86/pci/numaq_32.c +++ /dev/null | |||
@@ -1,165 +0,0 @@ | |||
1 | /* | ||
2 | * numaq_32.c - Low-level PCI access for NUMA-Q machines | ||
3 | */ | ||
4 | |||
5 | #include <linux/pci.h> | ||
6 | #include <linux/init.h> | ||
7 | #include <linux/nodemask.h> | ||
8 | #include <asm/apic.h> | ||
9 | #include <asm/mpspec.h> | ||
10 | #include <asm/pci_x86.h> | ||
11 | #include <asm/numaq.h> | ||
12 | |||
13 | #define BUS2QUAD(global) (mp_bus_id_to_node[global]) | ||
14 | |||
15 | #define BUS2LOCAL(global) (mp_bus_id_to_local[global]) | ||
16 | |||
17 | #define QUADLOCAL2BUS(quad,local) (quad_local_to_mp_bus_id[quad][local]) | ||
18 | |||
19 | #define PCI_CONF1_MQ_ADDRESS(bus, devfn, reg) \ | ||
20 | (0x80000000 | (BUS2LOCAL(bus) << 16) | (devfn << 8) | (reg & ~3)) | ||
21 | |||
22 | static void write_cf8(unsigned bus, unsigned devfn, unsigned reg) | ||
23 | { | ||
24 | unsigned val = PCI_CONF1_MQ_ADDRESS(bus, devfn, reg); | ||
25 | if (xquad_portio) | ||
26 | writel(val, XQUAD_PORT_ADDR(0xcf8, BUS2QUAD(bus))); | ||
27 | else | ||
28 | outl(val, 0xCF8); | ||
29 | } | ||
30 | |||
31 | static int pci_conf1_mq_read(unsigned int seg, unsigned int bus, | ||
32 | unsigned int devfn, int reg, int len, u32 *value) | ||
33 | { | ||
34 | unsigned long flags; | ||
35 | void *adr __iomem = XQUAD_PORT_ADDR(0xcfc, BUS2QUAD(bus)); | ||
36 | |||
37 | WARN_ON(seg); | ||
38 | if (!value || (bus >= MAX_MP_BUSSES) || (devfn > 255) || (reg > 255)) | ||
39 | return -EINVAL; | ||
40 | |||
41 | raw_spin_lock_irqsave(&pci_config_lock, flags); | ||
42 | |||
43 | write_cf8(bus, devfn, reg); | ||
44 | |||
45 | switch (len) { | ||
46 | case 1: | ||
47 | if (xquad_portio) | ||
48 | *value = readb(adr + (reg & 3)); | ||
49 | else | ||
50 | *value = inb(0xCFC + (reg & 3)); | ||
51 | break; | ||
52 | case 2: | ||
53 | if (xquad_portio) | ||
54 | *value = readw(adr + (reg & 2)); | ||
55 | else | ||
56 | *value = inw(0xCFC + (reg & 2)); | ||
57 | break; | ||
58 | case 4: | ||
59 | if (xquad_portio) | ||
60 | *value = readl(adr); | ||
61 | else | ||
62 | *value = inl(0xCFC); | ||
63 | break; | ||
64 | } | ||
65 | |||
66 | raw_spin_unlock_irqrestore(&pci_config_lock, flags); | ||
67 | |||
68 | return 0; | ||
69 | } | ||
70 | |||
71 | static int pci_conf1_mq_write(unsigned int seg, unsigned int bus, | ||
72 | unsigned int devfn, int reg, int len, u32 value) | ||
73 | { | ||
74 | unsigned long flags; | ||
75 | void *adr __iomem = XQUAD_PORT_ADDR(0xcfc, BUS2QUAD(bus)); | ||
76 | |||
77 | WARN_ON(seg); | ||
78 | if ((bus >= MAX_MP_BUSSES) || (devfn > 255) || (reg > 255)) | ||
79 | return -EINVAL; | ||
80 | |||
81 | raw_spin_lock_irqsave(&pci_config_lock, flags); | ||
82 | |||
83 | write_cf8(bus, devfn, reg); | ||
84 | |||
85 | switch (len) { | ||
86 | case 1: | ||
87 | if (xquad_portio) | ||
88 | writeb(value, adr + (reg & 3)); | ||
89 | else | ||
90 | outb((u8)value, 0xCFC + (reg & 3)); | ||
91 | break; | ||
92 | case 2: | ||
93 | if (xquad_portio) | ||
94 | writew(value, adr + (reg & 2)); | ||
95 | else | ||
96 | outw((u16)value, 0xCFC + (reg & 2)); | ||
97 | break; | ||
98 | case 4: | ||
99 | if (xquad_portio) | ||
100 | writel(value, adr + reg); | ||
101 | else | ||
102 | outl((u32)value, 0xCFC); | ||
103 | break; | ||
104 | } | ||
105 | |||
106 | raw_spin_unlock_irqrestore(&pci_config_lock, flags); | ||
107 | |||
108 | return 0; | ||
109 | } | ||
110 | |||
111 | #undef PCI_CONF1_MQ_ADDRESS | ||
112 | |||
113 | static const struct pci_raw_ops pci_direct_conf1_mq = { | ||
114 | .read = pci_conf1_mq_read, | ||
115 | .write = pci_conf1_mq_write | ||
116 | }; | ||
117 | |||
118 | |||
119 | static void pci_fixup_i450nx(struct pci_dev *d) | ||
120 | { | ||
121 | /* | ||
122 | * i450NX -- Find and scan all secondary buses on all PXB's. | ||
123 | */ | ||
124 | int pxb, reg; | ||
125 | u8 busno, suba, subb; | ||
126 | int quad = BUS2QUAD(d->bus->number); | ||
127 | |||
128 | dev_info(&d->dev, "searching for i450NX host bridges\n"); | ||
129 | reg = 0xd0; | ||
130 | for(pxb=0; pxb<2; pxb++) { | ||
131 | pci_read_config_byte(d, reg++, &busno); | ||
132 | pci_read_config_byte(d, reg++, &suba); | ||
133 | pci_read_config_byte(d, reg++, &subb); | ||
134 | dev_dbg(&d->dev, "i450NX PXB %d: %02x/%02x/%02x\n", | ||
135 | pxb, busno, suba, subb); | ||
136 | if (busno) { | ||
137 | /* Bus A */ | ||
138 | pci_scan_bus_with_sysdata(QUADLOCAL2BUS(quad, busno)); | ||
139 | } | ||
140 | if (suba < subb) { | ||
141 | /* Bus B */ | ||
142 | pci_scan_bus_with_sysdata(QUADLOCAL2BUS(quad, suba+1)); | ||
143 | } | ||
144 | } | ||
145 | pcibios_last_bus = -1; | ||
146 | } | ||
147 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82451NX, pci_fixup_i450nx); | ||
148 | |||
149 | int __init pci_numaq_init(void) | ||
150 | { | ||
151 | int quad; | ||
152 | |||
153 | raw_pci_ops = &pci_direct_conf1_mq; | ||
154 | |||
155 | pcibios_scan_root(0); | ||
156 | if (num_online_nodes() > 1) | ||
157 | for_each_online_node(quad) { | ||
158 | if (quad == 0) | ||
159 | continue; | ||
160 | printk("Scanning PCI bus %d for quad %d\n", | ||
161 | QUADLOCAL2BUS(quad,0), quad); | ||
162 | pci_scan_bus_with_sysdata(QUADLOCAL2BUS(quad, 0)); | ||
163 | } | ||
164 | return 0; | ||
165 | } | ||