diff options
author | Ingo Molnar <mingo@elte.hu> | 2009-01-28 11:09:58 -0500 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2009-01-28 17:20:34 -0500 |
commit | 018e047f3a98bd8d9e9d78b19bc38415f0c34dd7 (patch) | |
tree | 4e3b47a6e5b3e5e50ecdc668b7261399ce3457c0 /arch | |
parent | 25dc004903a38f0b6f6626dbbab058c8709c5398 (diff) |
x86, ES7000: consolidate the APIC code
Consolidate all the ES7000 APIC code into arch/x86/mach-generic/es7000.c.
With this ES7000 ceases to rely on any subarchitecture include files.
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/x86/include/asm/es7000/apic.h | 236 | ||||
-rw-r--r-- | arch/x86/include/asm/es7000/apicdef.h | 9 | ||||
-rw-r--r-- | arch/x86/include/asm/es7000/ipi.h | 22 | ||||
-rw-r--r-- | arch/x86/include/asm/es7000/mpparse.h | 23 | ||||
-rw-r--r-- | arch/x86/include/asm/es7000/wakecpu.h | 16 | ||||
-rw-r--r-- | arch/x86/mach-generic/es7000.c | 314 |
6 files changed, 295 insertions, 325 deletions
diff --git a/arch/x86/include/asm/es7000/apic.h b/arch/x86/include/asm/es7000/apic.h deleted file mode 100644 index b89b45db735d..000000000000 --- a/arch/x86/include/asm/es7000/apic.h +++ /dev/null | |||
@@ -1,236 +0,0 @@ | |||
1 | #ifndef __ASM_ES7000_APIC_H | ||
2 | #define __ASM_ES7000_APIC_H | ||
3 | |||
4 | #include <linux/gfp.h> | ||
5 | |||
6 | #define xapic_phys_to_log_apicid(cpu) per_cpu(x86_bios_cpu_apicid, cpu) | ||
7 | |||
8 | static inline int es7000_apic_id_registered(void) | ||
9 | { | ||
10 | return 1; | ||
11 | } | ||
12 | |||
13 | static inline const cpumask_t *target_cpus_cluster(void) | ||
14 | { | ||
15 | return &CPU_MASK_ALL; | ||
16 | } | ||
17 | |||
18 | static inline const cpumask_t *es7000_target_cpus(void) | ||
19 | { | ||
20 | return &cpumask_of_cpu(smp_processor_id()); | ||
21 | } | ||
22 | |||
23 | #define APIC_DFR_VALUE_CLUSTER (APIC_DFR_CLUSTER) | ||
24 | #define INT_DELIVERY_MODE_CLUSTER (dest_LowestPrio) | ||
25 | #define INT_DEST_MODE_CLUSTER (1) /* logical delivery broadcast to all procs */ | ||
26 | |||
27 | #define APIC_DFR_VALUE (APIC_DFR_FLAT) | ||
28 | |||
29 | static inline unsigned long | ||
30 | es7000_check_apicid_used(physid_mask_t bitmap, int apicid) | ||
31 | { | ||
32 | return 0; | ||
33 | } | ||
34 | static inline unsigned long es7000_check_apicid_present(int bit) | ||
35 | { | ||
36 | return physid_isset(bit, phys_cpu_present_map); | ||
37 | } | ||
38 | |||
39 | extern void es7000_enable_apic_mode(void); | ||
40 | |||
41 | #define apicid_cluster(apicid) (apicid & 0xF0) | ||
42 | |||
43 | static inline unsigned long calculate_ldr(int cpu) | ||
44 | { | ||
45 | unsigned long id; | ||
46 | id = xapic_phys_to_log_apicid(cpu); | ||
47 | return (SET_APIC_LOGICAL_ID(id)); | ||
48 | } | ||
49 | |||
50 | /* | ||
51 | * Set up the logical destination ID. | ||
52 | * | ||
53 | * Intel recommends to set DFR, LdR and TPR before enabling | ||
54 | * an APIC. See e.g. "AP-388 82489DX User's Manual" (Intel | ||
55 | * document number 292116). So here it goes... | ||
56 | */ | ||
57 | static inline void es7000_init_apic_ldr_cluster(void) | ||
58 | { | ||
59 | unsigned long val; | ||
60 | int cpu = smp_processor_id(); | ||
61 | |||
62 | apic_write(APIC_DFR, APIC_DFR_VALUE_CLUSTER); | ||
63 | val = calculate_ldr(cpu); | ||
64 | apic_write(APIC_LDR, val); | ||
65 | } | ||
66 | |||
67 | static inline void es7000_init_apic_ldr(void) | ||
68 | { | ||
69 | unsigned long val; | ||
70 | int cpu = smp_processor_id(); | ||
71 | |||
72 | apic_write(APIC_DFR, APIC_DFR_VALUE); | ||
73 | val = calculate_ldr(cpu); | ||
74 | apic_write(APIC_LDR, val); | ||
75 | } | ||
76 | |||
77 | extern int apic_version [MAX_APICS]; | ||
78 | static inline void es7000_setup_apic_routing(void) | ||
79 | { | ||
80 | int apic = per_cpu(x86_bios_cpu_apicid, smp_processor_id()); | ||
81 | printk("Enabling APIC mode: %s. Using %d I/O APICs, target cpus %lx\n", | ||
82 | (apic_version[apic] == 0x14) ? | ||
83 | "Physical Cluster" : "Logical Cluster", | ||
84 | nr_ioapics, cpus_addr(*es7000_target_cpus())[0]); | ||
85 | } | ||
86 | |||
87 | static inline int es7000_apicid_to_node(int logical_apicid) | ||
88 | { | ||
89 | return 0; | ||
90 | } | ||
91 | |||
92 | |||
93 | static inline int es7000_cpu_present_to_apicid(int mps_cpu) | ||
94 | { | ||
95 | if (!mps_cpu) | ||
96 | return boot_cpu_physical_apicid; | ||
97 | else if (mps_cpu < nr_cpu_ids) | ||
98 | return (int) per_cpu(x86_bios_cpu_apicid, mps_cpu); | ||
99 | else | ||
100 | return BAD_APICID; | ||
101 | } | ||
102 | |||
103 | static inline physid_mask_t es7000_apicid_to_cpu_present(int phys_apicid) | ||
104 | { | ||
105 | static int id = 0; | ||
106 | physid_mask_t mask; | ||
107 | mask = physid_mask_of_physid(id); | ||
108 | ++id; | ||
109 | return mask; | ||
110 | } | ||
111 | |||
112 | extern u8 cpu_2_logical_apicid[]; | ||
113 | /* Mapping from cpu number to logical apicid */ | ||
114 | static inline int es7000_cpu_to_logical_apicid(int cpu) | ||
115 | { | ||
116 | #ifdef CONFIG_SMP | ||
117 | if (cpu >= nr_cpu_ids) | ||
118 | return BAD_APICID; | ||
119 | return (int)cpu_2_logical_apicid[cpu]; | ||
120 | #else | ||
121 | return logical_smp_processor_id(); | ||
122 | #endif | ||
123 | } | ||
124 | |||
125 | static inline physid_mask_t es7000_ioapic_phys_id_map(physid_mask_t phys_map) | ||
126 | { | ||
127 | /* For clustered we don't have a good way to do this yet - hack */ | ||
128 | return physids_promote(0xff); | ||
129 | } | ||
130 | |||
131 | extern unsigned int boot_cpu_physical_apicid; | ||
132 | |||
133 | static inline int es7000_check_phys_apicid_present(int cpu_physical_apicid) | ||
134 | { | ||
135 | boot_cpu_physical_apicid = read_apic_id(); | ||
136 | return (1); | ||
137 | } | ||
138 | |||
139 | static inline unsigned int | ||
140 | es7000_cpu_mask_to_apicid_cluster(const struct cpumask *cpumask) | ||
141 | { | ||
142 | int cpus_found = 0; | ||
143 | int num_bits_set; | ||
144 | int apicid; | ||
145 | int cpu; | ||
146 | |||
147 | num_bits_set = cpumask_weight(cpumask); | ||
148 | /* Return id to all */ | ||
149 | if (num_bits_set == nr_cpu_ids) | ||
150 | return 0xFF; | ||
151 | /* | ||
152 | * The cpus in the mask must all be on the apic cluster. If are not | ||
153 | * on the same apicid cluster return default value of target_cpus(): | ||
154 | */ | ||
155 | cpu = cpumask_first(cpumask); | ||
156 | apicid = es7000_cpu_to_logical_apicid(cpu); | ||
157 | |||
158 | while (cpus_found < num_bits_set) { | ||
159 | if (cpumask_test_cpu(cpu, cpumask)) { | ||
160 | int new_apicid = es7000_cpu_to_logical_apicid(cpu); | ||
161 | |||
162 | if (apicid_cluster(apicid) != | ||
163 | apicid_cluster(new_apicid)) { | ||
164 | printk ("%s: Not a valid mask!\n", __func__); | ||
165 | |||
166 | return 0xFF; | ||
167 | } | ||
168 | apicid = new_apicid; | ||
169 | cpus_found++; | ||
170 | } | ||
171 | cpu++; | ||
172 | } | ||
173 | return apicid; | ||
174 | } | ||
175 | |||
176 | static inline unsigned int es7000_cpu_mask_to_apicid(const cpumask_t *cpumask) | ||
177 | { | ||
178 | int cpus_found = 0; | ||
179 | int num_bits_set; | ||
180 | int apicid; | ||
181 | int cpu; | ||
182 | |||
183 | num_bits_set = cpus_weight(*cpumask); | ||
184 | /* Return id to all */ | ||
185 | if (num_bits_set == nr_cpu_ids) | ||
186 | return es7000_cpu_to_logical_apicid(0); | ||
187 | /* | ||
188 | * The cpus in the mask must all be on the apic cluster. If are not | ||
189 | * on the same apicid cluster return default value of target_cpus(): | ||
190 | */ | ||
191 | cpu = first_cpu(*cpumask); | ||
192 | apicid = es7000_cpu_to_logical_apicid(cpu); | ||
193 | while (cpus_found < num_bits_set) { | ||
194 | if (cpu_isset(cpu, *cpumask)) { | ||
195 | int new_apicid = es7000_cpu_to_logical_apicid(cpu); | ||
196 | |||
197 | if (apicid_cluster(apicid) != | ||
198 | apicid_cluster(new_apicid)) { | ||
199 | printk ("%s: Not a valid mask!\n", __func__); | ||
200 | |||
201 | return es7000_cpu_to_logical_apicid(0); | ||
202 | } | ||
203 | apicid = new_apicid; | ||
204 | cpus_found++; | ||
205 | } | ||
206 | cpu++; | ||
207 | } | ||
208 | return apicid; | ||
209 | } | ||
210 | |||
211 | |||
212 | static inline unsigned int | ||
213 | es7000_cpu_mask_to_apicid_and(const struct cpumask *inmask, | ||
214 | const struct cpumask *andmask) | ||
215 | { | ||
216 | int apicid = es7000_cpu_to_logical_apicid(0); | ||
217 | cpumask_var_t cpumask; | ||
218 | |||
219 | if (!alloc_cpumask_var(&cpumask, GFP_ATOMIC)) | ||
220 | return apicid; | ||
221 | |||
222 | cpumask_and(cpumask, inmask, andmask); | ||
223 | cpumask_and(cpumask, cpumask, cpu_online_mask); | ||
224 | apicid = es7000_cpu_mask_to_apicid(cpumask); | ||
225 | |||
226 | free_cpumask_var(cpumask); | ||
227 | |||
228 | return apicid; | ||
229 | } | ||
230 | |||
231 | static inline int es7000_phys_pkg_id(int cpuid_apic, int index_msb) | ||
232 | { | ||
233 | return cpuid_apic >> index_msb; | ||
234 | } | ||
235 | |||
236 | #endif /* __ASM_ES7000_APIC_H */ | ||
diff --git a/arch/x86/include/asm/es7000/apicdef.h b/arch/x86/include/asm/es7000/apicdef.h deleted file mode 100644 index c74881a7b3d8..000000000000 --- a/arch/x86/include/asm/es7000/apicdef.h +++ /dev/null | |||
@@ -1,9 +0,0 @@ | |||
1 | #ifndef __ASM_ES7000_APICDEF_H | ||
2 | #define __ASM_ES7000_APICDEF_H | ||
3 | |||
4 | static inline unsigned int es7000_get_apic_id(unsigned long x) | ||
5 | { | ||
6 | return (x >> 24) & 0xFF; | ||
7 | } | ||
8 | |||
9 | #endif | ||
diff --git a/arch/x86/include/asm/es7000/ipi.h b/arch/x86/include/asm/es7000/ipi.h deleted file mode 100644 index 81e77c812baa..000000000000 --- a/arch/x86/include/asm/es7000/ipi.h +++ /dev/null | |||
@@ -1,22 +0,0 @@ | |||
1 | #ifndef __ASM_ES7000_IPI_H | ||
2 | #define __ASM_ES7000_IPI_H | ||
3 | |||
4 | void default_send_IPI_mask_sequence(const struct cpumask *mask, int vector); | ||
5 | void default_send_IPI_mask_allbutself(const struct cpumask *mask, int vector); | ||
6 | |||
7 | static inline void es7000_send_IPI_mask(const struct cpumask *mask, int vector) | ||
8 | { | ||
9 | default_send_IPI_mask_sequence(mask, vector); | ||
10 | } | ||
11 | |||
12 | static inline void es7000_send_IPI_allbutself(int vector) | ||
13 | { | ||
14 | default_send_IPI_mask_allbutself(cpu_online_mask, vector); | ||
15 | } | ||
16 | |||
17 | static inline void es7000_send_IPI_all(int vector) | ||
18 | { | ||
19 | es7000_send_IPI_mask(cpu_online_mask, vector); | ||
20 | } | ||
21 | |||
22 | #endif /* __ASM_ES7000_IPI_H */ | ||
diff --git a/arch/x86/include/asm/es7000/mpparse.h b/arch/x86/include/asm/es7000/mpparse.h deleted file mode 100644 index 662eb1e574de..000000000000 --- a/arch/x86/include/asm/es7000/mpparse.h +++ /dev/null | |||
@@ -1,23 +0,0 @@ | |||
1 | #ifndef __ASM_ES7000_MPPARSE_H | ||
2 | #define __ASM_ES7000_MPPARSE_H | ||
3 | |||
4 | #include <linux/acpi.h> | ||
5 | |||
6 | extern int parse_unisys_oem (char *oemptr); | ||
7 | extern int find_unisys_acpi_oem_table(unsigned long *oem_addr); | ||
8 | extern void unmap_unisys_acpi_oem_table(unsigned long oem_addr); | ||
9 | extern void setup_unisys(void); | ||
10 | |||
11 | #ifdef CONFIG_ACPI | ||
12 | static inline int es7000_check_dsdt(void) | ||
13 | { | ||
14 | struct acpi_table_header header; | ||
15 | |||
16 | if (ACPI_SUCCESS(acpi_get_table_header(ACPI_SIG_DSDT, 0, &header)) && | ||
17 | !strncmp(header.oem_id, "UNISYS", 6)) | ||
18 | return 1; | ||
19 | return 0; | ||
20 | } | ||
21 | #endif | ||
22 | |||
23 | #endif /* __ASM_MACH_MPPARSE_H */ | ||
diff --git a/arch/x86/include/asm/es7000/wakecpu.h b/arch/x86/include/asm/es7000/wakecpu.h deleted file mode 100644 index 99c72be1840e..000000000000 --- a/arch/x86/include/asm/es7000/wakecpu.h +++ /dev/null | |||
@@ -1,16 +0,0 @@ | |||
1 | #ifndef __ASM_ES7000_WAKECPU_H | ||
2 | #define __ASM_ES7000_WAKECPU_H | ||
3 | |||
4 | #define ES7000_TRAMPOLINE_PHYS_LOW 0x467 | ||
5 | #define ES7000_TRAMPOLINE_PHYS_HIGH 0x469 | ||
6 | |||
7 | static inline void es7000_wait_for_init_deassert(atomic_t *deassert) | ||
8 | { | ||
9 | #ifndef CONFIG_ES7000_CLUSTERED_APIC | ||
10 | while (!atomic_read(deassert)) | ||
11 | cpu_relax(); | ||
12 | #endif | ||
13 | return; | ||
14 | } | ||
15 | |||
16 | #endif /* __ASM_MACH_WAKECPU_H */ | ||
diff --git a/arch/x86/mach-generic/es7000.c b/arch/x86/mach-generic/es7000.c index be090b2037ca..8b6113ec380c 100644 --- a/arch/x86/mach-generic/es7000.c +++ b/arch/x86/mach-generic/es7000.c | |||
@@ -11,13 +11,300 @@ | |||
11 | #include <linux/kernel.h> | 11 | #include <linux/kernel.h> |
12 | #include <linux/string.h> | 12 | #include <linux/string.h> |
13 | #include <linux/init.h> | 13 | #include <linux/init.h> |
14 | #include <asm/es7000/apicdef.h> | 14 | #include <linux/acpi.h> |
15 | #include <linux/smp.h> | 15 | #include <linux/smp.h> |
16 | #include <asm/es7000/apic.h> | 16 | #include <asm/ipi.h> |
17 | #include <asm/es7000/ipi.h> | ||
18 | #include <asm/es7000/mpparse.h> | ||
19 | #include <asm/mach-default/mach_wakecpu.h> | 17 | #include <asm/mach-default/mach_wakecpu.h> |
20 | 18 | ||
19 | #define APIC_DFR_VALUE_CLUSTER (APIC_DFR_CLUSTER) | ||
20 | #define INT_DELIVERY_MODE_CLUSTER (dest_LowestPrio) | ||
21 | #define INT_DEST_MODE_CLUSTER (1) /* logical delivery broadcast to all procs */ | ||
22 | |||
23 | #define APIC_DFR_VALUE (APIC_DFR_FLAT) | ||
24 | |||
25 | extern void es7000_enable_apic_mode(void); | ||
26 | extern int apic_version [MAX_APICS]; | ||
27 | extern u8 cpu_2_logical_apicid[]; | ||
28 | extern unsigned int boot_cpu_physical_apicid; | ||
29 | |||
30 | extern int parse_unisys_oem (char *oemptr); | ||
31 | extern int find_unisys_acpi_oem_table(unsigned long *oem_addr); | ||
32 | extern void unmap_unisys_acpi_oem_table(unsigned long oem_addr); | ||
33 | extern void setup_unisys(void); | ||
34 | |||
35 | #define apicid_cluster(apicid) (apicid & 0xF0) | ||
36 | #define xapic_phys_to_log_apicid(cpu) per_cpu(x86_bios_cpu_apicid, cpu) | ||
37 | |||
38 | static void es7000_vector_allocation_domain(int cpu, cpumask_t *retmask) | ||
39 | { | ||
40 | /* Careful. Some cpus do not strictly honor the set of cpus | ||
41 | * specified in the interrupt destination when using lowest | ||
42 | * priority interrupt delivery mode. | ||
43 | * | ||
44 | * In particular there was a hyperthreading cpu observed to | ||
45 | * deliver interrupts to the wrong hyperthread when only one | ||
46 | * hyperthread was specified in the interrupt desitination. | ||
47 | */ | ||
48 | *retmask = (cpumask_t){ { [0] = APIC_ALL_CPUS, } }; | ||
49 | } | ||
50 | |||
51 | |||
52 | static void es7000_wait_for_init_deassert(atomic_t *deassert) | ||
53 | { | ||
54 | #ifndef CONFIG_ES7000_CLUSTERED_APIC | ||
55 | while (!atomic_read(deassert)) | ||
56 | cpu_relax(); | ||
57 | #endif | ||
58 | return; | ||
59 | } | ||
60 | |||
61 | static unsigned int es7000_get_apic_id(unsigned long x) | ||
62 | { | ||
63 | return (x >> 24) & 0xFF; | ||
64 | } | ||
65 | |||
66 | #ifdef CONFIG_ACPI | ||
67 | static int es7000_check_dsdt(void) | ||
68 | { | ||
69 | struct acpi_table_header header; | ||
70 | |||
71 | if (ACPI_SUCCESS(acpi_get_table_header(ACPI_SIG_DSDT, 0, &header)) && | ||
72 | !strncmp(header.oem_id, "UNISYS", 6)) | ||
73 | return 1; | ||
74 | return 0; | ||
75 | } | ||
76 | #endif | ||
77 | |||
78 | static void es7000_send_IPI_mask(const struct cpumask *mask, int vector) | ||
79 | { | ||
80 | default_send_IPI_mask_sequence(mask, vector); | ||
81 | } | ||
82 | |||
83 | static void es7000_send_IPI_allbutself(int vector) | ||
84 | { | ||
85 | default_send_IPI_mask_allbutself(cpu_online_mask, vector); | ||
86 | } | ||
87 | |||
88 | static void es7000_send_IPI_all(int vector) | ||
89 | { | ||
90 | es7000_send_IPI_mask(cpu_online_mask, vector); | ||
91 | } | ||
92 | |||
93 | static int es7000_apic_id_registered(void) | ||
94 | { | ||
95 | return 1; | ||
96 | } | ||
97 | |||
98 | static const cpumask_t *target_cpus_cluster(void) | ||
99 | { | ||
100 | return &CPU_MASK_ALL; | ||
101 | } | ||
102 | |||
103 | static const cpumask_t *es7000_target_cpus(void) | ||
104 | { | ||
105 | return &cpumask_of_cpu(smp_processor_id()); | ||
106 | } | ||
107 | |||
108 | static unsigned long | ||
109 | es7000_check_apicid_used(physid_mask_t bitmap, int apicid) | ||
110 | { | ||
111 | return 0; | ||
112 | } | ||
113 | static unsigned long es7000_check_apicid_present(int bit) | ||
114 | { | ||
115 | return physid_isset(bit, phys_cpu_present_map); | ||
116 | } | ||
117 | |||
118 | static unsigned long calculate_ldr(int cpu) | ||
119 | { | ||
120 | unsigned long id = xapic_phys_to_log_apicid(cpu); | ||
121 | |||
122 | return (SET_APIC_LOGICAL_ID(id)); | ||
123 | } | ||
124 | |||
125 | /* | ||
126 | * Set up the logical destination ID. | ||
127 | * | ||
128 | * Intel recommends to set DFR, LdR and TPR before enabling | ||
129 | * an APIC. See e.g. "AP-388 82489DX User's Manual" (Intel | ||
130 | * document number 292116). So here it goes... | ||
131 | */ | ||
132 | static void es7000_init_apic_ldr_cluster(void) | ||
133 | { | ||
134 | unsigned long val; | ||
135 | int cpu = smp_processor_id(); | ||
136 | |||
137 | apic_write(APIC_DFR, APIC_DFR_VALUE_CLUSTER); | ||
138 | val = calculate_ldr(cpu); | ||
139 | apic_write(APIC_LDR, val); | ||
140 | } | ||
141 | |||
142 | static void es7000_init_apic_ldr(void) | ||
143 | { | ||
144 | unsigned long val; | ||
145 | int cpu = smp_processor_id(); | ||
146 | |||
147 | apic_write(APIC_DFR, APIC_DFR_VALUE); | ||
148 | val = calculate_ldr(cpu); | ||
149 | apic_write(APIC_LDR, val); | ||
150 | } | ||
151 | |||
152 | static void es7000_setup_apic_routing(void) | ||
153 | { | ||
154 | int apic = per_cpu(x86_bios_cpu_apicid, smp_processor_id()); | ||
155 | printk("Enabling APIC mode: %s. Using %d I/O APICs, target cpus %lx\n", | ||
156 | (apic_version[apic] == 0x14) ? | ||
157 | "Physical Cluster" : "Logical Cluster", | ||
158 | nr_ioapics, cpus_addr(*es7000_target_cpus())[0]); | ||
159 | } | ||
160 | |||
161 | static int es7000_apicid_to_node(int logical_apicid) | ||
162 | { | ||
163 | return 0; | ||
164 | } | ||
165 | |||
166 | |||
167 | static int es7000_cpu_present_to_apicid(int mps_cpu) | ||
168 | { | ||
169 | if (!mps_cpu) | ||
170 | return boot_cpu_physical_apicid; | ||
171 | else if (mps_cpu < nr_cpu_ids) | ||
172 | return (int) per_cpu(x86_bios_cpu_apicid, mps_cpu); | ||
173 | else | ||
174 | return BAD_APICID; | ||
175 | } | ||
176 | |||
177 | static physid_mask_t es7000_apicid_to_cpu_present(int phys_apicid) | ||
178 | { | ||
179 | static int id = 0; | ||
180 | physid_mask_t mask; | ||
181 | |||
182 | mask = physid_mask_of_physid(id); | ||
183 | ++id; | ||
184 | |||
185 | return mask; | ||
186 | } | ||
187 | |||
188 | /* Mapping from cpu number to logical apicid */ | ||
189 | static int es7000_cpu_to_logical_apicid(int cpu) | ||
190 | { | ||
191 | #ifdef CONFIG_SMP | ||
192 | if (cpu >= nr_cpu_ids) | ||
193 | return BAD_APICID; | ||
194 | return (int)cpu_2_logical_apicid[cpu]; | ||
195 | #else | ||
196 | return logical_smp_processor_id(); | ||
197 | #endif | ||
198 | } | ||
199 | |||
200 | static physid_mask_t es7000_ioapic_phys_id_map(physid_mask_t phys_map) | ||
201 | { | ||
202 | /* For clustered we don't have a good way to do this yet - hack */ | ||
203 | return physids_promote(0xff); | ||
204 | } | ||
205 | |||
206 | static int es7000_check_phys_apicid_present(int cpu_physical_apicid) | ||
207 | { | ||
208 | boot_cpu_physical_apicid = read_apic_id(); | ||
209 | return (1); | ||
210 | } | ||
211 | |||
212 | static unsigned int | ||
213 | es7000_cpu_mask_to_apicid_cluster(const struct cpumask *cpumask) | ||
214 | { | ||
215 | int cpus_found = 0; | ||
216 | int num_bits_set; | ||
217 | int apicid; | ||
218 | int cpu; | ||
219 | |||
220 | num_bits_set = cpumask_weight(cpumask); | ||
221 | /* Return id to all */ | ||
222 | if (num_bits_set == nr_cpu_ids) | ||
223 | return 0xFF; | ||
224 | /* | ||
225 | * The cpus in the mask must all be on the apic cluster. If are not | ||
226 | * on the same apicid cluster return default value of target_cpus(): | ||
227 | */ | ||
228 | cpu = cpumask_first(cpumask); | ||
229 | apicid = es7000_cpu_to_logical_apicid(cpu); | ||
230 | |||
231 | while (cpus_found < num_bits_set) { | ||
232 | if (cpumask_test_cpu(cpu, cpumask)) { | ||
233 | int new_apicid = es7000_cpu_to_logical_apicid(cpu); | ||
234 | |||
235 | if (apicid_cluster(apicid) != | ||
236 | apicid_cluster(new_apicid)) { | ||
237 | printk ("%s: Not a valid mask!\n", __func__); | ||
238 | |||
239 | return 0xFF; | ||
240 | } | ||
241 | apicid = new_apicid; | ||
242 | cpus_found++; | ||
243 | } | ||
244 | cpu++; | ||
245 | } | ||
246 | return apicid; | ||
247 | } | ||
248 | |||
249 | static unsigned int es7000_cpu_mask_to_apicid(const cpumask_t *cpumask) | ||
250 | { | ||
251 | int cpus_found = 0; | ||
252 | int num_bits_set; | ||
253 | int apicid; | ||
254 | int cpu; | ||
255 | |||
256 | num_bits_set = cpus_weight(*cpumask); | ||
257 | /* Return id to all */ | ||
258 | if (num_bits_set == nr_cpu_ids) | ||
259 | return es7000_cpu_to_logical_apicid(0); | ||
260 | /* | ||
261 | * The cpus in the mask must all be on the apic cluster. If are not | ||
262 | * on the same apicid cluster return default value of target_cpus(): | ||
263 | */ | ||
264 | cpu = first_cpu(*cpumask); | ||
265 | apicid = es7000_cpu_to_logical_apicid(cpu); | ||
266 | while (cpus_found < num_bits_set) { | ||
267 | if (cpu_isset(cpu, *cpumask)) { | ||
268 | int new_apicid = es7000_cpu_to_logical_apicid(cpu); | ||
269 | |||
270 | if (apicid_cluster(apicid) != | ||
271 | apicid_cluster(new_apicid)) { | ||
272 | printk ("%s: Not a valid mask!\n", __func__); | ||
273 | |||
274 | return es7000_cpu_to_logical_apicid(0); | ||
275 | } | ||
276 | apicid = new_apicid; | ||
277 | cpus_found++; | ||
278 | } | ||
279 | cpu++; | ||
280 | } | ||
281 | return apicid; | ||
282 | } | ||
283 | |||
284 | static unsigned int | ||
285 | es7000_cpu_mask_to_apicid_and(const struct cpumask *inmask, | ||
286 | const struct cpumask *andmask) | ||
287 | { | ||
288 | int apicid = es7000_cpu_to_logical_apicid(0); | ||
289 | cpumask_var_t cpumask; | ||
290 | |||
291 | if (!alloc_cpumask_var(&cpumask, GFP_ATOMIC)) | ||
292 | return apicid; | ||
293 | |||
294 | cpumask_and(cpumask, inmask, andmask); | ||
295 | cpumask_and(cpumask, cpumask, cpu_online_mask); | ||
296 | apicid = es7000_cpu_mask_to_apicid(cpumask); | ||
297 | |||
298 | free_cpumask_var(cpumask); | ||
299 | |||
300 | return apicid; | ||
301 | } | ||
302 | |||
303 | static int es7000_phys_pkg_id(int cpuid_apic, int index_msb) | ||
304 | { | ||
305 | return cpuid_apic >> index_msb; | ||
306 | } | ||
307 | |||
21 | void __init es7000_update_genapic_to_cluster(void) | 308 | void __init es7000_update_genapic_to_cluster(void) |
22 | { | 309 | { |
23 | apic->target_cpus = target_cpus_cluster; | 310 | apic->target_cpus = target_cpus_cluster; |
@@ -80,18 +367,6 @@ static int __init es7000_acpi_madt_oem_check(char *oem_id, char *oem_table_id) | |||
80 | } | 367 | } |
81 | #endif | 368 | #endif |
82 | 369 | ||
83 | static void es7000_vector_allocation_domain(int cpu, cpumask_t *retmask) | ||
84 | { | ||
85 | /* Careful. Some cpus do not strictly honor the set of cpus | ||
86 | * specified in the interrupt destination when using lowest | ||
87 | * priority interrupt delivery mode. | ||
88 | * | ||
89 | * In particular there was a hyperthreading cpu observed to | ||
90 | * deliver interrupts to the wrong hyperthread when only one | ||
91 | * hyperthread was specified in the interrupt desitination. | ||
92 | */ | ||
93 | *retmask = (cpumask_t){ { [0] = APIC_ALL_CPUS, } }; | ||
94 | } | ||
95 | 370 | ||
96 | struct genapic apic_es7000 = { | 371 | struct genapic apic_es7000 = { |
97 | 372 | ||
@@ -140,10 +415,11 @@ struct genapic apic_es7000 = { | |||
140 | .send_IPI_self = NULL, | 415 | .send_IPI_self = NULL, |
141 | 416 | ||
142 | .wakeup_cpu = NULL, | 417 | .wakeup_cpu = NULL, |
143 | .trampoline_phys_low = DEFAULT_TRAMPOLINE_PHYS_LOW, | ||
144 | .trampoline_phys_high = DEFAULT_TRAMPOLINE_PHYS_HIGH, | ||
145 | 418 | ||
146 | .wait_for_init_deassert = default_wait_for_init_deassert, | 419 | .trampoline_phys_low = 0x467, |
420 | .trampoline_phys_high = 0x469, | ||
421 | |||
422 | .wait_for_init_deassert = es7000_wait_for_init_deassert, | ||
147 | 423 | ||
148 | /* Nothing to do for most platforms, since cleared by the INIT cycle: */ | 424 | /* Nothing to do for most platforms, since cleared by the INIT cycle: */ |
149 | .smp_callin_clear_local_apic = NULL, | 425 | .smp_callin_clear_local_apic = NULL, |