Path: blob/master/arch/x86/kernel/apic/x2apic_phys.c
17537 views
#include <linux/threads.h>1#include <linux/cpumask.h>2#include <linux/string.h>3#include <linux/kernel.h>4#include <linux/ctype.h>5#include <linux/init.h>6#include <linux/dmar.h>78#include <asm/smp.h>9#include <asm/x2apic.h>1011int x2apic_phys;1213static struct apic apic_x2apic_phys;1415static int set_x2apic_phys_mode(char *arg)16{17x2apic_phys = 1;18return 0;19}20early_param("x2apic_phys", set_x2apic_phys_mode);2122static int x2apic_acpi_madt_oem_check(char *oem_id, char *oem_table_id)23{24if (x2apic_phys)25return x2apic_enabled();26else27return 0;28}2930static void31__x2apic_send_IPI_mask(const struct cpumask *mask, int vector, int apic_dest)32{33unsigned long query_cpu;34unsigned long this_cpu;35unsigned long flags;3637x2apic_wrmsr_fence();3839local_irq_save(flags);4041this_cpu = smp_processor_id();42for_each_cpu(query_cpu, mask) {43if (apic_dest == APIC_DEST_ALLBUT && this_cpu == query_cpu)44continue;45__x2apic_send_IPI_dest(per_cpu(x86_cpu_to_apicid, query_cpu),46vector, APIC_DEST_PHYSICAL);47}48local_irq_restore(flags);49}5051static void x2apic_send_IPI_mask(const struct cpumask *mask, int vector)52{53__x2apic_send_IPI_mask(mask, vector, APIC_DEST_ALLINC);54}5556static void57x2apic_send_IPI_mask_allbutself(const struct cpumask *mask, int vector)58{59__x2apic_send_IPI_mask(mask, vector, APIC_DEST_ALLBUT);60}6162static void x2apic_send_IPI_allbutself(int vector)63{64__x2apic_send_IPI_mask(cpu_online_mask, vector, APIC_DEST_ALLBUT);65}6667static void x2apic_send_IPI_all(int vector)68{69__x2apic_send_IPI_mask(cpu_online_mask, vector, APIC_DEST_ALLINC);70}7172static unsigned int x2apic_cpu_mask_to_apicid(const struct cpumask *cpumask)73{74/*75* We're using fixed IRQ delivery, can only return one phys APIC ID.76* May as well be the first.77*/78int cpu = cpumask_first(cpumask);7980if ((unsigned)cpu < nr_cpu_ids)81return per_cpu(x86_cpu_to_apicid, cpu);82else83return BAD_APICID;84}8586static unsigned int87x2apic_cpu_mask_to_apicid_and(const struct cpumask *cpumask,88const struct cpumask *andmask)89{90int cpu;9192/*93* We're using fixed IRQ delivery, can only return one phys APIC ID.94* May as well be the first.95*/96for_each_cpu_and(cpu, cpumask, andmask) {97if (cpumask_test_cpu(cpu, cpu_online_mask))98break;99}100101return per_cpu(x86_cpu_to_apicid, cpu);102}103104static void init_x2apic_ldr(void)105{106}107108static int x2apic_phys_probe(void)109{110if (x2apic_mode && x2apic_phys)111return 1;112113return apic == &apic_x2apic_phys;114}115116static struct apic apic_x2apic_phys = {117118.name = "physical x2apic",119.probe = x2apic_phys_probe,120.acpi_madt_oem_check = x2apic_acpi_madt_oem_check,121.apic_id_registered = x2apic_apic_id_registered,122123.irq_delivery_mode = dest_Fixed,124.irq_dest_mode = 0, /* physical */125126.target_cpus = x2apic_target_cpus,127.disable_esr = 0,128.dest_logical = 0,129.check_apicid_used = NULL,130.check_apicid_present = NULL,131132.vector_allocation_domain = x2apic_vector_allocation_domain,133.init_apic_ldr = init_x2apic_ldr,134135.ioapic_phys_id_map = NULL,136.setup_apic_routing = NULL,137.multi_timer_check = NULL,138.cpu_present_to_apicid = default_cpu_present_to_apicid,139.apicid_to_cpu_present = NULL,140.setup_portio_remap = NULL,141.check_phys_apicid_present = default_check_phys_apicid_present,142.enable_apic_mode = NULL,143.phys_pkg_id = x2apic_phys_pkg_id,144.mps_oem_check = NULL,145146.get_apic_id = x2apic_get_apic_id,147.set_apic_id = x2apic_set_apic_id,148.apic_id_mask = 0xFFFFFFFFu,149150.cpu_mask_to_apicid = x2apic_cpu_mask_to_apicid,151.cpu_mask_to_apicid_and = x2apic_cpu_mask_to_apicid_and,152153.send_IPI_mask = x2apic_send_IPI_mask,154.send_IPI_mask_allbutself = x2apic_send_IPI_mask_allbutself,155.send_IPI_allbutself = x2apic_send_IPI_allbutself,156.send_IPI_all = x2apic_send_IPI_all,157.send_IPI_self = x2apic_send_IPI_self,158159.trampoline_phys_low = DEFAULT_TRAMPOLINE_PHYS_LOW,160.trampoline_phys_high = DEFAULT_TRAMPOLINE_PHYS_HIGH,161.wait_for_init_deassert = NULL,162.smp_callin_clear_local_apic = NULL,163.inquire_remote_apic = NULL,164165.read = native_apic_msr_read,166.write = native_apic_msr_write,167.icr_read = native_x2apic_icr_read,168.icr_write = native_x2apic_icr_write,169.wait_icr_idle = native_x2apic_wait_icr_idle,170.safe_wait_icr_idle = native_safe_x2apic_wait_icr_idle,171};172173apic_driver(apic_x2apic_phys);174175176