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 
20 static struct apic apic_physflat;
21 static struct apic apic_flat;
22 
23 struct apic *apic __ro_after_init = &apic_flat;
24 EXPORT_SYMBOL_GPL(apic);
25 
flat_acpi_madt_oem_check(char * oem_id,char * oem_table_id)26 static int flat_acpi_madt_oem_check(char *oem_id, char *oem_table_id)
27 {
28 	return 1;
29 }
30 
31 /*
32  * Set up the logical destination ID.
33  *
34  * Intel recommends to set DFR, LDR and TPR before enabling
35  * an APIC.  See e.g. "AP-388 82489DX User's Manual" (Intel
36  * document number 292116).  So here it goes...
37  */
flat_init_apic_ldr(void)38 void flat_init_apic_ldr(void)
39 {
40 	unsigned long val;
41 	unsigned long num, id;
42 
43 	num = smp_processor_id();
44 	id = 1UL << num;
45 	apic_write(APIC_DFR, APIC_DFR_FLAT);
46 	val = apic_read(APIC_LDR) & ~APIC_LDR_MASK;
47 	val |= SET_APIC_LOGICAL_ID(id);
48 	apic_write(APIC_LDR, val);
49 }
50 
_flat_send_IPI_mask(unsigned long mask,int vector)51 static void _flat_send_IPI_mask(unsigned long mask, int vector)
52 {
53 	unsigned long flags;
54 
55 	local_irq_save(flags);
56 	__default_send_IPI_dest_field(mask, vector, APIC_DEST_LOGICAL);
57 	local_irq_restore(flags);
58 }
59 
flat_send_IPI_mask(const struct cpumask * cpumask,int vector)60 static void flat_send_IPI_mask(const struct cpumask *cpumask, int vector)
61 {
62 	unsigned long mask = cpumask_bits(cpumask)[0];
63 
64 	_flat_send_IPI_mask(mask, vector);
65 }
66 
67 static void
flat_send_IPI_mask_allbutself(const struct cpumask * cpumask,int vector)68 flat_send_IPI_mask_allbutself(const struct cpumask *cpumask, int vector)
69 {
70 	unsigned long mask = cpumask_bits(cpumask)[0];
71 	int cpu = smp_processor_id();
72 
73 	if (cpu < BITS_PER_LONG)
74 		__clear_bit(cpu, &mask);
75 
76 	_flat_send_IPI_mask(mask, vector);
77 }
78 
flat_get_apic_id(unsigned long x)79 static unsigned int flat_get_apic_id(unsigned long x)
80 {
81 	return (x >> 24) & 0xFF;
82 }
83 
set_apic_id(unsigned int id)84 static u32 set_apic_id(unsigned int id)
85 {
86 	return (id & 0xFF) << 24;
87 }
88 
read_xapic_id(void)89 static unsigned int read_xapic_id(void)
90 {
91 	return flat_get_apic_id(apic_read(APIC_ID));
92 }
93 
flat_apic_id_registered(void)94 static int flat_apic_id_registered(void)
95 {
96 	return physid_isset(read_xapic_id(), phys_cpu_present_map);
97 }
98 
flat_phys_pkg_id(int initial_apic_id,int index_msb)99 static int flat_phys_pkg_id(int initial_apic_id, int index_msb)
100 {
101 	return initial_apic_id >> index_msb;
102 }
103 
flat_probe(void)104 static int flat_probe(void)
105 {
106 	return 1;
107 }
108 
109 static struct apic apic_flat __ro_after_init = {
110 	.name				= "flat",
111 	.probe				= flat_probe,
112 	.acpi_madt_oem_check		= flat_acpi_madt_oem_check,
113 	.apic_id_valid			= default_apic_id_valid,
114 	.apic_id_registered		= flat_apic_id_registered,
115 
116 	.delivery_mode			= APIC_DELIVERY_MODE_FIXED,
117 	.dest_mode_logical		= true,
118 
119 	.disable_esr			= 0,
120 
121 	.check_apicid_used		= NULL,
122 	.init_apic_ldr			= flat_init_apic_ldr,
123 	.ioapic_phys_id_map		= NULL,
124 	.setup_apic_routing		= NULL,
125 	.cpu_present_to_apicid		= default_cpu_present_to_apicid,
126 	.apicid_to_cpu_present		= NULL,
127 	.check_phys_apicid_present	= default_check_phys_apicid_present,
128 	.phys_pkg_id			= flat_phys_pkg_id,
129 
130 	.get_apic_id			= flat_get_apic_id,
131 	.set_apic_id			= set_apic_id,
132 
133 	.calc_dest_apicid		= apic_flat_calc_apicid,
134 
135 	.send_IPI			= default_send_IPI_single,
136 	.send_IPI_mask			= flat_send_IPI_mask,
137 	.send_IPI_mask_allbutself	= flat_send_IPI_mask_allbutself,
138 	.send_IPI_allbutself		= default_send_IPI_allbutself,
139 	.send_IPI_all			= default_send_IPI_all,
140 	.send_IPI_self			= default_send_IPI_self,
141 
142 	.inquire_remote_apic		= default_inquire_remote_apic,
143 
144 	.read				= native_apic_mem_read,
145 	.write				= native_apic_mem_write,
146 	.eoi_write			= native_apic_mem_write,
147 	.icr_read			= native_apic_icr_read,
148 	.icr_write			= native_apic_icr_write,
149 	.wait_icr_idle			= native_apic_wait_icr_idle,
150 	.safe_wait_icr_idle		= native_safe_apic_wait_icr_idle,
151 };
152 
153 /*
154  * Physflat mode is used when there are more than 8 CPUs on a system.
155  * We cannot use logical delivery in this case because the mask
156  * overflows, so use physical mode.
157  */
physflat_acpi_madt_oem_check(char * oem_id,char * oem_table_id)158 static int physflat_acpi_madt_oem_check(char *oem_id, char *oem_table_id)
159 {
160 #ifdef CONFIG_ACPI
161 	/*
162 	 * Quirk: some x86_64 machines can only use physical APIC mode
163 	 * regardless of how many processors are present (x86_64 ES7000
164 	 * is an example).
165 	 */
166 	if (acpi_gbl_FADT.header.revision >= FADT2_REVISION_ID &&
167 		(acpi_gbl_FADT.flags & ACPI_FADT_APIC_PHYSICAL)) {
168 		printk(KERN_DEBUG "system APIC only can use physical flat");
169 		return 1;
170 	}
171 
172 	if (!strncmp(oem_id, "IBM", 3) && !strncmp(oem_table_id, "EXA", 3)) {
173 		printk(KERN_DEBUG "IBM Summit detected, will use apic physical");
174 		return 1;
175 	}
176 #endif
177 
178 	return 0;
179 }
180 
physflat_init_apic_ldr(void)181 static void physflat_init_apic_ldr(void)
182 {
183 	/*
184 	 * LDR and DFR are not involved in physflat mode, rather:
185 	 * "In physical destination mode, the destination processor is
186 	 * specified by its local APIC ID [...]." (Intel SDM, 10.6.2.1)
187 	 */
188 }
189 
physflat_probe(void)190 static int physflat_probe(void)
191 {
192 	if (apic == &apic_physflat || num_possible_cpus() > 8 ||
193 	    jailhouse_paravirt())
194 		return 1;
195 
196 	return 0;
197 }
198 
199 static struct apic apic_physflat __ro_after_init = {
200 
201 	.name				= "physical flat",
202 	.probe				= physflat_probe,
203 	.acpi_madt_oem_check		= physflat_acpi_madt_oem_check,
204 	.apic_id_valid			= default_apic_id_valid,
205 	.apic_id_registered		= flat_apic_id_registered,
206 
207 	.delivery_mode			= APIC_DELIVERY_MODE_FIXED,
208 	.dest_mode_logical		= false,
209 
210 	.disable_esr			= 0,
211 
212 	.check_apicid_used		= NULL,
213 	.init_apic_ldr			= physflat_init_apic_ldr,
214 	.ioapic_phys_id_map		= NULL,
215 	.setup_apic_routing		= NULL,
216 	.cpu_present_to_apicid		= default_cpu_present_to_apicid,
217 	.apicid_to_cpu_present		= NULL,
218 	.check_phys_apicid_present	= default_check_phys_apicid_present,
219 	.phys_pkg_id			= flat_phys_pkg_id,
220 
221 	.get_apic_id			= flat_get_apic_id,
222 	.set_apic_id			= set_apic_id,
223 
224 	.calc_dest_apicid		= apic_default_calc_apicid,
225 
226 	.send_IPI			= default_send_IPI_single_phys,
227 	.send_IPI_mask			= default_send_IPI_mask_sequence_phys,
228 	.send_IPI_mask_allbutself	= default_send_IPI_mask_allbutself_phys,
229 	.send_IPI_allbutself		= default_send_IPI_allbutself,
230 	.send_IPI_all			= default_send_IPI_all,
231 	.send_IPI_self			= default_send_IPI_self,
232 
233 	.inquire_remote_apic		= default_inquire_remote_apic,
234 
235 	.read				= native_apic_mem_read,
236 	.write				= native_apic_mem_write,
237 	.eoi_write			= native_apic_mem_write,
238 	.icr_read			= native_apic_icr_read,
239 	.icr_write			= native_apic_icr_write,
240 	.wait_icr_idle			= native_apic_wait_icr_idle,
241 	.safe_wait_icr_idle		= native_safe_apic_wait_icr_idle,
242 };
243 
244 /*
245  * We need to check for physflat first, so this order is important.
246  */
247 apic_drivers(apic_physflat, apic_flat);
248