1#include <linux/init.h> 2 3#include <asm/x86_init.h> 4#include <asm/apic.h> 5#include <asm/xen/hypercall.h> 6 7#include <xen/xen.h> 8#include <xen/interface/physdev.h> 9#include "xen-ops.h" 10#include "pmu.h" 11#include "smp.h" 12 13static unsigned int xen_io_apic_read(unsigned apic, unsigned reg) 14{ 15 struct physdev_apic apic_op; 16 int ret; 17 18 apic_op.apic_physbase = mpc_ioapic_addr(apic); 19 apic_op.reg = reg; 20 ret = HYPERVISOR_physdev_op(PHYSDEVOP_apic_read, &apic_op); 21 if (!ret) 22 return apic_op.value; 23 24 /* fallback to return an emulated IO_APIC values */ 25 if (reg == 0x1) 26 return 0x00170020; 27 else if (reg == 0x0) 28 return apic << 24; 29 30 return 0xfd; 31} 32 33static unsigned long xen_set_apic_id(unsigned int x) 34{ 35 WARN_ON(1); 36 return x; 37} 38 39static unsigned int xen_get_apic_id(unsigned long x) 40{ 41 return ((x)>>24) & 0xFFu; 42} 43 44static u32 xen_apic_read(u32 reg) 45{ 46 struct xen_platform_op op = { 47 .cmd = XENPF_get_cpuinfo, 48 .interface_version = XENPF_INTERFACE_VERSION, 49 .u.pcpu_info.xen_cpuid = 0, 50 }; 51 int ret = 0; 52 53 /* Shouldn't need this as APIC is turned off for PV, and we only 54 * get called on the bootup processor. But just in case. */ 55 if (!xen_initial_domain() || smp_processor_id()) 56 return 0; 57 58 if (reg == APIC_LVR) 59 return 0x10; 60#ifdef CONFIG_X86_32 61 if (reg == APIC_LDR) 62 return SET_APIC_LOGICAL_ID(1UL << smp_processor_id()); 63#endif 64 if (reg != APIC_ID) 65 return 0; 66 67 ret = HYPERVISOR_dom0_op(&op); 68 if (ret) 69 return 0; 70 71 return op.u.pcpu_info.apic_id << 24; 72} 73 74static void xen_apic_write(u32 reg, u32 val) 75{ 76 if (reg == APIC_LVTPC) { 77 (void)pmu_apic_update(reg); 78 return; 79 } 80 81 /* Warn to see if there's any stray references */ 82 WARN(1,"register: %x, value: %x\n", reg, val); 83} 84 85static u64 xen_apic_icr_read(void) 86{ 87 return 0; 88} 89 90static void xen_apic_icr_write(u32 low, u32 id) 91{ 92 /* Warn to see if there's any stray references */ 93 WARN_ON(1); 94} 95 96static u32 xen_safe_apic_wait_icr_idle(void) 97{ 98 return 0; 99} 100 101static int xen_apic_probe_pv(void) 102{ 103 if (xen_pv_domain()) 104 return 1; 105 106 return 0; 107} 108 109static int xen_madt_oem_check(char *oem_id, char *oem_table_id) 110{ 111 return xen_pv_domain(); 112} 113 114static int xen_id_always_valid(int apicid) 115{ 116 return 1; 117} 118 119static int xen_id_always_registered(void) 120{ 121 return 1; 122} 123 124static int xen_phys_pkg_id(int initial_apic_id, int index_msb) 125{ 126 return initial_apic_id >> index_msb; 127} 128 129#ifdef CONFIG_X86_32 130static int xen_x86_32_early_logical_apicid(int cpu) 131{ 132 /* Match with APIC_LDR read. Otherwise setup_local_APIC complains. */ 133 return 1 << cpu; 134} 135#endif 136 137static void xen_noop(void) 138{ 139} 140 141static void xen_silent_inquire(int apicid) 142{ 143} 144 145static struct apic xen_pv_apic = { 146 .name = "Xen PV", 147 .probe = xen_apic_probe_pv, 148 .acpi_madt_oem_check = xen_madt_oem_check, 149 .apic_id_valid = xen_id_always_valid, 150 .apic_id_registered = xen_id_always_registered, 151 152 /* .irq_delivery_mode - used in native_compose_msi_msg only */ 153 /* .irq_dest_mode - used in native_compose_msi_msg only */ 154 155 .target_cpus = default_target_cpus, 156 .disable_esr = 0, 157 /* .dest_logical - default_send_IPI_ use it but we use our own. */ 158 .check_apicid_used = default_check_apicid_used, /* Used on 32-bit */ 159 160 .vector_allocation_domain = flat_vector_allocation_domain, 161 .init_apic_ldr = xen_noop, /* setup_local_APIC calls it */ 162 163 .ioapic_phys_id_map = default_ioapic_phys_id_map, /* Used on 32-bit */ 164 .setup_apic_routing = NULL, 165 .cpu_present_to_apicid = default_cpu_present_to_apicid, 166 .apicid_to_cpu_present = physid_set_mask_of_physid, /* Used on 32-bit */ 167 .check_phys_apicid_present = default_check_phys_apicid_present, /* smp_sanity_check needs it */ 168 .phys_pkg_id = xen_phys_pkg_id, /* detect_ht */ 169 170 .get_apic_id = xen_get_apic_id, 171 .set_apic_id = xen_set_apic_id, /* Can be NULL on 32-bit. */ 172 .apic_id_mask = 0xFF << 24, /* Used by verify_local_APIC. Match with what xen_get_apic_id does. */ 173 174 .cpu_mask_to_apicid_and = flat_cpu_mask_to_apicid_and, 175 176#ifdef CONFIG_SMP 177 .send_IPI_mask = xen_send_IPI_mask, 178 .send_IPI_mask_allbutself = xen_send_IPI_mask_allbutself, 179 .send_IPI_allbutself = xen_send_IPI_allbutself, 180 .send_IPI_all = xen_send_IPI_all, 181 .send_IPI_self = xen_send_IPI_self, 182#endif 183 /* .wait_for_init_deassert- used by AP bootup - smp_callin which we don't use */ 184 .inquire_remote_apic = xen_silent_inquire, 185 186 .read = xen_apic_read, 187 .write = xen_apic_write, 188 .eoi_write = xen_apic_write, 189 190 .icr_read = xen_apic_icr_read, 191 .icr_write = xen_apic_icr_write, 192 .wait_icr_idle = xen_noop, 193 .safe_wait_icr_idle = xen_safe_apic_wait_icr_idle, 194 195#ifdef CONFIG_X86_32 196 /* generic_processor_info and setup_local_APIC. */ 197 .x86_32_early_logical_apicid = xen_x86_32_early_logical_apicid, 198#endif 199}; 200 201static void __init xen_apic_check(void) 202{ 203 if (apic == &xen_pv_apic) 204 return; 205 206 pr_info("Switched APIC routing from %s to %s.\n", apic->name, 207 xen_pv_apic.name); 208 apic = &xen_pv_apic; 209} 210void __init xen_init_apic(void) 211{ 212 x86_io_apic_ops.read = xen_io_apic_read; 213 /* On PV guests the APIC CPUID bit is disabled so none of the 214 * routines end up executing. */ 215 if (!xen_initial_domain()) 216 apic = &xen_pv_apic; 217 218 x86_platform.apic_post_init = xen_apic_check; 219} 220apic_driver(xen_pv_apic); 221