1 #ifndef _ASM_GENAPIC_H
2 #define _ASM_GENAPIC_H 1
3 
4 #include <xen/cpumask.h>
5 
6 /*
7  * Generic APIC driver interface.
8  *
9  * An straight forward mapping of the APIC related parts of the
10  * x86 subarchitecture interface to a dynamic object.
11  *
12  * This is used by the "generic" x86 subarchitecture.
13  *
14  * Copyright 2003 Andi Kleen, SuSE Labs.
15  */
16 
17 struct mpc_config_translation;
18 struct mpc_config_bus;
19 struct mp_config_table;
20 struct mpc_config_processor;
21 
22 struct genapic {
23 	const char *name;
24 	int (*probe)(void);
25 
26 	void (*init_apic_ldr)(void);
27 	const cpumask_t *(*vector_allocation_cpumask)(int cpu);
28 	unsigned int (*cpu_mask_to_apicid)(const cpumask_t *cpumask);
29 	void (*send_IPI_mask)(const cpumask_t *mask, int vector);
30     void (*send_IPI_self)(uint8_t vector);
31 };
32 
33 #define APIC_INIT(aname, aprobe) \
34 	.name = aname, \
35 	.probe = aprobe
36 
37 #define TARGET_CPUS ((const typeof(cpu_online_map) *)&cpu_online_map)
38 #define init_apic_ldr() alternative_vcall(genapic.init_apic_ldr)
39 #define cpu_mask_to_apicid(mask) ({ \
40 	/* \
41 	 * There are a number of places where the address of a local variable \
42 	 * gets passed here. The use of ?: in alternative_call<N>() triggers an \
43 	 * "address of ... is always true" warning in such a case with at least \
44 	 * gcc 7 and 8. Hence the seemingly pointless local variable here. \
45 	 */ \
46 	const cpumask_t *m_ = (mask); \
47 	alternative_call(genapic.cpu_mask_to_apicid, m_); \
48 })
49 #define vector_allocation_cpumask(cpu) \
50 	alternative_call(genapic.vector_allocation_cpumask, cpu)
51 
52 extern struct genapic genapic;
53 extern const struct genapic apic_default;
54 extern const struct genapic apic_bigsmp;
55 
56 void cf_check send_IPI_self_legacy(uint8_t vector);
57 
58 void cf_check init_apic_ldr_flat(void);
59 void cf_check send_IPI_mask_flat(const cpumask_t *cpumask, int vector);
60 
61 void cf_check init_apic_ldr_phys(void);
62 unsigned int cf_check cpu_mask_to_apicid_phys(const cpumask_t *cpumask);
63 void cf_check send_IPI_mask_phys(const cpumask_t *mask, int vector);
64 const cpumask_t *cf_check vector_allocation_cpumask_phys(int cpu);
65 
66 void generic_apic_probe(void);
67 void generic_bigsmp_probe(void);
68 
69 #endif
70