Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/arch/x86/include/asm/apic.h
10821 views
1
#ifndef _ASM_X86_APIC_H
2
#define _ASM_X86_APIC_H
3
4
#include <linux/cpumask.h>
5
#include <linux/pm.h>
6
7
#include <asm/alternative.h>
8
#include <asm/cpufeature.h>
9
#include <asm/processor.h>
10
#include <asm/apicdef.h>
11
#include <asm/atomic.h>
12
#include <asm/fixmap.h>
13
#include <asm/mpspec.h>
14
#include <asm/system.h>
15
#include <asm/msr.h>
16
17
#define ARCH_APICTIMER_STOPS_ON_C3 1
18
19
/*
20
* Debugging macros
21
*/
22
#define APIC_QUIET 0
23
#define APIC_VERBOSE 1
24
#define APIC_DEBUG 2
25
26
/*
27
* Define the default level of output to be very little
28
* This can be turned up by using apic=verbose for more
29
* information and apic=debug for _lots_ of information.
30
* apic_verbosity is defined in apic.c
31
*/
32
#define apic_printk(v, s, a...) do { \
33
if ((v) <= apic_verbosity) \
34
printk(s, ##a); \
35
} while (0)
36
37
38
#if defined(CONFIG_X86_LOCAL_APIC) && defined(CONFIG_X86_32)
39
extern void generic_apic_probe(void);
40
#else
41
static inline void generic_apic_probe(void)
42
{
43
}
44
#endif
45
46
#ifdef CONFIG_X86_LOCAL_APIC
47
48
extern unsigned int apic_verbosity;
49
extern int local_apic_timer_c2_ok;
50
51
extern int disable_apic;
52
53
#ifdef CONFIG_SMP
54
extern void __inquire_remote_apic(int apicid);
55
#else /* CONFIG_SMP */
56
static inline void __inquire_remote_apic(int apicid)
57
{
58
}
59
#endif /* CONFIG_SMP */
60
61
static inline void default_inquire_remote_apic(int apicid)
62
{
63
if (apic_verbosity >= APIC_DEBUG)
64
__inquire_remote_apic(apicid);
65
}
66
67
/*
68
* With 82489DX we can't rely on apic feature bit
69
* retrieved via cpuid but still have to deal with
70
* such an apic chip so we assume that SMP configuration
71
* is found from MP table (64bit case uses ACPI mostly
72
* which set smp presence flag as well so we are safe
73
* to use this helper too).
74
*/
75
static inline bool apic_from_smp_config(void)
76
{
77
return smp_found_config && !disable_apic;
78
}
79
80
/*
81
* Basic functions accessing APICs.
82
*/
83
#ifdef CONFIG_PARAVIRT
84
#include <asm/paravirt.h>
85
#endif
86
87
#ifdef CONFIG_X86_64
88
extern int is_vsmp_box(void);
89
#else
90
static inline int is_vsmp_box(void)
91
{
92
return 0;
93
}
94
#endif
95
extern void xapic_wait_icr_idle(void);
96
extern u32 safe_xapic_wait_icr_idle(void);
97
extern void xapic_icr_write(u32, u32);
98
extern int setup_profiling_timer(unsigned int);
99
100
static inline void native_apic_mem_write(u32 reg, u32 v)
101
{
102
volatile u32 *addr = (volatile u32 *)(APIC_BASE + reg);
103
104
alternative_io("movl %0, %1", "xchgl %0, %1", X86_FEATURE_11AP,
105
ASM_OUTPUT2("=r" (v), "=m" (*addr)),
106
ASM_OUTPUT2("0" (v), "m" (*addr)));
107
}
108
109
static inline u32 native_apic_mem_read(u32 reg)
110
{
111
return *((volatile u32 *)(APIC_BASE + reg));
112
}
113
114
extern void native_apic_wait_icr_idle(void);
115
extern u32 native_safe_apic_wait_icr_idle(void);
116
extern void native_apic_icr_write(u32 low, u32 id);
117
extern u64 native_apic_icr_read(void);
118
119
extern int x2apic_mode;
120
121
#ifdef CONFIG_X86_X2APIC
122
/*
123
* Make previous memory operations globally visible before
124
* sending the IPI through x2apic wrmsr. We need a serializing instruction or
125
* mfence for this.
126
*/
127
static inline void x2apic_wrmsr_fence(void)
128
{
129
asm volatile("mfence" : : : "memory");
130
}
131
132
static inline void native_apic_msr_write(u32 reg, u32 v)
133
{
134
if (reg == APIC_DFR || reg == APIC_ID || reg == APIC_LDR ||
135
reg == APIC_LVR)
136
return;
137
138
wrmsr(APIC_BASE_MSR + (reg >> 4), v, 0);
139
}
140
141
static inline u32 native_apic_msr_read(u32 reg)
142
{
143
u64 msr;
144
145
if (reg == APIC_DFR)
146
return -1;
147
148
rdmsrl(APIC_BASE_MSR + (reg >> 4), msr);
149
return (u32)msr;
150
}
151
152
static inline void native_x2apic_wait_icr_idle(void)
153
{
154
/* no need to wait for icr idle in x2apic */
155
return;
156
}
157
158
static inline u32 native_safe_x2apic_wait_icr_idle(void)
159
{
160
/* no need to wait for icr idle in x2apic */
161
return 0;
162
}
163
164
static inline void native_x2apic_icr_write(u32 low, u32 id)
165
{
166
wrmsrl(APIC_BASE_MSR + (APIC_ICR >> 4), ((__u64) id) << 32 | low);
167
}
168
169
static inline u64 native_x2apic_icr_read(void)
170
{
171
unsigned long val;
172
173
rdmsrl(APIC_BASE_MSR + (APIC_ICR >> 4), val);
174
return val;
175
}
176
177
extern int x2apic_phys;
178
extern void check_x2apic(void);
179
extern void enable_x2apic(void);
180
extern void x2apic_icr_write(u32 low, u32 id);
181
static inline int x2apic_enabled(void)
182
{
183
u64 msr;
184
185
if (!cpu_has_x2apic)
186
return 0;
187
188
rdmsrl(MSR_IA32_APICBASE, msr);
189
if (msr & X2APIC_ENABLE)
190
return 1;
191
return 0;
192
}
193
194
#define x2apic_supported() (cpu_has_x2apic)
195
static inline void x2apic_force_phys(void)
196
{
197
x2apic_phys = 1;
198
}
199
#else
200
static inline void check_x2apic(void)
201
{
202
}
203
static inline void enable_x2apic(void)
204
{
205
}
206
static inline int x2apic_enabled(void)
207
{
208
return 0;
209
}
210
static inline void x2apic_force_phys(void)
211
{
212
}
213
214
#define x2apic_preenabled 0
215
#define x2apic_supported() 0
216
#endif
217
218
extern void enable_IR_x2apic(void);
219
220
extern int get_physical_broadcast(void);
221
222
extern int lapic_get_maxlvt(void);
223
extern void clear_local_APIC(void);
224
extern void connect_bsp_APIC(void);
225
extern void disconnect_bsp_APIC(int virt_wire_setup);
226
extern void disable_local_APIC(void);
227
extern void lapic_shutdown(void);
228
extern int verify_local_APIC(void);
229
extern void sync_Arb_IDs(void);
230
extern void init_bsp_APIC(void);
231
extern void setup_local_APIC(void);
232
extern void end_local_APIC_setup(void);
233
extern void bsp_end_local_APIC_setup(void);
234
extern void init_apic_mappings(void);
235
void register_lapic_address(unsigned long address);
236
extern void setup_boot_APIC_clock(void);
237
extern void setup_secondary_APIC_clock(void);
238
extern int APIC_init_uniprocessor(void);
239
extern int apic_force_enable(unsigned long addr);
240
241
/*
242
* On 32bit this is mach-xxx local
243
*/
244
#ifdef CONFIG_X86_64
245
extern int apic_is_clustered_box(void);
246
#else
247
static inline int apic_is_clustered_box(void)
248
{
249
return 0;
250
}
251
#endif
252
253
extern int setup_APIC_eilvt(u8 lvt_off, u8 vector, u8 msg_type, u8 mask);
254
255
#else /* !CONFIG_X86_LOCAL_APIC */
256
static inline void lapic_shutdown(void) { }
257
#define local_apic_timer_c2_ok 1
258
static inline void init_apic_mappings(void) { }
259
static inline void disable_local_APIC(void) { }
260
# define setup_boot_APIC_clock x86_init_noop
261
# define setup_secondary_APIC_clock x86_init_noop
262
#endif /* !CONFIG_X86_LOCAL_APIC */
263
264
#ifdef CONFIG_X86_64
265
#define SET_APIC_ID(x) (apic->set_apic_id(x))
266
#else
267
268
#endif
269
270
/*
271
* Copyright 2004 James Cleverdon, IBM.
272
* Subject to the GNU Public License, v.2
273
*
274
* Generic APIC sub-arch data struct.
275
*
276
* Hacked for x86-64 by James Cleverdon from i386 architecture code by
277
* Martin Bligh, Andi Kleen, James Bottomley, John Stultz, and
278
* James Cleverdon.
279
*/
280
struct apic {
281
char *name;
282
283
int (*probe)(void);
284
int (*acpi_madt_oem_check)(char *oem_id, char *oem_table_id);
285
int (*apic_id_registered)(void);
286
287
u32 irq_delivery_mode;
288
u32 irq_dest_mode;
289
290
const struct cpumask *(*target_cpus)(void);
291
292
int disable_esr;
293
294
int dest_logical;
295
unsigned long (*check_apicid_used)(physid_mask_t *map, int apicid);
296
unsigned long (*check_apicid_present)(int apicid);
297
298
void (*vector_allocation_domain)(int cpu, struct cpumask *retmask);
299
void (*init_apic_ldr)(void);
300
301
void (*ioapic_phys_id_map)(physid_mask_t *phys_map, physid_mask_t *retmap);
302
303
void (*setup_apic_routing)(void);
304
int (*multi_timer_check)(int apic, int irq);
305
int (*cpu_present_to_apicid)(int mps_cpu);
306
void (*apicid_to_cpu_present)(int phys_apicid, physid_mask_t *retmap);
307
void (*setup_portio_remap)(void);
308
int (*check_phys_apicid_present)(int phys_apicid);
309
void (*enable_apic_mode)(void);
310
int (*phys_pkg_id)(int cpuid_apic, int index_msb);
311
312
/*
313
* When one of the next two hooks returns 1 the apic
314
* is switched to this. Essentially they are additional
315
* probe functions:
316
*/
317
int (*mps_oem_check)(struct mpc_table *mpc, char *oem, char *productid);
318
319
unsigned int (*get_apic_id)(unsigned long x);
320
unsigned long (*set_apic_id)(unsigned int id);
321
unsigned long apic_id_mask;
322
323
unsigned int (*cpu_mask_to_apicid)(const struct cpumask *cpumask);
324
unsigned int (*cpu_mask_to_apicid_and)(const struct cpumask *cpumask,
325
const struct cpumask *andmask);
326
327
/* ipi */
328
void (*send_IPI_mask)(const struct cpumask *mask, int vector);
329
void (*send_IPI_mask_allbutself)(const struct cpumask *mask,
330
int vector);
331
void (*send_IPI_allbutself)(int vector);
332
void (*send_IPI_all)(int vector);
333
void (*send_IPI_self)(int vector);
334
335
/* wakeup_secondary_cpu */
336
int (*wakeup_secondary_cpu)(int apicid, unsigned long start_eip);
337
338
int trampoline_phys_low;
339
int trampoline_phys_high;
340
341
void (*wait_for_init_deassert)(atomic_t *deassert);
342
void (*smp_callin_clear_local_apic)(void);
343
void (*inquire_remote_apic)(int apicid);
344
345
/* apic ops */
346
u32 (*read)(u32 reg);
347
void (*write)(u32 reg, u32 v);
348
u64 (*icr_read)(void);
349
void (*icr_write)(u32 low, u32 high);
350
void (*wait_icr_idle)(void);
351
u32 (*safe_wait_icr_idle)(void);
352
353
#ifdef CONFIG_X86_32
354
/*
355
* Called very early during boot from get_smp_config(). It should
356
* return the logical apicid. x86_[bios]_cpu_to_apicid is
357
* initialized before this function is called.
358
*
359
* If logical apicid can't be determined that early, the function
360
* may return BAD_APICID. Logical apicid will be configured after
361
* init_apic_ldr() while bringing up CPUs. Note that NUMA affinity
362
* won't be applied properly during early boot in this case.
363
*/
364
int (*x86_32_early_logical_apicid)(int cpu);
365
366
/*
367
* Optional method called from setup_local_APIC() after logical
368
* apicid is guaranteed to be known to initialize apicid -> node
369
* mapping if NUMA initialization hasn't done so already. Don't
370
* add new users.
371
*/
372
int (*x86_32_numa_cpu_node)(int cpu);
373
#endif
374
};
375
376
/*
377
* Pointer to the local APIC driver in use on this system (there's
378
* always just one such driver in use - the kernel decides via an
379
* early probing process which one it picks - and then sticks to it):
380
*/
381
extern struct apic *apic;
382
383
/*
384
* APIC drivers are probed based on how they are listed in the .apicdrivers
385
* section. So the order is important and enforced by the ordering
386
* of different apic driver files in the Makefile.
387
*
388
* For the files having two apic drivers, we use apic_drivers()
389
* to enforce the order with in them.
390
*/
391
#define apic_driver(sym) \
392
static struct apic *__apicdrivers_##sym __used \
393
__aligned(sizeof(struct apic *)) \
394
__section(.apicdrivers) = { &sym }
395
396
#define apic_drivers(sym1, sym2) \
397
static struct apic *__apicdrivers_##sym1##sym2[2] __used \
398
__aligned(sizeof(struct apic *)) \
399
__section(.apicdrivers) = { &sym1, &sym2 }
400
401
extern struct apic *__apicdrivers[], *__apicdrivers_end[];
402
403
/*
404
* APIC functionality to boot other CPUs - only used on SMP:
405
*/
406
#ifdef CONFIG_SMP
407
extern atomic_t init_deasserted;
408
extern int wakeup_secondary_cpu_via_nmi(int apicid, unsigned long start_eip);
409
#endif
410
411
#ifdef CONFIG_X86_LOCAL_APIC
412
static inline u32 apic_read(u32 reg)
413
{
414
return apic->read(reg);
415
}
416
417
static inline void apic_write(u32 reg, u32 val)
418
{
419
apic->write(reg, val);
420
}
421
422
static inline u64 apic_icr_read(void)
423
{
424
return apic->icr_read();
425
}
426
427
static inline void apic_icr_write(u32 low, u32 high)
428
{
429
apic->icr_write(low, high);
430
}
431
432
static inline void apic_wait_icr_idle(void)
433
{
434
apic->wait_icr_idle();
435
}
436
437
static inline u32 safe_apic_wait_icr_idle(void)
438
{
439
return apic->safe_wait_icr_idle();
440
}
441
442
#else /* CONFIG_X86_LOCAL_APIC */
443
444
static inline u32 apic_read(u32 reg) { return 0; }
445
static inline void apic_write(u32 reg, u32 val) { }
446
static inline u64 apic_icr_read(void) { return 0; }
447
static inline void apic_icr_write(u32 low, u32 high) { }
448
static inline void apic_wait_icr_idle(void) { }
449
static inline u32 safe_apic_wait_icr_idle(void) { return 0; }
450
451
#endif /* CONFIG_X86_LOCAL_APIC */
452
453
static inline void ack_APIC_irq(void)
454
{
455
/*
456
* ack_APIC_irq() actually gets compiled as a single instruction
457
* ... yummie.
458
*/
459
460
/* Docs say use 0 for future compatibility */
461
apic_write(APIC_EOI, 0);
462
}
463
464
static inline unsigned default_get_apic_id(unsigned long x)
465
{
466
unsigned int ver = GET_APIC_VERSION(apic_read(APIC_LVR));
467
468
if (APIC_XAPIC(ver) || boot_cpu_has(X86_FEATURE_EXTD_APICID))
469
return (x >> 24) & 0xFF;
470
else
471
return (x >> 24) & 0x0F;
472
}
473
474
/*
475
* Warm reset vector default position:
476
*/
477
#define DEFAULT_TRAMPOLINE_PHYS_LOW 0x467
478
#define DEFAULT_TRAMPOLINE_PHYS_HIGH 0x469
479
480
#ifdef CONFIG_X86_64
481
extern int default_acpi_madt_oem_check(char *, char *);
482
483
extern void apic_send_IPI_self(int vector);
484
485
DECLARE_PER_CPU(int, x2apic_extra_bits);
486
487
extern int default_cpu_present_to_apicid(int mps_cpu);
488
extern int default_check_phys_apicid_present(int phys_apicid);
489
#endif
490
491
static inline void default_wait_for_init_deassert(atomic_t *deassert)
492
{
493
while (!atomic_read(deassert))
494
cpu_relax();
495
return;
496
}
497
498
extern struct apic *generic_bigsmp_probe(void);
499
500
501
#ifdef CONFIG_X86_LOCAL_APIC
502
503
#include <asm/smp.h>
504
505
#define APIC_DFR_VALUE (APIC_DFR_FLAT)
506
507
static inline const struct cpumask *default_target_cpus(void)
508
{
509
#ifdef CONFIG_SMP
510
return cpu_online_mask;
511
#else
512
return cpumask_of(0);
513
#endif
514
}
515
516
DECLARE_EARLY_PER_CPU(u16, x86_bios_cpu_apicid);
517
518
519
static inline unsigned int read_apic_id(void)
520
{
521
unsigned int reg;
522
523
reg = apic_read(APIC_ID);
524
525
return apic->get_apic_id(reg);
526
}
527
528
extern void default_setup_apic_routing(void);
529
530
extern struct apic apic_noop;
531
532
#ifdef CONFIG_X86_32
533
534
static inline int noop_x86_32_early_logical_apicid(int cpu)
535
{
536
return BAD_APICID;
537
}
538
539
/*
540
* Set up the logical destination ID.
541
*
542
* Intel recommends to set DFR, LDR and TPR before enabling
543
* an APIC. See e.g. "AP-388 82489DX User's Manual" (Intel
544
* document number 292116). So here it goes...
545
*/
546
extern void default_init_apic_ldr(void);
547
548
static inline int default_apic_id_registered(void)
549
{
550
return physid_isset(read_apic_id(), phys_cpu_present_map);
551
}
552
553
static inline int default_phys_pkg_id(int cpuid_apic, int index_msb)
554
{
555
return cpuid_apic >> index_msb;
556
}
557
558
#endif
559
560
static inline unsigned int
561
default_cpu_mask_to_apicid(const struct cpumask *cpumask)
562
{
563
return cpumask_bits(cpumask)[0] & APIC_ALL_CPUS;
564
}
565
566
static inline unsigned int
567
default_cpu_mask_to_apicid_and(const struct cpumask *cpumask,
568
const struct cpumask *andmask)
569
{
570
unsigned long mask1 = cpumask_bits(cpumask)[0];
571
unsigned long mask2 = cpumask_bits(andmask)[0];
572
unsigned long mask3 = cpumask_bits(cpu_online_mask)[0];
573
574
return (unsigned int)(mask1 & mask2 & mask3);
575
}
576
577
static inline unsigned long default_check_apicid_used(physid_mask_t *map, int apicid)
578
{
579
return physid_isset(apicid, *map);
580
}
581
582
static inline unsigned long default_check_apicid_present(int bit)
583
{
584
return physid_isset(bit, phys_cpu_present_map);
585
}
586
587
static inline void default_ioapic_phys_id_map(physid_mask_t *phys_map, physid_mask_t *retmap)
588
{
589
*retmap = *phys_map;
590
}
591
592
static inline int __default_cpu_present_to_apicid(int mps_cpu)
593
{
594
if (mps_cpu < nr_cpu_ids && cpu_present(mps_cpu))
595
return (int)per_cpu(x86_bios_cpu_apicid, mps_cpu);
596
else
597
return BAD_APICID;
598
}
599
600
static inline int
601
__default_check_phys_apicid_present(int phys_apicid)
602
{
603
return physid_isset(phys_apicid, phys_cpu_present_map);
604
}
605
606
#ifdef CONFIG_X86_32
607
static inline int default_cpu_present_to_apicid(int mps_cpu)
608
{
609
return __default_cpu_present_to_apicid(mps_cpu);
610
}
611
612
static inline int
613
default_check_phys_apicid_present(int phys_apicid)
614
{
615
return __default_check_phys_apicid_present(phys_apicid);
616
}
617
#else
618
extern int default_cpu_present_to_apicid(int mps_cpu);
619
extern int default_check_phys_apicid_present(int phys_apicid);
620
#endif
621
622
#endif /* CONFIG_X86_LOCAL_APIC */
623
624
#endif /* _ASM_X86_APIC_H */
625
626