1 // SPDX-License-Identifier: GPL-2.0
3 * APIC driver for "bigsmp" xAPIC machines with more than 8 virtual CPUs.
5 * Drives the local APIC in "clustered mode".
7 #include <linux/cpumask.h>
12 #include <asm/io_apic.h>
16 static u32
bigsmp_get_apic_id(u32 x
)
18 return (x
>> 24) & 0xFF;
21 static void bigsmp_send_IPI_allbutself(int vector
)
23 default_send_IPI_mask_allbutself_phys(cpu_online_mask
, vector
);
26 static void bigsmp_send_IPI_all(int vector
)
28 default_send_IPI_mask_sequence_phys(cpu_online_mask
, vector
);
31 static int dmi_bigsmp
; /* can be set by dmi scanners */
33 static int hp_ht_bigsmp(const struct dmi_system_id
*d
)
35 printk(KERN_NOTICE
"%s detected: force use of apic=bigsmp\n", d
->ident
);
42 static const struct dmi_system_id bigsmp_dmi_table
[] = {
43 { hp_ht_bigsmp
, "HP ProLiant DL760 G2",
44 { DMI_MATCH(DMI_BIOS_VENDOR
, "HP"),
45 DMI_MATCH(DMI_BIOS_VERSION
, "P44-"),
49 { hp_ht_bigsmp
, "HP ProLiant DL740",
50 { DMI_MATCH(DMI_BIOS_VENDOR
, "HP"),
51 DMI_MATCH(DMI_BIOS_VERSION
, "P47-"),
54 { } /* NULL entry stops DMI scanning */
57 static int probe_bigsmp(void)
59 return dmi_check_system(bigsmp_dmi_table
);
62 static struct apic apic_bigsmp __ro_after_init
= {
65 .probe
= probe_bigsmp
,
67 .dest_mode_logical
= false,
71 .cpu_present_to_apicid
= default_cpu_present_to_apicid
,
74 .get_apic_id
= bigsmp_get_apic_id
,
76 .calc_dest_apicid
= apic_default_calc_apicid
,
78 .send_IPI
= default_send_IPI_single_phys
,
79 .send_IPI_mask
= default_send_IPI_mask_sequence_phys
,
80 .send_IPI_mask_allbutself
= NULL
,
81 .send_IPI_allbutself
= bigsmp_send_IPI_allbutself
,
82 .send_IPI_all
= bigsmp_send_IPI_all
,
83 .send_IPI_self
= default_send_IPI_self
,
85 .read
= native_apic_mem_read
,
86 .write
= native_apic_mem_write
,
87 .eoi
= native_apic_mem_eoi
,
88 .icr_read
= native_apic_icr_read
,
89 .icr_write
= native_apic_icr_write
,
90 .wait_icr_idle
= apic_mem_wait_icr_idle
,
91 .safe_wait_icr_idle
= apic_mem_wait_icr_idle_timeout
,
94 bool __init
apic_bigsmp_possible(bool cmdline_override
)
96 return apic
== &apic_bigsmp
|| !cmdline_override
;
99 void __init
apic_bigsmp_force(void)
101 if (apic
!= &apic_bigsmp
)
102 apic_install_driver(&apic_bigsmp
);
105 apic_driver(apic_bigsmp
);