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