1// SPDX-License-Identifier: GPL-2.0-only
2/*
3 * Copyright 2004 James Cleverdon, IBM.
4 *
5 * Flat APIC subarch code.
6 *
7 * Hacked for x86-64 by James Cleverdon from i386 architecture code by
8 * Martin Bligh, Andi Kleen, James Bottomley, John Stultz, and
9 * James Cleverdon.
10 */
11#include <linux/cpumask.h>
12#include <linux/export.h>
13#include <linux/acpi.h>
14
15#include <asm/jailhouse_para.h>
16#include <asm/apic.h>
17
18#include "local.h"
19
20static struct apic apic_physflat;
21static struct apic apic_flat;
22
23struct apic *apic __ro_after_init = &apic_flat;
24EXPORT_SYMBOL_GPL(apic);
25
26static int flat_acpi_madt_oem_check(char *oem_id, char *oem_table_id)
27{
28	return 1;
29}
30
31static void _flat_send_IPI_mask(unsigned long mask, int vector)
32{
33	unsigned long flags;
34
35	local_irq_save(flags);
36	__default_send_IPI_dest_field(mask, vector, APIC_DEST_LOGICAL);
37	local_irq_restore(flags);
38}
39
40static void flat_send_IPI_mask(const struct cpumask *cpumask, int vector)
41{
42	unsigned long mask = cpumask_bits(cpumask)[0];
43
44	_flat_send_IPI_mask(mask, vector);
45}
46
47static void
48flat_send_IPI_mask_allbutself(const struct cpumask *cpumask, int vector)
49{
50	unsigned long mask = cpumask_bits(cpumask)[0];
51	int cpu = smp_processor_id();
52
53	if (cpu < BITS_PER_LONG)
54		__clear_bit(cpu, &mask);
55
56	_flat_send_IPI_mask(mask, vector);
57}
58
59static u32 flat_get_apic_id(u32 x)
60{
61	return (x >> 24) & 0xFF;
62}
63
64static int flat_probe(void)
65{
66	return 1;
67}
68
69static struct apic apic_flat __ro_after_init = {
70	.name				= "flat",
71	.probe				= flat_probe,
72	.acpi_madt_oem_check		= flat_acpi_madt_oem_check,
73
74	.dest_mode_logical		= true,
75
76	.disable_esr			= 0,
77
78	.init_apic_ldr			= default_init_apic_ldr,
79	.cpu_present_to_apicid		= default_cpu_present_to_apicid,
80
81	.max_apic_id			= 0xFE,
82	.get_apic_id			= flat_get_apic_id,
83
84	.calc_dest_apicid		= apic_flat_calc_apicid,
85
86	.send_IPI			= default_send_IPI_single,
87	.send_IPI_mask			= flat_send_IPI_mask,
88	.send_IPI_mask_allbutself	= flat_send_IPI_mask_allbutself,
89	.send_IPI_allbutself		= default_send_IPI_allbutself,
90	.send_IPI_all			= default_send_IPI_all,
91	.send_IPI_self			= default_send_IPI_self,
92	.nmi_to_offline_cpu		= true,
93
94	.read				= native_apic_mem_read,
95	.write				= native_apic_mem_write,
96	.eoi				= native_apic_mem_eoi,
97	.icr_read			= native_apic_icr_read,
98	.icr_write			= native_apic_icr_write,
99	.wait_icr_idle			= apic_mem_wait_icr_idle,
100	.safe_wait_icr_idle		= apic_mem_wait_icr_idle_timeout,
101};
102
103/*
104 * Physflat mode is used when there are more than 8 CPUs on a system.
105 * We cannot use logical delivery in this case because the mask
106 * overflows, so use physical mode.
107 */
108static int physflat_acpi_madt_oem_check(char *oem_id, char *oem_table_id)
109{
110#ifdef CONFIG_ACPI
111	/*
112	 * Quirk: some x86_64 machines can only use physical APIC mode
113	 * regardless of how many processors are present (x86_64 ES7000
114	 * is an example).
115	 */
116	if (acpi_gbl_FADT.header.revision >= FADT2_REVISION_ID &&
117		(acpi_gbl_FADT.flags & ACPI_FADT_APIC_PHYSICAL)) {
118		printk(KERN_DEBUG "system APIC only can use physical flat");
119		return 1;
120	}
121
122	if (!strncmp(oem_id, "IBM", 3) && !strncmp(oem_table_id, "EXA", 3)) {
123		printk(KERN_DEBUG "IBM Summit detected, will use apic physical");
124		return 1;
125	}
126#endif
127
128	return 0;
129}
130
131static int physflat_probe(void)
132{
133	return apic == &apic_physflat || num_possible_cpus() > 8 || jailhouse_paravirt();
134}
135
136static struct apic apic_physflat __ro_after_init = {
137
138	.name				= "physical flat",
139	.probe				= physflat_probe,
140	.acpi_madt_oem_check		= physflat_acpi_madt_oem_check,
141
142	.dest_mode_logical		= false,
143
144	.disable_esr			= 0,
145
146	.cpu_present_to_apicid		= default_cpu_present_to_apicid,
147
148	.max_apic_id			= 0xFE,
149	.get_apic_id			= flat_get_apic_id,
150
151	.calc_dest_apicid		= apic_default_calc_apicid,
152
153	.send_IPI			= default_send_IPI_single_phys,
154	.send_IPI_mask			= default_send_IPI_mask_sequence_phys,
155	.send_IPI_mask_allbutself	= default_send_IPI_mask_allbutself_phys,
156	.send_IPI_allbutself		= default_send_IPI_allbutself,
157	.send_IPI_all			= default_send_IPI_all,
158	.send_IPI_self			= default_send_IPI_self,
159	.nmi_to_offline_cpu		= true,
160
161	.read				= native_apic_mem_read,
162	.write				= native_apic_mem_write,
163	.eoi				= native_apic_mem_eoi,
164	.icr_read			= native_apic_icr_read,
165	.icr_write			= native_apic_icr_write,
166	.wait_icr_idle			= apic_mem_wait_icr_idle,
167	.safe_wait_icr_idle		= apic_mem_wait_icr_idle_timeout,
168};
169
170/*
171 * We need to check for physflat first, so this order is important.
172 */
173apic_drivers(apic_physflat, apic_flat);
174