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_safe(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
)
45 x
= ((id
& 0xffU
) << 24);
49 static unsigned int numachip2_get_apic_id(unsigned long x
)
53 rdmsrl(MSR_FAM10H_MMIO_CONF_BASE
, mcfg
);
54 return ((mcfg
>> (28 - 8)) & 0xfff00) | (x
>> 24);
57 static unsigned long numachip2_set_apic_id(unsigned int id
)
62 static int numachip_apic_id_valid(int apicid
)
64 /* Trust what bootloader passes in MADT */
68 static int numachip_apic_id_registered(void)
73 static int numachip_phys_pkg_id(int initial_apic_id
, int index_msb
)
75 return initial_apic_id
>> index_msb
;
78 static void numachip1_apic_icr_write(int apicid
, unsigned int val
)
80 write_lcsr(CSR_G3_EXT_IRQ_GEN
, (apicid
<< 16) | val
);
83 static void numachip2_apic_icr_write(int apicid
, unsigned int val
)
85 numachip2_write32_lcsr(NUMACHIP2_APIC_ICR
, (apicid
<< 12) | val
);
88 static int numachip_wakeup_secondary(int phys_apicid
, unsigned long start_rip
)
90 numachip_apic_icr_write(phys_apicid
, APIC_DM_INIT
);
91 numachip_apic_icr_write(phys_apicid
, APIC_DM_STARTUP
|
97 static void numachip_send_IPI_one(int cpu
, int vector
)
99 int local_apicid
, apicid
= per_cpu(x86_cpu_to_apicid
, cpu
);
103 local_apicid
= __this_cpu_read(x86_cpu_to_apicid
);
105 /* Send via local APIC where non-local part matches */
106 if (!((apicid
^ local_apicid
) >> NUMACHIP_LAPIC_BITS
)) {
109 local_irq_save(flags
);
110 __default_send_IPI_dest_field(apicid
, vector
,
112 local_irq_restore(flags
);
118 dmode
= (vector
== NMI_VECTOR
) ? APIC_DM_NMI
: APIC_DM_FIXED
;
119 numachip_apic_icr_write(apicid
, dmode
| vector
);
122 static void numachip_send_IPI_mask(const struct cpumask
*mask
, int vector
)
126 for_each_cpu(cpu
, mask
)
127 numachip_send_IPI_one(cpu
, vector
);
130 static void numachip_send_IPI_mask_allbutself(const struct cpumask
*mask
,
133 unsigned int this_cpu
= smp_processor_id();
136 for_each_cpu(cpu
, mask
) {
138 numachip_send_IPI_one(cpu
, vector
);
142 static void numachip_send_IPI_allbutself(int vector
)
144 unsigned int this_cpu
= smp_processor_id();
147 for_each_online_cpu(cpu
) {
149 numachip_send_IPI_one(cpu
, vector
);
153 static void numachip_send_IPI_all(int vector
)
155 numachip_send_IPI_mask(cpu_online_mask
, vector
);
158 static void numachip_send_IPI_self(int vector
)
160 apic_write(APIC_SELF_IPI
, vector
);
163 static int __init
numachip1_probe(void)
165 return apic
== &apic_numachip1
;
168 static int __init
numachip2_probe(void)
170 return apic
== &apic_numachip2
;
173 static void fixup_cpu_id(struct cpuinfo_x86
*c
, int node
)
178 this_cpu_write(cpu_llc_id
, node
);
180 /* Account for nodes per socket in multi-core-module processors */
181 if (static_cpu_has_safe(X86_FEATURE_NODEID_MSR
)) {
182 rdmsrl(MSR_FAM10H_NODE_ID
, val
);
183 nodes
= ((val
>> 3) & 7) + 1;
186 c
->phys_proc_id
= node
/ nodes
;
189 static int __init
numachip_system_init(void)
191 /* Map the LCSR area and set up the apic_icr_write function */
192 switch (numachip_system
) {
194 init_extra_mapping_uc(NUMACHIP_LCSR_BASE
, NUMACHIP_LCSR_SIZE
);
195 numachip_apic_icr_write
= numachip1_apic_icr_write
;
196 x86_init
.pci
.arch_init
= pci_numachip_init
;
199 init_extra_mapping_uc(NUMACHIP2_LCSR_BASE
, NUMACHIP2_LCSR_SIZE
);
200 numachip_apic_icr_write
= numachip2_apic_icr_write
;
202 /* Use MCFG config cycles rather than locked CF8 cycles */
203 raw_pci_ops
= &pci_mmcfg
;
209 x86_cpuinit
.fixup_cpu_id
= fixup_cpu_id
;
213 early_initcall(numachip_system_init
);
215 static int numachip1_acpi_madt_oem_check(char *oem_id
, char *oem_table_id
)
217 if ((strncmp(oem_id
, "NUMASC", 6) != 0) ||
218 (strncmp(oem_table_id
, "NCONNECT", 8) != 0))
226 static int numachip2_acpi_madt_oem_check(char *oem_id
, char *oem_table_id
)
228 if ((strncmp(oem_id
, "NUMASC", 6) != 0) ||
229 (strncmp(oem_table_id
, "NCONECT2", 8) != 0))
237 /* APIC IPIs are queued */
238 static void numachip_apic_wait_icr_idle(void)
242 /* APIC NMI IPIs are queued */
243 static u32
numachip_safe_apic_wait_icr_idle(void)
248 static const struct apic apic_numachip1 __refconst
= {
249 .name
= "NumaConnect system",
250 .probe
= numachip1_probe
,
251 .acpi_madt_oem_check
= numachip1_acpi_madt_oem_check
,
252 .apic_id_valid
= numachip_apic_id_valid
,
253 .apic_id_registered
= numachip_apic_id_registered
,
255 .irq_delivery_mode
= dest_Fixed
,
256 .irq_dest_mode
= 0, /* physical */
258 .target_cpus
= online_target_cpus
,
261 .check_apicid_used
= NULL
,
263 .vector_allocation_domain
= default_vector_allocation_domain
,
264 .init_apic_ldr
= flat_init_apic_ldr
,
266 .ioapic_phys_id_map
= NULL
,
267 .setup_apic_routing
= NULL
,
268 .cpu_present_to_apicid
= default_cpu_present_to_apicid
,
269 .apicid_to_cpu_present
= NULL
,
270 .check_phys_apicid_present
= default_check_phys_apicid_present
,
271 .phys_pkg_id
= numachip_phys_pkg_id
,
273 .get_apic_id
= numachip1_get_apic_id
,
274 .set_apic_id
= numachip1_set_apic_id
,
275 .apic_id_mask
= 0xffU
<< 24,
277 .cpu_mask_to_apicid_and
= default_cpu_mask_to_apicid_and
,
279 .send_IPI_mask
= numachip_send_IPI_mask
,
280 .send_IPI_mask_allbutself
= numachip_send_IPI_mask_allbutself
,
281 .send_IPI_allbutself
= numachip_send_IPI_allbutself
,
282 .send_IPI_all
= numachip_send_IPI_all
,
283 .send_IPI_self
= numachip_send_IPI_self
,
285 .wakeup_secondary_cpu
= numachip_wakeup_secondary
,
286 .inquire_remote_apic
= NULL
, /* REMRD not supported */
288 .read
= native_apic_mem_read
,
289 .write
= native_apic_mem_write
,
290 .eoi_write
= native_apic_mem_write
,
291 .icr_read
= native_apic_icr_read
,
292 .icr_write
= native_apic_icr_write
,
293 .wait_icr_idle
= numachip_apic_wait_icr_idle
,
294 .safe_wait_icr_idle
= numachip_safe_apic_wait_icr_idle
,
297 apic_driver(apic_numachip1
);
299 static const struct apic apic_numachip2 __refconst
= {
300 .name
= "NumaConnect2 system",
301 .probe
= numachip2_probe
,
302 .acpi_madt_oem_check
= numachip2_acpi_madt_oem_check
,
303 .apic_id_valid
= numachip_apic_id_valid
,
304 .apic_id_registered
= numachip_apic_id_registered
,
306 .irq_delivery_mode
= dest_Fixed
,
307 .irq_dest_mode
= 0, /* physical */
309 .target_cpus
= online_target_cpus
,
312 .check_apicid_used
= NULL
,
314 .vector_allocation_domain
= default_vector_allocation_domain
,
315 .init_apic_ldr
= flat_init_apic_ldr
,
317 .ioapic_phys_id_map
= NULL
,
318 .setup_apic_routing
= NULL
,
319 .cpu_present_to_apicid
= default_cpu_present_to_apicid
,
320 .apicid_to_cpu_present
= NULL
,
321 .check_phys_apicid_present
= default_check_phys_apicid_present
,
322 .phys_pkg_id
= numachip_phys_pkg_id
,
324 .get_apic_id
= numachip2_get_apic_id
,
325 .set_apic_id
= numachip2_set_apic_id
,
326 .apic_id_mask
= 0xffU
<< 24,
328 .cpu_mask_to_apicid_and
= default_cpu_mask_to_apicid_and
,
330 .send_IPI_mask
= numachip_send_IPI_mask
,
331 .send_IPI_mask_allbutself
= numachip_send_IPI_mask_allbutself
,
332 .send_IPI_allbutself
= numachip_send_IPI_allbutself
,
333 .send_IPI_all
= numachip_send_IPI_all
,
334 .send_IPI_self
= numachip_send_IPI_self
,
336 .wakeup_secondary_cpu
= numachip_wakeup_secondary
,
337 .inquire_remote_apic
= NULL
, /* REMRD not supported */
339 .read
= native_apic_mem_read
,
340 .write
= native_apic_mem_write
,
341 .eoi_write
= native_apic_mem_write
,
342 .icr_read
= native_apic_icr_read
,
343 .icr_write
= native_apic_icr_write
,
344 .wait_icr_idle
= numachip_apic_wait_icr_idle
,
345 .safe_wait_icr_idle
= numachip_safe_apic_wait_icr_idle
,
348 apic_driver(apic_numachip2
);