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
6 * Numascale NumaConnect-Specific APIC Code
8 * Copyright (C) 2011 Numascale AS. All rights reserved.
10 * Send feedback to <support@numascale.com>
14 #include <linux/init.h>
16 #include <asm/numachip/numachip.h>
17 #include <asm/numachip/numachip_csr.h>
19 #include <asm/apic_flat_64.h>
20 #include <asm/pgtable.h>
21 #include <asm/pci_x86.h>
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
;
28 static unsigned int numachip1_get_apic_id(unsigned long x
)
31 unsigned int id
= (x
>> 24) & 0xff;
33 if (static_cpu_has(X86_FEATURE_NODEID_MSR
)) {
34 rdmsrl(MSR_FAM10H_NODE_ID
, value
);
35 id
|= (value
<< 2) & 0xff00;
41 static unsigned long numachip1_set_apic_id(unsigned int id
)
43 return (id
& 0xff) << 24;
46 static unsigned int numachip2_get_apic_id(unsigned long x
)
50 rdmsrl(MSR_FAM10H_MMIO_CONF_BASE
, mcfg
);
51 return ((mcfg
>> (28 - 8)) & 0xfff00) | (x
>> 24);
54 static unsigned long numachip2_set_apic_id(unsigned int id
)
59 static int numachip_apic_id_valid(int apicid
)
61 /* Trust what bootloader passes in MADT */
65 static int numachip_apic_id_registered(void)
70 static int numachip_phys_pkg_id(int initial_apic_id
, int index_msb
)
72 return initial_apic_id
>> index_msb
;
75 static void numachip1_apic_icr_write(int apicid
, unsigned int val
)
77 write_lcsr(CSR_G3_EXT_IRQ_GEN
, (apicid
<< 16) | val
);
80 static void numachip2_apic_icr_write(int apicid
, unsigned int val
)
82 numachip2_write32_lcsr(NUMACHIP2_APIC_ICR
, (apicid
<< 12) | val
);
85 static int numachip_wakeup_secondary(int phys_apicid
, unsigned long start_rip
)
87 numachip_apic_icr_write(phys_apicid
, APIC_DM_INIT
);
88 numachip_apic_icr_write(phys_apicid
, APIC_DM_STARTUP
|
94 static void numachip_send_IPI_one(int cpu
, int vector
)
96 int local_apicid
, apicid
= per_cpu(x86_cpu_to_apicid
, cpu
);
100 local_apicid
= __this_cpu_read(x86_cpu_to_apicid
);
102 /* Send via local APIC where non-local part matches */
103 if (!((apicid
^ local_apicid
) >> NUMACHIP_LAPIC_BITS
)) {
106 local_irq_save(flags
);
107 __default_send_IPI_dest_field(apicid
, vector
,
109 local_irq_restore(flags
);
115 dmode
= (vector
== NMI_VECTOR
) ? APIC_DM_NMI
: APIC_DM_FIXED
;
116 numachip_apic_icr_write(apicid
, dmode
| vector
);
119 static void numachip_send_IPI_mask(const struct cpumask
*mask
, int vector
)
123 for_each_cpu(cpu
, mask
)
124 numachip_send_IPI_one(cpu
, vector
);
127 static void numachip_send_IPI_mask_allbutself(const struct cpumask
*mask
,
130 unsigned int this_cpu
= smp_processor_id();
133 for_each_cpu(cpu
, mask
) {
135 numachip_send_IPI_one(cpu
, vector
);
139 static void numachip_send_IPI_allbutself(int vector
)
141 unsigned int this_cpu
= smp_processor_id();
144 for_each_online_cpu(cpu
) {
146 numachip_send_IPI_one(cpu
, vector
);
150 static void numachip_send_IPI_all(int vector
)
152 numachip_send_IPI_mask(cpu_online_mask
, vector
);
155 static void numachip_send_IPI_self(int vector
)
157 apic_write(APIC_SELF_IPI
, vector
);
160 static int __init
numachip1_probe(void)
162 return apic
== &apic_numachip1
;
165 static int __init
numachip2_probe(void)
167 return apic
== &apic_numachip2
;
170 static void fixup_cpu_id(struct cpuinfo_x86
*c
, int node
)
175 this_cpu_write(cpu_llc_id
, node
);
177 /* Account for nodes per socket in multi-core-module processors */
178 if (static_cpu_has(X86_FEATURE_NODEID_MSR
)) {
179 rdmsrl(MSR_FAM10H_NODE_ID
, val
);
180 nodes
= ((val
>> 3) & 7) + 1;
183 c
->phys_proc_id
= node
/ nodes
;
186 static int __init
numachip_system_init(void)
188 /* Map the LCSR area and set up the apic_icr_write function */
189 switch (numachip_system
) {
191 init_extra_mapping_uc(NUMACHIP_LCSR_BASE
, NUMACHIP_LCSR_SIZE
);
192 numachip_apic_icr_write
= numachip1_apic_icr_write
;
195 init_extra_mapping_uc(NUMACHIP2_LCSR_BASE
, NUMACHIP2_LCSR_SIZE
);
196 numachip_apic_icr_write
= numachip2_apic_icr_write
;
202 x86_cpuinit
.fixup_cpu_id
= fixup_cpu_id
;
203 x86_init
.pci
.arch_init
= pci_numachip_init
;
207 early_initcall(numachip_system_init
);
209 static int numachip1_acpi_madt_oem_check(char *oem_id
, char *oem_table_id
)
211 if ((strncmp(oem_id
, "NUMASC", 6) != 0) ||
212 (strncmp(oem_table_id
, "NCONNECT", 8) != 0))
220 static int numachip2_acpi_madt_oem_check(char *oem_id
, char *oem_table_id
)
222 if ((strncmp(oem_id
, "NUMASC", 6) != 0) ||
223 (strncmp(oem_table_id
, "NCONECT2", 8) != 0))
231 /* APIC IPIs are queued */
232 static void numachip_apic_wait_icr_idle(void)
236 /* APIC NMI IPIs are queued */
237 static u32
numachip_safe_apic_wait_icr_idle(void)
242 static const struct apic apic_numachip1 __refconst
= {
243 .name
= "NumaConnect system",
244 .probe
= numachip1_probe
,
245 .acpi_madt_oem_check
= numachip1_acpi_madt_oem_check
,
246 .apic_id_valid
= numachip_apic_id_valid
,
247 .apic_id_registered
= numachip_apic_id_registered
,
249 .irq_delivery_mode
= dest_Fixed
,
250 .irq_dest_mode
= 0, /* physical */
252 .target_cpus
= online_target_cpus
,
255 .check_apicid_used
= NULL
,
257 .vector_allocation_domain
= default_vector_allocation_domain
,
258 .init_apic_ldr
= flat_init_apic_ldr
,
260 .ioapic_phys_id_map
= NULL
,
261 .setup_apic_routing
= NULL
,
262 .cpu_present_to_apicid
= default_cpu_present_to_apicid
,
263 .apicid_to_cpu_present
= NULL
,
264 .check_phys_apicid_present
= default_check_phys_apicid_present
,
265 .phys_pkg_id
= numachip_phys_pkg_id
,
267 .get_apic_id
= numachip1_get_apic_id
,
268 .set_apic_id
= numachip1_set_apic_id
,
270 .cpu_mask_to_apicid
= default_cpu_mask_to_apicid
,
272 .send_IPI
= numachip_send_IPI_one
,
273 .send_IPI_mask
= numachip_send_IPI_mask
,
274 .send_IPI_mask_allbutself
= numachip_send_IPI_mask_allbutself
,
275 .send_IPI_allbutself
= numachip_send_IPI_allbutself
,
276 .send_IPI_all
= numachip_send_IPI_all
,
277 .send_IPI_self
= numachip_send_IPI_self
,
279 .wakeup_secondary_cpu
= numachip_wakeup_secondary
,
280 .inquire_remote_apic
= NULL
, /* REMRD not supported */
282 .read
= native_apic_mem_read
,
283 .write
= native_apic_mem_write
,
284 .eoi_write
= native_apic_mem_write
,
285 .icr_read
= native_apic_icr_read
,
286 .icr_write
= native_apic_icr_write
,
287 .wait_icr_idle
= numachip_apic_wait_icr_idle
,
288 .safe_wait_icr_idle
= numachip_safe_apic_wait_icr_idle
,
291 apic_driver(apic_numachip1
);
293 static const struct apic apic_numachip2 __refconst
= {
294 .name
= "NumaConnect2 system",
295 .probe
= numachip2_probe
,
296 .acpi_madt_oem_check
= numachip2_acpi_madt_oem_check
,
297 .apic_id_valid
= numachip_apic_id_valid
,
298 .apic_id_registered
= numachip_apic_id_registered
,
300 .irq_delivery_mode
= dest_Fixed
,
301 .irq_dest_mode
= 0, /* physical */
303 .target_cpus
= online_target_cpus
,
306 .check_apicid_used
= NULL
,
308 .vector_allocation_domain
= default_vector_allocation_domain
,
309 .init_apic_ldr
= flat_init_apic_ldr
,
311 .ioapic_phys_id_map
= NULL
,
312 .setup_apic_routing
= NULL
,
313 .cpu_present_to_apicid
= default_cpu_present_to_apicid
,
314 .apicid_to_cpu_present
= NULL
,
315 .check_phys_apicid_present
= default_check_phys_apicid_present
,
316 .phys_pkg_id
= numachip_phys_pkg_id
,
318 .get_apic_id
= numachip2_get_apic_id
,
319 .set_apic_id
= numachip2_set_apic_id
,
321 .cpu_mask_to_apicid
= default_cpu_mask_to_apicid
,
323 .send_IPI
= numachip_send_IPI_one
,
324 .send_IPI_mask
= numachip_send_IPI_mask
,
325 .send_IPI_mask_allbutself
= numachip_send_IPI_mask_allbutself
,
326 .send_IPI_allbutself
= numachip_send_IPI_allbutself
,
327 .send_IPI_all
= numachip_send_IPI_all
,
328 .send_IPI_self
= numachip_send_IPI_self
,
330 .wakeup_secondary_cpu
= numachip_wakeup_secondary
,
331 .inquire_remote_apic
= NULL
, /* REMRD not supported */
333 .read
= native_apic_mem_read
,
334 .write
= native_apic_mem_write
,
335 .eoi_write
= native_apic_mem_write
,
336 .icr_read
= native_apic_icr_read
,
337 .icr_write
= native_apic_icr_write
,
338 .wait_icr_idle
= numachip_apic_wait_icr_idle
,
339 .safe_wait_icr_idle
= numachip_safe_apic_wait_icr_idle
,
342 apic_driver(apic_numachip2
);