xref: /linux/arch/x86/kernel/apic/apic_numachip.c (revision d9d4dee6cedfa17e5eedcba242dca3091bf73bc3)
1 /*
2  * This file is subject to the terms and conditions of the GNU General Public
3  * License.  See the file "COPYING" in the main directory of this archive
4  * for more details.
5  *
6  * Numascale NumaConnect-Specific APIC Code
7  *
8  * Copyright (C) 2011 Numascale AS. All rights reserved.
9  *
10  * Send feedback to <support@numascale.com>
11  *
12  */
13 
14 #include <linux/init.h>
15 
16 #include <asm/numachip/numachip.h>
17 #include <asm/numachip/numachip_csr.h>
18 #include <asm/ipi.h>
19 #include <asm/apic_flat_64.h>
20 #include <asm/pgtable.h>
21 #include <asm/pci_x86.h>
22 
23 u8 numachip_system __read_mostly;
24 static const struct apic apic_numachip1;
25 static const struct apic apic_numachip2;
26 static void (*numachip_apic_icr_write)(int apicid, unsigned int val) __read_mostly;
27 
28 static unsigned int numachip1_get_apic_id(unsigned long x)
29 {
30 	unsigned long value;
31 	unsigned int id = (x >> 24) & 0xff;
32 
33 	if (static_cpu_has_safe(X86_FEATURE_NODEID_MSR)) {
34 		rdmsrl(MSR_FAM10H_NODE_ID, value);
35 		id |= (value << 2) & 0xff00;
36 	}
37 
38 	return id;
39 }
40 
41 static unsigned long numachip1_set_apic_id(unsigned int id)
42 {
43 	unsigned long x;
44 
45 	x = ((id & 0xffU) << 24);
46 	return x;
47 }
48 
49 static unsigned int numachip2_get_apic_id(unsigned long x)
50 {
51 	u64 mcfg;
52 
53 	rdmsrl(MSR_FAM10H_MMIO_CONF_BASE, mcfg);
54 	return ((mcfg >> (28 - 8)) & 0xfff00) | (x >> 24);
55 }
56 
57 static unsigned long numachip2_set_apic_id(unsigned int id)
58 {
59 	return id << 24;
60 }
61 
62 static int numachip_apic_id_valid(int apicid)
63 {
64 	/* Trust what bootloader passes in MADT */
65 	return 1;
66 }
67 
68 static int numachip_apic_id_registered(void)
69 {
70 	return 1;
71 }
72 
73 static int numachip_phys_pkg_id(int initial_apic_id, int index_msb)
74 {
75 	return initial_apic_id >> index_msb;
76 }
77 
78 static void numachip1_apic_icr_write(int apicid, unsigned int val)
79 {
80 	write_lcsr(CSR_G3_EXT_IRQ_GEN, (apicid << 16) | val);
81 }
82 
83 static void numachip2_apic_icr_write(int apicid, unsigned int val)
84 {
85 	numachip2_write32_lcsr(NUMACHIP2_APIC_ICR, (apicid << 12) | val);
86 }
87 
88 static int numachip_wakeup_secondary(int phys_apicid, unsigned long start_rip)
89 {
90 	numachip_apic_icr_write(phys_apicid, APIC_DM_INIT);
91 	numachip_apic_icr_write(phys_apicid, APIC_DM_STARTUP |
92 		(start_rip >> 12));
93 
94 	return 0;
95 }
96 
97 static void numachip_send_IPI_one(int cpu, int vector)
98 {
99 	int apicid = per_cpu(x86_cpu_to_apicid, cpu);
100 	unsigned int dmode;
101 
102 	dmode = (vector == NMI_VECTOR) ? APIC_DM_NMI : APIC_DM_FIXED;
103 	numachip_apic_icr_write(apicid, dmode | vector);
104 }
105 
106 static void numachip_send_IPI_mask(const struct cpumask *mask, int vector)
107 {
108 	unsigned int cpu;
109 
110 	for_each_cpu(cpu, mask)
111 		numachip_send_IPI_one(cpu, vector);
112 }
113 
114 static void numachip_send_IPI_mask_allbutself(const struct cpumask *mask,
115 						int vector)
116 {
117 	unsigned int this_cpu = smp_processor_id();
118 	unsigned int cpu;
119 
120 	for_each_cpu(cpu, mask) {
121 		if (cpu != this_cpu)
122 			numachip_send_IPI_one(cpu, vector);
123 	}
124 }
125 
126 static void numachip_send_IPI_allbutself(int vector)
127 {
128 	unsigned int this_cpu = smp_processor_id();
129 	unsigned int cpu;
130 
131 	for_each_online_cpu(cpu) {
132 		if (cpu != this_cpu)
133 			numachip_send_IPI_one(cpu, vector);
134 	}
135 }
136 
137 static void numachip_send_IPI_all(int vector)
138 {
139 	numachip_send_IPI_mask(cpu_online_mask, vector);
140 }
141 
142 static void numachip_send_IPI_self(int vector)
143 {
144 	apic_write(APIC_SELF_IPI, vector);
145 }
146 
147 static int __init numachip1_probe(void)
148 {
149 	return apic == &apic_numachip1;
150 }
151 
152 static int __init numachip2_probe(void)
153 {
154 	return apic == &apic_numachip2;
155 }
156 
157 static void fixup_cpu_id(struct cpuinfo_x86 *c, int node)
158 {
159 	u64 val;
160 	u32 nodes = 1;
161 
162 	this_cpu_write(cpu_llc_id, node);
163 
164 	/* Account for nodes per socket in multi-core-module processors */
165 	if (static_cpu_has_safe(X86_FEATURE_NODEID_MSR)) {
166 		rdmsrl(MSR_FAM10H_NODE_ID, val);
167 		nodes = ((val >> 3) & 7) + 1;
168 	}
169 
170 	c->phys_proc_id = node / nodes;
171 }
172 
173 static int __init numachip_system_init(void)
174 {
175 	/* Map the LCSR area and set up the apic_icr_write function */
176 	switch (numachip_system) {
177 	case 1:
178 		init_extra_mapping_uc(NUMACHIP_LCSR_BASE, NUMACHIP_LCSR_SIZE);
179 		numachip_apic_icr_write = numachip1_apic_icr_write;
180 		x86_init.pci.arch_init = pci_numachip_init;
181 		break;
182 	case 2:
183 		init_extra_mapping_uc(NUMACHIP2_LCSR_BASE, NUMACHIP2_LCSR_SIZE);
184 		numachip_apic_icr_write = numachip2_apic_icr_write;
185 
186 		/* Use MCFG config cycles rather than locked CF8 cycles */
187 		raw_pci_ops = &pci_mmcfg;
188 		break;
189 	default:
190 		return 0;
191 	}
192 
193 	x86_cpuinit.fixup_cpu_id = fixup_cpu_id;
194 
195 	return 0;
196 }
197 early_initcall(numachip_system_init);
198 
199 static int numachip1_acpi_madt_oem_check(char *oem_id, char *oem_table_id)
200 {
201 	if ((strncmp(oem_id, "NUMASC", 6) != 0) ||
202 	    (strncmp(oem_table_id, "NCONNECT", 8) != 0))
203 		return 0;
204 
205 	numachip_system = 1;
206 
207 	return 1;
208 }
209 
210 static int numachip2_acpi_madt_oem_check(char *oem_id, char *oem_table_id)
211 {
212 	if ((strncmp(oem_id, "NUMASC", 6) != 0) ||
213 	    (strncmp(oem_table_id, "NCONECT2", 8) != 0))
214 		return 0;
215 
216 	numachip_system = 2;
217 
218 	return 1;
219 }
220 
221 static const struct apic apic_numachip1 __refconst = {
222 	.name				= "NumaConnect system",
223 	.probe				= numachip1_probe,
224 	.acpi_madt_oem_check		= numachip1_acpi_madt_oem_check,
225 	.apic_id_valid			= numachip_apic_id_valid,
226 	.apic_id_registered		= numachip_apic_id_registered,
227 
228 	.irq_delivery_mode		= dest_Fixed,
229 	.irq_dest_mode			= 0, /* physical */
230 
231 	.target_cpus			= online_target_cpus,
232 	.disable_esr			= 0,
233 	.dest_logical			= 0,
234 	.check_apicid_used		= NULL,
235 
236 	.vector_allocation_domain	= default_vector_allocation_domain,
237 	.init_apic_ldr			= flat_init_apic_ldr,
238 
239 	.ioapic_phys_id_map		= NULL,
240 	.setup_apic_routing		= NULL,
241 	.cpu_present_to_apicid		= default_cpu_present_to_apicid,
242 	.apicid_to_cpu_present		= NULL,
243 	.check_phys_apicid_present	= default_check_phys_apicid_present,
244 	.phys_pkg_id			= numachip_phys_pkg_id,
245 
246 	.get_apic_id			= numachip1_get_apic_id,
247 	.set_apic_id			= numachip1_set_apic_id,
248 	.apic_id_mask			= 0xffU << 24,
249 
250 	.cpu_mask_to_apicid_and		= default_cpu_mask_to_apicid_and,
251 
252 	.send_IPI_mask			= numachip_send_IPI_mask,
253 	.send_IPI_mask_allbutself	= numachip_send_IPI_mask_allbutself,
254 	.send_IPI_allbutself		= numachip_send_IPI_allbutself,
255 	.send_IPI_all			= numachip_send_IPI_all,
256 	.send_IPI_self			= numachip_send_IPI_self,
257 
258 	.wakeup_secondary_cpu		= numachip_wakeup_secondary,
259 	.inquire_remote_apic		= NULL, /* REMRD not supported */
260 
261 	.read				= native_apic_mem_read,
262 	.write				= native_apic_mem_write,
263 	.eoi_write			= native_apic_mem_write,
264 	.icr_read			= native_apic_icr_read,
265 	.icr_write			= native_apic_icr_write,
266 	.wait_icr_idle			= native_apic_wait_icr_idle,
267 	.safe_wait_icr_idle		= native_safe_apic_wait_icr_idle,
268 };
269 
270 apic_driver(apic_numachip1);
271 
272 static const struct apic apic_numachip2 __refconst = {
273 	.name				= "NumaConnect2 system",
274 	.probe				= numachip2_probe,
275 	.acpi_madt_oem_check		= numachip2_acpi_madt_oem_check,
276 	.apic_id_valid			= numachip_apic_id_valid,
277 	.apic_id_registered		= numachip_apic_id_registered,
278 
279 	.irq_delivery_mode		= dest_Fixed,
280 	.irq_dest_mode			= 0, /* physical */
281 
282 	.target_cpus			= online_target_cpus,
283 	.disable_esr			= 0,
284 	.dest_logical			= 0,
285 	.check_apicid_used		= NULL,
286 
287 	.vector_allocation_domain	= default_vector_allocation_domain,
288 	.init_apic_ldr			= flat_init_apic_ldr,
289 
290 	.ioapic_phys_id_map		= NULL,
291 	.setup_apic_routing		= NULL,
292 	.cpu_present_to_apicid		= default_cpu_present_to_apicid,
293 	.apicid_to_cpu_present		= NULL,
294 	.check_phys_apicid_present	= default_check_phys_apicid_present,
295 	.phys_pkg_id			= numachip_phys_pkg_id,
296 
297 	.get_apic_id			= numachip2_get_apic_id,
298 	.set_apic_id			= numachip2_set_apic_id,
299 	.apic_id_mask			= 0xffU << 24,
300 
301 	.cpu_mask_to_apicid_and		= default_cpu_mask_to_apicid_and,
302 
303 	.send_IPI_mask			= numachip_send_IPI_mask,
304 	.send_IPI_mask_allbutself	= numachip_send_IPI_mask_allbutself,
305 	.send_IPI_allbutself		= numachip_send_IPI_allbutself,
306 	.send_IPI_all			= numachip_send_IPI_all,
307 	.send_IPI_self			= numachip_send_IPI_self,
308 
309 	.wakeup_secondary_cpu		= numachip_wakeup_secondary,
310 	.inquire_remote_apic		= NULL, /* REMRD not supported */
311 
312 	.read				= native_apic_mem_read,
313 	.write				= native_apic_mem_write,
314 	.eoi_write			= native_apic_mem_write,
315 	.icr_read			= native_apic_icr_read,
316 	.icr_write			= native_apic_icr_write,
317 	.wait_icr_idle			= native_apic_wait_icr_idle,
318 	.safe_wait_icr_idle		= native_safe_apic_wait_icr_idle,
319 };
320 
321 apic_driver(apic_numachip2);
322